diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index f0ba18954..e10c54dcd 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -17,7 +17,8 @@ add_library(chipset OBJECT acc2168.c cs8230.c ali1217.c ali1429.c headland.c int cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti495.c opti895.c opti5x7.c scamp.c scat.c via_vt82c49x.c via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c - stpc.c opti283.c opti291.c via_apollo.c via_pipc.c wd76c10.c + gc100.c olivetti_eva.c stpc.c + opti283.c opti291.c via_apollo.c via_pipc.c wd76c10.c vl82c480.c) if(M1489) diff --git a/src/chipset/gc100.c b/src/chipset/gc100.c new file mode 100644 index 000000000..97c944f74 --- /dev/null +++ b/src/chipset/gc100.c @@ -0,0 +1,256 @@ +/* + * 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. + * + * Implementation of the G2 GC100/GC100A chipset. + * NOTE: As documentation is currently available only for the + * CG100 chipset, the GC100A chipset has been reverese-engineered. + * Thus, its behavior may not be fully accurate. + * + * Authors: EngiNerd + * + * Copyright 2020-2021 EngiNerd + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/nmi.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/mem.h> +#include <86box/device.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/gameport.h> +#include <86box/ibm_5161.h> +#include <86box/keyboard.h> +#include <86box/rom.h> +#include <86box/machine.h> +#include <86box/chipset.h> +#include <86box/io.h> +#include <86box/video.h> + +typedef struct +{ + uint8_t reg[0x10]; +} gc100_t; + +#define ENABLE_GC100_LOG 1 + +#ifdef ENABLE_GC100_LOG +int gc100_do_log = ENABLE_GC100_LOG; +static void +gc100_log(const char *fmt, ...) +{ + va_list ap; + + if (gc100_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define gc100_log(fmt, ...) +#endif + +static uint8_t +get_fdd_switch_settings(){ + + int i, fdd_count = 0; + + for (i = 0; i < FDD_NUM; i++) { + if (fdd_get_flags(i)) + fdd_count++; + } + + if (!fdd_count) + return 0x00; + else + return ((fdd_count - 1) << 6) | 0x01; + +} + +static uint8_t +get_videomode_switch_settings(){ + + if (video_is_mda()) + return 0x30; + else if (video_is_cga()) + return 0x20; /* 0x10 would be 40x25 */ + else + return 0x00; + +} + +static void +gc100_write(uint16_t port, uint8_t val, void *priv) +{ + gc100_t *dev = (gc100_t *) priv; + + uint16_t addr = port & 0xf; + + dev->reg[addr] = val; + + switch (addr) + { + /* addr 0x2 + * bits 5-7: not used + * bit 4: intenal memory wait states + * bits 2-3: external memory wait states + * bits 0-1: i/o access wait states + */ + case 0x2: + break; + + /* addr 0x3 + * bits 1-7: not used + * bit 0: turbo 0 xt 1 + */ + case 0x3: + if (val & 0x1) + cpu_dynamic_switch(0); + else + cpu_dynamic_switch(cpu); + break; + + /* addr 0x5 + * programmable dip-switches + * bits 6-7: floppy drive number + * bits 4-5: video mode + * bits 2-3: memory size + * bit 1: fpu + * bit 0: not used + */ + + /* addr 0x6 */ + + /* addr 0x7 */ + + } + + gc100_log("GC100: Write %02x at %02x\n", val, port); + +} + +static uint8_t +gc100_read(uint16_t port, void *priv) +{ + gc100_t *dev = (gc100_t *) priv; + uint8_t ret = 0xff; + + uint16_t addr = port & 0xf; + + ret = dev->reg[addr]; + + gc100_log("GC100: Read %02x at %02x\n", ret, port); + + switch (addr) + { + /* addr 0x2 + * bits 5-7: not used + * bit 4: intenal memory wait states + * bits 2-3: external memory wait states + * bits 0-1: i/o access wait states + */ + case 0x2: + break; + + /* addr 0x3 + * bits 1-7: not used + * bit 0: turbo 0 xt 1 + */ + case 0x3: + break; + + /* addr 0x5 + * programmable dip-switches + * bits 6-7: floppy drive number + * bits 4-5: video mode + * bits 2-3: memory size + * bit 1: fpu + * bit 0: not used + */ + case 0x5: + ret = ret & 0x0c; + ret |= get_fdd_switch_settings(); + ret |= get_videomode_switch_settings(); + if (hasfpu) + ret |= 0x02; + + break; + + /* addr 0x6 */ + + /* addr 0x7 */ + + } + + return ret; +} + + +static void +gc100_close(void *priv) +{ + gc100_t *dev = (gc100_t *) priv; + + free(dev); +} + +static void * +gc100_init(const device_t *info) +{ + gc100_t *dev = (gc100_t *) malloc(sizeof(gc100_t)); + memset(dev, 0, sizeof(gc100_t)); + + dev->reg[0x2] = 0xff; + dev->reg[0x3] = 0x0; + dev->reg[0x5] = 0x0; + dev->reg[0x6] = 0x0; + dev->reg[0x7] = 0x0; + + /* GC100A */ + if(info->local) { + io_sethandler(0x0c2, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); + io_sethandler(0x0c5, 0x03, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); + } + /* GC100 */ + else { + io_sethandler(0x022, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); + io_sethandler(0x025, 0x01, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev); + } + + return dev; +} + +const device_t gc100_device = { + "G2 GC100", + 0, + 0, + gc100_init, gc100_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + +const device_t gc100a_device = { + "G2 GC100A", + 0, + 1, + gc100_init, gc100_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + diff --git a/src/chipset/olivetti_eva.c b/src/chipset/olivetti_eva.c new file mode 100644 index 000000000..34b09c622 --- /dev/null +++ b/src/chipset/olivetti_eva.c @@ -0,0 +1,166 @@ +/* + * 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. + * + * Implementation of the Olivetti EVA (98/86) Gate Array. + * + * Note: This chipset has no datasheet, everything were done via + * reverse engineering the BIOS of various machines using it. + * + * Authors: EngiNerd + * + * Copyright 2020-2021 EngiNerd + */ + + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/video.h> +#include <86box/mem.h> + +typedef struct +{ + uint8_t reg_065; + uint8_t reg_067; + uint8_t reg_069; +} olivetti_eva_t; + +#ifdef ENABLE_OLIVETTI_EVA_LOG +int olivetti_eva_do_log = ENABLE_OLIVETTI_EVA_LOG; +static void +olivetti_eva_log(const char *fmt, ...) +{ + va_list ap; + + if (olivetti_eva_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define olivetti_eva_log(fmt, ...) +#endif + +static void +olivetti_eva_write(uint16_t addr, uint8_t val, void *priv) +{ + olivetti_eva_t *dev = (olivetti_eva_t *) priv; + olivetti_eva_log("Olivetti EVA Gate Array: Write %02x at %02x\n", val, addr); + + switch (addr) { + case 0x065: + dev->reg_065 = val; + break; + case 0x067: + dev->reg_067 = val; + break; + case 0x069: + dev->reg_069 = val; + /* + * Unfortunately, if triggered, the BIOS remapping function fails causing + * a fatal error. Therefore, this code section is currently commented. + */ + // if (val & 1){ + // /* + // * Set the register to 7 or above for the BIOS to trigger the + // * memory remapping function if shadowing is active. + // */ + // dev->reg_069 = 0x7; + // } + // if (val & 8) { + // /* + // * Activate shadowing for region e0000-fffff + // */ + // mem_remap_top(256); + // mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + // } + break; + } +} + +static uint8_t +olivetti_eva_read(uint16_t addr, void *priv) +{ + olivetti_eva_t *dev = (olivetti_eva_t *) priv; + uint8_t ret = 0xff; + switch (addr) { + case 0x065: + ret = dev->reg_065; + break; + case 0x067: + /* never happens */ + ret = dev->reg_067; + break; + case 0x069: + ret = dev->reg_069; + break; + } + olivetti_eva_log("Olivetti EVA Gate Array: Read %02x at %02x\n", ret, addr); + return ret; +} + + +static void +olivetti_eva_close(void *priv) +{ + olivetti_eva_t *dev = (olivetti_eva_t *) priv; + + free(dev); +} + +static void * +olivetti_eva_init(const device_t *info) +{ + olivetti_eva_t *dev = (olivetti_eva_t *) malloc(sizeof(olivetti_eva_t)); + memset(dev, 0, sizeof(olivetti_eva_t)); + + /* GA98 registers */ + dev->reg_065 = 0x00; + + /* RAM page registers: never read, only set */ + dev->reg_067 = 0x00; + + /* RAM enable registers */ + dev->reg_069 = 0x0; + + io_sethandler(0x0065, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev); + io_sethandler(0x0067, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev); + io_sethandler(0x0069, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev); + + /* When shadowing is not enabled in BIOS, all upper memory is available as XMS */ + mem_remap_top(384); + + /* + * Default settings when NVRAM is cleared activate shadowing. + * Thus, to avoid boot errors, remap only 256k from UMB to XMS. + * Remove this block once BIOS memory remapping works. + */ + mem_remap_top(256); + + return dev; +} + +const device_t olivetti_eva_device = { + "Olivetti EVA Gate Array", + 0, + 0, + olivetti_eva_init, olivetti_eva_close, NULL, + { NULL }, NULL, NULL, + NULL +}; diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 74563cf8f..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) @@ -2137,7 +2163,6 @@ kbd_read(uint16_t port, void *priv) ret |= 0x2; /* 0x10 would be 40x25 */ else ret |= 0x0; - ret = 0xff; } else { /* bit 2 always on */ ret |= 0x4; @@ -2291,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: @@ -2447,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/device/keyboard_xt.c b/src/device/keyboard_xt.c index 69360e00c..57f6788fb 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -24,6 +24,8 @@ #include #include #include +#include +#define HAVE_STDARG_H #include #include <86box/86box.h> #include <86box/device.h> @@ -598,7 +600,7 @@ kbd_read(uint16_t port, void *priv) ret = ((mem_size-64) / 32) >> 4; } else if (kbd->type == 8 || kbd->type == 9) { - /* Olivetti M19 or Zenith Data Systems Z-151*/ + /* Olivetti M19 or Zenith Data Systems Z-151 */ if (kbd->pb & 0x04) ret = kbd->pd & 0xbf; else diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 0f7bea3a1..546cdf4f8 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -2173,6 +2173,11 @@ fdc_set_base(fdc_t *fdc, int base) { int super_io = (fdc->flags & FDC_FLAG_SUPERIO); + 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); @@ -2189,6 +2194,7 @@ fdc_set_base(fdc_t *fdc, int base) 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); } @@ -2200,6 +2206,11 @@ 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_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); @@ -2217,6 +2228,7 @@ fdc_remove(fdc_t *fdc) } } } +} void diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 60a9e8d73..dc42e7889 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -46,6 +46,10 @@ extern const device_t scat_sx_device; extern const device_t cs8230_device; extern const device_t cs4031_device; +/* G2 */ +extern const device_t gc100_device; +extern const device_t gc100a_device; + /* Headland */ extern const device_t headland_gc10x_device; extern const device_t headland_ht18a_device; @@ -141,4 +145,7 @@ extern const device_t wd76c10_device; extern const device_t phoenix_486_jumper_device; extern const device_t vpc2007_device; +#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) +extern const device_t olivetti_eva_device; +#endif #endif /*EMU_CHIPSET_H*/ 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 74cafc50d..a419de290 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -255,6 +255,13 @@ extern int machine_at_spc4620p_init(const machine_t *); extern int machine_at_kmxc02_init(const machine_t *); extern int machine_at_deskmaster286_init(const machine_t *); +extern int machine_at_ncrpc8_init(const machine_t *); +extern int machine_at_ncr3302_init(const machine_t *); + +#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) +extern int machine_at_olim290_init(const machine_t *); +#endif + extern int machine_at_shuttle386sx_init(const machine_t *); extern int machine_at_adi386sx_init(const machine_t *); extern int machine_at_commodore_sl386sx16_init(const machine_t *); @@ -263,22 +270,24 @@ extern int machine_at_spc6033p_init(const machine_t *); extern int machine_at_wd76c10_init(const machine_t *); extern int machine_at_flytech386_init(const machine_t *); -extern int machine_at_olim290_init(const machine_t *); -extern int machine_at_ncrpc8_init(const machine_t *); -extern int machine_at_ncr3302_init(const machine_t *); - extern int machine_at_awardsx_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_M6117) extern int machine_at_arb1375_init(const machine_t *); extern int machine_at_pja511m_init(const machine_t *); #endif +extern int machine_at_ncrpc916sx_init(const machine_t *); + +extern int machine_at_olim300_08_init(const machine_t *); +extern int machine_at_olim300_15_init(const machine_t *); + #ifdef EMU_DEVICE_H extern const device_t *at_ama932j_get_device(void); extern const device_t *at_flytech386_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 */ @@ -611,8 +620,6 @@ extern int machine_xt_ncrpc4i_init(const machine_t *); extern int machine_xt_mpc1600_init(const machine_t *); extern int machine_xt_eaglepcspirit_init(const machine_t *); extern int machine_xt_multitechpc700_init(const machine_t *); -extern int machine_xt_p3105_init(const machine_t *); -extern int machine_xt_p3120_init(const machine_t *); extern int machine_xt_iskra3104_init(const machine_t *); @@ -630,6 +637,9 @@ extern int machine_xt_laserxt_init(const machine_t *); extern int machine_xt_lxt3_init(const machine_t *); #endif +/* m_xt_philips.c */ +extern int machine_xt_p3105_init(const machine_t *); +extern int machine_xt_p3120_init(const machine_t *); /* m_xt_t1000.c */ extern int machine_xt_t1000_init(const machine_t *); extern int machine_xt_t1200_init(const machine_t *); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 6775b0bea..0bb49ac7b 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..17a564069 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -292,9 +292,11 @@ 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 */ +extern const device_t paradise_pvga1a_ncr3302_device; extern const device_t paradise_pvga1a_pc2086_device; extern const device_t paradise_pvga1a_pc3086_device; extern const device_t paradise_pvga1a_device; diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index 7576ae130..846ab6074 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -14,6 +14,7 @@ # add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c + m_xt_philips.c m_xt_t1000.c m_xt_t1000_vid.c m_xt_xi8088.c m_xt_zenith.c m_pcjr.c m_amstrad.c m_europc.c m_xt_olivetti.c m_tandy.c m_at.c m_at_commodore.c m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 274eedad0..b78e0ee33 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -40,6 +40,7 @@ #include <86box/sio.h> #include <86box/serial.h> #include <86box/video.h> +#include <86box/vid_cga.h> #include <86box/flash.h> #include <86box/machine.h> @@ -704,49 +705,6 @@ machine_at_pja511m_init(const machine_t *model) } #endif - - -static uint8_t -m290_read(uint16_t port, void *priv) -{ - uint8_t ret = 0x0; - switch (port) { - /* - * port 69: - * dip-switch bank on mainboard (off=1) - * bit 3 - use OCG/CGA display adapter (off) / other display adapter (on) - */ - case 0x69: - if(video_is_cga()) - ret |= 0x8|0x4; - ret |= 0x1|0x2; - } - return (ret); -} - -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_device); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); - - io_sethandler(0x069, 1, m290_read, NULL, NULL, NULL, NULL, NULL, NULL); - - return ret; -} - - /* * Current bugs: * - ctrl-alt-del produces an 8042 error @@ -800,7 +758,113 @@ machine_at_ncr3302_init(const machine_t *model) device_add(&fdc_at_device); if (gfxcard == VID_INTERNAL) - device_add(¶dise_pvga1a_device); + device_add(¶dise_pvga1a_ncr3302_device); return ret; } + +/* + * Current bugs: + * - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error + */ +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); + mem_remap_top(384); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) +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); + + if (fdc_type == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&olivetti_eva_device); + + return ret; +} +#endif + +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); + + /* Stock VRAM is maxed out, so no need to expose video card config */ + if (gfxcard == VID_INTERNAL) + device_add(&oti067_m300_device); + + return ret; +} + diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 7640b0932..698cc46ca 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -11,12 +11,13 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/fdc_ext.h> +#include <86box/hdc.h> #include <86box/gameport.h> #include <86box/ibm_5161.h> #include <86box/keyboard.h> #include <86box/rom.h> #include <86box/machine.h> - +#include <86box/chipset.h> static void machine_xt_common_init(const machine_t *model) @@ -399,58 +400,3 @@ machine_xt_multitechpc700_init(const machine_t *model) return ret; } - -/* - * Current bugs and limitations: - * - 640-768 conventional memory not usable (should be mapped at address d0000-effff) - */ -int -machine_xt_p3105_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/philips_p3105/philipsnms9100.bin", - 0x000fc000, 16384, 0); - - if (bios_only || !ret) - return ret; - - device_add(&keyboard_pc_device); - - machine_xt_common_init(model); - - return ret; -} - -/* - * Current bugs and limitations: - * - 640-768 conventional memory not usable (should be mapped at address d0000-effff) - * - BIOS detects 4 fdds, so hdd letter is E instead of C - */ -int -machine_xt_p3120_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/philips_p3120/philips_p3120.bin", - 0x000f8000, 32768, 0); - - if (bios_only || !ret) - return ret; - - device_add(&keyboard_pc_device); - - machine_common_init(model); - - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_at_device); - - nmi_init(); - - if (joystick_type) - device_add(&gameport_device); - - return ret; -} \ No newline at end of file diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index cd0790a3c..78b405398 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -725,6 +725,7 @@ machine_xt_olim24_init(const machine_t *model) machine_common_init(model); + /* On-board FDC can be disabled only on M24SP */ if (fdc_type == FDC_INTERNAL) device_add(&fdc_xt_device); @@ -773,7 +774,7 @@ machine_xt_olim240_init(const machine_t *model) */ device_add(&keyboard_at_olivetti_device); - /* FIXME: make sure this is correct?? */ + /* FIXME: make sure this is correct?? */ device_add(&at_nvr_device); if (fdc_type == FDC_INTERNAL) @@ -792,6 +793,7 @@ machine_xt_olim240_init(const machine_t *model) * Current bugs: * - 640x400x2 graphics mode not supported (bit 0 of register 0x3de cannot be set) * - optional mouse emulation missing + * - setting CPU speed at 4.77MHz sometimes throws a timer error. If the machine is hard-resetted, the error disappears. */ int machine_xt_olim19_init(const machine_t *model) @@ -812,7 +814,7 @@ machine_xt_olim19_init(const machine_t *model) machine_common_init(model); - if (fdc_type == FDC_INTERNAL) + /* On-board FDC cannot be disabled */ device_add(&fdc_xt_device); m19_vid_init(vid); @@ -825,39 +827,3 @@ machine_xt_olim19_init(const machine_t *model) return ret; } - - -/* not working, returns timer error */ -/* it appears to be a rebadged Hitachi HL 320 laptop */ -int -machine_xt_olim15_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear(L"roms/machines/olivetti_m15/oliv_m15.bin", - 0x000fc000, 16384, 0); - - if (bios_only || !ret) - return ret; - - machine_common_init(model); - - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); - - device_add(&keyboard_xt_olivetti_device); - - device_add(&cga_device); - - /* FIXME: make sure this is correct?? */ - //device_add(&at_nvr_device); - - if (fdc_type == FDC_INTERNAL) - device_add(&fdc_xt_device); - - if (joystick_type) - device_add(&gameport_device); - - nmi_init(); - - return ret; -} \ No newline at end of file diff --git a/src/machine/m_xt_philips.c b/src/machine/m_xt_philips.c new file mode 100644 index 000000000..9adfc82d7 --- /dev/null +++ b/src/machine/m_xt_philips.c @@ -0,0 +1,203 @@ +/* + * 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 Philips XT-compatible machines. + * + * + * + * Authors: EngiNerd + * + * Copyright 2020-2021 EngiNerd. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/nmi.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/mem.h> +#include <86box/device.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/gameport.h> +#include <86box/ibm_5161.h> +#include <86box/keyboard.h> +#include <86box/rom.h> +#include <86box/machine.h> +#include <86box/chipset.h> +#include <86box/io.h> +#include <86box/video.h> + +typedef struct +{ + uint8_t reg; +} philips_t; + +#ifdef ENABLE_philips_LOG +int philips_do_log = ENABLE_philips_LOG; +static void +philips_log(const char *fmt, ...) +{ + va_list ap; + + if (philips_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define philips_log(fmt, ...) +#endif + +static void +philips_write(uint16_t port, uint8_t val, void *priv) +{ + philips_t *dev = (philips_t *) priv; + + switch (port) + { + /* port 0xc0 + * bit 7: turbo + * bits 4-5: rtc read/set (I2C Bus SDA/SCL?) + * bit 2: parity disabled + */ + case 0xc0: + dev->reg = val; + if (val & 0x80) + cpu_dynamic_switch(cpu); + else + cpu_dynamic_switch(0); + break; + } + + philips_log("Philips XT Mainboard: Write %02x at %02x\n", val, port); + +} + +static uint8_t +philips_read(uint16_t port, void *priv) +{ + philips_t *dev = (philips_t *) priv; + uint8_t ret = 0xff; + + switch (port) + { + /* port 0xc0 + * bit 7: turbo + * bits 4-5: rtc read/set + * bit 2: parity disabled + */ + case 0xc0: + ret = dev->reg; + break; + + } + + philips_log("Philips XT Mainboard: Read %02x at %02x\n", ret, port); + + return ret; +} + + +static void +philips_close(void *priv) +{ + philips_t *dev = (philips_t *) priv; + + free(dev); +} + +static void * +philips_init(const device_t *info) +{ + philips_t *dev = (philips_t *) malloc(sizeof(philips_t)); + memset(dev, 0, sizeof(philips_t)); + + dev->reg = 0x40; + + io_sethandler(0x0c0, 0x01, philips_read, NULL, NULL, philips_write, NULL, NULL, dev); + + return dev; +} + +const device_t philips_device = { + "Philips XT Mainboard", + 0, + 0, + philips_init, philips_close, NULL, + { NULL }, NULL, NULL, + NULL +}; + + +void +machine_xt_philips_common_init(const machine_t *model) +{ + machine_common_init(model); + + pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + + /* On-board FDC cannot be disabled */ + device_add(&fdc_xt_device); + + nmi_init(); + + if (joystick_type) + device_add(&gameport_device); + + device_add(&keyboard_pc_device); + + device_add(&philips_device); + + device_add(&xta_hd20_device); + +} + +int +machine_xt_p3105_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/philips_p3105/philipsnms9100.bin", + 0x000fc000, 16384, 0); + + if (bios_only || !ret) + return ret; + + machine_xt_philips_common_init(model); + + return ret; +} + +int +machine_xt_p3120_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/philips_p3120/philips_p3120.bin", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_xt_philips_common_init(model); + + device_add(&gc100a_device); + + return ret; +} + diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d49e1a65a..8c7b6cd71 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -73,8 +73,7 @@ const machine_t machines[] = { { "[8088] NCR PC4i", "pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_ncrpc4i_init, NULL }, { "[8088] Olivetti M19", "m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_olim19_init, NULL }, { "[8088] OpenXT", "openxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_open_xt_init, NULL }, - { "[8088] Philips P3105/NMS9100", "p3105", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 768, 256, 0, machine_xt_p3105_init, NULL }, - { "[8088] Philips P3120", "p3120", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 768, 256, 0, machine_xt_p3120_init, NULL }, + { "[8088] Philips P3105/NMS9100", "p3105", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA, 256, 768, 256, 0, machine_xt_p3105_init, NULL }, { "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_pxxt_init, NULL }, { "[8088] Schneider EuroPC", "europc", MACHINE_TYPE_8088, CPU_PKG_8088_EUROPC, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, { "[8088] Tandy 1000", "tandy", MACHINE_TYPE_8088, CPU_PKG_8088_EUROPC, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device }, @@ -87,6 +86,7 @@ const machine_t machines[] = { { "[8088] Zenith Data Systems Z-151/152/161", "zdsz151", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_z151_init, NULL }, { "[8088] Zenith Data Systems Z-159", "zdsz159", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_z159_init, NULL }, { "[8088] Zenith Data Systems SupersPort (Z-184)", "zdsupers", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_xt_z184_init, z184_get_device }, + { "[GC100A] Philips P3120", "p3120", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA, 256, 768, 256, 0, machine_xt_p3120_init, NULL }, /* 8086 Machines */ { "[8086] Amstrad PC1512", "pc1512", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 8000000, 8000000, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device }, @@ -122,7 +122,9 @@ const machine_t machines[] = { { "[ISA] Compaq Portable III", "portableiii", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 640, 16384, 128, 127, machine_at_portableiii_init, at_cpqiii_get_device }, { "[ISA] MR 286 clone", "mr286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 16384, 128, 127, machine_at_mr286_init, NULL }, { "[ISA] NCR PC8/810/710/3390/3392", "pc8", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_ncrpc8_init, NULL }, +#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) { "[ISA] Olivetti M290", "m290", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 640, 16384, 128, 127, machine_at_olim290_init, NULL }, +#endif #if defined(DEV_BRANCH) && defined(USE_OPEN_AT) { "[ISA] OpenAT", "open_at", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_open_at_init, NULL }, #endif @@ -143,13 +145,14 @@ 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 }, - + /* 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] 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 }, #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 }, @@ -160,6 +163,8 @@ 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", "cmdsl386sx16", 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", "cmdsl386sx16", 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 }, diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 4cd1dcef1..62debb1b5 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -15,7 +15,7 @@ add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c661.c sio_fdc37c66x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c - sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87311.c sio_pc87332.c + sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c sio_prime3b.c sio_prime3c.c sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c sio_vt82c686.c) 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/video/vid_paradise.c b/src/video/vid_paradise.c index 3f025fd3b..c0781846b 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -352,6 +352,16 @@ void *paradise_init(const device_t *info, uint32_t memsize) return paradise; } +static void *paradise_pvga1a_ncr3302_init(const device_t *info) +{ + paradise_t *paradise = paradise_init(info, 1 << 18); + + if (paradise) + rom_init(¶dise->bios_rom, L"roms/machines/ncr_3302/c000-wd_1987-1989-740011-003058-019c.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + return paradise; +} + static void *paradise_pvga1a_pc2086_init(const device_t *info) { paradise_t *paradise = paradise_init(info, 1 << 18); @@ -361,6 +371,7 @@ static void *paradise_pvga1a_pc2086_init(const device_t *info) return paradise; } + static void *paradise_pvga1a_pc3086_init(const device_t *info) { paradise_t *paradise = paradise_init(info, 1 << 18); @@ -464,7 +475,6 @@ void paradise_force_redraw(void *p) paradise->svga.fullchange = changeframecount; } - const device_t paradise_pvga1a_pc2086_device = { "Paradise PVGA1A (Amstrad PC2086)", @@ -478,6 +488,7 @@ const device_t paradise_pvga1a_pc2086_device = paradise_force_redraw, NULL }; + const device_t paradise_pvga1a_pc3086_device = { "Paradise PVGA1A (Amstrad PC3086)", @@ -516,6 +527,20 @@ static const device_config_t paradise_pvga1a_config[] = } }; +const device_t paradise_pvga1a_ncr3302_device = +{ + "Paradise PVGA1A (NCR 3302)", + 0, + PVGA1A, + paradise_pvga1a_ncr3302_init, + paradise_close, + NULL, + { NULL }, + paradise_speed_changed, + paradise_force_redraw, + paradise_pvga1a_config +}; + const device_t paradise_pvga1a_device = { "Paradise PVGA1A", diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 5aaad9a86..458c26593 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -99,6 +99,9 @@ ifeq ($(DEV_BUILD), y) ifndef USE_VECT486VL USE_VECT486VL := y endif + ifndef OLIVETTI + OLIVETTI := y + endif else ifndef DEBUG DEBUG := n @@ -172,6 +175,9 @@ else ifndef USE_VECT486VL USE_VECT486VL := n endif + ifndef OLIVETTI + OLIVETTI := n + endif endif # Defaults for several build options (possibly defined in a chained file.) @@ -575,6 +581,11 @@ ifeq ($(USE_VECT486VL), y) OPTS += -DUSE_VECT486VL endif +ifeq ($(OLIVETTI), y) +OPTS += -DUSE_OLIVETTI +endif + + endif @@ -607,11 +618,13 @@ CPUOBJ := cpu.o cpu_table.o \ CHIPSETOBJ := acc2168.o cs8230.o ali1217.o ali1429.o headland.o intel_82335.o cs4031.o \ intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \ neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o via_vt82c49x.o via_vt82c505.o \ + gc100.o olivetti_eva.o \ sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o stpc.o opti283.o opti291.o \ via_apollo.o via_pipc.o wd76c10.o vl82c480.o MCHOBJ := machine.o machine_table.o \ m_xt.o m_xt_compaq.o \ + m_xt_philips.o \ m_xt_t1000.o m_xt_t1000_vid.o \ m_xt_xi8088.o m_xt_zenith.o \ m_pcjr.o \ @@ -633,14 +646,14 @@ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm keyboard.o \ keyboard_xt.o keyboard_at.o \ mouse.o \ - mouse_bus.o \ + mouse_bus.o \ mouse_serial.o mouse_ps2.o \ phoenix_486_jumper.o 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_prime3b.o sio_prime3c.o \ sio_w83787f.o \ sio_w83877f.o sio_w83977f.o \