mirror of
https://github.com/wavemotion-dave/GimliDS.git
synced 2025-06-19 14:25:38 -04:00
Version 1.1 - See readme.md for details.
This commit is contained in:
parent
26d89638b1
commit
93b7b75c55
BIN
GimliDS.nds
BIN
GimliDS.nds
Binary file not shown.
2
Makefile
2
Makefile
@ -9,7 +9,7 @@ include $(DEVKITARM)/ds_rules
|
|||||||
|
|
||||||
export TARGET := GimliDS
|
export TARGET := GimliDS
|
||||||
export TOPDIR := $(CURDIR)
|
export TOPDIR := $(CURDIR)
|
||||||
export VERSION := 1.0a
|
export VERSION := 1.1
|
||||||
|
|
||||||
ICON := -b $(CURDIR)/C64_icon.bmp "GimliDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/GimliDS"
|
ICON := -b $(CURDIR)/C64_icon.bmp "GimliDS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/GimliDS"
|
||||||
|
|
||||||
|
@ -147,6 +147,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
```
|
```
|
||||||
## Change Log
|
## Change Log
|
||||||
|
|
||||||
|
Version 1.1 release 11-May-2025 by wavemotion-dave
|
||||||
|
* Fix to CIA vars initialization so games like Chuckie Egg start properly.
|
||||||
|
* Fix to TOD clock counters (previous versions would not clock at all... fixes some utilities mostly).
|
||||||
|
* Improved REU handling for a bit more speed (gain of 1-2 frames on REU games)
|
||||||
|
* Improved VIC handling for a bit more speed (gain of 1-2 frames across the board)
|
||||||
|
|
||||||
Version 1.0 release 09-May-2025 by wavemotion-dave
|
Version 1.0 release 09-May-2025 by wavemotion-dave
|
||||||
* Added TOGGLE ZOOM button map to scale screen 1:1 temporarily (to make text games readable)
|
* Added TOGGLE ZOOM button map to scale screen 1:1 temporarily (to make text games readable)
|
||||||
* Another proper fix for CPU jump commands not handling the extra cycle it takes.
|
* Another proper fix for CPU jump commands not handling the extra cycle it takes.
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
@ -1351,7 +1351,7 @@ void C64::main_loop(void)
|
|||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
if (ThePrefs.TrueDrive)
|
if (ThePrefs.TrueDrive)
|
||||||
{
|
{
|
||||||
int cycles_1541 = FLOPPY_CYCLES_PER_LINE + CycleDeltas[myConfig.flopCycles];
|
int cycles_1541 = FLOPPY_CYCLES_PER_LINE;
|
||||||
TheCPU1541->CountVIATimers(cycles_1541);
|
TheCPU1541->CountVIATimers(cycles_1541);
|
||||||
|
|
||||||
if (!TheCPU1541->Idle)
|
if (!TheCPU1541->Idle)
|
||||||
|
@ -84,7 +84,7 @@ void MOS6526::Reset(void)
|
|||||||
pra = prb = ddra = ddrb = 0;
|
pra = prb = ddra = ddrb = 0;
|
||||||
|
|
||||||
ta = tb = 0xffff;
|
ta = tb = 0xffff;
|
||||||
latcha = latchb = 1;
|
latcha = latchb = 0xffff;
|
||||||
|
|
||||||
tod_10ths = tod_sec = tod_min = 0; tod_hr = 1;
|
tod_10ths = tod_sec = tod_min = 0; tod_hr = 1;
|
||||||
alm_10ths = alm_sec = alm_min = alm_hr = 0;
|
alm_10ths = alm_sec = alm_min = alm_hr = 0;
|
||||||
@ -559,7 +559,6 @@ void MOS6526::CountTOD(void)
|
|||||||
tod_divider--;
|
tod_divider--;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Reload divider according to 50/60 Hz flag
|
// Reload divider according to 50/60 Hz flag
|
||||||
if (cra & 0x80)
|
if (cra & 0x80)
|
||||||
tod_divider = 4;
|
tod_divider = 4;
|
||||||
|
@ -947,7 +947,7 @@
|
|||||||
case 0x7c:
|
case 0x7c:
|
||||||
case 0xdc:
|
case 0xdc:
|
||||||
case 0xfc:
|
case 0xfc:
|
||||||
#if PRECISE_CPU_CYCLES
|
#if PRECISE_CPU_CYCLES_NO // Save the effort and we need the ITCM_CODE space
|
||||||
read_byte_abs_x();
|
read_byte_abs_x();
|
||||||
#else
|
#else
|
||||||
pc+=2;
|
pc+=2;
|
||||||
|
@ -51,8 +51,11 @@
|
|||||||
|
|
||||||
extern u8 myRAM[];
|
extern u8 myRAM[];
|
||||||
|
|
||||||
|
// We are emulating the REU-1764 (256K) only
|
||||||
u8 REU_RAM[256 * 1024];
|
u8 REU_RAM[256 * 1024];
|
||||||
|
|
||||||
|
#define RAM_MASK 0x3FFFF
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REU constructor
|
* REU constructor
|
||||||
*/
|
*/
|
||||||
@ -61,7 +64,6 @@ REU::REU(MOS6510 * cpu) : the_cpu(cpu)
|
|||||||
{
|
{
|
||||||
// Allocate expansion RAM
|
// Allocate expansion RAM
|
||||||
ram_size = 0x40000; // 256K only
|
ram_size = 0x40000; // 256K only
|
||||||
ram_mask = ram_size - 1;
|
|
||||||
|
|
||||||
ex_ram = REU_RAM;
|
ex_ram = REU_RAM;
|
||||||
|
|
||||||
@ -208,6 +210,11 @@ void REU::WriteIO2(uint16_t adr, uint8_t byte)
|
|||||||
{
|
{
|
||||||
execute_dma();
|
execute_dma();
|
||||||
}
|
}
|
||||||
|
if ((byte & 0x90) == 0x80)
|
||||||
|
{
|
||||||
|
// This would normally be the 'delayed' write... not fully handled by GimliDS as we can't afford the trigger check on FF00
|
||||||
|
execute_dma();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
regs[adr & 0xf] = byte;
|
regs[adr & 0xf] = byte;
|
||||||
@ -236,45 +243,44 @@ void REU::execute_dma()
|
|||||||
// Get transfer length
|
// Get transfer length
|
||||||
uint16_t length = regs[7] | (regs[8] << 8);
|
uint16_t length = regs[7] | (regs[8] << 8);
|
||||||
|
|
||||||
// Calculate address increments
|
// We are skipping the memory increment of regs[10] as there
|
||||||
unsigned c64_inc = (regs[10] & 0x80) ? 0 : 1;
|
// are no known practical uses of it... and we need the speed.
|
||||||
unsigned reu_inc = (regs[10] & 0x40) ? 0 : 1;
|
|
||||||
|
|
||||||
// Do transfer
|
if ((regs[1] & 3) == 0)
|
||||||
bool verify_error = false;
|
|
||||||
while (!verify_error)
|
|
||||||
{
|
{
|
||||||
switch (regs[1] & 3)
|
while (length--)
|
||||||
{
|
{
|
||||||
case 0: // C64 -> REU
|
REU_RAM[reu_adr++ & RAM_MASK] = the_cpu->REUReadByte(c64_adr++);
|
||||||
ex_ram[reu_adr & ram_mask] = the_cpu->REUReadByte(c64_adr);
|
|
||||||
break;
|
|
||||||
case 1: // C64 <- REU
|
|
||||||
the_cpu->REUWriteByte(c64_adr, ex_ram[reu_adr & ram_mask]);
|
|
||||||
break;
|
|
||||||
case 2: { // C64 <-> REU
|
|
||||||
uint8_t tmp = the_cpu->REUReadByte(c64_adr);
|
|
||||||
the_cpu->REUWriteByte(c64_adr, ex_ram[reu_adr & ram_mask]);
|
|
||||||
ex_ram[reu_adr & ram_mask] = tmp;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case 3: // Compare
|
}
|
||||||
if (ex_ram[reu_adr & ram_mask] != the_cpu->REUReadByte(c64_adr))
|
else if ((regs[1] & 3) == 1)
|
||||||
|
{
|
||||||
|
while (length--)
|
||||||
|
{
|
||||||
|
the_cpu->REUWriteByte(c64_adr++, REU_RAM[reu_adr++ & RAM_MASK]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((regs[1] & 3) == 2)
|
||||||
|
{
|
||||||
|
while (length--)
|
||||||
|
{
|
||||||
|
uint8_t tmp = the_cpu->REUReadByte(c64_adr);
|
||||||
|
the_cpu->REUWriteByte(c64_adr++, REU_RAM[reu_adr & RAM_MASK]);
|
||||||
|
REU_RAM[reu_adr++ & RAM_MASK] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Compare
|
||||||
|
{
|
||||||
|
while (length--)
|
||||||
|
{
|
||||||
|
if (REU_RAM[reu_adr++ & RAM_MASK] != the_cpu->REUReadByte(c64_adr++))
|
||||||
{
|
{
|
||||||
regs[0] |= 0x20; // Verify error
|
regs[0] |= 0x20; // Verify error
|
||||||
verify_error = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
c64_adr += c64_inc;
|
}
|
||||||
reu_adr += reu_inc;
|
|
||||||
if (--length == 0)
|
|
||||||
{
|
|
||||||
regs[0] |= 0x40; // Transfer finished
|
regs[0] |= 0x40; // Transfer finished
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update address and length registers
|
// Update address and length registers
|
||||||
if (regs[1] & 0x20)
|
if (regs[1] & 0x20)
|
||||||
@ -289,7 +295,7 @@ void REU::execute_dma()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reu_adr &= ram_mask;
|
reu_adr &= RAM_MASK;
|
||||||
regs[2] = c64_adr & 0xff;
|
regs[2] = c64_adr & 0xff;
|
||||||
regs[3] = c64_adr >> 8;
|
regs[3] = c64_adr >> 8;
|
||||||
regs[4] = reu_adr & 0xff;
|
regs[4] = reu_adr & 0xff;
|
||||||
@ -308,7 +314,7 @@ void REU::execute_dma()
|
|||||||
void REU::GetState(REUState *rs)
|
void REU::GetState(REUState *rs)
|
||||||
{
|
{
|
||||||
rs->ram_size = ram_size;
|
rs->ram_size = ram_size;
|
||||||
rs->ram_mask = ram_mask;
|
rs->ram_mask = RAM_MASK;
|
||||||
rs->autoload_c64_adr_lo = autoload_c64_adr_lo;
|
rs->autoload_c64_adr_lo = autoload_c64_adr_lo;
|
||||||
rs->autoload_c64_adr_hi = autoload_c64_adr_hi;
|
rs->autoload_c64_adr_hi = autoload_c64_adr_hi;
|
||||||
rs->autoload_reu_adr_lo = autoload_reu_adr_lo;
|
rs->autoload_reu_adr_lo = autoload_reu_adr_lo;
|
||||||
@ -327,7 +333,7 @@ void REU::GetState(REUState *rs)
|
|||||||
void REU::SetState(REUState *rs)
|
void REU::SetState(REUState *rs)
|
||||||
{
|
{
|
||||||
ram_size = rs->ram_size;
|
ram_size = rs->ram_size;
|
||||||
ram_size = rs->ram_mask;
|
ram_mask = RAM_MASK;
|
||||||
autoload_c64_adr_lo = rs->autoload_c64_adr_lo;
|
autoload_c64_adr_lo = rs->autoload_c64_adr_lo;
|
||||||
autoload_c64_adr_hi = rs->autoload_c64_adr_hi;
|
autoload_c64_adr_hi = rs->autoload_c64_adr_hi;
|
||||||
autoload_reu_adr_lo = rs->autoload_reu_adr_lo;
|
autoload_reu_adr_lo = rs->autoload_reu_adr_lo;
|
||||||
|
@ -1018,7 +1018,7 @@ __attribute__ ((noinline)) ITCM_CODE void MOS6569::el_ecm_text(uint8 *p, uint8
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MOS6569::el_std_idle(uint8 *p, uint8 *r)
|
__attribute__ ((noinline)) ITCM_CODE void MOS6569::el_std_idle(uint8 *p, uint8 *r)
|
||||||
{
|
{
|
||||||
uint8 data = *get_physical(ctrl1 & 0x40 ? 0x39ff : 0x3fff);
|
uint8 data = *get_physical(ctrl1 & 0x40 ? 0x39ff : 0x3fff);
|
||||||
uint32 *lp = (uint32 *)p;
|
uint32 *lp = (uint32 *)p;
|
||||||
@ -1431,7 +1431,7 @@ int MOS6569::EmulateLine(void)
|
|||||||
if (raster >= FIRST_DMA_LINE && raster <= LAST_DMA_LINE && ((raster & 7) == y_scroll) && bad_lines_enabled)
|
if (raster >= FIRST_DMA_LINE && raster <= LAST_DMA_LINE && ((raster & 7) == y_scroll) && bad_lines_enabled)
|
||||||
{
|
{
|
||||||
is_bad_line = true;
|
is_bad_line = true;
|
||||||
cycles_left = BAD_CYCLES_PER_LINE + CycleDeltas[myConfig.cpuCycles];
|
cycles_left = BAD_CYCLES_PER_LINE + CycleDeltas[myConfig.cpuCycles] + CycleDeltas[myConfig.badCycles];
|
||||||
}
|
}
|
||||||
goto VIC_nop;
|
goto VIC_nop;
|
||||||
}
|
}
|
||||||
@ -1452,7 +1452,7 @@ int MOS6569::EmulateLine(void)
|
|||||||
{
|
{
|
||||||
// Turn on display
|
// Turn on display
|
||||||
display_state = is_bad_line = true;
|
display_state = is_bad_line = true;
|
||||||
cycles_left = BAD_CYCLES_PER_LINE + CycleDeltas[myConfig.cpuCycles];
|
cycles_left = BAD_CYCLES_PER_LINE + CycleDeltas[myConfig.cpuCycles] + CycleDeltas[myConfig.badCycles];
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
// Read and latch 40 bytes from video matrix and color RAM
|
// Read and latch 40 bytes from video matrix and color RAM
|
||||||
|
@ -386,7 +386,7 @@ void SetDefaultGameConfig(void)
|
|||||||
myConfig.reserved7 = 0;
|
myConfig.reserved7 = 0;
|
||||||
myConfig.reserved8 = 0xA5; // So it's easy to spot on an "upgrade" and we can re-default it
|
myConfig.reserved8 = 0xA5; // So it's easy to spot on an "upgrade" and we can re-default it
|
||||||
myConfig.cpuCycles = 0; // Normal 63 - this is the delta adjustment to that
|
myConfig.cpuCycles = 0; // Normal 63 - this is the delta adjustment to that
|
||||||
myConfig.flopCycles = 0; // Normal 64 - this is the delta adjustment to that
|
myConfig.badCycles = 0; // Normal 23 - this is the delta adjustment to that
|
||||||
|
|
||||||
myConfig.offsetX = 32; // Push the side border off the main display
|
myConfig.offsetX = 32; // Push the side border off the main display
|
||||||
myConfig.offsetY = 19; // Push the top border off the main display
|
myConfig.offsetY = 19; // Push the top border off the main display
|
||||||
@ -394,7 +394,7 @@ void SetDefaultGameConfig(void)
|
|||||||
myConfig.scaleY = 200; // Scale the 200 pixels of C64 display to the DS 200 (yes, there is only 192 so this will cut... use PAN UP/DN)
|
myConfig.scaleY = 200; // Scale the 200 pixels of C64 display to the DS 200 (yes, there is only 192 so this will cut... use PAN UP/DN)
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 CycleDeltas[] = {0,1,2,3,4,5,6,7,8,9,-9,-8,-7,-6,-5,-4,-3,-2,-1}; // Used with myConfig.cpuCycles and myConfig.flopCycles
|
s16 CycleDeltas[] = {0,1,2,3,4,5,6,7,8,9,-9,-8,-7,-6,-5,-4,-3,-2,-1}; // Used with myConfig.cpuCycles and myConfig.badCycles
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Read file twice and ensure we get the same CRC... if not, do it again
|
// Read file twice and ensure we get the same CRC... if not, do it again
|
||||||
@ -592,7 +592,7 @@ const struct options_t Option_Table[1][20] =
|
|||||||
{"LCD JITTER", {"NONE", "LIGHT", "HEAVY"}, &myConfig.jitter, 3},
|
{"LCD JITTER", {"NONE", "LIGHT", "HEAVY"}, &myConfig.jitter, 3},
|
||||||
{"DISK SOUND", {"SFX OFF", "SFX ON"}, &myConfig.diskSFX, 2},
|
{"DISK SOUND", {"SFX OFF", "SFX ON"}, &myConfig.diskSFX, 2},
|
||||||
{"CPU CYCLES", {CYCLE_DELTA_STR}, &myConfig.cpuCycles, 19},
|
{"CPU CYCLES", {CYCLE_DELTA_STR}, &myConfig.cpuCycles, 19},
|
||||||
{"1541 CYCLES", {CYCLE_DELTA_STR}, &myConfig.flopCycles, 19},
|
{"BAD CYCLES" , {CYCLE_DELTA_STR}, &myConfig.badCycles, 19},
|
||||||
{"POUND KEY", {"POUND", "LEFT ARROW", "UP ARROW", "C= COMMODORE"}, &myConfig.poundKey, 4},
|
{"POUND KEY", {"POUND", "LEFT ARROW", "UP ARROW", "C= COMMODORE"}, &myConfig.poundKey, 4},
|
||||||
|
|
||||||
{"D-PAD UP", {KEY_MAP_OPTIONS}, &myConfig.key_map[0], 65},
|
{"D-PAD UP", {KEY_MAP_OPTIONS}, &myConfig.key_map[0], 65},
|
||||||
|
@ -21,7 +21,7 @@ struct __attribute__((__packed__)) Config_t
|
|||||||
u8 reserved7;
|
u8 reserved7;
|
||||||
u8 reserved8;
|
u8 reserved8;
|
||||||
u8 cpuCycles;
|
u8 cpuCycles;
|
||||||
u8 flopCycles;
|
u8 badCycles;
|
||||||
s8 offsetX;
|
s8 offsetX;
|
||||||
s8 offsetY;
|
s8 offsetY;
|
||||||
s16 scaleX;
|
s16 scaleX;
|
||||||
|
Loading…
Reference in New Issue
Block a user