Improvements to Acermate 386SX25/N :
- Implemented serial & parallel port configuration - Implemented shadow RAM - OTI-067 now configured as on-board device rather than separate card
This commit is contained in:
parent
980fd2dcfa
commit
9dbedefc5f
5 changed files with 147 additions and 6 deletions
127
src/acer386sx.c
127
src/acer386sx.c
|
|
@ -1,22 +1,92 @@
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "device.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "lpt.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "vid_oti067.h"
|
||||||
|
|
||||||
#include "acer386sx.h"
|
#include "acer386sx.h"
|
||||||
|
|
||||||
static int acer_index = 0;
|
static int acer_index = 0;
|
||||||
static uint8_t acer_regs[256];
|
static uint8_t acer_regs[256];
|
||||||
|
static uint8_t acer_last_write;
|
||||||
|
static int acer_locked;
|
||||||
|
static void *acer_oti067;
|
||||||
|
|
||||||
|
void acer386sx_set_oti067(void *oti067)
|
||||||
|
{
|
||||||
|
acer_oti067 = oti067;
|
||||||
|
}
|
||||||
|
|
||||||
void acer386sx_write(uint16_t addr, uint8_t val, void *priv)
|
void acer386sx_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
if (addr & 1)
|
if (addr & 1)
|
||||||
acer_regs[acer_index] = val;
|
{
|
||||||
|
if (acer_locked)
|
||||||
|
{
|
||||||
|
if (acer_last_write == 0x14 && val == 0x09)
|
||||||
|
acer_locked = 0;
|
||||||
|
|
||||||
|
acer_last_write = val;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acer_index == 0xff && val == 0xff)
|
||||||
|
acer_locked = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pclog("Write ACER reg %02x %02x %08x\n", acer_index, val, cs);
|
||||||
|
acer_regs[acer_index] = val;
|
||||||
|
|
||||||
|
switch (acer_index)
|
||||||
|
{
|
||||||
|
case 0xa:
|
||||||
|
switch ((val >> 4) & 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xb:
|
||||||
|
switch ((val >> 4) & 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
acer_index = val;
|
acer_index = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t acer386sx_read(uint16_t addr, void *priv)
|
uint8_t acer386sx_read(uint16_t addr, void *priv)
|
||||||
{
|
{
|
||||||
|
if (acer_locked)
|
||||||
|
return 0xff;
|
||||||
if (addr & 1)
|
if (addr & 1)
|
||||||
{
|
{
|
||||||
if ((acer_index >= 0xc0 || acer_index == 0x20) && cpu_iscyrix)
|
if ((acer_index >= 0xc0 || acer_index == 0x20) && cpu_iscyrix)
|
||||||
|
|
@ -27,7 +97,60 @@ uint8_t acer386sx_read(uint16_t addr, void *priv)
|
||||||
return acer_index;
|
return acer_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t acer386sx_37f = 0, acer386sx_io = 0;
|
||||||
|
void acer386sx_io_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x37f:
|
||||||
|
acer386sx_37f = val;
|
||||||
|
if (val & 4)
|
||||||
|
oti067_enable_disable(acer_oti067, 0);
|
||||||
|
else
|
||||||
|
oti067_enable_disable(acer_oti067, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3f3:
|
||||||
|
acer386sx_io = val;
|
||||||
|
serial1_remove();
|
||||||
|
serial2_remove();
|
||||||
|
lpt1_remove();
|
||||||
|
lpt2_remove();
|
||||||
|
|
||||||
|
switch (val & 3)
|
||||||
|
{
|
||||||
|
case 0: lpt1_init(0x378); break;
|
||||||
|
case 1: lpt1_init(0x3bc); break;
|
||||||
|
case 2: lpt1_init(0x278); break;
|
||||||
|
}
|
||||||
|
if (!(val & 0x04))
|
||||||
|
serial1_set(0x3f8, 4);
|
||||||
|
if (!(val & 0x08))
|
||||||
|
serial2_set(0x2f8, 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t acer386sx_io_read(uint16_t addr, void *priv)
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x37f:
|
||||||
|
return acer386sx_37f;
|
||||||
|
|
||||||
|
case 0x3f3:
|
||||||
|
return acer386sx_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
void acer386sx_init()
|
void acer386sx_init()
|
||||||
{
|
{
|
||||||
io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL);
|
io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL);
|
||||||
|
io_sethandler(0x037f, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL);
|
||||||
|
io_sethandler(0x03f3, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
acer386sx_io = 0;
|
||||||
|
acer386sx_37f = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
void acer386sx_init();
|
void acer386sx_init();
|
||||||
|
void acer386sx_set_oti067(void *oti067);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_oti067.h"
|
#include "vid_oti067.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
|
#include "acer386sx.h"
|
||||||
|
|
||||||
typedef struct oti067_t
|
typedef struct oti067_t
|
||||||
{
|
{
|
||||||
|
|
@ -171,6 +172,21 @@ void *oti067_common_init(char *bios_fn, int vram_size)
|
||||||
return oti067;
|
return oti067;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void oti067_enable_disable(void *p, int enable)
|
||||||
|
{
|
||||||
|
oti067_t *oti067 = (oti067_t *)p;
|
||||||
|
|
||||||
|
mem_mapping_disable(&oti067->bios_rom.mapping);
|
||||||
|
io_removehandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067);
|
||||||
|
io_removehandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067);
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
mem_mapping_enable(&oti067->bios_rom.mapping);
|
||||||
|
io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067);
|
||||||
|
io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void *oti067_init()
|
void *oti067_init()
|
||||||
{
|
{
|
||||||
int vram_size = device_get_config_int("memory");
|
int vram_size = device_get_config_int("memory");
|
||||||
|
|
@ -181,9 +197,8 @@ void *oti067_acer386_init()
|
||||||
{
|
{
|
||||||
oti067_t *oti067 = oti067_common_init("acer386/oti067.bin", 512);
|
oti067_t *oti067 = oti067_common_init("acer386/oti067.bin", 512);
|
||||||
|
|
||||||
if (oti067)
|
acer386sx_set_oti067(oti067);
|
||||||
oti067->bios_rom.rom[0x5d] = 0x74;
|
|
||||||
|
|
||||||
return oti067;
|
return oti067;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
extern device_t oti067_device;
|
extern device_t oti067_device;
|
||||||
extern device_t oti067_acer386_device;
|
extern device_t oti067_acer386_device;
|
||||||
|
|
||||||
|
void oti067_enable_disable(void *p, int enable);
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ void video_init()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_ACER386:
|
case ROM_ACER386:
|
||||||
device_add(&oti067_device);
|
device_add(&oti067_acer386_device);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ROM_IBMPS1_2011:
|
case ROM_IBMPS1_2011:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue