diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 4e7449be5..51b9acbb7 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -1617,14 +1617,38 @@ ) ) +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; TIMER-H ;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + ;;;;;;;;;;;;; ;; timer-h ;;;;;;;;;;;;; +(deftype timer-mode (uint32) + (;(data uint32 :offset 0 :size 32) + (clks uint8 :offset 0 :size 2) + (gate uint8 :offset 2 :size 1) + (gats uint8 :offset 3 :size 1) + (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) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + (deftype timer-bank (structure) - ((count uint32 :offset-assert 0) - (mode uint32 :offset 16) ;; not sure why these are so widely spaced. match hw? - (comp uint32 :offset 32) + ((count uint32 :offset-assert 0) + (mode timer-mode :offset 16) + (comp uint32 :offset 32) ) :method-count-assert 9 :size-assert #x24 @@ -1632,7 +1656,7 @@ ) (deftype timer-hold-bank (timer-bank) - ((hold uint32 :offset 48) ;; not sure why so widely spaced + ((hold uint32 :offset 48) ) :method-count-assert 9 :size-assert #x34 @@ -1649,10 +1673,16 @@ :flag-assert #x90000001c ) +(define-extern *ticks-per-frame* int) +(define-extern timer-init (function timer-bank timer-mode int)) + (deftype profile-frame (structure) ((name basic :offset-assert 0) (time-stamp uint32 :offset-assert 4) (color uint32 :offset-assert 8) + (r uint8 :offset 8) ;; TODO : verify colors + (g uint8 :offset 9) ;; TODO (again) : these are actually bitfields + (b uint8 :offset 10) ) :method-count-assert 9 :size-assert #xc @@ -1668,7 +1698,7 @@ :size-assert #x4010 :flag-assert #xe00004010 (:methods - (dummy-9 () none 9) + (get-last-frame-time-stamp (profile-bar) uint 9) (dummy-10 () none 10) (dummy-11 () none 11) (dummy-12 () none 12) @@ -31684,7 +31714,6 @@ ;;(define-extern stopwatch object) ;; unknown type ;;(define-extern *ticks-per-frame* object) ;; unknown type ;;(define-extern profile-bar object) ;; unknown type -(define-extern timer-init function) ;;(define-extern timer-bank object) ;; unknown type ;;(define-extern profile-frame object) ;; unknown type (define-extern stopwatch-init function) diff --git a/decompiler/config/jak1_ntsc_black_label.jsonc b/decompiler/config/jak1_ntsc_black_label.jsonc index 51215bfb4..473ec6be1 100644 --- a/decompiler/config/jak1_ntsc_black_label.jsonc +++ b/decompiler/config/jak1_ntsc_black_label.jsonc @@ -57,7 +57,7 @@ "anonymous_function_types_file":"decompiler/config/jak1_ntsc_black_label/anonymous_function_types.jsonc", "analyze_functions":true, - "analyze_expressions":false, + "analyze_expressions":true, "function_type_prop":true, "write_disassembly":true, "write_hex_near_instructions":false, diff --git a/goal_src/engine/ps2/timer-h.gc b/goal_src/engine/ps2/timer-h.gc index 8df413ee9..2aada4642 100644 --- a/goal_src/engine/ps2/timer-h.gc +++ b/goal_src/engine/ps2/timer-h.gc @@ -5,3 +5,123 @@ ;; name in dgo: timer-h ;; dgos: GAME, ENGINE + +;; The Emotion Engine has 4 hardware timers. +(defconstant EE_TIMER0 #x10000000) ;; has HOLD register! +(defconstant EE_TIMER1 #x10000800) ;; has HOLD register! +(defconstant EE_TIMER2 #x10001000) ;; does NOT have HOLD register! +(defconstant EE_TIMER3 #x10001800) ;; does NOT have HOLD register! + +;; 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) + (clks uint8 :offset 0 :size 2) + (gate uint8 :offset 2 :size 1) + (gats uint8 :offset 3 :size 1) + (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) + ) + :method-count-assert 9 + :size-assert #x4 + :flag-assert #x900000004 + ) + +;; this matches an EE timer (without a HOLD register, timers 2 and 3) +;; Each register is 128-bits wide, but only the lower 32-bits are usable, and the upper +;; 16-bits of that are hardwired to zero. +(deftype timer-bank (structure) + ((count uint32 :offset-assert 0) + (mode timer-mode :offset 16) + (comp uint32 :offset 32) + ) + :method-count-assert 9 + :size-assert #x24 + :flag-assert #x900000024 + ) + +;; this matches an EE timer (with a HOLD register, timers 0 and 1) +(deftype timer-hold-bank (timer-bank) + ((hold uint32 :offset 48) + ) + :method-count-assert 9 + :size-assert #x34 + :flag-assert #x900000034 + ) + +(deftype stopwatch (basic) + ((prev-time-elapsed uint64 :offset-assert 8) + (start-time uint64 :offset-assert 16) + (begin-level int32 :offset-assert 24) + ) + :method-count-assert 9 + :size-assert #x1c + :flag-assert #x90000001c + ) + +;; Confusing! What IS this measuring exactly? Hmm... +(define *ticks-per-frame* (/ 2500000 256)) ;; 2 500 000 / 256 = 9765 + +(defun timer-init ((bank timer-bank) (mode timer-mode)) + "Initiate a timer, start counting at a rate of 1 every 256 bus clocks (BUSCLK: ~147.456MHz)." + (set! (-> bank mode) mode) + (set! (-> bank count) 0) + ) + +;; segfaults OpenGOAL as it does not support ps2 EE timers +; (timer-init (the-as timer-bank EE_TIMER1) (the-as timer-mode #x82)) + + +(deftype profile-frame (structure) + ((name basic :offset-assert 0) + (time-stamp uint32 :offset-assert 4) + (color uint32 :offset-assert 8) + (r uint8 :offset 8) ;; TODO : verify colors + (g uint8 :offset 9) ;; TODO (again) : these are actually bitfields + (b uint8 :offset 10) + ) + :method-count-assert 9 + :size-assert #xc + :flag-assert #x90000000c + ) + +(defmethod inspect profile-frame ((obj profile-frame)) + (let ((this-frame obj)) + (format #t "[~8x] profile-frame~%" this-frame) + (format #t "~Tname: ~A~%" (-> this-frame name)) + (format #t "~Ttime-stamp: ~D~%" (-> this-frame time-stamp)) + (format #t "~Tcolor: ~D ~D ~D~%" (-> this-frame r) (-> this-frame g) (-> this-frame b)) + ) + obj + ) + + +(deftype profile-bar (basic) + ((profile-frame-count int32 :offset-assert 4) + (cache-time uint64 :offset-assert 8) + (data profile-frame 1024 :inline :offset-assert 16) + ) + :method-count-assert 14 + :size-assert #x4010 + :flag-assert #xe00004010 + (:methods + (get-last-frame-time-stamp (profile-bar) uint 9) + (dummy-10 () none 10) + (dummy-11 () none 11) + (dummy-12 () none 12) + (dummy-13 () none 13) + ) + ) + +;; tentative name +(defmethod get-last-frame-time-stamp profile-bar ((obj profile-bar)) + "Returns the timestamp of the last (non-remaining) frame on the profiler bar." + (-> obj data (+ (-> obj profile-frame-count) -2) time-stamp) + ) +