diff --git a/source/cd_hw/scd.c b/source/cd_hw/scd.c index c8b6574..8ec9347 100644 --- a/source/cd_hw/scd.c +++ b/source/cd_hw/scd.c @@ -92,6 +92,12 @@ void prg_ram_dma_w(unsigned int words) /* update DMA source address */ cdc.dac.w += (words << 1); + /* check PRG-RAM write protected area */ + if (dst_index < (scd.regs[0x02>>1].byte.h << 9)) + { + return; + } + /* DMA transfer */ while (words--) { diff --git a/source/genesis.c b/source/genesis.c index e8fd34c..cac055e 100644 --- a/source/genesis.c +++ b/source/genesis.c @@ -327,8 +327,33 @@ void gen_reset(int hard_reset) /* reset Z80 */ z80_reset(); -} + /* some Z80 registers need to be initialized on Power ON */ + if (hard_reset) + { + /* Power Base Converter specific */ + if (system_hw == SYSTEM_PBC) + { + /* startup code logic (verified on real hardware): */ + /* 21 01 E1 : LD HL, $E101 + 25 -- -- : DEC H + F9 -- -- : LD SP,HL + C7 -- -- : RST $00 + 01 01 -- : LD BC, $xx01 + */ + Z80.hl.w.l = 0xE001; + Z80.sp.w.l = 0xDFFF; + Z80.r = 4; + } + + /* Master System specific (when BIOS is disabled) */ + else if ((system_hw & SYSTEM_SMS) && (!(config.bios & 1) || !(system_bios & SYSTEM_SMS))) + { + /* usually done by BIOS & required by some SMS games that don't initialize SP */ + Z80.sp.w.l = 0xDFFF; + } + } +} /*-----------------------------------------------------------------------*/ /* OS ROM / TMSS register control functions (Genesis mode) */ diff --git a/source/m68k/m68kcpu.h b/source/m68k/m68kcpu.h index a65033b..317f2cd 100644 --- a/source/m68k/m68kcpu.h +++ b/source/m68k/m68kcpu.h @@ -1070,28 +1070,36 @@ INLINE uint OPER_PCIX_32(void) {uint ea = EA_PCIX_32(); return m68ki_read_pcre /* ---------------------------- Stack Functions --------------------------- */ /* Push/pull data from the stack */ +/* Optimized access assuming stack is always located in ROM/RAM [EkeEke] */ INLINE void m68ki_push_16(uint value) { REG_SP = MASK_OUT_ABOVE_32(REG_SP - 2); - m68ki_write_16(REG_SP, value); + /*m68ki_write_16(REG_SP, value);*/ + *(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value; } INLINE void m68ki_push_32(uint value) { REG_SP = MASK_OUT_ABOVE_32(REG_SP - 4); - m68ki_write_32(REG_SP, value); + /*m68ki_write_32(REG_SP, value);*/ + *(uint16 *)(m68ki_cpu.memory_map[(REG_SP>>16)&0xff].base + (REG_SP & 0xffff)) = value >> 16; + *(uint16 *)(m68ki_cpu.memory_map[((REG_SP + 2)>>16)&0xff].base + ((REG_SP + 2) & 0xffff)) = value & 0xffff; } INLINE uint m68ki_pull_16(void) { + uint sp = REG_SP; REG_SP = MASK_OUT_ABOVE_32(REG_SP + 2); - return m68ki_read_16(REG_SP-2); + return m68k_read_immediate_16(sp); + /*return m68ki_read_16(sp);*/ } INLINE uint m68ki_pull_32(void) { + uint sp = REG_SP; REG_SP = MASK_OUT_ABOVE_32(REG_SP + 4); - return m68ki_read_32(REG_SP-4); + return m68k_read_immediate_32(sp); + /*return m68ki_read_32(sp);*/ } diff --git a/source/mem68k.c b/source/mem68k.c index 499cceb..5798d75 100644 --- a/source/mem68k.c +++ b/source/mem68k.c @@ -650,6 +650,12 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data) return; } + case 0x02: /* PRG-RAM Write Protection */ + { + scd.regs[0x02>>1].byte.h = data; + return; + } + case 0x03: /* Memory mode */ { m68k_poll_sync(0x02); diff --git a/source/z80/z80.c b/source/z80/z80.c index cb11685..7a1754d 100644 --- a/source/z80/z80.c +++ b/source/z80/z80.c @@ -31,6 +31,7 @@ * This Z80 emulator assumes a ZiLOG NMOS model. * * Additional changes [Eke-Eke]: + * - Removed z80_burn function (unused) * - Discarded multi-chip support (unused) * - Fixed cycle counting for FD and DD prefixed instructions * - Fixed behavior of chained FD and DD prefixes (R register should be only incremented by one @@ -3358,11 +3359,9 @@ void z80_init(const void *config, int (*irqcallback)(int)) Z80.daisy = config; Z80.irq_callback = irqcallback; - /* Reset registers to their initial values (NB: should be random on real hardware) */ - AF = BC = DE = HL = 0; + /* Clear registers values (NB: should be random on real hardware ?) */ + AF = BC = DE = HL = SP = IX = IY =0; F = ZF; /* Zero flag is set */ - IX = IY = 0xffff; /* IX and IY are FFFF after a reset! (from MAME) */ - SP = 0xdfff; /* required by some SMS games that don't initialize SP */ /* setup cycle tables */ cc[Z80_TABLE_op] = cc_op; @@ -3411,20 +3410,6 @@ void z80_run(unsigned int cycles) } } -/**************************************************************************** - * Burn 'cycles' T-states. Adjust R register for the lost time - ****************************************************************************/ -void z80_burn(unsigned int cycles) -{ - if( cycles > 0 ) - { - /* NOP takes 4 cycles per instruction */ - int n = (cycles + 3) / 4; - R += n; - Z80.cycles += 4 * n * 15; - } -} - /**************************************************************************** * Get all registers in given buffer ****************************************************************************/ diff --git a/source/z80/z80.h b/source/z80/z80.h index 49d361a..d505775 100644 --- a/source/z80/z80.h +++ b/source/z80/z80.h @@ -62,7 +62,6 @@ extern unsigned char (*z80_readport)(unsigned int port); extern void z80_init(const void *config, int (*irqcallback)(int)); extern void z80_reset (void); extern void z80_run(unsigned int cycles); -extern void z80_burn(unsigned int cycles); extern void z80_get_context (void *dst); extern void z80_set_context (void *src); extern void z80_set_irq_line(unsigned int state);