Added Award 286 (using SCAT chipset). Patch from Greatpsycho.
This commit is contained in:
parent
61d7cf2276
commit
9329a997cc
10 changed files with 548 additions and 3 deletions
|
|
@ -235,6 +235,14 @@ ROM files needed:
|
|||
ami286\amic206.bin
|
||||
|
||||
|
||||
Award 286 clone (1990)
|
||||
This is a generic 286 clone with an Award BIOS.
|
||||
|
||||
ROM files needed:
|
||||
|
||||
award286\award.bin
|
||||
|
||||
|
||||
IBM PS/1 Model 2011 (1990)
|
||||
This is a 286 with integrated VGA and a basic GUI and DOS 4.01 in ROM.
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ dac.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.
|
|||
headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c \
|
||||
keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \
|
||||
linux-time.c lpt.c mcr.c mem.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c \
|
||||
olivetti_m24.c opti.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c serial.c sis496.c sound.c \
|
||||
olivetti_m24.c opti.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c scat.c serial.c sis496.c sound.c \
|
||||
sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \
|
||||
sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb.c sound_sb_dsp.c sound_sn76489.c \
|
||||
sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.c thread-pthread.c \
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
|
|||
i430vx.o ide.o intel.o intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o \
|
||||
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \
|
||||
serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \
|
||||
scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \
|
||||
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
|
||||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o \
|
||||
sound_ym7128.o soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
|
|||
i430vx.o ide.o intel.o intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o \
|
||||
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o \
|
||||
mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o \
|
||||
serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \
|
||||
scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \
|
||||
sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
|
||||
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
|
||||
soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ enum
|
|||
ROM_IBMAT,
|
||||
ROM_CMDPC30,
|
||||
ROM_AMI286,
|
||||
ROM_AWARD286,
|
||||
ROM_DELL200,
|
||||
ROM_MISC286,
|
||||
ROM_IBMAT386,
|
||||
|
|
|
|||
|
|
@ -364,6 +364,13 @@ int loadbios()
|
|||
// memset(romext,0x63,0x8000);
|
||||
return 1;
|
||||
|
||||
case ROM_AWARD286:
|
||||
f=romfopen("roms/award286/award.bin","rb");
|
||||
if (!f) break;
|
||||
fread(rom,65536,1,f);
|
||||
fclose(f);
|
||||
return 1;
|
||||
|
||||
case ROM_EUROPC:
|
||||
// return 0;
|
||||
f=romfopen("roms/europc/50145","rb");
|
||||
|
|
|
|||
10
src/model.c
10
src/model.c
|
|
@ -37,6 +37,7 @@
|
|||
#include "piix.h"
|
||||
#include "pit.h"
|
||||
#include "ps1.h"
|
||||
#include "scat.h"
|
||||
#include "serial.h"
|
||||
#include "sis496.h"
|
||||
#include "sound_ps1.h"
|
||||
|
|
@ -60,6 +61,7 @@ void at_init();
|
|||
void deskpro386_init();
|
||||
void ps1_init();
|
||||
void at_neat_init();
|
||||
void at_scat_init();
|
||||
void at_acer386sx_init();
|
||||
void at_wd76c10_init();
|
||||
void at_ali1429_init();
|
||||
|
|
@ -99,6 +101,7 @@ MODEL models[] =
|
|||
{"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_init},
|
||||
{"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_init},
|
||||
{"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_neat_init},
|
||||
{"Award 286 clone", ROM_AWARD286, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_scat_init},
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, 1, 1, 16, 1, at_init},
|
||||
{"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_286, "", NULL, "", NULL}, 1, 1, 1, 16, 1, ps1_init},
|
||||
{"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, 1, 1, 15, 1, deskpro386_init},
|
||||
|
|
@ -301,6 +304,13 @@ void at_neat_init()
|
|||
neat_init();
|
||||
}
|
||||
|
||||
void at_scat_init()
|
||||
{
|
||||
at_init();
|
||||
mouse_serial_init();
|
||||
scat_init();
|
||||
}
|
||||
|
||||
void at_acer386sx_init()
|
||||
{
|
||||
at_init();
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ void loadnvr()
|
|||
case ROM_IBMPS1_2011: f = romfopen("nvr/ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */break;
|
||||
case ROM_CMDPC30: f = romfopen("nvr/cmdpc30.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AMI286: f = romfopen("nvr/ami286.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_AWARD286: f = romfopen("nvr/award286.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_DELL200: f = romfopen("nvr/dell200.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_IBMAT386: f = romfopen("nvr/at386.nvr", "rb"); nvrmask = 127; break;
|
||||
case ROM_DESKPRO_386: f = romfopen("nvr/deskpro386.nvr", "rb"); break;
|
||||
|
|
@ -182,6 +183,7 @@ void savenvr()
|
|||
case ROM_IBMPS1_2011: f = romfopen("nvr/ibmps1_2011.nvr", "wb"); break;
|
||||
case ROM_CMDPC30: f = romfopen("nvr/cmdpc30.nvr", "wb"); break;
|
||||
case ROM_AMI286: f = romfopen("nvr/ami286.nvr", "wb"); break;
|
||||
case ROM_AWARD286: f = romfopen("nvr/award286.nvr", "wb"); break;
|
||||
case ROM_DELL200: f = romfopen("nvr/dell200.nvr", "wb"); break;
|
||||
case ROM_IBMAT386: f = romfopen("nvr/at386.nvr", "wb"); break;
|
||||
case ROM_DESKPRO_386: f = romfopen("nvr/deskpro386.nvr", "wb"); break;
|
||||
|
|
|
|||
495
src/scat.c
Normal file
495
src/scat.c
Normal file
|
|
@ -0,0 +1,495 @@
|
|||
/*This is the chipset used in the Award 286 clone model*/
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "scat.h"
|
||||
#include "mem.h"
|
||||
|
||||
static uint8_t scat_regs[256];
|
||||
static int scat_index;
|
||||
static uint8_t scat_port_92 = 0;
|
||||
static uint8_t scat_ems_reg_2xA = 0;
|
||||
static mem_mapping_t scat_mapping[32];
|
||||
static mem_mapping_t scat_high_mapping[16];
|
||||
static scat_t scat_stat[32];
|
||||
static uint32_t scat_xms_bound;
|
||||
static mem_mapping_t scat_shadowram_mapping;
|
||||
static mem_mapping_t scat_512k_clip_mapping;
|
||||
|
||||
void scat_shadow_state_update()
|
||||
{
|
||||
int i, val, val2;
|
||||
|
||||
// TODO - Segment A000 to BFFF shadow ram enable features and ROM enable features should be implemented later.
|
||||
for (i = 8; i < 24; i++)
|
||||
{
|
||||
val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL;
|
||||
if (i < 8)
|
||||
{
|
||||
val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((scat_regs[0x49] >> ((i - 8) >> 1)) & 1)
|
||||
{
|
||||
val |= MEM_WRITE_DISABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL;
|
||||
}
|
||||
mem_set_mem_state((i + 40) << 14, 0x4000, val);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void scat_set_xms_bound(uint8_t val)
|
||||
{
|
||||
uint32_t max_xms_size = (mem_size >= 16384) ? 0xFC0000 : mem_size << 10;
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case 1:
|
||||
scat_xms_bound = 0x100000;
|
||||
break;
|
||||
case 2:
|
||||
scat_xms_bound = 0x140000;
|
||||
break;
|
||||
case 3:
|
||||
scat_xms_bound = 0x180000;
|
||||
break;
|
||||
case 4:
|
||||
scat_xms_bound = 0x200000;
|
||||
break;
|
||||
case 5:
|
||||
scat_xms_bound = 0x300000;
|
||||
break;
|
||||
case 6:
|
||||
scat_xms_bound = 0x400000;
|
||||
break;
|
||||
case 7:
|
||||
scat_xms_bound = 0x600000;
|
||||
break;
|
||||
case 8:
|
||||
scat_xms_bound = 0x800000;
|
||||
break;
|
||||
case 9:
|
||||
scat_xms_bound = 0xA00000;
|
||||
break;
|
||||
case 10:
|
||||
scat_xms_bound = 0xC00000;
|
||||
break;
|
||||
case 11:
|
||||
scat_xms_bound = 0xE00000;
|
||||
break;
|
||||
default:
|
||||
scat_xms_bound = (mem_size >= 16384 ? 0xFC0000 : mem_size << 10);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3)
|
||||
{
|
||||
if (val != 1)
|
||||
{
|
||||
mem_mapping_enable(&scat_shadowram_mapping);
|
||||
if (val == 0)
|
||||
scat_xms_bound = 0x160000;
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_mapping_disable(&scat_shadowram_mapping);
|
||||
}
|
||||
pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10);
|
||||
if (scat_xms_bound > 0x100000)
|
||||
mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
if (scat_xms_bound < 0x160000)
|
||||
mem_set_mem_state(scat_xms_bound, 0x160000 - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scat_xms_bound > max_xms_size)
|
||||
scat_xms_bound = max_xms_size;
|
||||
pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10);
|
||||
if (scat_xms_bound > 0x100000)
|
||||
mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
if (scat_xms_bound < (mem_size << 10))
|
||||
mem_set_mem_state(scat_xms_bound, (mem_size << 10) - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t get_scat_addr(uint32_t addr, scat_t *p)
|
||||
{
|
||||
if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80))
|
||||
{
|
||||
addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14;
|
||||
}
|
||||
else if (p == NULL && mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7))
|
||||
addr &= 0x7FFFF;
|
||||
if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && addr >= 0x100000)
|
||||
addr -= 0x60000;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void scat_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t scat_reg_valid = 0, scat_shadow_update = 0, index;
|
||||
uint32_t base_addr, virt_addr;
|
||||
|
||||
switch (port)
|
||||
{
|
||||
case 0x22:
|
||||
scat_index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
switch (scat_index)
|
||||
{
|
||||
case SCAT_CLOCK_CONTROL:
|
||||
case SCAT_PERIPHERAL_CONTROL:
|
||||
case SCAT_EMS_CONTROL:
|
||||
scat_reg_valid = 1;
|
||||
break;
|
||||
case SCAT_POWER_MANAGEMENT:
|
||||
val &= 0x40; // TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later.
|
||||
scat_reg_valid = 1;
|
||||
break;
|
||||
case SCAT_DRAM_CONFIGURATION:
|
||||
if((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0)
|
||||
{
|
||||
if((val & 0x0F) == 3)
|
||||
{
|
||||
mem_mapping_enable(&scat_shadowram_mapping);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_mapping_disable(&scat_shadowram_mapping);
|
||||
}
|
||||
if(mem_size < 2048)
|
||||
{
|
||||
if ((val & 0x0F) > 7) mem_mapping_enable(&scat_512k_clip_mapping);
|
||||
else mem_mapping_disable(&scat_512k_clip_mapping);
|
||||
}
|
||||
}
|
||||
flushmmucache();
|
||||
scat_reg_valid = 1;
|
||||
break;
|
||||
case SCAT_EXTENDED_BOUNDARY:
|
||||
scat_set_xms_bound(val & 0x0f);
|
||||
mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
flushmmucache();
|
||||
scat_reg_valid = 1;
|
||||
break;
|
||||
case SCAT_ROM_ENABLE:
|
||||
case SCAT_RAM_WRITE_PROTECT:
|
||||
case SCAT_SHADOW_RAM_ENABLE_1:
|
||||
case SCAT_SHADOW_RAM_ENABLE_2:
|
||||
case SCAT_SHADOW_RAM_ENABLE_3:
|
||||
scat_reg_valid = 1;
|
||||
scat_shadow_update = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (scat_reg_valid)
|
||||
scat_regs[scat_index] = val;
|
||||
if (scat_shadow_update)
|
||||
scat_shadow_state_update();
|
||||
pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, pc);
|
||||
break;
|
||||
|
||||
case 0x92:
|
||||
if ((mem_a20_key ^ val) & 2)
|
||||
{
|
||||
mem_a20_alt = val & 2;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
if ((~scat_port_92 & val) & 1)
|
||||
{
|
||||
softresetx86();
|
||||
}
|
||||
scat_port_92 = val;
|
||||
break;
|
||||
|
||||
case 0x208:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40)
|
||||
{
|
||||
pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
scat_stat[index].regs_2x8 = val;
|
||||
}
|
||||
break;
|
||||
case 0x209:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40)
|
||||
{
|
||||
pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
scat_stat[index].regs_2x9 = val;
|
||||
base_addr = (index + 16) << 14;
|
||||
if(index >= 24)
|
||||
base_addr += 0x30000;
|
||||
|
||||
if (val & 0x80)
|
||||
{
|
||||
virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14;
|
||||
mem_mapping_enable(&scat_mapping[index]);
|
||||
mem_mapping_set_exec(&scat_mapping[index], ram + get_scat_addr(virt_addr, &scat_stat[index]));
|
||||
pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_mapping_disable(&scat_mapping[index]);
|
||||
pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr);
|
||||
}
|
||||
|
||||
if (scat_ems_reg_2xA & 0x80)
|
||||
{
|
||||
scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & 0x1f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x20A:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40)
|
||||
{
|
||||
pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, pc);
|
||||
scat_ems_reg_2xA = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x218:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41)
|
||||
{
|
||||
pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
scat_stat[index].regs_2x8 = val;
|
||||
}
|
||||
break;
|
||||
case 0x219:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41)
|
||||
{
|
||||
pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
scat_stat[index].regs_2x9 = val;
|
||||
base_addr = (index + 16) << 14;
|
||||
if (index >= 24)
|
||||
base_addr += 0x30000;
|
||||
|
||||
if (val & 0x80)
|
||||
{
|
||||
virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14;
|
||||
mem_mapping_enable(&scat_mapping[index]);
|
||||
mem_mapping_set_exec(&scat_mapping[index], ram + get_scat_addr(virt_addr, &scat_stat[index]));
|
||||
pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_mapping_disable(&scat_mapping[index]);
|
||||
pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr);
|
||||
}
|
||||
|
||||
if (scat_ems_reg_2xA & 0x80)
|
||||
{
|
||||
scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & 0x1f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x21A:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41)
|
||||
{
|
||||
pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, pc);
|
||||
scat_ems_reg_2xA = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t scat_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t val = 0xff, index;
|
||||
switch (port)
|
||||
{
|
||||
case 0x23:
|
||||
switch (scat_index)
|
||||
{
|
||||
case SCAT_MISCELLANEOUS_STATUS:
|
||||
val = (scat_regs[scat_index] & 0xbf) | ((scat_port_92 & 2) << 5);
|
||||
break;
|
||||
default:
|
||||
val = scat_regs[scat_index];
|
||||
break;
|
||||
}
|
||||
pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, pc);
|
||||
break;
|
||||
|
||||
case 0x92:
|
||||
val = scat_port_92;
|
||||
break;
|
||||
|
||||
case 0x208:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40)
|
||||
{
|
||||
pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
val = scat_stat[index].regs_2x8;
|
||||
}
|
||||
break;
|
||||
case 0x209:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40)
|
||||
{
|
||||
pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
val = scat_stat[index].regs_2x9;
|
||||
}
|
||||
break;
|
||||
case 0x20A:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40)
|
||||
{
|
||||
pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, pc);
|
||||
val = scat_ems_reg_2xA;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x218:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41)
|
||||
{
|
||||
pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
val = scat_stat[index].regs_2x8;
|
||||
}
|
||||
break;
|
||||
case 0x219:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41)
|
||||
{
|
||||
pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, pc);
|
||||
index = scat_ems_reg_2xA & 0x1F;
|
||||
val = scat_stat[index].regs_2x9;
|
||||
}
|
||||
break;
|
||||
case 0x21A:
|
||||
if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41)
|
||||
{
|
||||
pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, pc);
|
||||
val = scat_ems_reg_2xA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
uint8_t mem_read_scatems(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t val = 0xff;
|
||||
scat_t *stat = (scat_t *)priv;
|
||||
|
||||
addr = get_scat_addr(addr, stat);
|
||||
if (addr < (mem_size << 10))
|
||||
val = mem_read_ram(addr, priv);
|
||||
|
||||
return val;
|
||||
}
|
||||
uint16_t mem_read_scatemsw(uint32_t addr, void *priv)
|
||||
{
|
||||
uint16_t val = 0xffff;
|
||||
scat_t *stat = (scat_t *)priv;
|
||||
|
||||
addr = get_scat_addr(addr, stat);
|
||||
if (addr < (mem_size << 10))
|
||||
val = mem_read_ramw(addr, priv);
|
||||
|
||||
return val;
|
||||
}
|
||||
uint32_t mem_read_scatemsl(uint32_t addr, void *priv)
|
||||
{
|
||||
uint32_t val = 0xffffffff;
|
||||
scat_t *stat = (scat_t *)priv;
|
||||
|
||||
addr = get_scat_addr(addr, stat);
|
||||
if (addr < (mem_size << 10))
|
||||
val = mem_read_raml(addr, priv);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void mem_write_scatems(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
scat_t *stat = (scat_t *)priv;
|
||||
|
||||
addr = get_scat_addr(addr, stat);
|
||||
if (addr < (mem_size << 10))
|
||||
mem_write_ram(addr, val, priv);
|
||||
}
|
||||
void mem_write_scatemsw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
scat_t *stat = (scat_t *)priv;
|
||||
|
||||
addr = get_scat_addr(addr, stat);
|
||||
if (addr < (mem_size << 10))
|
||||
mem_write_ramw(addr, val, priv);
|
||||
}
|
||||
void mem_write_scatemsl(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
scat_t *stat = (scat_t *)priv;
|
||||
|
||||
addr = get_scat_addr(addr, stat);
|
||||
if (addr < (mem_size << 10))
|
||||
mem_write_raml(addr, val, priv);
|
||||
}
|
||||
|
||||
void scat_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0092, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
scat_regs[i] = 0xff;
|
||||
}
|
||||
|
||||
scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0;
|
||||
scat_regs[SCAT_VERSION] = 10;
|
||||
scat_regs[SCAT_CLOCK_CONTROL] = 2;
|
||||
scat_regs[SCAT_PERIPHERAL_CONTROL] = 0x80;
|
||||
scat_regs[SCAT_MISCELLANEOUS_STATUS] = 0x37;
|
||||
scat_regs[SCAT_POWER_MANAGEMENT] = 0;
|
||||
scat_regs[SCAT_ROM_ENABLE] = 0xC0;
|
||||
scat_regs[SCAT_RAM_WRITE_PROTECT] = 0;
|
||||
scat_regs[SCAT_SHADOW_RAM_ENABLE_1] = 0;
|
||||
scat_regs[SCAT_SHADOW_RAM_ENABLE_2] = 0;
|
||||
scat_regs[SCAT_SHADOW_RAM_ENABLE_3] = 0;
|
||||
scat_regs[SCAT_DRAM_CONFIGURATION] = 2;
|
||||
scat_regs[SCAT_EXTENDED_BOUNDARY] = 0;
|
||||
scat_regs[SCAT_EMS_CONTROL] = 0;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
scat_stat[i].regs_2x8 = 0xff;
|
||||
scat_stat[i].regs_2x9 = 0x03;
|
||||
mem_mapping_add(&scat_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]);
|
||||
mem_mapping_disable(&scat_mapping[i]);
|
||||
}
|
||||
|
||||
// TODO - Only normal CPU accessing address FF0000 to FFFFFF mapped to ROM. Normal CPU accessing address FC0000 to FEFFFF map to ROM should be implemented later.
|
||||
for (i = 12; i < 16; i++)
|
||||
{
|
||||
mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (i << 14), 0, NULL);
|
||||
}
|
||||
|
||||
if (mem_size == 1024)
|
||||
{
|
||||
mem_mapping_add(&scat_shadowram_mapping, 0x100000, 0x60000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL);
|
||||
}
|
||||
|
||||
// Need to RAM 512kb clipping emulation if only 256KB or 64KB modules installed in memory bank.
|
||||
// TODO - 512KB clipping should be applied all RAM refer.
|
||||
mem_mapping_add(&scat_512k_clip_mapping, 0x80000, 0x20000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram, MEM_MAPPING_INTERNAL, NULL);
|
||||
mem_mapping_disable(&scat_512k_clip_mapping);
|
||||
// ---
|
||||
|
||||
scat_set_xms_bound(0);
|
||||
scat_shadow_state_update();
|
||||
}
|
||||
22
src/scat.h
Normal file
22
src/scat.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#define SCAT_DMA_WAIT_STATE_CONTROL 0x01
|
||||
#define SCAT_VERSION 0x40
|
||||
#define SCAT_CLOCK_CONTROL 0x41
|
||||
#define SCAT_PERIPHERAL_CONTROL 0x44
|
||||
#define SCAT_MISCELLANEOUS_STATUS 0x45
|
||||
#define SCAT_POWER_MANAGEMENT 0x46
|
||||
#define SCAT_ROM_ENABLE 0x48
|
||||
#define SCAT_RAM_WRITE_PROTECT 0x49
|
||||
#define SCAT_SHADOW_RAM_ENABLE_1 0x4A
|
||||
#define SCAT_SHADOW_RAM_ENABLE_2 0x4B
|
||||
#define SCAT_SHADOW_RAM_ENABLE_3 0x4C
|
||||
#define SCAT_DRAM_CONFIGURATION 0x4D
|
||||
#define SCAT_EXTENDED_BOUNDARY 0x4E
|
||||
#define SCAT_EMS_CONTROL 0x4F
|
||||
|
||||
typedef struct scat_t
|
||||
{
|
||||
uint8_t regs_2x8;
|
||||
uint8_t regs_2x9;
|
||||
} scat_t;
|
||||
|
||||
void scat_init();
|
||||
Loading…
Reference in a new issue