[jak3] dma, dma-bucket, dma-buffer (#3331)

This commit is contained in:
water111
2024-01-27 11:44:08 -05:00
committed by GitHub
parent f045e6cef1
commit 4bd5111280
12 changed files with 809 additions and 46 deletions
+61 -40
View File
@@ -4215,35 +4215,36 @@
;; dma ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (define-extern dma-sync-hang function) ;; (function dma-bank none)
;; (define-extern dma-sync-crash function) ;; (function dma-bank none)
;; (define-extern dma-send function) ;; (function dma-bank uint uint none)
;; (define-extern dma-send-chain function) ;; (function dma-bank-source uint none)
;; (define-extern dma-send-chain-no-tte function) ;; (function dma-bank-source uint none)
;; (define-extern dma-send-chain-no-flush function) ;; (function dma-bank-source uint none)
;; (define-extern dma-send-to-spr function) ;; (function uint uint uint symbol none)
;; (define-extern dma-send-to-spr-no-flush function) ;; (function uint uint uint symbol none)
;; (define-extern dma-send-from-spr function) ;; (function uint uint uint symbol none)
;; (define-extern dma-send-from-spr-no-flush function) ;; (function uint uint uint symbol none)
;; (define-extern dma-initialize function) ;; (function none)
;; (define-extern clear-vu0-mem function) ;; (function none)
;; (define-extern clear-vu1-mem function) ;; (function none)
;; (define-extern dump-vu1-mem function) ;; (function none)
;; (define-extern dump-vu1-range function) ;; (function uint uint symbol)
;; (define-extern reset-vif1-path function) ;; (function none)
;; (define-extern ultimate-memcpy function) ;; (function pointer pointer uint none)
;; (define-extern symlink2 function) ;; (function none)
;; (define-extern symlink3 function) ;; (function none)
(define-extern dma-sync-hang (function dma-bank none))
(define-extern dma-sync-crash (function dma-bank none))
(define-extern dma-send (function dma-bank uint uint none))
(define-extern dma-send-chain (function dma-bank-source uint none))
(define-extern dma-send-chain-no-tte (function dma-bank-source uint none))
(define-extern dma-send-chain-no-flush (function dma-bank-source uint none))
(define-extern dma-send-to-spr (function uint uint uint symbol none))
(define-extern dma-send-to-spr-no-flush (function uint uint uint symbol none))
(define-extern dma-send-from-spr (function uint uint uint symbol none))
(define-extern dma-send-from-spr-no-flush (function uint uint uint symbol none))
(define-extern dma-initialize (function none))
(define-extern clear-vu0-mem (function none))
(define-extern clear-vu1-mem (function none))
(define-extern dump-vu1-mem (function none))
(define-extern dump-vu1-range (function uint uint symbol))
(define-extern reset-vif1-path (function none))
(define-extern ultimate-memcpy (function pointer pointer uint none))
(define-extern symlink2 (function none))
(define-extern symlink3 (function none))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dma-buffer ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(deftype dma-packet (structure)
((dma dma-tag :offset-assert 0) ;; dma-tag
"The header for a DMA transfer, containing an DMA tag, and VIF tags."
((dma dma-tag :offset-assert 0)
(vif0 vif-tag :offset-assert 8) ;; guessed by decompiler
(vif1 vif-tag :offset-assert 12) ;; guessed by decompiler
(quad uint128 :offset 0)
(quad uint128 :offset-assert 0 :overlay-at dma)
)
:method-count-assert 9
:size-assert #x10
@@ -4251,6 +4252,7 @@
)
(deftype dma-packet-array (inline-array-class)
"Unused dma array. Unclear how it should be used."
((data dma-packet :dynamic :offset-assert 16) ;; guessed by decompiler
)
:method-count-assert 14
@@ -4259,8 +4261,9 @@
)
(deftype dma-gif (structure)
"Believed unused GIF header type."
((gif uint64 2 :offset-assert 0) ;; guessed by decompiler
(quad uint128 :offset 0)
(quad uint128 :offset-assert 0 :overlay-at gif)
)
:method-count-assert 9
:size-assert #x10
@@ -4268,9 +4271,10 @@
)
(deftype dma-gif-packet (structure)
"The header for a DMA transfer that goes directly to GIF, containing DMA, VIF, GIF tags."
((dma-vif dma-packet :inline :offset-assert 0)
(gif uint64 2 :offset-assert 16) ;; guessed by decompiler
(quad uint128 2 :offset 0) ;; guessed by decompiler
(quad uint128 2 :offset-assert 0 :overlay-at dma-vif) ;; guessed by decompiler
)
:method-count-assert 9
:size-assert #x20
@@ -4278,12 +4282,16 @@
)
(deftype dma-buffer (basic)
"A buffer for DMA data."
((allocated-length int32 :offset-assert 4)
(base pointer :offset-assert 8) ;; guessed by decompiler
(end pointer :offset-assert 12) ;; guessed by decompiler
(real-buffer-end int32 :offset-assert 16)
(data uint64 1 :offset 32) ;; guessed by decompiler
)
(:methods
(new "Allocate a DMA buffer to hold the given size" (symbol type int) _type_) ;; 0
)
:method-count-assert 9
:size-assert #x28
:flag-assert #x900000028
@@ -4292,20 +4300,33 @@
)
)
;; (define-extern dma-buffer-inplace-new function) ;; (function dma-buffer int dma-buffer)
;; (define-extern dma-buffer-length function) ;; (function dma-buffer int)
;; (define-extern dma-buffer-free function) ;; (function dma-buffer int)
;; (define-extern dma-buffer-add-vu-function function) ;; (function dma-buffer vu-function int symbol)
;; (define-extern dma-buffer-send function) ;; (function dma-bank dma-buffer none)
;; (define-extern dma-buffer-send-chain function) ;; (function dma-bank-source dma-buffer none)
(define-extern dma-buffer-inplace-new
"Create a dma-buffer in-place. Does not set the type of the dma-buffer object."
(function dma-buffer int dma-buffer))
(define-extern dma-buffer-length
"Get length used in quadwords, rounded up."
(function dma-buffer int))
(define-extern dma-buffer-free
"Get the number of free quadwords between base and end pointers."
(function dma-buffer int))
(define-extern dma-buffer-add-vu-function
"Add DMA tags to load the given VU function. The destination in vu instruction memory
is specific inside the vu-function. This does NOT copy the vu-function into the buffer,
but creates a reference to the existing VU function." (function dma-buffer vu-function int symbol))
(define-extern dma-buffer-send
"Send the DMA buffer! DOES NOT TRANSFER TAG, you probably want dma-buffer-send-chain instead."
(function dma-bank dma-buffer none))
(define-extern dma-buffer-send-chain
"Send the DMA buffer! Sends the tags, so this is suitable for the main graphics chain."
(function dma-bank-source dma-buffer none))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dma-bucket ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (define-extern dma-buffer-add-buckets function) ;; (function dma-buffer int (inline-array dma-bucket))
;; (define-extern dma-buffer-patch-buckets function) ;; (function (inline-array dma-bucket) int (inline-array dma-bucket))
;; (define-extern dma-bucket-insert-tag function) ;; (function (inline-array dma-bucket) bucket-id pointer (pointer dma-tag) pointer)
(define-extern dma-buffer-add-buckets "Initialize an array of dma-buckets in a DMA buffer." (function dma-buffer int (inline-array dma-bucket)))
(define-extern dma-buffer-patch-buckets "Patch together DMA buckets after they have been filled." (function dma-bucket int dma-bucket))
(define-extern dma-bucket-insert-tag "Add a dma chain to the bucket." (function (inline-array dma-bucket) bucket-id pointer (pointer dma-tag) pointer))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; dma-disasm ;;
@@ -4464,7 +4485,7 @@
:size-assert #x10
:flag-assert #x900000010
(:methods
(new
(new
"Create a cpad-list for 2 controllers. It's fine to do this even if one or both controllers
aren't connected yet."
(symbol type) _type_) ;; 0
@@ -5519,7 +5540,7 @@
and arg2 is down (-y). Will have the pitch of forward."
(function matrix vector vector matrix))
(define-extern forward-down-nopitch->inv-matrix
"Create a matrix representing an inverse transform where arg1 is forward (+z)
"Create a matrix representing an inverse transform where arg1 is forward (+z)
and arg2 is down (-y). Will not use the pitch of forward."
(function matrix vector vector matrix))
(define-extern forward-up->inv-matrix
@@ -7712,7 +7733,7 @@
"The math-camera matrices are used to compute fogging values, which are a per-vertex uint8 that
tells the GS how 'foggy' the color should be. This should be proportional to how far away the vertex
is. There is a scaling factor applied so the fog intensity isn't affected by the field of view angle.
The fog-corrector stores a fog-end fog-start value that is corrected for the field of view.
The actual correction factor is computed in cam-update.gc.
Without this corrector, the fogginess of the world would change as the FOV changes
@@ -8151,7 +8172,7 @@
(deftype connectable (structure)
"A connectable is the linked-list node part of a connection.
The connections themselves are owned by the engine.
The `next0`/`prev0` references are used for how this belongs in the connectable list
belonging to the [[engine]]. These terminate on special nodes stored in the engine:
`alive-list`/`alive-list-end` for the active connections, and `dead-list`/`dead-list-end`
@@ -8244,7 +8265,7 @@
"Add a connection between this engine and a given process."
(engine process object object object object) connection) ;; 15
(remove-from-process "Remove all connections from process for this engine." (engine process) int) ;; 16
(remove-matching
(remove-matching
"Call the given function on each connection and the engine.
If it returns truthy, `move-to-dead` that connection."
(engine (function connection engine symbol)) int) ;; 17
@@ -11167,7 +11188,7 @@
;; (define-extern *stats-bsp* object) ;; symbol
;; (define-extern *stats-buffer* object) ;; symbol
;; (define-extern *stats-target* object) ;; symbol
;; (define-extern *stats-profile-bars* object) ;; symbol
(define-extern *stats-profile-bars* symbol)
;; (define-extern *stats-perf* object) ;; symbol
;; (define-extern *artist-all-visible* object) ;; symbol
;; (define-extern *artist-flip-visible* object) ;; symbol
@@ -11175,7 +11196,7 @@
;; (define-extern *artist-fix-frustum* object) ;; symbol
;; (define-extern *artist-error-spheres* object) ;; symbol
;; (define-extern *artist-use-menu-subdiv* object) ;; symbol
;; (define-extern *display-profile* object) ;; symbol
(define-extern *display-profile* symbol)
;; (define-extern *display-sidekick-stats* object) ;; symbol
;; (define-extern *display-quad-stats* object) ;; symbol
;; (define-extern *display-tri-stats* object) ;; symbol
@@ -11211,7 +11232,7 @@
;; (define-extern *display-sprite-marks* object) ;; symbol
;; (define-extern *display-sprite-spheres* object) ;; symbol
;; (define-extern *display-entity-errors* object) ;; symbol
;; (define-extern *display-capture-mode* object)
(define-extern *display-capture-mode* symbol)
;; (define-extern *display-instance-info* object) ;; symbol
;; (define-extern *display-deci-count* object) ;; symbol
;; (define-extern *sync-dma* object) ;; symbol
@@ -197,5 +197,20 @@
[96, "t2", "(pointer gs-xyzf)"],
[97, "t2", "(pointer uint64)"],
[[110, 117], "v1", "(pointer uint64)"]
],
"dma-bucket-insert-tag": [
[[2, 6], "v1", "dma-bucket"],
[3, "a0", "dma-bucket"]
],
"dma-buffer-add-buckets": [
[[1, 4], "v1", "dma-bucket"],
[5, "v1", "pointer"],
[[9, 11], "v1", "dma-bucket"],
[11, "v1", "pointer"]
],
"dma-buffer-patch-buckets": [
[[3, 34], "a0", "dma-bucket"],
[[34, 38], "a0", "dma-packet"]
// [34, "a0", "(inline-array dma-bucket)"]
]
}
@@ -458,5 +458,35 @@
"vars": {
"gp-0": "mouse"
}
},
"(method 0 dma-buffer)": {
"args": ["allocation", "type-to-make", "size-bytes"]
},
"dma-buffer-inplace-new": {
"args": ["dma-buff", "size-bytes"]
},
"dma-buffer-length": {
"args": ["dma-buf"]
},
"dma-buffer-free": {
"args": ["dma-buf"]
},
"dma-buffer-add-vu-function": {
"args": ["dma-buf", "vu-func", "flush-path-3"]
},
"dma-buffer-send": {
"args": ["chan", "buf"]
},
"dma-buffer-send-chain": {
"args": ["chan", "buf"]
},
"dma-buffer-patch-buckets": {
"args": ["base", "count"]
},
"dma-buffer-add-buckets": {
"args": ["dma-buf", "bucket-count"]
},
"dma-bucket-insert-tag": {
"args": ["buckets", "bucket", "start-tag", "end-tag-to-patch"]
}
}
+60
View File
@@ -7,3 +7,63 @@
;; DECOMP BEGINS
;; WARN: Return type mismatch pointer vs (inline-array dma-bucket).
(defun dma-buffer-add-buckets ((dma-buf dma-buffer) (bucket-count int))
"Initialize an array of dma-buckets in a DMA buffer."
(let ((v0-0 (-> dma-buf base)))
(let ((v1-0 (the-as object v0-0)))
(dotimes (a2-0 bucket-count)
(set! (-> (the-as dma-bucket v1-0) tag)
(new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int (&+ (the-as pointer v1-0) 16)))
)
(set! (-> (the-as dma-bucket v1-0) last) (the-as (pointer dma-tag) v1-0))
(set! v1-0 (&+ (the-as pointer v1-0) 16))
)
(set! (-> dma-buf base) (the-as pointer v1-0))
)
(the-as (inline-array dma-bucket) v0-0)
)
)
(defun dma-buffer-patch-buckets ((base dma-bucket) (count int))
"Patch together DMA buckets after they have been filled."
(when (nonzero? base)
(dotimes (v1-1 count)
(cond
((= base (-> base last))
(set! (-> base tag) (new 'static 'dma-tag :id (dma-tag-id cnt)))
(set! (-> base clear) (the-as uint 0))
0
)
(else
(set! (-> base last 0 addr) (the-as int (&+ base 16)))
(cond
((and (or *display-profile* *stats-profile-bars*) (not *display-capture-mode*))
(set! (-> (the-as dma-packet base) vif0) (new 'static 'vif-tag :cmd (vif-cmd mark) :imm v1-1))
(set! (-> (the-as dma-packet base) vif1) (new 'static 'vif-tag :irq #x1))
)
(else
(set! (-> base clear) (the-as uint 0))
0
)
)
)
)
(&+! base 16)
)
)
base
)
(defun dma-bucket-insert-tag ((buckets (inline-array dma-bucket))
(bucket bucket-id)
(start-tag pointer)
(end-tag-to-patch (pointer dma-tag))
)
"Add a dma chain to the bucket."
(let ((v1-1 (-> buckets bucket)))
(set! (-> (the-as dma-bucket (-> v1-1 last)) next) (the-as uint start-tag))
(set! (-> v1-1 last) end-tag-to-patch)
)
start-tag
)
+167
View File
@@ -205,6 +205,79 @@
)
)
(defmacro with-cnt-vif-block (bindings &rest body)
"Start a cnt w/ vif direct to gif dma packet setup for the dma-buffer in bindings.
With this, you can transfer data through PATH2 without having to setup the tag yourself.
The qwc of the transfer is determined at runtime at the end of this block."
(let ((buf (first bindings)))
(with-gensyms (buf-start buf-qwc)
`(let ((,buf-start (-> ,buf base)))
;; setup the dmatag for PATH2 transfer, qwc is 0 (patched later)
(dma-buffer-add-cnt-vif2 ,buf 0
(new 'static 'vif-tag :cmd (vif-cmd nop))
(new 'static 'vif-tag :cmd (vif-cmd direct))
)
;; things with this buffer!
,@body
;; patch qwc! just do the difference between the current ptr and the old one and turn it into qwords.
;; we take one qword out because it's the initial dmatag which isnt part of the count.
;; this rounds *down*, so make sure to fill the buffer in 128-bit boundaries.
(let ((,buf-qwc (/ (+ (&- -16 ,buf-start) (the int (-> ,buf base))) 16)))
(cond
((nonzero? ,buf-qwc) ;; stuff was added to the buffer
;; patch the DMA tag
(logior! (-> (the-as (pointer dma-tag) ,buf-start) 0) (the-as uint (new 'static 'dma-tag :qwc ,buf-qwc)))
;; patch the 2nd vifcode's imm field (qwc)
(logior! (-> (the-as (pointer dma-tag) ,buf-start) 1) (the-as uint (shl (shr (shl ,buf-qwc 48) 48) 32)))
)
(else ;; nothing was added to the buffer. delete the dmatag, you cannot transfer 0 qwords.
(set! (-> ,buf base) ,buf-start)
)
)
)
)
))
)
(defmacro with-cnt-vif-block-qwc (bindings &rest body)
"Start a cnt w/ vif direct to gif dma packet setup for the dma-buffer in bindings.
With this, you can transfer data through PATH2 without having to setup the tag yourself.
The qwc of the transfer is determined at runtime at the end of this block.
WARNING: You MUST guarantee that the resulting qwc is NOT zero!"
(let ((buf (first bindings)))
(with-gensyms (buf-start buf-qwc)
`(let ((,buf-start (the-as dma-packet (-> ,buf base))))
;; dmatag will be added at the end so we reserve
(&+! (-> ,buf base) 16)
;; setup the dmatag for PATH2 transfer, qwc is 0 (patched later)
(dma-buffer-add-cnt-vif2 ,buf 0
(new 'static 'vif-tag :cmd (vif-cmd nop))
(new 'static 'vif-tag :cmd (vif-cmd direct))
)
;; things with this buffer!
,@body
;; we make the dmatag now! its at the start.
(let ((,buf-qwc (/ (+ (- -16 (the-as int ,buf-start)) (the-as int (-> ,buf base))) 16)))
(set! (-> ,buf-start dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc ,buf-qwc))
(set! (-> ,buf-start vif0) (new 'static 'vif-tag))
(set! (-> ,buf-start vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1 :imm ,buf-qwc))
)
)
))
)
(defmacro with-dma-bucket (bindings &rest body)
"Start a new dma-bucket in body that will be finished at the end.
The bindings are the dma-buffer, dma-bucket and bucket-id respectively."
@@ -257,6 +330,7 @@
;; DECOMP BEGINS
(deftype dma-packet (structure)
"The header for a DMA transfer, containing an DMA tag, and VIF tags."
((dma dma-tag)
(vif0 vif-tag)
(vif1 vif-tag)
@@ -266,6 +340,7 @@
(deftype dma-packet-array (inline-array-class)
"Unused dma array. Unclear how it should be used."
((data dma-packet :dynamic)
)
)
@@ -274,6 +349,7 @@
(set! (-> dma-packet-array heap-base) (the-as uint 16))
(deftype dma-gif (structure)
"Believed unused GIF header type."
((gif uint64 2)
(quad uint128 :overlay-at (-> gif 0))
)
@@ -281,6 +357,7 @@
(deftype dma-gif-packet (structure)
"The header for a DMA transfer that goes directly to GIF, containing DMA, VIF, GIF tags."
((dma-vif dma-packet :inline)
(gif uint64 2)
(quad uint128 2 :overlay-at (-> dma-vif dma))
@@ -289,6 +366,7 @@
(deftype dma-buffer (basic)
"A buffer for DMA data."
((allocated-length int32)
(base pointer)
(end pointer)
@@ -300,3 +378,92 @@
)
)
(defmethod new dma-buffer ((allocation symbol) (type-to-make type) (size-bytes int))
"Allocate a DMA buffer to hold the given size"
(let ((v0-0 (object-new allocation type-to-make (+ size-bytes -4 (-> type-to-make size)))))
(set! (-> v0-0 base) (-> v0-0 data))
(set! (-> v0-0 allocated-length) size-bytes)
(set! (-> v0-0 real-buffer-end) (the-as int (&+ (-> v0-0 data) size-bytes)))
v0-0
)
)
(defun dma-buffer-inplace-new ((dma-buff dma-buffer) (size-bytes int))
"Create a dma-buffer in-place. Does not set the type of the dma-buffer object."
(set! (-> dma-buff base) (-> dma-buff data))
(set! (-> dma-buff allocated-length) size-bytes)
dma-buff
)
(defmethod length ((this dma-buffer))
(-> this allocated-length)
)
(defmethod asize-of ((this dma-buffer))
(+ (-> this allocated-length) -4 (-> dma-buffer size))
)
(defun dma-buffer-length ((dma-buf dma-buffer))
"Get length used in quadwords, rounded up."
(shr (+ (&- (-> dma-buf base) (the-as uint (-> dma-buf data))) 15) 4)
)
(defun dma-buffer-free ((dma-buf dma-buffer))
"Get the number of free quadwords between base and end pointers."
(shr (+ (&- (-> dma-buf end) (the-as uint (-> dma-buf base))) 15) 4)
)
;; ERROR: Failed store: (s.w! (+ t2-0 8) t3-5) at op 23
;; ERROR: Failed store: (s.w! (+ t2-0 12) t3-8) at op 32
(defun dma-buffer-add-vu-function ((dma-buf dma-buffer) (vu-func vu-function) (flush-path-3 int))
"Add DMA tags to load the given VU function. The destination in vu instruction memory
is specific inside the vu-function. This does NOT copy the vu-function into the buffer,
but creates a reference to the existing VU function."
;; The first 4 bytes of a vu-function object's data are discarded because they aren't aligned.
(let ((func-ptr (the-as pointer (&-> vu-func data 4)))
(qlen (-> vu-func qlength)) ;; number of quadwords
(origin (-> vu-func origin)) ;; destination address in VU instruction memory.
)
;; loop until whole program is transferred.
(while (> qlen 0)
;; transfer up to 127 quadwords at a single time.
(let ((qwc-now (min 127 qlen)))
;; Set up DMA to transfer the data from the vu-function
;; ref id = reference to data outside of the buffer.
(dma-buffer-add-ref-vif2 dma-buf qwc-now func-ptr
;; Set up first vifcode as a flush.
(new 'static 'vif-tag :cmd (if (zero? flush-path-3) (vif-cmd flushe) (vif-cmd flusha)))
;; next vifcode, transfer microprogram. This is in 64-bit units (VU instructions)
(new 'static 'vif-tag :cmd (vif-cmd mpg) :num (shl qwc-now 1) :imm origin)
)
;; increment by qwc-now quadwords.
(&+! func-ptr (shl qwc-now 4))
(set! qlen (- qlen qwc-now))
(+! origin (shl qwc-now 1))
)
)
)
#f
)
(defun dma-buffer-send ((chan dma-bank) (buf dma-buffer))
"Send the DMA buffer! DOES NOT TRANSFER TAG, you probably want dma-buffer-send-chain instead."
(when (< (-> buf allocated-length) (&- (-> buf base) (the-as uint (-> buf data))))
(crash!)
0
)
(dma-send chan (the-as uint (-> buf data)) (the-as uint (dma-buffer-length buf)))
(none)
)
(defun dma-buffer-send-chain ((chan dma-bank-source) (buf dma-buffer))
"Send the DMA buffer! Sends the tags, so this is suitable for the main graphics chain."
(when (< (-> buf allocated-length) (&- (-> buf base) (the-as uint (-> buf data))))
(crash!)
0
)
(dma-send-chain chan (the-as uint (-> buf data)))
(none)
)
+154
View File
@@ -7,3 +7,157 @@
;; DECOMP BEGINS
(defun dma-sync-hang ((bank dma-bank))
"Hang here until the dma transfer is completed.
This is worse than the dma-sync-fast because it ends
up spamming the DMA bank register more often, and reduces
the speed of the DMA transfer.
This function is unused."
(crash!)
(none)
)
(defun dma-sync-crash ((arg0 dma-bank))
"Wait for DMA to finish for a while, then crash if we can't.
This function is unused."
(crash!)
(none)
)
(defun dma-send ((arg0 dma-bank) (madr uint) (qwc uint))
"Send DMA given an address and a quadword count.
The madr can be in main memory or scratchpad.
This is appropriate for VIF0/GIF transfers.
It can be used for VIF1, but will do VIF -> madr, which is probably
not what you want."
(crash!)
(none)
)
(defun dma-send-chain ((arg0 dma-bank-source) (tadr uint))
"Send DMA! tadr should be a tag address, possibly in spad ram.
This is useful for sending to VIF.
Tag transfer is enabled, and DIR is set so a VIF1 transfer
goes from tadr -> VIF."
(crash!)
(none)
)
(defun dma-send-chain-no-tte ((arg0 dma-bank-source) (arg1 uint))
"Send DMA chain! TTE bit is not set, don't transfer tags.
This is never used."
(crash!)
(none)
)
(defun dma-send-chain-no-flush ((arg0 dma-bank-source) (arg1 uint))
"Send DMA chain! But don't flush the cache, so be careful here. TTE enable."
(crash!)
(none)
)
(defun dma-send-to-spr ((sadr uint) (madr uint) (qwc uint) (sync symbol))
"Transfer data to spr"
(crash!)
(none)
)
(defun dma-send-to-spr-no-flush ((sadr uint) (madr uint) (qwc uint) (sync symbol))
"Transfer to spr. Doesn't flush the cache first, so be careful."
(crash!)
(none)
)
(defun dma-send-from-spr ((madr uint) (sadr uint) (qwc uint) (sync symbol))
"Transfer from spr."
(crash!)
(none)
)
(defun dma-send-from-spr-no-flush ((madr uint) (sadr uint) (qwc uint) (sync symbol))
"Transfer from spr, don't flush the cache."
(crash!)
(none)
)
(defun dma-initialize ()
"Due to a bug in the PS2 hardware, you must always disable the DMAtag mismatch
error. This is done here."
(#when PC_PORT
(return 0)
)
(set! (-> (the-as vif-bank #x10003800) err me0) 1)
(set! (-> (the-as vif-bank #x10003c00) err me0) 1)
(none)
)
(defun clear-vu0-mem ()
"Set the vu0 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory.
Will crash on PC Port."
(crash!)
(none)
)
(defun clear-vu1-mem ()
"Set the vu1 data memory to 0xabadbeef. This uses the slow EE mapping of VU memory.
Will crash on PC Port."
(crash!)
(none)
)
(defun dump-vu1-mem ()
"Print VU1 memory to runtime stdout.
Will crash on PC Port."
(crash!)
(none)
)
(defun dump-vu1-range ((start uint) (total-count uint))
"Print part of VU1 memory to runtime stdout.
Will crash on PC Port."
(crash!)
#f
)
(defun reset-vif1-path ()
"When things go wrong, totally reset vif1."
(#unless PC_PORT
;; changed for jak 3! now prints to 0.
(format 0 "~`dma-bank-vif`I~`vif-bank`I" #x10009000 #x10003c00)
)
(reset-path)
(set-graphics-mode)
(format 0 "gkernel: vif1 path reset!~%")
(none)
)
(defun ultimate-memcpy ((dst pointer) (src pointer) (size-bytes uint))
"The Fastest Memory Copy, for larger transfers.
Memory is copied in ascending order, in 4 kB blocks.
The size should be a multiple of 16 bytes."
;; on PC Port, just call C mem-move, it's the fastest.
(__mem-move dst src size-bytes)
(none)
)
(defun symlink2 ()
"symlink2 is a handwritten assembly version of the v2 linking routine.
it is not ported because the OpenGOAL linker has its own implementation already."
(crash!)
(none)
)
(defun symlink3 ()
"symlink3 is a handwritten assembly version of the v3 linking routine.
OpenGOAL uses a different format for v3, customized for x86-64, so this is not
needed. The C++ implementation is plenty fast enough"
(crash!)
(none)
)
;; configuration required to work around hardware bug on the PS2.
;; doesn't do anything important
(dma-initialize)
+1
View File
@@ -5,6 +5,7 @@
;; name in dgo: video-h
;; dgos: GAME
(define-extern set-graphics-mode (function none))
(define-extern get-video-mode (function symbol))
;; DECOMP BEGINS
+3
View File
@@ -6,6 +6,9 @@
;; dgos: GAME
(declare-type dma-buffer structure)
(define-extern *display-profile* symbol)
(define-extern *stats-profile-bars* symbol)
(define-extern *display-capture-mode* symbol)
;; DECOMP BEGINS
+73
View File
@@ -0,0 +1,73 @@
;;-*-Lisp-*-
(in-package goal)
;; definition for function dma-buffer-add-buckets
;; WARN: Return type mismatch pointer vs (inline-array dma-bucket).
(defun dma-buffer-add-buckets ((dma-buf dma-buffer) (bucket-count int))
"Initialize an array of dma-buckets in a DMA buffer."
(let ((v0-0 (-> dma-buf base)))
(let ((v1-0 (the-as object v0-0)))
(dotimes (a2-0 bucket-count)
(set! (-> (the-as dma-bucket v1-0) tag)
(new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int (&+ (the-as pointer v1-0) 16)))
)
(set! (-> (the-as dma-bucket v1-0) last) (the-as (pointer dma-tag) v1-0))
(set! v1-0 (&+ (the-as pointer v1-0) 16))
)
(set! (-> dma-buf base) (the-as pointer v1-0))
)
(the-as (inline-array dma-bucket) v0-0)
)
)
;; definition for function dma-buffer-patch-buckets
(defun dma-buffer-patch-buckets ((base dma-bucket) (count int))
"Patch together DMA buckets after they have been filled."
(when (nonzero? base)
(dotimes (v1-1 count)
(cond
((= base (-> base last))
(set! (-> base tag) (new 'static 'dma-tag :id (dma-tag-id cnt)))
(set! (-> base clear) (the-as uint 0))
0
)
(else
(set! (-> base last 0 addr) (the-as int (&+ base 16)))
(cond
((and (or *display-profile* *stats-profile-bars*) (not *display-capture-mode*))
(set! (-> (the-as dma-packet base) vif0) (new 'static 'vif-tag :cmd (vif-cmd mark) :imm v1-1))
(set! (-> (the-as dma-packet base) vif1) (new 'static 'vif-tag :irq #x1))
)
(else
(set! (-> base clear) (the-as uint 0))
0
)
)
)
)
(&+! base 16)
)
)
base
)
;; definition for function dma-bucket-insert-tag
(defun dma-bucket-insert-tag ((buckets (inline-array dma-bucket))
(bucket bucket-id)
(start-tag pointer)
(end-tag-to-patch (pointer dma-tag))
)
"Add a dma chain to the bucket."
(let ((v1-1 (-> buckets bucket)))
(set! (-> (the-as dma-bucket (-> v1-1 last)) next) (the-as uint start-tag))
(set! (-> v1-1 last) end-tag-to-patch)
)
start-tag
)
;; failed to figure out what this is:
0
+241
View File
@@ -0,0 +1,241 @@
;;-*-Lisp-*-
(in-package goal)
;; definition of type dma-packet
(deftype dma-packet (structure)
"The header for a DMA transfer, containing an DMA tag, and VIF tags."
((dma dma-tag)
(vif0 vif-tag)
(vif1 vif-tag)
(quad uint128 :overlay-at dma)
)
)
;; definition for method 3 of type dma-packet
;; INFO: Used lq/sq
(defmethod inspect ((this dma-packet))
(when (not this)
(set! this this)
(goto cfg-4)
)
(format #t "[~8x] ~A~%" this 'dma-packet)
(format #t "~1Tdma: #x~X~%" (-> this dma))
(format #t "~1Tvif0: #x~X~%" (-> this vif0))
(format #t "~1Tvif1: #x~X~%" (-> this vif1))
(format #t "~1Tquad: ~D~%" (-> this quad))
(label cfg-4)
this
)
;; definition of type dma-packet-array
(deftype dma-packet-array (inline-array-class)
"Unused dma array. Unclear how it should be used."
((data dma-packet :dynamic)
)
)
;; definition for method 3 of type dma-packet-array
(defmethod inspect ((this dma-packet-array))
(when (not this)
(set! this this)
(goto cfg-4)
)
(format #t "[~8x] ~A~%" this (-> this type))
(format #t "~1Tlength: ~D~%" (-> this length))
(format #t "~1Tallocated-length: ~D~%" (-> this allocated-length))
(format #t "~1Tdata[0] @ #x~X~%" (-> this data))
(label cfg-4)
this
)
;; failed to figure out what this is:
(set! (-> dma-packet-array heap-base) (the-as uint 16))
;; definition of type dma-gif
(deftype dma-gif (structure)
"Believed unused GIF header type."
((gif uint64 2)
(quad uint128 :overlay-at (-> gif 0))
)
)
;; definition for method 3 of type dma-gif
;; INFO: Used lq/sq
(defmethod inspect ((this dma-gif))
(when (not this)
(set! this this)
(goto cfg-4)
)
(format #t "[~8x] ~A~%" this 'dma-gif)
(format #t "~1Tgif[2] @ #x~X~%" (-> this gif))
(format #t "~1Tquad: ~D~%" (-> this quad))
(label cfg-4)
this
)
;; definition of type dma-gif-packet
(deftype dma-gif-packet (structure)
"The header for a DMA transfer that goes directly to GIF, containing DMA, VIF, GIF tags."
((dma-vif dma-packet :inline)
(gif uint64 2)
(quad uint128 2 :overlay-at (-> dma-vif dma))
)
)
;; definition for method 3 of type dma-gif-packet
(defmethod inspect ((this dma-gif-packet))
(when (not this)
(set! this this)
(goto cfg-4)
)
(format #t "[~8x] ~A~%" this 'dma-gif-packet)
(format #t "~1Tdma-vif: #<dma-packet @ #x~X>~%" (-> this dma-vif))
(format #t "~1Tgif[2] @ #x~X~%" (-> this gif))
(format #t "~1Tquad[2] @ #x~X~%" (-> this dma-vif))
(label cfg-4)
this
)
;; definition of type dma-buffer
(deftype dma-buffer (basic)
"A buffer for DMA data."
((allocated-length int32)
(base pointer)
(end pointer)
(real-buffer-end int32)
(data uint64 1 :offset 32)
)
(:methods
(new (symbol type int) _type_)
)
)
;; definition for method 3 of type dma-buffer
(defmethod inspect ((this dma-buffer))
(when (not this)
(set! this this)
(goto cfg-4)
)
(format #t "[~8x] ~A~%" this (-> this type))
(format #t "~1Tallocated-length: ~D~%" (-> this allocated-length))
(format #t "~1Tbase: #x~X~%" (-> this base))
(format #t "~1Tend: #x~X~%" (-> this end))
(format #t "~1Treal-buffer-end: ~D~%" (-> this real-buffer-end))
(format #t "~1Tdata[1] @ #x~X~%" (-> this data))
(label cfg-4)
this
)
;; definition for method 0 of type dma-buffer
(defmethod new dma-buffer ((allocation symbol) (type-to-make type) (size-bytes int))
"Allocate a DMA buffer to hold the given size"
(let ((v0-0 (object-new allocation type-to-make (+ size-bytes -4 (-> type-to-make size)))))
(set! (-> v0-0 base) (-> v0-0 data))
(set! (-> v0-0 allocated-length) size-bytes)
(set! (-> v0-0 real-buffer-end) (the-as int (&+ (-> v0-0 data) size-bytes)))
v0-0
)
)
;; definition for function dma-buffer-inplace-new
(defun dma-buffer-inplace-new ((dma-buff dma-buffer) (size-bytes int))
"Create a dma-buffer in-place. Does not set the type of the dma-buffer object."
(set! (-> dma-buff base) (-> dma-buff data))
(set! (-> dma-buff allocated-length) size-bytes)
dma-buff
)
;; definition for method 4 of type dma-buffer
(defmethod length ((this dma-buffer))
(-> this allocated-length)
)
;; definition for method 5 of type dma-buffer
(defmethod asize-of ((this dma-buffer))
(+ (-> this allocated-length) -4 (-> dma-buffer size))
)
;; definition for function dma-buffer-length
(defun dma-buffer-length ((dma-buf dma-buffer))
"Get length used in quadwords, rounded up."
(shr (+ (&- (-> dma-buf base) (the-as uint (-> dma-buf data))) 15) 4)
)
;; definition for function dma-buffer-free
(defun dma-buffer-free ((dma-buf dma-buffer))
"Get the number of free quadwords between base and end pointers."
(shr (+ (&- (-> dma-buf end) (the-as uint (-> dma-buf base))) 15) 4)
)
;; definition for function dma-buffer-add-vu-function
;; ERROR: Failed store: (s.w! (+ t2-0 8) t3-5) at op 23
;; ERROR: Failed store: (s.w! (+ t2-0 12) t3-8) at op 32
(defun dma-buffer-add-vu-function ((dma-buf dma-buffer) (vu-func vu-function) (flush-path-3 int))
"Add DMA tags to load the given VU function. The destination in vu instruction memory
is specific inside the vu-function. This does NOT copy the vu-function into the buffer,
but creates a reference to the existing VU function."
(let ((v1-0 (the-as object (+ (the-as uint vu-func) 16)))
(a3-0 (-> vu-func qlength))
(a1-1 (-> vu-func origin))
)
(while (> a3-0 0)
(let ((t0-1 (min 127 a3-0)))
(let* ((t1-1 dma-buf)
(t2-0 (-> t1-1 base))
)
(set! (-> (the-as (pointer int64) t2-0))
(logior (logior #x30000000 (shr (shl t0-1 48) 48)) (shr (shl (the-as int v1-0) 33) 1))
)
(let ((t3-5 (shr
(shl
(if (zero? flush-path-3)
16
19
)
57
)
33
)
)
)
(s.w! (+ t2-0 8) t3-5)
)
(let ((t3-8 (logior (logior #x4a000000 (shr (shl a1-1 48) 48)) (shr (shl (* t0-1 2) 56) 40))))
(s.w! (+ t2-0 12) t3-8)
)
(set! (-> t1-1 base) (&+ t2-0 16))
)
(set! v1-0 (+ (the-as uint v1-0) (* t0-1 16)))
(set! a3-0 (- a3-0 t0-1))
(+! a1-1 (* t0-1 2))
)
)
)
#f
)
;; definition for function dma-buffer-send
(defun dma-buffer-send ((chan dma-bank) (buf dma-buffer))
"Send the DMA buffer! DOES NOT TRANSFER TAG, you probably want dma-buffer-send-chain instead."
(when (< (-> buf allocated-length) (&- (-> buf base) (the-as uint (-> buf data))))
(crash!)
0
)
(dma-send chan (the-as uint (-> buf data)) (the-as uint (dma-buffer-length buf)))
(none)
)
;; definition for function dma-buffer-send-chain
(defun dma-buffer-send-chain ((chan dma-bank-source) (buf dma-buffer))
"Send the DMA buffer! Sends the tags, so this is suitable for the main graphics chain."
(when (< (-> buf allocated-length) (&- (-> buf base) (the-as uint (-> buf data))))
(crash!)
0
)
(dma-send-chain chan (the-as uint (-> buf data)))
(none)
)
+1 -5
View File
@@ -428,7 +428,7 @@
;; definition for function forward-down-nopitch->inv-matrix
;; INFO: Used lq/sq
(defun forward-down-nopitch->inv-matrix ((arg0 matrix) (arg1 vector) (arg2 vector))
"Create a matrix representing an inverse transform where arg1 is forward (+z)
"Create a matrix representing an inverse transform where arg1 is forward (+z)
and arg2 is down (-y). Will not use the pitch of forward."
(vector-normalize-copy! (-> arg0 uvec) arg2 1.0)
(vector-negate! (-> arg0 uvec) (-> arg0 uvec))
@@ -2048,7 +2048,3 @@
)
arg0
)
+3 -1
View File
@@ -49,7 +49,9 @@
"update-math-camera",
"transform-point-vector!",
"transform-point-qword!",
"transform-point-vector-scale!"
"transform-point-vector-scale!",
// dma
"dma-buffer-add-vu-function"
],
"skip_compile_states": {}