diff --git a/src/scamp.c b/src/scamp.c index 6fe9570..d11e3cc 100644 --- a/src/scamp.c +++ b/src/scamp.c @@ -9,12 +9,23 @@ static struct uint8_t cfg_regs[256]; int cfg_enable; + int ram_config; + + mem_mapping_t ram_mapping[2]; + uint32_t ram_virt_base[2], ram_phys_base[2]; + uint32_t ram_mask[2]; + int row_virt_shift[2], row_phys_shift[2]; + int ram_interleaved[2]; + int ibank_shift[2]; + uint8_t port_92; } scamp; #define CFG_ID 0x00 #define CFG_SLTPTR 0x02 #define CFG_RAMMAP 0x03 +#define CFG_EMSEN1 0x0b +#define CFG_EMSEN2 0x0c #define CFG_ABAXS 0x0e #define CFG_CAXS 0x0f #define CFG_DAXS 0x10 @@ -24,6 +35,453 @@ static struct #define RAMMAP_REMP386 (1 << 4) +/*Commodore SL386SX requires proper memory slot decoding to detect memory size. + Therefore we emulate the SCAMP memory address decoding, and therefore are + limited to the DRAM combinations supported by the actual chip*/ +enum +{ + BANK_NONE, + BANK_256K, + BANK_256K_INTERLEAVED, + BANK_1M, + BANK_1M_INTERLEAVED, + BANK_4M, + BANK_4M_INTERLEAVED +}; + +static const struct +{ + int size_kb; + int rammap; + int bank[2]; +} ram_configs[] = +{ + {512, 0x0, {BANK_256K, BANK_NONE}}, + {1024, 0x1, {BANK_256K_INTERLEAVED, BANK_NONE}}, + {1536, 0x2, {BANK_256K_INTERLEAVED, BANK_256K}}, + {2048, 0x3, {BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}}, + {3072, 0xc, {BANK_256K_INTERLEAVED, BANK_1M}}, + {4096, 0x5, {BANK_1M_INTERLEAVED, BANK_NONE}}, + {5120, 0xd, {BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {6144, 0x6, {BANK_1M_INTERLEAVED, BANK_1M}}, + {8192, 0x7, {BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {12288, 0xe, {BANK_1M_INTERLEAVED, BANK_4M}}, + {16384, 0x9, {BANK_4M_INTERLEAVED, BANK_NONE}}, +}; + +static const struct +{ + int bank[2]; + int remapped; +} rammap[16] = +{ + {{BANK_256K, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}, 0}, + + {{BANK_1M, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + + {{BANK_4M, BANK_NONE}, 0}, + {{BANK_4M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_NONE, BANK_4M}, 1}, /*Bank 2 remapped to 0*/ + {{BANK_NONE, BANK_4M_INTERLEAVED}, 1}, /*Banks 2/3 remapped to 0/1*/ + + {{BANK_256K_INTERLEAVED, BANK_1M}, 0}, + {{BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED}, 0}, /*Undocumented - probably wrong!*/ +}; + +/*The column bits masked when using 256kbit DRAMs in 4Mbit mode aren't contiguous, + so we use separate routines for that special case*/ +static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return 0xff; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + return ram[addr + scamp.ram_phys_base[bank]]; +} +static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + ram[addr + scamp.ram_phys_base[bank]] = val; +} + +/*Read/write handlers for interleaved memory banks. We must keep CPU and ram array + mapping linear, otherwise we won't be able to execute code from interleaved banks*/ +static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return 0xff; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = (addr >> (scamp.row_virt_shift[bank]+1)) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + return ram[addr + scamp.ram_phys_base[bank]]; +} +static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = (addr >> (scamp.row_virt_shift[bank]+1)) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + ram[addr + scamp.ram_phys_base[bank]] = val; +} + +static uint8_t ram_mirrored_read(uint32_t addr, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + + return ram[addr + scamp.ram_phys_base[bank]]; +} +static void ram_mirrored_write(uint32_t addr, uint8_t val, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + + ram[addr + scamp.ram_phys_base[bank]] = val; +} + +static void recalc_mappings(void) +{ + int c; + uint32_t virt_base = 0; + uint8_t cur_rammap = scamp.cfg_regs[CFG_RAMMAP] & 0xf; + int bank_nr = 0; + + for (c = 0; c < 2; c++) + mem_mapping_disable(&scamp.ram_mapping[c]); + + /*Once the BIOS programs the correct DRAM configuration, switch to regular + linear memory mapping*/ + if (cur_rammap == ram_configs[scamp.ram_config].rammap) + { + mem_mapping_set_handler(&ram_low_mapping, + mem_read_ram, mem_read_ramw, mem_read_raml, + mem_write_ram, mem_write_ramw, mem_write_raml); + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_enable(&ram_high_mapping); + return; + } + else + { + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_low_mapping); + } + + if (rammap[cur_rammap].bank[0] == BANK_NONE) + bank_nr = 1; + + pclog("Bank remap, cur_rammap=%x\n", cur_rammap); + + for (; bank_nr < 2; bank_nr++) + { + uint32_t old_virt_base = virt_base; + int phys_bank = ram_configs[scamp.ram_config].bank[bank_nr]; + + pclog(" Bank %i: phys_bank=%i rammap_bank=%i virt_base=%08x phys_base=%08x\n", bank_nr, phys_bank, rammap[cur_rammap].bank[bank_nr], virt_base, scamp.ram_phys_base[bank_nr]); + scamp.ram_virt_base[bank_nr] = virt_base; + + if (virt_base == 0) + { + switch (rammap[cur_rammap].bank[bank_nr]) + { + case BANK_NONE: + fatal("Bank 0 is empty!\n"); + break; + + case BANK_256K: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + } + virt_base += 512*1024; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + } + virt_base += 512*1024*2; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_1M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x100000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 2048*1024; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x300000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 2048*1024*2; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_4M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x700000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 8192*1024; + scamp.row_virt_shift[bank_nr] = 12; + break; + + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0xf00000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 8192*1024*2; + scamp.row_virt_shift[bank_nr] = 12; + break; + } + } + else + { + switch (rammap[cur_rammap].bank[bank_nr]) + { + case BANK_NONE: + break; + + case BANK_256K: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x80000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 512*1024; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x100000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 512*1024*2; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_1M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x200000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 2048*1024; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x400000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 2048*1024*2; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_4M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x800000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 8192*1024; + scamp.row_virt_shift[bank_nr] = 12; + break; + + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x1000000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 8192*1024*2; + scamp.row_virt_shift[bank_nr] = 12; + break; + } + } + switch (rammap[cur_rammap].bank[bank_nr]) + { + case BANK_256K: case BANK_1M: case BANK_4M: + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + pclog(" not interleaved\n"); + break; + + case BANK_256K_INTERLEAVED: case BANK_1M_INTERLEAVED: + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + pclog(" interleaved\n"); + break; + + case BANK_4M_INTERLEAVED: + if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) + { + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + pclog(" 256k in 4mi\n"); + } + else + { + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + pclog(" interleaved\n"); + } + break; + } + } +} + +#define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) + static void shadow_control(uint32_t addr, uint32_t size, int state) { // pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); @@ -79,27 +537,10 @@ void scamp_write(uint16_t addr, uint8_t val, void *p) switch (scamp.cfg_index) { case CFG_SLTPTR: -#if 0 - if (!val) - { - /*Disable all RAM*/ - mem_mapping_disable(&ram_low_mapping); - mem_mapping_disable(&ram_high_mapping); - } - else if (val < 0x10) - { - mem_mapping_set_addr(&ram_low_mapping, 0, (val > 9) ? 0xa0000 : (val << 16)); - mem_mapping_disable(&ram_high_mapping); - } - else - { - mem_mapping_enable(&ram_low_mapping); - mem_mapping_enable(&ram_high_mapping); - } -#endif break; case CFG_RAMMAP: + recalc_mappings(); mem_mapping_disable(&ram_remapped_mapping); if (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) { @@ -114,20 +555,20 @@ void scamp_write(uint16_t addr, uint8_t val, void *p) shadow_control(0xb0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); shadow_control(0xb8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); - shadow_control(0xc0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xc4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xc8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xcc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + shadow_control(0xc0000, 0x4000, scamp.cfg_regs[CFG_CAXS] & 3); + shadow_control(0xc4000, 0x4000, (scamp.cfg_regs[CFG_CAXS] >> 2) & 3); + shadow_control(0xc8000, 0x4000, (scamp.cfg_regs[CFG_CAXS] >> 4) & 3); + shadow_control(0xcc000, 0x4000, (scamp.cfg_regs[CFG_CAXS] >> 6) & 3); - shadow_control(0xd0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xd4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xd8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xdc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + shadow_control(0xd0000, 0x4000, scamp.cfg_regs[CFG_DAXS] & 3); + shadow_control(0xd4000, 0x4000, (scamp.cfg_regs[CFG_DAXS] >> 2) & 3); + shadow_control(0xd8000, 0x4000, (scamp.cfg_regs[CFG_DAXS] >> 4) & 3); + shadow_control(0xdc000, 0x4000, (scamp.cfg_regs[CFG_DAXS] >> 6) & 3); - shadow_control(0xe0000, 0x8000, scamp.cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xe8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xf0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xf8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + shadow_control(0xe0000, 0x8000, scamp.cfg_regs[CFG_FEAXS] & 3); + shadow_control(0xe8000, 0x8000, (scamp.cfg_regs[CFG_FEAXS] >> 2) & 3); + shadow_control(0xf0000, 0x8000, (scamp.cfg_regs[CFG_FEAXS] >> 4) & 3); + shadow_control(0xf8000, 0x8000, (scamp.cfg_regs[CFG_FEAXS] >> 6) & 3); } break; @@ -217,6 +658,9 @@ uint8_t scamp_read(uint16_t addr, void *p) void scamp_init(void) { + uint32_t addr; + int c; + memset(&scamp, 0, sizeof(scamp)); scamp.cfg_regs[CFG_ID] = ID_VL82C311; scamp.cfg_enable = 1; @@ -227,4 +671,88 @@ void scamp_init(void) io_sethandler(0x00f4, 0x0002, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); io_sethandler(0x00f9, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); io_sethandler(0x00fb, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + + scamp.ram_config = 0; + + /*Find best fit configuration for the requested memory size*/ + for (c = 0; c < NR_ELEMS(ram_configs); c++) + { + if (mem_size < ram_configs[c].size_kb) + break; + + scamp.ram_config = c; + } + + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_high_mapping); + + addr = 0; + for (c = 0; c < 2; c++) + { + mem_mapping_add(&scamp.ram_mapping[c], 0, 0, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL, + &ram[addr], MEM_MAPPING_INTERNAL, (void *)c); + mem_mapping_disable(&scamp.ram_mapping[c]); + + scamp.ram_phys_base[c] = addr; +// pclog("Bank calc : %i = %08x\n", c ,addr); + + switch (ram_configs[scamp.ram_config].bank[c]) + { + case BANK_NONE: + scamp.ram_mask[c] = 0; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_256K: + addr += 512*1024; + scamp.ram_mask[c] = 0x1ff; + scamp.row_phys_shift[c] = 10; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_256K_INTERLEAVED: + addr += 512*1024*2; + scamp.ram_mask[c] = 0x1ff; + scamp.row_phys_shift[c] = 10; + scamp.ibank_shift[c] = 19; + scamp.ram_interleaved[c] = 1; + break; + + case BANK_1M: + addr += 2048*1024; + scamp.ram_mask[c] = 0x3ff; + scamp.row_phys_shift[c] = 11; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_1M_INTERLEAVED: + addr += 2048*1024*2; + scamp.ram_mask[c] = 0x3ff; + scamp.row_phys_shift[c] = 11; + scamp.ibank_shift[c] = 21; + scamp.ram_interleaved[c] = 1; + break; + + case BANK_4M: + addr += 8192*1024; + scamp.ram_mask[c] = 0x7ff; + scamp.row_phys_shift[c] = 12; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_4M_INTERLEAVED: + addr += 8192*1024*2; + scamp.ram_mask[c] = 0x7ff; + scamp.row_phys_shift[c] = 12; + scamp.ibank_shift[c] = 23; + scamp.ram_interleaved[c] = 1; + break; + } + } + + mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); }