rlm@105: (ns com.aurellem.assembly rlm@105: (:use (com.aurellem gb-driver vbm title items)) rlm@105: (:import [com.aurellem.gb_driver SaveState])) rlm@105: rlm@106: (defn mid-game [] rlm@106: (read-state "mid-game")) rlm@105: rlm@105: (defn inject-assembly rlm@107: ([^SaveState state rlm@105: program-counter registers rlm@105: assembly-code] rlm@105: (let [scratch-memory (memory state)] rlm@105: ;; inject assembly code rlm@105: (dorun (map (fn [index val] rlm@105: (aset scratch-memory index val)) rlm@105: (range program-counter rlm@105: (+ program-counter (count assembly-code))) rlm@105: assembly-code)) rlm@106: (-> state rlm@106: (write-memory! scratch-memory) rlm@106: (write-registers! registers) rlm@106: (PC! program-counter)))) rlm@107: ;;([program-counter] rlm@107: ;; (fn [^SaveState state registers assembly-code] rlm@107: ;; (inject-assembly state program-counter registers assembly-code))) rlm@107: ) rlm@107: rlm@107: rlm@107: ;;(def inject-assembly-item rlm@107: ;; (inject-assembly (inc item-list-start))) rlm@105: rlm@105: (defn inject-item-assembly rlm@105: ([^SaveState state assembly-code] rlm@105: (inject-assembly state (inc item-list-start) rlm@105: (registers state) rlm@105: assembly-code)) rlm@105: ([assembly-code] rlm@105: (inject-item-assembly @current-state assembly-code))) rlm@105: rlm@105: (defn info rlm@105: ([^SaveState state] rlm@107: (println (format "PC: 0x%04X" (PC state))) rlm@106: (println "Instruction:" rlm@106: (format "0x%02X" (aget (memory state) (PC state)))) rlm@105: state)) rlm@105: rlm@107: (defn print-interrupt rlm@107: [^SaveState state] rlm@107: (println (format "IE: %d" (IE state))) rlm@107: state) rlm@107: rlm@105: (defn run-assembly rlm@105: ([info-fn assembly n] rlm@105: (let [final-state rlm@105: (reduce (fn [state _] rlm@105: (tick (info-fn state))) rlm@107: (inject-item-assembly rlm@107: (mid-game) assembly) rlm@105: (range n))] rlm@105: final-state)) rlm@105: ([assembly n] rlm@105: (run-assembly info assembly n))) rlm@107: rlm@107: rlm@107: (def buttons-port 0xFF00) rlm@107: rlm@107: rlm@107: (defn A [state] rlm@107: (bit-shift-right (bit-and 0x0000FF00 (AF state)) 8)) rlm@107: rlm@110: (defn binary-str [num] rlm@110: (format "%08d" rlm@110: (Integer/parseInt rlm@110: (Integer/toBinaryString num) 10))) rlm@110: rlm@110: (defn view-register [state name reg-fn] rlm@110: (println (format "%s: %s" name rlm@110: (binary-str (reg-fn state)))) rlm@110: state) rlm@110: rlm@110: rlm@107: (defn view-memory [state mem] rlm@110: (println (format "mem 0x%04X = %s" mem rlm@110: (binary-str (aget (memory state) mem)))) rlm@107: state) rlm@107: rlm@107: (defn read-buttons [] rlm@110: rlm@110: (-> (tick (mid-game)) rlm@110: (IE! 0) ; disable interrupts rlm@110: (inject-item-assembly rlm@110: (concat rlm@110: ;; write 00010000 to 0xFF00 to select joypad rlm@110: [0x18 ;D31D ; jump over rlm@110: 0x01 ;D31E ; the next 8 bits rlm@110: (Integer/parseInt "00010000" 2) ;D31F data section rlm@110: 0x00 ;D320 ; take a break rlm@107: rlm@110: 0xFA ;D321 ; put DC1F into A rlm@110: 0x1F ;D322 --> rlm@110: 0xD3 ;D323 --> D31F rlm@107: rlm@110: 0xEA ;D324 ; load (A), which is rlm@110: 0x00 ;D325 --> ; 00010000, into FF00 rlm@110: 0xFF ;D326 --> FF00 rlm@110: rlm@110: 0x00 rlm@110: ] rlm@110: rlm@110: [])) rlm@110: (info) rlm@110: (tick) ;; skip over data section rlm@110: (info) rlm@110: (tick) ;; no-op rlm@110: (info) rlm@110: (view-register "Register A" A) rlm@110: (tick) ;; load-data into A rlm@110: (view-register "Register A" A) rlm@110: (info) rlm@110: (view-memory 0xFF00) rlm@110: (tick) ;; load A into 0xFF00 rlm@110: (view-memory 0xFF00) rlm@110: )) rlm@107: rlm@107: rlm@107: (defn trace [state] rlm@107: (loop [program-counters [] rlm@107: opcodes []] rlm@107: (let [frame-boundary? rlm@107: (com.aurellem.gb.Gb/tick)] rlm@107: (println (count opcodes)) rlm@107: (if frame-boundary? rlm@107: [program-counters opcodes] rlm@107: (recur rlm@107: (conj program-counters rlm@107: (first (registers @current-state))) rlm@107: (conj opcodes rlm@107: (aget (memory @current-state) rlm@107: (PC @current-state)))))))) rlm@107: rlm@107: rlm@107: (defn good-trace [] rlm@107: (-> (mid-game) (tick) (IE! 0) rlm@107: (set-inv-mem [0x00 0x00 0X00 0x00]) rlm@107: (PC! item-list-start)(print-interrupt) rlm@107: (info) (tick) (info) (tick) (info)))