diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c new file mode 100644 index 000000000..a4dad3d29 --- /dev/null +++ b/src/chipset/opti283.c @@ -0,0 +1,175 @@ +/* + * 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 OPTi 82C283 chipset. + * + * + * + * Authors: Tiseno100 + * + * Copyright 2020 Tiseno100 + * + */ + +#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/keyboard.h> +#include <86box/mem.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + +typedef struct +{ + uint8_t index, + regs[256]; +} opti283_t; + +static void opti283_shadow_recalc(opti283_t *dev) +{ +uint32_t base; +uint32_t shflags, i = 0; + +shadowbios = 0; +shadowbios_write = 0; + + /* F0000 - FFFFF segmentation */ +if(!(dev->regs[0x11] & 0x80)){ + shadowbios = 1; + shadowbios_write = 0; + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); +} else { + shadowbios = 0; + shadowbios_write = 1; + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); +} + + /* C0000 - CFFFF segmentation */ +for(i = 4; i < 8; i++){ + base = 0xc0000 + ((i-4) << 14); + + if((dev->regs[0x13] & (1 << i)) & (dev->regs[0x11] & 0x10)){ + shflags = MEM_READ_INTERNAL; + shflags |= (!(dev->regs[0x11] & 0x01)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED; + mem_set_mem_state_both(base, 0x4000, shflags); + } else { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +} +} + + /* D0000 - DFFFF segmentation */ +for(i = 0; i < 4; i++){ + base = 0xd0000 + (i << 14); + if((dev->regs[0x12] & (1 << i)) & (dev->regs[0x11] & 0x20)){ + shflags = MEM_READ_INTERNAL; + shflags |= (!(dev->regs[0x11] & 0x02)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED; + mem_set_mem_state(base, 0x4000, shflags); + } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +} + + /* E0000 - EFFFF segmentation */ +for(i = 4; i < 8; i++){ + base = 0xe0000 + ((i-4) << 14); + if((dev->regs[0x12] & (1 << i)) & (dev->regs[0x11] & 0x40)){ + shflags = MEM_READ_INTERNAL; + shflags |= (!(dev->regs[0x11] & 0x04)) ? MEM_WRITE_INTERNAL : MEM_WRITE_DISABLED; + mem_set_mem_state(base, 0x4000, shflags); + } else mem_set_mem_state(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); +} + +} + +static void +opti283_write(uint16_t addr, uint8_t val, void *priv) +{ + opti283_t *dev = (opti283_t *) priv; + + switch (addr) { + case 0x22: + dev->index = val; + break; + case 0x24: + /*pclog("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);*/ + dev->regs[dev->index] = val; + + switch(dev->index){ + case 0x10: + cpu_update_waitstates(); + + case 0x11: + case 0x12: + case 0x13: + opti283_shadow_recalc(dev); + break; + } + break; + } +} + + +static uint8_t +opti283_read(uint16_t addr, void *priv) +{ + uint8_t ret = 0xff; + opti283_t *dev = (opti283_t *) priv; + + switch (addr) { + case 0x24: + ret = dev->regs[dev->index]; + break; + } + + return ret; +} + + +static void +opti283_close(void *priv) +{ + opti283_t *dev = (opti283_t *) priv; + + free(dev); +} + + +static void * +opti283_init(const device_t *info) +{ + opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t)); + memset(dev, 0, sizeof(opti283_t)); + + io_sethandler(0x022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev); + io_sethandler(0x024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev); + + dev->regs[0x10] = 0x3f; + dev->regs[0x11] = 0xf0; + opti283_shadow_recalc(dev); + + return dev; +} + + +const device_t opti283_device = { + "OPTi 82C283", + 0, + 0, + opti283_init, opti283_close, NULL, + NULL, NULL, NULL, + NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index de25fca32..c2e4b8fe0 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -60,6 +60,7 @@ extern const device_t slc90e66_device; extern const device_t ioapic_device; /* OPTi */ +extern const device_t opti283_device; extern const device_t opti493_device; extern const device_t opti495_device; extern const device_t opti802g_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index fc423786a..055679bac 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -252,6 +252,8 @@ extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); +extern int machine_at_rycleopardlx_init(const machine_t *); + extern int machine_at_pb410a_init(const machine_t *); extern int machine_at_acera1g_init(const machine_t *); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 0f47126ee..9876fd498 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -102,6 +102,25 @@ machine_at_ecs386_init(const machine_t *model) return ret; } +int +machine_at_rycleopardlx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/rycleopardlx/486-RYC-Leopard-LX.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti283_device); + device_add(&keyboard_at_ami_device); + device_add(&fdc_at_device); + + return ret; +} int machine_at_pb410a_init(const machine_t *model) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8a0488c0d..80828826d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -197,6 +197,7 @@ const machine_t machines[] = { { "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 4, 36, 1, 127, machine_at_pb410a_init, NULL }, /* 486 machines */ + { "[OPTi 283] RYC Leopard LX", "rycleopardlx", MACHINE_TYPE_486, {{"IBM", cpus_IBM486SLC}, {"", NULL}, {"", NULL},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 16, 1, 127, machine_at_rycleopardlx_init, NULL }, { "[OPTi 495] Award 486 clone", "award486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_init, NULL }, { "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_mr_init, NULL }, { "[OPTi 495] Dataexpert SX495 (486)", "ami486", MACHINE_TYPE_486, {{"Intel", cpus_i486S1}, {"AMD", cpus_Am486S1}, {"Cyrix", cpus_Cx486S1},{"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 32, 1, 127, machine_at_opti495_ami_init, NULL }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index f497103fb..69983be69 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -572,7 +572,7 @@ CPUOBJ := cpu.o cpu_table.o \ CHIPSETOBJ := acc2168.o cs8230.o ali1429.o headland.o i82335.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 \ - sis_85c310.o sis_85c471.o sis_85c496.o \ + sis_85c310.o sis_85c471.o sis_85c496.o opti283.o \ via_apollo.o via_vpx.o via_vt82c586b.o via_vt82c596b.o wd76c10.o vl82c480.o \ amd640.o