Skip to content

Commit

Permalink
Major restructure of ITCM Code to get a big speed boost in the new CZ…
Browse files Browse the repository at this point in the history
…80 core. Ready for 4.7 release.
  • Loading branch information
wavemotion-dave committed Dec 23, 2021
1 parent 52577a3 commit 47af130
Show file tree
Hide file tree
Showing 14 changed files with 59 additions and 51 deletions.
Binary file modified ColecoDS.nds
Binary file not shown.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ include $(DEVKITARM)/ds_rules

export TARGET := ColecoDS
export TOPDIR := $(CURDIR)
export VERSION := 4.6a
export VERSION := 4.7

ICON := -b $(CURDIR)/logo.bmp "ColecoDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/ColecoDS"

Expand Down
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ Thanks to Flubba for the SN76496 sound core.

Special thanks to Marat Fayzullin, as the
author of ColEM which is the code for the
core emulation (specifically TMS9918 VDP).
I think the original port was circa ColEM 2.1
with some fixes and updated Sprite/Line handling
from ColEM 5.6
core emulation (specifically TMS9918 VDP
and the CZ80 CPU core). I think the original
port was circa ColEM 2.1 with some fixes and
updated Sprite/Line handling from ColEM 5.6

Known Issues :
-----------------------
Expand Down Expand Up @@ -96,8 +96,23 @@ it for almost all games (Princess Quest is one game where you might turn it off)
handle it for the more simple games. So by default it's enabled for DSi and disabled for DS-LITE/PHAT.
You can toggle this in the "Game Options" (and START=SAVE it out as you wish).

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 slower but is much closer to 100% accurate and games generally run great.
For the DSi and above, the CZ80 core is the default.
For the DS-LITE/PHAT, the DrZ80 core is the default.
You can toggle this (and save on a per-game basis) in GAME OPTIONS.
If you want to use the CZ80 core but need a bit more speed to make the
games playable - you can also play with Vertical Sync and Frame Skip settings.

Versions :
-----------------------
V4.7: 23-Dec-2021 by wavemotion-dave
* Major speed improvements in the new CZ80 core.
* Installed new CZ80 core as the default for DSi and above.

V4.6: 22-Dec-2021 by wavemotion-dave
* New CZ80 core added to solve compatibility problems with the remaining games.

