Added the Packard Bell Legend 300SX.

This commit is contained in:
OBattler
2025-06-13 19:42:59 +02:00
parent 51882035af
commit 8482937f9f
11 changed files with 574 additions and 57 deletions

View File

@@ -17,6 +17,7 @@
add_library(chipset OBJECT add_library(chipset OBJECT
82c100.c 82c100.c
acc2036.c
acc2168.c acc2168.c
cs8220.c cs8220.c
cs8230.c cs8230.c

346
src/chipset/acc2036.c Normal file
View File

@@ -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, <mgrca8@gmail.com>
*
* Copyright 2025 Miran Grca.
*/
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#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
};

View File

@@ -18,6 +18,7 @@
#define EMU_CHIPSET_H #define EMU_CHIPSET_H
/* ACC */ /* ACC */
extern const device_t acc2036_device;
extern const device_t acc2168_device; extern const device_t acc2168_device;
/* ALi */ /* ALi */

View File

@@ -197,6 +197,7 @@ enum {
MACHINE_CHIPSET_GC100A, MACHINE_CHIPSET_GC100A,
MACHINE_CHIPSET_GC103, MACHINE_CHIPSET_GC103,
MACHINE_CHIPSET_HT18, MACHINE_CHIPSET_HT18,
MACHINE_CHIPSET_ACC_2036,
MACHINE_CHIPSET_ACC_2168, MACHINE_CHIPSET_ACC_2168,
MACHINE_CHIPSET_ALI_M1217, MACHINE_CHIPSET_ALI_M1217,
MACHINE_CHIPSET_ALI_M6117, 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_quadt286_init(const machine_t *);
extern int machine_at_mr286_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_init(const machine_t *);
extern int machine_at_neat_ami_init(const machine_t *); extern int machine_at_neat_ami_init(const machine_t *);
extern int machine_at_ataripc4_init(const machine_t *); extern int machine_at_ataripc4_init(const machine_t *);

View File

@@ -125,6 +125,8 @@ extern const device_t sio_detect_device;
#endif /* USE_SIO_DETECT */ #endif /* USE_SIO_DETECT */
/* UMC */ /* 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_device;
extern const device_t um82c863f_ide_device; extern const device_t um82c863f_ide_device;
extern const device_t um8663af_device; extern const device_t um8663af_device;

View File

@@ -469,6 +469,7 @@ extern const device_t if386jega_device;
/* Oak OTI-0x7 */ /* Oak OTI-0x7 */
extern const device_t oti037c_device; extern const device_t oti037c_device;
extern const device_t oti037_pbl300sx_device;
extern const device_t oti067_device; extern const device_t oti067_device;
extern const device_t oti067_acer386_device; extern const device_t oti067_acer386_device;
extern const device_t oti067_ama932j_device; extern const device_t oti067_ama932j_device;

View File

@@ -169,6 +169,74 @@ machine_at_quadt386sx_init(const machine_t *model)
return ret; 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 int
machine_at_neat_init(const machine_t *model) machine_at_neat_init(const machine_t *model)
{ {

View File

@@ -822,6 +822,7 @@ machine_at_403tg_d_mr_init(const machine_t *model)
return ret; return ret;
} }
static const device_config_t pb450_config[] = { static const device_config_t pb450_config[] = {
// clang-format off // clang-format off
{ {

View File

@@ -71,6 +71,7 @@ extern const device_t d842_device;
extern const device_t d943_device; extern const device_t d943_device;
extern const device_t dells333sl_device; extern const device_t dells333sl_device;
extern const device_t hot433a_device; extern const device_t hot433a_device;
extern const device_t pbl300sx_device;
const machine_filter_t machine_types[] = { const machine_filter_t machine_types[] = {
{ "None", MACHINE_TYPE_NONE }, { "None", MACHINE_TYPE_NONE },
@@ -107,6 +108,7 @@ const machine_filter_t machine_chipsets[] = {
{ "Headland GC100A", MACHINE_CHIPSET_GC100A }, { "Headland GC100A", MACHINE_CHIPSET_GC100A },
{ "Headland GC103", MACHINE_CHIPSET_GC103 }, { "Headland GC103", MACHINE_CHIPSET_GC103 },
{ "Headland HT18", MACHINE_CHIPSET_HT18 }, { "Headland HT18", MACHINE_CHIPSET_HT18 },
{ "ACC 2036", MACHINE_CHIPSET_ACC_2036 },
{ "ACC 2168", MACHINE_CHIPSET_ACC_2168 }, { "ACC 2168", MACHINE_CHIPSET_ACC_2168 },
{ "ALi M1217", MACHINE_CHIPSET_ALI_M1217 }, { "ALi M1217", MACHINE_CHIPSET_ALI_M1217 },
{ "ALi M6117", MACHINE_CHIPSET_ALI_M6117 }, { "ALi M6117", MACHINE_CHIPSET_ALI_M6117 },
@@ -4301,6 +4303,46 @@ const machine_t machines[] = {
.snd_device = NULL, .snd_device = NULL,
.net_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'. */ /* This has an AMIKey-2, which is an updated version of type 'H'. */
{ {
.name = "[ALi M1217] Acrosser AR-B1374", .name = "[ALi M1217] Acrosser AR-B1374",

View File

@@ -274,13 +274,42 @@ um8663f_init(UNUSED(const device_t *info))
dev->max_reg = info->local >> 8; 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); um8663f_reset(dev);
return 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 = { const device_t um82c863f_device = {
.name = "UMC UM82C863F Super I/O", .name = "UMC UM82C863F Super I/O",
.internal_name = "um82c863f", .internal_name = "um82c863f",

View File

@@ -30,6 +30,7 @@
#include <86box/vid_svga.h> #include <86box/vid_svga.h>
#include <86box/vid_svga_render.h> #include <86box/vid_svga_render.h>
#include <86box/plat_unused.h> #include <86box/plat_unused.h>
#include "cpu.h"
#define BIOS_037C_PATH "roms/video/oti/bios.bin" #define BIOS_037C_PATH "roms/video/oti/bios.bin"
#define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.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_PATH "roms/video/oti/oti077.vbi"
#define BIOS_077_ACER100T_PATH "roms/machines/acer100t/oti077_acer100t.BIN" #define BIOS_077_ACER100T_PATH "roms/machines/acer100t/oti077_acer100t.BIN"
enum { enum {
OTI_037C = 0, OTI_037C = 0,
OTI_067 = 2, OTI_037_PBL300SX = 1,
OTI_067_AMA932J = 3, OTI_067 = 2,
OTI_067_M300 = 4, OTI_067_AMA932J = 3,
OTI_077 = 5, OTI_067_M300 = 4,
OTI_077 = 5,
OTI_077_ACER100T = 6 OTI_077_ACER100T = 6
}; };
@@ -76,14 +77,15 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
uint8_t idx; uint8_t idx;
uint8_t enable; uint8_t enable;
if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3C3)) if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3c3))
return; 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; addr ^= 0x60;
switch (addr) { switch (addr) {
case 0x3C3: case 0x3c3:
if (!oti->chip_id) { if (!oti->chip_id) {
oti->enable_register = val & 1; oti->enable_register = val & 1;
return; return;
@@ -95,20 +97,20 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
case 0x3c7: case 0x3c7:
case 0x3c8: case 0x3c8:
case 0x3c9: 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); sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga);
else else
svga_out(addr, val, svga); svga_out(addr, val, svga);
return; return;
case 0x3D4: case 0x3d4:
if (oti->chip_id) if (oti->chip_id)
svga->crtcreg = val & 0x3f; svga->crtcreg = val & 0x3f;
else else
svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */ svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */
return; return;
case 0x3D5: case 0x3d5:
if (oti->chip_id && (svga->crtcreg & 0x20)) if (oti->chip_id && (svga->crtcreg & 0x20))
return; return;
idx = svga->crtcreg; idx = svga->crtcreg;
@@ -124,7 +126,8 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
if ((idx < 0x0e) || (idx > 0x10)) { if ((idx < 0x0e) || (idx > 0x10)) {
if (idx == 0x0c || idx == 0x0d) { if (idx == 0x0c || idx == 0x0d) {
svga->fullchange = 3; 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 { } else {
svga->fullchange = changeframecount; svga->fullchange = changeframecount;
svga_recalctimings(svga); svga_recalctimings(svga);
@@ -133,14 +136,14 @@ oti_out(uint16_t addr, uint8_t val, void *priv)
} }
break; break;
case 0x3DE: case 0x3de:
if (oti->chip_id) if (oti->chip_id)
oti->index = val & 0x1f; oti->index = val & 0x1f;
else else
oti->index = val; oti->index = val;
return; return;
case 0x3DF: case 0x3df:
idx = oti->index; idx = oti->index;
if (!oti->chip_id) if (!oti->chip_id)
idx &= 0x1f; idx &= 0x1f;
@@ -223,14 +226,14 @@ oti_in(uint16_t addr, void *priv)
addr ^= 0x60; addr ^= 0x60;
switch (addr) { switch (addr) {
case 0x3C2: case 0x3c2:
if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50)
temp = 0; temp = 0;
else else
temp = 0x10; temp = 0x10;
break; break;
case 0x3C3: case 0x3c3:
if (oti->chip_id) if (oti->chip_id)
temp = svga_in(addr, svga); temp = svga_in(addr, svga);
else else
@@ -248,11 +251,11 @@ oti_in(uint16_t addr, void *priv)
case 0x3CF: case 0x3CF:
return svga->gdcreg[svga->gdcaddr & 0xf]; return svga->gdcreg[svga->gdcaddr & 0xf];
case 0x3D4: case 0x3d4:
temp = svga->crtcreg; temp = svga->crtcreg;
break; break;
case 0x3D5: case 0x3d5:
if (oti->chip_id) { if (oti->chip_id) {
if (svga->crtcreg & 0x20) if (svga->crtcreg & 0x20)
temp = 0xff; temp = 0xff;
@@ -262,17 +265,19 @@ oti_in(uint16_t addr, void *priv)
temp = svga->crtc[svga->crtcreg & 0x1f]; temp = svga->crtc[svga->crtcreg & 0x1f];
break; break;
case 0x3DA: case 0x3da:
if (oti->chip_id) { if (oti->chip_id) {
temp = svga_in(addr, svga); temp = svga_in(addr, svga);
break; break;
} }
svga->attrff = 0; 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 The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again
it, the 0x3da active enable status does not include the border time, so this may be and expects the diagnostic bits to equal the current border colour. As I understand
an area where OTI-037C is not entirely VGA compatible.*/ 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; svga->cgastat &= ~0x30;
/* copy color diagnostic info from the overscan color register */ /* copy color diagnostic info from the overscan color register */
switch (svga->attrregs[0x12] & 0x30) { switch (svga->attrregs[0x12] & 0x30) {
@@ -307,13 +312,13 @@ oti_in(uint16_t addr, void *priv)
temp = svga->cgastat; temp = svga->cgastat;
break; break;
case 0x3DE: case 0x3de:
temp = oti->index; temp = oti->index;
if (oti->chip_id) if (oti->chip_id)
temp |= (oti->chip_id << 5); temp |= (oti->chip_id << 5);
break; break;
case 0x3DF: case 0x3df:
idx = oti->index; idx = oti->index;
if (!oti->chip_id) if (!oti->chip_id)
idx &= 0x1f; idx &= 0x1f;
@@ -441,6 +446,13 @@ oti_init(const device_t *info)
#endif #endif
break; 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: case OTI_067_AMA932J:
romfn = BIOS_067_AMA932J_PATH; romfn = BIOS_067_AMA932J_PATH;
oti->chip_id = 2; oti->chip_id = 2;
@@ -478,26 +490,25 @@ oti_init(const device_t *info)
break; break;
} }
if (romfn != NULL) { if (romfn != NULL)
rom_init(&oti->bios_rom, romfn, rom_init(&oti->bios_rom, romfn,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
}
oti->vram_mask = (oti->vram_size << 10) - 1; oti->vram_mask = (oti->vram_size << 10) - 1;
if (oti->chip_id == OTI_077_ACER100T){ if (oti->chip_id == OTI_077_ACER100T) {
/* josephillips: Required to show all BIOS /*
information on Acer 100T only josephillips: Required to show all BIOS
information on Acer 100T only
*/ */
video_inform(0x1,&timing_oti); video_inform(0x1, &timing_oti);
}else{ } else
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti); video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti);
}
svga_init(info, &oti->svga, oti, oti->vram_size << 10, svga_init(info, &oti->svga, oti, oti->vram_size << 10,
oti_recalctimings, oti_in, oti_out, NULL, NULL); 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.*/ oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/
io_sethandler(0x03c0, 32, io_sethandler(0x03c0, 32,
@@ -662,6 +673,20 @@ const device_t oti037c_device = {
.config = NULL .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 = { const device_t oti067_device = {
.name = "Oak OTI-067", .name = "Oak OTI-067",
.internal_name = "oti067", .internal_name = "oti067",
@@ -676,20 +701,6 @@ const device_t oti067_device = {
.config = oti067_config .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 = { const device_t oti067_ama932j_device = {
.name = "Oak OTI-067 (AMA-932J)", .name = "Oak OTI-067 (AMA-932J)",
.internal_name = "oti067_ama932j", .internal_name = "oti067_ama932j",
@@ -704,21 +715,20 @@ const device_t oti067_ama932j_device = {
.config = oti067_ama932j_config .config = oti067_ama932j_config
}; };
const device_t oti077_acer100t_device = { const device_t oti067_m300_device = {
.name = "Oak OTI-077 (Acer 100T)", .name = "Oak OTI-067 (Olivetti M300-08/15)",
.internal_name = "oti077_acer100t", .internal_name = "oti067_m300",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = 6, .local = 4,
.init = oti_init, .init = oti_init,
.close = oti_close, .close = oti_close,
.reset = NULL, .reset = NULL,
.available = oti077_acer100t_available, .available = oti067_m300_available,
.speed_changed = oti_speed_changed, .speed_changed = oti_speed_changed,
.force_redraw = oti_force_redraw, .force_redraw = oti_force_redraw,
.config = oti077_acer100t_config .config = oti067_config
}; };
const device_t oti077_device = { const device_t oti077_device = {
.name = "Oak OTI-077", .name = "Oak OTI-077",
.internal_name = "oti077", .internal_name = "oti077",
@@ -732,3 +742,17 @@ const device_t oti077_device = {
.force_redraw = oti_force_redraw, .force_redraw = oti_force_redraw,
.config = oti077_config .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
};