Commit: 425e63a59562a5c6bc7c35069eed848c9aebe0e3 Parent: 0c74fb5cc96cc9d08610bc28d11d8c83b06caa46 Author: Vi Grey Date: 2019-11-04 11:42 UTC Summary: Add initial RAM data injection functionality Add ability to inject pre-saved initial RAM data into NES Console using Cartridge Swapping and specifically crafted .sav files. Add sav-examples/ directory with pre-made .sav files for initial RAM data injection. Add scripts/ directory to hold accompanying Python scripts. Add Ability to create specifically crafted .sav files with sav-create.py script. Add bin/archive/ directory for previous NES ROM file versions. Change sav-ram-extract.py script location from root of repository to scripts/ directory. Change 2018 to 2019 in Makefile. CHANGELOG.md | 13 ++++++ Makefile | 2 +- README.md | 80 +++++++++++++++++++++++++++++--- bin/{ => archive}/nes-ram-debug-tool-v0_0_0.nes | Bin bin/nes-ram-debug-tool-v0_0_1.nes | Bin 0 -> 786448 bytes sav-examples/fceux.sav | Bin 0 -> 8192 bytes sav-examples/mesen-ones.sav | Bin 0 -> 8192 bytes sav-examples/mesen-random-ae80af9e.sav | Bin 0 -> 8192 bytes sav-examples/mesen-zeros.sav | Bin 0 -> 8192 bytes sav-examples/ones.sav | Bin 0 -> 8192 bytes sav-examples/zeros.sav | Bin 0 -> 8192 bytes scripts/sav-create.py | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sav-ram-extract.py => scripts/sav-ram-extract.py | 4 ++ src/graphics/tileset.chr | Bin 8192 -> 8192 bytes src/nes-ram-debug-tool.asm | 8 +++- src/prg.asm | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ram.asm | 5 ++ 17 files changed, 479 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7551a68..d3d193a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # Change Log All notable changes to this project will be documented in this file. +## 0.0.1 - 2019-11-04 +### Added +- Ability to inject pre-saved initial RAM data into NES Console using Cartridge Swapping and specifically crafted .sav files +- sav-examples/ directory with pre-made .sav files for initial RAM data injection +- scripts/ directory to hold accompanying Python scripts +- Ability to create specifically crafted .sav files with sav-create.py script +- bin/archive/ directory for previous NES ROM file versions + +### Changed +- 0.0.0 sprite to 0.0.1 +- sav-ram-extract.py script location from root of repository to scripts/ directory +- 2018 to 2019 in Makefile + ## 0.0.0 - 2019-10-24 ### Added - Initial release diff --git a/Makefile b/Makefile index 9513a04..514772b 100755 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 2018, Vi Grey +# Copyright (C) 2019, Vi Grey # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index 9996e04..191443b 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,29 @@ # NES RAM Debug Tool -##### Version 0.0.0 +##### Version 0.0.1 NES ROM for TKROM boards that extracts initial NES RAM data and stores it in battery backed PRG RAM **_NES RAM Debug Tool was created by Vi Grey (https://vigrey.com) and is licensed under the BSD 2-Clause License._** + ### Description: -An NES ROM for TKROM boards and an accompanying Python script to extract the initial NES CPU and PPU RAM data of an NES console on Power On. These tools are used to debug initial NES RAM and was created with the intention of studying how memory changes on an NES console. The initial RAM data will be saved into WRAM and is meant to be dumped with a NES Cartridge Dumper like InfiniteNESLive's INLRetro Dumper-Programmer (https://www.infiniteneslives.com/inlretro.php). +An NES ROM for TKROM boards and an accompanying Python script to extract the initial NES CPU and PPU RAM data of an NES console on Power On. These tools are used to debug initial NES RAM and was created with the intention of studying how memory changes on an NES console. The initial RAM data will be saved into WRAM and is meant to be dumped with a NES Cartridge Dumper like InfiniteNESLives' INLRetro Dumper-Programmer (https://www.infiniteneslives.com/inlretro.php). + ### Platforms: - Linux - macOS - BSD + ## NES ROM + ### NES ROM Build Dependencies: - asm6 _(You'll probably have to build asm6 from source. Make sure the asm6 binary is named **asm** and that the binary is executable and accessible in your PATH. The source code can be found at **http://3dscapture.com/NES/asm6.zip**)_ + ### Build NES ROM: From a terminal, go to the the main directory of this project (the directory this README.md file exists in), you can then build the NES ROM with the following command. @@ -26,11 +31,13 @@ From a terminal, go to the the main directory of this project (the directory thi The resulting NES ROM will be located at **bin/nes-ram-debug-tool.nes** + ### Cleaning NES ROM Build Environment: If you used `make` to build the NES ROM file, you can run the following command to clean up the build environment. $ make clean + ### NES ROM .sav File Syntax **Offset values are based on the beginning of the .sav file (_$0000_), rather than the WRAM location data (_$6000_)** @@ -40,16 +47,30 @@ The next 4KB of the .sav file (_$0800_-_$17FF_) is the 4KB of PPU nametable data The next 32B of the .sav file (_$1800_-_$181F_) is the 32KB of PPU palette data (PPU _$3F00_-_$3F1F_) -## .sav RAM Extract Script +The next 4B of the .sav file (_$1820_-_$1823_) is the CRC32 checksum of _$0000_-_$181F_ of the .sav file + +Bytes _$1FF3_-_$1FFC_ will be `ViGreyTech` when the .sav file was created by the accompanying .sav Create Python script **sav-create.py**. If _$1FF3_-_$1FFC_ of the .sav file is `ViGreyTech` while playing this NES ROM on an NES Console, the stored CPU and PPU RAM data in the .sav file will be injected into the NES Console's CPU and PPU RAM. -### .sav RAM Extract Script Dependencies: +Bytes _$1FFD_-_$1FFF_ will be a 6502 JMP instruction to a 16 bit start location address in CPU RAM (CPU _$0000_-_$07FD_) for a 3 byte infinite loop that will run from CPU RAM if Bytes _$1FF3_-_$1FFC_ of the .sav file is `ViGreyTech`. That infinite loop will allow the NES Cartridge to removed from the NES Console while the NES Console is still powered on and let the user insert another NES Game Cartridge to start the new NES Game with the injected CPU and PPU RAM. + + +## Accompanying Python Scripts +Included in this repository are python scripts that can be used with the NES ROM's .sav file. These files are stored in the **scripts** directory. + + +### Accompanying Python Script Dependencies: - Python >= 3 + +## .sav RAM Extract Script +This script will extract the CPU and PPU RAM values from a the 8KB NES ROM WRAM .sav file. + + ### .sav RAM Extract Script Usage: $ python3 sav-ram-extract.py -h Usage: python3 sav-ram-extract.py [ OPTIONS ] [out_dir_path] - sav_file is the 8KB .sav file for you wish to exctract from. + sav_file is the 8KB .sav file for you wish to extract from. out_dir_path is an optional directory path to store the created CPU and PPU RAM files in. @@ -64,19 +85,64 @@ The next 32B of the .sav file (_$1800_-_$181F_) is the 32KB of PPU palette data python3 sav-ram-extract.py ~/nes-ram-debug-tool.sav ~/ram/ python3 sav-ram-extract.py ../nes-ram-debug-tool.sav ~/ram/ -### .sav RAM Extract Script CPU/PPU RAM Files -When you use the .sav RAM Extract Script, two .ram files should be created, one CPU .ram file and one PPU .ram file. These file names will start with the date/time of file creation, followed by a dash, then cpu.ram or ppu.ram. These .ram files contain the initial editable CPU and PPU ram of the NES console on power on that was stored in the .sav file. + +### .sav RAM Extract Script Output CPU/PPU RAM Files +When you use the **.sav RAM Extract Script**, two .ram files should be created, one CPU .ram file and one PPU .ram file. These file names will start with the date/time of file creation, followed by a dash, then cpu.ram or ppu.ram. These .ram files contain the initial editable CPU and PPU ram of the NES console on power on that was stored in the .sav file. The CPU .ram file will be a 64KB file that stores the initial console CPU RAM state. Only console RAM data that is editable by the cartridge is properly stored, while everything else is replaced with `00` bytes. PRG ROM data is not stored in this file. Everything at and after _$2000_ in the CPU .ram file is replaced with `00` bytes. The PPU .ram file will be a 16KB file that stores the initial console PPU RAM state. Only console RAM data that is editable by the cartridge is properly stored, while everything else is replaced with `00` bytes. CHR ROM data is not stored in this file. Everything before _$2000_ in the PPU .ram file is replaced with `00` bytes. + +## .sav Create Script +This script convert a 64KB NES CPU RAM dump and 16KB NES PPU RAM dump into a WRAM .sav file for the NES ROM. When the NES ROM uses the resulting .sav file, the NES ROM will inject that RAM data into the NES Console's CPU and PPU RAM. + +### .sav Create Script Usage + $ python3 sav-create.py -h + Usage: python3 sav-create.py [ OPTIONS ]... + + cpu is the 64KB CPU RAM dump file to be injected into the NES. + ppu is the 16KB PPU RAM dump file to be injected into the NES. + sav_file is the 8KB .sav file you are creating using this script. + + Options: + -h, --help Print Help (this message) and exit + -l, --loop Start hex address in CPU RAM (0000-07FD) for a 3 byte + loop that allows for cartridge swapping on an NES + Console with a disabled CIC Lockout Chip after RAM + injection to the console (Default value is 0100) + --version Print version information and exit + + Examples: + python3 sav-create.py cpu.dmp ppu.dmp nes-ram-debug-tool.sav + python3 sav-create.py ~/cpu.dmp ~/ppu.dmp ~/nes-ram-debug-tool.sav + python3 sav-create.py -l 07F0 cpu.dmp ppu.dmp nes-ram-debug-tool.sav + python3 sav-create.py --loop 8A cpu.dmp ppu.dmp nes-ram-debug-tool.sav + python3 sav-create.py cpu.dmp ppu.dmp nes-ram-debug-tool.sav -l 8A + python3 sav-create.py cpu.dmp -l 8 ppu.dmp ../nes-ram-debug-tool.sav + python3 sav-create.py cpu.dmp ppu.dmp -l 200 ../nes-ram-debug-tool.sav + + +### Cartridge Swapping +When using a .sav file that was created with the **.sav Create Script** on an NES Cartridge and powering the NES Console on, the NES Cartridge will end up injecting the data stored in the .sav file into the NES CPU and PPU RAM. It will then run an infinite loop from memory. It is at this point where the user can remove the NES Cartridge while the NES Console is still powered on, place in a new cartridge, and hit the **RESET** button. If the NES Console has a disabled CIC Lockout Chip, the injected CPU and PPU RAM should be the initial RAM upon startup of the new cartridge. + +**Please Note:** If the NES Console has a functioning CIC Lockout Chip, the console will power off and back on repeatedly until the reset button is pressed. This will cause the NES Console to break out of the infinite loop. CPU RAM also degrades over time while the cartridge is being swapped on an NES Console with a functioning CIC Lockout Chip. It is still possible to cartridge swap on an unmodified front loading NES Console, but be aware of likely RAM decay. If the NES Console has a disabled CIC Lockout Chip (like a modded front loader) or no CIC Lockout Chip at all (like the top loader NES-101 console model), the console should stay powered on running the infinite loop. + + +### Example Pre-Made .sav Files +Included in this repository are .sav files that can be used with the NES ROM. These example .sav files are stored in the **sav-examples** directory. You can use these example .sav files to inject predetermined RAM values in the NES Console's CPU and PPU RAM using the NES ROM when it is running in an NES Cartridge. + +All example .sav files will create the infinite loop in the NES Console CPU memory for cartridge swapping at CPU _$0100_-_$0102_ + + ### Special Thanks - **DwangoAC** (https://tas.bot): For finally convincing me to make a tool like this after I have procrastinated on making a tool like this for many months - **Brad Smith** (http://rainwarrior.ca): For providing me with tips and knowledge while streaming production of this +- **Paul Molloy** (https://infiniteneslives.com): For creating and providing the NES TKROM board for testing and use + ### License: Copyright (C) 2019, Vi Grey All rights reserved. diff --git a/bin/nes-ram-debug-tool-v0_0_0.nes b/bin/archive/nes-ram-debug-tool-v0_0_0.nes similarity index 100% rename from bin/nes-ram-debug-tool-v0_0_0.nes rename to bin/archive/nes-ram-debug-tool-v0_0_0.nes diff --git a/bin/nes-ram-debug-tool-v0_0_1.nes b/bin/nes-ram-debug-tool-v0_0_1.nes new file mode 100644 index 0000000..67de53c Binary files /dev/null and b/bin/nes-ram-debug-tool-v0_0_1.nes differ diff --git a/sav-examples/fceux.sav b/sav-examples/fceux.sav new file mode 100644 index 0000000..908de9f Binary files /dev/null and b/sav-examples/fceux.sav differ diff --git a/sav-examples/mesen-ones.sav b/sav-examples/mesen-ones.sav new file mode 100644 index 0000000..b3e2389 Binary files /dev/null and b/sav-examples/mesen-ones.sav differ diff --git a/sav-examples/mesen-random-ae80af9e.sav b/sav-examples/mesen-random-ae80af9e.sav new file mode 100644 index 0000000..0ed05e9 Binary files /dev/null and b/sav-examples/mesen-random-ae80af9e.sav differ diff --git a/sav-examples/mesen-zeros.sav b/sav-examples/mesen-zeros.sav new file mode 100644 index 0000000..ae61efe Binary files /dev/null and b/sav-examples/mesen-zeros.sav differ diff --git a/sav-examples/ones.sav b/sav-examples/ones.sav new file mode 100644 index 0000000..9b6c652 Binary files /dev/null and b/sav-examples/ones.sav differ diff --git a/sav-examples/zeros.sav b/sav-examples/zeros.sav new file mode 100644 index 0000000..f70eb1d Binary files /dev/null and b/sav-examples/zeros.sav differ diff --git a/scripts/sav-create.py b/scripts/sav-create.py new file mode 100755 index 0000000..ec4b6f0 --- /dev/null +++ b/scripts/sav-create.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2019, Vi Grey +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +import binascii +import os +import sys + +VERSION = "0.0.1" + + +def parse_cpu_ram_file(): + global cpu_dump_data + try: + cpu_file = open(cpu_dump_path, 'rb') + cpu_dump_data = cpu_file.read() + if len(cpu_dump_data) != 65536: + print('\x1b[91mInvalid NES CPU RAM Dump File. Must Be Exactly ' + + '64KB in Size.\x1b[0m') + exit(1) + except: + print('\x1b[91mNES CPU RAM Dump File Required\x1b[0m') + exit(1) + return + + +def parse_ppu_ram_file(): + global ppu_dump_data + try: + ppu_file = open(ppu_dump_path, 'rb') + ppu_dump_data = ppu_file.read() + if len(ppu_dump_data) != 16384: + print('\x1b[91mInvalid NES PPU RAM Dump File. Must Be Exactly ' + + '16KB in Size.\x1b[0m') + exit(1) + except: + print('\x1b[91mNES PPU RAM Dump File Required\x1b[0m') + exit(1) + return + + +def calculate_sav_file_crc32(sav_data): + generated_crc32_int = binascii.crc32(sav_data) + return generated_crc32_int.to_bytes(4, byteorder='big') + + +def generate_sav_file(): + sav_file_data = b'' + sav_file_data += cpu_dump_data[:2048] + sav_file_data += ppu_dump_data[8192: 12288] + sav_file_data += ppu_dump_data[16128: 16160] + sav_file_data += calculate_sav_file_crc32(sav_file_data) + sav_file_data += b'\x00' * 1999 + sav_file_data += b'ViGreyTech\x4c' + loop_location_hex = hex(loop_location)[2:] + loop_location_hex = '0' * (4 - len(loop_location_hex)) + loop_location_hex + sav_file_data += bytes.fromhex(loop_location_hex[2:]) + sav_file_data += bytes.fromhex(loop_location_hex[:2]) + try: + sav_file = open(sav_file_path, 'wb') + sav_file.write(sav_file_data) + print('\x1b[92mNES ROM File Successfully Written to ' + sav_file_path + + '\x1b[0m') + except: + print('\x1b[91mUnable to NES SAV File to ' + + sav_file_path + '\x1b[0m') + exit(1) + return + + +def print_version(): + print('sav-create ' + VERSION) + + +def print_help(): + help_string = ('Usage: python3 sav-create.py [ OPTIONS ]... ' + + '\n\n' + + 'cpu is the 64KB CPU RAM dump file to be injected into ' + + 'the NES.\n' + + 'ppu is the 16KB PPU RAM dump file to be injected into ' + + 'the NES.\n' + + 'sav_file is the 8KB .sav file you are creating using ' + + 'this script.\n\n' + + 'Options:\n' + + ' -h, --help Print Help (this message) and exit\n' + + ' -l, --loop Start hex address in CPU RAM ' + + '(0000-07FD) for a 3 byte\n' + + ' loop that allows for cartridge ' + + 'swapping on an NES\n' + + ' Console with a disabled CIC Lockout Chip ' + + 'after RAM\n' + + ' injection to the console (Default ' + + 'value is 0100)\n' + ' --version Print version information and ' + + 'exit\n\n' + + 'Examples:\n' + + ' python3 sav-create.py cpu.dmp ppu.dmp nes-ram-debug-' + + 'tool.sav\n' + + ' python3 sav-create.py ~/cpu.dmp ~/ppu.dmp ~/nes-ram-' + + 'debug-tool.sav\n' + ' python3 sav-create.py -l 07F0 cpu.dmp ppu.dmp nes-ram-' + + 'debug-tool.sav\n' + ' python3 sav-create.py --loop 8A cpu.dmp ppu.dmp nes-' + + 'ram-debug-tool.sav\n' + ' python3 sav-create.py cpu.dmp ppu.dmp nes-ram-debug-' + + 'tool.sav -l 8A\n' + ' python3 sav-create.py cpu.dmp -l 8 ppu.dmp ../nes-ram-' + + 'debug-tool.sav\n' + ' python3 sav-create.py cpu.dmp ppu.dmp -l 200 ../nes-' + + 'ram-debug-tool.sav' + ) + print(help_string) + + +sav_file_path = '' +cpu_dump_path = '' +cpu_dump_data = b'' +ppu_dump_path = '' +ppu_dump_data = b'' +loop_location = 256 +loop_flag = '' + + +if len(sys.argv) >= 2: + # START OF STATIC FLAGS + # START OF HELP + if sys.argv[1] == '-h' or sys.argv[1] == '--help': + print_help() + exit(0) + # START OF VERSION + elif sys.argv[1] == '--version': + print_version() + exit(0) + # END OF STATIC FLAGS + + + if "-l" in sys.argv or "--loop" in sys.argv: + loop_flag = "--loop" + try: + sys.argv.index("-l") + loop_flag = "-l" + except: + pass + + argv_order = ["", "cpu_dump", "ppu_dump", "sav_file"] + if loop_flag != "": + loop_flag_index = sys.argv.index(loop_flag) + if loop_flag_index <= 4: + argv_order.insert(loop_flag_index, "loop_flag") + argv_order.insert(loop_flag_index + 1, "loop_location") + + for x in range(len(argv_order)): + if argv_order[x] == "cpu_dump": + cpu_dump_path = sys.argv[x] + elif argv_order[x] == "ppu_dump": + ppu_dump_path = sys.argv[x] + elif argv_order[x] == "sav_file": + sav_file_path = sys.argv[x] + elif argv_order[x] == "loop_location": + try: + loop_location_tmp = int(sys.argv[x], 16) + if loop_location_tmp >= 0 and loop_location_tmp <= 2045: + loop_location = loop_location_tmp + else: + raise + except: + print('\x1b[91mValue for Loop Flag Must Be a Hex Number ' + + 'Between 0000 and 07FD\x1b[0m') + exit(1) +else: + print('\x1b[91mInvalid Input Values. Use --help to See Expected Input ' + + 'Values\x1b[0m') + exit(1) + + +parse_cpu_ram_file() +parse_ppu_ram_file() +generate_sav_file() diff --git a/sav-ram-extract.py b/scripts/sav-ram-extract.py similarity index 99% rename from sav-ram-extract.py rename to scripts/sav-ram-extract.py index 4a10d0f..9bbca38 100755 --- a/sav-ram-extract.py +++ b/scripts/sav-ram-extract.py @@ -32,6 +32,7 @@ import sys VERSION = "0.0.0" + def check_sav_file_crc32(): crc32_sav = sav_file_data[6176: 6180] generated_crc32_int = binascii.crc32(sav_file_data[:6176]) @@ -97,9 +98,11 @@ def generate_ppu_ram_file(): exit(1) return + def print_version(): print('sav-ram-extract ' + VERSION) + def print_help(): help_string = ('Usage: python3 sav-ram-extract.py [ OPTIONS ] ' + '[out_dir_path]\n\n' + @@ -123,6 +126,7 @@ def print_help(): '~/ram/') print(help_string) + sav_file_path = '' sav_file_data = b'' cpu_ram_data = b'' diff --git a/src/graphics/tileset.chr b/src/graphics/tileset.chr index e0c9b6f..251fdac 100644 Binary files a/src/graphics/tileset.chr and b/src/graphics/tileset.chr differ diff --git a/src/nes-ram-debug-tool.asm b/src/nes-ram-debug-tool.asm index b136a0b..3e72b80 100644 --- a/src/nes-ram-debug-tool.asm +++ b/src/nes-ram-debug-tool.asm @@ -26,8 +26,8 @@ ; Version 0.0.0 .db "NES", $1A - .db $02 - .db $01 + .db $20 + .db $20 .db %01000011 .db $00 .db 0, 0, 0, 0, 0, 0, 0, 0 @@ -35,6 +35,9 @@ .include "ram.asm" .include "defs.asm" +.base $0000 +.pad $78000, $FF + .base $8000 .pad $C000, $FF @@ -44,3 +47,4 @@ .base $0000 .incbin "graphics/tileset.chr" +.pad $40000, $FF diff --git a/src/prg.asm b/src/prg.asm index abc0f14..9538c7c 100644 --- a/src/prg.asm +++ b/src/prg.asm @@ -71,6 +71,182 @@ InitialVWaitLoop: bne InitialVWaitLoop +;;;;;;;;;; +;; +;; Constructed .sav File Check +;; +;;;;;;;;;; + +CheckConstructedSav: + lda savconstructed + cmp #$56 + bne SavFileNotConstructed + lda (savconstructed + 1) + cmp #$69 + bne SavFileNotConstructed + lda (savconstructed + 2) + cmp #$47 + bne SavFileNotConstructed + lda (savconstructed + 3) + cmp #$72 + bne SavFileNotConstructed + lda (savconstructed + 4) + cmp #$65 + bne SavFileNotConstructed + lda (savconstructed + 5) + cmp #$79 + bne SavFileNotConstructed + lda (savconstructed + 6) + cmp #$54 + bne SavFileNotConstructed + lda (savconstructed + 7) + cmp #$65 + bne SavFileNotConstructed + lda (savconstructed + 8) + cmp #$63 + bne SavFileNotConstructed + lda (savconstructed + 9) + cmp #$68 + beq ConstructedSavWRAMtoCPU + +SavFileNotConstructed: + jmp CheckReset + + +;;;;;;;;;; +;; +;; Constructed .sav WRAM ($6000 - $67FF) to CPU RAM ($0000 - $07FF) +;; +;;;;;;;;;; + +ConstructedSavWRAMtoCPU: + lda #$02 + sta addr + lda #$60 + sta (addr + 1) + ldy #$00 +ConstructedSavWRAMtoCPULoop: + lda (addr), y + tax + lda (addr + 1) + sec + sbc #$60 + sta (addr + 1) + txa + sta (addr), y + lda addr + clc + adc #$01 + sta addr + lda (addr + 1) + adc #$60 + sta (addr + 1) + cmp #$68 + bne ConstructedSavWRAMtoCPULoop + + +;;;;;;;;;; +;; +;; Constructed .sav WRAM ($6800 - $77FF) to PPU Nametable RAM ($2000 - $2FFF) +;; +;;;;;;;;;; + +ConstructedSavWRAMtoPPU2000To2FFF: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + sta addr + tay + lda #$68 + sta (addr + 1) +ConstructedSavWRAMtoPPU2000To2FFFLoop: + lda (addr), y + sta PPU_DATA + lda addr + clc + adc #$01 + sta addr + lda (addr + 1) + adc #$00 + sta (addr + 1) + cmp #$78 + bne ConstructedSavWRAMtoPPU2000To2FFFLoop + + +;;;;;;;;;; +;; +;; Constructed .sav WRAM ($7800 - $781F) to PPU Palette RAM ($3F00 - $3F1F) +;; +;;;;;;;;;; + +ConstructedSavWRAMtoPPU3F00To3F1F: + lda PPU_STATUS + lda #$3F + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + sta addr + tay + lda #$78 + sta (addr + 1) +ConstructedSavWRAMtoPPU3F00To3F1FLoop: + lda (addr), y + sta PPU_DATA + lda addr + clc + adc #$01 + sta addr + cmp #$20 + bne ConstructedSavWRAMtoPPU3F00To3F1FLoop + + +;;;;;;;;;; +;; +;; Cartridge Swap Infinite Loop Setup +;; +;;;;;;;;;; + +CartridgeSwapInfiniteLoopSetup: + ldy #$00 + lda $7FFE + sta addr + lda $7FFF + sta (addr + 1) + lda $7FFD + sta (addr), y + iny + lda $7FFE + sta (addr), y + iny + lda $7FFF + sta (addr), y + + +;;;;;;;;;; +;; +;; Constructed .sav WRAM ($6000 - $6001) to CPU RAM ($0000 - $0001) +;; +;;;;;;;;;; + +ConstructedSavWRAMtoCPUEnd: + lda $6000 + sta addr + lda $6001 + sta (addr + 1) + + +;;;;;;;;;; +;; +;; Cartridge Swap Infinite Loop Start +;; +;;;;;;;;;; + +CartridgeSwapInfiniteLoopStart: + jmp $7FFD + + ;;;;;;;;;; ;; ;; Console Reset Check diff --git a/src/ram.asm b/src/ram.asm index 1bd03b8..5275c25 100644 --- a/src/ram.asm +++ b/src/ram.asm @@ -12,6 +12,11 @@ ppupalettes dsb 32 .ende +.enum $7FF3 + savconstructed dsb 10 + infiniteloopaddr dsb 3 +.ende + .enum $7820 crc32 dsb 4 .ende