From b92a2823bba538b7b5496bd15d163022ba60a4e5 Mon Sep 17 00:00:00 2001 From: ManDude <7569514+ManDude@users.noreply.github.com> Date: Mon, 22 Feb 2021 06:02:12 +0000 Subject: [PATCH] Make a `fake-asm` macro for (mips) assembly we want to show but not use + some other fixes (#277) * use new fake-asm macro * [timer] update some docs and code for clarity * Fix typos * uncomment "sync" instructions * some decimal to hex * move fake-asm's to gcommon * [timer] document timer-mode more. * Fix errors * i dont like this --- decompiler/config/all-types.gc | 39 ++++++++------ goal_src/engine/dma/dma-bucket.gc | 2 +- goal_src/engine/dma/dma-buffer.gc | 2 +- goal_src/engine/dma/dma.gc | 88 +++++++++++++++---------------- goal_src/engine/ps2/timer-h.gc | 28 ++++++---- goal_src/engine/ps2/timer.gc | 29 +++------- goal_src/goal-lib.gc | 13 +++++ goal_src/kernel/gcommon.gc | 12 +++++ 8 files changed, 120 insertions(+), 93 deletions(-) diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index a1d78f308..6c6f96ba2 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -1934,17 +1934,26 @@ ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; (deftype timer-mode (uint32) - (;(data uint32 :offset 0 :size 32) + (;; clock selection: + ;; 0: BUSCLK + ;; 1: BUSCLK/16 + ;; 2: BUSCLK/256 + ;; 3: hblank (clks uint8 :offset 0 :size 2) - (gate uint8 :offset 2 :size 1) - (gats uint8 :offset 3 :size 1) + (gate uint8 :offset 2 :size 1) ;; gate function enable + (gats uint8 :offset 3 :size 1) ;; gate selection: 0 = hblank, 1 = vblank + ;; gate mode: + ;; 0: count while gate signal is low + ;; 1: start when gate signal rises + ;; 2: start when gate signal falls + ;; 3: start when gate signal rises/falls (gatm uint8 :offset 4 :size 2) - (zret uint8 :offset 6 :size 1) - (cue uint8 :offset 7 :size 1) - (cmpe uint8 :offset 8 :size 1) - (ovfe uint8 :offset 9 :size 1) - (equf uint8 :offset 10 :size 1) - (ovff uint8 :offset 11 :size 1) + (zret uint8 :offset 6 :size 1) ;; zero return: clear counter when equal to reference value + (cue uint8 :offset 7 :size 1) ;; count-up enable + (cmpe uint8 :offset 8 :size 1) ;; compare-interrupt enable + (ovfe uint8 :offset 9 :size 1) ;; overflow-interrupt enable + (equf uint8 :offset 10 :size 1) ;; equal-flag + (ovff uint8 :offset 11 :size 1) ;; overflow-flag ) :method-count-assert 9 :size-assert #x4 @@ -2022,12 +2031,12 @@ (define-extern timer-count (function timer-bank uint)) (define-extern disable-irq (function none)) (define-extern enable-irq (function none)) -(define-extern stopwatch-init (function stopwatch none)) -(define-extern stopwatch-reset (function stopwatch none)) -(define-extern stopwatch-start (function stopwatch none)) -(define-extern stopwatch-stop (function stopwatch none)) -(define-extern stopwatch-begin (function stopwatch none)) -(define-extern stopwatch-end (function stopwatch none)) +(define-extern stopwatch-init (function stopwatch int)) +(define-extern stopwatch-reset (function stopwatch int)) +(define-extern stopwatch-start (function stopwatch int)) +(define-extern stopwatch-stop (function stopwatch uint)) +(define-extern stopwatch-begin (function stopwatch int)) +(define-extern stopwatch-end (function stopwatch uint)) (define-extern stopwatch-elapsed-ticks (function stopwatch uint)) (define-extern stopwatch-elapsed-seconds (function stopwatch float)) diff --git a/goal_src/engine/dma/dma-bucket.gc b/goal_src/engine/dma/dma-bucket.gc index fbe911081..f690dc579 100644 --- a/goal_src/engine/dma/dma-bucket.gc +++ b/goal_src/engine/dma/dma-bucket.gc @@ -19,7 +19,7 @@ ;; Each bucket contains: ;; a tag, (64-bits), to point to the chain of the bucket -;; last, a pointer to the last tag of this bucket, so the bucket can be patched to point to the next. +;; last, a pointer to the last tag of this bucket, so that the bucket can be patched to point to the next. (defun dma-buffer-add-buckets ((dma-buf dma-buffer) (count int)) "Add count buckets to the dma buffer. Each bucket is initialized empty." diff --git a/goal_src/engine/dma/dma-buffer.gc b/goal_src/engine/dma/dma-buffer.gc index a71009fbd..19e4c8667 100644 --- a/goal_src/engine/dma/dma-buffer.gc +++ b/goal_src/engine/dma/dma-buffer.gc @@ -117,7 +117,7 @@ (defun dma-buffer-add-vu-function ((dma-buf dma-buffer) (vu-func vu-function) (arg2 int)) "Add DMA chain instructions to load the given VU function to VU program memory. The destination address in VU memory is specified inside of the vu-function. - if arg2 = 0, then use FLUSHE, otherwise use FLUSHA, I think the runs _before_ the program upload. + if arg2 = 0, then use FLUSHE, otherwise use FLUSHA, I think it runs _before_ the program upload. Should run with TTE." (local-vars (func-ptr uint) diff --git a/goal_src/engine/dma/dma.gc b/goal_src/engine/dma/dma.gc index 27a0e8611..891f94cd3 100644 --- a/goal_src/engine/dma/dma.gc +++ b/goal_src/engine/dma/dma.gc @@ -59,21 +59,21 @@ Like dma-send-no-scratch, this sets chcr to zero, which may be undesirable." (dma-sync (the-as pointer arg0) 0 0) (flush-cache 0) - ;;(.sync.l) + (.sync.l) (set! (-> arg0 madr) (logior (logand #xfffffff (the-as int madr)) ;; lower 28 bits are untouched ;; if we are transferring to the scratchpad (at 70000000) ;; we should set bit 31 in madr, per the manual. (if (= (logand #x70000000 (the-as int madr)) #x70000000) - (shl 32768 16) ;; set bit 31 + (shl #x8000 16) ;; set bit 31 0) ) ) (set! (-> arg0 qwc) qwc) - ;(.sync.l) + (.sync.l) ;; set str! (set! (-> arg0 chcr) (new 'static 'dma-chcr :str 1)) - ;(.sync.l) + (.sync.l) (none) ) @@ -81,17 +81,17 @@ "Send DMA! tadr should be a tag address, possibly in spad ram." (dma-sync (the-as pointer arg0) 0 0) (flush-cache 0) - ;(.sync.l) + (.sync.l) (set! (-> arg0 qwc) 0) ;; adjust address (set! (-> arg0 tadr) - (logior (logand 268435455 (the-as int tadr)) - (if (= (logand 1879048192 (the-as int tadr)) 1879048192) - (shl 32768 16) + (logior (logand #xfffffff (the-as int tadr)) + (if (= (logand #x70000000 (the-as int tadr)) #x70000000) + (shl #x8000 16) 0) ) ) - ;(.sync.l) + (.sync.l) ;;(set! (-> arg0 chcr) 325) (set! (-> arg0 chcr) (new 'static 'dma-chcr @@ -100,7 +100,7 @@ :tte 1 ;; send tags :str 1) ;; go! ) - ;(.sync.l) + (.sync.l) (none) ) @@ -108,19 +108,19 @@ "Send DMA chain! TTE bit is not set, don't transfer tags." (dma-sync (the-as pointer arg0) 0 0) (flush-cache 0) - ;;(.sync.l) + (.sync.l) (set! (-> arg0 qwc) 0) (set! (-> arg0 tadr) (logior - (logand 268435455 (the-as int arg1)) + (logand #xfffffff (the-as int arg1)) (the-as uint - (if (= (logand 1879048192 (the-as int arg1)) 1879048192) (shl 32768 16) 0) + (if (= (logand #x70000000 (the-as int arg1)) #x70000000) (shl #x8000 16) 0) ) ) ) - ;;(.sync.l) + (.sync.l) (set! (-> arg0 chcr) (new 'static 'dma-chcr :dir 1 ;; from memory @@ -128,7 +128,7 @@ :tte 0 ;; no tags :str 1) ;; go! ) - ;;(.sync.l) + (.sync.l) (none) ) @@ -141,14 +141,14 @@ (set! (-> arg0 tadr) (logior - (logand 268435455 (the-as int arg1)) + (logand #xfffffff (the-as int arg1)) (the-as uint - (if (= (logand 1879048192 (the-as int arg1)) 1879048192) (shl 32768 16) 0) + (if (= (logand #x70000000 (the-as int arg1)) #x70000000) (shl #x8000 16) 0) ) ) ) - ;;(.sync.l) + (.sync.l) ;;(set! (-> arg0 chcr) 325) (set! (-> arg0 chcr) (new 'static 'dma-chcr @@ -157,7 +157,7 @@ :tte 1 :str 1) ) - ;;(.sync.l) + (.sync.l) (set! v0-1 0) (none) ) @@ -169,12 +169,12 @@ (dma-sync (the-as pointer s5-0) 0 0) (flush-cache 0) (.sync.l) - (set! (-> s5-0 madr) (logand #xFFFFFFF (the-as int madr))) - (set! (-> s5-0 sadr) (logand #xFFFFFFF (the-as int sadr))) + (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) + (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) (set! (-> s5-0 qwc) qwc) - ;;(.sync.l) + (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str 1)) - ;;(.sync.l) + (.sync.l) (if sync (dma-sync (the-as pointer s5-0) 0 0)) (none) @@ -185,13 +185,13 @@ (local-vars (s5-0 dma-bank-spr)) (set! s5-0 SPR_TO_BANK) (dma-sync (the-as pointer s5-0) 0 0) - ;;(.sync.l) - (set! (-> s5-0 madr) (logand 268435455 (the-as int madr))) - (set! (-> s5-0 sadr) (logand 268435455 (the-as int sadr))) + (.sync.l) + (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) + (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) (set! (-> s5-0 qwc) qwc) - ;;(.sync.l) + (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str 1)) - ;;(.sync.l) + (.sync.l) (if sync (dma-sync (the-as pointer s5-0) 0 0)) (none) ) @@ -202,13 +202,13 @@ (set! s5-0 SPR_FROM_BANK) (dma-sync (the-as pointer s5-0) 0 0) (flush-cache 0) - ;;(.sync.l) - (set! (-> s5-0 madr) (logand 268435455 (the-as int madr))) - (set! (-> s5-0 sadr) (logand 268435455 (the-as int sadr))) + (.sync.l) + (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) + (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) (set! (-> s5-0 qwc) qwc) - ;;(.sync.l) + (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str 1)) - ;;(.sync.l) + (.sync.l) (if sync (dma-sync (the-as pointer s5-0) 0 0)) (none) ) @@ -218,13 +218,13 @@ (local-vars (s5-0 dma-bank-spr)) (set! s5-0 SPR_FROM_BANK) (dma-sync (the-as pointer s5-0) 0 0) - ;;(.sync.l) - (set! (-> s5-0 madr) (logand 268435455 (the-as int madr))) - (set! (-> s5-0 sadr) (logand 268435455 (the-as int sadr))) + (.sync.l) + (set! (-> s5-0 madr) (logand #xfffffff (the-as int madr))) + (set! (-> s5-0 sadr) (logand #xfffffff (the-as int sadr))) (set! (-> s5-0 qwc) qwc) - ;;(.sync.l) + (.sync.l) (set! (-> s5-0 chcr) (new 'static 'dma-chcr :str 1)) - ;;(.sync.l) + (.sync.l) (if sync (dma-sync (the-as pointer s5-0) 0 0)) (none) ) @@ -264,7 +264,7 @@ (defun clear-vu1-mem () "Clear the data memory of VU1, filling it with abadbeef - This uses the slow memory mapping of VU0's data memory at 0x11004000" + This uses the slow memory mapping of VU1's data memory at 0x1100C000" (local-vars (v1-0 (pointer uint32)) (a0-0 int) @@ -371,15 +371,15 @@ ) (set! qwc-remaining (- qwc-remaining (the-as uint qwc-transferred-now))) - ;;(.sync.l) + (.sync.l) ;; set up dma (set! (-> spr-to-bank madr) (the uint src)) (set! (-> spr-to-bank sadr) 0) (set! (-> spr-to-bank qwc) qwc-transferred-now) - ;;(.sync.l) + (.sync.l) ;; start dma (set! (-> spr-to-bank chcr) (new 'static 'dma-chcr :str 1)) - ;;(.sync.l) + (.sync.l) ;; sync (dma-sync (the-as pointer spr-to-bank) 0 0) @@ -391,9 +391,9 @@ (set! (-> spr-from-bank sadr) 0) (set! (-> spr-from-bank qwc) qwc-transferred-now) ;; transfer! - ;;(.sync.l) + (.sync.l) (set! (-> spr-from-bank chcr) (new 'static 'dma-chcr :str 1)) - ;;(.sync.l) + (.sync.l) ;; sync! (dma-sync (the-as pointer spr-from-bank) 0 0) ;; advance dst. diff --git a/goal_src/engine/ps2/timer-h.gc b/goal_src/engine/ps2/timer-h.gc index 7879cc916..0aecd8206 100644 --- a/goal_src/engine/ps2/timer-h.gc +++ b/goal_src/engine/ps2/timer-h.gc @@ -14,19 +14,27 @@ ;; this matches the Tn_MODE register structure of the ps2 EE timers. ;; Only the lower 32 bits of these registers are usable, and the upper 16 hardwired to zero -;; TODO : define constants for these bitfields? (deftype timer-mode (uint32) - (;(data uint32 :offset 0 :size 32) + (;; clock selection: + ;; 0: BUSCLK + ;; 1: BUSCLK/16 + ;; 2: BUSCLK/256 + ;; 3: hblank (clks uint8 :offset 0 :size 2) - (gate uint8 :offset 2 :size 1) - (gats uint8 :offset 3 :size 1) + (gate uint8 :offset 2 :size 1) ;; gate function enable + (gats uint8 :offset 3 :size 1) ;; gate selection: 0 = hblank, 1 = vblank + ;; gate mode: + ;; 0: count while gate signal is low + ;; 1: start when gate signal rises + ;; 2: start when gate signal falls + ;; 3: start when gate signal rises/falls (gatm uint8 :offset 4 :size 2) - (zret uint8 :offset 6 :size 1) - (cue uint8 :offset 7 :size 1) - (cmpe uint8 :offset 8 :size 1) - (ovfe uint8 :offset 9 :size 1) - (equf uint8 :offset 10 :size 1) - (ovff uint8 :offset 11 :size 1) + (zret uint8 :offset 6 :size 1) ;; zero return: clear counter when equal to reference value + (cue uint8 :offset 7 :size 1) ;; count-up enable + (cmpe uint8 :offset 8 :size 1) ;; compare-interrupt enable + (ovfe uint8 :offset 9 :size 1) ;; overflow-interrupt enable + (equf uint8 :offset 10 :size 1) ;; equal-flag + (ovff uint8 :offset 11 :size 1) ;; overflow-flag ) :method-count-assert 9 :size-assert #x4 diff --git a/goal_src/engine/ps2/timer.gc b/goal_src/engine/ps2/timer.gc index 956082fb7..78ac37c83 100644 --- a/goal_src/engine/ps2/timer.gc +++ b/goal_src/engine/ps2/timer.gc @@ -5,16 +5,6 @@ ;; name in dgo: timer ;; dgos: GAME, ENGINE -;; Sneakily disable these instructions for readibility (remove this later) -;; SYNC is an EE instruction that waits for various memory access to be completed -;; (this might not be necessary for x86_64) -(defmacro .sync.l () `(none)) -(defmacro .sync.p () `(none)) -;; Copies the contents of a cop0 (system control) register to a gpr -(defmacro .mfc0 (dest src) `(none)) -;; Copies the contents of a gpr to a cop0 (system control) register -(defmacro .mtc0 (dest src) `(none)) - (defun timer-reset ((timer timer-bank)) "Reset a timer's counter to zero" @@ -63,7 +53,6 @@ "Init a stopwatch" (set! (-> obj begin-level) 0) (set! (-> obj prev-time-elapsed) 0) - (none) ) @@ -76,7 +65,6 @@ (set! (-> obj start-time) count) ) ) - (none) ) (defun stopwatch-start ((obj stopwatch)) @@ -88,7 +76,6 @@ (set! (-> obj start-time) count) ) ) - (none) ) (defun stopwatch-stop ((obj stopwatch)) @@ -97,16 +84,15 @@ (set! (-> obj begin-level) 0) (let ((count 0)) (let ((count 0)) - (.mfc0 count Count) ; wrong register? a typo in a rlet? who knows. + (.mfc0 count Count) ;; wrong register? a typo in a rlet? who knows. (+! (-> obj prev-time-elapsed) (- count (-> obj start-time))) ) ) ) - (none) ) (defun stopwatch-begin ((obj stopwatch)) - "Begin a stopwatch layer. Starts the stopwatch if it has not yet begun" + "Begin a stopwatch level, and starts it if it hasn't yet" (when (zero? (-> obj begin-level)) (let ((count 0)) (.mfc0 count Count) @@ -114,12 +100,12 @@ ) ) (+! (-> obj begin-level) 1) - (none) ) -;; NOTE : there is no guard against ending a stopwatch too many times! (defun stopwatch-end ((obj stopwatch)) - "End a stopwatch layer. Stops the stopwatch if it has ended as many times as it has begun" + "End a stopwatch level. Stops the stopwatch if it's back to level zero. + There is no guard against ending a stopwatch too many times, and a negative level + will cause errors!" (+! (-> obj begin-level) -1) (when (zero? (-> obj begin-level)) (set! (-> obj begin-level) 0) @@ -128,17 +114,16 @@ (+! (-> obj prev-time-elapsed) (- count (-> obj start-time))) ) ) - (none) ) (defun stopwatch-elapsed-ticks ((obj stopwatch)) "Returns the elapsed time so far (in clock cycles) of a stopwatch" (let ((elapsed (-> obj prev-time-elapsed))) (when (> (-> obj begin-level) 0) - (let ((count 0)) + (let ((count (the uint 0))) (.mfc0 count Count) (+! elapsed (- count (-> obj start-time))) - ;(set! count elapsed) ;; ?? + (set! count elapsed) ;; ?? ) ) elapsed diff --git a/goal_src/goal-lib.gc b/goal_src/goal-lib.gc index 5b5897e23..e60565ac0 100644 --- a/goal_src/goal-lib.gc +++ b/goal_src/goal-lib.gc @@ -498,3 +498,16 @@ (defmacro <0.si (a) `(< (the-as int ,a) (the-as int 0)) ) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; (Fake) MIPS Macros +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; these are macros for MIPS instructions which we may want to keep in the source code for +;; readibility/curiosity/documentation, but will not translate into any actual instructions at all + +;; A macro that generates a macro for the specified instruction +(defmacro fake-asm (asm-name &rest args) + `(defmacro ,asm-name (,@args) `(none)) + ) diff --git a/goal_src/kernel/gcommon.gc b/goal_src/kernel/gcommon.gc index ac19e45ed..a40fcf83b 100644 --- a/goal_src/kernel/gcommon.gc +++ b/goal_src/kernel/gcommon.gc @@ -1371,3 +1371,15 @@ ) ) ) + + +(#when PC_PORT + ;; SYNC is an EE instruction that waits for various memory access and DMA to be completed + ;; DMA will be instant in the PC port, so these are no longer necessary + (fake-asm .sync.l) + (fake-asm .sync.p) + ;; Copies the contents of a cop0 (system control) register to a gpr + (fake-asm .mfc0 dest src) + ;; Copies the contents of a gpr to a cop0 (system control) register + (fake-asm .mtc0 dest src) + )