From 38ed8f55f62772bc6b559a6dd7da024f8216a16c Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 21 Mar 2015 16:11:27 +0200 Subject: [PATCH] Action Replay 2/3 freeze function update. --- ar.cpp | 182 ++++++++++++++++++++++++++++++++------------------- cia.cpp | 8 +-- include/ar.h | 2 +- 3 files changed, 118 insertions(+), 74 deletions(-) diff --git a/ar.cpp b/ar.cpp index 02fbb432..ba8d80bf 100644 --- a/ar.cpp +++ b/ar.cpp @@ -1,7 +1,7 @@ /* * UAE Action Replay 1/2/3/1200 and HRTMon support * -* (c) 2000-2006 Toni Wilen +* (c) 2000-2015 Toni Wilen * (c) 2003 Mark Cox * * Action Replay 1200 (basically old version of HRTMon): @@ -81,19 +81,23 @@ * first 8 bytes of ROM are not really ROM, they are * used to read/write cartridge's hardware state * -* 0x400000: hides cartridge ROM/RAM when written -* 0x400001: read/write HW state -* 3 = reset (read-only) -* 2 = sets HW to activate when breakpoint condition is detected -* 1 = ??? -* 0 = freeze pressed +* Read/write HW state +* +* 0x400001.B READ: +* +* 11 (3) = freeze was caused by reset condition +* 10 (2) = freeze was caused by 0xBFD100.B WRITE +* 01 (1) = freeze was caused by 0xBFE001.B READ +* 00 (0) = freeze was caused by button press +* +* 0x400001.B WRITE +* +* bit 1 set: enable freeze caused by BFE001.B READ +* bit 0 set: enable freeze caused by BFD100.B WRITE +* * 0x400002/0x400003: mirrors 0x400000/0x400001 * 0x400006/0x400007: when written to, turns chip-ram overlay off * -* breakpoint condition is detected when CPU first accesses -* chip memory below 1024 bytes and then reads CIA register -* $BFE001. -* * cartridge hardware also snoops CPU accesses to custom chip * registers (DFF000-DFF1FE). All CPU custom chip accesses are * saved to RAM at 0x44f000-0x44f1ff. Note that emulated AR3 also @@ -222,11 +226,17 @@ extern void activate_debugger (void); static const TCHAR *cart_memnames[] = { NULL, _T("hrtmon"), _T("arhrtmon"), _T("superiv") }; -#define ARMODE_FREEZE 0 /* AR2/3 The action replay 'freeze' button has been pressed. */ -#define ARMODE_BREAKPOINT_AR2 2 /* AR2: The action replay is activated via a breakpoint. */ -#define ARMODE_BREAKPOINT_ACTIVATED 1 -#define ARMODE_BREAKPOINT_AR3_RESET_AR2 3 /* AR2: The action replay is activated after a reset. */ -/* AR3: The action replay is activated by a breakpoint. */ +// Action Replay 2/3 +// $400001.B read values +#define ARMODE_FREEZE 0 /* 'freeze' button has been pressed. */ +#define ARMODE_READ_BFE001 1 /* BFE001 read = freeze */ +#define ARMODE_WRITE_BFD100 2 /* BFD100 write = freeze */ +#define ARMODE_SOFTRESET 2 +#define ARMODE_RESET 3 /* reset state */ +// $400001.B written values +#define ARMODE_ACTIVATE_BFE001 2 +#define ARMODE_ACTIVATE_BFD100 1 +#define ARMODE_ACTIVE_NONE 0 #define CART_AR 0 #define CART_HRTMON 1 @@ -239,6 +249,7 @@ static int hrtmon_ciadiv = 256; int hrtmon_flag = ACTION_REPLAY_INACTIVE; static int cart_type; +static int ar_mapped, ar_hidden; static uae_u8 *hrtmemory = 0, *hrtmemory2 = 0, *hrtmemory3 = 0; static uae_u8 *armemory_rom = 0, *armemory_ram = 0; @@ -500,7 +511,7 @@ static int ar_rom_file_size; static int ar_rom_location; /*static*/ int armodel; static uae_u8 artemp[4]; /* Space to store the 'real' level 7 interrupt */ -static uae_u8 armode; +static uae_u8 armode_read, armode_write; static uae_u32 arrom_start, arrom_size, arrom_mask; static uae_u32 arram_start, arram_size, arram_mask; @@ -573,35 +584,24 @@ STATIC_INLINE int ar3a (uaecptr addr, uae_u8 b, int writing) return 0; #endif - if (!writing) /* reading */ - { + if (!writing) { + //write_log(_T("READ %x\n"), addr); if (addr == 1 || addr == 3) /* This is necessary because we don't update rom location 0 every time we change armode */ - return armode | (regs.irc & ~3); + return armode_read | (regs.irc & ~3); else if (addr < 4) return (addr & 1) ? regs.irc : regs.irc >> 8; - else - return armemory_rom[addr]; - } - /* else, we are writing */ - else if (addr == 1) { - armode = b; - if (armode >= 2) { - if (armode == ARMODE_BREAKPOINT_AR2) { - write_log (_T("AR2: exit with breakpoint(s) active\n")); /* Correct for AR2 */ - } else if (armode == ARMODE_BREAKPOINT_AR3_RESET_AR2 ) { - write_log (_T("AR3: exit waiting for breakpoint.\n")); /* Correct for AR3 (waiting for breakpoint)*/ - } else { - write_log (_T("AR2/3: mode(%d) > 3 this shouldn't happen.\n"), armode); - } - } else { - write_log (_T("AR: exit with armode(%d)\n"), armode); + return armemory_rom[addr]; + } else { + //write_log(_T("WRITE %x\n"), addr); + if (addr == 1) { + armode_write = b; + armode_read = 0; + write_log(_T("ARMODE %02x written\n"), b); + set_special (SPCFLAG_ACTION_REPLAY); + action_replay_flag = ACTION_REPLAY_HIDE; + } else if (addr == 6) { + copytoamiga (regs.vbr + 0x7c, artemp, 4); } - - set_special (SPCFLAG_ACTION_REPLAY); - action_replay_flag = ACTION_REPLAY_HIDE; - } else if (addr == 6) { - copytoamiga (regs.vbr + 0x7c, artemp, 4); - write_log (_T("AR: chipmem returned\n")); } return 0; } @@ -644,7 +644,7 @@ void REGPARAM2 chipmem_lput_actionreplay23 (uaecptr addr, uae_u32 l) addr &= chipmem_bank.mask; m = (uae_u32 *)(chipmem_bank.baseaddr + addr); do_put_mem_long (m, l); - if (addr == 8 && action_replay_flag == ACTION_REPLAY_WAITRESET) + if (action_replay_flag == ACTION_REPLAY_WAITRESET) action_replay_chipwrite(); } void REGPARAM2 chipmem_wput_actionreplay23 (uaecptr addr, uae_u32 w) @@ -655,7 +655,7 @@ void REGPARAM2 chipmem_wput_actionreplay23 (uaecptr addr, uae_u32 w) addr &= chipmem_bank.mask; m = (uae_u16 *)(chipmem_bank.baseaddr + addr); do_put_mem_word (m, w); - if (addr == 8 && action_replay_flag == ACTION_REPLAY_WAITRESET) + if (action_replay_flag == ACTION_REPLAY_WAITRESET) action_replay_chipwrite(); } @@ -683,12 +683,23 @@ static uae_u32 action_replay_calculate_checksum(void); static uae_u8* get_checksum_location(void); static void disable_rom_test(void); +static uae_u32 ar_null(int size) +{ + if (size == 4) + return dummy_bank.lget(0); + if (size == 2) + return dummy_bank.wget(0); + return dummy_bank.bget(0); +} + static uae_u32 REGPARAM2 arram_lget (uaecptr addr) { uae_u32 *m; #ifdef JIT special_mem |= S_READ; #endif + if (ar_hidden) + return ar_null(4); addr -= arram_start; addr &= arram_mask; m = (uae_u32 *)(armemory_ram + addr); @@ -715,6 +726,8 @@ static uae_u32 REGPARAM2 arram_wget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif + if (ar_hidden) + return ar_null(4); addr -= arram_start; addr &= arram_mask; m = (uae_u16 *)(armemory_ram + addr); @@ -726,6 +739,8 @@ static uae_u32 REGPARAM2 arram_bget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif + if (ar_hidden) + return ar_null(4); addr -= arram_start; addr &= arram_mask; return armemory_ram[addr]; @@ -738,6 +753,8 @@ void REGPARAM2 arram_lput (uaecptr addr, uae_u32 l) #ifdef JIT special_mem |= S_WRITE; #endif + if (ar_hidden) + return; addr -= arram_start; addr &= arram_mask; m = (uae_u32 *)(armemory_ram + addr); @@ -765,6 +782,8 @@ void REGPARAM2 arram_wput (uaecptr addr, uae_u32 w) #ifdef JIT special_mem |= S_WRITE; #endif + if (ar_hidden) + return; addr -= arram_start; addr &= arram_mask; m = (uae_u16 *)(armemory_ram + addr); @@ -776,6 +795,8 @@ void REGPARAM2 arram_bput (uaecptr addr, uae_u32 b) #ifdef JIT special_mem |= S_WRITE; #endif + if (ar_hidden) + return; addr -= arram_start; addr &= arram_mask; armemory_ram[addr] = b; @@ -800,6 +821,8 @@ static uae_u32 REGPARAM2 arrom_lget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif + if (ar_hidden) + return ar_null(4); addr -= arrom_start; addr &= arrom_mask; return (ar3a (addr, 0, 0) << 24) | (ar3a (addr + 1, 0, 0) << 16) | (ar3a (addr + 2, 0, 0) << 8) | ar3a (addr + 3, 0, 0); @@ -810,6 +833,8 @@ static uae_u32 REGPARAM2 arrom_wget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif + if (ar_hidden) + return ar_null(2); addr -= arrom_start; addr &= arrom_mask; return (ar3a (addr, 0, 0) << 8) | ar3a (addr + 1, 0, 0); @@ -820,6 +845,8 @@ static uae_u32 REGPARAM2 arrom_bget (uaecptr addr) #ifdef JIT special_mem |= S_READ; #endif + if (ar_hidden) + return ar_null(1); addr -= arrom_start; addr &= arrom_mask; return ar3a (addr, 0, 0); @@ -830,6 +857,8 @@ static void REGPARAM2 arrom_lput (uaecptr addr, uae_u32 l) #ifdef JIT special_mem |= S_WRITE; #endif + if (ar_hidden) + return; addr -= arrom_start; addr &= arrom_mask; ar3a (addr + 0,(uae_u8)(l >> 24), 1); @@ -843,6 +872,8 @@ static void REGPARAM2 arrom_wput (uaecptr addr, uae_u32 w) #ifdef JIT special_mem |= S_WRITE; #endif + if (ar_hidden) + return; addr -= arrom_start; addr &= arrom_mask; ar3a (addr + 0,(uae_u8)(w >> 8), 1); @@ -854,6 +885,8 @@ static void REGPARAM2 arrom_bput (uaecptr addr, uae_u32 b) #ifdef JIT special_mem |= S_WRITE; #endif + if (ar_hidden) + return; addr -= arrom_start; addr &= arrom_mask; ar3a (addr, b, 1); @@ -891,6 +924,10 @@ static void action_replay_map_banks (void) { if(!armemory_rom) return; + ar_hidden = false; + if (ar_mapped > 0) + return; + ar_mapped = 1; map_banks (&arrom_bank, arrom_start >> 16, arrom_size >> 16, 0); map_banks (&arram_bank, arram_start >> 16, arram_size >> 16, 0); } @@ -903,6 +940,10 @@ static void action_replay_unmap_banks (void) action_replay_map_banks (); return; } + ar_hidden = true; + if (ar_mapped == 0) + return; + ar_mapped = 0; map_banks (&dummy_bank, arrom_start >> 16 , arrom_size >> 16, 0); map_banks (&dummy_bank, arram_start >> 16 , arram_size >> 16, 0); } @@ -927,7 +968,6 @@ static void hide_cart (int hide) static void action_replay_go (void) { - //write_log (_T("AR GO %d\n"), armode); cartridge_enter(); hide_cart (0); memcpy (armemory_ram + 0xf000, ar_custom, 2 * 256); @@ -1043,18 +1083,9 @@ void action_replay_enter (void) } if (action_replay_flag == ACTION_REPLAY_DORESET) { write_log (_T("AR2/3: reset\n")); - armode = action_replay_hardreset ? ARMODE_BREAKPOINT_AR3_RESET_AR2 : 2; + armode_read = action_replay_hardreset ? ARMODE_RESET : ARMODE_SOFTRESET; action_replay_hardreset = false; - } else if (armode == ARMODE_FREEZE) { - write_log (_T("AR2/3: activated (freeze)\n")); - } else if (armode >= 2) { - if (armode == ARMODE_BREAKPOINT_AR2) - write_log (_T("AR2: activated (breakpoint)\n")); - else if (armode == ARMODE_BREAKPOINT_AR3_RESET_AR2) - write_log (_T("AR3: activated (breakpoint)\n")); - else - write_log (_T("AR2/3: mode(%d) > 3 this shouldn't happen.\n"), armode); - armode = ARMODE_BREAKPOINT_ACTIVATED; + ar_mapped = -1; } action_replay_go(); } @@ -1082,6 +1113,7 @@ void check_prefs_changed_carts (int in_memory_reset) void action_replay_reset (bool hardreset, bool keyboardreset) { + ar_mapped = -1; if (hrtmemory) { if (isrestore ()) { if (m68k_getpc () >= hrtmem_start && m68k_getpc () <= hrtmem_start + hrtmem_size) @@ -1108,8 +1140,7 @@ void action_replay_reset (bool hardreset, bool keyboardreset) action_replay_flag = ACTION_REPLAY_ACTIVE; hide_cart (0); } else { - write_log_debug (_T("Setting flag to ACTION_REPLAY_WAITRESET (%d)\n"), hardreset); - write_log_debug (_T("armode == %d\n"), armode); + armode_read = ARMODE_RESET; action_replay_flag = ACTION_REPLAY_WAITRESET; if (hardreset || keyboardreset || armodel == 2) action_replay_hardreset = true; @@ -1118,7 +1149,7 @@ void action_replay_reset (bool hardreset, bool keyboardreset) } } -void action_replay_ciaread (void) +void action_replay_cia_access(bool write) { if (armodel < 2) return; @@ -1126,13 +1157,15 @@ void action_replay_ciaread (void) return; if (action_replay_flag == ACTION_REPLAY_INACTIVE) return; - if (armode < 2) - /* If there are no active breakpoints */ - return; - if (m68k_getpc () >= 0x200) - return; - action_replay_flag = ACTION_REPLAY_ACTIVATE; - set_special (SPCFLAG_ACTION_REPLAY); + if ((armode_write & ARMODE_ACTIVATE_BFE001) && !write) { + armode_read = ARMODE_READ_BFE001; + action_replay_flag = ACTION_REPLAY_ACTIVATE; + set_special (SPCFLAG_ACTION_REPLAY); + } else if ((armode_write & ARMODE_ACTIVATE_BFD100) && write) { + armode_read = ARMODE_WRITE_BFD100; + action_replay_flag = ACTION_REPLAY_ACTIVATE; + set_special (SPCFLAG_ACTION_REPLAY); + } } int action_replay_freeze (void) @@ -1143,7 +1176,7 @@ int action_replay_freeze (void) } else { action_replay_flag = ACTION_REPLAY_ACTIVATE; set_special (SPCFLAG_ACTION_REPLAY); - armode = ARMODE_FREEZE; + armode_read = ARMODE_FREEZE; } return 1; } else if (hrtmon_flag) { @@ -1174,8 +1207,19 @@ static void action_replay_chipwrite (void) void action_replay_hide(void) { - hide_cart(1); - action_replay_flag = ACTION_REPLAY_IDLE; + if (armodel >= 2) { + // Do not unmap if breakpoint mode + // It would cause dozens of map/unmaps per frame + // Just "hide" it. + ar_hidden = true; + if (armode_read == 0) { + hide_cart(1); + } + action_replay_flag = ACTION_REPLAY_IDLE; + } else { + hide_cart(1); + action_replay_flag = ACTION_REPLAY_IDLE; + } } void hrtmon_hide(void) diff --git a/cia.cpp b/cia.cpp index c2b3765d..2a4c90f9 100644 --- a/cia.cpp +++ b/cia.cpp @@ -990,7 +990,7 @@ static uae_u8 ReadCIAA (unsigned int addr) switch (reg) { case 0: #ifdef ACTION_REPLAY - action_replay_ciaread (); + action_replay_cia_access(false); #endif tmp = DISK_status_ciaa() & 0x3c; tmp |= handle_joystick_buttons (ciaapra, ciaadra); @@ -1175,9 +1175,6 @@ static uae_u8 ReadCIAB (unsigned int addr) #endif return tmp; case 1: -#ifdef ACTION_REPLAY - action_replay_ciaread (); -#endif #if DONGLE_DEBUG > 0 if (notinrom ()) write_log (_T("BFD100 R %02X %s\n"), ciabprb, debuginfo(0)); @@ -1494,6 +1491,9 @@ static void WriteCIAB (uae_u16 addr, uae_u8 val) #endif break; case 1: +#ifdef ACTION_REPLAY + action_replay_cia_access(true); +#endif #if DONGLE_DEBUG > 0 if (notinrom ()) write_log (_T("BFD100 W %02X %s\n"), val, debuginfo(0)); diff --git a/include/ar.h b/include/ar.h index 0a272e52..b1cb263a 100644 --- a/include/ar.h +++ b/include/ar.h @@ -34,7 +34,7 @@ extern int armodel; extern int is_ar_pc_in_rom(void); extern int is_ar_pc_in_ram(void); extern void action_replay_enter (void); -extern void action_replay_ciaread (void); +extern void action_replay_cia_access (bool write); extern void action_replay_hide (void); extern void action_replay_reset (bool hardreset, bool keyboardreset); extern int action_replay_load (void); -- 2.47.3