diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 7817ac052..89998ff39 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(chipset OBJECT 82c100.c + acc2036.c acc2168.c cs8220.c cs8230.c diff --git a/src/chipset/acc2036.c b/src/chipset/acc2036.c new file mode 100644 index 000000000..225c22813 --- /dev/null +++ b/src/chipset/acc2036.c @@ -0,0 +1,346 @@ +/* + * 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 ACC 2036 chipset. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/port_92.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/chipset.h> + +typedef struct { + uint32_t virt; + uint32_t phys; + + mem_mapping_t mapping; +} ram_page_t; + +typedef struct { + uint8_t reg; + uint8_t regs[32]; + + ram_page_t ram_mid_pages[24]; + ram_page_t ems_pages[4]; +} acc2036_t; + +static uint8_t +acc2036_mem_read(uint32_t addr, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = ram[addr]; + + return ret; +} + +static uint16_t +acc2036_mem_readw(uint32_t addr, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + uint16_t ret = 0xffff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = *(uint16_t *) &(ram[addr]); + + return ret; +} + +static void +acc2036_mem_write(uint32_t addr, uint8_t val, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +static void +acc2036_mem_writew(uint32_t addr, uint16_t val, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + *(uint16_t *) &(ram[addr]) = val; +} + +static void +acc2036_recalc(acc2036_t *dev) +{ + uint32_t ems_bases[4] = { 0x000c0000, 0x000c8000, 0x000d0000, 0x000e0000 }; + + int start_i = (ems_bases[dev->regs[0x0c] & 0x03] - 0x000a0000) >> 14; + int end_i = start_i + 3; + + for (int i = 0; i < 24; i++) { + ram_page_t *rp = &dev->ram_mid_pages[i]; + mem_mapping_disable(&rp->mapping); + } + + for (int i = 0; i < 4; i++) { + ram_page_t *ep = &dev->ems_pages[i]; + mem_mapping_disable(&ep->mapping); + } + + for (int i = 0; i < 24; i++) { + ram_page_t *rp = &dev->ram_mid_pages[i]; + + if ((dev->regs[0x03] & 0x08) && (i >= start_i) && (i <= end_i)) { + /* EMS */ + ram_page_t *ep = &dev->ems_pages[i - start_i]; + + mem_mapping_disable(&rp->mapping); + mem_mapping_set_addr(&ep->mapping, ep->virt, 0x000040000); + mem_mapping_set_exec(&ep->mapping, ram + ep->phys); + mem_set_mem_state_both(ep->virt, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + int master_write; + int master_read; + int bit; + int ew_flag; + int er_flag; + int flags; + uint8_t val; + + mem_mapping_set_addr(&rp->mapping, rp->virt, 0x000040000); + mem_mapping_set_exec(&rp->mapping, ram + rp->phys); + + if ((i >= 8) && (i <= 15)) { + /* 0C0000-0DFFFF */ + master_write = dev->regs[0x02] & 0x08; + master_read = dev->regs[0x02] & 0x04; + bit = ((i - 8) >> 1); + val = dev->regs[0x0d] & (1 << bit); + if (i >= 12) { + ew_flag = (dev->regs[0x07] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + er_flag = (dev->regs[0x07] & 0x80) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + } else { + ew_flag = (dev->regs[0x07] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + er_flag = (dev->regs[0x07] & 0x40) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + } + flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag; + flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag; + mem_set_mem_state_both(rp->virt, 0x00004000, flags); + } else if (i > 15) { + /* 0E0000-0FFFFF */ + master_write = dev->regs[0x02] & 0x02; + master_read = dev->regs[0x02] & 0x01; + bit = (((i - 8) >> 2) + 2); + val = dev->regs[0x0c] & (1 << bit); + if (i >= 20) { + ew_flag = MEM_WRITE_EXTANY; + er_flag = MEM_READ_EXTANY; + } else { + ew_flag = (dev->regs[0x0c] & 0x10) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + er_flag = (dev->regs[0x0c] & 0x10) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + } + flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag; + flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag; + mem_set_mem_state_both(rp->virt, 0x00004000, flags); + } + } + } + + if (dev->regs[0x00] & 0x40) + mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else + mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + for (int i = 0x01; i <= 0x06; i++) { + uint32_t base = 0x00fe0000 - (i * 0x00010000); + + if (dev->regs[i] & 0x40) + mem_set_mem_state_both(base, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else + mem_set_mem_state_both(base, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + if (dev->regs[i] & 0x80) + mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else + mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + + mem_remap_top(0); + if (dev->regs[0x03] & 0x10) { + if (dev->regs[0x02] & 0x0c) + mem_remap_top(128); + else if (dev->regs[0x02] & 0x03) + mem_remap_top(256); + else + mem_remap_top(384); + } + + flushmmucache_nopc(); +} + +static uint8_t +acc2036_in(uint16_t port, void *priv) { + acc2036_t *dev = (acc2036_t *) priv; + uint8_t reg = dev->reg - 0x20; + uint8_t ret = 0xff; + + if (port & 0x0001) switch (dev->reg) { + default: + break; + case 0x20 ... 0x2e: + case 0x31 ... 0x3f: + ret = dev->regs[reg]; + break; + } else + ret = dev->reg; + + return ret; +} + +static void +acc2036_out(uint16_t port, uint8_t val, void *priv) { + acc2036_t *dev = (acc2036_t *) priv; + uint8_t reg = dev->reg - 0x20; + + if (port & 0x0001) switch (dev->reg) { + default: + break; + case 0x20 ... 0x23: + dev->regs[reg] = val; + acc2036_recalc(dev); + break; + case 0x24 ... 0x2b: + dev->regs[reg] = val; + dev->ems_pages[(reg - 0x04) >> 1].phys = ((dev->regs[reg & 0xfe] & 0x1f) << 19) | + ((dev->regs[reg | 0x01] & 0x1f) << 14); + acc2036_recalc(dev); + break; + case 0x2c: case 0x2d: + dev->regs[reg] = val; + acc2036_recalc(dev); + break; + case 0x2e: + dev->regs[reg] = val | 0x10; + break; + case 0x31: + dev->regs[reg] = val; + mem_a20_alt = (val & 0x01); + mem_a20_recalc(); + flushmmucache(); + if (val & 0x02) { + softresetx86(); /* Pulse reset! */ + cpu_set_edx(); + flushmmucache(); + } + break; + case 0x32 ... 0x3f: + dev->regs[reg] = val; + break; + } else + dev->reg = val; +} + +static void +acc2036_close(void *priv) +{ + acc2036_t *dev = (acc2036_t *) priv; + + free(dev); +} + +static void * +acc2036_init(UNUSED(const device_t *info)) +{ + acc2036_t *dev = (acc2036_t *) calloc(1, sizeof(acc2036_t)); + + for (int i = 0; i < 24; i++) { + ram_page_t *rp = &dev->ram_mid_pages[i]; + + rp->virt = 0x000a0000 + (i << 14); + rp->phys = 0x000a0000 + (i << 14); + mem_mapping_add(&rp->mapping, rp->virt, 0x00004000, + acc2036_mem_read, acc2036_mem_readw, NULL, + acc2036_mem_write, acc2036_mem_writew, NULL, + ram + rp->phys, MEM_MAPPING_INTERNAL, rp); + } + + for (int i = 0; i < 4; i++) { + ram_page_t *ep = &dev->ems_pages[i]; + + ep->virt = 0x000d0000 + (i << 14); + ep->phys = 0x00000000 + (i << 14); + mem_mapping_add(&ep->mapping, ep->virt, 0x00004000, + acc2036_mem_read, acc2036_mem_readw, NULL, + acc2036_mem_write, acc2036_mem_writew, NULL, + ram + ep->phys, MEM_MAPPING_INTERNAL, ep); + mem_mapping_disable(&ep->mapping); + } + + mem_mapping_disable(&ram_mid_mapping); + + dev->regs[0x00] = 0x02; + dev->regs[0x0e] = 0x10; + dev->regs[0x11] = 0x01; + dev->regs[0x13] = 0x40; + dev->regs[0x15] = 0x40; + dev->regs[0x17] = 0x40; + dev->regs[0x19] = 0x40; + dev->regs[0x1b] = 0x40; + dev->regs[0x1c] = 0x22; + dev->regs[0x1d] = 0xc4; + dev->regs[0x1f] = 0x30; + acc2036_recalc(dev); + + mem_a20_alt = 0x01; + mem_a20_recalc(); + flushmmucache(); + + io_sethandler(0x00f2, 0x0002, + acc2036_in, NULL, NULL, acc2036_out, NULL, NULL, dev); + + device_add(&port_92_device); + + return dev; +} + +const device_t acc2036_device = { + .name = "ACC 2036", + .internal_name = "acc2036", + .flags = 0, + .local = 0, + .init = acc2036_init, + .close = acc2036_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 1b5684414..0d750c4cf 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -18,6 +18,7 @@ #define EMU_CHIPSET_H /* ACC */ +extern const device_t acc2036_device; extern const device_t acc2168_device; /* ALi */ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index e59ca494a..3b62d28d6 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -197,6 +197,7 @@ enum { MACHINE_CHIPSET_GC100A, MACHINE_CHIPSET_GC103, MACHINE_CHIPSET_HT18, + MACHINE_CHIPSET_ACC_2036, MACHINE_CHIPSET_ACC_2168, MACHINE_CHIPSET_ALI_M1217, MACHINE_CHIPSET_ALI_M6117, @@ -456,6 +457,7 @@ extern int machine_at_px286_init(const machine_t *); extern int machine_at_quadt286_init(const machine_t *); extern int machine_at_mr286_init(const machine_t *); +extern int machine_at_pbl300sx_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_ataripc4_init(const machine_t *); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 613b294d8..0b07d7a13 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -125,6 +125,8 @@ extern const device_t sio_detect_device; #endif /* USE_SIO_DETECT */ /* UMC */ +extern const device_t um82c862f_device; +extern const device_t um82c862f_ide_device; extern const device_t um82c863f_device; extern const device_t um82c863f_ide_device; extern const device_t um8663af_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 74658708c..77e192291 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -469,6 +469,7 @@ extern const device_t if386jega_device; /* Oak OTI-0x7 */ extern const device_t oti037c_device; +extern const device_t oti037_pbl300sx_device; extern const device_t oti067_device; extern const device_t oti067_acer386_device; extern const device_t oti067_ama932j_device; diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index a295f305a..65fbd4fd9 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -169,6 +169,74 @@ machine_at_quadt386sx_init(const machine_t *model) return ret; } +static const device_config_t pbl300sx_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pbl300sx", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "1991", .internal_name = "pbl300sx_1991", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/V1.10_1113_910723.bin", "" } }, + { .name = "1992", .internal_name = "pbl300sx", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/pb_l300sx_1992.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pbl300sx_device = { + .name = "Packard Bell Legend 300SX", + .internal_name = "pbl300sx_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pbl300sx_config +}; + +int +machine_at_pbl300sx_init(const machine_t *model) +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&acc2036_device); + + device_add(&keyboard_ps2_phoenix_device); + + device_add(&ide_isa_device); + device_add(&um82c862f_ide_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + return ret; +} + int machine_at_neat_init(const machine_t *model) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index b2a335e61..6dd5b1cae 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -822,6 +822,7 @@ machine_at_403tg_d_mr_init(const machine_t *model) return ret; } + static const device_config_t pb450_config[] = { // clang-format off { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 371cb7d47..5c96efc02 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -71,6 +71,7 @@ extern const device_t d842_device; extern const device_t d943_device; extern const device_t dells333sl_device; extern const device_t hot433a_device; +extern const device_t pbl300sx_device; const machine_filter_t machine_types[] = { { "None", MACHINE_TYPE_NONE }, @@ -107,6 +108,7 @@ const machine_filter_t machine_chipsets[] = { { "Headland GC100A", MACHINE_CHIPSET_GC100A }, { "Headland GC103", MACHINE_CHIPSET_GC103 }, { "Headland HT18", MACHINE_CHIPSET_HT18 }, + { "ACC 2036", MACHINE_CHIPSET_ACC_2036 }, { "ACC 2168", MACHINE_CHIPSET_ACC_2168 }, { "ALi M1217", MACHINE_CHIPSET_ALI_M1217 }, { "ALi M6117", MACHINE_CHIPSET_ALI_M6117 }, @@ -4301,6 +4303,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Most likely has Phonenix KBC firmware. */ + { + .name = "[ACC 2036] Packard Bell Legend 300SX", + .internal_name = "pbl300sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ACC_2036, + .init = machine_at_pbl300sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &pbl300sx_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &oti037_pbl300sx_device, + .snd_device = NULL, + .net_device = NULL + }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[ALi M1217] Acrosser AR-B1374", diff --git a/src/sio/sio_um8663f.c b/src/sio/sio_um8663f.c index 03fa4f9aa..6075fe3e7 100644 --- a/src/sio/sio_um8663f.c +++ b/src/sio/sio_um8663f.c @@ -274,13 +274,42 @@ um8663f_init(UNUSED(const device_t *info)) dev->max_reg = info->local >> 8; - io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); + if (dev->max_reg != 0x00) + io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); um8663f_reset(dev); return dev; } +const device_t um82c862f_device = { + .name = "UMC UM82C862F Super I/O", + .internal_name = "um82c862f", + .flags = 0, + .local = 0x0000, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um82c862f_ide_device = { + .name = "UMC UM82C862F Super I/O (With IDE)", + .internal_name = "um82c862f_ide", + .flags = 0, + .local = 0x0001, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t um82c863f_device = { .name = "UMC UM82C863F Super I/O", .internal_name = "um82c863f", diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 70bac6425..3233f9d00 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -30,6 +30,7 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/plat_unused.h> +#include "cpu.h" #define BIOS_037C_PATH "roms/video/oti/bios.bin" #define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.BIN" @@ -38,13 +39,13 @@ #define BIOS_077_PATH "roms/video/oti/oti077.vbi" #define BIOS_077_ACER100T_PATH "roms/machines/acer100t/oti077_acer100t.BIN" - enum { - OTI_037C = 0, - OTI_067 = 2, - OTI_067_AMA932J = 3, - OTI_067_M300 = 4, - OTI_077 = 5, + OTI_037C = 0, + OTI_037_PBL300SX = 1, + OTI_067 = 2, + OTI_067_AMA932J = 3, + OTI_067_M300 = 4, + OTI_077 = 5, OTI_077_ACER100T = 6 }; @@ -76,14 +77,15 @@ oti_out(uint16_t addr, uint8_t val, void *priv) uint8_t idx; uint8_t enable; - if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3C3)) + if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3c3)) return; - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + if (((((addr & 0xfff0) == 0x3d0) || ((addr & 0xfff0) == 0x3b0)) && (addr < 0x3de)) && + !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { - case 0x3C3: + case 0x3c3: if (!oti->chip_id) { oti->enable_register = val & 1; return; @@ -95,20 +97,20 @@ oti_out(uint16_t addr, uint8_t val, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) + if ((oti->chip_id == OTI_077) || (oti->chip_id == OTI_077_ACER100T)) sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else svga_out(addr, val, svga); return; - case 0x3D4: + case 0x3d4: if (oti->chip_id) svga->crtcreg = val & 0x3f; else svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */ return; - case 0x3D5: + case 0x3d5: if (oti->chip_id && (svga->crtcreg & 0x20)) return; idx = svga->crtcreg; @@ -124,7 +126,8 @@ oti_out(uint16_t addr, uint8_t val, void *priv) if ((idx < 0x0e) || (idx > 0x10)) { if (idx == 0x0c || idx == 0x0d) { svga->fullchange = 3; - svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -133,14 +136,14 @@ oti_out(uint16_t addr, uint8_t val, void *priv) } break; - case 0x3DE: + case 0x3de: if (oti->chip_id) oti->index = val & 0x1f; else oti->index = val; return; - case 0x3DF: + case 0x3df: idx = oti->index; if (!oti->chip_id) idx &= 0x1f; @@ -223,14 +226,14 @@ oti_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { - case 0x3C2: + case 0x3c2: if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) temp = 0; else temp = 0x10; break; - case 0x3C3: + case 0x3c3: if (oti->chip_id) temp = svga_in(addr, svga); else @@ -248,11 +251,11 @@ oti_in(uint16_t addr, void *priv) case 0x3CF: return svga->gdcreg[svga->gdcaddr & 0xf]; - case 0x3D4: + case 0x3d4: temp = svga->crtcreg; break; - case 0x3D5: + case 0x3d5: if (oti->chip_id) { if (svga->crtcreg & 0x20) temp = 0xff; @@ -262,17 +265,19 @@ oti_in(uint16_t addr, void *priv) temp = svga->crtc[svga->crtcreg & 0x1f]; break; - case 0x3DA: + case 0x3da: if (oti->chip_id) { temp = svga_in(addr, svga); break; } svga->attrff = 0; - /*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again - and expects the diagnostic bits to equal the current border colour. As I understand - it, the 0x3da active enable status does not include the border time, so this may be - an area where OTI-037C is not entirely VGA compatible.*/ + /* + The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again + and expects the diagnostic bits to equal the current border colour. As I understand + it, the 0x3da active enable status does not include the border time, so this may be + an area where OTI-037C is not entirely VGA compatible. + */ svga->cgastat &= ~0x30; /* copy color diagnostic info from the overscan color register */ switch (svga->attrregs[0x12] & 0x30) { @@ -307,13 +312,13 @@ oti_in(uint16_t addr, void *priv) temp = svga->cgastat; break; - case 0x3DE: + case 0x3de: temp = oti->index; if (oti->chip_id) temp |= (oti->chip_id << 5); break; - case 0x3DF: + case 0x3df: idx = oti->index; if (!oti->chip_id) idx &= 0x1f; @@ -441,6 +446,13 @@ oti_init(const device_t *info) #endif break; + case OTI_037_PBL300SX: + romfn = NULL; + oti->chip_id = 0; + oti->vram_size = 256; + oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */ + break; + case OTI_067_AMA932J: romfn = BIOS_067_AMA932J_PATH; oti->chip_id = 2; @@ -478,26 +490,25 @@ oti_init(const device_t *info) break; } - if (romfn != NULL) { + if (romfn != NULL) rom_init(&oti->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - } oti->vram_mask = (oti->vram_size << 10) - 1; - if (oti->chip_id == OTI_077_ACER100T){ - /* josephillips: Required to show all BIOS - information on Acer 100T only + if (oti->chip_id == OTI_077_ACER100T) { + /* + josephillips: Required to show all BIOS + information on Acer 100T only */ - video_inform(0x1,&timing_oti); - }else{ + video_inform(0x1, &timing_oti); + } else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti); - } svga_init(info, &oti->svga, oti, oti->vram_size << 10, oti_recalctimings, oti_in, oti_out, NULL, NULL); - if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) + if ((oti->chip_id == OTI_077) || (oti->chip_id == OTI_077_ACER100T)) oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/ io_sethandler(0x03c0, 32, @@ -662,6 +673,20 @@ const device_t oti037c_device = { .config = NULL }; +const device_t oti037_pbl300sx_device = { + .name = "Oak OTI-037 (Packard Bell Legend 300SX)", + .internal_name = "oti037_pbl300sx", + .flags = DEVICE_ISA, + .local = 1, + .init = oti_init, + .close = oti_close, + .reset = NULL, + .available = NULL, + .speed_changed = oti_speed_changed, + .force_redraw = oti_force_redraw, + .config = NULL +}; + const device_t oti067_device = { .name = "Oak OTI-067", .internal_name = "oti067", @@ -676,20 +701,6 @@ const device_t oti067_device = { .config = oti067_config }; -const device_t oti067_m300_device = { - .name = "Oak OTI-067 (Olivetti M300-08/15)", - .internal_name = "oti067_m300", - .flags = DEVICE_ISA, - .local = 4, - .init = oti_init, - .close = oti_close, - .reset = NULL, - .available = oti067_m300_available, - .speed_changed = oti_speed_changed, - .force_redraw = oti_force_redraw, - .config = oti067_config -}; - const device_t oti067_ama932j_device = { .name = "Oak OTI-067 (AMA-932J)", .internal_name = "oti067_ama932j", @@ -704,21 +715,20 @@ const device_t oti067_ama932j_device = { .config = oti067_ama932j_config }; -const device_t oti077_acer100t_device = { - .name = "Oak OTI-077 (Acer 100T)", - .internal_name = "oti077_acer100t", +const device_t oti067_m300_device = { + .name = "Oak OTI-067 (Olivetti M300-08/15)", + .internal_name = "oti067_m300", .flags = DEVICE_ISA, - .local = 6, + .local = 4, .init = oti_init, .close = oti_close, .reset = NULL, - .available = oti077_acer100t_available, + .available = oti067_m300_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, - .config = oti077_acer100t_config + .config = oti067_config }; - const device_t oti077_device = { .name = "Oak OTI-077", .internal_name = "oti077", @@ -732,3 +742,17 @@ const device_t oti077_device = { .force_redraw = oti_force_redraw, .config = oti077_config }; + +const device_t oti077_acer100t_device = { + .name = "Oak OTI-077 (Acer 100T)", + .internal_name = "oti077_acer100t", + .flags = DEVICE_ISA, + .local = 6, + .init = oti_init, + .close = oti_close, + .reset = NULL, + .available = oti077_acer100t_available, + .speed_changed = oti_speed_changed, + .force_redraw = oti_force_redraw, + .config = oti077_acer100t_config +};