Expand Down
Binary file modified arm9/gfx_data/pdev_bg0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 7 additions & 2 deletions arm9/source/colecoDS.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ void DisplayStatusLine(bool bForce)
// ------------------------------------------------------------------------
// The main emulation loop is here... call into the Z80, VDP and PSG
// ------------------------------------------------------------------------
ITCM_CODE void colecoDS_main(void)
void colecoDS_main(void)
{
u32 keys_pressed;
u16 iTx, iTy;
Expand All @@ -494,8 +494,10 @@ ITCM_CODE void colecoDS_main(void)
static u32 lastUN = 0;
static u8 dampenClick = 0;

showMainMenu(); // Returns when user has asked for a game to run...
// Returns when user has asked for a game to run...
showMainMenu();

// Get the Coleco Machine Emualtor ready
colecoInit(gpFic[ucGameAct].szName);

colecoSetPal();
Expand All @@ -513,10 +515,12 @@ ITCM_CODE void colecoDS_main(void)
timingFrames = 0;
emuFps=0;

// Default SGM statics back to init state
last_sgm_mode = false;
last_ay_mode = false;
last_mc_mode = 0;

// Force the sound engine to turn on when we start emulation
bStartSoundEngine = true;

// -------------------------------------------------------------------
Expand All @@ -527,6 +531,7 @@ ITCM_CODE void colecoDS_main(void)
// Take a tour of the Z80 counter and display the screen if necessary
if (!LoopZ80())
{
// If we've been asked to start the sound engine, rock-and-roll!
if (bStartSoundEngine)
{
bStartSoundEngine = false;
Expand Down
4 changes: 2 additions & 2 deletions arm9/source/colecoDS.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <string.h>
#include "cpu/z80/drz80/Z80_interface.h"

#define VERSIONCLDS "4.6"
#define VERSIONCLDS "4.7"

//#define DEBUG_Z80 YES

Expand Down Expand Up @@ -34,7 +34,7 @@
#define JST_RED JST_FIRER
#define JST_YELLOW JST_FIREL

// These 4 are now actual Colecovision key maps... they trigger the spinners.
// These 4 are not actual Colecovision key maps... they trigger the spinner logic.
#define META_SPINX_LEFT 0xFFFF0001
#define META_SPINX_RIGHT 0xFFFF0002
#define META_SPINY_LEFT 0xFFFF0003
Expand Down
7 changes: 4 additions & 3 deletions arm9/source/colecogeneric.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,10 +701,10 @@ void SetDefaultGameConfig(void)
myConfig.autoFire2 = 0;
myConfig.overlay = 0;
myConfig.maxSprites = 0;
myConfig.vertSync = (isDSiMode() ? 1:0);
myConfig.vertSync = (isDSiMode() ? 1:0); // Default is Vertical Sync ON for DSi and OFF for DS-LITE
myConfig.spinSpeed = 0;
myConfig.touchPad = 0;
myConfig.cpuCore = 0; // Default is the faster DrZ80 core
myConfig.cpuCore = (isDSiMode() ? 1:0); // Default is slower/accurate CZ80 for DSi and faster DrZ80 core for DS-LITE
myConfig.reserved9 = 0;
myConfig.reservedA = 0;
myConfig.reservedB = 0;
Expand Down Expand Up @@ -784,6 +784,7 @@ void SetDefaultGameConfig(void)

// ------------------------------------------------------------------------
// These games all need the slower but higher compatibility CZ80 CPU Core
// so override the default above for these games in order to play them.
// ------------------------------------------------------------------------
if (
(file_crc == 0xead5e824) || // Arno Dash
Expand Down Expand Up @@ -889,7 +890,7 @@ const struct options_t Option_Table[] =
{"AUTO FIRE B2", {"OFF", "ON"}, &myConfig.autoFire2, 2},
{"TOUCH PAD", {"PLAYER 1", "PLAYER 2"}, &myConfig.touchPad, 2},
{"SPIN SPEED", {"NORMAL", "FAST", "FASTEST", "SLOW", "SLOWEST"}, &myConfig.spinSpeed, 5},
{"Z80 CPU CORE", {"DRZ80 (Fast)", "CZ80 (Slow)"}, &myConfig.cpuCore, 2},
{"Z80 CPU CORE", {"DRZ80 (Faster)", "CZ80 (Slower)"}, &myConfig.cpuCore, 2},
#if 0 // Developer use only
{"Z80 CYCLES!!", {"NORMAL", "+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9", "+10", "-1", "-2", "-3", "-4", "-5"}, &dev_z80_cycles, 16},
#endif
Expand Down
4 changes: 2 additions & 2 deletions arm9/source/colecomngt.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,11 +794,11 @@ ITCM_CODE void cpu_writeport16(register unsigned short Port,register unsigned ch
// -----------------------------------------------
// These two functions are for the CZ80 core...
// -----------------------------------------------
ITCM_CODE void OutZ80(register word Port,register byte Value)
void OutZ80(register word Port,register byte Value)
{
cpu_writeport16(Port, Value);
}
ITCM_CODE byte InZ80(register word Port)
byte InZ80(register word Port)
{
return cpu_readport16(Port);
}
Expand Down
2 changes: 1 addition & 1 deletion arm9/source/cpu/sn76496/Fake_AY.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ u8 c_idx=0;
// We handle envelopes here... the timing is nowhere near exact but so few games utilize this
// and so accuracy isn't all that critical. The sound will be a little off - but it will be ok.
// ---------------------------------------------------------------------------------------------
ITCM_CODE void FakeAY_Loop(void)
void FakeAY_Loop(void)
{
static u16 delay=0;

Expand Down
2 changes: 1 addition & 1 deletion arm9/source/cpu/tms9918a/tms9918a.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ void ITCM_CODE RefreshLine2(u8 uY) {
/** Refresh line Y (0..191) of SCREEN3, including sprites **/
/** in this line. **/
/*************************************************************/
void ITCM_CODE RefreshLine3(u8 uY) {
void RefreshLine3(u8 uY) {
register byte X,K,Offset;
register byte *P,*T;

Expand Down
8 changes: 4 additions & 4 deletions arm9/source/cpu/tms9918a/tms9918a.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ extern u8 bResetVLatch;
extern u8 TMS9918A_palette[16*3];
extern tScrMode SCR[MAXSCREEN+1];

extern void ITCM_CODE RefreshLine0(u8 uY);
extern void ITCM_CODE RefreshLine1(u8 uY);
extern void ITCM_CODE RefreshLine2(u8 uY);
extern void ITCM_CODE RefreshLine3(u8 uY);
extern void RefreshLine0(u8 uY);
extern void RefreshLine1(u8 uY);
extern void RefreshLine2(u8 uY);
extern void RefreshLine3(u8 uY);

extern byte WrCtrl9918(byte value);
extern void WrData9918(byte value);
Expand Down
20 changes: 4 additions & 16 deletions arm9/source/cpu/z80/Z80.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,10 @@ INLINE byte OpZ80(word A) { return pColecoMem[A]; }
// -----------------------------------------------
// These two functions are for the CZ80 core...
// -----------------------------------------------
extern u8 bMagicMegaCart, romBankMask;
extern void cpu_writemem16 (u8 value,u16 address);
extern void BankSwitch(u8 bank);
INLINE void WrZ80(register word address,register byte Value)
{
cpu_writemem16(Value, address);
}

INLINE byte RdZ80(register word address)
{
if (bMagicMegaCart && (address >= 0xFFC0)) // Handle Megacart Hot Spots
{
BankSwitch(address & romBankMask);
}
return (pColecoMem[address]);
}
extern byte cpu_readmem16_banked (u16 address);
#define WrZ80(A,V) cpu_writemem16(V,A)
#define RdZ80(A) cpu_readmem16_banked(A)

#define S(Fl) CPU.AF.B.l|=Fl
#define R(Fl) CPU.AF.B.l&=~(Fl)
Expand Down Expand Up @@ -520,7 +508,7 @@ void ResetZ80(Z80 *R)
/** negative, and current register values in R. **/
/*************************************************************/
#ifdef EXECZ80
int ExecZ80(register Z80 *R,register int RunCycles)
ITCM_CODE int ExecZ80(register Z80 *R,register int RunCycles)
{
register byte I;
register pair J;
Expand Down
28 changes: 14 additions & 14 deletions arm9/source/cpu/z80/drz80/Z80_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,41 +27,41 @@ extern u8 romBankMask;
extern u8 romBuffer[];


ITCM_CODE u32 z80_rebaseSP(u16 address) {
u32 z80_rebaseSP(u16 address) {
drz80.Z80SP_BASE = (unsigned int) pColecoMem;
drz80.Z80SP = drz80.Z80SP_BASE + address;
return (drz80.Z80SP);
}

ITCM_CODE u32 z80_rebasePC(u16 address) {
u32 z80_rebasePC(u16 address) {
drz80.Z80PC_BASE = (unsigned int) pColecoMem;
drz80.Z80PC = drz80.Z80PC_BASE + address;
return (drz80.Z80PC);
}

ITCM_CODE void z80_irq_callback(void) {
void z80_irq_callback(void) {
drz80.Z80_IRQ = 0x00;
}

// -----------------------------
// Normal 8-bit Read... fast!
// -----------------------------
ITCM_CODE u8 cpu_readmem16 (u16 address) {
u8 cpu_readmem16 (u16 address) {
return (pColecoMem[address]);
}

// -----------------------------
// Normal 16-bit Read... fast!
// -----------------------------
ITCM_CODE u16 drz80MemReadW(u16 address)
u16 drz80MemReadW(u16 address)
{
return (pColecoMem[address] | (pColecoMem[address+1] << 8));
}

// ------------------------------------------------
// Switch banks... do this as fast as possible..
// ------------------------------------------------
ITCM_CODE void BankSwitch(u8 bank)
void BankSwitch(u8 bank)
{
if (lastBank != bank) // Only if the bank was changed...
{
Expand All @@ -82,7 +82,7 @@ ITCM_CODE void BankSwitch(u8 bank)
// -------------------------------------------------
// 8-bit read with bankswitch support... slower...
// -------------------------------------------------
ITCM_CODE u8 cpu_readmem16_banked (u16 address)
u8 cpu_readmem16_banked (u16 address)
{
if (bMagicMegaCart) // Handle Megacart Hot Spots
{
Expand All @@ -97,7 +97,7 @@ ITCM_CODE u8 cpu_readmem16_banked (u16 address)
// -------------------------------------------------
// 16-bit read with bankswitch support... slower...
// -------------------------------------------------
ITCM_CODE u16 drz80MemReadW_banked(u16 addr)
u16 drz80MemReadW_banked(u16 addr)
{
if (bMagicMegaCart) // Handle Megacart Hot Spots
{
Expand All @@ -112,7 +112,7 @@ ITCM_CODE u16 drz80MemReadW_banked(u16 addr)
// Write memory handles both normal writes and bankswitched since
// write is much less common than reads...
// ------------------------------------------------------------------
ITCM_CODE void cpu_writemem16 (u8 value,u16 address)
void cpu_writemem16 (u8 value,u16 address)
{
extern u8 sRamAtE000_OK;
extern u8 sgm_enable;
Expand Down Expand Up @@ -151,13 +151,13 @@ ITCM_CODE void cpu_writemem16 (u8 value,u16 address)
// -----------------------------------------------------------------
// The 16-bit write simply makes 2 calls into the 8-bit writes...
// -----------------------------------------------------------------
ITCM_CODE void drz80MemWriteW(u16 data,u16 addr)
void drz80MemWriteW(u16 data,u16 addr)
{
cpu_writemem16(data & 0xff , addr);
cpu_writemem16(data>>8,addr+1);
}

ITCM_CODE void Z80_Cause_Interrupt(int type)
void Z80_Cause_Interrupt(int type)
{
if (type == Z80_NMI_INT)
{
Expand All @@ -174,13 +174,13 @@ ITCM_CODE void Z80_Cause_Interrupt(int type)
}
}

ITCM_CODE void Z80_Clear_Pending_Interrupts(void)
void Z80_Clear_Pending_Interrupts(void)
{
drz80.pending_irq = 0;
drz80.Z80_IRQ = 0;
}

ITCM_CODE void Interrupt(void)
void Interrupt(void)
{
if (drz80.pending_irq & NMI_IRQ) /* NMI IRQ */
{
Expand Down Expand Up @@ -247,7 +247,7 @@ void DrZ80_Reset(void) {
// produce exactly an evenly-divisible number of
// cycles for a given scanline...
// --------------------------------------------------
ITCM_CODE int DrZ80_execute(int cycles)
int DrZ80_execute(int cycles)
{
drz80.cycles = cycles + cycle_deficit;

Expand Down
1 change: 0 additions & 1 deletion arm9/source/cpu/z80/drz80/drz80.s
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,6 @@ DrZ80Ver: .long 0x0001
.equ Z80_HALT, 1<<2

;@ --------------------------- Framework --------------------------
.section .itcm
DrZ80Run:
;@ r0 = pointer to cpu context
;@ r1 = ISTATES to execute
Expand Down

0 comments on commit 47af130

Please sign in to comment.