From e387e70ef254f7d5f75f0f49ae7215ca9db74663 Mon Sep 17 00:00:00 2001 From: paulb-nl Date: Sun, 16 Jun 2024 15:59:08 +0200 Subject: [PATCH] Updates from main branch RTC fixes Implement KEY0 and OPRI registers HDMA fixes Megaduck audio fixes Bootrom updates (GBA/Fastboot) --- BootROMs/cgb_boot.mif | 414 +++++++++++++++++++++++++++-------------- Gameboy.sv | 74 ++++++-- rtl/cart.v | 2 + rtl/gb.v | 98 ++++++---- rtl/hdma.v | 118 +++++------- rtl/mappers/huc3.v | 9 +- rtl/mappers/mappers.v | 7 +- rtl/mappers/mbc3.v | 15 +- rtl/mappers/tama.v | 98 +++++----- rtl/megaswizzle.sv | 76 +++++--- rtl/reg_savestates.vhd | 4 +- rtl/savestate_ui.sv | 4 +- rtl/video.v | 64 +++++-- 13 files changed, 614 insertions(+), 369 deletions(-) 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/Gameboy.sv b/Gameboy.sv index 4a6499f..0691e7a 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 @@ -204,7 +208,7 @@ assign DDRAM_WE = 0; // 0 1 2 3 4 5 6 // 01234567890123456789012345678901 23456789012345678901234567890123 // 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV -// XXXXXX XXXX XXXXXXXXXXXX X XXXXX +// XXXXXX XXXX XXXXXXXXXXXX X XXXXXX `include "build_id.v" localparam CONF_STR = { @@ -220,9 +224,8 @@ localparam CONF_STR = { "P1,Audio & Video;", "P1-;", - "P1ON,Seperator Line,Off,On;", + "P1ON,Seperator Line,Off,On;", "P1OC,Inverted color,No,Yes;", - "h6P1o5,Use GBA Mode,No,Yes;", "P1O12,Custom Palette,Off,Auto,On;", "h1P1FC3,GBP,Load Palette;", "P1-;", @@ -233,7 +236,7 @@ localparam CONF_STR = { "P1O5,Sync Video,Off,On;", "P1-;", "P1O78,Stereo mix,none,25%,50%,100%;", - "P1OGH,Audioselect,GB 1,GB 2,Mixed,Split 1=L 2=R;", + "P1OGH,Audioselect,GB 1,GB 2,Mixed,Split 1=L 2=R;", "P2,Misc.;", "P2-;", @@ -241,6 +244,8 @@ localparam CONF_STR = { "P2FC5,BIN,Load DMG Boot;", "P2FC6,BIN,Load SGB Boot;", "P2-;", + "d6P2O[37],GBC/GBA mode,GBC,GBA;", + "d8P2O[42],Fast boot,Off,On;", "P2o6,Rumble,On,Off;", "-;", @@ -331,7 +336,10 @@ hps_io #(.CONF_STR(CONF_STR), .WIDE(1)) hps_io .buttons(buttons), .status(status), - .status_menumask({sys_megaduck,using_real_cgb_bios,1'b0,isGBC,(cart1_ready & cart2_ready),sav_supported,|tint,1'b0}), + .status_menumask({7'h0, + fastboot_available, + sys_megaduck, boot_gba_available,1'b0,isGBC, + (cart1_ready & cart2_ready),sav_supported,|tint,1'b0}), .status_in(status), .status_set(1'b0), .direct_video(direct_video), @@ -387,6 +395,40 @@ 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 : {mbc1_addr[0], ~mbc1_addr[0]}; wire [15:0] sdram_do; wire [15:0] sdram_di = cart_download ? ioctl_dout : 16'd0; @@ -451,11 +493,8 @@ wire rumbling1, rumbling2; wire [2:0] mapper_sel = status[41:39]; 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 @@ -486,6 +525,13 @@ wire SaveStateBus_rst1; assign joy0_rumble = {8'd0, ((rumbling1 & ~status[38]) ? 8'd128 : 8'd0)}; +reg ce_32k; // 32768Hz clock for RTC +reg [9:0] ce_32k_div; +always @(posedge clk_sys) begin + ce_32k_div <= ce_32k_div + 1'b1; + ce_32k <= !ce_32k_div; +end + cart_top cart1 ( .reset ( reset ), @@ -540,6 +586,7 @@ cart_top cart1 ( .joystick_analog_0 ( joystick_analog_0 ), + .ce_32k ( ce_32k ), .RTC_time ( RTC_time ), .RTC_timestampOut ( RTC_timestampOut ), .RTC_savedtimeOut ( RTC_savedtimeOut ), @@ -573,7 +620,7 @@ gb gb1 ( .ce_2x ( ce1_cpu2x ), // ~8MHz in dualspeed mode (GBC) .isGBC ( isGBC ), - .isGBC_game ( isGBC_game ), + .real_cgb_boot ( using_real_cgb_bios ), .isSGB ( 1'b0 ), .megaduck ( megaduck ), @@ -591,7 +638,8 @@ gb gb1 ( .nCS ( gb1_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 ), @@ -726,6 +774,7 @@ cart_top cart2 ( .joystick_analog_0 ( joystick_analog_1 ), + .ce_32k ( ce_32k ), .RTC_time ( RTC_time ), .RTC_timestampOut ( ), .RTC_savedtimeOut ( ), @@ -760,7 +809,7 @@ gb gb2 ( .isGBC ( isGBC ), - .isGBC_game ( isGBC_game ), + .real_cgb_boot ( using_real_cgb_bios ), .isSGB ( 1'b0 ), .megaduck ( megaduck ), @@ -778,7 +827,8 @@ gb gb2 ( .nCS ( gb2_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/rtl/cart.v b/rtl/cart.v index db52eb8..f209376 100644 --- a/rtl/cart.v +++ b/rtl/cart.v @@ -52,6 +52,7 @@ module cart_top ( input [15:0] joystick_analog_0, + input ce_32k, input [32:0] RTC_time, output [31:0] RTC_timestampOut, output [47:0] RTC_savedtimeOut, @@ -133,6 +134,7 @@ mappers mappers ( .joystick_analog_0 ( joystick_analog_0 ), + .ce_32k ( ce_32k ), .RTC_time ( RTC_time ), .RTC_timestampOut ( RTC_timestampOut ), .RTC_savedtimeOut ( RTC_savedtimeOut ), diff --git a/rtl/gb.v b/rtl/gb.v index 24fff2d..94b373e 100644 --- a/rtl/gb.v +++ b/rtl/gb.v @@ -28,7 +28,7 @@ module gb ( input [7:0] joystick, input isGBC, - input isGBC_game, + input real_cgb_boot, input isSGB, // cartridge interface @@ -51,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, @@ -131,9 +133,9 @@ wire [4:0] Savestate_RAMRWrEn; localparam SAVESTATE_MODULES = 8; wire [63:0] SaveStateBus_wired_or[0:SAVESTATE_MODULES-1]; -wire [54:0] SS_Top; -wire [54:0] SS_Top_BACK; -eReg_SavestateV #(0, 31, 54, 0, 64'h0000000000800001) iREG_SAVESTATE_Top (clk_sys, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[6], SS_Top_BACK, SS_Top); +wire [56:0] SS_Top; +wire [56:0] SS_Top_BACK; +eReg_SavestateV #(0, 31, 56, 0, 64'h0000000000800001) iREG_SAVESTATE_Top (clk_sys, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[6], SS_Top_BACK, SS_Top); wire [10:0] SS_Top2; wire [10:0] SS_Top2_BACK; @@ -142,11 +144,14 @@ eReg_SavestateV #(0, 38, 10, 0, 64'h0000000000000000) iREG_SAVESTATE_Top2 (clk_s // include cpu reg boot_rom_enabled; +reg [1:0] ff4c_key0; // GBC DMG mode register +wire isGBC_mode = !ff4c_key0 | boot_rom_enabled; + wire [15:0] cpu_addr; wire [7:0] cpu_do; wire sel_timer = (cpu_addr[15:4] == 12'hff0) && (cpu_addr[3:2] == 2'b01); -wire sel_video_reg = (cpu_addr[15:4] == 12'hff4) || (isGBC && (cpu_addr[15:2] == 14'h3fda)); //video and oam dma (+ ff68-ff6B when gbc) +wire sel_video_reg = (cpu_addr[15:4] == 12'hff4) || (isGBC && (cpu_addr[15:4] == 12'hff6) && (cpu_addr[3:0] >= 4'h8 && cpu_addr[3:0] <= 4'hC)); //video and oam dma (+ ff68-ff6C when gbc) wire sel_video_oam = cpu_addr[15:8] == 8'hfe; wire sel_joy = cpu_addr == 16'hff00; // joystick controller wire sel_sb = cpu_addr == 16'hff01; // serial SB - Serial transfer data @@ -169,9 +174,12 @@ wire sel_boot_rom, sel_boot_rom_cgb; // unused cgb registers wire sel_FF72 = isGBC && cpu_addr == 16'hff72; // unused register, all bits read/write wire sel_FF73 = isGBC && cpu_addr == 16'hff73; // unused register, all bits read/write -wire sel_FF74 = isGBC && isGBC_game && (cpu_addr == 16'hff74); // unused register, all bits read/write, only in CGB mode +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; @@ -198,11 +206,12 @@ wire dma_sel_ext_bus = isGBC ? dma_sel_ext_bus_cgb : dma_sel_ext_bus_dmg; //CGB wire sel_vram_bank = (cpu_addr==16'hff4f); -wire sel_wram_bank = isGBC && (isGBC_game || boot_rom_enabled) && (cpu_addr==16'hff70); -wire sel_hdma = isGBC && (isGBC_game || boot_rom_enabled) && (cpu_addr[15:4]==12'hff5) && +wire sel_wram_bank = isGBC && isGBC_mode && (cpu_addr==16'hff70); +wire sel_hdma = isGBC && isGBC_mode && (cpu_addr[15:4]==12'hff5) && ((cpu_addr[3:0]!=4'd0)&&(cpu_addr[3:0]< 4'd6)); //HDMA FF51-FF55 -wire sel_key1 = isGBC && isGBC_game && (cpu_addr == 16'hff4d); // KEY1 - CGB Mode Only - Prepare Speed Switch -wire sel_rp = isGBC && isGBC_game && (cpu_addr == 16'hff56); //FF56 - RP - CGB Mode Only - Infrared Communications Port +wire sel_key0 = isGBC && boot_rom_enabled && (cpu_addr == 16'hff4c); // KEY0 - CGB / DMG mode register +wire sel_key1 = isGBC && isGBC_mode && (cpu_addr == 16'hff4d); // KEY1 - CGB Mode Only - Prepare Speed Switch +wire sel_rp = isGBC && isGBC_mode && (cpu_addr == 16'hff56); //FF56 - RP - CGB Mode Only - Infrared Communications Port //HDMA can select from $0000 to $7ff0 or A000-DFF0 wire [15:0] hdma_source_addr; @@ -237,7 +246,7 @@ wire [7:0] joy_do; wire [7:0] sb_o; wire [7:0] timer_do; wire [7:0] video_do; -reg [7:0] audio_do; +wire [7:0] audio_do; wire [7:0] boot_do; wire [7:0] vram_do; wire [7:0] vram1_do; @@ -257,6 +266,7 @@ wire [7:0] cpu_di = sel_wram_bank?{5'h1f,wram_bank}: isGBC&&sel_vram_bank?{7'h7f,vram_bank}: sel_hdma?{hdma_do}: //hdma GBC + sel_key0 ? { 4'hF, ff4c_key0, 2'b10 } : sel_key1?{cpu_speed,6'h3f,prepare_switch}: //key1 cpu speed register(GBC) sel_joy?joy_do: // joystick register sel_sb?sb_o: // serial transfer data register @@ -275,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; @@ -288,7 +299,10 @@ wire clk = clk_sys & ce; wire ce_cpu = cpu_speed ? ce_2x:ce; wire clk_cpu = clk_sys & ce_cpu; -wire cpu_clken = !(isGBC && hdma_active) && ce_cpu; //when hdma is enabled stop CPU (GBC) +// when hdma is enabled stop CPU (GBC). Finish read/write before stopping CPU +wire hdma_cpu_stop = (isGBC & hdma_active & cpu_rd_n & cpu_wr_n); +wire cpu_clken = ~hdma_cpu_stop & ce_cpu; + reg reset_r = 1; wire reset_ss; @@ -303,7 +317,7 @@ assign SS_Top_BACK[54] = old_cpu_wr_n; always @(posedge clk_sys) begin if(reset_ss) old_cpu_wr_n <= SS_Top[54]; // 1'b0 - else if (cpu_clken) old_cpu_wr_n <= cpu_wr_n; + else if (ce_cpu) old_cpu_wr_n <= cpu_wr_n; end wire cpu_wr_n_edge = ~(old_cpu_wr_n & ~cpu_wr_n); @@ -313,11 +327,19 @@ wire genie_ovr; wire [7:0] genie_data; wire [15:0] cpu_addr_raw; +wire [7:0] snd_d_in; +wire [7:0] snd_d_out; megaduck_swizzle md_swizz ( .megaduck (megaduck), .a_in (cpu_addr_raw), - .a_out (cpu_addr) + .a_out (cpu_addr), + + .snd_in_di (cpu_do), + .snd_in_do (snd_d_in), + + .snd_out_di (snd_d_out), + .snd_out_do (audio_do) ); GBse cpu ( @@ -365,6 +387,27 @@ CODES codes ( .genie_data (genie_data) ); +// -------------------------------------------------------------------- +// --------------------- GBC/DMG mode KEY0 (GBC) ---------------------- +// -------------------------------------------------------------------- + +assign SS_Top_BACK[56:55] = ff4c_key0; + +// KEY0 FF4C CPU mode register +// Bits 2 and 3 CPU mode select +// 00: CGB mode (Mode used by carts supporting CGB) +// 01: DMG/MGB mode (Mode used by DMG/MGB-only carts) + //10: PGB1 mode (STOP the CPU, with the LCD operated by an external signal) +// 11: PGB2 mode (CPU still running, with the LCD operated by an external signal) +// R/W only when boot rom is enabled +// https://forums.nesdev.org/viewtopic.php?t=19888 +always @(posedge clk_sys) begin + if(reset_ss) begin + ff4c_key0 <= SS_Top[56:55]; // 2'd0; + end else if(sel_key0 & ce_cpu & ~cpu_wr_n_edge) begin + ff4c_key0 <= cpu_do[3:2]; + end +end // -------------------------------------------------------------------- // --------------------- Speed Toggle KEY1 (GBC)----------------------- @@ -395,25 +438,6 @@ end wire audio_rd = !cpu_rd_n && sel_audio; wire audio_wr = !cpu_wr_n_edge && sel_audio; -reg [7:0] snd_d_in; -wire [7:0] snd_d_out; - -// Megaduck has reversed nybbles for some registers -always @(*) begin - snd_d_in = cpu_do; - audio_do = snd_d_out; - if (megaduck) begin - if (cpu_addr[7:4] == 1 && (cpu_addr_raw[3:0] == 1 || cpu_addr_raw[3:0] == 7)) - snd_d_in = {cpu_do[3:0], cpu_do[7:4]}; - if (cpu_addr[7:4] == 2 && (cpu_addr_raw[3:0] == 1 || cpu_addr_raw[3:0] == 2)) - snd_d_in = {cpu_do[3:0], cpu_do[7:4]}; - - if (cpu_addr[7:4] == 1 && (cpu_addr_raw[3:0] == 1 || cpu_addr_raw[3:0] == 7)) - audio_do = {snd_d_out[3:0], snd_d_out[7:4]}; - if (cpu_addr[7:4] == 2 && (cpu_addr_raw[3:0] == 1 || cpu_addr_raw[3:0] == 2)) - audio_do = {snd_d_out[3:0], snd_d_out[7:4]}; - end -end gbc_snd audio ( .clk ( clk_sys ), @@ -659,9 +683,11 @@ video video ( .ce ( ce ), // 4Mhz .ce_cpu ( ce_cpu ), //can be 2x in cgb double speed mode .isGBC ( isGBC ), - .isGBC_game ( isGBC_game|boot_rom_enabled ), //enable GBC mode during bootstrap rom + .isGBC_mode ( isGBC_mode ), //enable GBC mode during bootstrap rom .megaduck ( megaduck ), + .boot_rom_en ( boot_rom_enabled ), + .irq ( video_irq ), .vblank_irq ( vblank_irq ), @@ -910,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), @@ -940,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) ------------------ // -------------------------------------------------------------------- diff --git a/rtl/hdma.v b/rtl/hdma.v index 63b3cb4..411c4b7 100644 --- a/rtl/hdma.v +++ b/rtl/hdma.v @@ -34,7 +34,7 @@ wire [44:0] SS_HDMA_BACK; eReg_SavestateV #(0, 7, 44, 0, 64'h0000000001FFFFF0) iREG_SAVESTATE_HDMA (clk, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_Dout, SS_HDMA_BACK, SS_HDMA); //"The preparation time (4 clocks) is the same in single and double speed mode" -localparam START_DELAY = 3'd4; +localparam START_DELAY = 3'd4, END_DELAY = 3'd4; // ff51-ff55 HDMA1-5 (GBC) @@ -61,6 +61,8 @@ reg [2:0] dma_delay; reg [1:0] hdma_state; parameter active=2'd0,blocksent=2'd1,wait_h=2'd2; +wire mode_gdma = (hdma_mode == 1'b0); +wire mode_hdma = (hdma_mode == 1'b1); assign SS_HDMA_BACK[ 0] = hdma_active ; assign SS_HDMA_BACK[ 2: 1] = hdma_state ; @@ -103,12 +105,9 @@ always @(posedge clk) begin // writing the hdma register engages the dma engine 4'h5: begin hdma_length <= {1'b0,din[6:0]}; - if (hdma_mode == 1 && hdma_enabled && !din[7]) begin //terminate an active H-Blank transfer by writing zero to Bit 7 of FF55 - hdma_state <= wait_h; - hdma_end <= 1'b1; - hdma_rd <= 1'b0; + if (hdma_mode == 1 && hdma_enabled && !din[7]) begin //terminate a pending H-Blank transfer by writing zero to Bit 7 of FF55 hdma_enabled <= 1'b0; - end else begin //normal trigger + end else begin //normal trigger hdma_enabled <= 1'b1; hdma_mode <= din[7]; dma_delay <= START_DELAY; @@ -123,84 +122,65 @@ always @(posedge clk) begin // Currently IRAM takes 1 CPU cycle to get data. If hdma_active is lowered // at the same time as hdma_rd then the CPU will read invalid data. if (hdma_end) begin - hdma_active <= 0; - hdma_end <= 0; + if (dma_delay > 0) begin + dma_delay <= dma_delay - 1'b1; + end else begin + hdma_active <= 0; + hdma_end <= 0; + end end + //mode 0 GDMA do the transfer in one go after inital delay + //mode 1 HDMA transfer 1 block (16bytes) in each H-Blank only if (hdma_enabled) begin - if(hdma_mode==0) begin //mode 0 GDMA do the transfer in one go after inital delay + + if (mode_gdma || (mode_hdma && hdma_state == active)) begin hdma_active <= 1'b1; - hdma_rd <= 1'b1; // get data from RAM ready while waiting if (dma_delay>0) begin - dma_delay <= dma_delay - 1'b1; + dma_delay <= dma_delay - 1'b1; + if (dma_delay == 1) + hdma_rd <= 1'b1; end else begin - if(hdma_length != 8'hFF) begin - hdma_cnt <= hdma_cnt + 1'd1; - if (hdma_cnt == byte_cycles) begin - hdma_cnt <= 2'd0; - byte_cnt <= byte_cnt + 1'b1; - if (&byte_cnt) begin - hdma_source <= hdma_source + 1'b1; - hdma_target <= hdma_target + 1'b1; - hdma_length <= hdma_length - 1'd1; - if (hdma_length == 0) begin - hdma_end <= 1'b1; - hdma_rd <= 1'b0; - hdma_enabled <= 1'b0; - end + hdma_cnt <= hdma_cnt + 1'd1; + if (hdma_cnt == byte_cycles) begin + hdma_cnt <= 2'd0; + byte_cnt <= byte_cnt + 1'b1; + if (&byte_cnt) begin + hdma_source <= hdma_source + 1'b1; + hdma_target <= hdma_target + 1'b1; + hdma_length <= hdma_length - 1'd1; + if (hdma_length == 0 || &hdma_target) begin + hdma_enabled <= 1'b0; + hdma_end <= 1'b1; + hdma_rd <= 1'b0; + dma_delay <= END_DELAY; + end + if (mode_hdma) begin + hdma_state <= blocksent; + hdma_end <= 1'b1; + hdma_rd <= 1'b0; + dma_delay <= END_DELAY; end end end - end + end + end - end else begin //mode 1 HDMA transfer 1 block (16bytes) in each H-Blank only + if (mode_hdma) begin case (hdma_state) - - wait_h: begin - if (lcd_mode == 2'b00 ) begin // Mode 00: h-blank + + wait_h: begin + if (lcd_mode == 2'b00) begin // Mode 00: h-blank dma_delay <= START_DELAY; hdma_state <= active; end - hdma_end <= 1'b1; - hdma_rd <= 1'b0; - end - - blocksent: begin - if (hdma_length == 8'hFF) begin //check if finished - hdma_enabled <= 1'b0; - end - if (lcd_mode == 2'b11) // wait for mode 3, mode before h-blank - hdma_state <= wait_h; - end + end - active: begin - if(hdma_length != 8'hFF) begin - hdma_active <= 1'b1; - hdma_rd <= 1'b1; // get data from RAM ready while waiting - if (dma_delay>0) begin - dma_delay <= dma_delay - 1'b1; - end else begin - hdma_cnt <= hdma_cnt + 1'd1; - if (hdma_cnt == byte_cycles) begin - hdma_cnt <= 2'd0; - byte_cnt <= byte_cnt + 1'b1; - if (&byte_cnt) begin - hdma_source <= hdma_source + 1'b1; - hdma_target <= hdma_target + 1'b1; - hdma_length <= hdma_length - 1'd1; - hdma_state <= blocksent; - hdma_end <= 1'b1; - hdma_rd <= 1'b0; - end - end - end - end else begin - hdma_end <= 1'b1; - hdma_rd <= 1'b0; - hdma_enabled <= 1'b0; - end - end - endcase + blocksent: begin + if (lcd_mode == 2'b11) // wait for mode 3, mode before h-blank + hdma_state <= wait_h; + end + endcase end end end diff --git a/rtl/mappers/huc3.v b/rtl/mappers/huc3.v index 9cc3696..3f525ca 100644 --- a/rtl/mappers/huc3.v +++ b/rtl/mappers/huc3.v @@ -8,6 +8,7 @@ module huc3 ( input [63:0] savestate_data, inout [63:0] savestate_back_b, + input ce_32k, input [32:0] RTC_time, inout [31:0] RTC_timestampOut_b, inout [47:0] RTC_savedtimeOut_b, @@ -105,7 +106,7 @@ reg [ 7:0] rtc_index; reg [ 3:0] rtc_flags; reg [ 3:0] rtc_out; reg [ 5:0] rtc_seconds; -reg [24:0] rtc_subseconds; +reg [14:0] rtc_subseconds; reg [11:0] rtc_minutes; // Minutes of the day 0-1439 reg [15:0] rtc_days; @@ -119,15 +120,15 @@ reg [31:0] diffSeconds; wire diffSeconds_fast_count = (diffSeconds > 0); always @(posedge clk_sys) begin - rtc_subseconds <= rtc_subseconds + 1'b1; + if (ce_32k) rtc_subseconds <= rtc_subseconds + 1'b1; - if (rtc_subseconds_end) begin + if (ce_32k & rtc_subseconds_end) begin RTC_timestampOut <= RTC_timestampOut + 1'd1; end else if (diffSeconds_fast_count) begin // fast counting loaded seconds diffSeconds <= diffSeconds - 1'd1; end - if (rtc_subseconds_end | diffSeconds_fast_count) begin + if ((ce_32k & rtc_subseconds_end) | diffSeconds_fast_count) begin rtc_seconds <= rtc_seconds + 1'b1; if (rtc_seconds == 59) begin rtc_seconds <= 0; diff --git a/rtl/mappers/mappers.v b/rtl/mappers/mappers.v index 9703321..0fddb13 100644 --- a/rtl/mappers/mappers.v +++ b/rtl/mappers/mappers.v @@ -30,6 +30,7 @@ module mappers( input [15:0] joystick_analog_0, + input ce_32k, input [32:0] RTC_time, output [31:0] RTC_timestampOut, output [47:0] RTC_savedtimeOut, @@ -177,6 +178,7 @@ mbc3 map_mbc3 ( .savestate_data ( savestate_data ), .savestate_back_b ( savestate_back_b ), + .ce_32k ( ce_32k ), .RTC_time ( RTC_time ), .RTC_timestampOut_b( RTC_timestampOut_b ), .RTC_savedtimeOut_b( RTC_savedtimeOut_b ), @@ -394,6 +396,7 @@ huc3 map_huc3 ( .savestate_data ( savestate_data2 ), .savestate_back_b ( savestate_back2_b ), + .ce_32k ( ce_32k ), .RTC_time ( RTC_time ), .RTC_timestampOut_b( RTC_timestampOut_b ), .RTC_savedtimeOut_b( RTC_savedtimeOut_b ), @@ -468,7 +471,7 @@ tama map_tama ( .clk_sys ( clk_sys ), .ce_cpu ( ce ), - .ce_1x ( ce_cpu ), + .ce_32k ( ce_32k ), .savestate_load ( savestate_load ), .savestate_data ( savestate_data2 ), @@ -488,6 +491,8 @@ tama map_tama ( .cart_di ( cart_di ), .cart_oe_b ( cart_oe_b ), + .nCS ( nCS ), + .cram_rd ( cram_rd ), .cram_di ( cram_di ), .cram_do_b ( cram_do_b ), diff --git a/rtl/mappers/mbc3.v b/rtl/mappers/mbc3.v index 137afb9..65000c8 100644 --- a/rtl/mappers/mbc3.v +++ b/rtl/mappers/mbc3.v @@ -10,6 +10,7 @@ module mbc3 ( input [15:0] savestate_data, inout [15:0] savestate_back_b, + input ce_32k, input [32:0] RTC_time, inout [31:0] RTC_timestampOut_b, inout [47:0] RTC_savedtimeOut_b, @@ -147,7 +148,7 @@ assign ram_enabled = mbc_ram_enable & ~mbc3_mode & has_ram; ///////////////////////////// RTC /////////////////////////////// reg [2:0] rtc_index; -reg [25:0] rtc_subseconds; +reg [15:0] rtc_subseconds; reg [5:0] rtc_seconds, rtc_seconds_latch; reg [5:0] rtc_minutes, rtc_minutes_latch; reg [4:0] rtc_hours, rtc_hours_latch; @@ -156,7 +157,7 @@ reg rtc_overflow, rtc_overflow_latch; reg rtc_halt; wire [7:0] rtc_return; -wire rtc_subseconds_end = (rtc_subseconds >= 33554432); +wire rtc_subseconds_end = (rtc_subseconds >= 32768-1); wire RTC_timestampNew = RTC_time[32]; wire [31:0] RTC_timestampIn = RTC_time[31:0]; @@ -189,7 +190,7 @@ always @(posedge clk_sys) begin end rtc_change <= 1'b0; - rtc_subseconds <= rtc_subseconds + 1'd1; + if (ce_32k & ~rtc_halt) rtc_subseconds <= rtc_subseconds + 1'd1; if (mbc3_mode || (bk_wr && enable && img_size[9])) begin // RTC is either used by game or already used in savegame RTC_inuse <= 1'b1; @@ -226,7 +227,7 @@ always @(posedge clk_sys) begin case (rtc_index) 0: begin rtc_seconds <= cart_di[5:0]; - rtc_subseconds <= 26'd0; + rtc_subseconds <= 0; end 1: rtc_minutes <= cart_di[5:0]; 2: rtc_hours <= cart_di[4:0]; @@ -240,14 +241,14 @@ always @(posedge clk_sys) begin end else begin // normal counting - if (rtc_subseconds_end) begin - rtc_subseconds <= 26'd0; + if (ce_32k & rtc_subseconds_end) begin + rtc_subseconds <= 0; RTC_timestampOut <= RTC_timestampOut + 1'd1; end else if (diffSeconds_fast_count) begin // fast counting loaded seconds diffSeconds <= diffSeconds - 1'd1; end - if (rtc_subseconds_end | diffSeconds_fast_count) begin + if ((ce_32k & rtc_subseconds_end) | diffSeconds_fast_count) begin if (~rtc_halt) begin rtc_change <= 1'b1; rtc_seconds <= rtc_seconds + 1'd1; diff --git a/rtl/mappers/tama.v b/rtl/mappers/tama.v index e9cd823..4b655ea 100644 --- a/rtl/mappers/tama.v +++ b/rtl/mappers/tama.v @@ -3,7 +3,7 @@ module tama ( input clk_sys, input ce_cpu, - input ce_1x, + input ce_32k, input savestate_load, input [63:0] savestate_data, @@ -74,7 +74,7 @@ reg ram_io; reg prev_cram_rd; reg [6:0] rtc_seconds; -reg [21:0] rtc_subseconds; +reg [14:0] rtc_subseconds; reg [6:0] rtc_minutes; reg [5:0] rtc_hours; reg [5:0] rtc_days; @@ -84,7 +84,7 @@ reg rtc_24hours; reg [3:0] rtc_index; reg [1:0] rtc_leap_year; -wire sec_inc = &rtc_subseconds; // 4Mhz +wire sec_inc = &rtc_subseconds; reg [5:0] days_in_month; always @* begin @@ -136,9 +136,9 @@ always @(posedge clk_sys) begin cram_wr_r <= 1'd0; ram_io <= 1'd0; prev_cram_rd <= 1'd0; - end else if(ce_cpu) begin + end else begin - if (cart_wr & ~nCS & ~cart_addr[14]) begin // $A000-BFFF + if (ce_cpu & cart_wr & ~nCS & ~cart_addr[14]) begin // $A000-BFFF if (cart_addr[0]) begin reg_index <= cart_di[3:0]; // Register index if (cart_di[3:0] == 4'hA) begin @@ -163,7 +163,7 @@ always @(posedge clk_sys) begin // TODO: Get RTC working. How does the game use the RTC? // The in game timer runs at ~16x speed so 1 minute passes every 3.75 seconds. // Does the RTC also run 16x speed or only when the Game Boy is on? - if (ce_1x) begin + if (ce_32k) begin rtc_subseconds <= rtc_subseconds + 1'b1; if (sec_inc) begin rtc_seconds[3:0] <= rtc_seconds[3:0] + 1'b1; @@ -226,53 +226,55 @@ always @(posedge clk_sys) begin end end - cram_wr_r <= 0; - ram_io <= 0; - if (reg_start) begin - reg_start <= 0; + if (ce_cpu) begin + cram_wr_r <= 0; + ram_io <= 0; + if (reg_start) begin + reg_start <= 0; - if (|rtc_sel) begin // RTC - if (rtc_sel == 2'd1) begin - case (reg_addr) - 5'h04: begin - rtc_minutes <= reg_data_in[6:0]; - rtc_seconds <= 0; - rtc_subseconds <= 0; - end - 5'h05: rtc_hours <= reg_data_in[5:0]; - 5'h06: rtc_index <= 0; - default: ; - endcase + if (|rtc_sel) begin // RTC + if (rtc_sel == 2'd1) begin + case (reg_addr) + 5'h04: begin + rtc_minutes <= reg_data_in[6:0]; + rtc_seconds <= 0; + rtc_subseconds <= 0; + end + 5'h05: rtc_hours <= reg_data_in[5:0]; + 5'h06: rtc_index <= 0; + default: ; + endcase + end + + if (rtc_sel == 2'd2) begin + case ({reg_addr,reg_data_in[3:0]}) + {2'd0, 4'h7}: rtc_days[3:0] <= reg_data_in[7:4]; + {2'd0, 4'h8}: rtc_days[5:4] <= reg_data_in[5:4]; + {2'd0, 4'h9}: rtc_month[3:0] <= reg_data_in[7:4]; + {2'd0, 4'hA}: rtc_month[4] <= reg_data_in[4]; + {2'd0, 4'hB}: rtc_year[3:0] <= reg_data_in[7:4]; + {2'd0, 4'hC}: rtc_year[7:4] <= reg_data_in[7:4]; + + {2'd2, 4'hA}: rtc_24hours <= reg_data_in[4]; + {2'd2, 4'hB}: rtc_leap_year <= reg_data_in[5:4]; + default: ; + endcase + end + + end else begin // RAM + cram_wr_r <= ~ram_read; + ram_io <= 1; end - - if (rtc_sel == 2'd2) begin - case ({reg_addr,reg_data_in[3:0]}) - {2'd0, 4'h7}: rtc_days[3:0] <= reg_data_in[7:4]; - {2'd0, 4'h8}: rtc_days[5:4] <= reg_data_in[5:4]; - {2'd0, 4'h9}: rtc_month[3:0] <= reg_data_in[7:4]; - {2'd0, 4'hA}: rtc_month[4] <= reg_data_in[4]; - {2'd0, 4'hB}: rtc_year[3:0] <= reg_data_in[7:4]; - {2'd0, 4'hC}: rtc_year[7:4] <= reg_data_in[7:4]; - - {2'd2, 4'hA}: rtc_24hours <= reg_data_in[4]; - {2'd2, 4'hB}: rtc_leap_year <= reg_data_in[5:4]; - default: ; - endcase - end - - end else begin // RAM - cram_wr_r <= ~ram_read; - ram_io <= 1; end - end - if (ram_io & ram_read) begin - reg_data_out <= cram_di; - end + if (ram_io & ram_read) begin + reg_data_out <= cram_di; + end - prev_cram_rd <= cram_rd; - if (prev_cram_rd & ~cram_rd & ~cart_addr[0] & |rtc_sel & reg_index[3:1] == 3'b110) begin - rtc_index <= rtc_index + 1'b1; + prev_cram_rd <= cram_rd; + if (prev_cram_rd & ~cram_rd & ~cart_addr[0] & |rtc_sel & reg_index[3:1] == 3'b110) begin + rtc_index <= rtc_index + 1'b1; + end end end end diff --git a/rtl/megaswizzle.sv b/rtl/megaswizzle.sv index cdc211f..c87f69e 100644 --- a/rtl/megaswizzle.sv +++ b/rtl/megaswizzle.sv @@ -2,13 +2,21 @@ module megaduck_swizzle ( input megaduck, input [15:0] a_in, - output [15:0] a_out + output [15:0] a_out, + + input [7:0] snd_in_di, + output [7:0] snd_in_do, + + input [7:0] snd_out_di, + output [7:0] snd_out_do ); // Swizzle around MegaDuck register to match GB registers. always_comb begin a_out = a_in; + snd_in_do = snd_in_di; + snd_out_do = snd_out_di; if (megaduck) begin case (a_in) 16'hFF10: a_out = 16'hFF40; // LCDC @@ -24,31 +32,51 @@ module megaduck_swizzle 16'hFF16: a_out = 16'hFF4A; // WY 16'hFF17: a_out = 16'hFF4B; // WX - 16'hFF20: a_out = 16'hFF10; // Audio registers - 16'hFF21: a_out = 16'hFF12; - 16'hFF22: a_out = 16'hFF11; - 16'hFF23: a_out = 16'hFF13; - 16'hFF24: a_out = 16'hFF14; - 16'hFF25: a_out = 16'hFF16; - 16'hFF26: a_out = 16'hFF15; - 16'hFF27: a_out = 16'hFF17; - 16'hFF28: a_out = 16'hFF18; - 16'hFF29: a_out = 16'hFF19; - 16'hFF2A: a_out = 16'hFF1A; - 16'hFF2B: a_out = 16'hFF1B; - 16'hFF2C: a_out = 16'hFF1C; - 16'hFF2D: a_out = 16'hFF1D; - 16'hFF2E: a_out = 16'hFF1E; - 16'hFF2F: a_out = 16'hFF1F; - 16'hFF40: a_out = 16'hFF20; // The final 7 registers are after the audio ram - 16'hFF41: a_out = 16'hFF22; - 16'hFF42: a_out = 16'hFF21; - 16'hFF43: a_out = 16'hFF23; - 16'hFF44: a_out = 16'hFF24; - 16'hFF45: a_out = 16'hFF26; - 16'hFF46: a_out = 16'hFF25; + // Audio registers + 16'hFF20: a_out = 16'hFF10; // NR10 + 16'hFF21: a_out = 16'hFF12; // NR12 + 16'hFF22: a_out = 16'hFF11; // NR11 + 16'hFF23: a_out = 16'hFF13; // NR13 + 16'hFF24: a_out = 16'hFF14; // NR14 + 16'hFF25: a_out = 16'hFF16; // NR21 + 16'hFF27: a_out = 16'hFF17; // NR22 + 16'hFF28: a_out = 16'hFF18; // NR23 + 16'hFF29: a_out = 16'hFF19; // NR24 + 16'hFF2A: a_out = 16'hFF1A; // NR30 + 16'hFF2B: a_out = 16'hFF1B; // NR31 + 16'hFF2C: a_out = 16'hFF1C; // NR32 + 16'hFF2D: a_out = 16'hFF1E; // NR34 + 16'hFF2E: a_out = 16'hFF1D; // NR33 + // The final 7 registers are after the audio ram + 16'hFF40: a_out = 16'hFF20; // NR41 + 16'hFF41: a_out = 16'hFF22; // NR43 + 16'hFF42: a_out = 16'hFF21; // NR42 + 16'hFF43: a_out = 16'hFF23; // NR44 + 16'hFF44: a_out = 16'hFF24; // NR50 + 16'hFF45: a_out = 16'hFF26; // NR52 + 16'hFF46: a_out = 16'hFF25; // NR51 default: a_out = a_in; endcase + + // Megaduck has reversed nybbles for some registers + case (a_in[7:0]) + // NR12, NR22, NR42, NR43 + 8'h21, 8'h27, 8'h42, 8'h41: begin + snd_in_do = {snd_in_di[3:0], snd_in_di[7:4]}; + snd_out_do = {snd_out_di[3:0], snd_out_di[7:4]}; + end + + // NR32 swizzled volume bits + // https://github.com/bbbbbr/hUGEDriver/commit/b7abcb10dae7b7ac6296568878474b35baee2bae + // GB: Bits:6..5 : 00 = mute, 01 = 100%, 10 = 50%, 11 = 25% + // MD: Bits:6..5 : 00 = mute, 11 = 100%, 10 = 50%, 01 = 25% + 8'h2C: begin + snd_in_do[6] = ^snd_in_di[6:5]; + snd_out_do[6] = ^snd_out_di[6:5]; + end + + default: ; + endcase end end endmodule \ No newline at end of file diff --git a/rtl/reg_savestates.vhd b/rtl/reg_savestates.vhd index c379824..7f85dba 100644 --- a/rtl/reg_savestates.vhd +++ b/rtl/reg_savestates.vhd @@ -24,7 +24,7 @@ package pReg_savestates is constant REG_SAVESTATE_Link : regmap_type := ( 8, 16, 0, 1, x"0000000000000000"); constant REG_SAVESTATE_Video1 : regmap_type := ( 9, 60, 0, 1, x"0000000000000000"); - constant REG_SAVESTATE_Video2 : regmap_type := ( 10, 61, 0, 1, x"00000000FFFFFC00"); + constant REG_SAVESTATE_Video2 : regmap_type := ( 10, 63, 0, 1, x"00000000FFFFFC00"); constant REG_SAVESTATE_BPalette : regmap_type := ( 11, 63, 0, 8, x"0000000000000000"); constant REG_SAVESTATE_OPalette : regmap_type := ( 19, 63, 0, 8, x"0000000000000000"); constant REG_SAVESTATE_Video3 : regmap_type := ( 27, 63, 0, 1, x"0000000000000000"); @@ -38,7 +38,7 @@ package pReg_savestates is constant REG_SAVESTATE_Wave1_GBC : regmap_type := ( 35, 63, 0, 1, x"FF00FF00FF00FF00"); constant REG_SAVESTATE_Wave2_GBC : regmap_type := ( 36, 63, 0, 1, x"FF00FF00FF00FF00"); - constant REG_SAVESTATE_Top : regmap_type := ( 31, 54, 0, 1, x"0000000000800001"); + constant REG_SAVESTATE_Top : regmap_type := ( 31, 56, 0, 1, x"0000000000800001"); constant REG_SAVESTATE_Top2 : regmap_type := ( 38, 10, 0, 1, x"0000000000000000"); constant REG_SAVESTATE_Ext : regmap_type := ( 32, 15, 0, 1, x"0000000000000001"); constant REG_SAVESTATE_Ext2 : regmap_type := ( 37, 63, 0, 1, x"0000000000000000"); diff --git a/rtl/savestate_ui.sv b/rtl/savestate_ui.sv index bfdb522..d2784ee 100644 --- a/rtl/savestate_ui.sv +++ b/rtl/savestate_ui.sv @@ -56,7 +56,6 @@ always @(posedge clk) begin ss_info_req <= 1'b0; statusUpdate <= 1'b0; - lastOSDsetting <= status_slot; if(allow_ss) begin @@ -70,7 +69,8 @@ always @(posedge clk) begin 'h0C: begin ss_save <= pressed & alt; ss_load <= pressed & ~alt; ss_base <= 3; statusUpdate <= 1'b1; end // F4 endcase end - + + lastOSDsetting <= status_slot; if (lastOSDsetting != status_slot) begin ss_base <= status_slot; statusUpdate <= 1'b1; diff --git a/rtl/video.v b/rtl/video.v index 4c9d3c9..0d79aad 100644 --- a/rtl/video.v +++ b/rtl/video.v @@ -25,9 +25,11 @@ module video ( input ce, // 4 Mhz cpu clock input ce_cpu, // 4 or 8Mhz input isGBC, - input isGBC_game, + input isGBC_mode, input megaduck, + input boot_rom_en, + // cpu register adn oam interface input cpu_sel_oam, input cpu_sel_reg, @@ -81,13 +83,13 @@ wire [63:0] SaveStateBus_wired_or[0:SAVESTATE_MODULES-1]; wire [60:0] SS_Video1; wire [60:0] SS_Video1_BACK; -wire [61:0] SS_Video2; -wire [61:0] SS_Video2_BACK; +wire [63:0] SS_Video2; +wire [63:0] SS_Video2_BACK; wire [63:0] SS_Video3; wire [63:0] SS_Video3_BACK; eReg_SavestateV #(0, 9, 60, 0, 64'h0000000000000000) iREG_SAVESTATE_Video1 (clk, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[ 0], SS_Video1_BACK, SS_Video1); -eReg_SavestateV #(0, 10, 61, 0, 64'h00000000FFFFFC00) iREG_SAVESTATE_Video2 (clk, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[ 1], SS_Video2_BACK, SS_Video2); +eReg_SavestateV #(0, 10, 63, 0, 64'h00000000FFFFFC00) iREG_SAVESTATE_Video2 (clk, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[ 1], SS_Video2_BACK, SS_Video2); eReg_SavestateV #(0, 27, 63, 0, 64'h0000000000000000) iREG_SAVESTATE_Video3 (clk, SaveStateBus_Din, SaveStateBus_Adr, SaveStateBus_wren, SaveStateBus_rst, SaveStateBus_wired_or[18], SS_Video3_BACK, SS_Video3); wire [63:0] SS_BPAL [7:0]; @@ -150,7 +152,7 @@ wire lcdc_spr_ena = megaduck ? lcdc[0] : lcdc[1]; // When Bit 0 is cleared, the background and window lose their priority // - the sprites will be always displayed on top of background and window, // independently of the priority flags in OAM and BG Map attributes." -wire lcdc_bg_ena = (megaduck ? lcdc[6] : lcdc[0]) | (isGBC&&isGBC_game); +wire lcdc_bg_ena = (megaduck ? lcdc[6] : lcdc[0]) | (isGBC&&isGBC_mode); wire lcdc_bg_prio = megaduck ? lcdc[6] : lcdc[0]; assign lcd_on = lcdc_on; @@ -197,6 +199,13 @@ reg obpi_ai; //Bit 7 Auto Increment (0=Disabled, 1=Increment after Writi //FF6B - OCPD/OBPD - Sprite Palette Data reg[7:0] obpd [63:0]; //64 bytes +//FF6C Bit 0 OBJ priority mode select +// 0: smaller OBJ-NO has higher priority (GBC) +// 1: smaller X coordinate has higher priority (DMG) +// https://forums.nesdev.org/viewtopic.php?t=19888 +reg ff6c_opri; +reg obj_prio_dmg_mode; + // -------------------------------------------------------------------- // ----------------------------- DMA engine --------------------------- // -------------------------------------------------------------------- @@ -385,6 +394,8 @@ assign SS_Video2_BACK[ 44] = bgpi_ai; assign SS_Video2_BACK[ 45] = obpi_ai; assign SS_Video2_BACK[53:46] = lyc_r_gbc; assign SS_Video2_BACK[61:54] = lyc_r_dmg; +assign SS_Video2_BACK[ 62] = ff6c_opri; +assign SS_Video2_BACK[ 63] = obj_prio_dmg_mode; genvar palI; generate @@ -443,6 +454,8 @@ always @(posedge clk) begin bgpi_ai <= SS_Video2[ 44]; // 1'b0; obpi_ai <= SS_Video2[ 45]; // 1'b0; lyc_r_gbc <= SS_Video2[53:46]; // 8'h00; + ff6c_opri <= SS_Video2[ 62]; // 1'b0; + obj_prio_dmg_mode <= SS_Video2[ 63]; // 1'b0; bgpd[ 0] <= SS_BPAL[0][ 7: 0]; bgpd[16] <= SS_BPAL[2][ 7: 0]; bgpd[32] <= SS_BPAL[4][ 7: 0]; bgpd[48] <= SS_BPAL[6][ 7: 0]; //8'h00; bgpd[ 1] <= SS_BPAL[0][15: 8]; bgpd[17] <= SS_BPAL[2][15: 8]; bgpd[33] <= SS_BPAL[4][15: 8]; bgpd[49] <= SS_BPAL[6][15: 8]; //8'h00; @@ -491,13 +504,15 @@ always @(posedge clk) begin 8'h49: obp1 <= cpu_di; 8'h4a: wy <= cpu_di; 8'h4b: wx <= cpu_di; + endcase - //gbc + //gbc + if (isGBC) case(cpu_addr) 8'h68: begin bgpi <= cpu_di[5:0]; bgpi_ai <= cpu_di[7]; end - 8'h69: begin + 8'h69: if (isGBC_mode) begin if (vram_cpu_allow) begin bgpd[bgpi] <= cpu_di; end @@ -508,12 +523,20 @@ always @(posedge clk) begin obpi <= cpu_di[5:0]; obpi_ai <= cpu_di[7]; end - 8'h6B: begin + 8'h6B: if (isGBC_mode) begin if (vram_cpu_allow) begin obpd[obpi] <= cpu_di; end if (obpi_ai) obpi <= obpi + 6'h1; end + 8'h6C: begin + // Reportedly can be written to when boot rom is enabled or FF4C Bit2=0 (GBC mode) + // but only affects OBJ prio if written when boot rom is enabled. + if (boot_rom_en | isGBC_mode) begin + ff6c_opri <= cpu_di[0]; + end + if (boot_rom_en) obj_prio_dmg_mode <= cpu_di[0]; + end endcase end end @@ -536,9 +559,10 @@ assign cpu_do = (cpu_addr == 8'h4b)?wx: isGBC? (cpu_addr == 8'h68)?{bgpi_ai,1'd1,bgpi}: - (cpu_addr == 8'h69 && isGBC_game && vram_cpu_allow)?bgpd[bgpi]: + (cpu_addr == 8'h69 && isGBC_mode && vram_cpu_allow)?bgpd[bgpi]: (cpu_addr == 8'h6a)?{obpi_ai,1'd1,obpi}: - (cpu_addr == 8'h6b && isGBC_game && vram_cpu_allow)?obpd[obpi]: + (cpu_addr == 8'h6b && isGBC_mode && vram_cpu_allow)?obpd[obpi]: + (cpu_addr == 8'h6c) ? { 7'h7f, ff6c_opri } : 8'hff: 8'hff; @@ -773,9 +797,9 @@ reg [7:0] spr_tile_data0; reg [7:0] bg_tile_attr,bg_tile_attr_new; //GBC //gbc check tile bank -wire [7:0] bg_vram_data_a = (isGBC & isGBC_game & bg_tile_attr_new[3]) ? vram1_data : vram_data; +wire [7:0] bg_vram_data_a = (isGBC & isGBC_mode & bg_tile_attr_new[3]) ? vram1_data : vram_data; //gbc x-flip -wire [7:0] bg_vram_data_in = (isGBC & isGBC_game & bg_tile_attr_new[5]) ? bit_reverse(bg_vram_data_a) : bg_vram_data_a; +wire [7:0] bg_vram_data_in = (isGBC & isGBC_mode & bg_tile_attr_new[5]) ? bit_reverse(bg_vram_data_a) : bg_vram_data_a; // A bg or sprite fetch takes 6 cycles reg [2:0] bg_fetch_cycle; @@ -797,7 +821,7 @@ wire spr_pal = sprite_attr[4]; wire spr_attr_cgb_bank = sprite_attr[3]; wire [2:0] spr_cgb_pal = sprite_attr[2:0]; -wire [7:0] spr_vram_data = (isGBC & isGBC_game & spr_attr_cgb_bank) ? vram1_data : vram_data; +wire [7:0] spr_vram_data = (isGBC & isGBC_mode & spr_attr_cgb_bank) ? vram1_data : vram_data; wire [7:0] spr_tile_data_in = spr_attr_h_flip ? bit_reverse(spr_vram_data) : spr_vram_data; // CGB sprite priority. Non-transparent pixels with lower sprite_index have priority. @@ -814,7 +838,7 @@ wire [7:0] spr_cgb_index_prio = spr_cgb_prio(spr_cgb_index_shift[3], spr_cgb_ind // DMG sprite pixels are only loaded into the shift register if the old pixel is transparent. // CGB will mask the old pixel to 0 if the new pixel has higher priority. -wire [7:0] spr_tile_mask = (spr_tile_shift_0 | spr_tile_shift_1) & ((isGBC & isGBC_game) ? ~spr_cgb_index_prio : 8'hFF); +wire [7:0] spr_tile_mask = (spr_tile_shift_0 | spr_tile_shift_1) & ((isGBC & ~obj_prio_dmg_mode) ? ~spr_cgb_index_prio : 8'hFF); // cycle through the B01s states wire bg_tile_map_rd = (mode3 && bg_fetch_cycle[2:1] == 2'b00); @@ -839,7 +863,7 @@ always @(posedge clk) begin if (bg_fetch_cycle[0]) begin if(bg_tile_map_rd) begin bg_tile <= vram_data; - if (isGBC & isGBC_game) bg_tile_attr_new <= vram1_data; //get tile attr from vram bank1 + if (isGBC & isGBC_mode) bg_tile_attr_new <= vram1_data; //get tile attr from vram bank1 end if(bg_tile_data0_rd) bg_tile_data0 <= bg_vram_data_in; @@ -929,7 +953,7 @@ wire bg_tile_a12 = !lcdc_tile_data_sel?(~bg_tile[7]):1'b0; wire tile_map_sel = window_ena?lcdc_win_tile_map_sel:lcdc_bg_tile_map_sel; //GBC: check if flipped y -wire [2:0] tile_line_flip = (isGBC && isGBC_game && bg_tile_attr_new[6]) ? ~tile_line : tile_line; +wire [2:0] tile_line_flip = (isGBC && isGBC_mode && bg_tile_attr_new[6]) ? ~tile_line : tile_line; assign vram_addr = bg_tile_map_rd?{2'b11, tile_map_sel, bg_tile_map_addr}: @@ -979,7 +1003,7 @@ sprites sprites ( // https://forums.nesdev.com/viewtopic.php?f=20&t=10771&sid=8fdb6e110fd9b5434d4a567b1199585e#p122222 // priority list: BG0 < OBJL < BGL < OBJH < BGH -wire bg_piority = isGBC && isGBC_game && bg_tile_attr[7]; +wire bg_piority = isGBC && isGBC_mode && bg_tile_attr[7]; reg sprite_pixel_visible; @@ -992,7 +1016,7 @@ always @(*) begin sprite_pixel_visible = 1'b0; if (|sprite_pixel_data && lcdc_spr_ena) begin // pixel active and sprites enabled - if (isGBC&&isGBC_game) begin + if (isGBC&&isGBC_mode) begin if (sprite_pixel_data == 2'b00) sprite_pixel_visible = 1'b0; else if (bg_pix_data == 2'b00) @@ -1030,7 +1054,7 @@ wire [1:0] obp_data = (sprite_pixel_data == 2'b00) ? obp[1:0] : (sprite_pixel_data == 2'b10) ? obp[5:4] : obp[7:6]; -wire [5:0] palette_index = isGBC_game ? {bg_tile_attr[2:0], bg_pix_data, 1'b0} : //GBC game +wire [5:0] palette_index = isGBC_mode ? {bg_tile_attr[2:0], bg_pix_data, 1'b0} : //GBC game {3'd0, bgp_data , 1'b0}; //GB game in GBC mode // apply bg palette @@ -1039,7 +1063,7 @@ wire [14:0] pix_rgb_data = isGBC ? {bgpd[palette_index+1][6:0],bgpd[palette_inde // apply sprite palette wire [2:0] spr_cgb_pal_out = {spr_cgb_pal_shift[2][7], spr_cgb_pal_shift[1][7],spr_cgb_pal_shift[0][7]}; -wire [5:0] sprite_palette_index = isGBC_game? {spr_cgb_pal_out, sprite_pixel_data, 1'b0 } : //gbc game +wire [5:0] sprite_palette_index = isGBC_mode? {spr_cgb_pal_out, sprite_pixel_data, 1'b0 } : //gbc game {sprite_pixel_cmap, obp_data, 1'b0}; //GB game in GBC mode wire [14:0] sprite_pix = isGBC ? {obpd[sprite_palette_index+1][6:0],obpd[sprite_palette_index]} : //gbc