# HG changeset patch # User Robert McIntyre # Date 1334400115 18000 # Node ID 21b8b3350b2055dee8b4636710507d71d0011d3a # Parent f2f1e0b8c1c79dac08b4fe33f2cd525dcd3e3204 everything works :) now I have total control over the game. diff -r f2f1e0b8c1c7 -r 21b8b3350b20 clojure/com/aurellem/gb/rlm_assembly.clj --- a/clojure/com/aurellem/gb/rlm_assembly.clj Sat Apr 14 04:09:51 2012 -0500 +++ b/clojure/com/aurellem/gb/rlm_assembly.clj Sat Apr 14 05:41:55 2012 -0500 @@ -224,7 +224,7 @@ (if (< n 0) (+ 256 n) n)) -(defn frame-metronome** [] +(defn frame-metronome [] (let [init [0xC5] ;; save value of BC timing-loop [0x01 ; \ @@ -247,18 +247,18 @@ (defn frame-metronome* [] [0x3E ;; smallest version, but uses repeated nybbles - 0x01 + 0x01 0xE0 0xFF]) - -(defn frame-metronome [] +(defn frame-metronome** [] [0x06 ;; load 0xFE into B 0xFE 0x04 ;; inc B, now B == FF - 0x3E + + 0x3E ;; RLM-debug 0x01 ;; 1->A - + 0x48 ;; B->C 0x02]) ;; A->(BC) set exclusive v-blank interrupt @@ -266,8 +266,10 @@ "Ensure that frame-metronome ticks exactly once every frame." ([] (test-frame-metronome 151)) ([steps] - (let [inc-E [0x1C 0x76 0x18 - (->signed-8-bit -4)] + (let [inc-E [0x1C 0x18 + (->signed-8-bit + (+ -3 + (-(count (frame-metronome)))))] program (concat (frame-metronome) inc-E) count-frames @@ -284,10 +286,7 @@ count-frames))) (defn read-user-input [] - [0xAF 0x4F 0x47 ;; 0->A; 0->C; 0->B - 0xC5 ;; save value of BC - - 0x3E + [0x3E 0x20 ; prepare to measure d-pad 0x3F ; clear carry flag no-op to prevent repeated nybbles @@ -378,7 +377,8 @@ ;; multi-action-modes ;; WRITE 0x47 ;; A->B - (let [header (concat (frame-metronome) (read-user-input)) + (let [init [0xAF 0x4F 0x47] ;; 0->A; 0->C; 0->B + header (concat (frame-metronome) (read-user-input)) input [0xC1 ;; pop BC so it's not volatile @@ -409,7 +409,7 @@ 0x7B ;; E->A 0x4F ;; A->C now C stores previous instruction 0x18 ;; return - :to-halt] + :to-jump] output [:output-start ;; just a label @@ -423,7 +423,6 @@ 0x23 ;; inc HL - 0x76 ;; HALT, peasant! 0x18 :to-beginning] @@ -433,11 +432,14 @@ (disect-bytes-2 (+ start-address (count header) + (count init) (symbol-index :to-be-executed input)))) :to-be-executed 0x3F} ;; clear carry flag no-op program** (flatten - (replace symbols (concat header input output))) + (replace + symbols + (concat init header input output))) resolve-internal-jumps {:output-start [] @@ -451,13 +453,13 @@ (flatten (replace resolve-internal-jumps program**)) resolve-external-jumps - {:to-halt + {:to-jump (- (- (symbol-index :to-beginning program*) - (symbol-index :to-halt program*)) 3) + (symbol-index :to-jump program*)) 2) :to-beginning (->signed-8-bit - (+ 2 (count (frame-metronome)) + (+ (count init) -1 (- (symbol-index :to-beginning program*))))} program diff -r f2f1e0b8c1c7 -r 21b8b3350b20 clojure/com/aurellem/run/bootstrap_1.clj --- a/clojure/com/aurellem/run/bootstrap_1.clj Sat Apr 14 04:09:51 2012 -0500 +++ b/clojure/com/aurellem/run/bootstrap_1.clj Sat Apr 14 05:41:55 2012 -0500 @@ -779,18 +779,18 @@ 0xD162 (+ 0xD162 (count pattern))) pattern)))) -(defn launch-main-bootstrap-program +(defn-memo launch-main-bootstrap-program ([] (launch-main-bootstrap-program (control-checkpoint) ;;(launch-bootstrap-program) )) ([script] - (->> script - (play-moves - (bootstrap-pattern (main-bootstrap-program))) - (play-moves - (take 263 (interleave (repeat 1000 [:b]) - (repeat 1000 []))))))) + (->> script + (play-moves + (bootstrap-pattern (main-bootstrap-program))) + (play-moves + (take 253 (interleave (repeat 1000 [:b]) + (repeat 1000 []))))))) (defn test-main-bootstrap-integrety [] @@ -811,17 +811,32 @@ (map buttons [set-H-mode target-high 0x00 set-L-mode target-low 0x00]))))) - + +(defn write-RAM-segment + "Assumes that the game is under control of the main-bootstrap + program in MODE-SELECT mode and that target-address has been + appropriately set, and writes 255 bytes or less to RAM." + [segment script] + (->> script + (play-moves + (map buttons + [write-mode (count segment)])) + (play-moves (map buttons segment)) + (play-moves [[]]))) + (defn write-RAM "Assumes that the game is under control of the main-bootstrap program in MODE-SELECT mode, and rewrites RAM starting at 'start-address with 'new-ram." [start-address new-ram script] - (->> script - (set-target-address start-address) - (play-moves [(buttons (count new-ram))]) - (play-moves (map buttons new-ram)))) - + (loop [s (set-target-address start-address script) + to-write new-ram] + (if (< (count to-write) 0x100) + (write-RAM-segment to-write s) + (recur + (write-RAM-segment (take 0xFF to-write) s) + (drop 0xFF to-write))))) + (defn transfer-control "Assumes that the game is under control of the main-bootstrap program in MODE-SELECT mode, and jumps to the target-address." @@ -830,17 +845,23 @@ (set-target-address target-address) (play-moves [(buttons jump-mode)]))) -(defn relocate-main-bootstrap +(def box-target (+ 90 pokemon-box-1-address)) + +(defn-memo relocate-main-bootstrap ([] (relocate-main-bootstrap (launch-main-bootstrap-program))) ([script] (let [target (+ 90 pokemon-box-1-address)] (->> script - (do-nothing 500))))) + (do-nothing 2) + (write-RAM target (main-bootstrap-program target)) + (do-nothing 1) + (transfer-control target) + (do-nothing 1))))) (def mid-game-data (subvec (vec (memory (mid-game))) pokemon-list-start - (+ pokemon-list-start 100))) + (+ pokemon-list-start 697))) (def mid-game-map-address 0x46BC) @@ -849,9 +870,39 @@ ([script] (->> script (do-nothing 10) - (write-RAM pokemon-list-start mid-game-data)))) + (write-RAM pokemon-list-start + mid-game-data)))) +(defn test-set-data + ([] (test-set-data (relocate-main-bootstrap))) + ([script] + (->> script + (do-nothing 10) + (write-RAM pokemon-list-start + (repeat 500 0xCC))))) + +(defn test-mid-game-transfer [] + (= (subvec (vec (memory (second (set-mid-game-data)))) + pokemon-list-start + (+ pokemon-list-start 500)) + (subvec (vec (memory (mid-game))) + pokemon-list-start + (+ pokemon-list-start 500)))) - +(defn return-to-pokemon-kernel + ([] (return-to-pokemon-kernel (set-mid-game-data))) + ([script] + (let [scratch (+ 200 pokemon-box-1-address) + return-program + (flatten + [0xFB + 0xC3 + (reverse (disect-bytes-2 mid-game-map-address))])] + (->> script + (write-RAM scratch return-program) + (transfer-control scratch) + (do-nothing 1))))) + + diff -r f2f1e0b8c1c7 -r 21b8b3350b20 moves/temp.vbm Binary file moves/temp.vbm has changed