mirror of
https://github.com/open-goal/jak-project
synced 2026-09-07 03:30:01 -04:00
[Decompiler] WIP: Stack Spills (#382)
* set up types * cleaned up type analysis and got things working through atomic ops * expression working, need types * improved types and names * getting close * finish up dma-disasm * fix
This commit is contained in:
@@ -56,3 +56,600 @@
|
||||
(new 'static 'vif-disasm-element :print #x8)))
|
||||
|
||||
|
||||
|
||||
(defun disasm-vif-details ((stream symbol) (data (pointer uint8)) (kind vif-cmd) (count int))
|
||||
(cond
|
||||
((= kind (vif-cmd unpack-v4-8))
|
||||
(let ((data-ptr (&-> data 4)))
|
||||
(dotimes (i count)
|
||||
(format stream " #x~X: #x~2X #x~2X #x~2X #x~2X~%"
|
||||
(+ (+ (shl i 2) 4) (the-as int data))
|
||||
(-> data-ptr (shl i 2))
|
||||
(-> data-ptr (+ (shl i 2) 1))
|
||||
(-> data-ptr (+ (shl i 2) 2))
|
||||
(-> data-ptr (+ (shl i 2) 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= kind (vif-cmd unpack-s-8))
|
||||
(let ((s3-1 (&-> data 4)))
|
||||
(dotimes (s2-1 count)
|
||||
;; this is messed up and I think somebody put a parenthesis in
|
||||
;; the wrong spot. I believe the format below only has one
|
||||
;; format argument but should have 2.
|
||||
(format stream " #x~X: #x~2x~%"
|
||||
(+ (+ s2-1 4) (the-as int data))
|
||||
count
|
||||
)
|
||||
;; the actual assembly is very strange here.
|
||||
(let ((v1-21 (-> s3-1 (* 3 s2-1))))
|
||||
)
|
||||
(let ((v1-26 (-> s3-1 (+ (* 3 s2-1) 1))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= kind (vif-cmd unpack-v4-32))
|
||||
(let ((s3-2 (the-as (pointer uint32) (&-> data 4))))
|
||||
(dotimes (s2-2 count)
|
||||
(format stream " #x~X: #x~8x #x~8x #x~8x #x~8x~%"
|
||||
(+ (+ (shl s2-2 4) 4) (the-as int data))
|
||||
(-> s3-2 (shl s2-2 2))
|
||||
(-> s3-2 (+ (shl s2-2 2) 1))
|
||||
(-> s3-2 (+ (shl s2-2 2) 2))
|
||||
(-> s3-2 (+ (shl s2-2 2) 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= kind (vif-cmd unpack-v4-16))
|
||||
(let ((s3-3 (the-as (pointer uint16) (&-> data 4))))
|
||||
(dotimes (s2-3 count)
|
||||
(format stream " #x~X: #x~4x #x~4x #x~4x #x~4x~%"
|
||||
(+ (+ (shl s2-3 3) 4) (the-as int data))
|
||||
(-> s3-3 (shl s2-3 2))
|
||||
(-> s3-3 (+ (shl s2-3 2) 1))
|
||||
(-> s3-3 (+ (shl s2-3 2) 2))
|
||||
(-> s3-3 (+ (shl s2-3 2) 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= kind (vif-cmd unpack-v3-32))
|
||||
(let ((s3-4 (the-as (pointer uint32) (&-> data 4))))
|
||||
(dotimes (s2-4 count)
|
||||
(format stream " #x~X: #x~8x #x~8x #x~8x~%"
|
||||
(+ (+ (* 12 s2-4) 4) (the-as int data))
|
||||
(-> (&+ s3-4 (* 12 s2-4)) 0)
|
||||
(-> s3-4 (+ (* 3 s2-4) 1))
|
||||
(-> s3-4 (+ (* 3 s2-4) 2))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= kind (vif-cmd unpack-v3-16))
|
||||
(let ((s3-5 (the-as (pointer uint16) (&-> data 4))))
|
||||
(dotimes (s2-5 count)
|
||||
(format stream " #x~X: #x~4x #x~4x #x~4x~%"
|
||||
(+ (+ (* 6 s2-5) 4) (the-as int data))
|
||||
(-> (&+ s3-5 (* 6 s2-5)) 0)
|
||||
(-> s3-5 (+ (* 3 s2-5) 1))
|
||||
(-> s3-5 (+ (* 3 s2-5) 2))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= kind (vif-cmd unpack-v2-16))
|
||||
(let ((s3-6 (the-as (pointer uint16) (&-> data 4))))
|
||||
(dotimes (s2-6 count)
|
||||
(format stream " #x~X: #x~4x #x~4x~%"
|
||||
(+ (+ (shl s2-6 2) 4) (the-as int data))
|
||||
(-> (&+ s3-6 (* 6 s2-6)) 0)
|
||||
(-> s3-6 (+ (* 3 s2-6) 1))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(format stream " #x~X: Data format #b~b not yet supported, add it for yourself!~%"
|
||||
(&-> data 4)
|
||||
kind
|
||||
)
|
||||
)
|
||||
)
|
||||
#f
|
||||
)
|
||||
|
||||
(defun disasm-vif-tag ((data (pointer vif-tag)) (words int) (stream symbol) (details symbol))
|
||||
"Print out a vif code and the immediate data.
|
||||
Will print stuff until the number of words has been reached.
|
||||
Returns how many bytes we overshot by."
|
||||
(local-vars
|
||||
(cmd vif-cmd)
|
||||
(data-ptr (pointer vif-tag))
|
||||
(data-idx int)
|
||||
(unpack-imm vif-unpack-imm)
|
||||
)
|
||||
(let ((byte-idx 0))
|
||||
(while (< byte-idx (shl words 2))
|
||||
(let ((packet-size 4)) ;; default packet size is 32-bits.
|
||||
(let ((first-tag (-> data 0)))
|
||||
;; print the packet's address.
|
||||
(format stream " #x~X:" data)
|
||||
;; iterate through the disasm table, looking for a match
|
||||
(dotimes (cmd-template-idx (-> *vif-disasm-table* length))
|
||||
(set! cmd (-> first-tag cmd))
|
||||
;; check the command against the table's mask and tag
|
||||
(when (= (logand cmd (the-as uint (-> *vif-disasm-table* cmd-template-idx mask)))
|
||||
(-> *vif-disasm-table* cmd-template-idx tag)
|
||||
)
|
||||
(let* ((print-kind (-> *vif-disasm-table* cmd-template-idx print))
|
||||
(v0-1 (cond
|
||||
((zero? print-kind)
|
||||
;; just the name and irq bit.
|
||||
(format stream " (~s :irq ~D)~%"
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
)
|
||||
)
|
||||
((= print-kind 1)
|
||||
;; name and immediate register value.
|
||||
(format stream " (~s :irq ~D :~s #x~X)~%"
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
(-> *vif-disasm-table* cmd-template-idx string2)
|
||||
(-> first-tag imm)
|
||||
)
|
||||
)
|
||||
((= print-kind 2)
|
||||
;; name and stcycl immediate
|
||||
(let ((stcycl-imm (the-as vif-stcycl-imm (-> first-tag imm))))
|
||||
(format stream " (~s :irq ~D :wl ~D :cl ~D)~%"
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
(-> stcycl-imm wl)
|
||||
(-> stcycl-imm cl)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= print-kind 3)
|
||||
;; name and a single word of extra data
|
||||
(set! packet-size 8) ;; 4 + 4 = 8 byte packet.
|
||||
(format stream " (~s :irq ~D :~s #x~X)~%"
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
(-> *vif-disasm-table* cmd-template-idx string2)
|
||||
(-> data 1)
|
||||
)
|
||||
)
|
||||
((= print-kind 4)
|
||||
;; 4x 1 word extra data
|
||||
(set! packet-size 20) ;; 4 + 16 = 20 byte packet.
|
||||
(format stream " (~s :irq ~D :~s "
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
(-> *vif-disasm-table* cmd-template-idx string2)
|
||||
)
|
||||
(format stream "#x~X #x~X #x~X #x~X)~%"
|
||||
(-> data 1)
|
||||
(-> data 2)
|
||||
(-> data 3)
|
||||
(-> data 4)
|
||||
)
|
||||
)
|
||||
((= print-kind 5)
|
||||
(format stream " (~s :irq ~D :instructions #x~D :addr #x~X)~%"
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
(-> first-tag num)
|
||||
(-> first-tag imm)
|
||||
)
|
||||
)
|
||||
((= print-kind 6)
|
||||
;; imm is quadword count.
|
||||
;; This packet size calculation is wrong.
|
||||
;; this doesn't seem to be a decompiler error, this matches
|
||||
;; the assembly, but makes no sense.
|
||||
(set! packet-size
|
||||
(the-as int (if (-> first-tag imm)
|
||||
#x100000
|
||||
(shl (-> first-tag imm) 4)
|
||||
)
|
||||
)
|
||||
)
|
||||
(format stream " (~s :irq ~D :qwc #x~D)~%"
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
(-> first-tag imm)
|
||||
)
|
||||
|
||||
;; loop over data and print it.
|
||||
(set! data-ptr (&-> data 1))
|
||||
(set! data-idx 0)
|
||||
(while (< data-idx (the-as int (-> first-tag imm)))
|
||||
(format stream " #x~X: #x~8x #x~8x #x~8x #x~8x~%"
|
||||
(+ (+ (shl data-idx 4) 4) (the-as int data))
|
||||
(-> data-ptr (shl data-idx 2))
|
||||
(-> data-ptr (+ (shl data-idx 2) 1))
|
||||
(-> data-ptr (+ (shl data-idx 2) 2))
|
||||
(-> data-ptr (+ (shl data-idx 2) 3))
|
||||
)
|
||||
(set! data-idx (+ data-idx 1))
|
||||
)
|
||||
#f
|
||||
)
|
||||
((= print-kind 7)
|
||||
(set! packet-size
|
||||
(the-as int
|
||||
(+
|
||||
(logand
|
||||
-4
|
||||
(+ (* (-> *vif-disasm-table* cmd-template-idx val)
|
||||
(the-as uint (-> first-tag num)))
|
||||
3
|
||||
)
|
||||
)
|
||||
4
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! unpack-imm (the-as vif-unpack-imm (-> first-tag imm)))
|
||||
(format stream " (~s :irq ~D :num ~D :addr #x~X "
|
||||
(-> *vif-disasm-table* cmd-template-idx string1)
|
||||
(-> first-tag irq)
|
||||
(-> first-tag num)
|
||||
(-> unpack-imm addr)
|
||||
)
|
||||
(format stream ":msk ~D :flg ~D :usn ~D [skip ~d])~%"
|
||||
(-> first-tag msk)
|
||||
(-> unpack-imm flg)
|
||||
(-> unpack-imm usn)
|
||||
(the-as uint packet-size)
|
||||
)
|
||||
(if details
|
||||
(disasm-vif-details
|
||||
stream
|
||||
(the-as (pointer uint8) data)
|
||||
(logand cmd (vif-cmd cmd-mask))
|
||||
(the-as int (-> first-tag num))
|
||||
)
|
||||
)
|
||||
)
|
||||
((= print-kind 8)
|
||||
(format stream " (*unknown* vif-tag #x~X)~%"
|
||||
(-> first-tag cmd)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
;; we matched, skip to the end.
|
||||
(set! cmd-template-idx (-> *vif-disasm-table* length))
|
||||
)
|
||||
)
|
||||
)
|
||||
;; increment counters.
|
||||
(+! byte-idx packet-size)
|
||||
(&+! data packet-size)
|
||||
)
|
||||
)
|
||||
(- byte-idx (shl words 2))
|
||||
)
|
||||
)
|
||||
|
||||
(defun disasm-dma-tag ((arg0 dma-tag) (arg1 symbol))
|
||||
(format arg1 "(dma-tag ")
|
||||
;; this is a case statement.
|
||||
(let ((t9-1 format)
|
||||
(a0-2 arg1)
|
||||
(a1-2 "~s")
|
||||
(v1-1 (-> arg0 id))
|
||||
)
|
||||
(t9-1 a0-2 a1-2 (cond
|
||||
((= v1-1 (dma-tag-id end))
|
||||
"end"
|
||||
)
|
||||
((= v1-1 (dma-tag-id ret))
|
||||
"ret"
|
||||
)
|
||||
((= v1-1 (dma-tag-id call))
|
||||
"call"
|
||||
)
|
||||
((= v1-1 (dma-tag-id refs))
|
||||
"refs"
|
||||
)
|
||||
((= v1-1 (dma-tag-id ref))
|
||||
"ref"
|
||||
)
|
||||
((= v1-1 (dma-tag-id next))
|
||||
"next"
|
||||
)
|
||||
((= v1-1 (dma-tag-id cnt))
|
||||
"cnt"
|
||||
)
|
||||
((zero? v1-1)
|
||||
"refe"
|
||||
)
|
||||
(else
|
||||
"*unknown*"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (> (the-as uint (-> arg0 addr)) 0)
|
||||
(format arg1 " :addr #x~8x" (-> arg0 addr))
|
||||
)
|
||||
(if (> (the-as uint (-> arg0 qwc)) 0)
|
||||
(format arg1 " :qwc ~d" (-> arg0 qwc))
|
||||
)
|
||||
(if (> (the-as uint (-> arg0 spr)) 0)
|
||||
(format arg1 " :spr ~d" (-> arg0 spr))
|
||||
)
|
||||
(if (> (the-as uint (-> arg0 irq)) 0)
|
||||
(format arg1 " :irq ~d" (-> arg0 irq))
|
||||
)
|
||||
(if (> (the-as uint (-> arg0 pce)) 0)
|
||||
(format arg1 " :pce ~d" (-> arg0 pce))
|
||||
)
|
||||
(format arg1 ")~%")
|
||||
(none)
|
||||
)
|
||||
|
||||
;; this is unused.
|
||||
(define *dma-disasm* #t)
|
||||
|
||||
(defun disasm-dma-list ((data dma-packet) (mode symbol) (verbose symbol) (stream symbol) (expected-size int))
|
||||
"Disassemble a dma list, starting from the given packet."
|
||||
(local-vars
|
||||
(addr object)
|
||||
(data-2 dma-packet)
|
||||
(qwc int)
|
||||
(ra-1 object)
|
||||
(ra-2 object)
|
||||
(call-depth int)
|
||||
(current-tag dma-tag)
|
||||
)
|
||||
;; this is a little messed up because of stack spills.
|
||||
(set! data-2 data)
|
||||
(let ((mode-2 mode)
|
||||
(verbose-2 verbose)
|
||||
(stream-2 stream)
|
||||
(expected-size-2 expected-size)
|
||||
)
|
||||
(if verbose-2
|
||||
(format stream-2 "~%--- ~X -----------------------------~%" data-2)
|
||||
)
|
||||
;; the end-condition will get set to #t when the end of the chain is reached,
|
||||
;; or 'error if invalid data is found.
|
||||
(let ((end-condition #f))
|
||||
;; statistics
|
||||
(let ((total-qwc 0)
|
||||
(total-tags 0)
|
||||
)
|
||||
(set! addr 0)
|
||||
(set! qwc 0)
|
||||
;; for the "call" feature
|
||||
(set! ra-1 0)
|
||||
(set! ra-2 1)
|
||||
(set! call-depth -1)
|
||||
;; the tag we're currently exploring.
|
||||
(set! current-tag (new 'static 'dma-tag))
|
||||
;; loop until tag is done
|
||||
(while (not end-condition)
|
||||
;; first, we should verify that the data pointer is valid so we don't crash
|
||||
(cond
|
||||
((not (valid? data-2 (the-as type #f) "dma-list tag pointer" #t stream-2))
|
||||
(format stream-2 "ERROR: dma-list tag pointer invalid~%")
|
||||
(set! end-condition 'error)
|
||||
)
|
||||
(else
|
||||
;; load the tag
|
||||
(set! current-tag (-> data-2 dma))
|
||||
;; check the address. it is unset on the first pass so we skip this check then.
|
||||
(when (not (or (zero? total-tags)
|
||||
(valid? addr (the-as type #f) "dma-list data pointer" #t stream-2)
|
||||
)
|
||||
)
|
||||
(format stream-2 "ERROR: dma-list data pointer invalid~%")
|
||||
(set! end-condition 'error)
|
||||
)
|
||||
;; check that the tag's value makes sense.
|
||||
(when (nonzero? (logand #x3ff0000 (the-as int current-tag)))
|
||||
(format stream-2 "ERROR: dma tag has data in reserved bits ~X~%")
|
||||
(set! end-condition 'error)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; next, disassembly the dma-tag.
|
||||
;; only do it if verbose is set, or we have encountered an error.
|
||||
(when (or verbose-2 (= end-condition 'error))
|
||||
(format stream-2 "#x~8x: " data-2)
|
||||
(cond
|
||||
((zero? call-depth)
|
||||
(format stream-2 " ")
|
||||
)
|
||||
((= call-depth 1)
|
||||
(format stream-2 " ")
|
||||
)
|
||||
)
|
||||
(disasm-dma-tag current-tag stream-2)
|
||||
)
|
||||
|
||||
;; now the dma data.
|
||||
(if end-condition
|
||||
(none) ;; do nothing if we want to end.
|
||||
(cond
|
||||
;; check if we are an addr in addr field dma tag.
|
||||
((or (zero? (+ (the-as uint (-> current-tag id)) (the-as uint -3))) ;; ref
|
||||
(zero? (+ (the-as uint (-> current-tag id)) (the-as uint -4))) ;; refs
|
||||
(zero? (-> current-tag id)) ;; refe
|
||||
)
|
||||
;; set addresss and qwc from the tag.
|
||||
(set! addr (-> current-tag addr))
|
||||
(set! qwc (the-as int (-> current-tag qwc)))
|
||||
;; optionally disassemble vif tags.
|
||||
(if mode-2
|
||||
;; I don't quite understand this. The first thing is for the tag transferred due to tte.
|
||||
;; but I don't understand what the v0-9 offset is.
|
||||
(let ((v0-9 (disasm-vif-tag (&-> data-2 vif0) 2 stream-2 (= mode-2 'details))))
|
||||
(disasm-vif-tag
|
||||
(the-as (pointer vif-tag) (+ (the-as uint addr) (the-as uint v0-9)))
|
||||
(the-as int (- (shl (the-as int qwc) 2) (the-as uint (sar v0-9 2))))
|
||||
stream-2
|
||||
(= mode-2 'details)
|
||||
)
|
||||
)
|
||||
)
|
||||
;; move on to next dma-packet. it is adjacent in memory for these modes.
|
||||
(set! data-2 (the-as dma-packet (&-> (the-as (pointer uint64) data-2) 2)))
|
||||
;; if we were a refe, it is now the end!
|
||||
(if (zero? (-> current-tag id)) ;; check refe.
|
||||
(set! end-condition #t)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(cond
|
||||
((= (-> current-tag id) (dma-tag-id cnt))
|
||||
;; cnt: address is after tag, next tag is after data.
|
||||
;; get the address from after the tag
|
||||
(set! addr (&-> (the-as (pointer uint64) data-2) 2))
|
||||
;; qwc from the tag
|
||||
(set! qwc (the-as int (-> current-tag qwc)))
|
||||
;; disassemble vif.
|
||||
(if mode-2
|
||||
(disasm-vif-tag
|
||||
(the-as (pointer vif-tag) (&-> (the-as (pointer uint64) data-2) 1))
|
||||
(the-as int (+ (shl (the-as int qwc) 2) 2))
|
||||
stream-2
|
||||
(= mode-2 'details)
|
||||
)
|
||||
)
|
||||
;; next data is after vif data.
|
||||
(set! data-2 (the-as dma-packet (+ (the-as uint data-2)
|
||||
(the-as uint (shl (the-as int (+ (the-as uint qwc)
|
||||
(the-as uint 1)))
|
||||
4)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
((= (-> current-tag id) (dma-tag-id next))
|
||||
;; address after tag and qwc in tag.
|
||||
(set! addr (&-> (the-as (pointer uint64) data-2) 2))
|
||||
(set! qwc (the-as int (-> current-tag qwc)))
|
||||
(if mode-2
|
||||
(disasm-vif-tag
|
||||
(the-as (pointer vif-tag) (&-> (the-as (pointer uint64) data-2) 1))
|
||||
(the-as int (+ (shl (the-as int qwc) 2) 2))
|
||||
stream-2
|
||||
(= mode-2 'details)
|
||||
)
|
||||
)
|
||||
;; addr is the next tag. check for infinite loop before continuing.
|
||||
(when (= data-2 (-> current-tag addr))
|
||||
(format stream-2 "ERROR: next tag creates infinite loop.~%")
|
||||
(set! end-condition 'error)
|
||||
)
|
||||
(set! data-2 (the-as dma-packet (-> current-tag addr)))
|
||||
)
|
||||
(else
|
||||
(cond
|
||||
((= (-> current-tag id) (dma-tag-id call))
|
||||
;; this "calls" a DMA chain, which should then return to here.
|
||||
;; the stack is only two deep.
|
||||
(set! addr (&-> (the-as (pointer uint64) data-2) 2))
|
||||
(set! qwc (the-as int (-> current-tag qwc)))
|
||||
(if mode-2
|
||||
(disasm-vif-tag (the-as (pointer vif-tag) (&-> (the-as (pointer uint64) data-2) 1))
|
||||
(the-as int (+ (shl (the-as int qwc) 2) 2))
|
||||
stream-2
|
||||
(= mode-2 'details)
|
||||
)
|
||||
)
|
||||
(set! data-2 (the-as dma-packet (-> current-tag addr)))
|
||||
;; increment stack
|
||||
(set! call-depth (+ call-depth 1))
|
||||
;; and store the return.
|
||||
(cond
|
||||
((zero? call-depth)
|
||||
(set! ra-1 (&+ (the pointer addr) qwc))
|
||||
)
|
||||
(else
|
||||
(set! ra-2 (&+ (the pointer addr) qwc))
|
||||
)
|
||||
)
|
||||
)
|
||||
((= (-> current-tag id) (dma-tag-id ret))
|
||||
;; return from a "called" dma chain.
|
||||
(set! addr (&-> (the-as (pointer uint64) data-2) 2))
|
||||
(set! qwc (the-as int (-> current-tag qwc)))
|
||||
(if mode-2
|
||||
(disasm-vif-tag (the-as (pointer vif-tag) (&-> (the-as (pointer uint64) data-2) 1))
|
||||
(the-as int (+ (shl (the-as int qwc) 2) 2))
|
||||
stream-2
|
||||
(= mode-2 'details)
|
||||
)
|
||||
)
|
||||
|
||||
;; restore the address from the stack
|
||||
;; likely a case.
|
||||
(let ((v1-123 call-depth))
|
||||
(cond
|
||||
((zero? v1-123)
|
||||
(set! data-2 (the-as dma-packet ra-1))
|
||||
)
|
||||
((= v1-123 1)
|
||||
(set! data-2 (the-as dma-packet ra-2))
|
||||
)
|
||||
(else
|
||||
(set! end-condition #t)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! call-depth (+ call-depth -1))
|
||||
)
|
||||
((= (-> current-tag id) (dma-tag-id end))
|
||||
(set! addr (&-> (the-as (pointer uint64) data-2) 2))
|
||||
(set! qwc (the-as int (-> current-tag qwc)))
|
||||
(set! end-condition #t)
|
||||
(if mode-2
|
||||
(disasm-vif-tag (the-as (pointer vif-tag) (&-> (the-as (pointer uint64) data-2) 1))
|
||||
(the-as int (+ (shl (the-as int qwc) 2) 2))
|
||||
stream-2
|
||||
(= mode-2 'details)
|
||||
)
|
||||
)
|
||||
|
||||
)
|
||||
(else
|
||||
(format stream-2 "ERROR: Unknown DMA TAG command.~%")
|
||||
(set! end-condition 'error)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
;; increment stats
|
||||
(+! total-qwc qwc)
|
||||
(+! total-tags 1)
|
||||
;; end, if we hit the tag limit.
|
||||
(if (and (>= expected-size-2 0) (>= total-tags expected-size-2))
|
||||
(set! end-condition #t)
|
||||
)
|
||||
)
|
||||
(when (or verbose-2 (= end-condition 'error))
|
||||
(format stream-2 "NOTICE: Total tags: ~d~%" total-tags)
|
||||
(format stream-2 "NOTICE: Total QWC: ~d~%" total-qwc)
|
||||
(format stream-2 "--------------------------------~%~%")
|
||||
)
|
||||
)
|
||||
(!= end-condition 'error)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -294,6 +294,7 @@
|
||||
(unpack-v4-16 109)
|
||||
(unpack-v4-8 110)
|
||||
(unpack-v4-5 111)
|
||||
(cmd-mask 239) ;; not sure what this is.
|
||||
)
|
||||
|
||||
;; this makes a copy of the above type, but uses a uint32.
|
||||
|
||||
Reference in New Issue
Block a user