;;-*-Lisp-*- (in-package goal) ;; definition of type rpc-buffer (deftype rpc-buffer (basic) "Buffer for storing input/output data for a remote procedure call to the overlord driver on the IOP." ((elt-size uint32) (elt-count uint32) (elt-used uint32) (busy basic) (base pointer) (data uint8 :dynamic :offset 32) ) (:methods (new (symbol type uint uint) rpc-buffer) ) ) ;; definition for method 3 of type rpc-buffer (defmethod inspect ((this rpc-buffer)) (when (not this) (set! this this) (goto cfg-4) ) (format #t "[~8x] ~A~%" this (-> this type)) (format #t "~1Telt-size: ~D~%" (-> this elt-size)) (format #t "~1Telt-count: ~D~%" (-> this elt-count)) (format #t "~1Telt-used: ~D~%" (-> this elt-used)) (format #t "~1Tbusy: ~A~%" (-> this busy)) (format #t "~1Tbase: ~D~%" (-> this base)) (format #t "~1Tdata[0] @ #x~X~%" (-> this data)) (label cfg-4) this ) ;; definition for method 0 of type rpc-buffer (defmethod new rpc-buffer ((allocation symbol) (type-to-make type) (arg0 uint) (arg1 uint)) (let* ((a2-2 (+ (-> type-to-make size) 63 (* (the-as int arg0) (the-as int arg1)))) (v0-0 (object-new allocation type-to-make (the-as int a2-2))) ) (set! (-> v0-0 elt-size) arg0) (set! (-> v0-0 elt-count) arg1) (set! (-> v0-0 elt-used) (the-as uint 0)) (set! (-> v0-0 busy) #f) (set! (-> v0-0 base) (logand -64 (&-> v0-0 data 63))) v0-0 ) ) ;; definition of type rpc-buffer-pair (deftype rpc-buffer-pair (basic) "A double buffer of RPC buffers. This is used to let the game queue up data in one buffer while the other is being read/written by overlord." ((buffer rpc-buffer 2) (current rpc-buffer) (last-recv-buffer pointer) (rpc-port int32) ) (:methods (new (symbol type uint uint int) rpc-buffer-pair) (call (rpc-buffer-pair uint pointer uint) int) (add-element (rpc-buffer-pair) pointer) (decrement-elt-used (rpc-buffer-pair) int) (sync (rpc-buffer-pair symbol) int) (check-busy (rpc-buffer-pair) symbol) (pop-last-received (rpc-buffer-pair) pointer) ) ) ;; definition for method 3 of type rpc-buffer-pair (defmethod inspect ((this rpc-buffer-pair)) (when (not this) (set! this this) (goto cfg-4) ) (format #t "[~8x] ~A~%" this (-> this type)) (format #t "~1Tbuffer[2] @ #x~X~%" (-> this buffer)) (format #t "~1Tcurrent: ~A~%" (-> this current)) (format #t "~1Tlast-recv-buffer: #x~X~%" (-> this last-recv-buffer)) (format #t "~1Trpc-port: ~D~%" (-> this rpc-port)) (label cfg-4) this ) ;; definition for method 0 of type rpc-buffer-pair (defmethod new rpc-buffer-pair ((allocation symbol) (type-to-make type) (arg0 uint) (arg1 uint) (arg2 int)) (let ((s3-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) (set! (-> s3-0 buffer 0) (new 'global 'rpc-buffer arg0 arg1)) (set! (-> s3-0 buffer 1) (new 'global 'rpc-buffer arg0 arg1)) (set! (-> s3-0 current) (-> s3-0 buffer 0)) (set! (-> s3-0 last-recv-buffer) (the-as pointer #f)) (set! (-> s3-0 rpc-port) arg2) s3-0 ) ) ;; definition for method 12 of type rpc-buffer-pair (defmethod sync ((this rpc-buffer-pair) (arg0 symbol)) "Wait for an in-progress rpc to finish." (let ((s5-0 (if (= (-> this current) (-> this buffer 0)) (-> this buffer 1) (-> this buffer 0) ) ) ) (when (-> s5-0 busy) (when (nonzero? (rpc-busy? (-> this rpc-port))) (if arg0 (format 0 "STALL: waiting for IOP on RPC port #~D~%" (-> this rpc-port)) ) (while (nonzero? (rpc-busy? (-> this rpc-port))) (nop!) (nop!) (nop!) (nop!) (nop!) (nop!) (nop!) (nop!) ) ) (set! (-> s5-0 busy) #f) (set! (-> s5-0 elt-used) (the-as uint 0)) 0 ) ) 0 ) ;; definition for method 13 of type rpc-buffer-pair (defmethod check-busy ((this rpc-buffer-pair)) "Check to see if an rpc is in progress." (let ((gp-0 (if (= (-> this current) (-> this buffer 0)) (-> this buffer 1) (-> this buffer 0) ) ) ) (when (-> gp-0 busy) (if (nonzero? (rpc-busy? (-> this rpc-port))) (return #t) ) (set! (-> gp-0 busy) #f) (set! (-> gp-0 elt-used) (the-as uint 0)) 0 ) ) #f ) ;; definition for method 9 of type rpc-buffer-pair (defmethod call ((this rpc-buffer-pair) (arg0 uint) (arg1 pointer) (arg2 uint)) "Start an async RPC call. If there is already one in progress, stall and wait for it to finish." (when (nonzero? (-> this current elt-used)) (let ((s2-0 (if (= (-> this current) (-> this buffer 0)) (-> this buffer 1) (-> this buffer 0) ) ) ) (when (-> s2-0 busy) (when (nonzero? (rpc-busy? (-> this rpc-port))) (format 0 "STALL: waiting for IOP on RPC port #~D~%" (-> this rpc-port)) (while (nonzero? (rpc-busy? (-> this rpc-port))) (nop!) (nop!) (nop!) (nop!) (nop!) (nop!) (nop!) (nop!) ) ) (set! (-> s2-0 busy) #f) (set! (-> s2-0 elt-used) (the-as uint 0)) 0 ) (let ((s1-0 (-> this current))) (rpc-call (-> this rpc-port) arg0 (the-as uint 1) (the-as uint (-> s1-0 base)) (the-as int (* (-> s1-0 elt-size) (-> s1-0 elt-used))) (the-as uint arg1) (the-as int arg2) ) (set! (-> s1-0 busy) (the-as basic #t)) ) (set! (-> this last-recv-buffer) arg1) (set! (-> this current) s2-0) ) ) 0 ) ;; definition for method 14 of type rpc-buffer-pair (defmethod pop-last-received ((this rpc-buffer-pair)) "Pop the response from the most recently completed rpc call." (let ((v0-0 (-> this last-recv-buffer))) (set! (-> this last-recv-buffer) (the-as pointer #f)) v0-0 ) ) ;; definition for method 10 of type rpc-buffer-pair (defmethod add-element ((this rpc-buffer-pair)) "Add an element. If the buffer is full, flush it!" (let ((v1-0 (-> this current))) (when (= (-> v1-0 elt-used) (-> v1-0 elt-count)) (if (zero? (-> this rpc-port)) (format 0 "WARNING: too many sound commands queued~%") ) (call this (the-as uint 0) (the-as pointer 0) (the-as uint 0)) (set! v1-0 (-> this current)) ) (let ((v0-2 (&+ (-> v1-0 base) (* (-> v1-0 elt-used) (-> v1-0 elt-size))))) (+! (-> v1-0 elt-used) 1) v0-2 ) ) ) ;; definition for method 11 of type rpc-buffer-pair (defmethod decrement-elt-used ((this rpc-buffer-pair)) "Remove the most recently queued element." (if (> (-> this current elt-used) 0) (+! (-> this current elt-used) -1) ) 0 ) ;; failed to figure out what this is: 0