rlm@145: (ns com.aurellem.gb.assembly rlm@145: (:use (com.aurellem.gb gb-driver vbm util items)) rlm@145: (:import [com.aurellem.gb.gb_driver SaveState])) rlm@145: rlm@145: (defn inject-assembly rlm@145: ([^SaveState state rlm@145: program-counter registers rlm@145: assembly-code] rlm@145: (let [scratch-memory (memory state)] rlm@145: ;; inject assembly code rlm@145: (dorun (map (fn [index val] rlm@145: (aset scratch-memory index val)) rlm@145: (range program-counter rlm@145: (+ program-counter (count assembly-code))) rlm@145: assembly-code)) rlm@145: (-> state rlm@145: (write-memory! scratch-memory) rlm@145: (write-registers! registers) rlm@145: (PC! program-counter))))) rlm@145: rlm@145: (defn inject-item-assembly rlm@145: ([^SaveState state assembly-code] rlm@145: (inject-assembly state (inc item-list-start) rlm@145: (registers state) rlm@145: assembly-code)) rlm@145: ([assembly-code] rlm@145: (inject-item-assembly @current-state assembly-code))) rlm@145: rlm@145: (defn run-assembly rlm@145: ([info-fn assembly n] rlm@145: (let [final-state rlm@145: (reduce (fn [state _] rlm@145: (tick (info-fn state))) rlm@145: (inject-item-assembly rlm@145: (mid-game) assembly) rlm@145: (range n))] rlm@145: final-state)) rlm@145: ([assembly n] rlm@145: (run-assembly d-tick assembly n))) rlm@145: rlm@145: (def buttons-port 0xFF00) rlm@145: rlm@145: (defn trace [state] rlm@145: (loop [program-counters [(first (registers @current-state)) ] rlm@145: opcodes [(aget (memory @current-state) (PC @current-state))]] rlm@145: (let [frame-boundary? rlm@145: (com.aurellem.gb.Gb/tick)] rlm@145: (if frame-boundary? rlm@145: [program-counters opcodes] rlm@145: (recur rlm@145: (conj program-counters rlm@145: (first (registers @current-state))) rlm@145: (conj opcodes rlm@145: (aget (memory @current-state) rlm@145: (PC @current-state)))))))) rlm@145: rlm@145: (defn print-trace [state n] rlm@145: (let [[program-counters opcodes] (trace state)] rlm@145: (dorun (map (fn [pc op] (println (format "%04X: 0x%02X" pc op))) rlm@145: (take n program-counters) rlm@145: (take n opcodes))))) rlm@145: rlm@145: (defn good-trace [] rlm@145: (-> (mid-game) (tick) (IE! 0) rlm@145: (set-inv-mem [0x00 0x00 0X00 0x00]) rlm@145: (PC! item-list-start)(print-interrupt) rlm@145: (d-tick) (tick) (d-tick) (tick) (d-tick))) rlm@145: rlm@145: (defn read-down-button [] rlm@145: (-> (tick (mid-game)) rlm@145: (IE! 0) ; disable interrupts rlm@145: (inject-item-assembly rlm@145: ;; write 00010000 to 0xFF00 to select joypad rlm@145: [0x18 ;D31D ; jump over rlm@145: 0x01 ;D31E ; the next 8 bits rlm@145: ;D31F rlm@145: (Integer/parseInt "00100000" 2) ; data section rlm@145: rlm@145: 0xFA ;D320 ; load (D31F) into A rlm@145: 0x1F ;D321 --> rlm@145: 0xD3 ;D322 --> D31F rlm@145: rlm@145: 0xEA ;D323 ; load (A), which is rlm@145: 0x00 ;D324 --> ; 00010000, into FF00 rlm@145: 0xFF ;D325 --> FF00 rlm@145: rlm@145: 0x18 ;D326 ; this is the place where rlm@145: 0x01 ;D327 ; we will store whether rlm@145: 0x00 ;D328 ; "down" is pressed. rlm@145: rlm@145: 0xFA ;D329 ; (FF00) -> A rlm@145: 0x00 ;D32A rlm@145: 0xFF ;D32B rlm@145: rlm@145: 0xCB ;D32C ; Test whether "down" rlm@145: 0x5F ;D32D ; is pressed. rlm@145: rlm@145: 0x28 ;D32E ; if down is pressed, rlm@145: 0x03 ;D32F ; skip the next section rlm@145: ; of code. rlm@145: ;; down-is-not-pressed rlm@145: 0xC3 ;D330 rlm@145: 0x1D ;D331 ; return to beginning rlm@145: 0xD3 ;D332 rlm@145: rlm@145: ;; down-is-pressed rlm@145: 0xEA ;D334 ; write A to D328 if rlm@145: 0x28 ;D335 ; "down" was pressed rlm@145: 0xD3 ;D336 rlm@145: rlm@145: 0xC3 ;D330 rlm@145: 0x1D ;D331 ; return to beginning rlm@145: 0xD3 ;D332 rlm@145: ]))) rlm@145: rlm@145: (defn test-read-down [] rlm@145: (= (view-memory (step (step (read-down-button) [:d])) 0xD328) rlm@145: (view-memory (step (step (read-down-button))) 0xD328))) rlm@145: rlm@145: (defn count-frames [] rlm@145: (-> (tick (mid-game)) rlm@145: (IE! 0) ; disable interrupts rlm@145: (inject-item-assembly rlm@145: [0x18 ;D31D ; jump over rlm@145: 0x02 ;D31E ; the next 2 bytes rlm@145: 0x00 ;D31F ; frame-count rlm@145: 0x00 ;D320 ; v-blank-prev rlm@145: rlm@145: 0xFA ;D321 rlm@145: 0x41 ;D322 ; load (FF41) into A rlm@145: 0xFF ;D323 ; this contains mode flags rlm@145: rlm@145: ;; if we're in v-blank, the bit-1 is 0 rlm@145: ;; and bit-2 is 1 Otherwise, it is not v-blank. rlm@145: 0xCB ;D324 ; test bit-1 of A rlm@145: 0x4F ;D325 rlm@145: rlm@145: 0xC2 ;D326 ; if bit-1 is not 0 rlm@145: 0x44 ;D327 ; GOTO not-v-blank rlm@145: 0xD3 ;D328 rlm@145: rlm@145: 0xCB ;D329 ; test bit-0 of A rlm@145: 0x47 ;D32A rlm@145: rlm@145: 0xCA ;D32B ; if bit-0 is not 1 rlm@145: 0x44 ;D32C ; GOTO not-v-blank rlm@145: 0xD3 ;D32D rlm@145: ;;; in v-blank mode rlm@145: ;; if v-blank-prev was 0, rlm@145: ;; increment frame-count rlm@145: rlm@145: 0xFA ;D32E ; load v-blank-prev to A rlm@145: 0x20 ;D32F rlm@145: 0xD3 ;D330 rlm@145: rlm@145: 0xCB ;D331 rlm@145: 0x47 ;D332 ; test bit-0 of A rlm@145: rlm@145: 0x20 ;D333 ; skip next section rlm@145: 0x07 ;D334 ; if v-blank-prev was not zero rlm@145: rlm@145: ;; v-blank was 0, increment frame-count rlm@145: 0xFA ;D335 ; load frame-count into A rlm@145: 0x1F ;D336 rlm@145: 0xD3 ;D337 rlm@145: rlm@145: 0x3C ;D338 ; inc A rlm@145: rlm@145: 0xEA ;D339 ; load A into frame-count rlm@145: 0x1F ;D33A rlm@145: 0xD3 ;D33B rlm@145: rlm@145: ;; set v-blank-prev to 1 rlm@145: 0x3E ;D33C ; load 1 into A rlm@145: 0x01 ;D33D rlm@145: rlm@145: 0xEA ;D33E ; load A into v-blank-prev rlm@145: 0x20 ;D33F rlm@145: 0xD3 ;D340 rlm@145: rlm@145: 0xC3 ;D341 ; return to beginning rlm@145: 0x1D ;D342 rlm@145: 0xD3 ;D343 rlm@145: rlm@145: ;;; not in v-blank mode rlm@145: ;; set v-blank-prev to 0 rlm@145: 0x3E ;D344 ; load 0 into A rlm@145: 0x00 ;D345 rlm@145: rlm@145: 0xEA ;D346 ; load A into v-blank-prev rlm@145: 0x20 ;D347 rlm@145: 0xD3 ;D348 rlm@145: rlm@145: 0xC3 ;D349 ; return to beginning rlm@145: 0x1D ;D34A rlm@145: 0xD3 ;D34B rlm@145: ]))) rlm@145: rlm@145: (defn step-count-frames [] rlm@145: (-> (read-down-button) rlm@145: (d-tick) rlm@145: (tick) ;; skip over data section rlm@145: (d-tick) rlm@145: (view-register "Register A" A) rlm@145: (tick) ;; load-data into A rlm@145: (view-register "Register A" A) rlm@145: (d-tick) rlm@145: (view-memory 0xFF00) rlm@145: (tick) ;; load A into 0xFF00 rlm@145: (view-memory 0xFF00) rlm@145: (d-tick) rlm@145: (tick) rlm@145: (d-tick) rlm@145: (tick) rlm@145: (d-tick) rlm@145: (tick) rlm@145: (d-tick) rlm@145: (tick) rlm@145: (d-tick) rlm@145: (tick) rlm@145: (d-tick) rlm@145: (tick) rlm@145: (print-inventory))) rlm@145: rlm@145: (defn test-count-frames [] rlm@145: (= 255 (aget (memory ((apply comp (repeat 255 step)) rlm@145: (count-frames))) rlm@145: 0xD31F))) rlm@145: rlm@145: ;; specs for main bootstrap program rlm@145: ;; starts in "mode-select" mode rlm@145: ;; Each button press takes place in a single frame. rlm@145: ;; mode-select-mode takes one of the main buttons rlm@145: ;; which selects one of up to eight modes rlm@145: ;; mode 1 activated by the "A" button rlm@145: ;; the next two button presses indicates the start rlm@145: ;; memory location which to which the bootstrap rlm@145: ;; program will write. rlm@145: ;; This is done by using each of the eight buttons to rlm@145: ;; spell out an 8 bit number. The order of buttons is rlm@145: ;; [:d :u :l :r :start :select :b :a] rlm@145: ;; [:a :start :l] --> 00101001 rlm@145: rlm@145: ;; the next button press determines how many bytes are to be rlm@145: ;; written, starting at the start position. rlm@145: rlm@145: ;; then, the actual bytes are entered and are written to the rlm@145: ;; start address in sequence. rlm@145: rlm@145: (defn input-number-assembly [] rlm@145: [0x18 ;D31D ; jump over rlm@145: 0x02 ;D31E ; the next 2 bytes rlm@145: 0x00 ;D31F ; frame-count rlm@145: 0x00 ;D320 ; v-blank-prev rlm@145: rlm@145: 0xFA ;D321 rlm@145: 0x41 ;D322 ; load (FF41) into A rlm@145: 0xFF ;D323 ; this contains mode flags rlm@145: rlm@145: ;; if we're in v-blank, the bit-1 is 0 rlm@145: ;; and bit-2 is 1 Otherwise, it is not v-blank. rlm@145: 0xCB ;D324 ; test bit-1 of A rlm@145: 0x4F ;D325 rlm@145: rlm@145: 0xC2 ;D326 ; if bit-1 is not 0 rlm@145: 0x44 ;D327 ; GOTO not-v-blank rlm@145: 0xD3 ;D328 rlm@145: rlm@145: 0xCB ;D329 ; test bit-0 of A rlm@145: 0x47 ;D32A rlm@145: rlm@145: 0xCA ;D32B ; if bit-0 is not 1 rlm@145: 0x44 ;D32C ; GOTO not-v-blank rlm@145: 0xD3 ;D32D rlm@145: rlm@145: ;;; in v-blank mode rlm@145: rlm@145: ;; if v-blank-prev was 0, rlm@145: ;; increment frame-count rlm@145: rlm@145: 0xFA ;D32E ; load v-blank-prev to A rlm@145: 0x20 ;D32F rlm@145: 0xD3 ;D330 rlm@145: rlm@145: 0xCB ;D331 rlm@145: 0x47 ;D332 ; test bit-0 of A rlm@145: rlm@145: 0x20 ;D333 ; skip next section rlm@145: 0x07 ;D334 ; if v-blank-prev was not zero rlm@145: rlm@145: ;; v-blank was 0, increment frame-count rlm@145: 0xFA ;D335 ; load frame-count into A rlm@145: 0x1F ;D336 rlm@145: 0xD3 ;D337 rlm@145: rlm@145: 0x3C ;D338 ; inc A rlm@145: rlm@145: 0xEA ;D339 ; load A into frame-count rlm@145: 0x1F ;D33A rlm@145: 0xD3 ;D33B rlm@145: rlm@145: ;; set v-blank-prev to 1 rlm@145: 0x3E ;D33C ; load 1 into A rlm@145: 0x01 ;D33D rlm@145: rlm@145: 0xEA ;D33E ; load A into v-blank-prev rlm@145: 0x20 ;D33F rlm@145: 0xD3 ;D340 rlm@145: rlm@145: 0xC3 ;D341 ; GOTO input handling code rlm@145: 0x4E ;D342 rlm@145: 0xD3 ;D343 rlm@145: rlm@145: ;;; not in v-blank mode rlm@145: ;; set v-blank-prev to 0 rlm@145: 0x3E ;D344 ; load 0 into A rlm@145: 0x00 ;D345 rlm@145: rlm@145: 0xEA ;D346 ; load A into v-blank-prev rlm@145: 0x20 ;D347 rlm@145: 0xD3 ;D348 rlm@145: rlm@145: 0xC3 ;D349 ; return to beginning rlm@145: 0x1D ;D34A rlm@145: 0xD3 ;D34B rlm@145: rlm@145: 0x00 ;D34C ; these are here rlm@145: 0x00 ;D34D ; for glue rlm@145: rlm@145: rlm@145: ;;; calculate input number based on button presses rlm@145: 0x18 ;D34E ; skip next 3 bytes rlm@145: 0x03 ;D34F rlm@145: ;D350 rlm@145: (Integer/parseInt "00100000" 2) ; select directional pad rlm@145: ;D351 rlm@145: (Integer/parseInt "00010000" 2) ; select buttons rlm@145: 0x00 ;D352 ; input-number rlm@145: rlm@145: ;; select directional pad, store low bits in B rlm@145: rlm@145: 0xFA ;D353 ; load (D350) into A rlm@145: 0x50 ;D354 --> rlm@145: 0xD3 ;D355 --> D31F rlm@145: rlm@145: 0xEA ;D356 ; load A, which is rlm@145: 0x00 ;D357 --> ; 00010000, into FF00 rlm@145: 0xFF ;D358 --> FF00 rlm@145: rlm@145: 0x06 ;D359 rlm@145: ;D35A rlm@145: (Integer/parseInt "11110000" 2) ; "11110000" -> B rlm@145: 0xFA ;D35B ; (FF00) -> A rlm@145: 0x00 ;D35C rlm@145: 0xFF ;D35D rlm@145: rlm@145: 0xCB ;D35E ; swap nybbles on A rlm@145: 0x37 ;D35F rlm@145: 0xA0 ;D360 ; (AND A B) -> A rlm@145: 0x47 ;D361 ; A -> B rlm@145: rlm@145: ;; select buttons store bottom bits in C rlm@145: rlm@145: 0xFA ; ; load (D351) into A rlm@145: 0x51 ; --> rlm@145: 0xD3 ; --> D31F rlm@145: rlm@145: 0xEA ; ; load (A), which is rlm@145: 0x00 ; --> ; 00001000, into FF00 rlm@145: 0xFF ; --> FF00 rlm@145: rlm@145: 0x0E ; rlm@145: (Integer/parseInt "00001111" 2) ; "00001111" -> C rlm@145: rlm@145: 0xFA ; ; (FF00) -> A rlm@145: 0x00 ; rlm@145: 0xFF ; rlm@145: rlm@145: 0xA1 ; ; (AND A C) -> A rlm@145: 0x4F ; ; A -> C rlm@145: rlm@145: ;; combine the B and C registers into the input number rlm@145: 0x79 ; ; C -> A rlm@145: 0xB0 ; ; (OR A B) -> A rlm@145: 0x2F ; ; negate A rlm@145: rlm@145: 0xEA ; ; store A into input-number rlm@145: 0x52 ; rlm@145: 0xD3 ; rlm@145: rlm@145: 0xC3 ; ; return to beginning rlm@145: 0x1D ; rlm@145: 0xD3 ; rlm@145: ]) rlm@145: rlm@145: rlm@145: rlm@145: (defn input-number [] rlm@145: (-> (tick (mid-game)) rlm@145: (IE! 0) ; disable interrupts rlm@145: (inject-item-assembly (input-number-assembly)))) rlm@145: rlm@145: (defn test-input-number rlm@145: "Input freestyle buttons and observe the effects at the repl." rlm@145: [] rlm@145: (set-state! (input-number)) rlm@145: (dotimes [_ 90000] (step (view-memory @current-state 0xD352)))) rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: (defn write-memory-assembly* rlm@145: "Currently, grabs input from the user each frame." rlm@145: [] rlm@145: [ rlm@145: ;; --------- FRAME METRONOME rlm@145: 0x18 ;; jump ahead to cleanup. first time only. rlm@145: 0x40 ;; v-blank-prev [D31E] rlm@145: rlm@145: 0xFA ;; load modes into A [D31F] rlm@145: 0x41 rlm@145: 0xFF rlm@145: rlm@145: 0x47 ;; A -> B rlm@145: 0xCB ;; rotate A rlm@145: 0x2F rlm@145: 0x2F ;; invert A rlm@145: rlm@145: 0xA0 rlm@145: 0x47 ;; now B_0 contains (VB==1) rlm@145: rlm@145: 0xFA ;; load v-blank-prev rlm@145: 0x1E rlm@145: 0xD3 rlm@145: rlm@145: 0x2F ;; complement v-blank-prev rlm@145: rlm@145: 0xA0 ;; A & B --> A rlm@145: 0x4F ;; now C_0 contains increment? rlm@145: rlm@145: rlm@145: 0x78 ;; B->A rlm@145: 0xEA ;; spit A --> vbprev rlm@145: 0x1E rlm@145: 0xD3 rlm@145: rlm@145: 0xCB ;test C_0 rlm@145: 0x41 rlm@145: 0x20 ; JUMP ahead to button input if nonzero rlm@145: 0x02 rlm@145: 0x18 ; JUMP back to frame metronome (D31F) rlm@145: 0xE7 rlm@145: rlm@145: ;; -------- GET BUTTON INPUT rlm@145: rlm@145: ;; btw, C_0 is now 1 rlm@145: ;; prepare to select bits rlm@145: rlm@145: 0x06 ;; load 0x00 into B rlm@145: 0x00 ;; to initialize for "OR" loop rlm@145: rlm@145: 0x3E ;; load 0x20 into A, to measure dpad rlm@145: 0x20 rlm@145: rlm@145: rlm@145: 0xE0 ;; load A into [FF00] ;; start of OR loop [D33C] rlm@145: 0x00 rlm@145: rlm@145: 0xF0 ;; load A from [FF00] rlm@145: 0x00 rlm@145: rlm@145: 0xE6 ;; bitmask 00001111 rlm@145: 0x0F rlm@145: rlm@145: 0xB0 ;; A or B --> A rlm@145: 0xCB rlm@145: 0x41 ;; test bit 0 of C rlm@145: 0x28 ;; JUMP forward if 0 rlm@145: 0x08 rlm@145: rlm@145: 0x47 ;; A -> B rlm@145: 0xCB ;; swap B nybbles rlm@145: 0x30 rlm@145: 0x0C ;; increment C rlm@145: 0x3E ;; load 0x10 into A, to measure btns rlm@145: 0x10 rlm@145: 0x18 ;; JUMP back to "load A into [FF00]" [20 steps?] rlm@145: 0xED rlm@145: rlm@145: rlm@145: ;; ------ TAKE ACTION BASED ON USER INPUT rlm@145: rlm@145: ;; "input mode" rlm@145: ;; mode 0x00 : select mode rlm@145: ;; mode 0x08 : select bytes-to-write rlm@145: ;; mode 0x10 : select hi-bit rlm@145: ;; mode 0x18 : select lo-bit rlm@145: rlm@145: ;; "output mode" rlm@145: ;; mode 0x20 : write bytes rlm@145: ;; mode 0xFF : jump PC rlm@145: rlm@145: rlm@145: ;; registers rlm@145: ;; D : mode select rlm@145: ;; E : count of bytes to write rlm@145: ;; H : address-high rlm@145: ;; L : address-low rlm@145: rlm@145: ;; now A contains the pressed keys rlm@145: 0x2F ; complement A, by request. [D34F] rlm@145: rlm@145: 0x47 ; A->B ;; now B contains the pressed keys rlm@145: 0x7B ; E->A ;; now A contains the count. rlm@145: rlm@145: 0xCB ; test bit 5 of D (are we in o/p mode?) rlm@145: 0x6A rlm@145: 0x28 ; if test == 0, skip this o/p section rlm@145: 0x13 ; JUMP rlm@145: rlm@145: 0xCB ; else, test bit 0 of D (fragile; are we in pc mode?) rlm@145: 0x42 rlm@145: 0x28 ; if test == 0, skip the following command rlm@145: 0x01 rlm@145: rlm@145: ;; output mode I: moving the program counter rlm@145: 0xE9 ; ** move PC to (HL) rlm@145: rlm@145: ;; output mode II: writing bytes rlm@145: 0xFE ; A compare 0. finished writing? rlm@145: 0x00 rlm@145: 0x20 ; if we are not finished, skip cleanup rlm@145: 0x04 ; JUMP rlm@145: rlm@145: ;; CLEANUP rlm@145: ;; btw, A is already zero. rlm@145: 0xAF ; zero A [D35F] rlm@145: 0x57 ; A->D; makes D=0. rlm@145: 0x18 ; end of frame rlm@145: 0xBC rlm@145: rlm@145: ;; ---- end of cleanup rlm@145: rlm@145: rlm@145: ;; continue writing bytes rlm@145: 0x1D ;; decrement E, the number of bytes to write [D363] rlm@145: 0x78 ;; B->A; now A contains the pressed keys rlm@145: 0x77 ;; copy A to (HL) rlm@145: 0x23 ;; increment HL rlm@145: 0x18 ;; end frame. [goto D31F] rlm@145: 0xB6 ;; TODO: set skip length backwards rlm@145: rlm@145: rlm@145: ;; ---- end of o/p section rlm@145: rlm@145: ;; i/p mode rlm@145: ;; adhere to the mode discipline: rlm@145: ;; D must be one of 0x00 0x08 0x10 0x18. rlm@145: rlm@145: 0x3E ;; load the constant 57 into A. [D369] rlm@145: 0x57 rlm@145: 0x82 ;; add the mode to A rlm@145: 0xEA ;; store A into "thing to execute" rlm@145: 0x74 rlm@145: 0xD3 rlm@145: rlm@145: 0x3E ;; load the constant 8 into A rlm@145: 0x08 rlm@145: 0x82 ;; add the mode to A rlm@145: rlm@145: 0x57 ;; store the incremented mode into D rlm@145: 0x78 ;; B->A; now A contains the pressed keys rlm@145: rlm@145: 0x00 ;; var: thing to execute [D374] rlm@145: rlm@145: 0x18 ;; end frame rlm@145: 0xA8 rlm@145: ] rlm@145: ) rlm@145: rlm@145: (defn write-mem-dyl [] rlm@145: (-> (tick (mid-game)) rlm@145: (IE! 0) rlm@145: (inject-item-assembly (write-memory-assembly*)))) rlm@145: rlm@145: rlm@145: (defn dylan* [] rlm@145: (-> rlm@145: (write-mem-dyl) rlm@145: rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: rlm@145: ;;(view-memory 0xD374) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: ;;(view-memory 0xD374) rlm@145: (d-tick) rlm@145: rlm@145: (view-register "A" A) rlm@145: (view-register "B" B) rlm@145: (view-register "C" C)) rlm@145: rlm@145: ) rlm@145: rlm@145: rlm@145: (defn dylan [] rlm@145: (-> rlm@145: (write-mem-dyl) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) ;; first loop rlm@145: rlm@145: rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) ;; dpad bits rlm@145: rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (d-tick) rlm@145: rlm@145: rlm@145: rlm@145: (view-register "A" A) rlm@145: (view-register "B" B) rlm@145: (view-register "C" C) rlm@145: rlm@145: )) rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: (defn d2 [] rlm@145: (-> rlm@145: (write-mem-dyl) rlm@145: (view-memory 0xD31F) rlm@145: step step step step step rlm@145: (view-memory 0xD31F))) rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: rlm@145: (defn write-memory-assembly [] rlm@145: [ rlm@145: ;; Main Timing Loop rlm@145: ;; Constantly check for v-blank and Trigger main state machine on rlm@145: ;; every transtion from v-blank to non-v-blank. rlm@145: rlm@145: 0x18 ; D31D ; Variable declaration rlm@145: 0x02 ; D31E rlm@145: 0x00 ; D31F ; frame-count rlm@145: 0x00 ; D320 ; v-blank-prev rlm@145: rlm@145: 0xF0 ; D321 ; load v-blank mode flags into A rlm@145: 0x41 rlm@145: 0x00 rlm@145: rlm@145: rlm@145: ;; Branch dependent on v-blank. v-blank happens when the last two rlm@145: ;; bits in A are "01" rlm@145: 0xCB ; D324 rlm@145: 0x4F ; D325 rlm@145: rlm@145: 0xC2 ; D326 ; if bit-1 is not 0, then rlm@145: 0x3E ; D327 ; GOTO non-v-blank. rlm@145: 0xD3 ; D328 rlm@145: rlm@145: 0xCB ; D329 rlm@145: 0x47 ; D32A rlm@145: rlm@145: 0xCA ; D32B ; if bit-0 is not 1, then rlm@145: 0x3E ; D32C ; GOTO non-v-blank. rlm@145: 0xD3 ; D32D rlm@145: rlm@145: ;; V-Blank rlm@145: ;; Activate state-machine if this is a transition event. rlm@145: rlm@145: 0xFA ; D32E ; load v-bank-prev into A rlm@145: 0x20 ; D32F rlm@145: 0xD3 ; D330 rlm@145: rlm@145: 0xFE ; D331 ; compare A to 0. >--------\ rlm@145: 0x00 ; D332 \ rlm@145: ; | rlm@145: ;; set v-blank-prev to 1. | rlm@145: 0x3E ; D333 ; load 1 into A. | rlm@145: 0x01 ; D334 | rlm@145: ; | rlm@145: 0xEA ; D335 ; load A into v-blank-prev | rlm@145: 0x20 ; D336 | rlm@145: 0xD3 ; D337 | rlm@145: ; / rlm@145: ;; if v-blank-prev was 0, activate state-machine <------/ rlm@145: 0xCA ; D338 ; if v-blank-prev rlm@145: 0x46 ; D339 ; was 0, rlm@145: 0xD3 ; D33A ; GOTO state-machine rlm@145: rlm@145: 0xC3 ; D33B rlm@145: 0x1D ; D33C rlm@145: 0xD3 ; D33D ; GOTO beginning rlm@145: ;; END V-blank rlm@145: rlm@145: ;; Non-V-Blank rlm@145: ;; Set v-blank-prev to 0 rlm@145: 0x3E ; D33E ; load 0 into A rlm@145: 0x00 ; D33F rlm@145: rlm@145: 0xEA ; D340 ; load A into v-blank-prev rlm@145: 0x20 ; D341 rlm@145: 0xD3 ; D342 rlm@145: rlm@145: 0xC3 ; D343 rlm@145: 0x1D ; D344 rlm@145: 0xD3 ; D345 ; GOTO beginning rlm@145: ;; END Not-V-Blank rlm@145: rlm@145: rlm@145: ;; Main State Machine -- Input Section rlm@145: ;; This is called once every frame. rlm@145: ;; It collects input and uses it to drive the rlm@145: ;; state transitions. rlm@145: rlm@145: ;; Increment frame-count rlm@145: 0xFA ; D346 ; load frame-count into A rlm@145: 0x1F ; D347 rlm@145: 0xD3 ; D348 rlm@145: rlm@145: 0x3C ; D349 ; inc A rlm@145: rlm@145: 0xEA ; D34A rlm@145: 0x1F ; D34B ; load A into frame-count rlm@145: 0xD3 ; D34C rlm@145: rlm@145: 0x00 ; D34D ; glue :) rlm@145: rlm@145: 0x18 ;D34E ; skip next 3 bytes rlm@145: 0x03 ;D34F rlm@145: ;D350 rlm@145: (Integer/parseInt "00100000" 2) ; select directional pad rlm@145: ;D351 rlm@145: (Integer/parseInt "00010000" 2) ; select buttons rlm@145: 0x00 ;D352 ; input-number rlm@145: rlm@145: ;; select directional pad; store low bits in B rlm@145: rlm@145: 0xFA ;D353 ; load (D350) into A rlm@145: 0x50 ;D354 --> rlm@145: 0xD3 ;D355 --> D350 rlm@145: rlm@145: 0xE0 ;D356 ; load (A), which is rlm@145: 0x00 ;D357 --> ; 00010000, into FF00 rlm@145: 0x00 ;D358 --> FF00 ;; NO-OP rlm@145: rlm@145: 0x06 ;D359 rlm@145: ;D35A rlm@145: (Integer/parseInt "11110000" 2) ; "11110000" -> B rlm@145: 0xF0 ;D35B ; (FF00) -> A rlm@145: 0x00 ;D35C rlm@145: 0x00 ;D35D ;; NO-OP rlm@145: rlm@145: 0xCB ;D35E ; swap nybbles on A rlm@145: 0x37 ;D35F rlm@145: 0xA0 ;D360 ; (AND A B) -> A rlm@145: 0x47 ;D361 ; A -> B rlm@145: rlm@145: ;; select buttons; store bottom bits in C rlm@145: rlm@145: 0xFA ;D362 ; load (D351) into A rlm@145: 0x51 ;D363 --> rlm@145: 0xD3 ;D364 --> D351 rlm@145: rlm@145: 0xE0 ;D365 ; load (A), which is rlm@145: 0x00 ;D366 --> ; 00001000, into FF00 rlm@145: 0x00 ;D367 --> FF00 ;; NO-OP rlm@145: rlm@145: 0x0E ;D368 rlm@145: ;D369 rlm@145: (Integer/parseInt "00001111" 2) ; "00001111" -> C rlm@145: rlm@145: 0xF0 ;D36A ; (FF00) -> A rlm@145: 0x00 ;D36B rlm@145: 0x00 ;D36C rlm@145: rlm@145: 0xA1 ;D36D ; (AND A C) -> A rlm@145: 0x4F ;D36E ; A -> C rlm@145: rlm@145: ;; combine the B and C registers into the input number rlm@145: 0x79 ;D36F ; C -> A rlm@145: 0xB0 ;D370 ; (OR A B) -> A rlm@145: 0x2F ;D371 ; negate A rlm@145: rlm@145: 0xEA ;D372 ; store A into input-number rlm@145: 0x52 ;D373 rlm@145: 0xD3 ;D374 rlm@145: rlm@145: 0x00 ;D375 rlm@145: 0x00 ;D376 rlm@145: 0x00 ;D377 rlm@145: 0x00 ;D378 rlm@145: 0x00 ;D379 rlm@145: 0x00 ;D37A rlm@145: 0x00 ;D37B ; these are here because rlm@145: 0x00 ;D37C ; I messed up :( rlm@145: 0x00 ;D37D rlm@145: 0x00 ;D37E rlm@145: 0x00 ;D37F rlm@145: rlm@145: ;; beginning of main state machine rlm@145: 0x18 ;D380 ; Declaration of variables rlm@145: 0x05 ;D381 ; 5 variables: rlm@145: 0x00 ;D382 ; current-mode rlm@145: 0x00 ;D383 ; bytes-to-write rlm@145: 0x00 ;D384 ; bytes-written rlm@145: 0x00 ;D385 ; start-point-high rlm@145: 0x00 ;D386 ; start-point-low rlm@145: rlm@145: rlm@145: ;; banch on current mode rlm@145: 0xFA ;D387 ; load current-mode (0xD382) rlm@145: 0x82 ;D388 ; into A rlm@145: 0xD3 ;D389 rlm@145: 0x00 ;D38A rlm@145: rlm@145: rlm@145: ;; GOTO Mode 0 (input-mode) if current-mode is 0 rlm@145: 0xFE ;D38B rlm@145: 0x00 ;D38C ; compare A with 0x00 rlm@145: rlm@145: 0xCA ;D38D ; goto Mode 0 if A == 0 rlm@145: 0xA8 ;D38E rlm@145: 0xD3 ;D38F rlm@145: rlm@145: ;; GOTO Mode 1 (set-length) if current-mode is 1 rlm@145: 0xFE ;D390 rlm@145: 0x01 ;D391 ; compare A with 0x01 rlm@145: rlm@145: 0xCA ;D392 rlm@145: 0xB1 ;D393 rlm@145: 0xD3 ;D394 ; goto Mode 1 if A == 1 rlm@145: rlm@145: ;; GOTO Mode 2 (set-start-point-high) if current mode is 2 rlm@145: 0xFE ;D395 rlm@145: 0x02 ;D396 ; compare A with 0x02 rlm@145: rlm@145: 0xCA ;D397 rlm@145: 0xBF ;D398 rlm@145: 0xD3 ;D399 ; goto Mode 2 if A == 2 rlm@145: rlm@145: ;; GOTO Mode 3 (set-start-point-low) if current mode is 3 rlm@145: 0xFE ;D39A rlm@145: 0x03 ;D39B rlm@145: rlm@145: 0xCA ;D39C rlm@145: 0xCD ;D39D rlm@145: 0xD3 ;D39E ; goto Mode 3 if A == 3 rlm@145: rlm@145: ;; GOTO Mode 4 (write-memory) if current mode is 4 rlm@145: 0xFE ;D39F rlm@145: 0x04 ;D3A0 rlm@145: rlm@145: 0xCA ;D3A1 rlm@145: 0xDB ;D3A2 rlm@145: 0xD3 ;D3A3 rlm@145: rlm@145: 0x00 ;D3A4 rlm@145: ;; End of Mode checking, goto beginning rlm@145: 0xC3 ;D3A5 rlm@145: 0x1D ;D3A6 rlm@145: 0xD3 ;D3A7 rlm@145: rlm@145: rlm@145: ;; Mode 0 -- input-mode mode rlm@145: ;; means that we are waiting for a mode, so set the mode to rlm@145: ;; whatever is currently in input-number. If nothing is rlm@145: ;; entered, then the program stays in input-mode mode rlm@145: rlm@145: ;; set current-mode to input-number rlm@145: 0xFA ;D3A8 ; load input-number (0xD352) rlm@145: 0x52 ;D3A9 ; into A rlm@145: 0xD3 ;D3AA rlm@145: rlm@145: 0xEA ;D3AB ; load A into current-mode rlm@145: 0x82 ;D3AC ; (0xD382) rlm@145: 0xD3 ;D3AD rlm@145: rlm@145: 0xC3 ;D3AE ; go back to beginning rlm@145: 0x1D ;D3AF rlm@145: 0xD3 ;D3B0 rlm@145: ;; End Mode 0 rlm@145: rlm@145: rlm@145: ;; Mode 1 -- set-length mode rlm@145: ;; This is the header for writing things to memory. rlm@145: ;; User specifies the number of bytes to write. rlm@145: ;; Mode is auto advanced to Mode 2 after this mode rlm@145: ;; completes. rlm@145: rlm@145: ;; Set bytes left to write to input-number; rlm@145: ;; set current-mode to 0x02. rlm@145: 0xFA ;D3B1 ; load input-number (0xD352) rlm@145: 0x52 ;D3B2 ; into A rlm@145: 0xD3 ;D3B3 rlm@145: rlm@145: 0xEA ;D3B4 ; load A into bytes-left-to-write rlm@145: 0x83 ;D3B5 ; (0xD383) rlm@145: 0xD3 ;D3B6 rlm@145: rlm@145: 0x3E ;D3B7 ; load 0x02 into A. rlm@145: 0x02 ;D3B8 rlm@145: rlm@145: 0xEA ;D3B9 ; load A to current-mode rlm@145: 0x82 ;D3BA ; advancing from Mode 1 to rlm@145: 0xD3 ;D3BB ; Mode 2 rlm@145: rlm@145: 0xC3 ;D3BC ; go back to beginning rlm@145: 0x1D ;D3BD rlm@145: 0xD3 ;D3BE rlm@145: ;; End Mode 1 rlm@145: rlm@145: rlm@145: ;; Mode 2 -- set start-point-high mode rlm@145: ;; Middle part of the header for writing things to memory. rlm@145: ;; User specifies the start location in RAM to which rlm@145: ;; data will be written. rlm@145: ;; Mode is auto advanced to Mode 3 after this mode completes. rlm@145: rlm@145: ;; Set start-point-high to input-number; rlm@145: ;; set current mode to 0x03. rlm@145: 0xFA ;D3BF ; load input-number (0xD352) rlm@145: 0x52 ;D3C0 ; into A rlm@145: 0xD3 ;D3C1 rlm@145: rlm@145: 0xEA ;D3C2 ; load A into start-point-high rlm@145: 0x85 ;D3C3 ; (0xD385) rlm@145: 0xD3 ;D3C4 rlm@145: rlm@145: 0x3E ;D3C5 ; load 0x03 into A. rlm@145: 0x03 ;D3C6 rlm@145: rlm@145: 0xEA ;D3C7 ; load A to current-mode, rlm@145: 0x82 ;D3C8 ; advancing from Mode 2 to rlm@145: 0xD3 ;D3C9 ; Mode 3. rlm@145: rlm@145: 0xC3 ;D3CA ; go back to beginning rlm@145: 0x1D ;D3CB rlm@145: 0xD3 ;D3CC rlm@145: ;;End Mode 2 rlm@145: rlm@145: rlm@145: ;; Mode 3 -- set-start-point-low mode rlm@145: ;; Final part of header for writing things to memory. rlm@145: ;; User specifies the low bytes of 16 bit start-point. rlm@145: rlm@145: ;; Set start-point-low to input-number; rlm@145: ;; set current mode to 0x04 rlm@145: 0xFA ;D3CD ; load input-number into A rlm@145: 0x52 ;D3CE rlm@145: 0xD3 ;D3CF rlm@145: rlm@145: 0xEA ;D3D0 ; load A into start-point-low rlm@145: 0x86 ;D3D1 rlm@145: 0xD3 ;D3D2 rlm@145: rlm@145: 0x3E ;D3D3 ; load 0x04 into A. rlm@145: 0x04 ;D3D4 rlm@145: rlm@145: 0xEA ;D3D5 ; load A to current-mode, rlm@145: 0x82 ;D3D6 ; advancing from Mode 3 to rlm@145: 0xD3 ;D3D7 ; Mode 4. rlm@145: rlm@145: 0xC3 ;D3D8 ; go back to beginning rlm@145: 0x1D ;D3D9 rlm@145: 0xD3 ;D3DA rlm@145: rlm@145: ;; Mode 4 -- write bytes mode rlm@145: rlm@145: ;; This is where RAM manipulation happens. User supplies rlm@145: ;; bytes every frame, which are written sequentially to rlm@145: ;; start-point until bytes-to-write have been written. Once rlm@145: ;; bytes-to-write have been written, the mode is reset to 0. rlm@145: rlm@145: ;; compare bytes-written with bytes-to-write. rlm@145: ;; if they are the same, then reset mode to 0 rlm@145: rlm@145: 0xFA ;D3DB ; load bytes-to-write into A rlm@145: 0x83 ;D3DC rlm@145: 0xD3 ;D3DD rlm@145: rlm@145: 0x47 ;D3DE ; load A into B rlm@145: rlm@145: 0xFA ;D3DF ; load bytes-written into A rlm@145: 0x84 ;D3E0 rlm@145: 0xD3 ;D3E1 rlm@145: rlm@145: 0xB8 ;D3E2 ; compare A with B rlm@145: rlm@145: 0xCA ;D3E3 ; if they are equal, go to cleanup rlm@145: 0x07 ;D3E4 rlm@145: 0xD4 ;D3E5 rlm@145: rlm@145: ;; Write Memory Section rlm@145: ;; Write the input-number, interpreted as an 8-bit number, rlm@145: ;; into the current target register, determined by rlm@145: ;; (+ start-point bytes-written). rlm@145: ;; Then, increment bytes-written by 1. rlm@145: rlm@145: 0xFA ;D3E6 ; load start-point-high into A rlm@145: 0x85 ;D3E7 rlm@145: 0xD3 ;D3E8 rlm@145: rlm@145: 0x67 ;D3E9 ; load A into H rlm@145: rlm@145: 0xFA ;D3EA ; load start-point-low into A rlm@145: 0x86 ;D3EB rlm@145: 0xD3 ;D3EC rlm@145: rlm@145: 0x6F ;D3ED ; load A into L rlm@145: rlm@145: 0xFA ;D3EE ; load bytes-written into A rlm@145: 0x84 ;D3EF rlm@145: 0xD3 ;D3F0 rlm@145: rlm@145: 0x00 ;D3F1 ; These are here because rlm@145: 0x00 ;D3F2 ; I screwed up again. rlm@145: 0x00 ;D3F3 rlm@145: rlm@145: 0x85 ;D3F4 ; add L to A; store A in L. rlm@145: 0x6F ;D3F5 rlm@145: rlm@145: 0x30 ;D3F6 ; If the addition overflowed, rlm@145: 0x01 ;D3F7 rlm@145: 0x24 ;D3F8 ; increment H. rlm@145: rlm@145: ;; Now, HL points to the correct place in memory rlm@145: rlm@145: 0xFA ;D3F9 ; load input-number into A rlm@145: 0x52 ;D3FA rlm@145: 0xD3 ;D3FB rlm@145: rlm@145: 0x77 ;D3FC ; load A into (HL) rlm@145: rlm@145: 0xFA ;D3FD ; load bytes-written into A rlm@145: 0x84 ;D3FE rlm@145: 0xD3 ;D3FF rlm@145: rlm@145: 0x3C ;D400 ; increment A rlm@145: rlm@145: 0xEA ;D401 ; load A into bytes-written rlm@145: 0x84 ;D402 rlm@145: 0xD3 ;D403 rlm@145: rlm@145: 0xC3 ;D404 ; go back to beginning. rlm@145: 0x1D ;D405 rlm@145: 0xD3 ;D406 rlm@145: ;; End Write Memory Section rlm@145: rlm@145: ;; Mode 4 Cleanup Section rlm@145: ;; reset bytes-written to 0 rlm@145: ;; set mode to 0 rlm@145: 0x3E ;D407 ; load 0 into A rlm@145: 0x00 ;D408 rlm@145: rlm@145: 0xEA ;D409 ; load A into bytes-written rlm@145: 0x84 ;D40A rlm@145: 0xD3 ;D40B rlm@145: rlm@145: 0xEA ;D40C ; load A into current-mode rlm@145: 0x82 ;D40D rlm@145: 0xD3 ;D40E rlm@145: rlm@145: 0xC3 ;D40F ; go back to beginning rlm@145: 0x1D ;D410 rlm@145: 0xD3 ;D411 rlm@145: rlm@145: ;; End Mode 4 rlm@145: rlm@145: ]) rlm@145: rlm@145: rlm@145: rlm@145: (def frame-count 0xD31F) rlm@145: (def input 0xD352) rlm@145: (def current-mode 0xD382) rlm@145: (def bytes-to-write 0xD383) rlm@145: (def bytes-written 0xD384) rlm@145: (def start-point-high 0xD385) rlm@145: (def start-point-low 0xD386) rlm@145: rlm@145: rlm@145: rlm@145: (defn write-memory [] rlm@145: (-> (tick (mid-game)) rlm@145: (IE! 0) ; disable interrupts rlm@145: (inject-item-assembly (write-memory-assembly)))) rlm@145: rlm@145: (defn test-write-memory [] rlm@145: (set-state! (write-memory)) rlm@145: (dorun rlm@145: (dotimes [_ 5000] rlm@145: (view-memory (step @current-state) current-mode)))) rlm@145: rlm@145: (def bytes-to-write 0xD383) rlm@145: (def start-point 0xD384) rlm@145: rlm@145: (defn print-blank-assembly rlm@145: [start end] rlm@145: (dorun rlm@145: (map rlm@145: #(println (format "0x00 ;%04X " %)) rlm@145: (range start end)))) rlm@145: rlm@145: (defn test-mode-2 [] rlm@145: (-> rlm@145: (write-memory) rlm@145: (view-memory frame-count) rlm@145: (step) rlm@145: (step [:a]) rlm@145: (step [:b]) rlm@145: (step [:start]) rlm@145: (step []) rlm@145: (view-memory frame-count))) rlm@145: rlm@145: rlm@145: rlm@145: (defn dylan-test-mode rlm@145: ([] (dylan-test-mode (write-mem-dyl))) rlm@145: ([target-state] rlm@145: (let [ rlm@145: v-blank-prev 54046 rlm@145: btn-register 65280 rlm@145: eggs 0xD374 rlm@145: ] rlm@145: rlm@145: (-> rlm@145: target-state rlm@145: rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick);; jumps back to beginning rlm@145: rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: rlm@145: rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) ;; just complemented A rlm@145: rlm@145: (tick) rlm@145: (DE! 0x1800) rlm@145: (AF! 0x7700) ;; change inputs @ A rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: rlm@145: ;;(view-memory eggs) rlm@145: (tick) rlm@145: (tick) rlm@145: ;;(view-memory eggs) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (tick) rlm@145: (d-tick) rlm@145: rlm@145: rlm@145: ;;(view-memory btn-register) rlm@145: (view-register "A" A) rlm@145: (view-register "B" B) rlm@145: rlm@145: ;;(view-register "C" C) rlm@145: (view-register "D" D) rlm@145: (view-register "E" E) rlm@145: (view-register "H" H) rlm@145: (view-register "L" L) rlm@145: )))) rlm@145: rlm@145: rlm@145: rlm@145: (defn drive-dylan [] rlm@145: (-> (write-mem-dyl) rlm@145: (#(do (println "memory from 0xC00F to 0xC01F:" rlm@145: (subvec (vec (memory %)) 0xC00F 0xC01F)) %)) rlm@145: (step []) rlm@145: (step []) rlm@145: (step []) rlm@145: (step [:start]) rlm@145: (step [:select]) rlm@145: (step [:u :d]) rlm@145: (step [:a :b :start :select]) rlm@145: (step [:a]) rlm@145: (step [:b]) rlm@145: (step [:a :b]) rlm@145: (step [:select]) rlm@145: (step []) rlm@145: (step []) rlm@145: (step []) rlm@145: (#(do (println "memory from 0xC00F to 0xC01F:" rlm@145: (subvec (vec (memory %)) 0xC00F 0xC01F)) %)) rlm@145: )) rlm@145: rlm@145: (defn test-mode-4 rlm@145: ([] (test-mode-4 (write-memory))) rlm@145: ([target-state] rlm@145: (-> rlm@145: target-state rlm@145: (#(do (println "memory from 0xC00F to 0xC01F:" rlm@145: (subvec (vec (memory %)) 0xC00F 0xC01F)) %)) rlm@145: (view-memory current-mode) rlm@145: (step []) rlm@145: (step []) rlm@145: (step []) rlm@145: (#(do (println "after three steps") %)) rlm@145: (view-memory current-mode) rlm@145: rlm@145: ;; Activate memory writing mode rlm@145: rlm@145: (#(do (println "step with [:a]") %)) rlm@145: (step [:a]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-to-write) rlm@145: (view-memory start-point-high) rlm@145: (view-memory start-point-low) rlm@145: rlm@145: ;; Specify four bytes to be written rlm@145: rlm@145: (#(do (println "step with [:select]")%)) rlm@145: (step [:select]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-to-write) rlm@145: (view-memory start-point-high) rlm@145: (view-memory start-point-low) rlm@145: rlm@145: ;; Specify target memory address as 0xC00F rlm@145: rlm@145: (#(do (println "step with [:u :d]")%)) rlm@145: (step [:u :d]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-to-write) rlm@145: (view-memory start-point-high) rlm@145: (view-memory start-point-low) rlm@145: rlm@145: (#(do (println "step with [:a :b :start :select]")%)) rlm@145: (step [:a :b :start :select]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-to-write) rlm@145: (view-memory start-point-high) rlm@145: (view-memory start-point-low) rlm@145: rlm@145: ;; Start reprogramming memory rlm@145: rlm@145: (#(do (println "step with [:a]")%)) rlm@145: (step [:a]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-written) rlm@145: rlm@145: (#(do (println "step with [:b]")%)) rlm@145: (step [:b]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-written) rlm@145: rlm@145: (#(do (println "step with [:a :b]")%)) rlm@145: (step [:a :b]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-written) rlm@145: rlm@145: (#(do (println "step with [:select]")%)) rlm@145: (step [:select]) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-written) rlm@145: rlm@145: ;; Reprogramming done, program ready for more commands. rlm@145: rlm@145: (#(do (println "step with []")%)) rlm@145: (step []) rlm@145: (view-memory current-mode) rlm@145: (view-memory bytes-written) rlm@145: rlm@145: (#(do (println "memory from 0xC00F to 0xC01F:" rlm@145: (subvec (vec (memory %)) 0xC00F 0xC01F)) %))))) rlm@145: