From b9b753c9aa7cc494c889d2114b93680bd38506ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 28 Dec 2020 05:34:33 +0100 Subject: [PATCH] Fixed the SCAMP chipset emulation and the Commodore SL386SX-25 (it was using the SL386SX-16 BIOS), added the SL386-SX16 (NEAT) and the Samsung SPC-4620P, SPC-6033P, and SPC-6000A. --- src/chipset/cs8230.c | 161 ++--- src/chipset/scamp.c | 1146 +++++++++++++++++----------------- src/device/keyboard_at.c | 16 +- src/include/86box/keyboard.h | 1 + src/include/86box/machine.h | 11 +- src/include/86box/video.h | 2 + src/machine/m_at_286_386sx.c | 107 +++- src/machine/m_at_386dx_486.c | 37 +- src/machine/machine_table.c | 10 +- src/mem/mem.c | 29 +- src/video/vid_ati28800.c | 58 +- src/video/vid_cl54xx.c | 2 +- 12 files changed, 900 insertions(+), 680 deletions(-) diff --git a/src/chipset/cs8230.c b/src/chipset/cs8230.c index 90432e271..e7ae64134 100644 --- a/src/chipset/cs8230.c +++ b/src/chipset/cs8230.c @@ -32,124 +32,131 @@ typedef struct { - int idx; - uint8_t regs[256]; + int idx; + uint8_t regs[256]; } cs8230_t; + static void shadow_control(uint32_t addr, uint32_t size, int state) { - switch (state) { - case 0x00: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x01: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 0x10: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 0x11: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - } - flushmmucache_nopc(); + switch (state) { + case 0x00: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x01: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 0x11: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + } + + flushmmucache_nopc(); } static void rethink_shadow_mappings(cs8230_t *cs8230) { - int c; + int c; - for (c = 0; c < 4*8; c++) { /*Addresses 40000-bffff in 16k blocks*/ - if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7))) - mem_set_mem_state(0x40000 + c*0x4000, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /*IO channel*/ - else - mem_set_mem_state(0x40000 + c*0x4000, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /*System board*/ - } - for (c = 0; c < 2*8; c++) { /*Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here*/ - if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7))) - mem_set_mem_state(0xc0000 + c*0x4000, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /*IO channel*/ - else - shadow_control(0xc0000 + c*0x4000, 0x4000, (cs8230->regs[9] >> (3-(c >> 2))) & 0x11); - } + for (c = 0; c < 32; c++) { + /* Addresses 40000-bffff in 16k blocks */ + if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /* I/O channel */ + else + mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /* System board */ + } + + for (c = 0; c < 16; c++) { + /* Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here */ + if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0xc0000 + (c << 14), 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /* I/O channel */ + else + shadow_control(0xc0000 + (c << 14), 0x4000, (cs8230->regs[9] >> (3 - (c >> 2))) & 0x11); + } } + static uint8_t cs8230_read(uint16_t port, void *p) { - cs8230_t *cs8230 = (cs8230_t *)p; - uint8_t ret = 0xff; + cs8230_t *cs8230 = (cs8230_t *) p; + uint8_t ret = 0xff; - if (port & 1) { - switch (cs8230->idx) { - case 0x04: /*82C301 ID/version*/ - ret = cs8230->regs[cs8230->idx] & ~0xe3; - break; + if (port & 1) { + switch (cs8230->idx) { + case 0x04: /* 82C301 ID/version */ + ret = cs8230->regs[cs8230->idx] & ~0xe3; + break; - case 0x08: /*82C302 ID/Version*/ - ret = cs8230->regs[cs8230->idx] & ~0xe0; - break; - - case 0x05: case 0x06: /*82C301 registers*/ - case 0x09: case 0x0a: case 0x0b: case 0x0c: /*82C302 registers*/ - case 0x0d: case 0x0e: case 0x0f: - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x28: case 0x29: case 0x2a: - ret = cs8230->regs[cs8230->idx]; - break; - } + case 0x08: /* 82C302 ID/Version */ + ret = cs8230->regs[cs8230->idx] & ~0xe0; + break; + + case 0x05: case 0x06: /* 82C301 registers */ + case 0x09: case 0x0a: case 0x0b: case 0x0c: /* 82C302 registers */ + case 0x0d: case 0x0e: case 0x0f: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x28: case 0x29: case 0x2a: + ret = cs8230->regs[cs8230->idx]; + break; } + } - return ret; + return ret; } + static void cs8230_write(uint16_t port, uint8_t val, void *p) { - cs8230_t *cs8230 = (cs8230_t *)p; - - if (!(port & 1)) - cs8230->idx = val; - else { - cs8230->regs[cs8230->idx] = val; - switch (cs8230->idx) { - case 0x09: /*RAM/ROM Configuration in boot area*/ - case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /*Address maps*/ - rethink_shadow_mappings(cs8230); - break; - } + cs8230_t *cs8230 = (cs8230_t *)p; + + if (!(port & 1)) + cs8230->idx = val; + else { + cs8230->regs[cs8230->idx] = val; + switch (cs8230->idx) { + case 0x09: /* RAM/ROM Configuration in boot area */ + case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /* Address maps */ + rethink_shadow_mappings(cs8230); + break; } + } } + static void cs8230_close(void *priv) { - cs8230_t *cs8230 = (cs8230_t *)priv; - - free(cs8230); + cs8230_t *cs8230 = (cs8230_t *)priv; + + free(cs8230); } + static void *cs8230_init(const device_t *info) { - cs8230_t *cs8230 = (cs8230_t *)malloc(sizeof(cs8230_t)); - memset(cs8230, 0, sizeof(cs8230_t)); + cs8230_t *cs8230 = (cs8230_t *)malloc(sizeof(cs8230_t)); + memset(cs8230, 0, sizeof(cs8230_t)); - io_sethandler(0x0022, 0x0002, - cs8230_read, NULL, NULL, - cs8230_write, NULL, NULL, - cs8230); + io_sethandler(0x0022, 0x0002, cs8230_read, NULL, NULL, cs8230_write, NULL, NULL, cs8230); - if (mem_size > 768) { - mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); - } + if (mem_size > 768) { + mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); + } - return cs8230; + return cs8230; } + const device_t cs8230_device = { "C&T CS8230 (386/AT)", 0, @@ -157,4 +164,4 @@ const device_t cs8230_device = { cs8230_init, cs8230_close, NULL, { NULL }, NULL, NULL, NULL -}; \ No newline at end of file +}; diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 222b483f9..ea9b68d9a 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -34,28 +34,6 @@ #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct { - void *parent; - int bank; -} ram_struct_t; - -typedef struct { - int cfg_index; - uint8_t cfg_regs[256]; - int cfg_enable; - - int ram_config; - - mem_mapping_t ram_mapping[2]; - - ram_struct_t ram_struct[3]; - - 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]; -} scamp_t; #define CFG_ID 0x00 #define CFG_SLTPTR 0x02 @@ -71,697 +49,745 @@ typedef struct { #define RAMMAP_REMP386 (1 << 4) +#define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) + + /*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 + BANK_NONE, + BANK_256K, + BANK_256K_INTERLEAVED, + BANK_1M, + BANK_1M_INTERLEAVED, + BANK_4M, + BANK_4M_INTERLEAVED }; + +typedef struct { + void * parent; + int bank; +} ram_struct_t; + +typedef struct { + int cfg_index; + uint8_t cfg_regs[256]; + int cfg_enable, ram_config; + + mem_mapping_t ram_mapping[2]; + ram_struct_t ram_struct[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], ibank_shift[2]; + + port_92_t * port_92; +} scamp_t; + static const struct { - int size_kb; - int rammap; - int bank[2]; + 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}}, + {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; + 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_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_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_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!*/ + {{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*/ + +/* 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 *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return 0xff; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return 0xff; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } - return ram[addr + dev->ram_phys_base[bank]]; + return ram[addr + dev->ram_phys_base[bank]]; } + + static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } - ram[addr + dev->ram_phys_base[bank]] = val; + ram[addr + dev->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 *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return 0xff; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return 0xff; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; - - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; - return ram[addr + dev->ram_phys_base[bank]]; + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } + + return ram[addr + dev->ram_phys_base[bank]]; } + + static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } - else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } - ram[addr + dev->ram_phys_base[bank]] = val; + ram[addr + dev->ram_phys_base[bank]] = val; } + static uint8_t ram_mirrored_read(uint32_t addr, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; - - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - return ram[addr + dev->ram_phys_base[bank]]; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + + return ram[addr + dev->ram_phys_base[bank]]; } + + static void ram_mirrored_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - ram[addr + dev->ram_phys_base[bank]] = val; + ram[addr + dev->ram_phys_base[bank]] = val; } + static void recalc_mappings(void *priv) { - scamp_t *dev = (scamp_t *) priv; - int c; - uint32_t virt_base = 0; - uint8_t cur_rammap = dev->cfg_regs[CFG_RAMMAP] & 0xf; - int bank_nr = 0; + scamp_t *dev = (scamp_t *) priv; + int c; + uint32_t virt_base = 0, old_virt_base; + uint8_t cur_rammap = dev->cfg_regs[CFG_RAMMAP] & 0xf; + int bank_nr = 0, phys_bank; + + mem_set_mem_state_both((1 << 20), (16256 - 1024) * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + for (c = 0; c < 2; c++) + mem_mapping_disable(&dev->ram_mapping[c]); + + /* Once the BIOS programs the correct DRAM configuration, switch to regular + linear memory mapping */ + if (cur_rammap == ram_configs[dev->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); + if (mem_size > 1024) + mem_set_mem_state_both((1 << 20), (mem_size - 1024) << 10, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + 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; - for (c = 0; c < 2; c++) - mem_mapping_disable(&dev->ram_mapping[c]); + for (; bank_nr < 2; bank_nr++) { + old_virt_base = virt_base; + phys_bank = ram_configs[dev->ram_config].bank[bank_nr]; - /*Once the BIOS programs the correct DRAM configuration, switch to regular - linear memory mapping*/ - if (cur_rammap == ram_configs[dev->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; + dev->ram_virt_base[bank_nr] = virt_base; -/* 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[dev->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, dev->ram_phys_base[bank_nr]); */ - dev->ram_virt_base[bank_nr] = virt_base; + if (virt_base == 0) { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + fatal(" Bank %i is empty!\n }\n}\n", bank_nr); + break; - 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 *)&dev->ram_struct[bank_nr]); + } + virt_base += (1 << 19); + dev->row_virt_shift[bank_nr] = 10; + 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 *)&dev->ram_struct[bank_nr]); - } - virt_base += 512*1024; - dev->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 *)&dev->ram_struct[bank_nr]); + } + virt_base += (1 << 20); + dev->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 *)&dev->ram_struct[bank_nr]); - } - virt_base += 512*1024*2; - dev->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 *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 21); + dev->row_virt_shift[bank_nr] = 11; + 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 *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 2048*1024; - dev->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 *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (3 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 22); + dev->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 *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 2048*1024*2; - dev->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 *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (7 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 23); + dev->row_virt_shift[bank_nr] = 12; + 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 *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 8192*1024; - dev->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 *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (15 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 24); + dev->row_virt_shift[bank_nr] = 12; + break; + } + } else { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + 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 *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 8192*1024*2; - dev->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(&dev->ram_mapping[bank_nr], virt_base, 0x80000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 19), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 19); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_256K: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x80000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 512*1024; - dev->row_virt_shift[bank_nr] = 10; - break; + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x100000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 20); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_256K_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x100000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 512*1024*2; - dev->row_virt_shift[bank_nr] = 10; - break; + case BANK_1M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x200000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 21), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 21); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_1M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x200000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 2048*1024; - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x400000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 22), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 22); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_1M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x400000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 2048*1024*2; - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_4M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x800000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 23), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 23); + dev->row_virt_shift[bank_nr] = 12; + break; - case BANK_4M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x800000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 8192*1024; - dev->row_virt_shift[bank_nr] = 12; - break; - - case BANK_4M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x1000000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 8192*1024*2; - dev->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(&dev->ram_mapping[bank_nr], + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x1000000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 24), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 24); + dev->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(&dev->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, + 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; + break; - case BANK_256K_INTERLEAVED: case BANK_1M_INTERLEAVED: - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + case BANK_256K_INTERLEAVED: case BANK_1M_INTERLEAVED: + mem_mapping_set_handler(&dev->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, + 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; + break; - case BANK_4M_INTERLEAVED: - if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + case BANK_4M_INTERLEAVED: + if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { + mem_mapping_set_handler(&dev->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, + 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(&dev->ram_mapping[bank_nr], + } else { + mem_mapping_set_handler(&dev->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, + 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; - } - } + } + 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); */ - switch (state) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); + switch (state) { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + + flushmmucache_nopc(); } + static void scamp_write(uint16_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - -/* pclog("scamp_write: addr=%04x val=%02x\n", addr, val); */ - switch (addr) { - case 0xec: - if (dev->cfg_enable) - dev->cfg_index = val; - break; - - case 0xed: - if (dev->cfg_enable) { - if (dev->cfg_index >= 0x02 && dev->cfg_index <= 0x16) { - dev->cfg_regs[dev->cfg_index] = val; -/* pclog("SCAMP CFG[%02x]=%02x\n", dev->cfg_index, val); */ - switch (dev->cfg_index) { - case CFG_SLTPTR: - break; + scamp_t *dev = (scamp_t *) priv; - case CFG_RAMMAP: - recalc_mappings(dev); - mem_mapping_disable(&ram_remapped_mapping); - if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) { - /*Enabling remapping will disable all shadowing*/ - mem_remap_top(384); - shadow_control(0xa0000, 0x60000, 0); - } else { - shadow_control(0xa0000, 0x8000, dev->cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xa8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xb0000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xb8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 6) & 3); + switch (addr) { + case 0xec: + if (dev->cfg_enable) + dev->cfg_index = val; + break; - shadow_control(0xc0000, 0x4000, dev->cfg_regs[CFG_CAXS] & 3); - shadow_control(0xc4000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 2) & 3); - shadow_control(0xc8000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 4) & 3); - shadow_control(0xcc000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 6) & 3); + case 0xed: + if (dev->cfg_enable && (dev->cfg_index >= 0x02) && (dev->cfg_index <= 0x16)) { + dev->cfg_regs[dev->cfg_index] = val; + switch (dev->cfg_index) { + case CFG_SLTPTR: + break; - shadow_control(0xd0000, 0x4000, dev->cfg_regs[CFG_DAXS] & 3); - shadow_control(0xd4000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 2) & 3); - shadow_control(0xd8000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 4) & 3); - shadow_control(0xdc000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 6) & 3); + case CFG_RAMMAP: + recalc_mappings(dev); + mem_mapping_disable(&ram_remapped_mapping); + if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) { + /* Enabling remapping will disable all shadowing */ + mem_remap_top(384); + shadow_control(0xa0000, 0x60000, 0); + } else { + shadow_control(0xa0000, 0x8000, dev->cfg_regs[CFG_ABAXS] & 3); + shadow_control(0xa8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 2) & 3); + shadow_control(0xb0000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 4) & 3); + shadow_control(0xb8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 6) & 3); - shadow_control(0xe0000, 0x8000, dev->cfg_regs[CFG_FEAXS] & 3); - shadow_control(0xe8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 2) & 3); - shadow_control(0xf0000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 4) & 3); - shadow_control(0xf8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 6) & 3); - } - break; + shadow_control(0xc0000, 0x4000, dev->cfg_regs[CFG_CAXS] & 3); + shadow_control(0xc4000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 2) & 3); + shadow_control(0xc8000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 4) & 3); + shadow_control(0xcc000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 6) & 3); - case CFG_ABAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xa0000, 0x8000, val & 3); - shadow_control(0xa8000, 0x8000, (val >> 2) & 3); - shadow_control(0xb0000, 0x8000, (val >> 4) & 3); - shadow_control(0xb8000, 0x8000, (val >> 6) & 3); - } - break; - - case CFG_CAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xc0000, 0x4000, val & 3); - shadow_control(0xc4000, 0x4000, (val >> 2) & 3); - shadow_control(0xc8000, 0x4000, (val >> 4) & 3); - shadow_control(0xcc000, 0x4000, (val >> 6) & 3); - } - break; - - case CFG_DAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xd0000, 0x4000, val & 3); - shadow_control(0xd4000, 0x4000, (val >> 2) & 3); - shadow_control(0xd8000, 0x4000, (val >> 4) & 3); - shadow_control(0xdc000, 0x4000, (val >> 6) & 3); - } - break; - - case CFG_FEAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xe0000, 0x8000, val & 3); - shadow_control(0xe8000, 0x8000, (val >> 2) & 3); - shadow_control(0xf0000, 0x8000, (val >> 4) & 3); - shadow_control(0xf8000, 0x8000, (val >> 6) & 3); - } - break; + shadow_control(0xd0000, 0x4000, dev->cfg_regs[CFG_DAXS] & 3); + shadow_control(0xd4000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 2) & 3); + shadow_control(0xd8000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 4) & 3); + shadow_control(0xdc000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 6) & 3); + + shadow_control(0xe0000, 0x8000, dev->cfg_regs[CFG_FEAXS] & 3); + shadow_control(0xe8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 2) & 3); + shadow_control(0xf0000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 4) & 3); + shadow_control(0xf8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 6) & 3); } - } - } - break; + break; - case 0xee: - if (dev->cfg_enable && mem_a20_alt) - outb(0x92, inb(0x92) & ~2); - break; - } + case CFG_ABAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xa0000, 0x8000, val & 3); + shadow_control(0xa8000, 0x8000, (val >> 2) & 3); + shadow_control(0xb0000, 0x8000, (val >> 4) & 3); + shadow_control(0xb8000, 0x8000, (val >> 6) & 3); + } + break; + + case CFG_CAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xc0000, 0x4000, val & 3); + shadow_control(0xc4000, 0x4000, (val >> 2) & 3); + shadow_control(0xc8000, 0x4000, (val >> 4) & 3); + shadow_control(0xcc000, 0x4000, (val >> 6) & 3); + } + break; + + case CFG_DAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xd0000, 0x4000, val & 3); + shadow_control(0xd4000, 0x4000, (val >> 2) & 3); + shadow_control(0xd8000, 0x4000, (val >> 4) & 3); + shadow_control(0xdc000, 0x4000, (val >> 6) & 3); + } + break; + + case CFG_FEAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xe0000, 0x8000, val & 3); + shadow_control(0xe8000, 0x8000, (val >> 2) & 3); + shadow_control(0xf0000, 0x8000, (val >> 4) & 3); + shadow_control(0xf8000, 0x8000, (val >> 6) & 3); + } + break; + } + } + break; + + case 0xee: + if (dev->cfg_enable && mem_a20_alt) { + dev->port_92->reg &= 0xfd; + mem_a20_alt = 0; + mem_a20_recalc(); + } + break; + } } static uint8_t scamp_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; - - switch (addr) { - case 0xee: - if (!mem_a20_alt) - outb(0x92, inb(0x92) | 2); - break; - - case 0xef: - softresetx86(); - cpu_set_edx(); - break; - } + scamp_t *dev = (scamp_t *) priv; + uint8_t ret = 0xff; -/* pclog("scamp_read: addr=%04x ret=%02x\n", addr, ret); */ - return ret; + switch (addr) { + case 0xed: + if (dev->cfg_enable && (dev->cfg_index >= 0x00) && (dev->cfg_index <= 0x16)) + ret = (dev->cfg_regs[dev->cfg_index]); + break; + + case 0xee: + if (!mem_a20_alt) { + dev->port_92->reg |= 0x02; + mem_a20_alt = 1; + mem_a20_recalc(); + } + break; + + case 0xef: + softresetx86(); + cpu_set_edx(); + break; + } + + return ret; } + static void scamp_close(void *priv) { - scamp_t *dev = (scamp_t *) priv; + scamp_t *dev = (scamp_t *) priv; - free(dev); + free(dev); } static void * scamp_init(const device_t *info) { - uint32_t addr; - int c; - scamp_t *dev = (scamp_t *)malloc(sizeof(scamp_t)); - memset(dev, 0, sizeof(scamp_t)); + uint32_t addr; + int c; + scamp_t *dev = (scamp_t *)malloc(sizeof(scamp_t)); + memset(dev, 0x00, sizeof(scamp_t)); - dev->cfg_regs[CFG_ID] = ID_VL82C311; - dev->cfg_enable = 1; - - io_sethandler(0x00e8, 0x0001, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00ea, 0x0006, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00f4, 0x0002, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00f9, 0x0001, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00fb, 0x0001, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - - dev->ram_config = 0; + dev->cfg_regs[CFG_ID] = ID_VL82C311; + dev->cfg_enable = 1; - /*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; - - dev->ram_config = c; - } + io_sethandler(0x00e8, 0x0001, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00ea, 0x0006, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00f4, 0x0002, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00f9, 0x0001, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00fb, 0x0001, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - mem_mapping_set_handler(&ram_low_mapping, + dev->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; + + dev->ram_config = c; + } + + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[0]); + 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++) { + dev->ram_struct[c].parent = dev; + dev->ram_struct[c].bank = c; + mem_mapping_add(&dev->ram_mapping[c], 0, 0, ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - dev->ram_struct[2].parent = dev; - dev->ram_struct[2].bank = 0; - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[2]); - mem_mapping_disable(&ram_high_mapping); + ram_mirrored_write, NULL, NULL, + &ram[addr], MEM_MAPPING_INTERNAL, (void *) &dev->ram_struct[c]); + mem_mapping_disable(&dev->ram_mapping[c]); - addr = 0; - for (c = 0; c < 2; c++) { - dev->ram_struct[c].parent = dev; - dev->ram_struct[c].bank = c; - mem_mapping_add(&dev->ram_mapping[c], 0, 0, - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL, - &ram[addr], MEM_MAPPING_INTERNAL, (void *) &dev->ram_struct[c]); - mem_mapping_disable(&dev->ram_mapping[c]); - - dev->ram_phys_base[c] = addr; -/* pclog("Bank calc : %i = %08x\n", c ,addr);*/ - - switch (ram_configs[dev->ram_config].bank[c]) { - case BANK_NONE: - dev->ram_mask[c] = 0; - dev->ram_interleaved[c] = 0; - break; - - case BANK_256K: - addr += 512*1024; - dev->ram_mask[c] = 0x1ff; - dev->row_phys_shift[c] = 10; - dev->ram_interleaved[c] = 0; - break; - - case BANK_256K_INTERLEAVED: - addr += 512*1024*2; - dev->ram_mask[c] = 0x1ff; - dev->row_phys_shift[c] = 10; - dev->ibank_shift[c] = 19; - dev->ram_interleaved[c] = 1; - break; + dev->ram_phys_base[c] = addr; - case BANK_1M: - addr += 2048*1024; - dev->ram_mask[c] = 0x3ff; - dev->row_phys_shift[c] = 11; - dev->ram_interleaved[c] = 0; - break; - - case BANK_1M_INTERLEAVED: - addr += 2048*1024*2; - dev->ram_mask[c] = 0x3ff; - dev->row_phys_shift[c] = 11; - dev->ibank_shift[c] = 21; - dev->ram_interleaved[c] = 1; - break; + switch (ram_configs[dev->ram_config].bank[c]) { + case BANK_NONE: + dev->ram_mask[c] = 0; + dev->ram_interleaved[c] = 0; + break; - case BANK_4M: - addr += 8192*1024; - dev->ram_mask[c] = 0x7ff; - dev->row_phys_shift[c] = 12; - dev->ram_interleaved[c] = 0; - break; + case BANK_256K: + addr += (1 << 19); + dev->ram_mask[c] = 0x1ff; + dev->row_phys_shift[c] = 10; + dev->ram_interleaved[c] = 0; + break; - case BANK_4M_INTERLEAVED: - addr += 8192*1024*2; - dev->ram_mask[c] = 0x7ff; - dev->row_phys_shift[c] = 12; - dev->ibank_shift[c] = 23; - dev->ram_interleaved[c] = 1; - break; - } - } - - mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - - return dev; + case BANK_256K_INTERLEAVED: + addr += (1 << 20); + dev->ram_mask[c] = 0x1ff; + dev->row_phys_shift[c] = 10; + dev->ibank_shift[c] = 19; + dev->ram_interleaved[c] = 1; + break; + + case BANK_1M: + addr += (1 << 21); + dev->ram_mask[c] = 0x3ff; + dev->row_phys_shift[c] = 11; + dev->ram_interleaved[c] = 0; + break; + + case BANK_1M_INTERLEAVED: + addr += (1 << 22); + dev->ram_mask[c] = 0x3ff; + dev->row_phys_shift[c] = 11; + dev->ibank_shift[c] = 21; + dev->ram_interleaved[c] = 1; + break; + + case BANK_4M: + addr += (1 << 23); + dev->ram_mask[c] = 0x7ff; + dev->row_phys_shift[c] = 12; + dev->ram_interleaved[c] = 0; + break; + + case BANK_4M_INTERLEAVED: + addr += (1 << 24); + dev->ram_mask[c] = 0x7ff; + dev->row_phys_shift[c] = 12; + dev->ibank_shift[c] = 23; + dev->ram_interleaved[c] = 1; + break; + } + } + + mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + dev->port_92 = device_add(&port_92_device); + + return dev; } @@ -772,4 +798,4 @@ const device_t vlsi_scamp_device = { scamp_init, scamp_close, NULL, { NULL }, NULL, NULL, NULL -}; \ No newline at end of file +}; diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 05a0d6e9e..af2caccbd 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -89,7 +89,8 @@ #define KBC_VEN_ACER 0x1c #define KBC_VEN_INTEL_AMI 0x20 #define KBC_VEN_OLIVETTI 0x24 -#define KBC_VEN_NCR 0x28 +#define KBC_VEN_NCR 0x28 +#define KBC_VEN_SAMSUNG 0x2c #define KBC_VEN_MASK 0x3c @@ -1955,7 +1956,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xaa: /* self-test */ kbd_log("ATkbc: self-test\n"); - if (kbc_ven == KBC_VEN_TOSHIBA) + if ((kbc_ven == KBC_VEN_TOSHIBA) || (kbc_ven == KBC_VEN_SAMSUNG)) dev->status |= STAT_IFULL; if (! dev->initialized) { kbd_log("ATkbc: self-test reinitialization\n"); @@ -2299,6 +2300,7 @@ kbd_init(const device_t *info) case KBC_VEN_AMI: case KBC_VEN_INTEL_AMI: + case KBC_VEN_SAMSUNG: dev->write60_ven = write60_ami; dev->write64_ven = write64_ami; break; @@ -2345,6 +2347,16 @@ const device_t keyboard_at_ami_device = { { NULL }, NULL, NULL, NULL }; +const device_t keyboard_at_samsung_device = { + "PC/AT Keyboard (Samsung)", + 0, + KBC_TYPE_ISA | KBC_VEN_SAMSUNG, + kbd_init, + kbd_close, + kbd_reset, + { NULL }, NULL, NULL, NULL +}; + const device_t keyboard_at_toshiba_device = { "PC/AT Keyboard (Toshiba)", 0, diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 0d5b397e6..6cf841df4 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -72,6 +72,7 @@ extern const device_t keyboard_xt_olivetti_device; extern const device_t keyboard_xt_zenith_device; extern const device_t keyboard_at_device; extern const device_t keyboard_at_ami_device; +extern const device_t keyboard_at_samsung_device; extern const device_t keyboard_at_toshiba_device; extern const device_t keyboard_at_olivetti_device; extern const device_t keyboard_at_ncr_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d50b93f83..56ee11e66 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -251,12 +251,15 @@ extern int machine_at_gw286ct_init(const machine_t *); extern int machine_at_super286tr_init(const machine_t *); extern int machine_at_spc4200p_init(const machine_t *); extern int machine_at_spc4216p_init(const machine_t *); +extern int machine_at_spc4620p_init(const machine_t *); extern int machine_at_kmxc02_init(const machine_t *); extern int machine_at_deskmaster286_init(const machine_t *); extern int machine_at_shuttle386sx_init(const machine_t *); extern int machine_at_adi386sx_init(const machine_t *); -extern int machine_at_commodore_sl386sx_init(const machine_t *); +extern int machine_at_commodore_sl386sx16_init(const machine_t *); +extern int machine_at_commodore_sl386sx25_init(const machine_t *); +extern int machine_at_spc6033p_init(const machine_t *); extern int machine_at_wd76c10_init(const machine_t *); extern int machine_at_olim290_init(const machine_t *); @@ -271,14 +274,16 @@ extern int machine_at_pja511m_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_ama932j_get_device(void); -extern const device_t *at_commodore_sl386sx_get_device(void); +extern const device_t *at_commodore_sl386sx25_get_device(void); +extern const device_t *at_spc4620p_get_device(void); +extern const device_t *at_spc6033p_get_device(void); #endif /* m_at_386dx_486.c */ - extern int machine_at_acc386_init(const machine_t *); extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); +extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_ustechnologies386_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b7c356942..c619d994a 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -205,6 +205,8 @@ extern const device_t ati18800_device; /* ATi 28800 */ extern const device_t ati28800_device; extern const device_t ati28800k_device; +extern const device_t ati28800k_spc4620p_device; +extern const device_t ati28800k_spc6033p_device; extern const device_t compaq_ati28800_device; #if defined(DEV_BRANCH) && defined(USE_XL24) extern const device_t ati28800_wonderxl24_device; diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index b6a40ac4c..ef2de1226 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -37,6 +37,7 @@ #include <86box/fdc.h> #include <86box/hdc.h> #include <86box/sio.h> +#include <86box/serial.h> #include <86box/video.h> #include <86box/flash.h> #include <86box/machine.h> @@ -355,6 +356,34 @@ machine_at_spc4216p_init(const machine_t *model) } +const device_t * +at_spc4620p_get_device(void) +{ + return &ati28800k_spc4620p_device; +} + + +int +machine_at_spc4620p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/spc4620p/31005h.u8", + L"roms/machines/spc4620p/31005h.u10", + 0x000f0000, 131072, 0x8000); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 1); + + if (gfxcard == VID_INTERNAL) + device_add(&ati28800k_spc4620p_device); + + return ret; +} + + int machine_at_kmxc02_init(const machine_t *model) { @@ -458,20 +487,13 @@ machine_at_wd76c10_init(const machine_t *model) } -const device_t * -at_commodore_sl386sx_get_device(void) -{ - return &gd5402_onboard_device; -} - - int -machine_at_commodore_sl386sx_init(const machine_t *model) +machine_at_commodore_sl386sx16_init(const machine_t *model) { int ret; - ret = bios_load_interleaved(L"roms/machines/cbm_sl386sx25/cbm-sl386sx-bios-lo-v1.04-390914-04.bin", - L"roms/machines/cbm_sl386sx25/cbm-sl386sx-bios-hi-v1.04-390915-04.bin", + ret = bios_load_interleaved(L"roms/machines/cbm_sl386sx16/cbm-sl386sx-bios-lo-v1.04-390914-04.bin", + L"roms/machines/cbm_sl386sx16/cbm-sl386sx-bios-hi-v1.04-390915-04.bin", 0x000f0000, 65536, 0); if (bios_only || !ret) @@ -481,7 +503,45 @@ machine_at_commodore_sl386sx_init(const machine_t *model) device_add(&keyboard_at_device); device_add(&fdc_at_device); + device_add(&neat_device); + /* Two serial ports - on the real hardware SL386SX-16, they are on the single UMC UM82C452. */ + device_add_inst(&ns16450_device, 1); + device_add_inst(&ns16450_device, 2); + + return ret; +} + + +static void +machine_at_scamp_common_init(const machine_t *model) +{ + machine_at_common_ide_init(model); + + device_add(&keyboard_ps2_ami_device); + device_add(&fdc_at_device); device_add(&vlsi_scamp_device); +} + + +const device_t * +at_commodore_sl386sx25_get_device(void) +{ + return &gd5402_onboard_device; +} + + +int +machine_at_commodore_sl386sx25_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/cbm_sl386sx25/f000.rom", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scamp_common_init(model); if (gfxcard == VID_INTERNAL) device_add(&gd5402_onboard_device); @@ -490,6 +550,33 @@ machine_at_commodore_sl386sx_init(const machine_t *model) } +const device_t * +at_spc6033p_get_device(void) +{ + return &ati28800k_spc6033p_device; +} + + +int +machine_at_spc6033p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/spc6033p/phoenix.bin", + 0x000f0000, 65536, 0x10000); + + if (bios_only || !ret) + return ret; + + machine_at_scamp_common_init(model); + + if (gfxcard == VID_INTERNAL) + device_add(&ati28800k_spc6033p_device); + + return ret; +} + + int machine_at_awardsx_init(const machine_t *model) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 681e1674b..4a9ed91a5 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -157,12 +157,34 @@ machine_at_ecs386_init(const machine_t *model) machine_at_common_init(model); device_add(&cs8230_device); - device_add(&keyboard_at_ami_device); device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); return ret; } + +int +machine_at_spc6000a_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/spc6000a/3c80.u27", + L"roms/machines/spc6000a/9f80.u26", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 1); + device_add(&cs8230_device); + device_add(&fdc_at_device); + device_add(&keyboard_at_samsung_device); + + return ret; +} + + int machine_at_ustechnologies386_init(const machine_t *model) { @@ -183,6 +205,7 @@ machine_at_ustechnologies386_init(const machine_t *model) return ret; } + int machine_at_rycleopardlx_init(const machine_t *model) { @@ -224,6 +247,7 @@ machine_at_486vchd_init(const machine_t *model) return ret; } + int machine_at_cs4031_init(const machine_t *model) { @@ -243,6 +267,7 @@ machine_at_cs4031_init(const machine_t *model) return ret; } + int machine_at_pb410a_init(const machine_t *model) { @@ -269,6 +294,7 @@ machine_at_pb410a_init(const machine_t *model) return ret; } + #if defined(DEV_BRANCH) && defined(USE_VECT486VL) int machine_at_vect486vl_init(const machine_t *model) // has HDC problems @@ -294,6 +320,7 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems return ret; } + const device_t * at_vect486vl_get_device(void) { @@ -301,6 +328,7 @@ at_vect486vl_get_device(void) } #endif + int machine_at_acera1g_init(const machine_t *model) { @@ -325,6 +353,7 @@ machine_at_acera1g_init(const machine_t *model) return ret; } + const device_t * at_acera1g_get_device(void) { @@ -445,6 +474,7 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } + int machine_at_403tg_init(const machine_t *model) { @@ -466,6 +496,7 @@ machine_at_403tg_init(const machine_t *model) return ret; } + int machine_at_pc330_6571_init(const machine_t *model) // doesn't like every CPU other than the iDX4 and the Intel OverDrive, hangs without a PS/2 mouse { @@ -516,6 +547,7 @@ machine_at_ami471_init(const machine_t *model) return ret; } + int machine_at_vli486sv2g_init(const machine_t *model) { @@ -534,6 +566,7 @@ machine_at_vli486sv2g_init(const machine_t *model) return ret; } + int machine_at_dtk486_init(const machine_t *model) { @@ -891,6 +924,7 @@ machine_at_486vipio2_init(const machine_t *model) } #endif + #if defined(DEV_BRANCH) && defined(USE_M1489) int machine_at_abpb4_init(const machine_t *model) @@ -919,6 +953,7 @@ machine_at_abpb4_init(const machine_t *model) } #endif + #if defined(DEV_BRANCH) && defined(USE_STPC) int machine_at_itoxstar_init(const machine_t *model) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index cadaf7f87..b1483da17 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -133,7 +133,7 @@ const machine_t machines[] = { { "[GC103] Quadtel 286 clone", "quadt286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_quadt286_init, NULL }, { "[GC103] Trigem 286M", "tg286m", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, { "[NEAT] AMI 286 clone", "ami286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[NEAT] NCR 3302", "ncr_3302", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 512, 16384, 128, 127, machine_at_ncr3302_init, NULL }, + { "[NEAT] NCR 3302", "ncr_3302", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 512, 16384, 128, 127, machine_at_ncr3302_init, NULL }, { "[NEAT] Phoenix 286 clone", "px286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_px286_init, NULL }, { "[SCAT] Award 286 clone", "award286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_award286_init, NULL }, { "[SCAT] GW-286CT GEAR", "gw286ct", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_gw286ct_init, NULL }, @@ -141,6 +141,7 @@ const machine_t machines[] = { { "[SCAT] Hyundai Super-286TR", "super286tr", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_super286tr_init, NULL }, { "[SCAT] Samsung SPC-4200P", "spc4200p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL }, { "[SCAT] Samsung SPC-4216P", "spc4216p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 1024, 5120,1024, 127, machine_at_spc4216p_init, NULL }, + { "[SCAT] Samsung SPC-4620P", "spc4620p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 5120,1024, 127, machine_at_spc4620p_init, NULL }, { "[SCAT] Samsung Deskmaster 286", "deskmaster286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_deskmaster286_init, NULL }, /* 286 machines that utilize the MCA bus */ @@ -156,9 +157,11 @@ const machine_t machines[] = { { "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, { "[Intel 82335] ADI 386SX", "adi386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_adi386sx_init, NULL }, { "[Intel 82335] Shuttle 386SX", "shuttle386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_shuttle386sx_init, NULL }, + { "[NEAT] Commodore SL386SX-16", "cbm_sl386sx16", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 8192, 512, 127, machine_at_commodore_sl386sx16_init, NULL }, { "[NEAT] DTK 386SX clone", "dtk386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_init, NULL }, { "[OPTi 291] DTK PPM-3333P", "awardsx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_awardsx_init, NULL }, - { "[SCAMP] Commodore SL386SX", "cbm_sl386sx25", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, + { "[SCAMP] Commodore SL386SX-25", "cbm_sl386sx25", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127, machine_at_commodore_sl386sx25_init, at_commodore_sl386sx25_get_device }, + { "[SCAMP] Samsung SPC-6033P", "spc6033p", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 12288, 2048, 127, machine_at_spc6033p_init, at_spc6033p_get_device }, { "[SCAT] KMX-C-02", "kmxc02", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 512, 127, machine_at_kmxc02_init, NULL }, { "[WD76C10] Amstrad MegaPC", "megapc", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 32768, 1024, 127, machine_at_wd76c10_init, NULL }, @@ -167,7 +170,8 @@ const machine_t machines[] = { /* 386DX machines */ { "[ACC 2168] AMI 386DX clone", "acc386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_acc386_init, NULL }, - { "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_ecs386_init, NULL }, + { "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_ecs386_init, NULL }, + { "[C&T 386] Samsung SPC-6000A", "spc6000a", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_spc6000a_init, NULL }, { "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 1024, 14336, 1024, 127, machine_at_portableiii386_init, at_cpqiii_get_device }, { "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, { "[SiS 310] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_asus386_init, NULL }, diff --git a/src/mem/mem.c b/src/mem/mem.c index 4c9d6a8c2..ae716718e 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -122,6 +122,7 @@ static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; static uint32_t _mem_state[MEM_MAPPINGS_NO]; +static uint32_t remap_start_addr; #ifdef ENABLE_MEM_LOG @@ -1976,8 +1977,7 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv) static uint8_t mem_read_remapped(uint32_t addr, void *priv) { - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) addreadlookup(mem_logical_addr, addr); return ram[addr]; @@ -1987,8 +1987,7 @@ mem_read_remapped(uint32_t addr, void *priv) static uint16_t mem_read_remappedw(uint32_t addr, void *priv) { - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; @@ -1998,8 +1997,7 @@ mem_read_remappedw(uint32_t addr, void *priv) static uint32_t mem_read_remappedl(uint32_t addr, void *priv) { - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; @@ -2010,8 +2008,7 @@ static void mem_write_remapped(uint32_t addr, uint8_t val, void *priv) { uint32_t oldaddr = addr; - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); @@ -2024,8 +2021,7 @@ static void mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) { uint32_t oldaddr = addr; - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); @@ -2038,8 +2034,7 @@ static void mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) { uint32_t oldaddr = addr; - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); @@ -2693,14 +2688,12 @@ mem_reset(void) base_mapping = last_mapping = NULL; - memset(_mem_state, 0x00, sizeof(_mem_state)); + /* Set the entire memory space as external. */ + memset(_mem_state, 0x02, sizeof(_mem_state)); + /* Set the low RAM space as internal. */ mem_set_mem_state_both(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state_both(0x0a0000, 0x60000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - mem_set_mem_state_both((mem_size << 10), (uint32_t) (0x100000000ULL - (mem_size << 10)), - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, @@ -2802,6 +2795,8 @@ mem_remap_top(int kb) if (size > kb) size = kb; + remap_start_addr = start << 10; + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { offset = c - ((start * 1024) >> 12); pages[c].mem = &ram[0xA0000 + (offset << 12)]; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 5dcca426a..da7fc4fcc 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -43,7 +43,12 @@ #endif #define BIOS_ATIKOR_PATH L"roms/video/ati28800/atikorvga.bin" +#define BIOS_ATIKOR_4620P_PATH_L L"roms/machines/spc4620p/31005h.u8" +#define BIOS_ATIKOR_4620P_PATH_H L"roms/machines/spc4620p/31005h.u10" +#define BIOS_ATIKOR_6033P_PATH L"roms/machines/spc6033p/phoenix.bin" #define FONT_ATIKOR_PATH L"roms/video/ati28800/ati_ksc5601.rom" +#define FONT_ATIKOR_4620P_PATH L"roms/machines/spc4620p/svb6120a_font.rom" +#define FONT_ATIKOR_6033P_PATH L"roms/machines/spc6033p/svb6120a_font.rom" #define BIOS_VGAXL_EVEN_PATH L"roms/video/ati28800/xleven.bin" #define BIOS_VGAXL_ODD_PATH L"roms/video/ati28800/xlodd.bin" @@ -80,7 +85,8 @@ typedef struct ati28800_t } ati28800_t; -static video_timings_t timing_ati28800 = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; +static video_timings_t timing_ati28800 = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; +static video_timings_t timing_ati28800_spc = {VIDEO_ISA, 2, 2, 4, 4, 4, 8}; #ifdef ENABLE_ATI28800_LOG @@ -459,9 +465,13 @@ ati28800k_init(const device_t *info) ati28800_t *ati28800 = (ati28800_t *) malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800); - - ati28800->memory = device_get_config_int("memory"); + if (info->local == 0) { + ati28800->memory = device_get_config_int("memory"); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800); + } else { + ati28800->memory = 512; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800_spc); + } ati28800->port_03dd_val = 0; ati28800->get_korean_font_base = 0; @@ -471,8 +481,22 @@ ati28800k_init(const device_t *info) ati28800->in_get_korean_font_kind_set = 0; ati28800->ksc5601_mode_enabled = 0; - rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont(FONT_ATIKOR_PATH, 6); + switch(info->local) { + case 0: + default: + rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_PATH, 6); + break; + case 1: + rom_init_interleaved(&ati28800->bios_rom, BIOS_ATIKOR_4620P_PATH_L, BIOS_ATIKOR_4620P_PATH_H, 0xc0000, + 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_4620P_PATH, 6); + break; + case 2: + rom_init(&ati28800->bios_rom, BIOS_ATIKOR_6033P_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_6033P_PATH, 6); + break; + } svga_init(info, &ati28800->svga, ati28800, ati28800->memory << 10, /*Memory size, default 512KB*/ ati28800k_recalctimings, @@ -709,6 +733,28 @@ const device_t ati28800k_device = ati28800_config }; +const device_t ati28800k_spc4620p_device = +{ + "ATI Korean VGA On-Board SPC-4620P", + DEVICE_ISA, + 1, + ati28800k_init, ati28800_close, NULL, + { NULL }, + ati28800_speed_changed, + ati28800_force_redraw +}; + +const device_t ati28800k_spc6033p_device = +{ + "ATI Korean VGA On-Board SPC-6033P", + DEVICE_ISA, + 2, + ati28800k_init, ati28800_close, NULL, + { NULL }, + ati28800_speed_changed, + ati28800_force_redraw +}; + const device_t compaq_ati28800_device = { "Compaq ATI-28800", diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 96a4e13a1..d08863952 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -42,7 +42,7 @@ #define BIOS_GD5401_PATH L"roms/video/cirruslogic/avga1.rom" #define BIOS_GD5402_PATH L"roms/video/cirruslogic/avga2.rom" -#define BIOS_GD5402_ONBOARD_PATH L"roms/machines/cbm_sl386sx25/Commodore386SX-25_AVGA2.bin" +#define BIOS_GD5402_ONBOARD_PATH L"roms/machines/cbm_sl386sx25/c000.rom" #define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi" #define BIOS_GD5422_PATH L"roms/video/cirruslogic/cl5422.bin" #define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin"