#include "ibm.h" #include "io.h" #include "mem.h" #include "sl82c460.h" static struct { int reg_idx; uint8_t regs[256]; } sl82c460; static void sl82c460_shadow_set(uint32_t base, uint32_t size, int state) { switch (state) { case 0: mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); break; case 1: mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); break; case 2: mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); break; case 3: mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); break; } } static void sl82c460_shadow_recalc() { sl82c460_shadow_set(0xc0000, 0x4000, sl82c460.regs[0x18] & 3); sl82c460_shadow_set(0xc4000, 0x4000, (sl82c460.regs[0x18] >> 2) & 3); sl82c460_shadow_set(0xc8000, 0x4000, (sl82c460.regs[0x18] >> 4) & 3); sl82c460_shadow_set(0xcc000, 0x4000, (sl82c460.regs[0x18] >> 6) & 3); sl82c460_shadow_set(0xd0000, 0x4000, sl82c460.regs[0x19] & 3); sl82c460_shadow_set(0xd4000, 0x4000, (sl82c460.regs[0x19] >> 2) & 3); sl82c460_shadow_set(0xd8000, 0x4000, (sl82c460.regs[0x19] >> 4) & 3); sl82c460_shadow_set(0xdc000, 0x4000, (sl82c460.regs[0x19] >> 6) & 3); sl82c460_shadow_set(0xe0000, 0x10000, (sl82c460.regs[0x1b] >> 4) & 3); sl82c460_shadow_set(0xf0000, 0x10000, (sl82c460.regs[0x1b] >> 2) & 3); } static void sl82c460_write(uint16_t addr, uint8_t val, void *p) { if (!(addr & 1)) sl82c460.reg_idx = val; else { // pclog("SL82C460 write %02x %02x\n", sl82c460.reg_idx, val); sl82c460.regs[sl82c460.reg_idx] = val; switch (sl82c460.reg_idx) { case 0x18: case 0x19: case 0x1b: sl82c460_shadow_recalc(); break; } } } static uint8_t sl82c460_read(uint16_t addr, void *p) { if (!(addr & 1)) return sl82c460.reg_idx; return sl82c460.regs[sl82c460.reg_idx]; } void sl82c460_init() { memset(&sl82c460, 0, sizeof(sl82c460)); io_sethandler(0x00a8, 0x0002, sl82c460_read, NULL, NULL, sl82c460_write, NULL, NULL, NULL); }