Implemented some Olivetti M300-family machines.

Implemented NCR PC916SX
Implemented PC87310 SuperIO
This commit is contained in:
EngiNerd89
2021-01-17 14:39:45 +01:00
parent 8c2c4fb9aa
commit a4de9d514b
11 changed files with 620 additions and 56 deletions

View File

@@ -1207,9 +1207,12 @@ write64_generic(void *priv, uint8_t val)
* bit 6: display type (0 color, 1 mono)
* bit 5: power-on default speed (0 high, 1 low)
* bit 4: sense RAM size (0 unsupported, 1 512k on system board)
* bits 0-3: unused
* bit 3: coprocessor detect
* bit 2: unused
* bit 1: high/auto speed
* bit 0: dma mode
*/
add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits | (video_is_mda() ? 0x40 : 0x00)) & 0xdf);
add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits | (video_is_mda() ? 0x40 : 0x00) | (hasfpu ? 0x08 : 0x00)) & 0xdf);
dev->input_port = ((dev->input_port + 1) & 3) |
(dev->input_port & 0xfc);
} else {
@@ -1507,6 +1510,29 @@ write60_quadtel(void *priv, uint8_t val)
return 1;
}
static uint8_t
write64_olivetti(void *priv, uint8_t val)
{
atkbd_t *dev = (atkbd_t *)priv;
switch (val) {
case 0x80: /* Olivetti-specific command */
/*
* bit 7: bus expansion board present (M300) / keyboard unlocked (M290)
* bits 4-6: ???
* bit 3: fast ram check (if inactive keyboard works erratically)
* bit 2: keyboard fuse present
* bits 0-1: ???
*/
add_to_kbc_queue_front(dev, (0x0c | ((is386) ? 0x00 : 0x80)) & 0xdf);
dev->input_port = ((dev->input_port + 1) & 3) |
(dev->input_port & 0xfc);
return 0;
}
return write64_generic(dev, val);
}
static uint8_t
write64_quadtel(void *priv, uint8_t val)
@@ -2290,13 +2316,16 @@ kbd_init(const device_t *info)
switch(dev->flags & KBC_VEN_MASK) {
case KBC_VEN_ACER:
case KBC_VEN_GENERIC:
case KBC_VEN_OLIVETTI:
case KBC_VEN_NCR:
case KBC_VEN_IBM_PS1:
case KBC_VEN_XI8088:
dev->write64_ven = write64_generic;
break;
case KBC_VEN_OLIVETTI:
dev->write64_ven = write64_olivetti;
break;
case KBC_VEN_AMI:
case KBC_VEN_INTEL_AMI:
case KBC_VEN_SAMSUNG:
@@ -2446,6 +2475,16 @@ const device_t keyboard_ps2_ami_device = {
{ NULL }, NULL, NULL, NULL
};
const device_t keyboard_ps2_olivetti_device = {
"PS/2 Keyboard (Olivetti)",
0,
KBC_TYPE_PS2_NOREF | KBC_VEN_OLIVETTI,
kbd_init,
kbd_close,
kbd_reset,
{ NULL }, NULL, NULL, NULL
};
const device_t keyboard_ps2_mca_device = {
"PS/2 Keyboard",
0,

View File

@@ -2165,20 +2165,26 @@ fdc_set_base(fdc_t *fdc, int base)
{
int super_io = (fdc->flags & FDC_FLAG_SUPERIO);
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_sethandler(base + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_sethandler(base, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_sethandler(base + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_sethandler(base + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_sethandler(base + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_NSC) {
io_sethandler(base + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_sethandler(base + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_sethandler(base, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_sethandler(base + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_sethandler(base + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_sethandler(base + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
}
}
fdc->base_address = base;
fdc_log("FDC Base address set%s (%04X)\n", super_io ? " for Super I/O" : "", fdc->base_address);
}
@@ -2190,20 +2196,26 @@ fdc_remove(fdc_t *fdc)
int super_io = (fdc->flags & FDC_FLAG_SUPERIO);
fdc_log("FDC Removed (%04X)\n", fdc->base_address);
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_removehandler(fdc->base_address + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_removehandler(fdc->base_address, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_removehandler(fdc->base_address + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_removehandler(fdc->base_address + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_NSC) {
io_removehandler(fdc->base_address + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_removehandler(fdc->base_address + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if (fdc->flags & FDC_FLAG_PCJR)
io_removehandler(fdc->base_address, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
io_removehandler(fdc->base_address + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
io_removehandler(fdc->base_address + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
}
}
}

View File

@@ -82,6 +82,7 @@ extern const device_t keyboard_ps2_ps1_pci_device;
extern const device_t keyboard_ps2_ps2_device;
extern const device_t keyboard_ps2_xi8088_device;
extern const device_t keyboard_ps2_ami_device;
extern const device_t keyboard_ps2_olivetti_device;
extern const device_t keyboard_ps2_mca_device;
extern const device_t keyboard_ps2_mca_2_device;
extern const device_t keyboard_ps2_quadtel_device;

View File

@@ -244,6 +244,11 @@ extern int machine_at_mr286_init(const machine_t *);
extern int machine_at_neat_init(const machine_t *);
extern int machine_at_neat_ami_init(const machine_t *);
extern int machine_at_olim300_05_init(const machine_t *);
extern int machine_at_olim300_10_init(const machine_t *);
extern int machine_at_olim300_08_init(const machine_t *);
extern int machine_at_olim300_15_init(const machine_t *);
extern int machine_at_ncrpc916sx_init(const machine_t *);
extern int machine_at_award286_init(const machine_t *);
extern int machine_at_gdc212m_init(const machine_t *);
@@ -263,6 +268,8 @@ 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 *);
extern int machine_at_olim290s_init(const machine_t *);
extern int machine_at_ncrpc8_init(const machine_t *);
extern int machine_at_ncr3302_init(const machine_t *);
@@ -277,6 +284,7 @@ extern const device_t *at_ama932j_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);
extern const device_t *at_m300_08_get_device(void);
#endif
/* m_at_386dx_486.c */

View File

@@ -43,6 +43,8 @@ extern const device_t pc87307_15c_device;
extern const device_t pc87307_both_device;
extern const device_t pc87309_device;
extern const device_t pc87309_15c_device;
extern const device_t pc87310_device;
extern const device_t pc87310_ide_device;
extern const device_t pc87311_device;
extern const device_t pc87311_ide_device;
extern const device_t pc87332_device;

View File

@@ -292,6 +292,7 @@ extern const device_t oti037c_device;
extern const device_t oti067_device;
extern const device_t oti067_acer386_device;
extern const device_t oti067_ama932j_device;
extern const device_t oti067_m300_device;
extern const device_t oti077_device;
/* Paradise/WD (S)VGA */

View File

@@ -643,31 +643,10 @@ machine_at_pja511m_init(const machine_t *model)
}
#endif
int
machine_at_olim290_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&keyboard_at_olivetti_device);
device_add(&fdc_at_device);
device_add(&olivetti_m290_registers_device);
return ret;
}
/*
* Current bugs:
* - ctrl-alt-del produces an 8042 error
* - Automatic soft-reboot after saving CMOS settings produces an 8042 error
* - no EMS management due to missing chipset implementation
*/
int
machine_at_ncrpc8_init(const machine_t *model)
@@ -690,7 +669,7 @@ machine_at_ncrpc8_init(const machine_t *model)
/*
* Current bugs:
* - ctrl-alt-del produces an 8042 error
* - Automatic soft-reboot after saving CMOS settings produces an 8042 error
*/
int
machine_at_ncr3302_init(const machine_t *model)
@@ -718,3 +697,202 @@ machine_at_ncr3302_init(const machine_t *model)
return ret;
}
/*
* Current bugs:
* - Automatic soft-reboot after saving CMOS settings produces an 8042 error
* - no EMS management due to missing chipset implementation (TACT82300)
*/
int
machine_at_ncrpc916sx_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved(L"roms/machines/ncr_pc916sx/ncr_386sx_u46-17_7.3.bin",
L"roms/machines/ncr_pc916sx/ncr_386sx_u12-19_7.3.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&keyboard_at_ncr_device);
device_add(&fdc_at_device);
return ret;
}
/*
* Current bugs:
* - no EMS management due to missing chipset implementation (custom ASIC)
*/
int
machine_at_olim290_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&keyboard_at_olivetti_device);
device_add(&fdc_at_device);
device_add(&olivetti_m290_registers_device);
return ret;
}
/*
* Current bugs:
* - no EMS management due to missing chipset implementation (TACT82300)
*/
int
machine_at_olim290s_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved(L"roms/machines/olivetti_m290s/286-olivetti-m203-low.bin",
L"roms/machines/olivetti_m290s/286-olivetti-m203-high.bin",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
device_add(&keyboard_ps2_olivetti_device);
device_add(&fdc_at_device);
if (gfxcard == VID_INTERNAL)
/* should use custom BIOS */
device_add(&paradise_pvga1a_device);
return ret;
}
const device_t *
at_m300_08_get_device(void)
{
return &oti067_m300_device;
}
int
machine_at_olim300_08_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m300_08/BIOS.ROM",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&opti283_device);
device_add(&keyboard_ps2_olivetti_device);
device_add(&pc87310_ide_device);
if (gfxcard == VID_INTERNAL)
device_add(&oti067_m300_device);
return ret;
}
/* Almost identical to M300-08, save for CPU speed, VRAM, and BIOS identification string */
int
machine_at_olim300_15_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m300_15/BIOS.ROM",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&opti283_device);
device_add(&keyboard_ps2_olivetti_device);
device_add(&pc87310_ide_device);
if (gfxcard == VID_INTERNAL)
/* Stock VRAM is maxed out, so no need to expose video card config */
device_add(&oti067_m300_device);
return ret;
}
/*
* Current bugs:
* - BIOS complains about FPU if not installed, pressing F1 allows to continue booting.
* - BIOS throws a cache memory error (since L2 cache is not implemented yet), pressing F1 allows to continue booting.
* - no EMS management due to missing chipset implementation (custom ASIC)
*/
int
machine_at_olim300_10_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m300_10/BIOS.ROM",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
device_add(&neat_device);
device_add(&keyboard_ps2_olivetti_device);
/* fdc should be dp8473, however it does not work. Instead, standard AT fdc works. */
device_add(&fdc_at_device);
if (gfxcard == VID_INTERNAL)
/* should be a PVGA1B/WD90C00 with custom BIOS */
device_add(&paradise_pvga1a_device);
return ret;
}
/*
* Current bugs:
* - BIOS complains about FPU if not installed, pressing F1 allows to continue booting.
* - no EMS management due to missing chipset implementation (custom ASIC)
*/
int
machine_at_olim300_05_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m300_05/BIOS.ROM",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_ide_init(model);
device_add(&neat_device);
device_add(&keyboard_ps2_olivetti_device);
/* fdc should be dp8473, however it does not work. Instead, standard AT fdc works. */
device_add(&fdc_at_device);
if (gfxcard == VID_INTERNAL)
/* should be a PVGA1B/WD90C00 with custom BIOS */
device_add(&paradise_pvga1a_device);
return ret;
}

View File

@@ -143,13 +143,16 @@ const machine_t machines[] = {
{ "[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 },
{ "[TACT82300] Olivetti M290S", "olivetti_m290s", MACHINE_TYPE_286, CPU_PKG_286, 0, 16000000, 16000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024,16384, 512, 127, machine_at_olim290s_init, NULL },
/* 286 machines that utilize the MCA bus */
{ "[MCA] IBM PS/2 model 50", "ibmps2_m50", MACHINE_TYPE_286, CPU_PKG_286 | CPU_PKG_486SLC_IBM, 0, 10000000, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 10240,1024, 63, machine_ps2_model_50_init, NULL },
/* 386SX machines */
{ "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO_FIXED, 2048, 6144,1024, 63, machine_ps1_m2121_init, NULL },
{ "[ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 6144,1024, 63, machine_ps1_m2121_init, NULL },
{ "[ISA] Olivetti M300-05", "olivetti_m300_05", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 16000000, 16000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 11264, 1024, 127, machine_at_olim300_05_init, NULL },
{ "[ISA] Olivetti M300-10", "olivetti_m300_10", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 20000000, 20000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 12288, 1024, 127, machine_at_olim300_10_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_M6117)
{ "[ALi M6117D] Acrosser AR-B1375", "arb1375", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_arb1375_init, NULL },
{ "[ALi M6117D] Acrosser PJ-A511M", "pja511m", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_pja511m_init, NULL },
@@ -159,10 +162,13 @@ const machine_t machines[] = {
{ "[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 283] Olivetti M300-08", "olivetti_m300_08", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 20000000, 20000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 16384, 2048, 127, machine_at_olim300_08_init, at_m300_08_get_device },
{ "[OPTi 283] Olivetti M300-15", "olivetti_m300_15", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 25000000, 25000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 16384, 2048, 127, machine_at_olim300_15_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-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 },
{ "[TACT82300] NCR PC916SX", "ncr_pc916sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 128, 127, machine_at_ncrpc916sx_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 },
/* 386SX machines which utilize the MCA bus */

283
src/sio/sio_pc87310.c Normal file
View File

@@ -0,0 +1,283 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the NatSemi PC87310 Super I/O chip.
*
*
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Tiseno100
* EngiNerd <webmaster.crrc@yahoo.it>
*
* Copyright 2020 Miran Grca.
* Copyright 2020 Tiseno100
* Copyright 2021 EngiNerd.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/pci.h>
#include <86box/rom.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#define HAS_IDE_FUNCTIONALITY dev->ide_function
#ifdef ENABLE_PC87310_LOG
int pc87310_do_log = ENABLE_PC87310_LOG;
static void
pc87310_log(const char *fmt, ...)
{
va_list ap;
if (pc87310_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define pc87310_log(fmt, ...)
#endif
typedef struct {
uint8_t tries, ide_function,
reg;
fdc_t *fdc;
serial_t *uart[2];
} pc87310_t;
static void
lpt1_handler(pc87310_t *dev)
{
int temp;
uint16_t lpt_port = 0x378;
uint8_t lpt_irq = 7;
/* bits 0-1:
* 00 378h
* 01 3bch
* 10 278h
* 11 disabled
*/
temp = dev->reg & 3;
switch (temp) {
case 0:
lpt_port = 0x378;
break;
case 1:
lpt_port = 0x3bc;
break;
case 2:
lpt_port = 0x278;
break;
case 3:
lpt_port = 0x000;
lpt_irq = 0xff;
break;
}
if (lpt_port)
lpt1_init(lpt_port);
lpt1_irq(lpt_irq);
}
static void
serial_handler(pc87310_t *dev, int uart)
{
int temp;
/* bit 2: disable serial port 1
* bit 3: disable serial port 2
* bit 4: swap serial ports
*/
temp = (dev->reg >> (2 + uart)) & 1;
//current serial port is enabled
if (!temp){
//configure serial port as COM2
if (((dev->reg >> 4) & 1) ^ uart)
serial_setup(dev->uart[uart], 0x2f8, 3);
// configure serial port as COM1
else
serial_setup(dev->uart[uart], 0x3f8, 4);
}
}
static void
pc87310_write(uint16_t port, uint8_t val, void *priv)
{
pc87310_t *dev = (pc87310_t *) priv;
uint8_t valxor;
// second write to config register
if (dev->tries) {
valxor = val ^ dev->reg;
dev->tries = 0;
dev->reg = val;
// first write to config register
} else {
dev->tries++;
return;
}
pc87310_log("SIO: written %01X\n", val);
/* reconfigure parallel port */
if (valxor & 0x03) {
lpt1_remove();
/* bits 0-1: 11 disable parallel port */
if (!((val & 1) && (val & 2)))
lpt1_handler(dev);
}
/* reconfigure serial ports */
if (valxor & 0x1c) {
serial_remove(dev->uart[0]);
serial_remove(dev->uart[1]);
/* bit 2: 1 disable first serial port */
if (!(val & 4))
serial_handler(dev, 0);
/* bit 3: 1 disable second serial port */
if (!(val & 8))
serial_handler(dev, 1);
}
/* reconfigure IDE controller */
if (valxor & 0x20) {
pc87310_log("SIO: HDC disabled\n");
ide_pri_disable();
/* bit 5: 1 disable ide controller */
if (!(val & 0x20) && HAS_IDE_FUNCTIONALITY) {
pc87310_log("SIO: HDC enabled\n");
ide_set_base(0, 0x1f0);
ide_set_side(0, 0x3f6);
ide_pri_enable();
}
}
/* reconfigure floppy disk controller */
if (valxor & 0x40) {
pc87310_log("SIO: FDC disabled\n");
fdc_remove(dev->fdc);
/* bit 6: 1 disable fdc */
if (!(val & 0x40)) {
pc87310_log("SIO: FDC enabled\n");
fdc_set_base(dev->fdc, 0x3f0);
}
}
return;
}
uint8_t
pc87310_read(uint16_t port, void *priv)
{
pc87310_t *dev = (pc87310_t *) priv;
uint8_t ret = 0xff;
dev->tries = 0;
ret = dev->reg;
pc87310_log("SIO: read %01X\n", ret);
return ret;
}
void
pc87310_reset(pc87310_t *dev)
{
dev->reg = 0x0;
dev->tries = 0;
/*
0 = 360 rpm @ 500 kbps for 3.5"
1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5"
*/
lpt1_remove();
lpt1_handler(dev);
serial_remove(dev->uart[0]);
serial_remove(dev->uart[1]);
serial_handler(dev, 0);
serial_handler(dev, 1);
fdc_reset(dev->fdc);
//ide_pri_enable();
}
static void
pc87310_close(void *priv)
{
pc87310_t *dev = (pc87310_t *) priv;
free(dev);
}
static void *
pc87310_init(const device_t *info)
{
pc87310_t *dev = (pc87310_t *) malloc(sizeof(pc87310_t));
memset(dev, 0, sizeof(pc87310_t));
/* Avoid conflicting with machines that make no use of the PC87310 Internal IDE */
HAS_IDE_FUNCTIONALITY = info->local;
dev->fdc = device_add(&fdc_at_nsc_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
if (HAS_IDE_FUNCTIONALITY)
device_add(&ide_isa_device);
pc87310_reset(dev);
io_sethandler(0x3f3, 0x0001,
pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev);
return dev;
}
const device_t pc87310_device = {
"National Semiconductor PC87310 Super I/O",
0,
0,
pc87310_init, pc87310_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
const device_t pc87310_ide_device = {
"National Semiconductor PC87310 Super I/O with IDE functionality",
0,
1,
pc87310_init, pc87310_close, NULL,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -30,7 +30,9 @@
#include <86box/vid_svga.h>
#define BIOS_037C_PATH L"roms/video/oti/bios.bin"
#define BIOS_067_AMA932J_PATH L"roms/machines/ama932j/oti067.bin"
#define BIOS_067_AMA932J_PATH L"roms/machines/ama932j/oti067.bin"
#define BIOS_067_M300_08_PATH L"roms/machines/olivetti_m300_08/EVC_BIOS.ROM"
#define BIOS_067_M300_15_PATH L"roms/machines/olivetti_m300_15/EVC_BIOS.ROM"
#define BIOS_077_PATH L"roms/video/oti/oti077.vbi"
@@ -38,6 +40,7 @@ enum {
OTI_037C,
OTI_067 = 2,
OTI_067_AMA932J,
OTI_067_M300 = 4,
OTI_077 = 5
};
@@ -362,6 +365,16 @@ oti_init(const device_t *info)
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
break;
case OTI_067_M300:
if (rom_present(BIOS_067_M300_15_PATH))
romfn = BIOS_067_M300_15_PATH;
else
romfn = BIOS_067_M300_08_PATH;
oti->vram_size = device_get_config_int("memory");
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
break;
case OTI_067:
case OTI_077:
romfn = BIOS_077_PATH;
@@ -439,6 +452,15 @@ oti067_077_available(void)
return(rom_present(BIOS_077_PATH));
}
static int
oti067_m300_available(void)
{
if (rom_present(BIOS_067_M300_15_PATH))
return(rom_present(BIOS_067_M300_15_PATH));
else
return(rom_present(BIOS_067_M300_08_PATH));
}
static const device_config_t oti067_config[] =
{
@@ -531,6 +553,18 @@ const device_t oti067_device =
oti067_config
};
const device_t oti067_m300_device =
{
"Oak OTI-067 (Olivetti M300-08/15)",
DEVICE_ISA,
4,
oti_init, oti_close, NULL,
{ oti067_m300_available },
oti_speed_changed,
oti_force_redraw,
oti067_config
};
const device_t oti067_ama932j_device =
{
"Oak OTI-067 (AMA-932J)",

View File

@@ -640,7 +640,7 @@ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm
SIOOBJ := sio_acc3221.o \
sio_f82c710.o sio_82091aa.o \
sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87311.o sio_pc87332.o \
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \
sio_prime3c.o \
sio_w83787f.o \
sio_w83877f.o sio_w83977f.o \