# HG changeset patch # User Robert McIntyre # Date 1332653925 18000 # Node ID 19fd38fe376e6431802297a086d7142ffee064ab # Parent e23ab90fcc8698b037870b777ff2f7405ccb3893 revived a functional version of Dylan's assembly. diff -r e23ab90fcc86 -r 19fd38fe376e clojure/com/aurellem/exp/item_bridge.clj --- a/clojure/com/aurellem/exp/item_bridge.clj Sun Mar 25 00:08:23 2012 -0500 +++ b/clojure/com/aurellem/exp/item_bridge.clj Sun Mar 25 00:38:45 2012 -0500 @@ -197,9 +197,10 @@ memory-function-address-start insertion-address-bits)))) -(def lemonade-trampoline (partial test-trampoline - trampoline-assembly - (menu-open-state))) +(def lemonade-trampoline + (partial test-trampoline + trampoline-assembly + (menu-open-state))) (defn trampoline-assembly-burn-heal [^SaveState state] (flatten @@ -210,8 +211,8 @@ 0x1D 0xD3 ;; set first item to lemonade - 0xC3 ;; return control to the game via absolute jump. - 0x0C ;; return control to Route 3's map-function + 0xC3 ;; return control to the game via absolute jump + 0x0C ;; to Route 3's map-function 0x55 ])) diff -r e23ab90fcc86 -r 19fd38fe376e clojure/com/aurellem/exp/notes.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clojure/com/aurellem/exp/notes.txt Sun Mar 25 00:38:45 2012 -0500 @@ -0,0 +1,17 @@ +start game + +get pikachu, fight rival, deliver oak's parcel + +buy 5 items from viridian store, with the last one being a +burn-heal. + +Perform save corruption. + +move one of the other items that wasn't destroyed (but not +burn-heal) to the money counter to get a bunch of money. + +buy 94 more burn heals. 95 burn heals spells out the +address that will safely return control to pokemon. + + + diff -r e23ab90fcc86 -r 19fd38fe376e clojure/com/aurellem/gb/assembly.clj --- a/clojure/com/aurellem/gb/assembly.clj Sun Mar 25 00:08:23 2012 -0500 +++ b/clojure/com/aurellem/gb/assembly.clj Sun Mar 25 00:38:45 2012 -0500 @@ -1334,30 +1334,6 @@ (view-register "L" L) )))) - - -(defn drive-dylan [] - (-> (write-mem-dyl) - (#(do (println "memory from 0xC00F to 0xC01F:" - (subvec (vec (memory %)) 0xC00F 0xC01F)) %)) - (step []) - (step []) - (step []) - (step [:start]) - (step [:select]) - (step [:u :d]) - (step [:a :b :start :select]) - (step [:a]) - (step [:b]) - (step [:a :b]) - (step [:select]) - (step []) - (step []) - (step []) - (#(do (println "memory from 0xC00F to 0xC01F:" - (subvec (vec (memory %)) 0xC00F 0xC01F)) %)) - )) - (defn test-mode-4 ([] (test-mode-4 (write-memory))) ([target-state] diff -r e23ab90fcc86 -r 19fd38fe376e clojure/com/aurellem/gb/dylan_assembly.clj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clojure/com/aurellem/gb/dylan_assembly.clj Sun Mar 25 00:38:45 2012 -0500 @@ -0,0 +1,199 @@ +(ns com.aurellem.gb.dylan-assembly + "A much more compact version of write-memory-assembly" + {:author "Dylan Holmes"} + (:use (com.aurellem.gb gb-driver assembly util)) + (:import [com.aurellem.gb.gb_driver SaveState])) + +(defn write-memory-assembly-compact + "Currently, grabs input from the user each frame." + [] + [ + ;; --------- FRAME METRONOME + 0x18 ;; jump ahead to cleanup. first time only. + 0x40 ;; v-blank-prev [D31E] + + 0xFA ;; load modes into A [D31F] + 0x41 + 0xFF + + 0x47 ;; A -> B + 0xCB ;; rotate A + 0x2F + 0x2F ;; invert A + + 0xA0 + 0x47 ;; now B_0 contains (VB==1) + + 0xFA ;; load v-blank-prev + 0x1E + 0xD3 + + 0x2F ;; complement v-blank-prev + + 0xA0 ;; A & B --> A + 0x4F ;; now C_0 contains increment? + + + 0x78 ;; B->A + 0xEA ;; spit A --> vbprev + 0x1E + 0xD3 + + 0xCB ;test C_0 + 0x41 + 0x20 ; JUMP ahead to button input if nonzero + 0x02 + 0x18 ; JUMP back to frame metronome (D31F) + 0xE7 + + ;; -------- GET BUTTON INPUT + + ;; btw, C_0 is now 1 + ;; prepare to select bits + + 0x06 ;; load 0x00 into B + 0x00 ;; to initialize for "OR" loop + + 0x3E ;; load 0x20 into A, to measure dpad + 0x20 + + + 0xE0 ;; load A into [FF00] ;; start of OR loop [D33C] + 0x00 + + 0xF0 ;; load A from [FF00] + 0x00 + + 0xE6 ;; bitmask 00001111 + 0x0F + + 0xB0 ;; A or B --> A + 0xCB + 0x41 ;; test bit 0 of C + 0x28 ;; JUMP forward if 0 + 0x08 + + 0x47 ;; A -> B + 0xCB ;; swap B nybbles + 0x30 + 0x0C ;; increment C + 0x3E ;; load 0x10 into A, to measure btns + 0x10 + 0x18 ;; JUMP back to "load A into [FF00]" [20 steps?] + 0xED + + + ;; ------ TAKE ACTION BASED ON USER INPUT + + ;; "input mode" + ;; mode 0x00 : select mode + ;; mode 0x08 : select bytes-to-write + ;; mode 0x10 : select hi-bit + ;; mode 0x18 : select lo-bit + + ;; "output mode" + ;; mode 0x20 : write bytes + ;; mode 0xFF : jump PC + + + ;; registers + ;; D : mode select + ;; E : count of bytes to write + ;; H : address-high + ;; L : address-low + + ;; now A contains the pressed keys + 0x2F ; complement A, by request. [D34F] + + 0x47 ; A->B ;; now B contains the pressed keys + 0x7B ; E->A ;; now A contains the count. + + 0xCB ; test bit 5 of D (are we in o/p mode?) + 0x6A + 0x28 ; if test == 0, skip this o/p section + 0x13 ; JUMP + + 0xCB ; else, test bit 0 of D (fragile; are we in pc mode?) + 0x42 + 0x28 ; if test == 0, skip the following command + 0x01 + + ;; output mode I: moving the program counter + 0xE9 ; ** move PC to (HL) + + ;; output mode II: writing bytes + 0xFE ; A compare 0. finished writing? + 0x00 + 0x20 ; if we are not finished, skip cleanup + 0x04 ; JUMP + + ;; CLEANUP + ;; btw, A is already zero. + 0xAF ; zero A [D35F] + 0x57 ; A->D; makes D=0. + 0x18 ; end of frame + 0xBC + + ;; ---- end of cleanup + + + ;; continue writing bytes + 0x1D ;; decrement E, the number of bytes to write [D363] + 0x78 ;; B->A; now A contains the pressed keys + 0x77 ;; copy A to (HL) + 0x23 ;; increment HL + 0x18 ;; end frame. [goto D31F] + 0xB6 ;; TODO: set skip length backwards + + + ;; ---- end of o/p section + + ;; i/p mode + ;; adhere to the mode discipline: + ;; D must be one of 0x00 0x08 0x10 0x18. + + 0x3E ;; load the constant 57 into A. [D369] + 0x57 + 0x82 ;; add the mode to A + 0xEA ;; store A into "thing to execute" + 0x74 + 0xD3 + + 0x3E ;; load the constant 8 into A + 0x08 + 0x82 ;; add the mode to A + + 0x57 ;; store the incremented mode into D + 0x78 ;; B->A; now A contains the pressed keys + + 0x00 ;; var: thing to execute [D374] + + 0x18 ;; end frame + 0xA8]) + +(defn write-mem-compact [] + (-> (tick (mid-game)) + (IE! 0) + (inject-item-assembly (write-memory-assembly-compact)))) + +(defn drive-compact [] + (-> (write-mem-compact) + (#(do (println "memory from 0xC00F to 0xC01F:" + (subvec (vec (memory %)) 0xC00F 0xC01F)) %)) + (step []) + (step []) + (step []) + (step [:start]) + (step [:select]) + (step [:u :d]) + (step [:a :b :start :select]) + (step [:a]) + (step [:b]) + (step [:a :b]) + (step [:select]) + (step []) + (step []) + (step []) + (#(do (println "memory from 0xC00F to 0xC01F:" + (subvec (vec (memory %)) 0xC00F 0xC01F)) %)))) +