diff --git a/ColecoDS.nds b/ColecoDS.nds index a1fb2f98..71099eb7 100644 Binary files a/ColecoDS.nds and b/ColecoDS.nds differ diff --git a/Makefile b/Makefile index dff516e8..f2bc727b 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ include $(DEVKITARM)/ds_rules export TARGET := ColecoDS export TOPDIR := $(CURDIR) -export VERSION := 7.3b +export VERSION := 7.4 ICON := -b $(CURDIR)/logo.bmp "ColecoDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/ColecoDS" diff --git a/README.md b/README.md index d4d95d16..2b3c96c6 100644 --- a/README.md +++ b/README.md @@ -193,13 +193,13 @@ For the MSX emulation, the colecovision keypad is mapped as follows: ``` 1 2 3 - 4 5 STOP + 4 ? STP M1 M2 M3 SPC 0 RET ``` -That should be enough to get most MSX1 cart games running... In Game Options you can also override the '5' key to be any mappable MSX key. For the few games that still require the MSX arrows to play - you can emulate that via the D-PAD in Game Options. +That should be enough to get most MSX1 cart games running... In Game Options you can also override the '?' key to be any mappable MSX key. For the few games that still require the MSX arrows to play - you can emulate that via the D-PAD in Game Options. As of version 6.1 there is also a custom overlay for "MSX Full" keyboard. Blend Mode (DSi) : @@ -237,7 +237,7 @@ A Tale of Two Cores : ColecoDS supports 2 different Z80 CPU cores. DrZ80 is very fast but is not 100% accurate so some games don't run right. CZ80 is 10% slower but is much closer to 100% accurate and games generally run great. -You can toggle this (and save on a per-game basis) in GAME OPTIONS. +The CZ80 core i the default across the board - but you can change this (and save on a per-game basis) in GAME OPTIONS. The Need For Speed : ----------------------- @@ -252,6 +252,14 @@ would personally try them: Versions : ----------------------- +V7.4: 05-June-2022 by wavemotion-dave +* Added back DrZ80 core and fixed Colecovision Boulder Dash so it doesn't crash. +* Better Einstein CTC handling so timing is a bit more accurate. +* Improved Einstein memory swap for faster performance. +* Improved MSX mapper detection - about 30 more games playable without fiddling with settings. +* MSX Pal game support added (it was only 80% working before this). +* A few more frames of performance squeezed out to make more games run buttery-smooth. + V7.3: 31-May-2022 by wavemotion-dave * Massive optimization of the VDP core and memory handling so we are now almost 35% faster on Colecovision games and more than 10% faster on all other systems. * Due to these optmizations, the DrZ80 core has been removed and only the high-compatibility CZ80 core remains. diff --git a/arm9/gfx_data/pdev_bg0.png b/arm9/gfx_data/pdev_bg0.png index 6876f07c..9f3ef844 100644 Binary files a/arm9/gfx_data/pdev_bg0.png and b/arm9/gfx_data/pdev_bg0.png differ diff --git a/arm9/source/colecoDS.c b/arm9/source/colecoDS.c index a707b679..1c1291be 100644 --- a/arm9/source/colecoDS.c +++ b/arm9/source/colecoDS.c @@ -532,8 +532,8 @@ void ResetColecovision(void) memotech_reset(); // Reset the memotech MTX specific vars svi_reset(); // Reset the SVI specific vars msx_reset(); // Reset the MSX specific vars - pv2000_reset(); // Reset the PV2000 stuff - einstein_reset(); + pv2000_reset(); // Reset the PV2000 specific vars + einstein_reset(); // Reset the Tatung Einstein specific vars adam_CapsLock = 0; adam_unsaved_data = 0; @@ -746,7 +746,7 @@ void DisplayStatusLine(bool bForce) AffChaine(23,0,6, (sg1000_mode == 2 ? "SC-3000":"SG-1000")); last_pal_mode = 99; } - if (last_pal_mode != myConfig.isPAL) + if (last_pal_mode != myConfig.isPAL && !myConfig.showFPS) { last_pal_mode = myConfig.isPAL; AffChaine(0,0,6, myConfig.isPAL ? "PAL":" "); @@ -782,8 +782,9 @@ void DisplayStatusLine(bool bForce) char tmp[15]; siprintf(tmp, "CAS %d%% ", (int)(100 * (int)tape_pos)/(int)tape_len); AffChaine(8,0,6, tmp); + last_pal_mode = 99; } - if (last_pal_mode != myConfig.isPAL) + if (last_pal_mode != myConfig.isPAL && !myConfig.showFPS) { last_pal_mode = myConfig.isPAL; AffChaine(0,0,6, myConfig.isPAL ? "PAL":" "); @@ -797,6 +798,7 @@ void DisplayStatusLine(bool bForce) last_msx_mode = msx_mode; siprintf(tmp, "MSX %dK ", (int)(LastROMSize/1024)); AffChaine(23,0,6, tmp); + last_pal_mode = 99; } if ((last_tape_pos != tape_pos) && (msx_mode == 2)) { @@ -804,6 +806,12 @@ void DisplayStatusLine(bool bForce) char tmp[15]; siprintf(tmp, "CAS %d%% ", (int)(100 * (int)tape_pos)/(int)tape_len); AffChaine(8,0,6, tmp); + last_pal_mode = 99; + } + if (last_pal_mode != myConfig.isPAL && !myConfig.showFPS) + { + last_pal_mode = myConfig.isPAL; + AffChaine(0,0,6, myConfig.isPAL ? "PAL":" "); } } else if (svi_mode) @@ -859,6 +867,11 @@ void DisplayStatusLine(bool bForce) { last_pencil_mode = creativision_mode; AffChaine(20,0,6, "CREATIVISION"); + last_pal_mode = 99; + } + if (last_pal_mode != myConfig.isPAL && !myConfig.showFPS) + { + last_pal_mode = myConfig.isPAL; AffChaine(0,0,6, myConfig.isPAL ? "PAL":" "); } } @@ -869,7 +882,7 @@ void DisplayStatusLine(bool bForce) AffChaine(22,0,6, "EINSTEIN"); last_pal_mode = 99; } - if (last_pal_mode != myConfig.isPAL) + if (last_pal_mode != myConfig.isPAL && !myConfig.showFPS) { last_pal_mode = myConfig.isPAL; AffChaine(0,0,6, myConfig.isPAL ? "PAL":" "); diff --git a/arm9/source/colecoDS.h b/arm9/source/colecoDS.h index a90c708f..b9a58ba6 100644 --- a/arm9/source/colecoDS.h +++ b/arm9/source/colecoDS.h @@ -16,7 +16,7 @@ #include "cpu/z80/Z80_interface.h" #include "C24XX.h" -#define VERSIONCLDS "7.3" +#define VERSIONCLDS "7.4" //#define DEBUG_Z80 YES //#define FULL_DEBUG diff --git a/arm9/source/colecomngt.c b/arm9/source/colecomngt.c index 6b4b9d74..5b46d5fb 100644 --- a/arm9/source/colecomngt.c +++ b/arm9/source/colecomngt.c @@ -500,6 +500,7 @@ void getfile_crc(const char *path) if (file_crc == 0x111fc33b) msx_beeper_enabled = 1; // MSX Avenger uses beeper if (file_crc == 0x690f9715) msx_beeper_enabled = 1; // MSX Batman (the movie) uses beeper if (file_crc == 0x3571f5d4) msx_beeper_enabled = 1; // MSX Master of the Universe uses beeper + if (file_crc == 0x2142bd10) msx_beeper_enabled = 1; // MSX Future Knight // ------------------------------------------------------------------------------ // And a handful of games require SRAM which is a special case-by-case basis... @@ -1051,7 +1052,7 @@ void Z80CTC_Timer(void) { if (--ctc_timer[3] <= 0) { - ctc_timer[3] = ((((ctc_control[3] & 0x20) ? 256 : 16) * (ctc_time[3] ? ctc_time[3]:256)) / 60) + 1; + ctc_timer[3] = ((((ctc_control[3] & 0x20) ? 256 : 16) * (ctc_time[3] ? ctc_time[3]:256)) / 51) + 1; if (ctc_control[3] & 0x80) CPU.IRequest = ctc_vector[3]; } } diff --git a/arm9/source/cpu/z80/Z80_interface.c b/arm9/source/cpu/z80/Z80_interface.c index d8222d8b..d0be500b 100644 --- a/arm9/source/cpu/z80/Z80_interface.c +++ b/arm9/source/cpu/z80/Z80_interface.c @@ -30,6 +30,7 @@ u8 lastBlock[4] __attribute__((section(".dtcm"))) = {99,99,99,99}; u32 msx_offset __attribute__((section(".dtcm"))) = 0; u8 msx_sram_at_8000 __attribute__((section(".dtcm"))) = 0; u8 msx_scc_enable __attribute__((section(".dtcm"))) = 0; +u8 einstein_ram_dirty __attribute__((section(".dtcm"))) = 0; extern u8 romBankMask; extern u8 Slot1ROM[]; @@ -357,7 +358,6 @@ void activision_pcb_write(u16 address) if (address == 0xFFF0) Write24XX(&EEPROM,EEPROM.Pins|C24XX_SDA); } - // ------------------------------------------------------------------ // Write memory handles both normal writes and bankswitched since // write is much less common than reads... We handle the MSX @@ -474,7 +474,7 @@ ITCM_CODE void cpu_writemem16 (u8 value,u16 address) if (address >= einstein_ram_start) { pColecoMem[address] = value; // Allow pretty much anything above the base ROM area - } + } else einstein_ram_dirty=1; Slot3RAM[address] = value; // Plus shadow copy to improve bank switching } // ---------------------------------------------------------------------------------- diff --git a/arm9/source/einstein.c b/arm9/source/einstein.c index d8e7a1b6..b884f77d 100644 --- a/arm9/source/einstein.c +++ b/arm9/source/einstein.c @@ -220,14 +220,23 @@ void einstein_swap_memory(void) if (einstein_ram_start == 0x8000) { - memcpy(pColecoMem, Slot3RAM, 0x8000); + extern u8 einstein_ram_dirty; + if (einstein_ram_dirty) // If we have some dirty bytes, copy over all of the RAM shadow copy + { + einstein_ram_dirty=0; + memcpy(pColecoMem, Slot3RAM, 0x8000); + } + else // Otherwise just copy over the RAM into where the BIOS was... saves time. + { + memcpy(pColecoMem, Slot3RAM, 0x2000); + } einstein_ram_start = 0x0000; } else { einstein_ram_start = 0x8000; memcpy(pColecoMem,EinsteinBios,0x2000); - memset(pColecoMem+0x2000,0xFF, 0x6000); + //memset(pColecoMem+0x2000,0xFF, 0x6000); - In theory we should blank this area but to save memory swap time we don't bother if (tape_len == 1626) // A bit of a hack... the size of the Diagnostic ROM { memcpy(pColecoMem+0x4000, romBuffer, tape_len); // only for Diagnostics ROM @@ -395,17 +404,15 @@ void cpu_writeport_einstein(register unsigned short Port,register unsigned char } else if (Port == 0x21) // ADC INT MASK { - debug4++; //key_int_mask = Value; } else if (Port == 0x25) // JOYSTICK INT MASK { - debug4++; //key_int_mask = Value; } else if (Port == 0x25) // Drive Select { - //if (Value & 1) zzz(); + //if (Value & 1) einstein_ram_dirty(); } else if (Port == 0x24) // ROM vs RAM bank port { diff --git a/arm9/source/msx.c b/arm9/source/msx.c index 2a955133..4840ab2a 100644 --- a/arm9/source/msx.c +++ b/arm9/source/msx.c @@ -677,8 +677,6 @@ u8 MSX_GuessROMType(u32 size) u8 type = KON8; // Default to Konami 8K mapper u16 guess[MAX_MAPPERS] = {0,0,0,0}; - if (size == (64 * 1024)) return ASC16; // Big percentage of 64K mapper ROMs are ASCII16 - for (int i=0; i guess[KON8]) && (guess[SCC8] > guess[ASC8]) && (guess[SCC8] > guess[ASC16])) type = SCC8; else type = KON8; + if (size == (64 * 1024)) type = ASC16; // Big percentage of 64K mapper ROMs are ASCII16 so default to that and override below + // ---------------------------------------------------------------------- // Since mappers are hard to detect reliably, check a few special CRCs @@ -746,7 +746,32 @@ u8 MSX_GuessROMType(u32 size) if (file_crc == 0xec036e37) type = ASC16; // Gall Force if (file_crc == 0xa29176e3) type = ASC16; // Mecha 9 if (file_crc == 0x03379ef8) type = ASC16; // MSXDev Step Up 1.2 - if (file_crc == 0x8183bae1) type = LIN64; // Mutants fro the Deep (fixed) + if (file_crc == 0x2f9bed70) type = ZEN16; // Adventure Kid + if (file_crc == 0xab9fb4a4) type = ASC16; // Astro Marine Corps + if (file_crc == 0x8cf0e6c0) type = ASC8; // Bomber King + if (file_crc == 0xf2f2f0c8) type = ASC16; // Borfestu (English Translation) + if (file_crc == 0x8801b31e) type = LIN64; // Break In + if (file_crc == 0x79cf953d) type = ASC8; // Death Wish III + if (file_crc == 0x387c1de7) type = ASC16; // Dragon Slayer III - Romantica + if (file_crc == 0x2526e568) type = ASC16; // Dungeon Hunter + if (file_crc == 0x1d75c0b4) type = ASC16; // Freedom Fighter (newest) + if (file_crc == 0xc570ea63) type = ASC16; // Freedom Fighter + if (file_crc == 0xa5b0e901) type = ASC16; // Game Over (Parts I and II) + if (file_crc == 0xb2e57a45) type = ASC16; // Gremlins II + if (file_crc == 0xb29edaec) type = ASC16; // Hydlide II + if (file_crc == 0x41c82156) type = ZEN8; // Hydlide III (Zenmia) + if (file_crc == 0xcb9eebfb) type = SCC8; // Lex Flics (translated) + if (file_crc == 0xd6c395f8) type = SCC8; // Monster Hunter + if (file_crc == 0x8183bae1) type = LIN64; // Mutants from the Deep + if (file_crc == 0xa78fdb26) type = ASC8; // No Back Down + if (file_crc == 0x454381e4) type = SCC8; // PuzzyBox 1.0 + if (file_crc == 0x31e3f039) type = LIN64; // Stupid Martians + if (file_crc == 0x9195c34c) type = ZEN8; // Super Boy III + if (file_crc == 0x73efe840) type = ASC16; // Super Pierrot + if (file_crc == 0x41676177) type = LIN64; // Tina's Island Adventure + if (file_crc == 0xc5c14bbd) type = KON8; // The Hobbit + if (file_crc == 0xfea70207) type = ASC16; // Vaxol + if (file_crc == 0x35899655) type = ASC8; // Venom Strikes Back return type; } diff --git a/arm9/source/pv2000.c b/arm9/source/pv2000.c index d62b1a1f..d71e793a 100644 --- a/arm9/source/pv2000.c +++ b/arm9/source/pv2000.c @@ -88,8 +88,6 @@ unsigned char cpu_readport_pv2000(register unsigned short Port) // PV-2000 ports are 8-bit Port &= 0x00FF; - debug4 = JoyState; - if (Port == 0x10) { u8 joy1 = 0x00;