diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 28fbc490a..d0a88a70a 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -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, diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index a48307b2f..b47e81f8c 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -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); + } + } } - } } diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 6cf841df4..3ca6089cc 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -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; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 31baeee20..2b70a9b14 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -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 */ diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 81dc8976e..c53e69e56 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -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; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index c619d994a..622827474 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -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 */ diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index ead2154c7..ffbe14648 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -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(¶dise_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(¶dise_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(¶dise_pvga1a_device); + + + return ret; +} + + diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 07e684cee..618911e45 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -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 */ diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c new file mode 100644 index 000000000..41322a818 --- /dev/null +++ b/src/sio/sio_pc87310.c @@ -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, + * Tiseno100 + * EngiNerd + * + * Copyright 2020 Miran Grca. + * Copyright 2020 Tiseno100 + * Copyright 2021 EngiNerd. + */ +#include +#include +#include +#include +#include +#include +#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 +}; \ No newline at end of file diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 08df31144..bdf1e3884 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -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)", diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 5d71b35e3..656b54649 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -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 \