Added emulation of IBM 80386 Memory Expansion Adapter. PS/2 Model 80 now supports up to 12MB RAM.
This commit is contained in:
parent
0c7dc88440
commit
aeccbd8bd6
4 changed files with 144 additions and 12 deletions
|
|
@ -36,7 +36,7 @@ static int _mem_state[0x40000];
|
|||
|
||||
static mem_mapping_t base_mapping;
|
||||
mem_mapping_t ram_low_mapping;
|
||||
static mem_mapping_t ram_high_mapping;
|
||||
mem_mapping_t ram_high_mapping;
|
||||
static mem_mapping_t ram_mid_mapping;
|
||||
static mem_mapping_t ram_remapped_mapping;
|
||||
mem_mapping_t bios_mapping[8];
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ FILE *romfopen(char *fn, char *mode);
|
|||
mem_mapping_t bios_mapping[8];
|
||||
mem_mapping_t bios_high_mapping[8];
|
||||
|
||||
extern mem_mapping_t ram_high_mapping;
|
||||
|
||||
typedef struct page_t
|
||||
{
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ MODEL models[] =
|
|||
/* {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},*/
|
||||
{"Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL},
|
||||
{"AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_headland_init, NULL},
|
||||
{"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 4, 2, ps2_model_80_init, NULL},
|
||||
{"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL},
|
||||
{"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL},
|
||||
{"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL},
|
||||
{"AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL},
|
||||
|
|
|
|||
151
src/ps2_mca.c
151
src/ps2_mca.c
|
|
@ -33,6 +33,8 @@ static struct
|
|||
uint8_t io_id;
|
||||
|
||||
mem_mapping_t shadow_mapping;
|
||||
mem_mapping_t split_mapping;
|
||||
mem_mapping_t expansion_mapping;
|
||||
|
||||
uint8_t (*planar_read)(uint16_t port);
|
||||
void (*planar_write)(uint16_t port, uint8_t val);
|
||||
|
|
@ -40,40 +42,73 @@ static struct
|
|||
uint8_t mem_regs[3];
|
||||
|
||||
uint32_t split_addr;
|
||||
|
||||
uint8_t mem_pos_regs[8];
|
||||
} ps2;
|
||||
|
||||
|
||||
uint8_t ps2_read_shadow_ram(uint32_t addr, void *priv)
|
||||
static uint8_t ps2_read_shadow_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = (addr & 0x1ffff) + 0xe0000;
|
||||
return mem_read_ram(addr, priv);
|
||||
}
|
||||
uint16_t ps2_read_shadow_ramw(uint32_t addr, void *priv)
|
||||
static uint16_t ps2_read_shadow_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = (addr & 0x1ffff) + 0xe0000;
|
||||
return mem_read_ramw(addr, priv);
|
||||
}
|
||||
uint32_t ps2_read_shadow_raml(uint32_t addr, void *priv)
|
||||
static uint32_t ps2_read_shadow_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = (addr & 0x1ffff) + 0xe0000;
|
||||
return mem_read_raml(addr, priv);
|
||||
}
|
||||
void ps2_write_shadow_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
static void ps2_write_shadow_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
addr = (addr & 0x1ffff) + 0xe0000;
|
||||
mem_write_ram(addr, val, priv);
|
||||
}
|
||||
void ps2_write_shadow_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
static void ps2_write_shadow_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
addr = (addr & 0x1ffff) + 0xe0000;
|
||||
mem_write_ramw(addr, val, priv);
|
||||
}
|
||||
void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
static void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
addr = (addr & 0x1ffff) + 0xe0000;
|
||||
mem_write_raml(addr, val, priv);
|
||||
}
|
||||
|
||||
static uint8_t ps2_read_split_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = (addr & 0x3ffff) + 0xa0000;
|
||||
return mem_read_ram(addr, priv);
|
||||
}
|
||||
static uint16_t ps2_read_split_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = (addr & 0x3ffff) + 0xa0000;
|
||||
return mem_read_ramw(addr, priv);
|
||||
}
|
||||
static uint32_t ps2_read_split_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
addr = (addr & 0x3ffff) + 0xa0000;
|
||||
return mem_read_raml(addr, priv);
|
||||
}
|
||||
static void ps2_write_split_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
addr = (addr & 0x3ffff) + 0xa0000;
|
||||
mem_write_ram(addr, val, priv);
|
||||
}
|
||||
static void ps2_write_split_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
addr = (addr & 0x3ffff) + 0xa0000;
|
||||
mem_write_ramw(addr, val, priv);
|
||||
}
|
||||
static void ps2_write_split_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
addr = (addr & 0x3ffff) + 0xa0000;
|
||||
mem_write_raml(addr, val, priv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define PS2_SETUP_IO 0x80
|
||||
|
|
@ -609,7 +644,7 @@ void ps2_mca_board_model_55sx_init()
|
|||
static void mem_encoding_update()
|
||||
{
|
||||
if (ps2.split_addr >= mem_size*1024)
|
||||
mem_set_mem_state(ps2.split_addr, 256 * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
mem_mapping_disable(&ps2.split_mapping);
|
||||
|
||||
ps2.split_addr = (ps2.mem_regs[0] & 0xf) << 20;
|
||||
|
||||
|
|
@ -621,7 +656,7 @@ static void mem_encoding_update()
|
|||
if (!(ps2.mem_regs[1] & 8))
|
||||
{
|
||||
if (ps2.split_addr >= mem_size*1024)
|
||||
mem_set_mem_state(ps2.split_addr, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, 256*1024);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -650,6 +685,24 @@ static void mem_encoding_write(uint16_t addr, uint8_t val, void *p)
|
|||
mem_encoding_update();
|
||||
}
|
||||
|
||||
static uint8_t ps2_mem_expansion_read(int port, void *p)
|
||||
{
|
||||
return ps2.mem_pos_regs[port & 7];
|
||||
}
|
||||
|
||||
static void ps2_mem_expansion_write(int port, uint8_t val, void *p)
|
||||
{
|
||||
if (port < 0x102 || port == 0x104)
|
||||
return;
|
||||
|
||||
ps2.mem_pos_regs[port & 7] = val;
|
||||
|
||||
if (ps2.mem_pos_regs[2] & 1)
|
||||
mem_mapping_enable(&ps2.expansion_mapping);
|
||||
else
|
||||
mem_mapping_disable(&ps2.expansion_mapping);
|
||||
}
|
||||
|
||||
void ps2_mca_board_model_80_type2_init()
|
||||
{
|
||||
ps2_mca_board_common_init();
|
||||
|
|
@ -667,8 +720,86 @@ void ps2_mca_board_model_80_type2_init()
|
|||
|
||||
ps2.mem_regs[1] = 2;
|
||||
|
||||
if (mem_size == 2*1024)
|
||||
switch (mem_size/1024)
|
||||
{
|
||||
case 1:
|
||||
ps2.option[1] = 0x0c;
|
||||
break;
|
||||
case 2:
|
||||
ps2.option[1] = 0x0e;
|
||||
else
|
||||
break;
|
||||
case 3:
|
||||
ps2.option[1] = 0x02;
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
ps2.option[1] = 0x0a;
|
||||
break;
|
||||
}
|
||||
|
||||
mem_mapping_add(&ps2.split_mapping,
|
||||
(mem_size+256) * 1024,
|
||||
256*1024,
|
||||
ps2_read_split_ram,
|
||||
ps2_read_split_ramw,
|
||||
ps2_read_split_raml,
|
||||
ps2_write_split_ram,
|
||||
ps2_write_split_ramw,
|
||||
ps2_write_split_raml,
|
||||
&ram[0xa0000],
|
||||
MEM_MAPPING_INTERNAL,
|
||||
NULL);
|
||||
mem_mapping_disable(&ps2.split_mapping);
|
||||
|
||||
if (mem_size > 4096)
|
||||
{
|
||||
/* Only 4 MB supported on planar, create a memory expansion card for the rest */
|
||||
mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x300000);
|
||||
|
||||
ps2.mem_pos_regs[0] = 0xff;
|
||||
ps2.mem_pos_regs[1] = 0xfc;
|
||||
|
||||
switch (mem_size/1024)
|
||||
{
|
||||
case 5:
|
||||
ps2.mem_pos_regs[4] = 0xfc;
|
||||
break;
|
||||
case 6:
|
||||
ps2.mem_pos_regs[4] = 0xfe;
|
||||
break;
|
||||
case 7:
|
||||
ps2.mem_pos_regs[4] = 0xf2;
|
||||
break;
|
||||
case 8:
|
||||
ps2.mem_pos_regs[4] = 0xfa;
|
||||
break;
|
||||
case 9:
|
||||
ps2.mem_pos_regs[4] = 0xca;
|
||||
break;
|
||||
case 10:
|
||||
ps2.mem_pos_regs[4] = 0xea;
|
||||
break;
|
||||
case 11:
|
||||
ps2.mem_pos_regs[4] = 0x2a;
|
||||
break;
|
||||
case 12:
|
||||
ps2.mem_pos_regs[4] = 0xaa;
|
||||
break;
|
||||
}
|
||||
|
||||
mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL);
|
||||
mem_mapping_add(&ps2.expansion_mapping,
|
||||
0x400000,
|
||||
(mem_size - 4096)*1024,
|
||||
mem_read_ram,
|
||||
mem_read_ramw,
|
||||
mem_read_raml,
|
||||
mem_write_ram,
|
||||
mem_write_ramw,
|
||||
mem_write_raml,
|
||||
&ram[0x400000],
|
||||
MEM_MAPPING_INTERNAL,
|
||||
NULL);
|
||||
mem_mapping_disable(&ps2.expansion_mapping);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue