diff --git a/.gitignore b/.gitignore index a80016f..7279fe7 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ c5_pin_model_dump.txt *.xml *_netlist *.cdf +BootROMs/obj/* diff --git a/BootROMs/CGB_logo.png b/BootROMs/CGB_logo.png new file mode 100644 index 0000000..4c78b4c Binary files /dev/null and b/BootROMs/CGB_logo.png differ diff --git a/BootROMs/SameBoyLogo.png b/BootROMs/CGB_logo_old.png similarity index 100% rename from BootROMs/SameBoyLogo.png rename to BootROMs/CGB_logo_old.png diff --git a/BootROMs/Makefile b/BootROMs/Makefile new file mode 100644 index 0000000..5c3f776 --- /dev/null +++ b/BootROMs/Makefile @@ -0,0 +1,86 @@ +PLATFORM := $(shell uname -s) +ifneq ($(findstring MINGW,$(PLATFORM)),) +PLATFORM := windows32 +USE_WINDRES := true +endif + +ifneq ($(findstring MSYS,$(PLATFORM)),) +PLATFORM := windows32 +endif + +SRC := ./src +OBJ := ./obj +BIN := ./bin + +ifeq ($(PLATFORM),windows32) +_ := $(shell chcp 65001) +EXESUFFIX:=.exe +NATIVE_CC = clang -IWindows -Wno-deprecated-declarations --target=i386-pc-windows +# To force use of the Unix version instead of the Windows version +MKDIR := $(shell which mkdir) +NULL := NUL +else +EXESUFFIX:= +NATIVE_CC := cc +MKDIR := mkdir +NULL := /dev/null +endif + +IMG_COMPRESS := $(OBJ)/logo-compress$(EXESUFFIX) + +# MiSTer CGB, DMG and SGB bootroms are compiled into a memory initialization file to be stored in the GameBoy core at built time. +.PHONY : default +default: cgb_boot.mif + +.PHONY : all +all: default bootroms checksum + +# All bins, including non-standard bootroms (e.g. CGB0, MGB) +.PHONY : bootroms +bootroms: $(BIN)/cgb0_boot.bin $(BIN)/cgb_boot.bin $(BIN)/dmg_boot.bin $(BIN)/mgb_boot.bin $(BIN)/sgb_boot.bin $(BIN)/sgb2_boot.bin + + +# MiSTer bootrom has a specific memory mapping for each variant (CGB is allocated 2308 bytes, DMG and SGB have 256) +%.mif: $(BIN)/cgb_boot.bin $(BIN)/dmg_boot.bin $(BIN)/sgb_boot.bin + srec_cat \ + $(BIN)/cgb_boot.bin -Binary -offset 0x000 -fill 0x00 0x000 0x900 \ + $(BIN)/dmg_boot.bin -Binary -offset 0x900 -fill 0x00 0x900 0xA00 \ + $(BIN)/sgb_boot.bin -Binary -offset 0xA00 -fill 0x00 0xA00 0xB00 \ + -fill 0x00 0xB00 0x1000 \ + -Output_Block_Size 16 -o $@ --mif + @# Insert helpful comments + @sed -i "/0000/i --CGB" $@ + @sed -i "/0900/i --DMG" $@ + @sed -i "/0A00/i --SGB" $@ + @sed -i "/0B00/i --Padding" $@ + +# Binary compiler +$(BIN)/%.bin: $(SRC)/%.asm $(OBJ)/CGB_logo.rle + -@$(MKDIR) -p $(dir $@) + rgbasm -l -i $(OBJ) -i $(SRC) -o $@.tmp $< + rgblink -o $@.tmp2 $@.tmp + dd if=$@.tmp2 of=$@ count=1 bs=$(if $(findstring mgb,$@)$(findstring dmg,$@)$(findstring sgb,$@),256,2304) 2> $(NULL) + @rm $@.tmp $@.tmp2 + +# CGB logo compression +$(OBJ)/%.rle: $(OBJ)/%.1bpp $(IMG_COMPRESS) + -@$(MKDIR) -p $(dir $@) + $(realpath $(IMG_COMPRESS)) < $< > $@ + +# Make CGB logo +$(OBJ)/%.1bpp: %.png + -@$(MKDIR) -p $(dir $@) + rgbgfx -d 1 -L 0,0:16,3 -Z -o $@ $< + +$(OBJ)/%$(EXESUFFIX): $(SRC)/%.c + -@$(MKDIR) -p $(dir $@) + $(NATIVE_CC) -std=c99 -Wall -Werror $< -o $@ + +.PHONY : checksum +checksum: $(OBJ)/checksum$(EXESUFFIX) + +.PHONY : clean +clean: + rm -rf $(OBJ) + rm -rf $(BIN) + rm -f *.mif diff --git a/BootROMs/README.md b/BootROMs/README.md index 8d95605..d85b7f0 100644 --- a/BootROMs/README.md +++ b/BootROMs/README.md @@ -1 +1,52 @@ -Open Source DMG and CGB boot Roms from [https://github.com/LIJI32/SameBoy/](https://github.com/LIJI32/SameBoy/) \ No newline at end of file +# Bootroms + +## Attribution + +The bootrom source code here has been adapted from the [SameBoy project](https://github.com/LIJI32/SameBoy/) +The MIT license is included in these files. + +## Compilation + +Bootrom compilation follows the same approach as [SameBoy](https://github.com/LIJI32/SameBoy/#compilation). + +The following tools and libraries are required to build bootroms: + +* clang or GCC +* make +* [rgbds](https://github.com/gbdev/rgbds/releases/) +* [SRecord](https://srecord.sourceforge.net/) + +The Makefile contains to following targets: + +* `default` compiles `dmg_boot.bin`, `cgb_boot.bin` and `sgb_boot.bin` and concatenates them into `cgb_boot.mif` +* `bootroms` compiles all `default` binaries as well as `mgb_boot.bin`, `cgb0_boot.bin` and `sgb2_boot.bin` +* `checksum` compiles a program to calculate simple checksums of binary files +* `all` all of the above +* `clean` delete all bootroms and object files, as well as `cgb_boot.mif` + +## Checksum + +A tool is provided to calculate the checksum of a binary file. These checksums are used in the core to verify if the enhanced boot features are available. + +**Note: If these bootroms are edited and recompiled in future, the checksums should be recalculated and updated in [Gameboy.sv](../Gameboy.sv)** + +## Enhancements + +For convenience, two enhancements have been added to the bootroms which enables the on-screen display to change the default boot behaviour without the user needing to load a new bootrom. +Some of these enhancements extend to alternative roms in the [binary folder](./bin) + +### Fast boot + +Fast boot skips the boot animation for the following bootroms: + +* `cgb_boot.bin` (built-in) +* `cgb0_boot.bin` +* `dmg_boot.bin` (built-in) + +### AGB emulation + +The Game Boy Advance had a slightly different CGB bootrom, which enabled special features in a small number of games. AGB emulation is available for: + +* `cgb_boot.bin` (built-in) +* `cgb0_boot.bin` +* The original CGB bootrom (not provided) diff --git a/BootROMs/agb_boot.bin b/BootROMs/agb_boot.bin deleted file mode 100644 index 0e5f9ce..0000000 Binary files a/BootROMs/agb_boot.bin and /dev/null differ diff --git a/BootROMs/bin/cgb0_boot.bin b/BootROMs/bin/cgb0_boot.bin new file mode 100644 index 0000000..90a8e84 Binary files /dev/null and b/BootROMs/bin/cgb0_boot.bin differ diff --git a/BootROMs/bin/cgb_boot.bin b/BootROMs/bin/cgb_boot.bin new file mode 100644 index 0000000..617a880 Binary files /dev/null and b/BootROMs/bin/cgb_boot.bin differ diff --git a/BootROMs/bin/dmg_boot.bin b/BootROMs/bin/dmg_boot.bin new file mode 100644 index 0000000..7849172 Binary files /dev/null and b/BootROMs/bin/dmg_boot.bin differ diff --git a/BootROMs/bin/mgb_boot.bin b/BootROMs/bin/mgb_boot.bin new file mode 100644 index 0000000..4ddb711 Binary files /dev/null and b/BootROMs/bin/mgb_boot.bin differ diff --git a/BootROMs/sgb2_boot.bin b/BootROMs/bin/sgb2_boot.bin similarity index 100% rename from BootROMs/sgb2_boot.bin rename to BootROMs/bin/sgb2_boot.bin diff --git a/BootROMs/sgb_boot.bin b/BootROMs/bin/sgb_boot.bin similarity index 100% rename from BootROMs/sgb_boot.bin rename to BootROMs/bin/sgb_boot.bin diff --git a/BootROMs/cgb_boot.bin b/BootROMs/cgb_boot.bin deleted file mode 100644 index 0f2a183..0000000 Binary files a/BootROMs/cgb_boot.bin and /dev/null differ diff --git a/BootROMs/cgb_boot.mif b/BootROMs/cgb_boot.mif index 78e362e..8d85f55 100644 --- a/BootROMs/cgb_boot.mif +++ b/BootROMs/cgb_boot.mif @@ -1,144 +1,270 @@ --- http://srecord.sourceforge.net/ --- --- Generated automatically by srec_cat -o --mif --- -DEPTH = 4096; -WIDTH = 8; -ADDRESS_RADIX = HEX; -DATA_RADIX = HEX; -CONTENT BEGIN -0000: 31 FE FF 21 00 80 CD EF 05 3E 02 0E 70 E2 26 D0 AF CD EF 05 E2 E0 C1 E0; -0018: 80 26 FE 0E A0 22 0D 20 FC 3E 80 E0 26 E0 11 3E F3 E0 12 E0 25 3E 77 E0; -0030: 24 CD 8F 08 3E FC E0 47 11 04 01 21 10 80 1A 47 CD BA 05 13 7B FE 34 20; -0048: F5 CD 54 06 3E 01 E0 4F AF 21 00 80 CD EF 05 CD 18 06 06 03 21 C2 98 16; -0060: 03 3E 08 0E 10 F5 3E 01 E0 4F 36 08 AF E0 4F F1 22 82 0D 20 F0 D6 2F D5; -0078: 11 10 00 19 D1 05 20 E3 15 28 0A 15 3E 38 2E A7 01 07 01 18 D8 11 A2 05; -0090: 0E 08 21 81 FF AF 2F 22 22 1A 13 22 1A 13 22 AF 22 22 22 22 0D 20 EF 21; -00A8: 81 FF CD 65 06 3E 91 E0 40 CD 76 06 06 2D CD DE 05 3E 83 CD E8 05 06 05; -00C0: CD DE 05 3E C1 CD E8 05 3E 1E E0 C2 CD E3 07 CD D2 05 21 C2 FF 35 20 F4; -00D8: CD 9F 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 50 00 00 00 00 00 00 00 00; -0108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01F8: 00 00 00 00 00 00 00 00 00 88 16 36 D1 DB F2 3C 8C 92 3D 5C 58 C9 3E 70; -0210: 1D 59 69 19 35 A8 14 AA 75 95 99 34 6F 15 FF 97 4B 90 17 10 39 F7 F6 A2; -0228: 49 4E C3 68 E0 8B F0 CE 0C 29 E8 B7 86 9A 52 01 9D 71 9C BD 5D 6D 67 3F; -0240: 6B B3 46 28 A5 C6 D3 27 61 18 66 6A BF 0D F4 B3 46 28 A5 C6 D3 27 61 18; -0258: 66 6A BF 0D F4 B3 00 04 05 23 22 03 1F 0F 0A 05 13 24 87 25 1E 2C 15 20; -0270: 1F 14 05 21 0D 0E 05 1D 05 12 09 03 02 1A 19 19 29 2A 1A 2D 2A 2D 24 26; -0288: 1A 2A 1E 29 22 22 05 2A 06 05 21 19 2A 2A 28 02 10 19 2A 2A 05 00 27 24; -02A0: 16 19 06 20 0C 24 0B 27 12 27 18 1F 32 11 2E 06 1B 00 2F 29 29 00 00 13; -02B8: 22 17 12 1D 42 45 46 41 41 52 42 45 4B 45 4B 20 52 2D 55 52 41 52 20 49; -02D0: 4E 41 49 4C 49 43 45 20 52 20 20 E8 90 90 90 A0 A0 A0 C0 C0 C0 48 48 48; -02E8: 00 00 00 D8 D8 D8 28 28 28 60 60 60 D0 D0 D0 80 40 40 20 E0 E0 20 10 10; -0300: 18 20 20 20 E8 E8 E0 20 E0 10 88 10 80 80 40 20 20 38 20 20 90 20 20 A0; -0318: 98 98 48 1E 1E 58 88 88 10 20 20 10 20 20 18 E0 E0 00 18 18 00 00 00 08; -0330: 90 B0 90 A0 B0 A0 C0 B0 C0 80 B0 40 88 20 68 DE 00 70 DE 20 78 98 B0 48; -0348: 80 E0 50 20 B8 E0 88 B0 10 20 00 10 20 E0 18 E0 18 00 18 E0 20 A8 E0 20; -0360: 18 E0 00 C8 18 E0 00 E0 40 20 18 E0 E0 18 30 20 E0 E8 F0 F0 F0 F8 F8 F8; -0378: E0 20 08 00 00 10 FF 7F BF 32 D0 00 00 00 9F 63 79 42 B0 15 CB 04 FF 7F; -0390: 31 6E 4A 45 00 00 FF 7F EF 1B 00 02 00 00 FF 7F 1F 42 F2 1C 00 00 FF 7F; -03A8: 94 52 4A 29 00 00 FF 7F FF 03 2F 01 00 00 FF 7F EF 03 D6 01 00 00 FF 7F; -03C0: B5 42 C8 3D 00 00 74 7E FF 03 80 01 00 00 FF 67 AC 77 13 1A 6B 2D D6 7E; -03D8: FF 4B 75 21 00 00 FF 53 5F 4A 52 7E 00 00 FF 4F D2 7E 4C 3A E0 1C ED 03; -03F0: FF 7F 5F 25 00 00 6A 03 1F 02 FF 03 FF 7F FF 7F DF 01 12 01 00 00 1F 23; -0408: 5F 03 F2 00 09 00 FF 7F EA 03 1F 01 00 00 9F 29 1A 00 0C 00 00 00 FF 7F; -0420: 7F 02 1F 00 00 00 FF 7F E0 03 06 02 20 01 FF 7F EB 7E 1F 00 00 7C FF 7F; -0438: FF 3F 00 7E 1F 00 FF 7F FF 03 1F 00 00 00 FF 03 1F 00 0C 00 00 00 FF 7F; -0450: 3F 03 93 01 00 00 00 00 00 42 7F 03 FF 7F FF 7F 8C 7E 00 7C 00 00 FF 7F; -0468: EF 1B 80 61 00 00 FF 7F EA 7F 5F 7D 00 00 78 47 90 32 87 1D 61 08 01 30; -0480: 05 08 00 28 2B 03 06 07 1C 31 33 34 35 36 3C 42 B9 A5 B9 A5 42 3C 30 00; -0498: 58 01 03 07 0F 1F 3E 3C 7C 78 46 7C 7F 3F 1F 0F 03 00 31 3F FF 51 C0 00; -04B0: 20 0F 20 1F 32 03 07 FF 41 F8 00 32 80 E0 F0 31 30 00 4B 01 E1 E3 E7 C7; -04C8: CF DF DE FE 7C 78 00 21 07 0F 21 1F 3F 45 7B FB F3 F1 E1 FF 90 00 20 80; -04E0: 20 81 30 C1 41 C3 E3 50 F7 21 FF 7F 40 00 21 F0 F8 20 FC 20 FE 21 FF CF; -04F8: 20 C7 51 C2 80 60 00 26 03 07 0F 1F 3F 7F FF 45 EF CF 8F 0F 1F 1E 21 3E; -0510: 3C 40 00 20 CF 32 DF 9F 9E 41 BE 3F 31 7C 78 31 7F FF 40 00 30 FF 41 FE; -0528: 00 40 F8 40 00 20 F8 20 F0 60 00 50 01 50 03 50 07 30 0F 40 00 40 FF 20; -0540: E3 20 E7 40 FF 21 C3 83 21 87 FF 52 FE FC 00 23 80 C0 C3 C7 35 CF 8F 9F; -0558: 1E 9E DE 20 DF 53 8F 87 03 00 22 1F 7F FF 83 F0 C0 80 00 31 C3 FF 41 FE; -0570: 00 56 E1 F9 FC FE 7E 1F 0F 58 1F 1E 3E 7C F8 F0 E0 C0 00 21 E0 F0 24 F8; -0588: 78 3D 3F 1F 30 0F 41 1F 1E 21 3E 3C 40 00 D9 0F 1E 3C 78 F8 F0 E0 C0 80; -05A0: 00 00 FF 7F 4F 77 C7 22 9F 03 7D 01 1D 24 38 6D 02 71 FF 7F BF 32 D0 00; -05B8: 00 00 CD BD 05 3E 04 0E 00 CB 20 F5 CB 11 F1 CB 11 3D 20 F5 79 22 23 22; -05D0: 23 C9 E5 21 0F FF CB 86 CB 46 28 FC E1 C9 CD E3 07 CD D2 05 05 20 F7 C9; -05E8: E0 13 3E 87 E0 14 C9 22 CB 6C 28 FB C9 CD F8 05 1A A1 47 1C 1C 1A 1D 1D; -0600: A1 CB 37 B0 CB 41 28 02 CB 37 23 22 CB 31 C9 CD 12 06 CD F5 05 1C 7B C9; -0618: 11 96 04 21 80 80 1A 13 47 E6 0F 28 08 4F 1A 22 23 13 0D 20 F9 CB 30 78; -0630: E6 0F 28 0A 4F 1A 13 22 23 0D 20 FB 18 E0 11 04 01 0E F0 CD 0F 06 C6 16; -0648: 5F CD 0F 06 D6 16 5F FE 1C 20 EE 23 11 8E 04 0E 08 1A 13 22 23 0D 20 F9; -0660: C9 0E 6A 18 06 16 40 1E 00 0E 68 3E 80 B3 E2 0C 2A E2 15 20 FB C9 3E 01; -0678: E0 4F 16 1A 06 02 CD DE 05 21 C0 98 0E 03 7E FE 0F 28 05 34 E6 07 28 03; -0690: 23 18 F3 7D F6 1F 6F 23 0D 20 EB 15 20 DE C9 06 20 0E 20 21 81 FF C5 CD; -06A8: 9D 07 C1 0D 20 F8 CD D2 05 CD D2 05 21 81 FF CD 65 06 05 20 E4 CD D2 07; -06C0: AF E0 4F 2F E0 00 CD D2 07 11 56 FF 2E 0D FA 43 01 CB 7F CC F2 06 CB 7F; -06D8: E0 4C F0 80 47 28 05 F0 C1 A7 20 06 AF 4F 3E 11 61 C9 CD F2 06 E0 4C 3E; -06F0: 01 C9 3E 01 E0 6C CD 20 07 CB 7F C4 74 08 E6 7F; -0700: 47 F0 C1 A7 28 0A 21 7D 04 4F 06 00 09 7E 18 01 78 CD D2 05 CD 6D 07 3E; -0718: 04 16 00 1E 08 2E 7C C9 21 4B 01 7E FE 33 28 05 3D 20 40 18 0C 2E 44 2A; -0730: FE 30 20 37 7E FE 31 20 32 2E 34 0E 10 AF 86 2C 0D 20 FB 47 21 00 02 7D; -0748: D6 5E C8 2A B8 20 F8 7D D6 41 38 0E E5 7D C6 7A 6F 7E E1 4F FA 37 01 B9; -0760: 20 E5 7D C6 5D 6F 78 E0 80 7E C9 AF C9 47 80 80 21 D9 02 06 00 4F 09 1E; -0778: 00 2A E5 21 7E 03 06 00 4F 09 16 08 CD 61 06 E1 CB 5B 20 04 1E 08 18 E9; -0790: 2A 21 7E 03 06 00 4F 09 16 08 C3 67 06 2A 5F 3A 57 01 21 04 7B E6 1F FE; -07A8: 1F 20 02 CB 81 7B E6 E0 FE E0 20 09 7A E6 03 FE 03 20 02 CB A9 7A E6 7C; -07C0: FE 7C 20 02 CB 90 E5 62 6B 09 54 5D E1 7B 22 7A 22 C9 21 51 FF 3E 88 22; -07D8: AF 22 3E 98 22 3E A0 22 36 12 C9 3E 20 E0 00 F0 00 2F E6 0F C8 C5 0E 00; -07F0: 0C 1F 30 FC 3E 10 E0 00 F0 00 2F 17 17 E6 0C 81 47 F0 C1 4F 78 E0 C1 B9; -0808: C1 C8 F5 E5 C5 D5 21 7D 04 4F 06 00 09 7E 47 80 80 21 DB 02 06 00 4F 09; -0820: 7E 21 7F 03 06 00 4F 09 3A FE 7F 20 02 23 23 F5 2A E5 21 81 FF CD 69 08; -0838: E1 E0 83 2A E5 21 82 FF CD 69 08 E1 E0 84 F1 28 02 23 23 2A E0 BB 2A E0; -0850: BC 2A E0 85 7E E0 86 CD D2 05 21 81 FF CD 65 06 3E 1E E0 C2 D1 C1 E1 F1; -0868: C9 11 08 00 0E 08 77 19 0D 20 FB C9 F5 CD D2 05 3E 19 EA 10 99 21 2F 99; -0880: 0E 0C 3D 28 08 32 0D 20 F9 2E 0F 18 F5 F1 C9 21 30 FF AF 0E 10 22 2F 0D; -0898: 20 FB C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -08B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -08C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -08E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -08F8: 00 00 00 00 00 00 00 00; - --- DMG -0900: 31 FE FF AF 21 FF 9F 32 CB 7C 20 FB 21 26 FF 0E; -0910: 11 3E 80 32 E2 0C 3E F3 E2 32 3E 77 77 3E FC E0; -0920: 47 F0 50 FE 42 28 75 11 04 01 21 10 80 1A 4F CD; -0930: A0 00 CD A0 00 13 7B FE 34 20 F2 11 B2 00 06 08; -0940: 1A 22 22 13 05 20 F9 3E 19 EA 10 99 21 2F 99 0E; -0950: 0C 3D 28 08 32 0D 20 F9 2E 0F 18 F3 67 3E 64 57; -0960: E0 42 3E 91 E0 40 04 1E 02 0E 0C F0 44 FE 90 20; -0970: FA 0D 20 F7 1D 20 F2 0E 13 24 7C 1E 83 FE 62 28; -0980: 06 1E C1 FE 64 20 06 7B E2 0C 3E 87 E2 F0 42 90; -0990: E0 42 15 20 D2 05 20 64 16 20 18 CB E0 40 18 5C; -09A0: 06 04 C5 CB 11 17 C1 CB 11 17 05 20 F5 22 23 22; -09B0: 23 C9 3C 42 B9 A5 B9 A5 42 3C FF FF FF FF FF FF; -09C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -09D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -09E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -09F0: FF FF FF FF FF FF FF FF FF FF FF FF 3E 01 E0 50; - ---SGB -0A00: 31 FE FF 21 00 80 22 CB 6C 28 FB 3E 80 E0 26 E0; -0A10: 11 3E F3 E0 12 E0 25 3E 77 E0 24 3E 00 E0 47 11; -0A20: 04 01 21 10 80 1A 47 CD C9 00 CD C9 00 13 7B EE; -0A30: 34 20 F2 11 EA 00 0E 08 1A 13 22 23 0D 20 F9 3E; -0A40: 19 EA 10 99 21 2F 99 0E 0C 3D 28 08 32 0D 20 F9; -0A50: 2E 0F 18 F5 3E 91 E0 40 3E F1 E0 80 21 04 01 AF; -0A60: 4F AF E2 3E 30 E2 F0 80 CD B7 00 E5 06 0E 16 00; -0A70: CD AD 00 82 57 05 20 F8 CD B7 00 E1 06 0E CD AD; -0A80: 00 CD B7 00 05 20 F7 3E 20 E2 3E 30 E2 F0 80 C6; -0A90: 02 E0 80 3E 58 BD 20 C9 0E 13 3E C1 E2 0C 3E 07; -0AA0: E2 3E FC E0 47 3E 01 21 60 C0 C3 FE 00 3E 4F BD; -0AB0: 38 02 2A C9 23 AF C9 5F 16 08 3E 10 CB 1B 38 01; -0AC0: 87 E2 3E 30 E2 15 C8 18 F1 3E 04 0E 00 CB 20 F5; -0AD0: CB 11 F1 CB 11 3D 20 F5 79 22 23 22 23 C9 E5 21; -0AE0: 0F FF CB 86 CB 46 28 FC E1 C9 3C 42 B9 A5 B9 A5; -0AF0: 42 3C 00 00 00 00 00 00 00 00 00 00 00 00 E0 50; -[0B00..0FFF]: 00; -END; +-- http://srecord.sourceforge.net/ +-- +-- Generated automatically by srec_cat -o --mif +-- +DEPTH = 4096; +WIDTH = 8; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +--CGB +0000: 31 FE FF CD D5 05 26 FE 0E A0 22 0D 20 FC 0E 10; +0010: 21 30 FF 22 2F 0D 20 FB E0 C1 E0 80 3E 80 E0 26; +0020: E0 11 3E F3 E0 12 E0 25 3E 77 E0 24 3E FC E0 47; +0030: 11 04 01 21 10 80 1A 47 CD A0 05 13 7B FE 34 20; +0040: F5 CD 3E 06 3E 01 E0 4F CD D5 05 CD 94 08 CC 02; +0050: 06 06 03 21 C2 98 16 03 3E 08 0E 10 CD 7B 00 82; +0060: 0D 20 F9 D6 2F D5 11 10 00 19 D1 05 20 EC 15 28; +0070: 17 15 3E 38 2E A7 01 07 01 18 E1 F5 3E 01 E0 4F; +0080: 36 08 AF E0 4F F1 22 C9 11 8E 05 0E 08 21 81 FF; +0090: AF 2F 22 22 CD 99 08 1A 13 22 1A 13 22 AF 22 22; +00A0: 22 22 0D 20 EC CD A7 07 3E 91 E0 40 CD 94 08 28; +00B0: 0C 3E 83 CD CE 05 06 05 CD C4 05 18 27 CD 4B 06; +00C0: 3E 30 E0 C2 06 04 CD C4 05 3E 83 CD CE 05 06 05; +00D0: CD C4 05 3E C1 CD CE 05 CD CE 07 CD B8 05 21 C2; +00E0: FF 35 20 F4 CD 74 06 CD 8F 08 28 01 04 3E 11 18; +00F0: 0D D0 00 98 A0 12 D0 00 80 00 40 00 00 00 E0 50; +0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0200: 00 88 16 36 D1 DB F2 3C 8C 92 3D 5C 58 C9 3E 70; +0210: 1D 59 69 19 35 A8 14 AA 75 95 99 34 6F 15 FF 97; +0220: 4B 90 17 10 39 F7 F6 A2 49 4E 43 68 E0 8B F0 CE; +0230: 0C 29 E8 B7 86 9A 52 01 9D 71 9C BD 5D 6D 67 3F; +0240: 6B B3 46 28 A5 C6 D3 27 61 18 66 6A BF 0D F4 B3; +0250: 46 28 A5 C6 D3 27 61 18 66 6A BF 0D F4 B3 00 04; +0260: 05 23 22 03 1F 0F 0A 05 13 24 87 25 1E 2C 15 20; +0270: 1F 14 05 21 0D 0E 05 1D 05 12 09 03 02 1A 19 19; +0280: 29 2A 1A 2D 2A 2D 24 26 9A 2A 1E 29 22 22 05 2A; +0290: 06 05 21 19 2A 2A 28 02 10 19 2A 2A 05 00 27 24; +02A0: 16 19 06 20 0C 24 0B 27 12 27 18 1F 32 11 2E 06; +02B0: 1B 00 2F 29 29 00 00 13 22 17 12 1D 42 45 46 41; +02C0: 41 52 42 45 4B 45 4B 20 52 2D 55 52 41 52 20 49; +02D0: 4E 41 49 4C 49 43 45 20 52 20 20 E8 90 90 90 A0; +02E0: A0 A0 C0 C0 C0 48 48 48 00 00 00 D8 D8 D8 28 28; +02F0: 28 60 60 60 D0 D0 D0 80 40 40 20 E0 E0 20 10 10; +0300: 18 20 20 20 E8 E8 E0 20 E0 10 88 10 80 80 40 20; +0310: 20 38 20 20 90 20 20 A0 98 98 48 1E 1E 58 88 88; +0320: 10 20 20 10 20 20 18 E0 E0 00 18 18 00 00 00 08; +0330: 90 B0 90 A0 B0 A0 C0 B0 C0 80 B0 40 88 20 68 DE; +0340: 00 70 DE 20 78 98 B6 48 80 E0 50 20 B8 E0 88 B0; +0350: 10 20 00 10 20 E0 18 E0 18 00 18 E0 20 A8 E0 20; +0360: 18 E0 00 C8 18 E0 00 E0 40 20 18 E0 E0 18 30 20; +0370: E0 E8 FF 7F BF 32 D0 00 00 00 9F 63 79 42 B0 15; +0380: CB 04 FF 7F 31 6E 4A 45 00 00 FF 7F EF 1B 00 02; +0390: 00 00 FF 7F 1F 42 F2 1C 00 00 FF 7F 94 52 4A 29; +03A0: 00 00 FF 7F FF 03 2F 01 00 00 FF 7F EF 03 D6 01; +03B0: 00 00 FF 7F B5 42 C8 3D 00 00 74 7E FF 03 80 01; +03C0: 00 00 FF 67 AC 77 13 1A 6B 2D D6 7E FF 4B 75 21; +03D0: 00 00 FF 53 5F 4A 52 7E 00 00 FF 4F D2 7E 4C 3A; +03E0: E0 1C ED 03 FF 7F 5F 25 00 00 6A 03 1F 02 FF 03; +03F0: FF 7F FF 7F DF 01 12 01 00 00 1F 23 5F 03 F2 00; +0400: 09 00 FF 7F EA 03 1F 01 00 00 9F 29 1A 00 0C 00; +0410: 00 00 FF 7F 7F 02 1F 00 00 00 FF 7F E0 03 06 02; +0420: 20 01 FF 7F EB 7E 1F 00 00 7C FF 7F FF 3F 00 7E; +0430: 1F 00 FF 7F FF 03 1F 00 00 00 FF 03 1F 00 0C 00; +0440: 00 00 FF 7F 3F 03 93 01 00 00 00 00 00 42 7F 03; +0450: FF 7F FF 7F 8C 7E 00 7C 00 00 FF 7F EF 1B 80 61; +0460: 00 00 03 90 0F 18 00 78 81 09 12 15 54 93 3C 42; +0470: B9 A5 B9 A5 42 3C 20 01 20 0F 20 3F 22 3E 7E F8; +0480: 40 F0 22 F8 78 7C 20 1F 20 07 20 00 40 FF 20 C0; +0490: 60 00 30 7F 30 0F 20 FF 20 FE 20 00 20 C0 20 F0; +04A0: 20 F1 22 01 03 07 20 0F 20 9F 22 BF 3C 7C 20 F8; +04B0: 20 F0 20 00 20 7C 20 FC 40 FE 20 9E 20 1F 30 FF; +04C0: 30 1F 40 0F 20 00 20 03 50 07 30 0F 20 1E 20 3E; +04D0: 20 3C 20 7C 40 F8 20 00 40 E0 40 F0 20 F1 20 FB; +04E0: 30 7F 30 3F 20 3E 20 1C 20 00 20 1E 20 3E 30 7E; +04F0: 30 FE 20 DE 20 DF 71 9F 0F 20 00 40 0F 60 1F 20; +0500: 3F 20 3E 20 3C 20 7C 40 FF 20 00 40 FF 40 80 40; +0510: FC 60 00 40 FC 20 00 40 80 30 00 50 01 60 03 40; +0520: 07 20 00 40 FF 40 F0 40 FF 30 E0 30 C0 40 FF 20; +0530: 00 20 E0 20 F8 20 FC 22 7C 7D F9 20 F3 20 FB 20; +0540: 79 20 F9 20 F0 20 C0 20 00 20 0F 20 3F 20 FC 20; +0550: F0 80 E0 20 F0 20 FF 20 3F 20 00 20 F9 20 FE 20; +0560: 1F 80 0F 22 1F 1E 7E 20 F8 20 E0 20 00 20 F0 20; +0570: F8 20 7C 22 3C 3F 9F 20 8F 60 1F 40 3E 20 00 20; +0580: 1F 20 3E 20 FC 20 F0 20 C0 20 80 C0 00 00 FF 7F; +0590: 4F 77 C7 22 9F 03 7D 01 1D 24 38 6D 00 55 60 6D; +05A0: CD A3 05 3E 04 0E 00 CB 20 F5 CB 11 F1 CB 11 3D; +05B0: 20 F5 79 22 23 22 23 C9 E5 21 0F FF CB 86 CB 46; +05C0: 28 FC E1 C9 CD CE 07 CD B8 05 05 20 F7 C9 E0 13; +05D0: 3E 87 E0 14 C9 21 00 80 AF 22 CB 6C 28 FA C9 CD; +05E0: E2 05 1A A1 47 1C 1C 1A 1D 1D A1 CB 37 B0 CB 41; +05F0: 28 02 CB 37 23 22 CB 31 C9 CD FC 05 CD DF 05 1C; +0600: 7B C9 11 76 04 21 80 80 1A 13 47 E6 0F 28 08 4F; +0610: 1A 22 23 13 0D 20 F9 CB 30 78 E6 0F 28 0A 4F 1A; +0620: 13 22 23 0D 20 FB 18 E0 11 04 01 0E F0 CD F9 05; +0630: C6 16 5F CD F9 05 D6 16 5F FE 1C 20 EE 23 11 6E; +0640: 04 0E 08 1A 13 22 23 0D 20 F9 C9 3E 01 E0 4F 16; +0650: 1A 06 02 CD C4 05 21 C0 98 0E 03 7E FE 0F 28 05; +0660: 34 E6 07 28 03 23 18 F3 7D F6 1F 6F 23 0D 20 EB; +0670: 15 20 DE C9 CD 94 08 28 05 3E C1 CD CE 05 06 20; +0680: 0E 20 21 81 FF C5 2A 5F 3A 57 01 21 04 7B E6 1F; +0690: FE 1F 20 01 0D 7B FE E0 38 09 7A E6 03 FE 03 20; +06A0: 02 CB A9 7A E6 7C FE 7C 20 02 CB 90 7B 81 22 7A; +06B0: 88 22 C1 0D 20 CF CD B8 05 CD A7 07 CD B8 05 05; +06C0: 20 BE 3E 02 E0 70 21 00 D0 CD D8 05 3C CD BB 07; +06D0: CD C0 07 CD BB 07 AF E0 70 2F E0 00 57 59 2E 0D; +06E0: FA 43 01 CB 7F CC 00 07 CB 7F E0 4C F0 80 47 28; +06F0: 02 F0 C1 AF 4F 61 C9 21 61 04 4F 06 00 09 7E C9; +0700: 3E 01 E0 6C CD 2B 07 CB 7F C4 74 08 CB BF 47 80; +0710: 80 47 F0 C1 A7 28 05 CD F7 06 18 01 78 CD B8 05; +0720: CD 82 07 3E 04 11 08 00 2E 7C C9 21 4B 01 7E FE; +0730: 33 28 05 3D 20 42 18 0C 2E 44 2A FE 30 20 39 7E; +0740: FE 31 20 34 2E 34 0E 10 AF 86 2C 0D 20 FB E0 80; +0750: 47 21 00 02 7D D6 5E C8 2A B8 20 F8 7D D6 42 38; +0760: 0E E5 7D C6 7A 6F 7E E1 4F FA 37 01 B9 20 E5 7D; +0770: C6 5D 6F 78 E0 80 7E C9 AF C9 21 D9 02 06 00 4F; +0780: 09 C9 CD 7A 07 1E 00 2A E5 21 72 03 4F 09 16 08; +0790: 0E 6A CD B0 07 E1 CB 5B 20 04 1E 08 18 E9 4E 21; +07A0: 72 03 09 16 08 18 05 21 81 FF 16 40 1E 00 0E 68; +07B0: 3E 80 B3 E2 0C 2A E2 15 20 FB C9 E0 4F 21 F1 00; +07C0: CD B8 05 0E 51 06 05 2A E2 0C 05 20 FA C9 FA 43; +07D0: 01 CB 7F C0 3E 20 E0 00 F0 00 2F E6 0F C8 2E 00; +07E0: 2C 1F 30 FC 3E 10 E0 00 F0 00 2F 17 17 E6 0C 85; +07F0: 6F F0 C1 BD C8 7D E0 C1 C5 D5 CD F7 06 CD 7A 07; +0800: 2C 2C 4E 21 73 03 09 3A FE 7F 20 02 23 23 F5 2A; +0810: E5 21 81 FF CD 6A 08 2E 83 CD 6A 08 E1 E0 87 2A; +0820: E5 21 82 FF CD 6A 08 2E 84 CD 6A 08 E1 E0 88 F1; +0830: 28 02 23 23 F0 BB E6 DE 47 2A E6 DE 80 47 FA BC; +0840: FF CB 97 4E CB 91 89 1F EA BC FF 78 1F EA BB FF; +0850: 2D 2A E0 BF 2A E0 C0 2A E0 85 2A E0 86 CD B8 05; +0860: CD A7 07 3E 30 E0 C2 D1 C1 C9 11 08 00 4B 77 19; +0870: 0D 20 FB C9 F5 CD B8 05 3E 19 EA 10 99 21 2F 99; +0880: 0E 0C 3D 28 08 32 0D 20 F9 2E 0F 18 F5 F1 C9 F0; +0890: 50 CB 47 C9 F0 50 CB 4F C9 E5 CD 8F 08 28 09 21; +08A0: 9C 05 7B BD 20 02 13 13 E1 C9 00 00 00 00 00 00; +08B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +08C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +08D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +08E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +08F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +--DMG +0900: 31 FE FF 21 00 80 22 CB 6C 28 FB 3E 80 E0 26 E0; +0910: 11 3E F3 E0 12 E0 25 3E 77 E0 24 3E FC E0 47 F0; +0920: 50 CB 4F 28 10 3E 91 E0 40 3E 83 CD DE 00 06 05; +0930: CD D7 00 18 60 11 04 01 21 10 80 1A 47 CD B6 00; +0940: CD B6 00 13 7B EE 34 20 F2 11 E5 00 0E 08 1A 13; +0950: 22 23 0D 20 F9 3E 19 EA 10 99 21 2F 99 0E 0C 3D; +0960: 28 08 32 0D 20 F9 2E 0F 18 F5 3E 64 E0 42 57 3E; +0970: 91 E0 40 06 83 CD CB 00 CD CB 00 7A FE 03 28 06; +0980: FE 01 20 06 06 C1 78 CD DE 00 15 7A E0 42 20 E5; +0990: 06 3C CD D7 00 F0 50 CB 4F 28 0A 3E C1 CD DE 00; +09A0: 06 1E CD D7 00 21 B0 01 E5 F1 21 4D 01 01 13 00; +09B0: 11 D8 00 C3 FE 00 3E 04 0E 00 CB 20 F5 CB 11 F1; +09C0: CB 11 3D 20 F5 79 22 23 22 23 C9 E5 21 0F FF CB; +09D0: 86 CB 46 28 FC E1 C9 CD CB 00 05 20 FA C9 E0 13; +09E0: 3E 87 E0 14 C9 3C 42 B9 A5 B9 A5 42 3C 00 00 00; +09F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E0 50; +--SGB +0A00: 31 FE FF 21 00 80 22 CB 6C 28 FB 3E 80 E0 26 E0; +0A10: 11 3E F3 E0 12 E0 25 3E 77 E0 24 3E 00 E0 47 11; +0A20: 04 01 21 10 80 1A 47 CD C9 00 CD C9 00 13 7B EE; +0A30: 34 20 F2 11 EA 00 0E 08 1A 13 22 23 0D 20 F9 3E; +0A40: 19 EA 10 99 21 2F 99 0E 0C 3D 28 08 32 0D 20 F9; +0A50: 2E 0F 18 F5 3E 91 E0 40 3E F1 E0 80 21 04 01 AF; +0A60: 4F AF E2 3E 30 E2 F0 80 CD B7 00 E5 06 0E 16 00; +0A70: CD AD 00 82 57 05 20 F8 CD B7 00 E1 06 0E CD AD; +0A80: 00 CD B7 00 05 20 F7 3E 20 E2 3E 30 E2 F0 80 C6; +0A90: 02 E0 80 3E 58 BD 20 C9 0E 13 3E C1 E2 0C 3E 07; +0AA0: E2 3E FC E0 47 3E 01 21 60 C0 C3 FE 00 3E 4F BD; +0AB0: 38 02 2A C9 23 AF C9 5F 16 08 3E 10 CB 1B 38 01; +0AC0: 87 E2 3E 30 E2 15 C8 18 F1 3E 04 0E 00 CB 20 F5; +0AD0: CB 11 F1 CB 11 3D 20 F5 79 22 23 22 23 C9 E5 21; +0AE0: 0F FF CB 86 CB 46 28 FC E1 C9 3C 42 B9 A5 B9 A5; +0AF0: 42 3C 00 00 00 00 00 00 00 00 00 00 00 00 E0 50; +--Padding +0B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0DB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0DE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0EA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0ED0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +END; diff --git a/BootROMs/cgb_boot_fast.asm b/BootROMs/cgb_boot_fast.asm deleted file mode 100644 index cddb475..0000000 --- a/BootROMs/cgb_boot_fast.asm +++ /dev/null @@ -1,2 +0,0 @@ -FAST EQU 1 -include "cgb_boot.asm" \ No newline at end of file diff --git a/BootROMs/dmg_boot.bin b/BootROMs/dmg_boot.bin deleted file mode 100644 index 5f42834..0000000 Binary files a/BootROMs/dmg_boot.bin and /dev/null differ diff --git a/BootROMs/dmg_boot.mem b/BootROMs/dmg_boot.mem deleted file mode 100644 index f25ee30..0000000 --- a/BootROMs/dmg_boot.mem +++ /dev/null @@ -1,256 +0,0 @@ -31 -FE -FF -21 -00 -80 -22 -CB -6C -28 -FB -3E -80 -E0 -26 -E0 -11 -3E -F3 -E0 -12 -E0 -25 -3E -77 -E0 -24 -3E -FC -E0 -47 -11 -04 -01 -21 -10 -80 -1A -47 -CD -82 -00 -CD -82 -00 -13 -7B -EE -34 -20 -F2 -11 -B1 -00 -0E -08 -1A -13 -22 -23 -0D -20 -F9 -3E -19 -EA -10 -99 -21 -2F -99 -0E -0C -3D -28 -08 -32 -0D -20 -F9 -2E -0F -18 -F5 -3E -91 -E0 -40 -06 -2D -CD -A3 -00 -3E -83 -CD -AA -00 -06 -05 -CD -A3 -00 -3E -C1 -CD -AA -00 -06 -46 -CD -A3 -00 -21 -B0 -01 -E5 -F1 -21 -4D -01 -01 -13 -00 -11 -D8 -00 -C3 -FE -00 -3E -04 -0E -00 -CB -20 -F5 -CB -11 -F1 -CB -11 -3D -20 -F5 -79 -22 -23 -22 -23 -C9 -E5 -21 -0F -FF -CB -86 -CB -46 -28 -FC -E1 -C9 -CD -97 -00 -05 -20 -FA -C9 -E0 -13 -3E -87 -E0 -14 -C9 -3C -42 -B9 -A5 -B9 -A5 -42 -3C -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -00 -E0 -50 \ No newline at end of file diff --git a/BootROMs/agb_boot.asm b/BootROMs/src/cgb0_boot.asm similarity index 66% rename from BootROMs/agb_boot.asm rename to BootROMs/src/cgb0_boot.asm index 95a2c78..d49166d 100644 --- a/BootROMs/agb_boot.asm +++ b/BootROMs/src/cgb0_boot.asm @@ -1,2 +1,2 @@ -AGB EQU 1 +CGB0 EQU 1 include "cgb_boot.asm" \ No newline at end of file diff --git a/BootROMs/cgb_boot.asm b/BootROMs/src/cgb_boot.asm similarity index 61% rename from BootROMs/cgb_boot.asm rename to BootROMs/src/cgb_boot.asm index 0472cbe..e4a9757 100644 --- a/BootROMs/cgb_boot.asm +++ b/BootROMs/src/cgb_boot.asm @@ -1,27 +1,38 @@ -; SameBoy CGB bootstrap ROM -; Todo: use friendly names for HW registers instead of magic numbers +;MIT License +; +;Copyright (c) 2015-2023 Lior Halphon +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in all +;copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;SOFTWARE. + +; Note: +; rBANK ($ff50) is used as special MiSTer read-only register to add OSD boot options + +INCLUDE "hardware.inc" + SECTION "BootCode", ROM0[$0] Start: ; Init stack pointer ld sp, $fffe ; Clear memory VRAM - ld hl, $8000 - call ClearMemoryPage - ld a, 2 - ld c, $70 - ld [c], a -; Clear RAM Bank 2 (Like the original boot ROM - ld h, $D0 - xor a - call ClearMemoryPage - ld [c], a + call ClearMemoryPage8000 -; Clear chosen input palette - ldh [InputPalette], a -; Clear title checksum - ldh [TitleChecksum], a - ; Clear OAM ld h, $fe ld c, $a0 @@ -30,21 +41,35 @@ Start: dec c jr nz, .clearOAMLoop +IF !DEF(CGB0) +; Init waveform + ld c, $10 + ld hl, $FF30 +.waveformLoop + ldi [hl], a + cpl + dec c + jr nz, .waveformLoop +ENDC + +; Clear chosen input palette + ldh [InputPalette], a +; Clear title checksum + ldh [TitleChecksum], a + ; Init Audio ld a, $80 - ldh [$26], a - ldh [$11], a + ldh [rNR52], a + ldh [rNR11], a ld a, $f3 - ldh [$12], a - ldh [$25], a + ldh [rNR12], a + ldh [rNR51], a ld a, $77 - ldh [$24], a - - call InitWaveform + ldh [rNR50], a ; Init BG palette ld a, $fc - ldh [$47], a + ldh [rBGP], a ; Load logo from ROM. ; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8. @@ -66,17 +91,12 @@ Start: ; Clear the second VRAM bank ld a, 1 - ldh [$4F], a - xor a - ld hl, $8000 - call ClearMemoryPage - call LoadTileset - + ldh [rVBK], a + call ClearMemoryPage8000 + call CheckFastBoot + call z, LoadTileset + ld b, 3 -IF DEF(FAST) - xor a - ldh [$4F], a -ELSE ; Load Tilemap ld hl, $98C2 ld d, 3 @@ -87,37 +107,42 @@ ELSE .tilemapRowLoop - push af - ; Switch to second VRAM Bank - ld a, 1 - ldh [$4F], a - ld [hl], 8 - ; Switch to back first VRAM Bank - xor a - ldh [$4F], a - pop af - ldi [hl], a - add d + call .write_with_palette + add d ; d = 3 for CGB logo, d = 1 for Nintendo logo dec c jr nz, .tilemapRowLoop - sub 47 + sub 47 ; 3*16 = 48 not 44? push de ld de, $10 add hl, de pop de - dec b + + dec b ; Hit 3 times for CGB logo, then once more for Nintendo logo jr nz, .tilemapLoop - dec d + dec d ; Hit twice, once at end of CGB logo, next at end of Nintendo logo jr z, .endTilemap - dec d + dec d ; Prev. dec + this one takes d = 3 to d = 1 - ld a, $38 + ; Nintendo Logo + ld a, $38 ; Offset into tile map? d is now 1 though? ld l, $a7 - ld bc, $0107 + ld bc, $0107 ; 1 row, 7 columns for Nintendo logo jr .tilemapRowLoop + +.write_with_palette + push af + ; Switch to second VRAM Bank + ld a, 1 + ldh [rVBK], a + ld [hl], 8 + ; Switch to back first VRAM Bank + xor a + ldh [rVBK], a + pop af + ldi [hl], a + ret .endTilemap -ENDC ; Expand Palettes ld de, AnimationColors @@ -125,23 +150,14 @@ ENDC ld hl, BgPalettes xor a .expandPalettesLoop: -IF !DEF(FAST) cpl -ENDC + ; One white ldi [hl], a ldi [hl], a -IF DEF(FAST) - ; 3 more whites - ldi [hl], a - ldi [hl], a - ldi [hl], a - ldi [hl], a - ldi [hl], a - ldi [hl], a -ELSE ; The actual color + call CheckAGBPalette ld a, [de] inc de ldi [hl], a @@ -155,23 +171,31 @@ ELSE ldi [hl], a ldi [hl], a ldi [hl], a -ENDC dec c jr nz, .expandPalettesLoop - ld hl, BgPalettes - call LoadBGPalettes64 + call LoadPalettesFromHRAM ; Turn on LCD ld a, $91 - ldh [$40], a + ldh [rLCDC], a -IF !DEF(FAST) + call CheckFastBoot + jr z, .doAnimation + + ld a, $83 + call PlaySound + ld b, 5 + call WaitBFrames + jr .fastBoot + +.doAnimation call DoIntroAnimation -; Wait ~0.75 seconds - ld b, 45 + ld a, 48 ; frames to wait after playing the chime + ldh [WaitLoopCounter], a + ld b, 4 ; frames to wait before playing the chime call WaitBFrames ; Play first sound @@ -183,30 +207,31 @@ IF !DEF(FAST) ld a, $c1 call PlaySound -; Wait ~0.5 seconds - ld a, 30 - ldh [WaitLoopCounter], a - .waitLoop call GetInputPaletteIndex call WaitFrame ld hl, WaitLoopCounter dec [hl] jr nz, .waitLoop -ELSE - ld a, $c1 - call PlaySound -ENDC - call Preboot -; Will be filled with NOPs +.fastBoot + call Preboot + call CheckAGB + jr z, .cgbmode + inc b ; AGB mode set b = 1, reset z flag +.cgbmode + ld a, $11 + jr BootGame + +HDMAData: + db $D0, $00, $98, $A0, $12 + db $D0, $00, $80, $00, $40 SECTION "BootGame", ROM0[$fe] BootGame: - ldh [$50], a + ldh [rBANK], a ; unmap boot ROM SECTION "MoreStuff", ROM0[$200] - ; Game Palettes Data TitleChecksums: db $00 ; Default @@ -251,7 +276,7 @@ TitleChecksums: db $A2 ; STAR WARS-NOA db $49 ; db $4E ; WAVERACE - db $43 | $80 ; + db $43 ; db $68 ; LOLO2 db $E0 ; YOSHI'S COOKIE db $8B ; MYSTIC QUEST @@ -309,101 +334,103 @@ FirstChecksumWithDuplicate: ChecksumsEnd: PalettePerChecksum: -; | $80 means game requires DMG boot tilemap - db 0 ; Default Palette - db 4 ; ALLEY WAY - db 5 ; YAKUMAN - db 35 ; BASEBALL, (Game and Watch 2) - db 34 ; TENNIS - db 3 ; TETRIS - db 31 ; QIX - db 15 ; DR.MARIO - db 10 ; RADARMISSION - db 5 ; F1RACE - db 19 ; YOSSY NO TAMAGO - db 36 ; - db 7 | $80 ; X - db 37 ; MARIOLAND2 - db 30 ; YOSSY NO COOKIE - db 44 ; ZELDA - db 21 ; - db 32 ; - db 31 ; TETRIS FLASH - db 20 ; DONKEY KONG - db 5 ; MARIO'S PICROSS - db 33 ; - db 13 ; POKEMON RED, (GAMEBOYCAMERA G) - db 14 ; POKEMON GREEN - db 5 ; PICROSS 2 - db 29 ; YOSSY NO PANEPON - db 5 ; KIRAKIRA KIDS - db 18 ; GAMEBOY GALLERY - db 9 ; POCKETCAMERA - db 3 ; - db 2 ; BALLOON KID - db 26 ; KINGOFTHEZOO - db 25 ; DMG FOOTBALL - db 25 ; WORLD CUP - db 41 ; OTHELLO - db 42 ; SUPER RC PRO-AM - db 26 ; DYNABLASTER - db 45 ; BOY AND BLOB GB2 - db 42 ; MEGAMAN - db 45 ; STAR WARS-NOA - db 36 ; - db 38 ; WAVERACE - db 26 ; - db 42 ; LOLO2 - db 30 ; YOSHI'S COOKIE - db 41 ; MYSTIC QUEST - db 34 ; - db 34 ; TOPRANKINGTENNIS - db 5 ; MANSELL - db 42 ; MEGAMAN3 - db 6 ; SPACE INVADERS - db 5 ; GAME&WATCH - db 33 ; DONKEYKONGLAND95 - db 25 ; ASTEROIDS/MISCMD - db 42 ; STREET FIGHTER 2 - db 42 ; DEFENDER/JOUST - db 40 ; KILLERINSTINCT95 - db 2 ; TETRIS BLAST - db 16 ; PINOCCHIO - db 25 ; - db 42 ; BA.TOSHINDEN - db 42 ; NETTOU KOF 95 - db 5 ; - db 0 ; TETRIS PLUS - db 39 ; DONKEYKONGLAND 3 - db 36 ; - db 22 ; SUPER MARIOLAND - db 25 ; GOLF - db 6 ; SOLARSTRIKER - db 32 ; GBWARS - db 12 ; KAERUNOTAMENI - db 36 ; - db 11 ; POKEMON BLUE - db 39 ; DONKEYKONGLAND - db 18 ; GAMEBOY GALLERY2 - db 39 ; DONKEYKONGLAND 2 - db 24 ; KID ICARUS - db 31 ; TETRIS2 - db 50 ; - db 17 ; MOGURANYA - db 46 ; - db 6 ; GALAGA&GALAXIAN - db 27 ; BT2RAGNAROKWORLD - db 0 ; KEN GRIFFEY JR - db 47 ; - db 41 ; MAGNETIC SOCCER - db 41 ; VEGAS STAKES - db 0 ; - db 0 ; MILLI/CENTI/PEDE - db 19 ; MARIO & YOSHI - db 34 ; SOCCER - db 23 ; POKEBOM - db 18 ; G&W GALLERY - db 29 ; TETRIS ATTACK +MACRO palette_index ; palette, flags + db ((\1)) | (\2) ; | $80 means game requires DMG boot tilemap +ENDM + palette_index 0, 0 ; Default Palette + palette_index 4, 0 ; ALLEY WAY + palette_index 5, 0 ; YAKUMAN + palette_index 35, 0 ; BASEBALL, (Game and Watch 2) + palette_index 34, 0 ; TENNIS + palette_index 3, 0 ; TETRIS + palette_index 31, 0 ; QIX + palette_index 15, 0 ; DR.MARIO + palette_index 10, 0 ; RADARMISSION + palette_index 5, 0 ; F1RACE + palette_index 19, 0 ; YOSSY NO TAMAGO + palette_index 36, 0 ; + palette_index 7, $80 ; X + palette_index 37, 0 ; MARIOLAND2 + palette_index 30, 0 ; YOSSY NO COOKIE + palette_index 44, 0 ; ZELDA + palette_index 21, 0 ; + palette_index 32, 0 ; + palette_index 31, 0 ; TETRIS FLASH + palette_index 20, 0 ; DONKEY KONG + palette_index 5, 0 ; MARIO'S PICROSS + palette_index 33, 0 ; + palette_index 13, 0 ; POKEMON RED, (GAMEBOYCAMERA G) + palette_index 14, 0 ; POKEMON GREEN + palette_index 5, 0 ; PICROSS 2 + palette_index 29, 0 ; YOSSY NO PANEPON + palette_index 5, 0 ; KIRAKIRA KIDS + palette_index 18, 0 ; GAMEBOY GALLERY + palette_index 9, 0 ; POCKETCAMERA + palette_index 3, 0 ; + palette_index 2, 0 ; BALLOON KID + palette_index 26, 0 ; KINGOFTHEZOO + palette_index 25, 0 ; DMG FOOTBALL + palette_index 25, 0 ; WORLD CUP + palette_index 41, 0 ; OTHELLO + palette_index 42, 0 ; SUPER RC PRO-AM + palette_index 26, 0 ; DYNABLASTER + palette_index 45, 0 ; BOY AND BLOB GB2 + palette_index 42, 0 ; MEGAMAN + palette_index 45, 0 ; STAR WARS-NOA + palette_index 36, 0 ; + palette_index 38, 0 ; WAVERACE + palette_index 26, $80 ; + palette_index 42, 0 ; LOLO2 + palette_index 30, 0 ; YOSHI'S COOKIE + palette_index 41, 0 ; MYSTIC QUEST + palette_index 34, 0 ; + palette_index 34, 0 ; TOPRANKINGTENNIS + palette_index 5, 0 ; MANSELL + palette_index 42, 0 ; MEGAMAN3 + palette_index 6, 0 ; SPACE INVADERS + palette_index 5, 0 ; GAME&WATCH + palette_index 33, 0 ; DONKEYKONGLAND95 + palette_index 25, 0 ; ASTEROIDS/MISCMD + palette_index 42, 0 ; STREET FIGHTER 2 + palette_index 42, 0 ; DEFENDER/JOUST + palette_index 40, 0 ; KILLERINSTINCT95 + palette_index 2, 0 ; TETRIS BLAST + palette_index 16, 0 ; PINOCCHIO + palette_index 25, 0 ; + palette_index 42, 0 ; BA.TOSHINDEN + palette_index 42, 0 ; NETTOU KOF 95 + palette_index 5, 0 ; + palette_index 0, 0 ; TETRIS PLUS + palette_index 39, 0 ; DONKEYKONGLAND 3 + palette_index 36, 0 ; + palette_index 22, 0 ; SUPER MARIOLAND + palette_index 25, 0 ; GOLF + palette_index 6, 0 ; SOLARSTRIKER + palette_index 32, 0 ; GBWARS + palette_index 12, 0 ; KAERUNOTAMENI + palette_index 36, 0 ; + palette_index 11, 0 ; POKEMON BLUE + palette_index 39, 0 ; DONKEYKONGLAND + palette_index 18, 0 ; GAMEBOY GALLERY2 + palette_index 39, 0 ; DONKEYKONGLAND 2 + palette_index 24, 0 ; KID ICARUS + palette_index 31, 0 ; TETRIS2 + palette_index 50, 0 ; + palette_index 17, 0 ; MOGURANYA + palette_index 46, 0 ; + palette_index 6, 0 ; GALAGA&GALAXIAN + palette_index 27, 0 ; BT2RAGNAROKWORLD + palette_index 0, 0 ; KEN GRIFFEY JR + palette_index 47, 0 ; + palette_index 41, 0 ; MAGNETIC SOCCER + palette_index 41, 0 ; VEGAS STAKES + palette_index 0, 0 ; + palette_index 0, 0 ; MILLI/CENTI/PEDE + palette_index 19, 0 ; MARIO & YOSHI + palette_index 34, 0 ; SOCCER + palette_index 23, 0 ; POKEBOM + palette_index 18, 0 ; G&W GALLERY + palette_index 29, 0 ; TETRIS ATTACK Dups4thLetterArray: db "BEFAARBEKEK R-URAR INAILICE R" @@ -411,10 +438,10 @@ Dups4thLetterArray: ; We assume the last three arrays fit in the same $100 byte page! PaletteCombinations: -palette_comb: MACRO ; Obj0, Obj1, Bg +MACRO palette_comb ; Obj0, Obj1, Bg db (\1) * 8, (\2) * 8, (\3) *8 ENDM -raw_palette_comb: MACRO ; Obj0, Obj1, Bg +MACRO raw_palette_comb ; Obj0, Obj1, Bg db (\1) * 2, (\2) * 2, (\3) * 2 ENDM palette_comb 4, 4, 29 @@ -453,7 +480,7 @@ ENDM palette_comb 17, 4, 13 raw_palette_comb 28 * 4 - 1, 0 * 4, 14 * 4 raw_palette_comb 28 * 4 - 1, 4 * 4, 15 * 4 - palette_comb 19, 22, 9 + raw_palette_comb 19 * 4, 23 * 4 - 1, 9 * 4 palette_comb 16, 28, 10 palette_comb 4, 23, 28 palette_comb 17, 22, 2 @@ -468,11 +495,6 @@ ENDM palette_comb 4, 3, 28 palette_comb 28, 3, 6 palette_comb 4, 28, 29 - ; SameBoy "Exclusives" - palette_comb 30, 30, 30 ; CGA - palette_comb 31, 31, 31 ; DMG LCD - palette_comb 28, 4, 1 - palette_comb 0, 0, 2 Palettes: dw $7FFF, $32BF, $00D0, $0000 @@ -505,34 +527,27 @@ Palettes: dw $0000, $4200, $037F, $7FFF dw $7FFF, $7E8C, $7C00, $0000 dw $7FFF, $1BEF, $6180, $0000 - ; SameBoy "Exclusives" - dw $7FFF, $7FEA, $7D5F, $0000 ; CGA 1 - dw $4778, $3290, $1D87, $0861 ; DMG LCD -KeyCombinationPalettes - db 1 ; Right - db 48 ; Left - db 5 ; Up - db 8 ; Down - db 0 ; Right + A - db 40 ; Left + A - db 43 ; Up + A - db 3 ; Down + A - db 6 ; Right + B - db 7 ; Left + B - db 28 ; Up + B - db 49 ; Down + B - ; SameBoy "Exclusives" - db 51 ; Right + A + B - db 52 ; Left + A + B - db 53 ; Up + A + B - db 54 ; Down + A + B +KeyCombinationPalettes: + db 1 * 3 ; Right + db 48 * 3 ; Left + db 5 * 3 ; Up + db 8 * 3 ; Down + db 0 * 3 ; Right + A + db 40 * 3 ; Left + A + db 43 * 3 ; Up + A + db 3 * 3 ; Down + A + db 6 * 3 ; Right + B + db 7 * 3 ; Left + B + db 28 * 3 ; Up + B + db 49 * 3 ; Down + B TrademarkSymbol: db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c -SameBoyLogo: - incbin "SameBoyLogo.rle" +CGBLogo: + incbin "CGB_logo.rle" + AnimationColors: dw $7FFF ; White @@ -542,12 +557,11 @@ AnimationColors: dw $017D ; Orange dw $241D ; Red dw $6D38 ; Purple - dw $7102 ; Blue + dw $5500 ; Blue + dw $6D60 ; Blue ; AGB version of blue, only used when AGB mode is set + AnimationColorsEnd: -DMGPalettes: - dw $7FFF, $32BF, $00D0, $0000 - ; Helper Functions DoubleBitsAndWriteRowTwice: call .twice @@ -589,13 +603,16 @@ WaitBFrames: ret PlaySound: - ldh [$13], a + ldh [rNR13], a ld a, $87 - ldh [$14], a + ldh [rNR14], a ret +ClearMemoryPage8000: + ld hl, $8000 ; Clear from HL to HL | 0x2000 ClearMemoryPage: + xor a ldi [hl], a bit 5, h jr z, ClearMemoryPage @@ -626,6 +643,7 @@ ReadTileLine: ret +; Nintendo Logo ReadCGBLogoHalfTile: call .do_twice .do_twice @@ -635,10 +653,10 @@ ReadCGBLogoHalfTile: ret LoadTileset: -; Copy SameBoy Logo - ld de, SameBoyLogo +; Copy CGB Logo + ld de, CGBLogo ld hl, $8080 -.sameboyLogoLoop +.cgbLogoLoop ld a, [de] inc de @@ -658,7 +676,7 @@ LoadTileset: swap b ld a, b and $0f - jr z, .sameboyLogoEnd + jr z, .cgbLogoEnd ld c, a ld a, [de] inc de @@ -668,11 +686,12 @@ LoadTileset: inc hl dec c jr nz, .repeatLoop - jr .sameboyLogoLoop + jr .cgbLogoLoop -.sameboyLogoEnd +.cgbLogoEnd ; Copy (unresized) ROM logo ld de, $104 +; Nintendo logo .CGBROMLogoLoop ld c, $f0 call ReadCGBLogoHalfTile @@ -697,33 +716,10 @@ ReadTrademarkSymbol: jr nz, .loadTrademarkSymbolLoop ret -LoadObjPalettes: - ld c, $6A - jr LoadPalettes - -LoadBGPalettes64: - ld d, 64 - -LoadBGPalettes: - ld e, 0 - ld c, $68 - -LoadPalettes: - ld a, $80 - or e - ld [c], a - inc c -.loop - ld a, [hli] - ld [c], a - dec d - jr nz, .loop - ret - DoIntroAnimation: ; Animate the intro ld a, 1 - ldh [$4F], a + ldh [rVBK], a ld d, 26 .animationLoop ld b, 2 @@ -752,92 +748,132 @@ DoIntroAnimation: ret Preboot: -IF !DEF(FAST) + call CheckFastBoot + jr z, .fadeStart + ld a, $c1 + call PlaySound ; Play final sound, but fade loop still needed with fastboot to init LCD + +.fadeStart ld b, 32 ; 32 times to fade .fadeLoop ld c, 32 ; 32 colors to fade ld hl, BgPalettes .frameLoop push bc - call BrightenColor + + ; Brighten Color + ld a, [hli] + ld e, a + ld a, [hld] + ld d, a + ; RGB(1,1,1) + ld bc, $421 + + ; Is blue maxed? + ld a, e + and $1F + cp $1F + jr nz, .blueNotMaxed + dec c +.blueNotMaxed + + ; Is green maxed? + ld a, e + cp $E0 + jr c, .greenNotMaxed + ld a, d + and $3 + cp $3 + jr nz, .greenNotMaxed + res 5, c +.greenNotMaxed + + ; Is red maxed? + ld a, d + and $7C + cp $7C + jr nz, .redNotMaxed + res 2, b +.redNotMaxed + + ld a, e + add c + ld [hli], a + ld a, d + adc b + ld [hli], a pop bc + dec c jr nz, .frameLoop call WaitFrame + call LoadPalettesFromHRAM call WaitFrame - ld hl, BgPalettes - call LoadBGPalettes64 dec b jr nz, .fadeLoop -ENDC + + ld a, 2 + ldh [rSVBK], a + ; Clear RAM Bank 2 (Like the original boot ROM) + ld hl, $D000 + call ClearMemoryPage + inc a call ClearVRAMViaHDMA - ; Select the first bank + call _ClearVRAMViaHDMA + call ClearVRAMViaHDMA ; A = $40, so it's bank 0 xor a - ldh [$4F], a + ldh [rSVBK], a cpl - ldh [$00], a - call ClearVRAMViaHDMA - + ldh [rJOYP], a + ; Final values for CGB mode - ld de, $ff56 + ld d, a + ld e, c ld l, $0d - + + ; Check cart CGB compatibility byte ld a, [$143] - bit 7, a - call z, EmulateDMG - bit 7, a - - ldh [$4C], a + bit 7, a + call z, EmulateDMG + bit 7, a + + ldh [rKEY0], a ; write CGB compatibility byte, CGB mode ldh a, [TitleChecksum] ld b, a - + jr z, .skipDMGForCGBCheck ldh a, [InputPalette] - and a - jr nz, .emulateDMGForCGBGame .skipDMGForCGBCheck -IF DEF(AGB) - ; Set registers to match the original AGB-CGB boot - ; AF = $1100, C = 0 - xor a - ld c, a - add a, $11 - ld h, c - ld b, 1 -ELSE ; Set registers to match the original CGB boot - ; AF = $1180, C = 0 xor a ld c, a - ld a, $11 ld h, c - ; B is set to the title checksum -ENDC ret -.emulateDMGForCGBGame - call EmulateDMG - ldh [$4C], a - ld a, $1 +GetKeyComboPalette: + ld hl, KeyCombinationPalettes - 1 ; Return value is 1-based, 0 means nothing down + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] ret EmulateDMG: ld a, 1 - ldh [$6C], a ; DMG Emulation + ldh [rOPRI], a ; DMG Emulation sprite priority call GetPaletteIndex bit 7, a call nz, LoadDMGTilemap - and $7F + res 7, a + ld b, a + add b + add b ld b, a ldh a, [InputPalette] and a jr z, .nothingDown - ld hl, KeyCombinationPalettes - 1 ; Return value is 1-based, 0 means nothing down - ld c ,a - ld b, 0 - add hl, bc - ld a, [hl] + call GetKeyComboPalette jr .paletteFromKeys .nothingDown ld a, b @@ -846,8 +882,7 @@ EmulateDMG: call LoadPalettesFromIndex ld a, 4 ; Set the final values for DMG mode - ld d, 0 - ld e, $8 + ld de, 8 ld l, $7c ret @@ -878,6 +913,7 @@ GetPaletteIndex: inc l dec c jr nz, .checksumLoop + ldh [TitleChecksum], a ld b, a ; c = 0 @@ -893,7 +929,7 @@ GetPaletteIndex: ; We might have a match, Do duplicate/4th letter check ld a, l - sub FirstChecksumWithDuplicate - TitleChecksums + sub FirstChecksumWithDuplicate - TitleChecksums + 1 jr c, .match ; Does not have a duplicate, must be a match! ; Has a duplicate; check 4th letter push hl @@ -920,16 +956,16 @@ GetPaletteIndex: xor a ret -LoadPalettesFromIndex: ; a = index of combination - ld b, a - ; Multiply by 3 - add b - add b - +; optimizations in callers rely on this returning with b = 0 +GetPaletteCombo: ld hl, PaletteCombinations ld b, 0 ld c, a add hl, bc + ret + +LoadPalettesFromIndex: ; a = index of combination + call GetPaletteCombo ; Obj Palettes ld e, 0 @@ -937,11 +973,12 @@ LoadPalettesFromIndex: ; a = index of combination ld a, [hli] push hl ld hl, Palettes - ld b, 0 + ; b is already 0 ld c, a add hl, bc ld d, 8 - call LoadObjPalettes + ld c, $6A + call LoadPalettes pop hl bit 3, e jr nz, .loadBGPalette @@ -949,142 +986,94 @@ LoadPalettesFromIndex: ; a = index of combination jr .loadObjPalette .loadBGPalette ;BG Palette - ld a, [hli] + ld c, [hl] + ; b is already 0 ld hl, Palettes - ld b, 0 - ld c, a add hl, bc ld d, 8 - jp LoadBGPalettes + jr LoadBGPalettes -BrightenColor: +LoadPalettesFromHRAM: + ld hl, BgPalettes + ld d, 64 + +LoadBGPalettes: + ld e, 0 + ld c, LOW(rBGPI) + +LoadPalettes: + ld a, $80 + or e + ld [c], a + inc c +.loop ld a, [hli] - ld e, a - ld a, [hld] - ld d, a - ; RGB(1,1,1) - ld bc, $421 - - ; Is blue maxed? - ld a, e - and $1F - cp $1F - jr nz, .blueNotMaxed - res 0, c -.blueNotMaxed - - ; Is green maxed? - ld a, e - and $E0 - cp $E0 - jr nz, .greenNotMaxed - ld a, d - and $3 - cp $3 - jr nz, .greenNotMaxed - res 5, c -.greenNotMaxed - - ; Is red maxed? - ld a, d - and $7C - cp $7C - jr nz, .redNotMaxed - res 2, b -.redNotMaxed - - ; Add de to bc - push hl - ld h, d - ld l, e - add hl, bc - ld d, h - ld e, l - pop hl - - ld a, e - ld [hli], a - ld a, d - ld [hli], a + ld [c], a + dec d + jr nz, .loop ret ClearVRAMViaHDMA: - ld hl, $FF51 - - ; Src - ld a, $88 - ld [hli], a - xor a - ld [hli], a - - ; Dest - ld a, $98 - ld [hli], a - ld a, $A0 - ld [hli], a - - ; Do it - ld [hl], $12 + ldh [rVBK], a + ld hl, HDMAData +_ClearVRAMViaHDMA: + call WaitFrame ; Wait for vblank + ld c, $51 + ld b, 5 +.loop + ld a, [hli] + ldh [c], a + inc c + dec b + jr nz, .loop ret +; clobbers AF and HL GetInputPaletteIndex: + ld a, [$143] + bit 7, a + ret nz ; if CGB game, palette cannot be chosen + ld a, $20 ; Select directions - ldh [$00], a - ldh a, [$00] + ldh [rJOYP], a + ldh a, [rJOYP] cpl and $F ret z ; No direction keys pressed, no palette - push bc - ld c, 0 + ld l, 0 .directionLoop - inc c + inc l rra jr nc, .directionLoop ; c = 1: Right, 2: Left, 3: Up, 4: Down ld a, $10 ; Select buttons - ldh [$00], a - ldh a, [$00] + ldh [rJOYP], a + ldh a, [rJOYP] cpl rla rla and $C - add c - ld b, a + add l + ld l, a ldh a, [InputPalette] - ld c, a - ld a, b - ldh [InputPalette], a - cp c - pop bc + cp l ret z ; No change, don't load + ld a, l + ldh [InputPalette], a ; Slide into change Animation Palette ChangeAnimationPalette: - push af - push hl push bc push de - ld hl, KeyCombinationPalettes - 1 ; Input palettes are 1-based, 0 means nothing down - ld c ,a - ld b, 0 - add hl, bc - ld a, [hl] - ld b, a - ; Multiply by 3 - add b - add b - - ld hl, PaletteCombinations + 2; Background Palette - ld b, 0 - ld c, a - add hl, bc - ld a, [hl] + call GetKeyComboPalette + call GetPaletteCombo + inc l + inc l + ld c, [hl] ld hl, Palettes + 1 - ld b, 0 - ld c, a add hl, bc ld a, [hld] cp $7F ; Is white color? @@ -1094,58 +1083,83 @@ ChangeAnimationPalette: .isWhite push af ld a, [hli] + push hl - ld hl, BgPalettes ; First color, all palette + ld hl, BgPalettes ; First color, all palettes + call ReplaceColorInAllPalettes + ld l, LOW(BgPalettes + 2) ; Second color, all palettes call ReplaceColorInAllPalettes pop hl - ldh [BgPalettes + 2], a ; Second color, first palette + ldh [BgPalettes + 6], a ; Fourth color, first palette ld a, [hli] push hl - ld hl, BgPalettes + 1 ; First color, all palette + ld hl, BgPalettes + 1 ; First color, all palettes + call ReplaceColorInAllPalettes + ld l, LOW(BgPalettes + 3) ; Second color, all palettes call ReplaceColorInAllPalettes pop hl - ldh [BgPalettes + 3], a ; Second color, first palette + ldh [BgPalettes + 7], a ; Fourth color, first palette + pop af jr z, .isNotWhite inc hl inc hl .isNotWhite + ; Mixing code by ISSOtm + ldh a, [BgPalettes + 7 * 8 + 2] + and ~$21 + ld b, a ld a, [hli] - ldh [BgPalettes + 7 * 8 + 2], a ; Second color, 7th palette + and ~$21 + add a, b + ld b, a + ld a, [BgPalettes + 7 * 8 + 3] + res 2, a ; and ~$04, but not touching carry + ld c, [hl] + res 2, c ; and ~$04, but not touching carry + adc a, c + rra ; Carry sort of "extends" the accumulator, we're bringing that bit back home + ld [BgPalettes + 7 * 8 + 3], a + ld a, b + rra + ld [BgPalettes + 7 * 8 + 2], a + dec l + ld a, [hli] - ldh [BgPalettes + 7 * 8 + 3], a ; Second color, 7th palette + ldh [BgPalettes + 7 * 8 + 6], a ; Fourth color, 7th palette + ld a, [hli] + ldh [BgPalettes + 7 * 8 + 7], a ; Fourth color, 7th palette + ld a, [hli] ldh [BgPalettes + 4], a ; Third color, first palette - ld a, [hl] + ld a, [hli] ldh [BgPalettes + 5], a ; Third color, first palette + call WaitFrame - ld hl, BgPalettes - call LoadBGPalettes64 + call LoadPalettesFromHRAM ; Delay the wait loop while the user is selecting a palette - ld a, 30 + ld a, 48 ldh [WaitLoopCounter], a pop de pop bc - pop hl - pop af ret ReplaceColorInAllPalettes: ld de, 8 - ld c, 8 + ld c, e .loop ld [hl], a add hl, de dec c jr nz, .loop ret - + LoadDMGTilemap: push af call WaitFrame - ld a,$19 ; Trademark symbol + ld a, $19 ; Trademark symbol ld [$9910], a ; ... put in the superscript position ld hl,$992f ; Bottom right corner of the logo ld c,$c ; Tiles in a logo row @@ -1155,27 +1169,41 @@ LoadDMGTilemap: ldd [hl], a dec c jr nz, .tilemapLoop - ld l,$0f ; Jump to top row + ld l, $0f ; Jump to top row jr .tilemapLoop .tilemapDone pop af ret -InitWaveform: - ld hl, $FF30 -; Init waveform - xor a - ld c, $10 -.waveformLoop - ldi [hl], a - cpl - dec c - jr nz, .waveformLoop +CheckAGB: + ldh a, [rBANK] + bit 0, a ret -SECTION "ROMMax", ROM0[$900] - ; Prevent us from overflowing - ds 1 +CheckFastBoot: + ldh a, [rBANK] + bit 1, a + ret + +CheckAGBPalette: + push hl + call CheckAGB + jr z, .normalPalette +; Check if we are loading the final blue color + ld hl, AnimationColors+14 + ld a, e + cp a, l + jr nz, .normalPalette + inc de ; Skip the CGB blue, use AGB blue + inc de +.normalPalette + pop hl + ret + +BootEnd: +IF BootEnd > $900 + FAIL "BootROM overflowed: {BootEnd}" +ENDC SECTION "HRAM", HRAM[$FF80] TitleChecksum: diff --git a/BootROMs/src/checksum.c b/BootROMs/src/checksum.c new file mode 100644 index 0000000..a7fff14 --- /dev/null +++ b/BootROMs/src/checksum.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include + +#define DMG_BIOS_SIZE 256 +#define CGB_BIOS_SIZE 2304 +#define PRINT_BYTES_PER_COL 16 + +int checksum_single_byte(FILE *, unsigned int); +int checksum_double_byte(FILE *, unsigned int); +int checksum_word(FILE *, unsigned int); +FILE *open_file(char *, unsigned int); +void print_bin(FILE *, unsigned int); + +int main(int argc, char** argv) { + unsigned int checksum; + unsigned int filesize = CGB_BIOS_SIZE; + FILE *bin; + if (argc < 2) { + printf("Binary file must be passed on the command line\n"); + return -1; + } + + bin = open_file(argv[1], filesize); + fseek(bin, 0, SEEK_END); + filesize = ftell(bin); + rewind(bin); + + print_bin(bin, filesize); + rewind(bin); + + printf("\n"); + printf("Calculating file checksum with different chunk sizes\n"); + checksum = checksum_word(bin, filesize); + printf("\tWords (%2lu-bit %4d words) = %#11x\n", sizeof(uint32_t)*8, filesize >> 2, checksum); + rewind(bin); + + checksum = checksum_double_byte(bin, filesize); + printf("\tHalf-words (%2lu-bit %4d hwords) = %#11x\n", sizeof(uint16_t)*8, filesize >> 1, checksum); + + rewind(bin); + checksum = checksum_single_byte(bin, filesize); + printf("\tBytes (%2lu-bit %4d bytes) = %#11x\n", sizeof(uint8_t)*8, filesize, checksum); + + fclose(bin); + return 0; +} + +FILE* open_file(char * filename, unsigned int filesize) { + FILE * file = fopen(filename, "rb"); + if (!file) { + printf("File '%s' does not exist\n", filename); + exit(-1); + } + return file; +} + +int checksum_single_byte(FILE *bin, unsigned int filesize) { + int checksum = 0; + uint8_t byte = 0; + unsigned char buffer[filesize]; + int i = 0; + + fread(&buffer, sizeof(uint8_t), filesize, bin); + for (i = 0; i < filesize; i++) { + byte = buffer[i]; + checksum += byte; + } + + return checksum; +} + +int checksum_double_byte(FILE *bin, unsigned int filesize) { + int checksum = 0; + int num_hwords = filesize >> 1; + uint16_t hword = 0; + uint16_t buffer[num_hwords]; + int i = 0; + + fread(&buffer, sizeof(uint16_t), num_hwords, bin); + for (i = 0; i < num_hwords; i++) { + hword = buffer[i]; + checksum += hword; + + } + + return checksum; +} + +int checksum_word(FILE *bin, unsigned int filesize) { + int checksum = 0; + int num_words = filesize >> 2; + uint32_t word = 0; + uint32_t buffer[num_words]; + int i = 0; + + fread(&buffer, sizeof(uint32_t), num_words, bin); + for (i = 0; i < num_words; i++) { + word = buffer[i]; + checksum += word; + } + + return checksum; +} + +void print_bin(FILE *bin, unsigned int filesize) { + uint8_t byte = 0; + unsigned char buffer[filesize]; + int i = 0; + + fread(&buffer, sizeof(uint8_t), filesize, bin); + printf("Binary file contents:"); + for (i = 0; i < filesize; i++) { + if (i % PRINT_BYTES_PER_COL == 0) { + printf("\n"); + printf("0x%03X |", i); + } + byte = buffer[i]; + printf("%3X ", byte); + } + printf("\n"); +} diff --git a/BootROMs/dmg_boot.asm b/BootROMs/src/dmg_boot.asm similarity index 51% rename from BootROMs/dmg_boot.asm rename to BootROMs/src/dmg_boot.asm index 6fb74fb..e00619e 100644 --- a/BootROMs/dmg_boot.asm +++ b/BootROMs/src/dmg_boot.asm @@ -1,5 +1,27 @@ -; SameBoy DMG bootstrap ROM -; Todo: use friendly names for HW registers instead of magic numbers +;MIT License +; +;Copyright (c) 2015-2023 Lior Halphon +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in all +;copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;SOFTWARE. + +INCLUDE "hardware.inc" + SECTION "BootCode", ROM0[$0] Start: ; Init stack pointer @@ -15,18 +37,34 @@ Start: ; Init Audio ld a, $80 - ldh [$26], a - ldh [$11], a + ldh [rNR52], a + ldh [rNR11], a ld a, $f3 - ldh [$12], a - ldh [$25], a + ldh [rNR12], a + ldh [rNR51], a ld a, $77 - ldh [$24], a + ldh [rNR50], a ; Init BG palette ld a, $fc - ldh [$47], a + ldh [rBGP], a + +; Fast Boot option + ldh a, [rBANK] + bit 1, a + jr z, .noFastBoot + ; Turn on LCD + ld a, $91 + ldh [rLCDC], a + ld a, $83 + call PlaySound + ld b, 5 + call WaitBFrames + + jr .finalSetup + +.noFastBoot ; Load logo from ROM. ; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8. ; Tiles are ordered left to right, top to bottom. @@ -69,35 +107,64 @@ Start: jr .tilemapLoop .tilemapDone + ld a, $64 + ldh [rSCY], a + ld d, a ; Set loop count $64 + ; Turn on LCD ld a, $91 - ldh [$40], a + ldh [rLCDC], a -; Wait ~0.75 seconds - ld b, 45 - call WaitBFrames + ld b, $83 ; Pre-load first sound +.animate + call WaitFrame + call WaitFrame - ; Play first sound - ld a, $83 + ld a, d + + cp $3 ; $62 frames in, play first sound + jr z, .soundFrame + + cp $1 + jr nz, .noSoundFrame + ld b, $c1 ; Play second sound on final animation frame +.soundFrame + ld a, b call PlaySound - ld b, 5 +.noSoundFrame + dec d + ld a, d + ldh [rSCY], a ; Scroll logo down 1 row + jr nz, .animate + +.endAnimation +; Wait ~1 second + ld b, 60 call WaitBFrames - ; Play second sound + +.finalSetup +; Play final sound if fast boot was used + ldh a, [rBANK] + bit 1, a + jr z, .skipSound ld a, $c1 call PlaySound - -; Wait ~1.15 seconds - ld b, 70 + ld b, 30 ; Wait ~0.5 s call WaitBFrames - +.skipSound + ; Set registers to match the original DMG boot +IF DEF(MGB) + ld hl, $FFB0 +ELSE ld hl, $01B0 +ENDC push hl pop af ld hl, $014D ld bc, $0013 ld de, $00D8 - + ; Boot the game jp BootGame @@ -139,9 +206,9 @@ WaitBFrames: ret PlaySound: - ldh [$13], a + ldh [rNR13], a ld a, $87 - ldh [$14], a + ldh [rNR14], a ret @@ -150,4 +217,4 @@ db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c SECTION "BootGame", ROM0[$fe] BootGame: - ldh [$50], a \ No newline at end of file + ldh [rBANK], a ; unmap boot ROM diff --git a/BootROMs/src/hardware.inc b/BootROMs/src/hardware.inc new file mode 100755 index 0000000..b341f1c --- /dev/null +++ b/BootROMs/src/hardware.inc @@ -0,0 +1,988 @@ +;* +;* Gameboy Hardware definitions +;* +;* Based on Jones' hardware.inc +;* And based on Carsten Sorensen's ideas. +;* +;* Rev 1.1 - 15-Jul-97 : Added define check +;* Rev 1.2 - 18-Jul-97 : Added revision check macro +;* Rev 1.3 - 19-Jul-97 : Modified for RGBASM V1.05 +;* Rev 1.4 - 27-Jul-97 : Modified for new subroutine prefixes +;* Rev 1.5 - 15-Aug-97 : Added _HRAM, PAD, CART defines +;* : and Nintendo Logo +;* Rev 1.6 - 30-Nov-97 : Added rDIV, rTIMA, rTMA, & rTAC +;* Rev 1.7 - 31-Jan-98 : Added _SCRN0, _SCRN1 +;* Rev 1.8 - 15-Feb-98 : Added rSB, rSC +;* Rev 1.9 - 16-Feb-98 : Converted I/O registers to $FFXX format +;* Rev 2.0 - : Added GBC registers +;* Rev 2.1 - : Added MBC5 & cart RAM enable/disable defines +;* Rev 2.2 - : Fixed NR42,NR43, & NR44 equates +;* Rev 2.3 - : Fixed incorrect _HRAM equate +;* Rev 2.4 - 27-Apr-13 : Added some cart defines (AntonioND) +;* Rev 2.5 - 03-May-15 : Fixed format (AntonioND) +;* Rev 2.6 - 09-Apr-16 : Added GBC OAM and cart defines (AntonioND) +;* Rev 2.7 - 19-Jan-19 : Added rPCMXX (ISSOtm) +;* Rev 2.8 - 03-Feb-19 : Added audio registers flags (Álvaro Cuesta) +;* Rev 2.9 - 28-Feb-20 : Added utility rP1 constants +;* Rev 3.0 - 27-Aug-20 : Register ordering, byte-based sizes, OAM additions, general cleanup (Blitter Object) +;* Rev 4.0 - 03-May-21 : Updated to use RGBDS 0.5.0 syntax, changed IEF_LCDC to IEF_STAT (Eievui) +;* Rev 4.1 - 16-Aug-21 : Added more flags, bit number defines, and offset constants for OAM and window positions (rondnelson99) +;* Rev 4.2 - 04-Sep-21 : Added CH3- and CH4-specific audio registers flags (ISSOtm) +;* Rev 4.3 - 07-Nov-21 : Deprecate VRAM address constants (Eievui) +;* Rev 4.4 - 11-Jan-22 : Deprecate VRAM CART_SRAM_2KB constant (avivace) +;* Rev 4.5 - 03-Mar-22 : Added bit number definitions for OCPS, BCPS and LCDC (sukus) + +IF __RGBDS_MAJOR__ == 0 && __RGBDS_MINOR__ < 5 + FAIL "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later." +ENDC + +; If all of these are already defined, don't do it again. + + IF !DEF(HARDWARE_INC) +DEF HARDWARE_INC EQU 1 + +MACRO rev_Check_hardware_inc +;NOTE: REVISION NUMBER CHANGES MUST BE ADDED +;TO SECOND PARAMETER IN FOLLOWING LINE. + IF \1 > 4.5 ;PUT REVISION NUMBER HERE + WARN "Version \1 or later of 'hardware.inc' is required." + ENDC +ENDM + +DEF _VRAM EQU $8000 ; $8000->$9FFF +DEF _SCRN0 EQU $9800 ; $9800->$9BFF +DEF _SCRN1 EQU $9C00 ; $9C00->$9FFF +DEF _SRAM EQU $A000 ; $A000->$BFFF +DEF _RAM EQU $C000 ; $C000->$CFFF / $C000->$DFFF +DEF _RAMBANK EQU $D000 ; $D000->$DFFF +DEF _OAMRAM EQU $FE00 ; $FE00->$FE9F +DEF _IO EQU $FF00 ; $FF00->$FF7F,$FFFF +DEF _AUD3WAVERAM EQU $FF30 ; $FF30->$FF3F +DEF _HRAM EQU $FF80 ; $FF80->$FFFE + +; *** MBC5 Equates *** + +DEF rRAMG EQU $0000 ; $0000->$1fff +DEF rROMB0 EQU $2000 ; $2000->$2fff +DEF rROMB1 EQU $3000 ; $3000->$3fff - If more than 256 ROM banks are present. +DEF rRAMB EQU $4000 ; $4000->$5fff - Bit 3 enables rumble (if present) + + +;*************************************************************************** +;* +;* Custom registers +;* +;*************************************************************************** + +; -- +; -- P1 ($FF00) +; -- Register for reading joy pad info. (R/W) +; -- +DEF rP1 EQU $FF00 + +DEF P1F_5 EQU %00100000 ; P15 out port, set to 0 to get buttons +DEF P1F_4 EQU %00010000 ; P14 out port, set to 0 to get dpad +DEF P1F_3 EQU %00001000 ; P13 in port +DEF P1F_2 EQU %00000100 ; P12 in port +DEF P1F_1 EQU %00000010 ; P11 in port +DEF P1F_0 EQU %00000001 ; P10 in port + +DEF P1F_GET_DPAD EQU P1F_5 +DEF P1F_GET_BTN EQU P1F_4 +DEF P1F_GET_NONE EQU P1F_4 | P1F_5 + + +; -- +; -- SB ($FF01) +; -- Serial Transfer Data (R/W) +; -- +DEF rSB EQU $FF01 + + +; -- +; -- SC ($FF02) +; -- Serial I/O Control (R/W) +; -- +DEF rSC EQU $FF02 + +DEF SCF_START EQU %10000000 ;Transfer Start Flag (1=Transfer in progress, or requested) +DEF SCF_SPEED EQU %00000010 ;Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only ** +DEF SCF_SOURCE EQU %00000001 ;Shift Clock (0=External Clock, 1=Internal Clock) + +DEF SCB_START EQU 7 +DEF SCB_SPEED EQU 1 +DEF SCB_SOURCE EQU 0 + +; -- +; -- DIV ($FF04) +; -- Divider register (R/W) +; -- +DEF rDIV EQU $FF04 + + +; -- +; -- TIMA ($FF05) +; -- Timer counter (R/W) +; -- +DEF rTIMA EQU $FF05 + + +; -- +; -- TMA ($FF06) +; -- Timer modulo (R/W) +; -- +DEF rTMA EQU $FF06 + + +; -- +; -- TAC ($FF07) +; -- Timer control (R/W) +; -- +DEF rTAC EQU $FF07 + +DEF TACF_START EQU %00000100 +DEF TACF_STOP EQU %00000000 +DEF TACF_4KHZ EQU %00000000 +DEF TACF_16KHZ EQU %00000011 +DEF TACF_65KHZ EQU %00000010 +DEF TACF_262KHZ EQU %00000001 + +DEF TACB_START EQU 2 + + +; -- +; -- IF ($FF0F) +; -- Interrupt Flag (R/W) +; -- +DEF rIF EQU $FF0F + + +; -- +; -- AUD1SWEEP/NR10 ($FF10) +; -- Sweep register (R/W) +; -- +; -- Bit 6-4 - Sweep Time +; -- Bit 3 - Sweep Increase/Decrease +; -- 0: Addition (frequency increases???) +; -- 1: Subtraction (frequency increases???) +; -- Bit 2-0 - Number of sweep shift (# 0-7) +; -- Sweep Time: (n*7.8ms) +; -- +DEF rNR10 EQU $FF10 +DEF rAUD1SWEEP EQU rNR10 + +DEF AUD1SWEEP_UP EQU %00000000 +DEF AUD1SWEEP_DOWN EQU %00001000 + + +; -- +; -- AUD1LEN/NR11 ($FF11) +; -- Sound length/Wave pattern duty (R/W) +; -- +; -- Bit 7-6 - Wave Pattern Duty (00:12.5% 01:25% 10:50% 11:75%) +; -- Bit 5-0 - Sound length data (# 0-63) +; -- +DEF rNR11 EQU $FF11 +DEF rAUD1LEN EQU rNR11 + + +; -- +; -- AUD1ENV/NR12 ($FF12) +; -- Envelope (R/W) +; -- +; -- Bit 7-4 - Initial value of envelope +; -- Bit 3 - Envelope UP/DOWN +; -- 0: Decrease +; -- 1: Range of increase +; -- Bit 2-0 - Number of envelope sweep (# 0-7) +; -- +DEF rNR12 EQU $FF12 +DEF rAUD1ENV EQU rNR12 + + +; -- +; -- AUD1LOW/NR13 ($FF13) +; -- Frequency low byte (W) +; -- +DEF rNR13 EQU $FF13 +DEF rAUD1LOW EQU rNR13 + + +; -- +; -- AUD1HIGH/NR14 ($FF14) +; -- Frequency high byte (W) +; -- +; -- Bit 7 - Initial (when set, sound restarts) +; -- Bit 6 - Counter/consecutive selection +; -- Bit 2-0 - Frequency's higher 3 bits +; -- +DEF rNR14 EQU $FF14 +DEF rAUD1HIGH EQU rNR14 + + +; -- +; -- AUD2LEN/NR21 ($FF16) +; -- Sound Length; Wave Pattern Duty (R/W) +; -- +; -- see AUD1LEN for info +; -- +DEF rNR21 EQU $FF16 +DEF rAUD2LEN EQU rNR21 + + +; -- +; -- AUD2ENV/NR22 ($FF17) +; -- Envelope (R/W) +; -- +; -- see AUD1ENV for info +; -- +DEF rNR22 EQU $FF17 +DEF rAUD2ENV EQU rNR22 + + +; -- +; -- AUD2LOW/NR23 ($FF18) +; -- Frequency low byte (W) +; -- +DEF rNR23 EQU $FF18 +DEF rAUD2LOW EQU rNR23 + + +; -- +; -- AUD2HIGH/NR24 ($FF19) +; -- Frequency high byte (W) +; -- +; -- see AUD1HIGH for info +; -- +DEF rNR24 EQU $FF19 +DEF rAUD2HIGH EQU rNR24 + + +; -- +; -- AUD3ENA/NR30 ($FF1A) +; -- Sound on/off (R/W) +; -- +; -- Bit 7 - Sound ON/OFF (1=ON,0=OFF) +; -- +DEF rNR30 EQU $FF1A +DEF rAUD3ENA EQU rNR30 + +DEF AUD3ENA_OFF EQU %00000000 +DEF AUD3ENA_ON EQU %10000000 + + +; -- +; -- AUD3LEN/NR31 ($FF1B) +; -- Sound length (R/W) +; -- +; -- Bit 7-0 - Sound length +; -- +DEF rNR31 EQU $FF1B +DEF rAUD3LEN EQU rNR31 + + +; -- +; -- AUD3LEVEL/NR32 ($FF1C) +; -- Select output level +; -- +; -- Bit 6-5 - Select output level +; -- 00: 0/1 (mute) +; -- 01: 1/1 +; -- 10: 1/2 +; -- 11: 1/4 +; -- +DEF rNR32 EQU $FF1C +DEF rAUD3LEVEL EQU rNR32 + +DEF AUD3LEVEL_MUTE EQU %00000000 +DEF AUD3LEVEL_100 EQU %00100000 +DEF AUD3LEVEL_50 EQU %01000000 +DEF AUD3LEVEL_25 EQU %01100000 + + +; -- +; -- AUD3LOW/NR33 ($FF1D) +; -- Frequency low byte (W) +; -- +; -- see AUD1LOW for info +; -- +DEF rNR33 EQU $FF1D +DEF rAUD3LOW EQU rNR33 + + +; -- +; -- AUD3HIGH/NR34 ($FF1E) +; -- Frequency high byte (W) +; -- +; -- see AUD1HIGH for info +; -- +DEF rNR34 EQU $FF1E +DEF rAUD3HIGH EQU rNR34 + + +; -- +; -- AUD4LEN/NR41 ($FF20) +; -- Sound length (R/W) +; -- +; -- Bit 5-0 - Sound length data (# 0-63) +; -- +DEF rNR41 EQU $FF20 +DEF rAUD4LEN EQU rNR41 + + +; -- +; -- AUD4ENV/NR42 ($FF21) +; -- Envelope (R/W) +; -- +; -- see AUD1ENV for info +; -- +DEF rNR42 EQU $FF21 +DEF rAUD4ENV EQU rNR42 + + +; -- +; -- AUD4POLY/NR43 ($FF22) +; -- Polynomial counter (R/W) +; -- +; -- Bit 7-4 - Selection of the shift clock frequency of the (scf) +; -- polynomial counter (0000-1101) +; -- freq=drf*1/2^scf (not sure) +; -- Bit 3 - Selection of the polynomial counter's step +; -- 0: 15 steps +; -- 1: 7 steps +; -- Bit 2-0 - Selection of the dividing ratio of frequencies (drf) +; -- 000: f/4 001: f/8 010: f/16 011: f/24 +; -- 100: f/32 101: f/40 110: f/48 111: f/56 (f=4.194304 Mhz) +; -- +DEF rNR43 EQU $FF22 +DEF rAUD4POLY EQU rNR43 + +DEF AUD4POLY_15STEP EQU %00000000 +DEF AUD4POLY_7STEP EQU %00001000 + + +; -- +; -- AUD4GO/NR44 ($FF23) +; -- +; -- Bit 7 - Initial (when set, sound restarts) +; -- Bit 6 - Counter/consecutive selection +; -- +DEF rNR44 EQU $FF23 +DEF rAUD4GO EQU rNR44 + + +; -- +; -- AUDVOL/NR50 ($FF24) +; -- Channel control / ON-OFF / Volume (R/W) +; -- +; -- Bit 7 - Vin->SO2 ON/OFF (left) +; -- Bit 6-4 - SO2 output level (left speaker) (# 0-7) +; -- Bit 3 - Vin->SO1 ON/OFF (right) +; -- Bit 2-0 - SO1 output level (right speaker) (# 0-7) +; -- +DEF rNR50 EQU $FF24 +DEF rAUDVOL EQU rNR50 + +DEF AUDVOL_VIN_LEFT EQU %10000000 ; SO2 +DEF AUDVOL_VIN_RIGHT EQU %00001000 ; SO1 + + +; -- +; -- AUDTERM/NR51 ($FF25) +; -- Selection of Sound output terminal (R/W) +; -- +; -- Bit 7 - Output channel 4 to SO2 terminal (left) +; -- Bit 6 - Output channel 3 to SO2 terminal (left) +; -- Bit 5 - Output channel 2 to SO2 terminal (left) +; -- Bit 4 - Output channel 1 to SO2 terminal (left) +; -- Bit 3 - Output channel 4 to SO1 terminal (right) +; -- Bit 2 - Output channel 3 to SO1 terminal (right) +; -- Bit 1 - Output channel 2 to SO1 terminal (right) +; -- Bit 0 - Output channel 1 to SO1 terminal (right) +; -- +DEF rNR51 EQU $FF25 +DEF rAUDTERM EQU rNR51 + +; SO2 +DEF AUDTERM_4_LEFT EQU %10000000 +DEF AUDTERM_3_LEFT EQU %01000000 +DEF AUDTERM_2_LEFT EQU %00100000 +DEF AUDTERM_1_LEFT EQU %00010000 +; SO1 +DEF AUDTERM_4_RIGHT EQU %00001000 +DEF AUDTERM_3_RIGHT EQU %00000100 +DEF AUDTERM_2_RIGHT EQU %00000010 +DEF AUDTERM_1_RIGHT EQU %00000001 + + +; -- +; -- AUDENA/NR52 ($FF26) +; -- Sound on/off (R/W) +; -- +; -- Bit 7 - All sound on/off (sets all audio regs to 0!) +; -- Bit 3 - Sound 4 ON flag (read only) +; -- Bit 2 - Sound 3 ON flag (read only) +; -- Bit 1 - Sound 2 ON flag (read only) +; -- Bit 0 - Sound 1 ON flag (read only) +; -- +DEF rNR52 EQU $FF26 +DEF rAUDENA EQU rNR52 + +DEF AUDENA_ON EQU %10000000 +DEF AUDENA_OFF EQU %00000000 ; sets all audio regs to 0! + + +; -- +; -- LCDC ($FF40) +; -- LCD Control (R/W) +; -- +DEF rLCDC EQU $FF40 + +DEF LCDCF_OFF EQU %00000000 ; LCD Control Operation +DEF LCDCF_ON EQU %10000000 ; LCD Control Operation +DEF LCDCF_WIN9800 EQU %00000000 ; Window Tile Map Display Select +DEF LCDCF_WIN9C00 EQU %01000000 ; Window Tile Map Display Select +DEF LCDCF_WINOFF EQU %00000000 ; Window Display +DEF LCDCF_WINON EQU %00100000 ; Window Display +DEF LCDCF_BG8800 EQU %00000000 ; BG & Window Tile Data Select +DEF LCDCF_BG8000 EQU %00010000 ; BG & Window Tile Data Select +DEF LCDCF_BG9800 EQU %00000000 ; BG Tile Map Display Select +DEF LCDCF_BG9C00 EQU %00001000 ; BG Tile Map Display Select +DEF LCDCF_OBJ8 EQU %00000000 ; OBJ Construction +DEF LCDCF_OBJ16 EQU %00000100 ; OBJ Construction +DEF LCDCF_OBJOFF EQU %00000000 ; OBJ Display +DEF LCDCF_OBJON EQU %00000010 ; OBJ Display +DEF LCDCF_BGOFF EQU %00000000 ; BG Display +DEF LCDCF_BGON EQU %00000001 ; BG Display + +DEF LCDCB_ON EQU 7 ; LCD Control Operation +DEF LCDCB_WIN9C00 EQU 6 ; Window Tile Map Display Select +DEF LCDCB_WINON EQU 5 ; Window Display +DEF LCDCB_BG8000 EQU 4 ; BG & Window Tile Data Select +DEF LCDCB_BG9C00 EQU 3 ; BG Tile Map Display Select +DEF LCDCB_OBJ16 EQU 2 ; OBJ Construction +DEF LCDCB_OBJON EQU 1 ; OBJ Display +DEF LCDCB_BGON EQU 0 ; BG Display +; "Window Character Data Select" follows BG + + +; -- +; -- STAT ($FF41) +; -- LCDC Status (R/W) +; -- +DEF rSTAT EQU $FF41 + +DEF STATF_LYC EQU %01000000 ; LYC=LY Coincidence (Selectable) +DEF STATF_MODE10 EQU %00100000 ; Mode 10 +DEF STATF_MODE01 EQU %00010000 ; Mode 01 (V-Blank) +DEF STATF_MODE00 EQU %00001000 ; Mode 00 (H-Blank) +DEF STATF_LYCF EQU %00000100 ; Coincidence Flag +DEF STATF_HBL EQU %00000000 ; H-Blank +DEF STATF_VBL EQU %00000001 ; V-Blank +DEF STATF_OAM EQU %00000010 ; OAM-RAM is used by system +DEF STATF_LCD EQU %00000011 ; Both OAM and VRAM used by system +DEF STATF_BUSY EQU %00000010 ; When set, VRAM access is unsafe + +DEF STATB_LYC EQU 6 +DEF STATB_MODE10 EQU 5 +DEF STATB_MODE01 EQU 4 +DEF STATB_MODE00 EQU 3 +DEF STATB_LYCF EQU 2 +DEF STATB_BUSY EQU 1 + +; -- +; -- SCY ($FF42) +; -- Scroll Y (R/W) +; -- +DEF rSCY EQU $FF42 + + +; -- +; -- SCX ($FF43) +; -- Scroll X (R/W) +; -- +DEF rSCX EQU $FF43 + + +; -- +; -- LY ($FF44) +; -- LCDC Y-Coordinate (R) +; -- +; -- Values range from 0->153. 144->153 is the VBlank period. +; -- +DEF rLY EQU $FF44 + + +; -- +; -- LYC ($FF45) +; -- LY Compare (R/W) +; -- +; -- When LY==LYC, STATF_LYCF will be set in STAT +; -- +DEF rLYC EQU $FF45 + + +; -- +; -- DMA ($FF46) +; -- DMA Transfer and Start Address (W) +; -- +DEF rDMA EQU $FF46 + + +; -- +; -- BGP ($FF47) +; -- BG Palette Data (W) +; -- +; -- Bit 7-6 - Intensity for %11 +; -- Bit 5-4 - Intensity for %10 +; -- Bit 3-2 - Intensity for %01 +; -- Bit 1-0 - Intensity for %00 +; -- +DEF rBGP EQU $FF47 + + +; -- +; -- OBP0 ($FF48) +; -- Object Palette 0 Data (W) +; -- +; -- See BGP for info +; -- +DEF rOBP0 EQU $FF48 + + +; -- +; -- OBP1 ($FF49) +; -- Object Palette 1 Data (W) +; -- +; -- See BGP for info +; -- +DEF rOBP1 EQU $FF49 + + +; -- +; -- WY ($FF4A) +; -- Window Y Position (R/W) +; -- +; -- 0 <= WY <= 143 +; -- When WY = 0, the window is displayed from the top edge of the LCD screen. +; -- +DEF rWY EQU $FF4A + + +; -- +; -- WX ($FF4B) +; -- Window X Position (R/W) +; -- +; -- 7 <= WX <= 166 +; -- When WX = 7, the window is displayed from the left edge of the LCD screen. +; -- Values of 0-6 and 166 are unreliable due to hardware bugs. +; -- +DEF rWX EQU $FF4B + +DEF WX_OFS EQU 7 ; add this to a screen position to get a WX position + + +; -- +; -- SPEED ($FF4D) +; -- Select CPU Speed (R/W) +; -- +DEF rKEY1 EQU $FF4D +DEF rSPD EQU rKEY1 + +DEF KEY1F_DBLSPEED EQU %10000000 ; 0=Normal Speed, 1=Double Speed (R) +DEF KEY1F_PREPARE EQU %00000001 ; 0=No, 1=Prepare (R/W) + + +; -- +; -- VBK ($FF4F) +; -- Select Video RAM Bank (R/W) +; -- +; -- Bit 0 - Bank Specification (0: Specify Bank 0; 1: Specify Bank 1) +; -- +DEF rVBK EQU $FF4F + + +; -- +; -- HDMA1 ($FF51) +; -- High byte for Horizontal Blanking/General Purpose DMA source address (W) +; -- CGB Mode Only +; -- +DEF rHDMA1 EQU $FF51 + + +; -- +; -- HDMA2 ($FF52) +; -- Low byte for Horizontal Blanking/General Purpose DMA source address (W) +; -- CGB Mode Only +; -- +DEF rHDMA2 EQU $FF52 + + +; -- +; -- HDMA3 ($FF53) +; -- High byte for Horizontal Blanking/General Purpose DMA destination address (W) +; -- CGB Mode Only +; -- +DEF rHDMA3 EQU $FF53 + + +; -- +; -- HDMA4 ($FF54) +; -- Low byte for Horizontal Blanking/General Purpose DMA destination address (W) +; -- CGB Mode Only +; -- +DEF rHDMA4 EQU $FF54 + + +; -- +; -- HDMA5 ($FF55) +; -- Transfer length (in tiles minus 1)/mode/start for Horizontal Blanking, General Purpose DMA (R/W) +; -- CGB Mode Only +; -- +DEF rHDMA5 EQU $FF55 + +DEF HDMA5F_MODE_GP EQU %00000000 ; General Purpose DMA (W) +DEF HDMA5F_MODE_HBL EQU %10000000 ; HBlank DMA (W) +DEF HDMA5B_MODE EQU 7 ; DMA mode select (W) + +; -- Once DMA has started, use HDMA5F_BUSY to check when the transfer is complete +DEF HDMA5F_BUSY EQU %10000000 ; 0=Busy (DMA still in progress), 1=Transfer complete (R) + + +; -- +; -- RP ($FF56) +; -- Infrared Communications Port (R/W) +; -- CGB Mode Only +; -- +DEF rRP EQU $FF56 + +DEF RPF_ENREAD EQU %11000000 +DEF RPF_DATAIN EQU %00000010 ; 0=Receiving IR Signal, 1=Normal +DEF RPF_WRITE_HI EQU %00000001 +DEF RPF_WRITE_LO EQU %00000000 + + +; -- +; -- BCPS ($FF68) +; -- Background Color Palette Specification (R/W) +; -- +DEF rBCPS EQU $FF68 + +DEF BCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) +DEF BCPSB_AUTOINC EQU 7 + + +; -- +; -- BCPD ($FF69) +; -- Background Color Palette Data (R/W) +; -- +DEF rBCPD EQU $FF69 + + +; -- +; -- OCPS ($FF6A) +; -- Object Color Palette Specification (R/W) +; -- +DEF rOCPS EQU $FF6A + +DEF OCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) +DEF OCPSB_AUTOINC EQU 7 + + +; -- +; -- OCPD ($FF6B) +; -- Object Color Palette Data (R/W) +; -- +DEF rOCPD EQU $FF6B + + +; -- +; -- SMBK/SVBK ($FF70) +; -- Select Main RAM Bank (R/W) +; -- +; -- Bit 2-0 - Bank Specification (0,1: Specify Bank 1; 2-7: Specify Banks 2-7) +; -- +DEF rSVBK EQU $FF70 +DEF rSMBK EQU rSVBK + + +; -- +; -- PCM12 ($FF76) +; -- Sound channel 1&2 PCM amplitude (R) +; -- +; -- Bit 7-4 - Copy of sound channel 2's PCM amplitude +; -- Bit 3-0 - Copy of sound channel 1's PCM amplitude +; -- +DEF rPCM12 EQU $FF76 + + +; -- +; -- PCM34 ($FF77) +; -- Sound channel 3&4 PCM amplitude (R) +; -- +; -- Bit 7-4 - Copy of sound channel 4's PCM amplitude +; -- Bit 3-0 - Copy of sound channel 3's PCM amplitude +; -- +DEF rPCM34 EQU $FF77 + + +; SameBoy additions +DEF rKEY0 EQU $FF4C +DEF rBANK EQU $FF50 +DEF rOPRI EQU $FF6C + +DEF rJOYP EQU rP1 +DEF rBGPI EQU rBCPS +DEF rBGPD EQU rBCPD +DEF rOBPI EQU rOCPS +DEF rOBPD EQU rOCPD + +; -- +; -- IE ($FFFF) +; -- Interrupt Enable (R/W) +; -- +DEF rIE EQU $FFFF + +DEF IEF_HILO EQU %00010000 ; Transition from High to Low of Pin number P10-P13 +DEF IEF_SERIAL EQU %00001000 ; Serial I/O transfer end +DEF IEF_TIMER EQU %00000100 ; Timer Overflow +DEF IEF_STAT EQU %00000010 ; STAT +DEF IEF_VBLANK EQU %00000001 ; V-Blank + +DEF IEB_HILO EQU 4 +DEF IEB_SERIAL EQU 3 +DEF IEB_TIMER EQU 2 +DEF IEB_STAT EQU 1 +DEF IEB_VBLANK EQU 0 + + +;*************************************************************************** +;* +;* Flags common to multiple sound channels +;* +;*************************************************************************** + +; -- +; -- Square wave duty cycle +; -- +; -- Can be used with AUD1LEN and AUD2LEN +; -- See AUD1LEN for more info +; -- +DEF AUDLEN_DUTY_12_5 EQU %00000000 ; 12.5% +DEF AUDLEN_DUTY_25 EQU %01000000 ; 25% +DEF AUDLEN_DUTY_50 EQU %10000000 ; 50% +DEF AUDLEN_DUTY_75 EQU %11000000 ; 75% + + +; -- +; -- Audio envelope flags +; -- +; -- Can be used with AUD1ENV, AUD2ENV, AUD4ENV +; -- See AUD1ENV for more info +; -- +DEF AUDENV_UP EQU %00001000 +DEF AUDENV_DOWN EQU %00000000 + + +; -- +; -- Audio trigger flags +; -- +; -- Can be used with AUD1HIGH, AUD2HIGH, AUD3HIGH +; -- See AUD1HIGH for more info +; -- + +DEF AUDHIGH_RESTART EQU %10000000 +DEF AUDHIGH_LENGTH_ON EQU %01000000 +DEF AUDHIGH_LENGTH_OFF EQU %00000000 + + +;*************************************************************************** +;* +;* CPU values on bootup (a=type, b=qualifier) +;* +;*************************************************************************** + +DEF BOOTUP_A_DMG EQU $01 ; Dot Matrix Game +DEF BOOTUP_A_CGB EQU $11 ; Color GameBoy +DEF BOOTUP_A_MGB EQU $FF ; Mini GameBoy (Pocket GameBoy) + +; if a=BOOTUP_A_CGB, bit 0 in b can be checked to determine if real CGB or +; other system running in GBC mode +DEF BOOTUP_B_CGB EQU %00000000 +DEF BOOTUP_B_AGB EQU %00000001 ; GBA, GBA SP, Game Boy Player, or New GBA SP + + +;*************************************************************************** +;* +;* Cart related +;* +;*************************************************************************** + +; $0143 Color GameBoy compatibility code +DEF CART_COMPATIBLE_DMG EQU $00 +DEF CART_COMPATIBLE_DMG_GBC EQU $80 +DEF CART_COMPATIBLE_GBC EQU $C0 + +; $0146 GameBoy/Super GameBoy indicator +DEF CART_INDICATOR_GB EQU $00 +DEF CART_INDICATOR_SGB EQU $03 + +; $0147 Cartridge type +DEF CART_ROM EQU $00 +DEF CART_ROM_MBC1 EQU $01 +DEF CART_ROM_MBC1_RAM EQU $02 +DEF CART_ROM_MBC1_RAM_BAT EQU $03 +DEF CART_ROM_MBC2 EQU $05 +DEF CART_ROM_MBC2_BAT EQU $06 +DEF CART_ROM_RAM EQU $08 +DEF CART_ROM_RAM_BAT EQU $09 +DEF CART_ROM_MMM01 EQU $0B +DEF CART_ROM_MMM01_RAM EQU $0C +DEF CART_ROM_MMM01_RAM_BAT EQU $0D +DEF CART_ROM_MBC3_BAT_RTC EQU $0F +DEF CART_ROM_MBC3_RAM_BAT_RTC EQU $10 +DEF CART_ROM_MBC3 EQU $11 +DEF CART_ROM_MBC3_RAM EQU $12 +DEF CART_ROM_MBC3_RAM_BAT EQU $13 +DEF CART_ROM_MBC5 EQU $19 +DEF CART_ROM_MBC5_BAT EQU $1A +DEF CART_ROM_MBC5_RAM_BAT EQU $1B +DEF CART_ROM_MBC5_RUMBLE EQU $1C +DEF CART_ROM_MBC5_RAM_RUMBLE EQU $1D +DEF CART_ROM_MBC5_RAM_BAT_RUMBLE EQU $1E +DEF CART_ROM_MBC7_RAM_BAT_GYRO EQU $22 +DEF CART_ROM_POCKET_CAMERA EQU $FC +DEF CART_ROM_BANDAI_TAMA5 EQU $FD +DEF CART_ROM_HUDSON_HUC3 EQU $FE +DEF CART_ROM_HUDSON_HUC1 EQU $FF + +; $0148 ROM size +; these are kilobytes +DEF CART_ROM_32KB EQU $00 ; 2 banks +DEF CART_ROM_64KB EQU $01 ; 4 banks +DEF CART_ROM_128KB EQU $02 ; 8 banks +DEF CART_ROM_256KB EQU $03 ; 16 banks +DEF CART_ROM_512KB EQU $04 ; 32 banks +DEF CART_ROM_1024KB EQU $05 ; 64 banks +DEF CART_ROM_2048KB EQU $06 ; 128 banks +DEF CART_ROM_4096KB EQU $07 ; 256 banks +DEF CART_ROM_8192KB EQU $08 ; 512 banks +DEF CART_ROM_1152KB EQU $52 ; 72 banks +DEF CART_ROM_1280KB EQU $53 ; 80 banks +DEF CART_ROM_1536KB EQU $54 ; 96 banks + +; $0149 SRAM size +; these are kilobytes +DEF CART_SRAM_NONE EQU 0 +DEF CART_SRAM_8KB EQU 2 ; 1 bank +DEF CART_SRAM_32KB EQU 3 ; 4 banks +DEF CART_SRAM_128KB EQU 4 ; 16 banks + +DEF CART_SRAM_ENABLE EQU $0A +DEF CART_SRAM_DISABLE EQU $00 + +; $014A Destination code +DEF CART_DEST_JAPANESE EQU $00 +DEF CART_DEST_NON_JAPANESE EQU $01 + + +;*************************************************************************** +;* +;* Keypad related +;* +;*************************************************************************** + +DEF PADF_DOWN EQU $80 +DEF PADF_UP EQU $40 +DEF PADF_LEFT EQU $20 +DEF PADF_RIGHT EQU $10 +DEF PADF_START EQU $08 +DEF PADF_SELECT EQU $04 +DEF PADF_B EQU $02 +DEF PADF_A EQU $01 + +DEF PADB_DOWN EQU $7 +DEF PADB_UP EQU $6 +DEF PADB_LEFT EQU $5 +DEF PADB_RIGHT EQU $4 +DEF PADB_START EQU $3 +DEF PADB_SELECT EQU $2 +DEF PADB_B EQU $1 +DEF PADB_A EQU $0 + + +;*************************************************************************** +;* +;* Screen related +;* +;*************************************************************************** + +DEF SCRN_X EQU 160 ; Width of screen in pixels +DEF SCRN_Y EQU 144 ; Height of screen in pixels +DEF SCRN_X_B EQU 20 ; Width of screen in bytes +DEF SCRN_Y_B EQU 18 ; Height of screen in bytes + +DEF SCRN_VX EQU 256 ; Virtual width of screen in pixels +DEF SCRN_VY EQU 256 ; Virtual height of screen in pixels +DEF SCRN_VX_B EQU 32 ; Virtual width of screen in bytes +DEF SCRN_VY_B EQU 32 ; Virtual height of screen in bytes + + +;*************************************************************************** +;* +;* OAM related +;* +;*************************************************************************** + +; OAM attributes +; each entry in OAM RAM is 4 bytes (sizeof_OAM_ATTRS) +RSRESET +DEF OAMA_Y RB 1 ; y pos plus 16 +DEF OAMA_X RB 1 ; x pos plus 8 +DEF OAMA_TILEID RB 1 ; tile id +DEF OAMA_FLAGS RB 1 ; flags (see below) +DEF sizeof_OAM_ATTRS RB 0 + +DEF OAM_Y_OFS EQU 16 ; add this to a screen-relative Y position to get an OAM Y position +DEF OAM_X_OFS EQU 8 ; add this to a screen-relative X position to get an OAM X position + +DEF OAM_COUNT EQU 40 ; number of OAM entries in OAM RAM + +; flags +DEF OAMF_PRI EQU %10000000 ; Priority +DEF OAMF_YFLIP EQU %01000000 ; Y flip +DEF OAMF_XFLIP EQU %00100000 ; X flip +DEF OAMF_PAL0 EQU %00000000 ; Palette number; 0,1 (DMG) +DEF OAMF_PAL1 EQU %00010000 ; Palette number; 0,1 (DMG) +DEF OAMF_BANK0 EQU %00000000 ; Bank number; 0,1 (GBC) +DEF OAMF_BANK1 EQU %00001000 ; Bank number; 0,1 (GBC) + +DEF OAMF_PALMASK EQU %00000111 ; Palette (GBC) + +DEF OAMB_PRI EQU 7 ; Priority +DEF OAMB_YFLIP EQU 6 ; Y flip +DEF OAMB_XFLIP EQU 5 ; X flip +DEF OAMB_PAL1 EQU 4 ; Palette number; 0,1 (DMG) +DEF OAMB_BANK1 EQU 3 ; Bank number; 0,1 (GBC) + + +;* +;* Nintendo scrolling logo +;* (Code won't work on a real GameBoy) +;* (if next lines are altered.) +MACRO NINTENDO_LOGO + DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D + DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 + DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E +ENDM + +; Deprecated constants. Please avoid using. + +DEF IEF_LCDC EQU %00000010 ; LCDC (see STAT) +DEF _VRAM8000 EQU _VRAM +DEF _VRAM8800 EQU _VRAM+$800 +DEF _VRAM9000 EQU _VRAM+$1000 +DEF CART_SRAM_2KB EQU 1 ; 1 incomplete bank + + + ENDC ;HARDWARE_INC diff --git a/BootROMs/logo-compress.c b/BootROMs/src/logo-compress.c similarity index 97% rename from BootROMs/logo-compress.c rename to BootROMs/src/logo-compress.c index 2274eb2..7e27775 100644 --- a/BootROMs/logo-compress.c +++ b/BootROMs/src/logo-compress.c @@ -1,9 +1,9 @@ #include #include -#include -#ifdef _WIN32 -#include -#include +#include +#ifdef _WIN32 +#include +#include #endif void pair(size_t count, uint8_t byte) @@ -39,11 +39,10 @@ int main(int argc, char *argv[]) size_t count = 1; uint8_t byte = getchar(); int new; - size_t position = 0; - -#ifdef _WIN32 - _setmode(0,_O_BINARY); - _setmode(1,_O_BINARY); + +#ifdef _WIN32 + _setmode(0,_O_BINARY); + _setmode(1,_O_BINARY); #endif while ((new = getchar()) != EOF) { diff --git a/BootROMs/src/mgb_boot.asm b/BootROMs/src/mgb_boot.asm new file mode 100644 index 0000000..3a98aef --- /dev/null +++ b/BootROMs/src/mgb_boot.asm @@ -0,0 +1,2 @@ +MGB EQU 1 +include "dmg_boot.asm" \ No newline at end of file diff --git a/BootROMs/sgb2_boot.asm b/BootROMs/src/sgb2_boot.asm similarity index 100% rename from BootROMs/sgb2_boot.asm rename to BootROMs/src/sgb2_boot.asm diff --git a/BootROMs/sgb_boot.asm b/BootROMs/src/sgb_boot.asm similarity index 69% rename from BootROMs/sgb_boot.asm rename to BootROMs/src/sgb_boot.asm index cdb9d77..8e0206f 100644 --- a/BootROMs/sgb_boot.asm +++ b/BootROMs/src/sgb_boot.asm @@ -1,5 +1,27 @@ -; SameBoy SGB bootstrap ROM -; Todo: use friendly names for HW registers instead of magic numbers +;MIT License +; +;Copyright (c) 2015-2023 Lior Halphon +; +;Permission is hereby granted, free of charge, to any person obtaining a copy +;of this software and associated documentation files (the "Software"), to deal +;in the Software without restriction, including without limitation the rights +;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;copies of the Software, and to permit persons to whom the Software is +;furnished to do so, subject to the following conditions: +; +;The above copyright notice and this permission notice shall be included in all +;copies or substantial portions of the Software. +; +;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;SOFTWARE. + +INCLUDE "hardware.inc" + SECTION "BootCode", ROM0[$0] Start: ; Init stack pointer @@ -15,17 +37,17 @@ Start: ; Init Audio ld a, $80 - ldh [$26], a - ldh [$11], a + ldh [rNR52], a + ldh [rNR11], a ld a, $f3 - ldh [$12], a - ldh [$25], a + ldh [rNR12], a + ldh [rNR51], a ld a, $77 - ldh [$24], a + ldh [rNR50], a ; Init BG palette to white ld a, $0 - ldh [$47], a + ldh [rBGP], a ; Load logo from ROM. ; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8. @@ -71,10 +93,10 @@ Start: ; Turn on LCD ld a, $91 - ldh [$40], a + ldh [rLCDC], a ld a, $f1 ; Packet magic, increases by 2 for every packet - ldh [$80], a + ldh [_HRAM], a ld hl, $104 ; Header start xor a @@ -86,7 +108,7 @@ Start: ld a, $30 ld [c], a - ldh a, [$80] + ldh a, [_HRAM] call SendByte push hl ld b, $e @@ -117,9 +139,9 @@ Start: ld [c], a ; Update command - ldh a, [$80] + ldh a, [_HRAM] add 2 - ldh [$80], a + ldh [_HRAM], a ld a, $58 cp l @@ -135,7 +157,7 @@ Start: ; Init BG palette ld a, $fc - ldh [$47], a + ldh [rBGP], a ; Set registers to match the original SGB boot IF DEF(SGB2) @@ -210,4 +232,4 @@ db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c SECTION "BootGame", ROM0[$fe] BootGame: - ldh [$50], a \ No newline at end of file + ldh [rBANK], a \ No newline at end of file diff --git a/Gameboy.sv b/Gameboy.sv index 342f9bd..c8675df 100644 --- a/Gameboy.sv +++ b/Gameboy.sv @@ -20,6 +20,10 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. //============================================================================ +// Bootrom checksums +`define MISTER_CGB0_CHECKSUM 18'h2CE10 +`define ORIGINAL_CGB_CHECKSUM 18'h2F3EA + module emu ( //Master input clock @@ -196,7 +200,7 @@ assign AUDIO_MIX = status[8:7]; // 0 1 2 3 4 5 6 // 01234567890123456789012345678901 23456789012345678901234567890123 // 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV -// XXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXX +// XXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXX `include "build_id.v" localparam CONF_STR = { @@ -225,7 +229,6 @@ localparam CONF_STR = { "P1-;", "P1OC,Inverted color,No,Yes;", "P1o4,Screen Shadow,No,Yes;", - "h6P1o5,Use GBA Mode,No,Yes;", "P1O12,Custom Palette,Off,Auto,On;", "h1P1FC3,GBP,Load Palette;", "P1-;", @@ -239,20 +242,26 @@ localparam CONF_STR = { "P1-;", "P1O78,Stereo mix,none,25%,50%,100%;", - "P2,Misc.;", + "P2,Bootroms;", "P2-;", "P2FC4,BIN,Load GBC Boot;", "P2FC5,BIN,Load DMG Boot;", "P2FC6,BIN,Load SGB Boot;", "P2-;", - "P2O6,Link Port,Disabled,Enabled;", - "P2o6,Rumble,On,Off;", - "P2-;", - "P2OP,FastForward Sound,On,Off;", - "P2OQ,Pause when OSD is open,Off,On;", - "P2OR,Rewind Capture,Off,On;", - "P2-;", - "P2o3,Super Game Boy + GBC,Off,On;", + "d6P2O[37],CGB/GBA mode,CGB,GBA;", + "d8P2O[42],Fast boot,Off,On;", + + "P3,Misc.;", + "P3-;", + "P3O6,Link Port,Disabled,Enabled;", + "P3o6,Rumble,On,Off;", + "P3-;", + "P3OP,FastForward Sound,On,Off;", + "P3OQ,Pause when OSD is open,Off,On;", + "P3OR,Rewind Capture,Off,On;", + "P3-;", + "P3o3,Super Game Boy + GBC,Off,On;", + "-;", "R0,Reset;", @@ -357,7 +366,10 @@ hps_io #(.CONF_STR(CONF_STR), .WIDE(1)) hps_io .buttons(buttons), .status(status), - .status_menumask({sys_megaduck,using_real_cgb_bios,sgb_border_en,isGBC,cart_ready,sav_supported,|tint,gg_available}), + .status_menumask({7'h0, + fastboot_available, + sys_megaduck, boot_gba_available, sgb_border_en, isGBC, + cart_ready, sav_supported, |tint, gg_available}), .status_in({status[63:34],ss_slot,status[31:0]}), .status_set(statusUpdate), .direct_video(direct_video), @@ -402,6 +414,39 @@ wire dmg_boot_download = ioctl_download && (filetype == 5); wire sgb_boot_download = ioctl_download && (filetype == 6); wire boot_download = cgb_boot_download | dmg_boot_download | sgb_boot_download; +///////////////////////////// Bootrom added features /////////////////////////// + +// Fastboot is available for MiSTer-built bootroms (except SGB) +wire fastboot_available = !((isGBC && using_custom_cgb_bootrom && checksum_cgb != `MISTER_CGB0_CHECKSUM) || (!isGBC && using_custom_dmg_bootrom)); +// GBA mode is available for MiSTer-built CGB bootroms and the original CGB bootrom. +// We verify that a loaded bootrom enables GBA mode by calculating a simple checksum. +wire boot_gba_available = (!using_custom_cgb_bootrom || using_real_cgb_bios || checksum_cgb == `MISTER_CGB0_CHECKSUM); +wire using_real_cgb_bios = (checksum_cgb == `ORIGINAL_CGB_CHECKSUM); + +reg using_custom_dmg_bootrom = 0; +reg using_custom_cgb_bootrom = 0; +always @(posedge clk_sys) begin + if (cgb_boot_download) + using_custom_cgb_bootrom <= 1; + if (dmg_boot_download) + using_custom_dmg_bootrom <= 1; +end + +reg boot_download_r; +always @(posedge clk_sys) + boot_download_r <= boot_download; + +// Calculate checksum for incoming cgb bootrom downloads +reg [17:0] checksum_cgb; +always @(posedge clk_sys) begin + // Reset checksum on new boot download + if (cgb_boot_download && !boot_download_r) + checksum_cgb <= 0; + else if (cgb_boot_download && ioctl_wr) + checksum_cgb <= checksum_cgb + ioctl_dout[15:8] + ioctl_dout[7:0]; +end + +//////////////////////////////////////////////////////////////////////////////// wire [1:0] sdram_ds = cart_download ? 2'b11 : {mbc_addr[0], ~mbc_addr[0]}; wire [15:0] sdram_do; @@ -541,11 +586,8 @@ cart_top cart ( ); reg [127:0] palette = 128'h828214517356305A5F1A3B4900000000; -reg using_real_cgb_bios = 0; always @(posedge clk_sys) begin - if (cgb_boot_download) - using_real_cgb_bios <= 1; if (palette_download & ioctl_wr) begin palette[127:0] <= {palette[111:0], ioctl_dout[7:0], ioctl_dout[15:8]}; end @@ -592,6 +634,7 @@ gb gb ( .ce_2x ( ce_cpu2x ), // ~8MHz in dualspeed mode (GBC) .isGBC ( isGBC ), + .real_cgb_boot ( using_real_cgb_bios ), .isSGB ( |sgb_en & ~isGBC ), .megaduck ( megaduck ), @@ -609,7 +652,8 @@ gb gb ( .nCS ( nCS ), - .boot_gba_en ( status[37] && using_real_cgb_bios ), + .boot_gba_en ( boot_gba_available && status[37] ), + .fast_boot_en ( fastboot_available && status[42] ), .cgb_boot_download ( cgb_boot_download ), .dmg_boot_download ( dmg_boot_download ), diff --git a/ReadMe.md b/ReadMe.md index 9f5a5d4..5da727c 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -18,9 +18,15 @@ This is port of [Gameboy for MiST](https://github.com/mist-devel/gameboy) * Real-Time Clock Support * Gameboy Link Port Support - Requires USERIO adapter * Cheats +* Fast boot +* GBA mode for GBC games ## Open Source Bootstrap roms -This now includes the open source boot ROMs from [https://github.com/LIJI32/SameBoy/](https://github.com/LIJI32/SameBoy/). For maximum compatibility/authenticity you can still place the Gameboy bios/bootroms into the Gameboy folder and load them in the menu with Misc->Load GBC/DMG/SGB boot. Loading an authentic Gameboy Color bios/bootroom is required in order to use GBA Mode. +Open source roms are included in the core, adapted from the SameBoy project [https://github.com/LIJI32/SameBoy/](https://github.com/LIJI32/SameBoy/). These roms have MiSTer-specific enhancements, allowing fast booting and GBA mode to be controlled by the on-screen display. + + For maximum compatibility/authenticity you can still place the Gameboy bios/bootroms into the Gameboy folder and load them in the menu with `Bootroms->Load GBC/DMG/SGB boot`. + +For more information see the [BootROM README](./BootROMs/README.md) ## Palettes This core supports custom palettes (*.gbp) which should be placed into the Gameboy folder. Some examples are available in the palettes folder. diff --git a/rtl/gb.v b/rtl/gb.v index 36903a3..94b373e 100644 --- a/rtl/gb.v +++ b/rtl/gb.v @@ -28,6 +28,7 @@ module gb ( input [7:0] joystick, input isGBC, + input real_cgb_boot, input isSGB, // cartridge interface @@ -50,7 +51,9 @@ module gb ( input [24:0] ioctl_addr, input [15:0] ioctl_dout, + // Bootrom features input boot_gba_en, + input fast_boot_en, // audio output [15:0] audio_l, @@ -174,6 +177,9 @@ wire sel_FF73 = isGBC && cpu_addr == 16'hff73; // unused register, a wire sel_FF74 = isGBC && isGBC_mode && (cpu_addr == 16'hff74); // unused register, all bits read/write, only in CGB mode wire sel_FF75 = isGBC && cpu_addr == 16'hff75; // unused register, bits 4-6 read/write +// Special MiSTer register for signalling to cpu bootrom +wire sel_FF50 = boot_rom_enabled && cpu_addr == 16'hff50; + wire ext_bus_wram_sel, ext_bus_cram_sel, ext_bus_rom_sel; wire ext_bus_rd, ext_bus_wr; wire [7:0] ext_bus_di; @@ -279,6 +285,7 @@ wire [7:0] cpu_di = sel_FF73?FF73: // unused register, all bits read/write sel_FF74?FF74: // unused register, all bits read/write, only in CGB mode sel_FF75?{1'b1,FF75, 4'b1111}: // unused register, bits 4-6 read/write + sel_FF50?{6'b0, fast_boot_en, boot_gba_en}: // MiSTer special instruction register 8'hff; wire cpu_wr_n; @@ -929,6 +936,7 @@ wire [10:0] boot_wr_addr = ioctl_addr[11:1]; wire [7:0] boot_q; + dpram_dif #(12,8,11,16,"BootROMs/cgb_boot.mif") boot_rom ( .clock (clk_sys), @@ -959,8 +967,7 @@ always begin endcase end -assign boot_do = (isGBC & boot_gba_en) ? boot_do_gba : boot_q; - +assign boot_do = (isGBC && boot_gba_en && real_cgb_boot) ? boot_do_gba : boot_q; // -------------------------------------------------------------------- // ------------------ External bus (WRAM, Cartridge) ------------------ // --------------------------------------------------------------------