From ff9f2aa632d02611557701868a59198758a9d2ee Mon Sep 17 00:00:00 2001 From: Matt Harlum Date: Thu, 8 Jul 2021 18:48:15 +0100 Subject: [PATCH] Add DF1 bootselect, Add option to move slow ram to chip ram --- default.cfg | 7 ++++ emulator.c | 68 +++++++++++++++++++++++++++++++ platforms/amiga/amiga-platform.c | 32 ++++++++++++++- platforms/amiga/amiga-registers.h | 6 +++ 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/default.cfg b/default.cfg index e34ba30..2590c2d 100644 --- a/default.cfg +++ b/default.cfg @@ -79,3 +79,10 @@ keyboard k nograb noautoconnect # Syntax is mouse [device] [toggle key] [autoconnect|noautoconnect] # (see "keyboard" above for autoconnect description) mouse /dev/input/mice m noautoconnect + +# Uncommenting below moves slow ram to the chip ram giving 1MB of chip ram +# NOTE: Requires a 1MB ECS Agnus (8372) and a trapdoor memory expansion! +#setvar move-slow-to-chip + +# Swap DF0 with DF1/2/3 - Useful for Kickstart 1.x / Trackloader games that will only boot from DF0 +#setvar swap-df0-df 1 diff --git a/emulator.c b/emulator.c index 560838c..836a258 100644 --- a/emulator.c +++ b/emulator.c @@ -42,6 +42,9 @@ int kb_hook_enabled = 0; int mouse_hook_enabled = 0; int cpu_emulation_running = 1; +int swap_df0_with_dfx = 0; +int spoof_df0_id = 0; +int move_slow_to_chip = 0; uint8_t mouse_dx = 0, mouse_dy = 0; uint8_t mouse_buttons = 0; @@ -867,6 +870,13 @@ static inline int32_t platform_read_check(uint8_t type, uint32_t addr, uint32_t *res = (rres ^ 0x40); return 1; } + if (swap_df0_with_dfx && spoof_df0_id) { + // DF0 doesn't emit a drive type ID on RDY pin + // If swapping DF0 with DF1-3 we need to provide this ID so that DF0 continues to function. + rres = (uint32_t)ps_read(type, addr); + *res = (rres & 0xDF); // Spoof drive id for swapped DF0 by setting RDY low + return 1; + } return 0; break; case CIAAICR: @@ -940,10 +950,36 @@ static inline int32_t platform_read_check(uint8_t type, uint32_t addr, uint32_t } return 0; break; + case CIABPRB: + if (swap_df0_with_dfx) { + uint32_t result = (uint32_t)ps_read(type, addr); + // SEL0 = 0x80, SEL1 = 0x10, SEL2 = 0x20, SEL3 = 0x40 + if (((result >> SEL0_BITNUM) & 1) != ((result >> (SEL0_BITNUM + swap_df0_with_dfx)) & 1)) { // If the value for SEL0/SELx differ + result ^= ((1 << SEL0_BITNUM) | (1 << (SEL0_BITNUM + swap_df0_with_dfx))); // Invert both bits to swap them around + } + *res = result; + return 1; + } + return 0; + break; default: break; } + if (move_slow_to_chip && addr >= 0x080000 && addr <= 0x0FFFFF) { + // A500 JP2 connects Agnus' A19 input to A23 instead of A19 by default, and decodes trapdoor memory at 0xC00000 instead of 0x080000. + // We can move the trapdoor to chipram simply by rewriting the address. + addr += 0xB80000; + *res = ps_read(type, addr); + return 1; + } + + if (move_slow_to_chip && addr >= 0xC00000 && addr <= 0xC7FFFF) { + // Block accesses through to trapdoor at slow ram address, otherwise it will be detected at 0x080000 and 0xC00000. + *res = 0; + return 1; + } + if (addr >= cfg->custom_low && addr < cfg->custom_high) { if (addr >= PISCSI_OFFSET && addr < PISCSI_UPPER) { *res = handle_piscsi_read(addr, type); @@ -962,6 +998,7 @@ static inline int32_t platform_read_check(uint8_t type, uint32_t addr, uint32_t return 1; } } + break; default: break; @@ -1088,10 +1125,40 @@ static inline int32_t platform_write_check(uint8_t type, uint32_t addr, uint32_t return 0; break; } + case CIABPRB: + if (swap_df0_with_dfx) { + if ((val & ((1 << (SEL0_BITNUM + swap_df0_with_dfx)) | 0x80)) == 0x80) { + // If drive selected but motor off, Amiga is reading drive ID. + spoof_df0_id = 1; + } else { + spoof_df0_id = 0; + } + + if (((val >> SEL0_BITNUM) & 1) != ((val >> (SEL0_BITNUM + swap_df0_with_dfx)) & 1)) { // If the value for SEL0/SELx differ + val ^= ((1 << SEL0_BITNUM) | (1 << (SEL0_BITNUM + swap_df0_with_dfx))); // Invert both bits to swap them around + } + ps_write(type,addr,val); + return 1; + } + return 0; + break; default: break; } + if (move_slow_to_chip && addr >= 0x080000 && addr <= 0x0FFFFF) { + // A500 JP2 connects Agnus' A19 input to A23 instead of A19 by default, and decodes trapdoor memory at 0xC00000 instead of 0x080000. + // We can move the trapdoor to chipram simply by rewriting the address. + addr += 0xB80000; + ps_write(type,addr,val); + return 1; + } + + if (move_slow_to_chip && addr >= 0xC00000 && addr <= 0xC7FFFF) { + // Block accesses through to trapdoor at slow ram address, otherwise it will be detected at 0x080000 and 0xC00000. + return 1; + } + if (addr >= cfg->custom_low && addr < cfg->custom_high) { if (addr >= PISCSI_OFFSET && addr < PISCSI_UPPER) { handle_piscsi_write(addr, val, type); @@ -1109,6 +1176,7 @@ static inline int32_t platform_write_check(uint8_t type, uint32_t addr, uint32_t return 1; } } + break; default: break; diff --git a/platforms/amiga/amiga-platform.c b/platforms/amiga/amiga-platform.c index bb50259..5808d8a 100644 --- a/platforms/amiga/amiga-platform.c +++ b/platforms/amiga/amiga-platform.c @@ -7,6 +7,7 @@ #include "amiga-autoconf.h" #include "amiga-registers.h" #include "amiga-interrupts.h" +#include "gpio/ps_protocol.h" #include "hunk-reloc.h" #include "net/pi-net-enums.h" #include "net/pi-net.h" @@ -57,6 +58,10 @@ extern unsigned int a314_base; extern int kb_hook_enabled; extern int mouse_hook_enabled; +extern int swap_df0_with_dfx; +extern int spoof_df0_id; +extern int move_slow_to_chip; + #define min(a, b) (a < b) ? a : b #define max(a, b) (a > b) ? a : b @@ -523,6 +528,18 @@ void setvar_amiga(struct emulator_config *cfg, char *var, char *val) { } } } + + if CHKVAR("swap-df0-df") { + if (val && strlen(val) != 0 && get_int(val) >= 1 && get_int(val) <= 3) { + swap_df0_with_dfx = get_int(val); + printf("[AMIGA] DF0 and DF%d swapped.\n",swap_df0_with_dfx); + } + } + + if CHKVAR("move-slow-to-chip") { + move_slow_to_chip = 1; + printf("[AMIGA] Slow ram moved to Chip.\n"); + } } void handle_reset_amiga(struct emulator_config *cfg) { @@ -531,14 +548,23 @@ void handle_reset_amiga(struct emulator_config *cfg) { ac_z2_current_pic = 0; ac_z3_current_pic = 0; + spoof_df0_id = 0; + DEBUG("[AMIGA] Reset handler.\n"); DEBUG("[AMIGA] AC done - Z2: %d Z3: %d.\n", ac_z2_done, ac_z3_done); if (piscsi_enabled) piscsi_refresh_drives(); - amiga_clear_emulating_irq(); + if (move_slow_to_chip) { + int agnus_rev = ((ps_read_16(0xDFF004) >> 8) & 0x6F); + if (agnus_rev != 0x20) { + move_slow_to_chip = 0; + printf("[AMIGA] Requested move slow ram to chip but 8372 Agnus not found - Disabling.\n"); + } + } + amiga_clear_emulating_irq(); adjust_ranges_amiga(cfg); } @@ -581,6 +607,10 @@ void shutdown_platform_amiga(struct emulator_config *cfg) { kick13_mode = 0; cdtv_mode = 0; + swap_df0_with_dfx = 0; + spoof_df0_id = 0; + move_slow_to_chip = 0; + autoconfig_reset_all(); printf("[AMIGA] Platform shutdown completed.\n"); } diff --git a/platforms/amiga/amiga-registers.h b/platforms/amiga/amiga-registers.h index 2012208..c42a8f7 100644 --- a/platforms/amiga/amiga-registers.h +++ b/platforms/amiga/amiga-registers.h @@ -36,12 +36,18 @@ void adjust_gayle_1200(); #define CIAAICR 0xBFED01 #define CIAACRA 0xBFEE01 #define CIAACRB 0xBFEF01 + +#define CIABPRA 0xBFD000 +#define CIABPRB 0xBFD100 + #define POTGOR 0xDFF016 #define SERDAT 0xDFF030 #define DMACON 0xDFF096 #define DMACONR 0xDFF002 +#define SEL0_BITNUM 3 + /* RAMSEY ADDRESSES */ #define RAMSEY_REG 0xDE0003 /* just a nibble, it should return 0x08 for defaults with 16MB */ #define RAMSEY_ID 0xDE0043 /* Either 0x0D or 0x0F (most recent version) */