From f4f860e763cf1192bf50a2268c1eb3b38fb49428 Mon Sep 17 00:00:00 2001 From: EkeEke Date: Thu, 27 Jun 2013 01:46:17 +0200 Subject: [PATCH 1/7] [Core/SCD] fixed CDD seek command again (Final Fight CD freeze with model 2 BIOS) --- core/cd_hw/cdd.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/core/cd_hw/cdd.c b/core/cd_hw/cdd.c index 1e63e1e..cee5e66 100644 --- a/core/cd_hw/cdd.c +++ b/core/cd_hw/cdd.c @@ -1230,8 +1230,20 @@ void cdd_process(void) { case 0x00: /* Drive Status */ { - /* RS1-RS8 unchanged */ + /* RS1-RS8 normally unchanged */ scd.regs[0x38>>1].byte.h = cdd.status; + + /* unless RS1 indicated invalid track infos */ + if (scd.regs[0x38>>1].byte.l == 0x0f) + { + /* and SEEK has ended */ + if (cdd.status != CD_SEEK) + { + /* then return valid track infos, e.g current track number in RS2-RS3 (fixes Lunar - The Silver Star) */ + scd.regs[0x38>>1].byte.l = 0x02; + scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[cdd.index + 1] : 0x0A0A; + } + } break; } @@ -1482,13 +1494,13 @@ void cdd_process(void) /* update status */ cdd.status = CD_SEEK; - /* return track index in RS2-RS3 (note: returning RS1=0x0f breaks Lunar - The Silver Star) */ - scd.regs[0x38>>1].w = (CD_SEEK << 8) | 0x02; - scd.regs[0x3a>>1].w = (cdd.index < cdd.toc.last) ? lut_BCD_16[index + 1] : 0x0A0A; + /* unknown RS1-RS8 values (returning 0xF in RS1 invalidates track infos in RS2-RS8 and fixes Final Fight CD intro when seek time is emulated) */ + scd.regs[0x38>>1].w = (CD_SEEK << 8) | 0x0f; + scd.regs[0x3a>>1].w = 0x0000; scd.regs[0x3c>>1].w = 0x0000; scd.regs[0x3e>>1].w = 0x0000; - scd.regs[0x40>>1].byte.h = 0x00; - break; + scd.regs[0x40>>1].w = ~(CD_SEEK + 0xf) & 0x0f; + return; } case 0x06: /* Pause */ @@ -1539,16 +1551,9 @@ void cdd_process(void) /* no audio track playing */ scd.regs[0x36>>1].byte.h = 0x01; - /* update status */ - cdd.status = CD_READY; - - /* unknown RS0-RS8 values (returning 0xF in RS1 invalidates track infos usually returned in RS2-RS8, also fixes Final Fight CD intro when seek time is emulated) */ - scd.regs[0x38>>1].w = (CD_READY << 8) | 0x0f; - scd.regs[0x3a>>1].w = 0x0000; - scd.regs[0x3c>>1].w = 0x0000; - scd.regs[0x3e>>1].w = 0x0000; - scd.regs[0x40>>1].w = ~(CD_READY + 0xf) & 0x0f; - return; + /* update status (RS1-RS8 unchanged) */ + cdd.status = scd.regs[0x38>>1].byte.h = CD_READY; + break; } case 0x0c: /* Close Tray */ From c5cc7d93afb9a5cc042d173c40c111ad2667d391 Mon Sep 17 00:00:00 2001 From: EkeEke Date: Thu, 27 Jun 2013 01:49:10 +0200 Subject: [PATCH 2/7] [Core/Input] added support for XE-A1P analog controller on both ports --- core/input_hw/activator.c | 8 ++--- core/input_hw/input.c | 13 +++++-- core/input_hw/paddle.c | 4 +-- core/input_hw/sportspad.c | 8 ++--- core/input_hw/xe_a1p.c | 74 +++++++++++++++++++++++++-------------- core/input_hw/xe_a1p.h | 8 +++-- core/io_ctrl.c | 11 ++++-- gx/gui/menu.c | 6 ---- 8 files changed, 82 insertions(+), 50 deletions(-) diff --git a/core/input_hw/activator.c b/core/input_hw/activator.c index f6fbdc9..2af22db 100644 --- a/core/input_hw/activator.c +++ b/core/input_hw/activator.c @@ -51,15 +51,15 @@ void activator_reset(int index) activator[index].Counter = 0; } -INLINE unsigned char activator_read(int port) +INLINE unsigned char activator_read(int index) { /* IR sensors 1-16 data (active low) */ - uint16 data = ~input.pad[port << 2]; + uint16 data = ~input.pad[index << 2]; /* D1 = D0 (data is ready) */ - uint8 temp = (activator[port].State & 0x01) << 1; + uint8 temp = (activator[index].State & 0x01) << 1; - switch (activator[port].Counter) + switch (activator[index].Counter) { case 0: /* x x x x 0 1 0 0 */ temp |= 0x04; diff --git a/core/input_hw/input.c b/core/input_hw/input.c index 3ddced7..4506c1a 100644 --- a/core/input_hw/input.c +++ b/core/input_hw/input.c @@ -198,6 +198,13 @@ void input_init(void) break; } + case SYSTEM_XE_A1P: + { + input.dev[4] = DEVICE_XE_A1P; + player++; + break; + } + case SYSTEM_MENACER: { input.dev[4] = DEVICE_LIGHTGUN; @@ -305,19 +312,19 @@ void input_reset(void) case DEVICE_XE_A1P: { - xe_a1p_reset(); + xe_a1p_reset(i); break; } case DEVICE_PADDLE: { - paddle_reset(i >> 2); + paddle_reset(i); break; } case DEVICE_SPORTSPAD: { - sportspad_reset(i >> 2); + sportspad_reset(i); break; } diff --git a/core/input_hw/paddle.c b/core/input_hw/paddle.c index 93f500f..2fa7093 100644 --- a/core/input_hw/paddle.c +++ b/core/input_hw/paddle.c @@ -45,8 +45,8 @@ static struct void paddle_reset(int index) { - input.analog[index << 2][0] = 128; - paddle[index].State = 0x40; + input.analog[index][0] = 128; + paddle[index>>2].State = 0x40; } INLINE unsigned char paddle_read(int port) diff --git a/core/input_hw/sportspad.c b/core/input_hw/sportspad.c index 03e176e..48154e1 100644 --- a/core/input_hw/sportspad.c +++ b/core/input_hw/sportspad.c @@ -46,10 +46,10 @@ static struct void sportspad_reset(int index) { - input.analog[index << 2][0] = 128; - input.analog[index << 2][1] = 128; - sportspad[index].State = 0x40; - sportspad[index].Counter = 0; + input.analog[index][0] = 128; + input.analog[index][1] = 128; + sportspad[index>>2].State = 0x40; + sportspad[index>>2].Counter = 0; } INLINE unsigned char sportspad_read(int port) diff --git a/core/input_hw/xe_a1p.c b/core/input_hw/xe_a1p.c index 0cb702f..8821ff9 100644 --- a/core/input_hw/xe_a1p.c +++ b/core/input_hw/xe_a1p.c @@ -43,39 +43,41 @@ static struct uint8 State; uint8 Counter; uint8 Latency; -} xe_a1p; +} xe_a1p[2]; -void xe_a1p_reset(void) +void xe_a1p_reset(int index) { - input.analog[0][0] = 128; - input.analog[0][1] = 128; - input.analog[1][0] = 128; - xe_a1p.State = 0x40; - xe_a1p.Counter = 0; - xe_a1p.Latency = 0; + input.analog[index][0] = 128; + input.analog[index][1] = 128; + input.analog[index+1][0] = 128; + index >>= 2; + xe_a1p[index].State = 0x40; + xe_a1p[index].Counter = 0; + xe_a1p[index].Latency = 0; } -unsigned char xe_a1p_read() +INLINE unsigned char xe_a1p_read(int index) { unsigned int temp = 0x40; + unsigned int port = index << 2; /* Left Stick X & Y analog values (bidirectional) */ - int x = input.analog[0][0]; - int y = input.analog[0][1]; + int x = input.analog[port][0]; + int y = input.analog[port][1]; /* Right Stick X or Y value (unidirectional) */ - int z = input.analog[1][0]; + int z = input.analog[port+1][0]; /* Buttons status (active low) */ - uint16 pad = ~input.pad[0]; + uint16 pad = ~input.pad[port]; /* Current internal cycle (0-7) */ - unsigned int cycle = xe_a1p.Counter & 7; + unsigned int cycle = xe_a1p[index].Counter & 7; /* Current 4-bit data cycle */ /* There are eight internal data cycle for each 5 acquisition sequence */ /* First 4 return the same 4-bit data, next 4 return next 4-bit data */ - switch (xe_a1p.Counter >> 2) + switch (xe_a1p[index].Counter >> 2) { case 0: temp |= ((pad >> 8) & 0x0F); /* E1 E2 Start Select */ @@ -119,42 +121,62 @@ unsigned char xe_a1p_read() cycle = (cycle + 1) & 7; /* Update internal cycle counter */ - xe_a1p.Counter = (xe_a1p.Counter & ~7) | cycle; + xe_a1p[index].Counter = (xe_a1p[index].Counter & ~7) | cycle; /* Update internal latency on each read */ - xe_a1p.Latency++; + xe_a1p[index].Latency++; return temp; } -void xe_a1p_write(unsigned char data, unsigned char mask) +INLINE void xe_a1p_write(int index, unsigned char data, unsigned char mask) { /* update bits set as output only */ - data = (xe_a1p.State & ~mask) | (data & mask); + data = (xe_a1p[index].State & ~mask) | (data & mask); /* look for TH 1->0 transitions */ - if (!(data & 0x40) && (xe_a1p.State & 0x40)) + if (!(data & 0x40) && (xe_a1p[index].State & 0x40)) { /* reset acquisition cycle */ - xe_a1p.Latency = xe_a1p.Counter = 0; + xe_a1p[index].Latency = xe_a1p[index].Counter = 0; } else { /* some games immediately write new data to TH */ /* so we make sure first sequence has actually been handled */ - if (xe_a1p.Latency > 2) + if (xe_a1p[index].Latency > 2) { /* next acquisition sequence */ - xe_a1p.Counter = (xe_a1p.Counter & ~7) + 8; + xe_a1p[index].Counter = (xe_a1p[index].Counter & ~7) + 8; /* 5 sequence max with 8 cycles each */ - if (xe_a1p.Counter > 32) + if (xe_a1p[index].Counter > 32) { - xe_a1p.Counter = 32; + xe_a1p[index].Counter = 32; } } } /* update internal state */ - xe_a1p.State = data; + xe_a1p[index].State = data; +} + +unsigned char xe_a1p_1_read(void) +{ + return xe_a1p_read(0); +} + +unsigned char xe_a1p_2_read(void) +{ + return xe_a1p_read(1); +} + +void xe_a1p_1_write(unsigned char data, unsigned char mask) +{ + xe_a1p_write(0, data, mask); +} + +void xe_a1p_2_write(unsigned char data, unsigned char mask) +{ + xe_a1p_write(1, data, mask); } diff --git a/core/input_hw/xe_a1p.h b/core/input_hw/xe_a1p.h index 66b0360..7c474ed 100644 --- a/core/input_hw/xe_a1p.h +++ b/core/input_hw/xe_a1p.h @@ -40,8 +40,10 @@ #define _XE_A1PH_ /* Function prototypes */ -extern void xe_a1p_reset(void); -extern unsigned char xe_a1p_read(void); -extern void xe_a1p_write(unsigned char data, unsigned char mask); +extern void xe_a1p_reset(int index); +extern unsigned char xe_a1p_1_read(void); +extern unsigned char xe_a1p_2_read(void); +extern void xe_a1p_1_write(unsigned char data, unsigned char mask); +extern void xe_a1p_2_write(unsigned char data, unsigned char mask); #endif diff --git a/core/io_ctrl.c b/core/io_ctrl.c index 2b4f924..8d476ab 100644 --- a/core/io_ctrl.c +++ b/core/io_ctrl.c @@ -110,8 +110,8 @@ void io_init(void) case SYSTEM_XE_A1P: { - port[0].data_w = xe_a1p_write; - port[0].data_r = xe_a1p_read; + port[0].data_w = xe_a1p_1_write; + port[0].data_r = xe_a1p_1_read; break; } @@ -181,6 +181,13 @@ void io_init(void) break; } + case SYSTEM_XE_A1P: + { + port[1].data_w = xe_a1p_2_write; + port[1].data_r = xe_a1p_2_read; + break; + } + case SYSTEM_ACTIVATOR: { port[1].data_w = activator_2_write; diff --git a/gx/gui/menu.c b/gx/gui/menu.c index 5788cde..b3beba6 100644 --- a/gx/gui/menu.c +++ b/gx/gui/menu.c @@ -2183,12 +2183,6 @@ static void ctrlmenu(void) input.system[1] += 2; } - /* XE-1AP on port A only */ - if (input.system[1] == SYSTEM_XE_A1P) - { - input.system[1]++; - } - /* 4-wayplay uses both ports */ if (input.system[1] == SYSTEM_WAYPLAY) { From dbdae3bf3e0addeaee921a87a1605db2bcca7626 Mon Sep 17 00:00:00 2001 From: EkeEke Date: Thu, 27 Jun 2013 01:54:02 +0200 Subject: [PATCH 3/7] [Core/input] updated header of modified files --- core/input_hw/activator.c | 2 +- core/input_hw/activator.h | 2 +- core/input_hw/input.c | 2 +- core/input_hw/input.h | 2 +- core/input_hw/paddle.c | 2 +- core/input_hw/paddle.h | 2 +- core/input_hw/sportspad.c | 2 +- core/input_hw/sportspad.h | 2 +- core/input_hw/xe_a1p.c | 2 +- core/input_hw/xe_a1p.h | 2 +- core/io_ctrl.c | 2 +- core/io_ctrl.h | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/input_hw/activator.c b/core/input_hw/activator.c index 2af22db..e256635 100644 --- a/core/input_hw/activator.c +++ b/core/input_hw/activator.c @@ -2,7 +2,7 @@ * Genesis Plus * Sega Activator support * - * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/activator.h b/core/input_hw/activator.h index ee75b2b..18c18fe 100644 --- a/core/input_hw/activator.h +++ b/core/input_hw/activator.h @@ -2,7 +2,7 @@ * Genesis Plus * Sega Activator support * - * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/input.c b/core/input_hw/input.c index 4506c1a..ce82634 100644 --- a/core/input_hw/input.c +++ b/core/input_hw/input.c @@ -3,7 +3,7 @@ * Input peripherals support * * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/input.h b/core/input_hw/input.h index 9798154..6f4d908 100644 --- a/core/input_hw/input.h +++ b/core/input_hw/input.h @@ -3,7 +3,7 @@ * Input peripherals support * * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/paddle.c b/core/input_hw/paddle.c index 2fa7093..bf655c5 100644 --- a/core/input_hw/paddle.c +++ b/core/input_hw/paddle.c @@ -2,7 +2,7 @@ * Genesis Plus * Sega Paddle Control support * - * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/paddle.h b/core/input_hw/paddle.h index 926e947..6097a55 100644 --- a/core/input_hw/paddle.h +++ b/core/input_hw/paddle.h @@ -2,7 +2,7 @@ * Genesis Plus * Sega Paddle Control support * - * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/sportspad.c b/core/input_hw/sportspad.c index 48154e1..8dab4cf 100644 --- a/core/input_hw/sportspad.c +++ b/core/input_hw/sportspad.c @@ -2,7 +2,7 @@ * Genesis Plus * Sega Sports Pad support * - * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/sportspad.h b/core/input_hw/sportspad.h index 139b862..d5ae383 100644 --- a/core/input_hw/sportspad.h +++ b/core/input_hw/sportspad.h @@ -2,7 +2,7 @@ * Genesis Plus * Sega Sports Pad support * - * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/xe_a1p.c b/core/input_hw/xe_a1p.c index 8821ff9..1f02774 100644 --- a/core/input_hw/xe_a1p.c +++ b/core/input_hw/xe_a1p.c @@ -2,7 +2,7 @@ * Genesis Plus * XE-A1P analog controller support * - * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/input_hw/xe_a1p.h b/core/input_hw/xe_a1p.h index 7c474ed..fe5b6a1 100644 --- a/core/input_hw/xe_a1p.h +++ b/core/input_hw/xe_a1p.h @@ -2,7 +2,7 @@ * Genesis Plus * XE-A1P analog controller support * - * Copyright (C) 2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2011-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/io_ctrl.c b/core/io_ctrl.c index 8d476ab..f221bf5 100644 --- a/core/io_ctrl.c +++ b/core/io_ctrl.c @@ -5,7 +5,7 @@ * Support for Master System (315-5216, 315-5237 & 315-5297), Game Gear & Mega Drive I/O chips * * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/io_ctrl.h b/core/io_ctrl.h index 01a7dbb..addc259 100644 --- a/core/io_ctrl.h +++ b/core/io_ctrl.h @@ -5,7 +5,7 @@ * Support for Master System (315-5216, 315-5237 & 315-5297), Game Gear & Mega Drive I/O chips * * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code) - * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: From 49d22ce6ed5a769e91f7090ad99756ccad028bbe Mon Sep 17 00:00:00 2001 From: EkeEke Date: Thu, 27 Jun 2013 23:32:27 +0200 Subject: [PATCH 4/7] [Core/VDP] improved HVC latch behavior when not locked in hardware but forced for gun emulation ("Gunfight - 3 in 1" randomization issues when Justifier is enabled) --- core/input_hw/lightgun.c | 4 ++-- core/input_hw/lightgun.h | 2 +- core/vdp_ctrl.c | 17 +++++++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/core/input_hw/lightgun.c b/core/input_hw/lightgun.c index f9a6d5f..4ed0b76 100644 --- a/core/input_hw/lightgun.c +++ b/core/input_hw/lightgun.c @@ -2,7 +2,7 @@ * Genesis Plus * Sega Light Phaser, Menacer & Konami Justifiers support * - * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -135,7 +135,7 @@ void lightgun_refresh(int port) m68k_update_irq(2); } - /* force HV Counter Latch (some games does not lock HV Counter but instead use larger offset value) */ + /* HACK: force HV Counter latch (some games does not lock HV Counter but instead use larger offset value) */ hvc_latch = 0x10000 | (y << 8); if (reg[12] & 1) { diff --git a/core/input_hw/lightgun.h b/core/input_hw/lightgun.h index 4a67946..0021297 100644 --- a/core/input_hw/lightgun.h +++ b/core/input_hw/lightgun.h @@ -2,7 +2,7 @@ * Genesis Plus * Sega Light Phaser, Menacer & Konami Justifiers support * - * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX) + * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/core/vdp_ctrl.c b/core/vdp_ctrl.c index 96c9f42..e2fe42e 100644 --- a/core/vdp_ctrl.c +++ b/core/vdp_ctrl.c @@ -1370,17 +1370,26 @@ unsigned int vdp_hvc_r(unsigned int cycles) } else { + /* Mode 5: HV counters are frozen (cf. lightgun games & Sunset Riders) */ if (reg[1] & 4) { - /* Mode 5: both counters are frozen (Lightgun games, Sunset Riders) */ + /* check if HVC is really locked or is read within INT2 callback (HVC latch is forced for lightgun emulation, cf. lightgun.c) */ + if ((reg[0] & 0x02) || (m68k.int_mask == 0x0200)) + { #ifdef LOGVDP - error("[%d(%d)][%d(%d)] HVC read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, hvc_latch & 0xffff, m68k_get_reg(M68K_REG_PC)); + error("[%d(%d)][%d(%d)] HVC read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data & 0xffff, m68k_get_reg(M68K_REG_PC)); #endif - return (data & 0xffff); + /* return latched HVC value */ + return (data & 0xffff); + } + + /* HV counters should be free-running (fixes "Gunfight - 3 in 1" randomization when Justifiers are enabled) */ + hvc_latch = 0; + data = hctab[cycles % MCYCLES_PER_LINE]; } else { - /* Mode 4: VCounter runs normally, HCounter is frozen */ + /* Mode 4: V counter runs normally, H counter is frozen */ data &= 0xff; } } From 75ac3317ed9f6964ffdde441ff27ee666ff0df6f Mon Sep 17 00:00:00 2001 From: EkeEke Date: Sun, 30 Jun 2013 13:06:04 +0200 Subject: [PATCH 5/7] [Core/Input] cleaner fix for lightgun emulation when HVC latch is disabled (better not make VDP core hackish) --- core/input_hw/lightgun.c | 22 +++++++++++++++++++--- core/vdp_ctrl.c | 23 ++++++++--------------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/core/input_hw/lightgun.c b/core/input_hw/lightgun.c index 4ed0b76..d6bf46e 100644 --- a/core/input_hw/lightgun.c +++ b/core/input_hw/lightgun.c @@ -129,14 +129,25 @@ void lightgun_refresh(int port) } } - /* External Interrupt ? */ + /* External Interrupt enabled ? */ if (reg[11] & 0x08) { m68k_update_irq(2); } - /* HACK: force HV Counter latch (some games does not lock HV Counter but instead use larger offset value) */ - hvc_latch = 0x10000 | (y << 8); + /* HVC latch enabled ? */ + if (reg[0] & 0x02) + { + /* line accurate V-Counter value */ + hvc_latch = 0x10000 | (y << 8); + } + else + { + /* HACK: force HVC latch even when disabled (a few games does not lock HV Counter but instead applies larger offset value) */ + hvc_latch = 0x20000 | (y << 8); + } + + /* pixel accurate H-Counter value */ if (reg[12] & 1) { hvc_latch |= hc_320[((x / 2) + input.x_offset) % 210]; @@ -147,6 +158,11 @@ void lightgun_refresh(int port) } } } + else if (hvc_latch & 0x20000) + { + /* HVC should be free-running on other lines when latch is disabled (fixes "Gunfight - 3 in 1" randomization) */ + hvc_latch = 0; + } } } diff --git a/core/vdp_ctrl.c b/core/vdp_ctrl.c index e2fe42e..b9df03e 100644 --- a/core/vdp_ctrl.c +++ b/core/vdp_ctrl.c @@ -1362,7 +1362,7 @@ unsigned int vdp_hvc_r(unsigned int cycles) int vc; unsigned int data = hvc_latch; - /* Check if HVC is frozen */ + /* Check if HVC latch is enabled */ if (!data) { /* Cycle-accurate HCounter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */ @@ -1370,26 +1370,18 @@ unsigned int vdp_hvc_r(unsigned int cycles) } else { - /* Mode 5: HV counters are frozen (cf. lightgun games & Sunset Riders) */ - if (reg[1] & 4) + /* Mode 5: H & V counters are frozen (cf. lightgun games, Sunset Riders logo) */ + if (reg[1] & 0x04) { - /* check if HVC is really locked or is read within INT2 callback (HVC latch is forced for lightgun emulation, cf. lightgun.c) */ - if ((reg[0] & 0x02) || (m68k.int_mask == 0x0200)) - { #ifdef LOGVDP - error("[%d(%d)][%d(%d)] HVC read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data & 0xffff, m68k_get_reg(M68K_REG_PC)); + error("[%d(%d)][%d(%d)] HVC latch read -> 0x%x (%x)\n", v_counter, (cycles/MCYCLES_PER_LINE-1)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data & 0xffff, m68k_get_reg(M68K_REG_PC)); #endif - /* return latched HVC value */ - return (data & 0xffff); - } - - /* HV counters should be free-running (fixes "Gunfight - 3 in 1" randomization when Justifiers are enabled) */ - hvc_latch = 0; - data = hctab[cycles % MCYCLES_PER_LINE]; + /* return latched HVC value */ + return (data & 0xffff); } else { - /* Mode 4: V counter runs normally, H counter is frozen */ + /* Mode 4: by default, V counter runs normally & H counter is frozen */ data &= 0xff; } } @@ -1413,6 +1405,7 @@ unsigned int vdp_hvc_r(unsigned int cycles) vc = (vc & ~1) | ((vc >> 8) & 1); } + /* return HCounter in LSB & VCounter in MSB */ data |= ((vc & 0xff) << 8); #ifdef LOGVDP From 091a0615f5b589916e8a1132d7c986dcd5586e7b Mon Sep 17 00:00:00 2001 From: EkeEke Date: Sun, 30 Jun 2013 13:06:50 +0200 Subject: [PATCH 6/7] [Core/MD] fixed regression with games using SRAM bank-switching (introduced in r792) --- core/cart_hw/md_cart.c | 106 +++++++++++++++++++++++++++++------------ core/cart_hw/sram.c | 33 ++----------- core/cart_hw/sram.h | 4 ++ 3 files changed, 84 insertions(+), 59 deletions(-) diff --git a/core/cart_hw/md_cart.c b/core/cart_hw/md_cart.c index f09217c..b49f310 100644 --- a/core/cart_hw/md_cart.c +++ b/core/cart_hw/md_cart.c @@ -4,7 +4,7 @@ * * Copyright (C) 2007-2013 Eke-Eke (Genesis Plus GX) * - * Most cartridge protections were initially documented by Haze + * Many cartridge protections were initially documented by Haze * (http://haze.mameworld.info/) * * Realtec mapper was documented by TascoDeluxe @@ -42,6 +42,7 @@ ****************************************************************************************/ #include "shared.h" +#include "eeprom_i2c.h" #include "eeprom_spi.h" #include "gamepad.h" @@ -356,7 +357,25 @@ void md_cart_init(void) BACKUP MEMORY ***********************************************/ sram_init(); - + eeprom_i2c_init(); + + /* external SRAM */ + if (sram.on && !sram.custom) + { + /* disabled on startup if ROM is mapped in same area */ + if (cart.romsize <= sram.start) + { + /* initialize m68k bus handlers */ + m68k.memory_map[sram.start >> 16].base = sram.sram; + m68k.memory_map[sram.start >> 16].read8 = sram_read_byte; + m68k.memory_map[sram.start >> 16].read16 = sram_read_word; + m68k.memory_map[sram.start >> 16].write8 = sram_write_byte; + m68k.memory_map[sram.start >> 16].write16 = sram_write_word; + zbank_memory_map[sram.start >> 16].read = sram_read_byte; + zbank_memory_map[sram.start >> 16].write = sram_write_byte; + } + } + /********************************************** SVP CHIP ***********************************************/ @@ -492,7 +511,7 @@ void md_cart_init(void) } /********************************************** - Cartridge Extra Hardware + CARTRIDGE EXTRA HARDWARE ***********************************************/ memset(&cart.hw, 0, sizeof(cart.hw)); @@ -607,7 +626,7 @@ void md_cart_init(void) m68k.memory_map[i].base = cart.rom + ((i & 0x03) << 16); } - /* 32K SRAM is initially disabled at $200000-$2FFFFF */ + /* 32K static RAM is mapped to $200000-$2FFFFF (disabled on startup) */ for (i=0x20; i<0x30; i++) { m68k.memory_map[i].base = sram.sram; @@ -789,10 +808,28 @@ int md_cart_context_load(uint8 *state) if (offset == 0xff) { /* SRAM */ - m68k.memory_map[i].base = sram.sram; + m68k.memory_map[i].base = sram.sram; + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; + } else { + /* check if SRAM was mapped there before loading state */ + if (m68k.memory_map[i].base == sram.sram) + { + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].read = NULL; + zbank_memory_map[i].write = zbank_unused_w; + } + /* ROM */ m68k.memory_map[i].base = cart.rom + (offset << 16); } @@ -829,9 +866,9 @@ static void mapper_sega_w(uint32 data) { /* Backup RAM mapped to $200000-$20ffff (normally mirrored up to $3fffff but this breaks Sonic Megamix and no game need it) */ m68k.memory_map[0x20].base = sram.sram; - m68k.memory_map[0x20].write8 = NULL; - m68k.memory_map[0x20].write16 = NULL; - zbank_memory_map[0x20].write = NULL; + m68k.memory_map[0x20].read8 = sram_read_byte; + m68k.memory_map[0x20].read16 = sram_read_word; + zbank_memory_map[0x20].read = sram_read_byte; /* Backup RAM write protection */ if (data & 2) @@ -840,6 +877,12 @@ static void mapper_sega_w(uint32 data) m68k.memory_map[0x20].write16 = m68k_unused_16_w; zbank_memory_map[0x20].write = zbank_unused_w; } + else + { + m68k.memory_map[0x20].write8 = sram_write_byte; + m68k.memory_map[0x20].write16 = sram_write_word; + zbank_memory_map[0x20].write = sram_write_byte; + } } /* S&K lock-on chip */ @@ -857,10 +900,13 @@ static void mapper_sega_w(uint32 data) /* cartridge ROM mapped to $200000-$3fffff */ for (i=0x20; i<0x40; i++) { - m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; - zbank_memory_map[i].write = zbank_unused_w; + m68k.memory_map[i].base = cart.rom + ((i<<16) & cart.mask); + m68k.memory_map[i].read8 = NULL; + m68k.memory_map[i].read16 = NULL; + zbank_memory_map[i].read = NULL; + m68k.memory_map[i].write8 = m68k_unused_8_w; + m68k.memory_map[i].write16 = m68k_unused_16_w; + zbank_memory_map[i].write = zbank_unused_w; } } } @@ -907,10 +953,10 @@ static void mapper_sf001_w(uint32 address, uint32 data) m68k.memory_map[i].base = cart.rom + (i << 16); m68k.memory_map[i].read8 = m68k_read_bus_8; m68k.memory_map[i].read16 = m68k_read_bus_16; - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; + m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; zbank_memory_map[i].read = zbank_unused_r; - zbank_memory_map[i].write = m68k_unused_8_w; + zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; } } @@ -939,12 +985,12 @@ static void mapper_sf001_w(uint32 address, uint32 data) while (i<0x40) { m68k.memory_map[i].base = sram.sram; - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - m68k.memory_map[i].write8 = NULL; - m68k.memory_map[i].write16 = NULL; - zbank_memory_map[i].read = NULL; - zbank_memory_map[i].write = NULL; + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; i++; } } @@ -956,10 +1002,10 @@ static void mapper_sf001_w(uint32 address, uint32 data) m68k.memory_map[i].base = cart.rom + (i << 16); m68k.memory_map[i].read8 = NULL; m68k.memory_map[i].read16 = NULL; - m68k.memory_map[i].write8 = m68k_unused_8_w; - m68k.memory_map[i].write16 = m68k_unused_16_w; + m68k.memory_map[i].write8 = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; + m68k.memory_map[i].write16 = (i > 0x00) ? m68k_unused_16_w : mapper_sf001_w; zbank_memory_map[i].read = NULL; - zbank_memory_map[i].write = m68k_unused_8_w; + zbank_memory_map[i].write = (i > 0x00) ? m68k_unused_8_w : mapper_sf001_w; } } @@ -1023,12 +1069,12 @@ static void mapper_sf004_w(uint32 address, uint32 data) /* 32KB static RAM mirrored into $200000-$2FFFFF (odd bytes only) */ for (i=0x20; i<0x30; i++) { - m68k.memory_map[i].read8 = NULL; - m68k.memory_map[i].read16 = NULL; - m68k.memory_map[i].write8 = NULL; - m68k.memory_map[i].write16 = NULL; - zbank_memory_map[i].read = NULL; - zbank_memory_map[i].write = NULL; + m68k.memory_map[i].read8 = sram_read_byte; + m68k.memory_map[i].read16 = sram_read_word; + m68k.memory_map[i].write8 = sram_write_byte; + m68k.memory_map[i].write16 = sram_write_word; + zbank_memory_map[i].read = sram_read_byte; + zbank_memory_map[i].write = sram_write_byte; } } else diff --git a/core/cart_hw/sram.c b/core/cart_hw/sram.c index 835ec15..382cf13 100644 --- a/core/cart_hw/sram.c +++ b/core/cart_hw/sram.c @@ -37,15 +37,9 @@ ****************************************************************************************/ #include "shared.h" -#include "eeprom_i2c.h" T_SRAM sram; -static unsigned int sram_read_byte(unsigned int address); -static unsigned int sram_read_word(unsigned int address); -static void sram_write_byte(unsigned int address, unsigned int data); -static void sram_write_word(unsigned int address, unsigned int data); - /**************************************************************************** * A quick guide to external RAM on the Genesis * @@ -194,44 +188,25 @@ void sram_init() sram.on = 1; } } - - /* autodetect games with serial EEPROM */ - eeprom_i2c_init(); - - /* initialize m68k bus handlers (if not already done) */ - if (sram.on && !sram.custom) - { - /* disabled on startup if ROM is mapped in same area */ - if (cart.romsize <= sram.start) - { - m68k.memory_map[sram.start >> 16].base = sram.sram; - m68k.memory_map[sram.start >> 16].read8 = sram_read_byte; - m68k.memory_map[sram.start >> 16].read16 = sram_read_word; - m68k.memory_map[sram.start >> 16].write8 = sram_write_byte; - m68k.memory_map[sram.start >> 16].write16 = sram_write_word; - zbank_memory_map[sram.start >> 16].read = sram_read_byte; - zbank_memory_map[sram.start >> 16].write = sram_write_byte; - } - } } -static unsigned int sram_read_byte(unsigned int address) +unsigned int sram_read_byte(unsigned int address) { return sram.sram[address & 0xffff]; } -static unsigned int sram_read_word(unsigned int address) +unsigned int sram_read_word(unsigned int address) { address &= 0xfffe; return (sram.sram[address + 1] | (sram.sram[address] << 8)); } -static void sram_write_byte(unsigned int address, unsigned int data) +void sram_write_byte(unsigned int address, unsigned int data) { sram.sram[address & 0xffff] = data; } -static void sram_write_word(unsigned int address, unsigned int data) +void sram_write_word(unsigned int address, unsigned int data) { address &= 0xfffe; sram.sram[address] = data >> 8; diff --git a/core/cart_hw/sram.h b/core/cart_hw/sram.h index d838e69..64934ca 100644 --- a/core/cart_hw/sram.h +++ b/core/cart_hw/sram.h @@ -52,6 +52,10 @@ typedef struct /* Function prototypes */ extern void sram_init(); +extern unsigned int sram_read_byte(unsigned int address); +extern unsigned int sram_read_word(unsigned int address); +extern void sram_write_byte(unsigned int address, unsigned int data); +extern void sram_write_word(unsigned int address, unsigned int data); /* global variables */ extern T_SRAM sram; From 5ee0d975dd30aeb36ac98d424ba1f867d83cbaf5 Mon Sep 17 00:00:00 2001 From: EkeEke Date: Sun, 30 Jun 2013 13:08:44 +0200 Subject: [PATCH 7/7] [Core/VDP] minor code cleanup --- core/vdp_ctrl.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/core/vdp_ctrl.c b/core/vdp_ctrl.c index b9df03e..7ec7d4f 100644 --- a/core/vdp_ctrl.c +++ b/core/vdp_ctrl.c @@ -1363,14 +1363,9 @@ unsigned int vdp_hvc_r(unsigned int cycles) unsigned int data = hvc_latch; /* Check if HVC latch is enabled */ - if (!data) + if (data) { - /* Cycle-accurate HCounter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */ - data = hctab[cycles % MCYCLES_PER_LINE]; - } - else - { - /* Mode 5: H & V counters are frozen (cf. lightgun games, Sunset Riders logo) */ + /* Mode 5: HV-counters are frozen (cf. lightgun games, Sunset Riders logo) */ if (reg[1] & 0x04) { #ifdef LOGVDP @@ -1381,15 +1376,20 @@ unsigned int vdp_hvc_r(unsigned int cycles) } else { - /* Mode 4: by default, V counter runs normally & H counter is frozen */ + /* Mode 4: by default, V-counter runs normally & H counter is frozen */ data &= 0xff; } } + else + { + /* Cycle-accurate H-Counter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */ + data = hctab[cycles % MCYCLES_PER_LINE]; + } - /* Cycle-accurate VCounter (cycle counter starts from line -1) */ + /* Cycle-accurate V-Counter (cycle counter starts from line -1) */ vc = (cycles / MCYCLES_PER_LINE) - 1; - /* VCounter overflow */ + /* V-Counter overflow */ if (vc > vc_max) { vc -= lines_per_frame; @@ -1405,7 +1405,7 @@ unsigned int vdp_hvc_r(unsigned int cycles) vc = (vc & ~1) | ((vc >> 8) & 1); } - /* return HCounter in LSB & VCounter in MSB */ + /* return H-Counter in LSB & V-Counter in MSB */ data |= ((vc & 0xff) << 8); #ifdef LOGVDP