From f9bd0b844f12ae3349a27e4534d195a07a649f9a Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 21 Aug 2017 18:20:08 +0100 Subject: [PATCH] More SCAT improvements. Patch from Greatpsycho. --- src/scat.c | 118 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/src/scat.c b/src/scat.c index 2bcbb4d..a565047 100644 --- a/src/scat.c +++ b/src/scat.c @@ -15,8 +15,7 @@ static mem_mapping_t scat_mapping[32]; static mem_mapping_t scat_high_mapping[16]; static scat_t scat_stat[32]; static uint32_t scat_xms_bound; -static mem_mapping_t scat_shadowram_mapping; -static mem_mapping_t scat_512k_clip_mapping; +static mem_mapping_t scat_shadowram_mapping[6]; static mem_mapping_t scat_4000_9FFF_mapping[24]; static mem_mapping_t scat_A000_BFFF_mapping; @@ -55,8 +54,9 @@ void scat_shadow_state_update() void scat_set_xms_bound(uint8_t val) { uint32_t max_xms_size = (mem_size >= 16384) ? 0xFC0000 : mem_size << 10; + int i; - switch (val) + switch (val & 0x0F) { case 1: scat_xms_bound = 0x100000; @@ -96,17 +96,21 @@ void scat_set_xms_bound(uint8_t val) break; } - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + if ((val & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) { if (val != 1) { - mem_mapping_enable(&scat_shadowram_mapping); - if (val == 0) + if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); + for(i=0;i<6;i++) + mem_mapping_enable(&scat_shadowram_mapping[i]); + if ((val & 0x0F) == 0) scat_xms_bound = 0x160000; } else { - mem_mapping_disable(&scat_shadowram_mapping); + for(i=0;i<6;i++) + mem_mapping_disable(&scat_shadowram_mapping[i]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); } pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); if (scat_xms_bound > 0x100000) @@ -116,6 +120,10 @@ void scat_set_xms_bound(uint8_t val) } else { + for(i=0;i<6;i++) + mem_mapping_disable(&scat_shadowram_mapping[i]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); + if (scat_xms_bound > max_xms_size) scat_xms_bound = max_xms_size; pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); @@ -129,19 +137,43 @@ void scat_set_xms_bound(uint8_t val) uint32_t get_scat_addr(uint32_t addr, scat_t *p) { if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) - { addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; - } - else if (p == NULL && mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7)) - addr &= 0x7FFFF; - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + + if (mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7 || (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) != 0)) + addr = (addr & ~0x780000) | ((addr & 0x600000) >> 2); + else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) { - if(addr >= 0x100000) addr -= 0x60000; - else if(addr >= 0xA0000) addr = 0xFFFFFFFF; + addr &= ~0x600000; + if(mem_size >= 2048) + addr |= (addr & 0x180000) << 2; } + + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) + addr ^= mem_size < 2048 ? 0x1F0000 : 0x670000; return addr; } +void scat_memmap_state_update() +{ + int i; + uint32_t addr; + + for(i=16;i<24;i++) + { + addr = get_scat_addr(0x40000 + (i << 14), NULL); + mem_mapping_set_exec(&scat_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + } + addr = get_scat_addr(0xA0000, NULL); + mem_mapping_set_exec(&scat_A000_BFFF_mapping, addr < (mem_size << 10) ? ram + addr : NULL); + for(i=0;i<6;i++) + { + addr = get_scat_addr(0x100000 + (i << 16), NULL); + mem_mapping_set_exec(&scat_shadowram_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + } + + flushmmucache(); +} + void scat_set_global_EMS_state(int state) { int i; @@ -172,7 +204,7 @@ void scat_set_global_EMS_state(int state) void scat_write(uint16_t port, uint8_t val, void *priv) { - uint8_t scat_reg_valid = 0, scat_shadow_update = 0, index; + uint8_t scat_reg_valid = 0, scat_shadow_update = 0, scat_map_update = 0, index; uint32_t base_addr, virt_addr; switch (port) @@ -216,31 +248,28 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: - // TODO - Implement mysterious address mapping when lower nibble of this register is 3 or 4 and memory size is greater than 1MB. if((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) { if((val & 0x0F) == 3) { - if(mem_size > 640) mem_mapping_disable(&scat_A000_BFFF_mapping); - if(mem_size > 768) mem_mapping_disable(&ram_mid_mapping); - mem_mapping_enable(&scat_shadowram_mapping); + if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); + for(index=0;index<6;index++) + mem_mapping_enable(&scat_shadowram_mapping[index]); } else { - mem_mapping_disable(&scat_shadowram_mapping); - if(mem_size > 640 && (val & 0x0F) > 3) - { - mem_mapping_enable(&scat_A000_BFFF_mapping); - if(mem_size > 768) mem_mapping_enable(&ram_mid_mapping); - } - } - if(mem_size < 2048) - { - if ((val & 0x0F) > 7) mem_mapping_enable(&scat_512k_clip_mapping); - else mem_mapping_disable(&scat_512k_clip_mapping); + for(index=0;index<6;index++) + mem_mapping_disable(&scat_shadowram_mapping[index]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); } } - flushmmucache(); + else + { + for(index=0;index<6;index++) + mem_mapping_disable(&scat_shadowram_mapping[index]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); + } + scat_map_update = 1; cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; cpu_update_waitstates(); @@ -248,9 +277,9 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; break; case SCAT_EXTENDED_BOUNDARY: - scat_set_xms_bound(val & 0x0f); + scat_set_xms_bound(val & 0x4f); mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - flushmmucache(); + if((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0x40) scat_map_update = 1; scat_reg_valid = 1; break; case SCAT_ROM_ENABLE: @@ -269,6 +298,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) else pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); if (scat_shadow_update) scat_shadow_state_update(); + if (scat_map_update) + scat_memmap_state_update(); // pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); break; @@ -463,14 +494,11 @@ void scat_init() for (i = 0; i < 24; i++) { - if(mem_size > 256 + (i << 4)) - { - mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x40000 + (i << 14), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_4000_9FFF_mapping[i]); - } + mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_4000_9FFF_mapping[i]); } - mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); mem_mapping_enable(&scat_A000_BFFF_mapping); for (i = 0; i < 32; i++) @@ -489,16 +517,8 @@ void scat_init() mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (i << 14), 0, NULL); } - if (mem_size == 1024) - { - mem_mapping_add(&scat_shadowram_mapping, 0x100000, 0x60000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); - } - - // Need to RAM 512kb clipping emulation if only 256KB or 64KB modules installed in memory bank. - // TODO - 512KB clipping should be applied all RAM refer. - mem_mapping_add(&scat_512k_clip_mapping, 0x80000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&scat_512k_clip_mapping); - // --- + for(i=0;i<6;i++) + mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); scat_set_xms_bound(0); scat_shadow_state_update();