diff --git a/source/cart_hw/cart_hw.c b/source/cart_hw/cart_hw.c index dfd45e3..c034c8a 100644 --- a/source/cart_hw/cart_hw.c +++ b/source/cart_hw/cart_hw.c @@ -472,7 +472,7 @@ void cart_hw_reset() break; case TYPE_AR: - datel_reset(); + datel_reset(1); break; case TYPE_SK: diff --git a/source/cart_hw/datel.c b/source/cart_hw/datel.c index 8edd9bc..1e25ee8 100644 --- a/source/cart_hw/datel.c +++ b/source/cart_hw/datel.c @@ -64,7 +64,7 @@ void datel_init(void) { case TYPE_AR: { - /* internal registers mapped at $0000-$ffff */ + /* internal registers mapped at $010000-$01ffff */ m68k_memory_map[0x01].write16 = ar_write_regs; /* $0000-$7fff mirrored into $8000-$ffff */ @@ -74,18 +74,15 @@ void datel_init(void) case TYPE_PRO1: { - /* internal registers mapped at $0000-$ffff */ + /* internal registers mapped at $010000-$01ffff */ m68k_memory_map[0x01].write16 = ar_write_regs; - /* RAM (64k) mapped at $400000-$7fffff */ - for (i=0x40; i<0x80; i++) - { - m68k_memory_map[i].base = action_replay.ram; - m68k_memory_map[i].read8 = NULL; - m68k_memory_map[i].read16 = NULL; - m68k_memory_map[i].write8 = NULL; - m68k_memory_map[i].write16 = NULL; - } + /* RAM (64k) mapped at $420000-$42ffff */ + m68k_memory_map[0x42].base = action_replay.ram; + m68k_memory_map[0x42].read8 = NULL; + m68k_memory_map[0x42].read16 = NULL; + m68k_memory_map[0x42].write8 = NULL; + m68k_memory_map[0x42].write16 = NULL; break; } @@ -94,15 +91,12 @@ void datel_init(void) /* internal registers mapped at $100000-$10ffff */ m68k_memory_map[0x10].write16 = ar_write_regs_pro2; - /* RAM (64k) mapped at $400000-$7fffff */ - for (i=0x40; i<0x80; i++) - { - m68k_memory_map[i].base = action_replay.ram; - m68k_memory_map[i].read8 = NULL; - m68k_memory_map[i].read16 = NULL; - m68k_memory_map[i].write8 = NULL; - m68k_memory_map[i].write16 = NULL; - } + /* RAM (64k) mapped at $600000-$60ffff */ + m68k_memory_map[0x60].base = action_replay.ram; + m68k_memory_map[0x60].read8 = NULL; + m68k_memory_map[0x60].read16 = NULL; + m68k_memory_map[0x60].write8 = NULL; + m68k_memory_map[0x60].write16 = NULL; break; } } @@ -119,10 +113,16 @@ void datel_init(void) #endif } -void datel_reset(void) +void datel_reset(int hard_reset) { if (action_replay.enabled) { + if (hard_reset) + { + /* clear RAM */ + memset(action_replay.ram,0,sizeof(action_replay.ram)); + } + /* reset codes */ datel_switch(0); @@ -133,33 +133,26 @@ void datel_reset(void) memset(action_replay.addr,0,sizeof(action_replay.addr)); /* ROM mapped at $000000-$3fffff */ - int i; switch (action_replay.enabled) { case TYPE_AR: /* 32k ROM */ case TYPE_PRO2: /* 64k ROM */ { - for (i=0x00; i<0x40; i++) - { - m68k_memory_map[i].base = action_replay.rom; - } + m68k_memory_map[0].base = action_replay.rom; break; } case TYPE_PRO1: /* 128k ROM */ { - for (i=0x00; i<0x40; i+=2) - { - m68k_memory_map[i].base = action_replay.rom; - m68k_memory_map[i+1].base = action_replay.rom + 0x10000; - } + m68k_memory_map[0].base = action_replay.rom; + m68k_memory_map[1].base = action_replay.rom + 0x10000; break; } } } } -void datel_switch(uint8 enable) +void datel_switch(int enable) { int i; if (enable) @@ -214,6 +207,13 @@ void datel_switch(uint8 enable) *(uint16 *)(work_ram + (action_replay.addr[i]&0xffff)) = action_replay.old[i]; } } + + /* set default Work RAM write handlers */ + for (i=0xe0; i<0x100; i++) + { + m68k_memory_map[i].write8 = NULL; + m68k_memory_map[i].write16 = NULL; + } } } @@ -280,18 +280,17 @@ static void ar_write_regs(uint32 address, uint32 data) action_replay.addr[2] = (action_replay.regs[8] | ((action_replay.regs[9] & 0x7f00) << 8)) << 1; action_replay.addr[3] = (action_replay.regs[11] | ((action_replay.regs[12] & 0x7f00) << 8)) << 1; - /* Cartridge ROM mapped to $000000-$3fffff */ + /* Enable Cartridge ROM */ /* NOTE: codes should be disabled on startup */ - int i; - for (i=0x00; i<0x40; i++) - { - m68k_memory_map[i].base = cart.rom + ((i<<16) & cart.mask); - } + m68k_memory_map[0].base = cart.rom; + m68k_memory_map[1].base = cart.rom + ((1<<16) & cart.mask); } } static void ar_write_regs_pro2(uint32 address, uint32 data) { - /* TODO */ -} + /* Enable Cartridge ROM */ + if (((address & 0xff) == 0x78) && (data == 0xffff)) + m68k_memory_map[0].base = cart.rom; +} \ No newline at end of file diff --git a/source/cart_hw/datel.h b/source/cart_hw/datel.h index 4ca57dd..7edd3a6 100644 --- a/source/cart_hw/datel.h +++ b/source/cart_hw/datel.h @@ -23,7 +23,7 @@ #define _DATEL_H_ extern void datel_init(void); -extern void datel_reset(void); -extern void datel_switch(uint8 enable); +extern void datel_reset(int hard_reset); +extern void datel_switch(int enable); #endif diff --git a/source/genesis.c b/source/genesis.c index 5b9e5cf..b05dd08 100644 --- a/source/genesis.c +++ b/source/genesis.c @@ -42,12 +42,12 @@ void set_softreset(void) resetline = (int) ((double) (lines_per_frame - 1) * rand() / (RAND_MAX + 1.0)); } -void gen_init (void) +void gen_init(void) { int i; /* initialize CPUs */ - m68k_set_cpu_type (M68K_CPU_TYPE_68000); + m68k_set_cpu_type(M68K_CPU_TYPE_68000); m68k_init(); z80_init(0,0,0,z80_irq_callback); @@ -113,33 +113,18 @@ void gen_init (void) } /* VDP */ - m68k_memory_map[0xc0].read8 = vdp_read_byte; - m68k_memory_map[0xc0].read16 = vdp_read_word; - m68k_memory_map[0xc0].write8 = vdp_write_byte; - m68k_memory_map[0xc0].write16 = vdp_write_word; - m68k_memory_map[0xc8].read8 = vdp_read_byte; - m68k_memory_map[0xc8].read16 = vdp_read_word; - m68k_memory_map[0xc8].write8 = vdp_write_byte; - m68k_memory_map[0xc8].write16 = vdp_write_word; - m68k_memory_map[0xd0].read8 = vdp_read_byte; - m68k_memory_map[0xd0].read16 = vdp_read_word; - m68k_memory_map[0xd0].write8 = vdp_write_byte; - m68k_memory_map[0xd0].write16 = vdp_write_word; - m68k_memory_map[0xd8].read8 = vdp_read_byte; - m68k_memory_map[0xd8].read16 = vdp_read_word; - m68k_memory_map[0xd8].write8 = vdp_write_byte; - m68k_memory_map[0xd8].write16 = vdp_write_word; - zbank_memory_map[0xc0].read = zbank_read_vdp; - zbank_memory_map[0xc0].write = zbank_write_vdp; - zbank_memory_map[0xc8].read = zbank_read_vdp; - zbank_memory_map[0xc8].write = zbank_write_vdp; - zbank_memory_map[0xd0].read = zbank_read_vdp; - zbank_memory_map[0xd0].write = zbank_write_vdp; - zbank_memory_map[0xd8].read = zbank_read_vdp; - zbank_memory_map[0xd8].write = zbank_write_vdp; + for (i=0xc0; i<0xe0; i+=8) + { + m68k_memory_map[i].read8 = vdp_read_byte; + m68k_memory_map[i].read16 = vdp_read_word; + m68k_memory_map[i].write8 = vdp_write_byte; + m68k_memory_map[i].write16 = vdp_write_word; + zbank_memory_map[i].read = zbank_read_vdp; + zbank_memory_map[i].write = zbank_write_vdp; + } } -void gen_reset (uint32 hard_reset) +void gen_reset(uint32 hard_reset) { if (hard_reset) { @@ -152,30 +137,30 @@ void gen_reset (uint32 hard_reset) { m68k_memory_map[0].base = bios_rom; } + + count_m68k = 0; + count_z80 = 0; + gen_running = 1; /* System is running */ + zreset = 0; /* Z80 is reset */ + zbusreq = 0; /* Z80 has control of the Z bus */ + zbusack = 1; /* Z80 is busy using the Z bus */ + zirq = 0; /* No interrupts occuring */ + zbank = 0; /* Assume default bank is $000000-$007FFF */ } - gen_running = 1; resetline = -1; - #ifdef NGC /* register SOFTRESET */ SYS_SetResetCallback(set_softreset); #endif - zreset = 0; /* Z80 is reset */ - zbusreq = 0; /* Z80 has control of the Z bus */ - zbusack = 1; /* Z80 is busy using the Z bus */ - zirq = 0; /* No interrupts occuring */ - zbank = 0; /* Assume default bank is 000000-007FFF */ - - /* Reset CPUs */ - m68k_pulse_reset (); - z80_reset (); - YM2612ResetChip(); - SN76489_Reset(); + /* reset CPUs */ + m68k_pulse_reset(); + z80_reset(); + fm_reset(); } -void gen_shutdown (void) +void gen_shutdown(void) { z80_exit(); } @@ -183,7 +168,7 @@ void gen_shutdown (void) /*----------------------------------------------------------------------- Bus controller chip functions -----------------------------------------------------------------------*/ -void gen_busreq_w (uint32 state) +void gen_busreq_w(uint32 state) { uint32 z80_cycles_to_run; @@ -217,7 +202,7 @@ void gen_busreq_w (uint32 state) zbusack = 1 ^ (zbusreq & zreset); } -void gen_reset_w (uint32 state) +void gen_reset_w(uint32 state) { uint32 z80_cycles_to_run; @@ -247,8 +232,8 @@ void gen_reset_w (uint32 state) } /* Reset Z80 & YM2612 */ - z80_reset (); - YM2612ResetChip(); + z80_reset(); + fm_reset(); } zreset = state; diff --git a/source/m68k/m68kconf.h b/source/m68k/m68kconf.h index 068c634..55d53ab 100644 --- a/source/m68k/m68kconf.h +++ b/source/m68k/m68kconf.h @@ -160,6 +160,14 @@ #define M68K_EMULATE_ADDRESS_ERROR OPT_ON +/* If ON, branch instructions will check for infinite loop and + * freeze current CPU execution . + * Unnecessary checking might be disabled to improve instruction + * emulation speed since infinite loops are going to "lock" the CPU + * execution anyway. + */ +#define M68K_CHECK_INFINITE_LOOP OPT_OFF + /* Turn ON to enable logging of illegal instruction calls. * M68K_LOG_FILEHANDLE must be #defined to a stdio file stream. * Turn on M68K_LOG_1010_1111 to log all 1010 and 1111 calls. diff --git a/source/m68k/m68kcpu.c b/source/m68k/m68kcpu.c index 9bac5b7..89f15ef 100644 --- a/source/m68k/m68kcpu.c +++ b/source/m68k/m68kcpu.c @@ -854,6 +854,7 @@ void m68k_run (int cyc) if(CPU_STOPPED) { count_m68k = cyc; + REG_PPC = REG_PC; return; } diff --git a/source/m68k/m68kcpu.h b/source/m68k/m68kcpu.h index f230f7a..1d4ae5f 100644 --- a/source/m68k/m68kcpu.h +++ b/source/m68k/m68kcpu.h @@ -304,7 +304,7 @@ extern unsigned int count_m68k; #define REG_DA m68ki_cpu.dar /* easy access to data and address regs */ #define REG_D m68ki_cpu.dar #define REG_A (m68ki_cpu.dar+8) -#define REG_PPC m68ki_cpu.ppc +#define REG_PPC m68ki_cpu.ppc #define REG_PC m68ki_cpu.pc #define REG_SP_BASE m68ki_cpu.sp #define REG_USP m68ki_cpu.sp[0] @@ -606,6 +606,12 @@ extern unsigned int count_m68k; #define M68K_DO_LOG_EMU(A) #endif +#if M68K_CHECK_INFINITE_LOOP + #define m68ki_check_infinite_loop() if(REG_PC == REG_PPC) USE_ALL_CYCLES() +#else + #define m68ki_check_infinite_loop() +#endif /* M68K_CHECK_INFINITE_LOOP */ + /* -------------------------- EA / Operand Access ------------------------- */ diff --git a/source/m68k/m68kops.c b/source/m68k/m68kops.c index 4db4a0e..e9d5fb2 100644 --- a/source/m68k/m68kops.c +++ b/source/m68k/m68kops.c @@ -8067,8 +8067,7 @@ static void m68k_op_bra_8(void) { m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -8078,8 +8077,7 @@ static void m68k_op_bra_16(void) REG_PC -= 2; m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ m68ki_branch_16(offset); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -8091,16 +8089,14 @@ static void m68k_op_bra_32(void) REG_PC -= 4; m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ m68ki_branch_32(offset); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ return; } else { m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ m68ki_branch_8(MASK_OUT_ABOVE_8(REG_IR)); - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } } @@ -16542,8 +16538,7 @@ static void m68k_op_jmp_32_ai(void) { m68ki_jump(EA_AY_AI_32()); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -16551,8 +16546,7 @@ static void m68k_op_jmp_32_di(void) { m68ki_jump(EA_AY_DI_32()); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -16560,8 +16554,7 @@ static void m68k_op_jmp_32_ix(void) { m68ki_jump(EA_AY_IX_32()); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -16569,8 +16562,7 @@ static void m68k_op_jmp_32_aw(void) { m68ki_jump(EA_AW_32()); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -16578,8 +16570,7 @@ static void m68k_op_jmp_32_al(void) { m68ki_jump(EA_AL_32()); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -16587,8 +16578,7 @@ static void m68k_op_jmp_32_pcdi(void) { m68ki_jump(EA_PCDI_32()); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } @@ -16596,8 +16586,7 @@ static void m68k_op_jmp_32_pcix(void) { m68ki_jump(EA_PCIX_32()); m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */ - if(REG_PC == REG_PPC) - USE_ALL_CYCLES(); + m68ki_check_infinite_loop(); /* auto-disable (see m68kcpu.h) */ } diff --git a/source/sound/Fir_Resampler.c b/source/sound/Fir_Resampler.c index 6d80ef1..e48aa40 100644 --- a/source/sound/Fir_Resampler.c +++ b/source/sound/Fir_Resampler.c @@ -76,11 +76,10 @@ static int available( unsigned long input_count ) int Fir_Resampler_initialize( int new_size ) { buffer = (sample_t *) realloc( buffer, (new_size + WRITE_OFFSET) * sizeof (sample_t) ); + write_pos = 0; if ( !buffer && new_size ) return 0; buffer_size = new_size + WRITE_OFFSET; - write_pos = 0; res = 1; - imp_phase = 0; skip_bits = 0; step = STEREO; ratio = 1.0; @@ -206,62 +205,61 @@ int Fir_Resampler_read( sample_t** out, unsigned long count ) sample_t const* imp = impulses [imp_phase]; int remain = res - imp_phase; int n; - + int pt0,pt1; + sample_t* i; + unsigned long l,r; + if ( end_pos - in >= WIDTH * STEREO ) { end_pos -= WIDTH * STEREO; do { - count--; - /* accumulate in extended precision */ - unsigned long l = 0; - unsigned long r = 0; - - const sample_t* i = in; - if ( count < 0 ) - break; - + l = 0; + r = 0; + + i = in; + for ( n = WIDTH / 2; n; --n ) { - int pt0 = imp [0]; + pt0 = imp [0]; l += pt0 * i [0]; r += pt0 * i [1]; - int pt1 = imp [1]; + pt1 = imp [1]; imp += 2; l += pt1 * i [2]; r += pt1 * i [3]; i += 4; } - + remain--; - + l >>= 15; r >>= 15; - + in += (skip * STEREO) & STEREO; skip >>= 1; in += step; - + if ( !remain ) { imp = impulses [0]; skip = skip_bits; remain = res; } - + *out_l++ = (sample_t) l; *out_r++ = (sample_t) r; } - while ( in <= end_pos ); + while ( (in <= end_pos) && (--count > 0) ); } - + imp_phase = res - remain; - + int left = write_pos - in; write_pos = &buffer [left]; memmove( buffer, in, left * sizeof *in ); - + return out_l - out[0]; } diff --git a/source/sound/sound.c b/source/sound/sound.c index 4c51fcc..0c28ff4 100644 --- a/source/sound/sound.c +++ b/source/sound/sound.c @@ -40,7 +40,7 @@ static inline int psg_sample_cnt(uint8 z80) else return ((count_m68k / m68cycles_per_sample[1]) - snd.psg.pos); } -/* update FM samples */ +/* run FM chip for n samples */ static inline void fm_update(int cnt) { if (cnt > 0) @@ -50,7 +50,7 @@ static inline void fm_update(int cnt) } } -/* update PSG samples */ +/* run PSG chip for n samples */ static inline void psg_update(int cnt) { if (cnt > 0) @@ -60,6 +60,7 @@ static inline void psg_update(int cnt) } } +/* initialize sound chips emulation */ void sound_init(int rate) { double vclk = (vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC) / 7.0; /* 68000 and YM2612 clock */ @@ -96,6 +97,13 @@ void sound_update(int fm_len, int psg_len) snd.psg.pos = 0; } +/* reset FM chip */ +void fm_reset(void) +{ + fm_update(fm_sample_cnt(0)); + YM2612ResetChip(); +} + /* write FM chip */ void fm_write(unsigned int cpu, unsigned int address, unsigned int data) { @@ -110,8 +118,7 @@ unsigned int fm_read(unsigned int cpu, unsigned int address) return YM2612Read(); } - -/* PSG write */ +/* write PSG chip */ void psg_write(unsigned int cpu, unsigned int data) { psg_update(psg_sample_cnt(cpu)); diff --git a/source/sound/sound.h b/source/sound/sound.h index 13182dd..a39ae0e 100644 --- a/source/sound/sound.h +++ b/source/sound/sound.h @@ -27,6 +27,7 @@ /* Function prototypes */ extern void sound_init(int rate); extern void sound_update(int fm_len, int psg_len); +extern void fm_reset(void); extern void fm_write(unsigned int cpu, unsigned int address, unsigned int data); extern unsigned int fm_read(unsigned int cpu, unsigned int address); extern void psg_write(unsigned int cpu, unsigned int data); diff --git a/source/system.c b/source/system.c index 85b5ca6..f83fe4c 100644 --- a/source/system.c +++ b/source/system.c @@ -78,7 +78,7 @@ void audio_update (int size) /* resampling */ if (config.hq_fm) { - int len = Fir_Resampler_input_needed(size * 2); + int len = Fir_Resampler_input_needed(size << 1); sound_update(len >> 1,size); Fir_Resampler_write(len); Fir_Resampler_read(fm,size); @@ -209,9 +209,9 @@ void audio_shutdown(void) void system_init (void) { /* Genesis hardware */ - gen_init (); - vdp_init (); - render_init (); + gen_init(); + vdp_init(); + render_init(); io_init(); /* Cartridge hardware */ @@ -227,9 +227,10 @@ void system_reset (void) cart_hw_reset(); /* Genesis hardware */ - gen_reset (1); - vdp_reset (); - render_reset (); + gen_reset(1); + SN76489_Reset(); + vdp_reset(); + render_reset(); io_reset(); /* Clear Sound Buffers */ @@ -321,6 +322,10 @@ int system_frame (int do_skip) /* wait for RESET button to be released */ while (SYS_ResetButtonDown()); #endif + /* Pro Action Replay (switch at "Trainer" position) */ + if (config.lock_on == TYPE_AR) + datel_reset(0); + gen_reset(0); } diff --git a/source/vdp.c b/source/vdp.c index ac39346..45b24b8 100644 --- a/source/vdp.c +++ b/source/vdp.c @@ -211,7 +211,7 @@ void vdp_reset(void) bitmap.viewport.ow = 224; /* reset border area */ - bitmap.viewport.x = (reg[12] & 1) ? 16 : 12; + bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0; bitmap.viewport.y = config.overscan ? (vdp_pal ? 32 : 8) : 0; bitmap.viewport.changed = 1; @@ -245,7 +245,7 @@ void vdp_restore(uint8 *vdp_regs) hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32; /* reinitialize overscan area */ - bitmap.viewport.x = (reg[12] & 1) ? 16 : 12; + bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0; bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0; bitmap.viewport.changed = 1; @@ -685,10 +685,7 @@ static inline void reg_w(unsigned int r, unsigned int d) /* update viewport */ bitmap.viewport.changed = 1; bitmap.viewport.h = (d & 8) ? 240 : 224; - if (config.overscan) - { - bitmap.viewport.y = ((vdp_pal ? 288 : 240) - bitmap.viewport.h) / 2; - } + if (config.overscan) bitmap.viewport.y = ((vdp_pal ? 288 : 240) - bitmap.viewport.h) / 2; /* update VC table */ if (vdp_pal) vctab = (d & 8) ? vc_pal_240 : vc_pal_224;