mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 09:58:19 -07:00
Merge branch '86Box:master' into master
This commit is contained in:
@@ -72,6 +72,7 @@ add_library(chipset OBJECT
|
||||
sis_5572_usb.c
|
||||
sis_5595_pmu.c
|
||||
sis_55xx.c
|
||||
sl82c461.c
|
||||
via_vt82c49x.c
|
||||
via_vt82c505.c
|
||||
gc100.c
|
||||
|
||||
@@ -1656,7 +1656,12 @@ i4x0_init(const device_t *info)
|
||||
regs[0x57] = 0x31;
|
||||
regs[0x59] = 0x0f;
|
||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02;
|
||||
dev->max_drb = 3;
|
||||
/* At the very least the 420ZX seems to read to 0x64, per the SB486PV. */
|
||||
if (dev->type == INTEL_420ZX) {
|
||||
regs[0x64] = 0x02;
|
||||
dev->max_drb = 4;
|
||||
} else
|
||||
dev->max_drb = 3;
|
||||
dev->drb_unit = 1;
|
||||
dev->drb_default = 0x02;
|
||||
break;
|
||||
|
||||
362
src/chipset/sl82c461.c
Normal file
362
src/chipset/sl82c461.c
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* 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 Symphony SL82C461 (Haydn II) chipset.
|
||||
*
|
||||
* Symphony SL82C461 Configuration Registers (WARNING: May be inaccurate!):
|
||||
*
|
||||
* - Register 00h:
|
||||
* - Bit 6: External cache present (if clear, AMI BIOS'es will not
|
||||
* allow enabling external cache).
|
||||
*
|
||||
* - Register 01h:
|
||||
* - Bit 0: Fast Gate A20 Enable (Handler mostly).
|
||||
* Is it? Enabling/disabling fast gate A20 doesn't appear
|
||||
* to do much to any register at all.
|
||||
*
|
||||
* - Register 02h:
|
||||
* - Bit 0: Optional Chipset Turbo Pin;
|
||||
* - Bits 4-2:
|
||||
* - 000 = CLK2/3;
|
||||
* - 001 = CLK2/4;
|
||||
* - 010 = CLK2/5;
|
||||
* - 011 = 7.159 MHz (ATCLK2);
|
||||
* - 100 = CLK2/6;
|
||||
* - 110 = CLK2/2.5;
|
||||
* - 111 = CLK2/2.
|
||||
*
|
||||
* - Register 06h:
|
||||
* - Bit 2: Decoupled Refresh Option.
|
||||
*
|
||||
* - Register 08h:
|
||||
* - Bits 3, 2: I/O Recovery Time (SYSCLK):
|
||||
* - 0, 0 = 0;
|
||||
* - 1, 1 = 12.
|
||||
* - Bit 1: Extended ALE.
|
||||
*
|
||||
* - Register 25h:
|
||||
* Bit 7 here causes AMI 111192 CMOS Setup to return 7168 KB RAM
|
||||
* instead of 6912 KB. This is 256 KB off. Relocation?
|
||||
* Also, returning bit 5 clear instead of set, causes the AMI BIOS
|
||||
* to set bits 0,1 of register 45h to 1,0 instead of 0,1.
|
||||
*
|
||||
* - Register 2Dh:
|
||||
* - Bit 7: Enable 256KB Memory Relocation;
|
||||
* - Bit 6: Enable 384KB Memory Relocation, bit 7 must also be set.
|
||||
*
|
||||
* - Register 2Eh:
|
||||
* - Bit 7: CC000-CFFFF Shadow Read Enable;
|
||||
* - Bit 6: CC000-CFFFF Shadow Write Enable;
|
||||
* - Bit 5: C8000-CBFFF Shadow Read Enable;
|
||||
* - Bit 4: C8000-CBFFF Shadow Write Enable;
|
||||
* - Bit 3: C4000-C7FFF Shadow Read Enable;
|
||||
* - Bit 2: C4000-C7FFF Shadow Write Enable;
|
||||
* - Bit 1: C0000-C3FFF Shadow Read Enable;
|
||||
* - Bit 0: C0000-C3FFF Shadow Write Enable.
|
||||
*
|
||||
* - Register 2Fh:
|
||||
* - Bit 7: DC000-DFFFF Shadow Read Enable;
|
||||
* - Bit 6: DC000-DFFFF Shadow Write Enable;
|
||||
* - Bit 5: D8000-DBFFF Shadow Read Enable;
|
||||
* - Bit 4: D8000-DBFFF Shadow Write Enable;
|
||||
* - Bit 3: D4000-D7FFF Shadow Read Enable;
|
||||
* - Bit 2: D4000-D7FFF Shadow Write Enable;
|
||||
* - Bit 1: D0000-D3FFF Shadow Read Enable;
|
||||
* - Bit 0: D0000-D3FFF Shadow Write Enable.
|
||||
*
|
||||
* - Register 30h:
|
||||
* - Bit 7: E0000-EFFFF Shadow Read Enable;
|
||||
* - Bit 6: E0000-EFFFF Shadow Write Enable.
|
||||
*
|
||||
* - Register 31h:
|
||||
* - Bit 7: F0000-FFFFF Shadow Read Enable;
|
||||
* - Bit 6: F0000-FFFFF Shadow Write Enable.
|
||||
*
|
||||
* - Register 33h (NOTE: Waitstates also affect register 32h):
|
||||
* - Bits 3, 0:
|
||||
* - 0,0 = 0 W/S;
|
||||
* - 1,0 = 1 W/S;
|
||||
* - 1,1 = 2 W/S.
|
||||
*
|
||||
* - Register 40h:
|
||||
* - Bit 3: External Cache Enabled (0 = yes, 1 = no);
|
||||
* I also see bits 5, 4, 3 of register 44h affected:
|
||||
* - 38h (so all 3 set) when cache is disabled;
|
||||
* - 00h (all 3 clear) when it's enabled.
|
||||
*
|
||||
* - Register 45h:
|
||||
* - Bit 3: Video Shadow RAM Cacheable;
|
||||
* - Bit 4: Adapter Shadow RAM Cacheable;
|
||||
* - Bit 5: BIOS Shadow RAM Cacheable.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
* Copyright 2021-2025 Tiseno100.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#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/mem.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t index;
|
||||
uint8_t regs[256];
|
||||
uint8_t shadow[4];
|
||||
} sl82c461_t;
|
||||
|
||||
#ifdef ENABLE_SL82C461_LOG
|
||||
int sl82c461_do_log = ENABLE_SL82C461_LOG;
|
||||
|
||||
static void
|
||||
sl82c461_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sl82c461_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define sl82c461_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
sl82c461_recalcmapping(sl82c461_t *dev)
|
||||
{
|
||||
int do_shadow = 0;
|
||||
|
||||
for (uint32_t i = 0; i < 8; i += 2) {
|
||||
if ((dev->regs[0x2e] ^ dev->shadow[0x00]) & (3 << i)) {
|
||||
uint32_t base = 0x000c0000 + ((i >> 1) << 14);
|
||||
uint32_t read = ((dev->regs[0x2e] >> i) & 0x02) ? MEM_READ_INTERNAL :
|
||||
MEM_READ_EXTANY;
|
||||
uint32_t write = ((dev->regs[0x2e] >> i) & 0x01) ? MEM_WRITE_INTERNAL :
|
||||
MEM_WRITE_EXTANY;
|
||||
|
||||
mem_set_mem_state_both(base, 0x00004000, read | write);
|
||||
|
||||
do_shadow++;
|
||||
}
|
||||
|
||||
if ((dev->regs[0x2f] ^ dev->shadow[0x01]) & (3 << i)) {
|
||||
uint32_t base = 0x000d0000 + ((i >> 1) << 14);
|
||||
uint32_t read = ((dev->regs[0x2f] >> i) & 0x02) ? MEM_READ_INTERNAL :
|
||||
MEM_READ_EXTANY;
|
||||
uint32_t write = ((dev->regs[0x2f] >> i) & 0x01) ? MEM_WRITE_INTERNAL :
|
||||
MEM_WRITE_EXTANY;
|
||||
|
||||
mem_set_mem_state_both(base, 0x00004000, read | write);
|
||||
|
||||
do_shadow++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dev->regs[0x30] ^ dev->shadow[0x02]) & 0xc0) {
|
||||
uint32_t base = 0x000e0000;
|
||||
uint32_t read = ((dev->regs[0x30] >> 6) & 0x02) ? MEM_READ_INTERNAL :
|
||||
MEM_READ_EXTANY;
|
||||
uint32_t write = ((dev->regs[0x30] >> 6) & 0x01) ? MEM_WRITE_INTERNAL :
|
||||
MEM_WRITE_EXTANY;
|
||||
|
||||
mem_set_mem_state_both(base, 0x00010000, read | write);
|
||||
|
||||
do_shadow++;
|
||||
}
|
||||
|
||||
if ((dev->regs[0x31] ^ dev->shadow[0x03]) & 0xc0) {
|
||||
uint32_t base = 0x000f0000;
|
||||
uint32_t read = ((dev->regs[0x31] >> 6) & 0x02) ? MEM_READ_INTERNAL :
|
||||
MEM_READ_EXTANY;
|
||||
uint32_t write = ((dev->regs[0x31] >> 6) & 0x01) ? MEM_WRITE_INTERNAL :
|
||||
MEM_WRITE_EXTANY;
|
||||
|
||||
shadowbios = !!((dev->regs[0x31] >> 6) & 0x02);
|
||||
shadowbios_write = !!((dev->regs[0x31] >> 6) & 0x01);
|
||||
|
||||
mem_set_mem_state_both(base, 0x00010000, read | write);
|
||||
|
||||
do_shadow++;
|
||||
}
|
||||
|
||||
if (do_shadow) {
|
||||
memcpy(dev->shadow, &(dev->regs[0x2e]), 4 * sizeof(uint8_t));
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sl82c461_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sl82c461_t *dev = (sl82c461_t *) priv;
|
||||
|
||||
sl82c461_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val);
|
||||
|
||||
if (addr & 0x0001) {
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x01:
|
||||
/* NOTE: This is to be verified. */
|
||||
mem_a20_alt = val & 1;
|
||||
mem_a20_recalc();
|
||||
break;
|
||||
case 0x02: {
|
||||
double bus_clk;
|
||||
switch (val & 0x1c) {
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 3.0;
|
||||
break;
|
||||
case 0x04:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
case 0x08:
|
||||
bus_clk = cpu_busspeed / 5.0;
|
||||
break;
|
||||
default:
|
||||
case 0x0c:
|
||||
bus_clk = 7159091.0;
|
||||
break;
|
||||
case 0x10:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x18:
|
||||
bus_clk = cpu_busspeed / 2.5;
|
||||
break;
|
||||
case 0x1c:
|
||||
bus_clk = cpu_busspeed / 2.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
} case 0x2d:
|
||||
switch (val & 0xc0) {
|
||||
case 0xc0:
|
||||
mem_remap_top(384);
|
||||
break;
|
||||
case 0x80:
|
||||
mem_remap_top(256);
|
||||
break;
|
||||
default:
|
||||
case 0x00:
|
||||
mem_remap_top(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x2e ... 0x31:
|
||||
sl82c461_recalcmapping(dev);
|
||||
break;
|
||||
case 0x33:
|
||||
switch (val & 0x09) {
|
||||
default:
|
||||
case 0x00:
|
||||
cpu_waitstates = 0;
|
||||
break;
|
||||
case 0x08:
|
||||
cpu_waitstates = 1;
|
||||
break;
|
||||
case 0x09:
|
||||
cpu_waitstates = 2;
|
||||
break;
|
||||
}
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case 0x40:
|
||||
cpu_cache_ext_enabled = !(val & 0x08);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
}
|
||||
} else
|
||||
dev->index = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sl82c461_read(uint16_t addr, void *priv)
|
||||
{
|
||||
sl82c461_t *dev = (sl82c461_t *) priv;
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
if (addr & 0x0001)
|
||||
if (dev->index == 0x00)
|
||||
ret = dev->regs[dev->index] | 0x40;
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
else
|
||||
ret = dev->index;
|
||||
|
||||
sl82c461_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sl82c461_close(void *priv)
|
||||
{
|
||||
sl82c461_t *dev = (sl82c461_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sl82c461_init(const device_t *info)
|
||||
{
|
||||
sl82c461_t *dev = (sl82c461_t *) calloc(1, sizeof(sl82c461_t));
|
||||
|
||||
dev->regs[0x00] = 0x40;
|
||||
|
||||
dev->regs[0x02] = 0x0c;
|
||||
dev->regs[0x40] = 0x08;
|
||||
|
||||
memset(dev->shadow, 0xff, 4 * sizeof(uint8_t));
|
||||
|
||||
mem_a20_alt = 0x00;
|
||||
mem_a20_recalc();
|
||||
|
||||
cpu_set_isa_speed(7159091.0);
|
||||
|
||||
sl82c461_recalcmapping(dev);
|
||||
|
||||
cpu_waitstates = 0;
|
||||
cpu_cache_ext_enabled = 0;
|
||||
|
||||
cpu_update_waitstates();
|
||||
|
||||
io_sethandler(0x00a8, 2,
|
||||
sl82c461_read, NULL, NULL,
|
||||
sl82c461_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sl82c461_device = {
|
||||
.name = "Symphony SL82C461 (Haydn II)",
|
||||
.internal_name = "sis_85c471",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = sl82c461_init,
|
||||
.close = sl82c461_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -24,14 +24,16 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct vl82c480_t {
|
||||
uint8_t idx;
|
||||
uint8_t regs[256];
|
||||
uint8_t idx;
|
||||
uint8_t regs[256];
|
||||
uint32_t banks[4];
|
||||
} vl82c480_t;
|
||||
|
||||
static int
|
||||
@@ -59,7 +61,7 @@ vl82c480_shflags(uint8_t access)
|
||||
}
|
||||
|
||||
static void
|
||||
vl82c480_recalc(vl82c480_t *dev)
|
||||
vl82c480_recalc_shadow(vl82c480_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint8_t access;
|
||||
@@ -69,8 +71,8 @@ vl82c480_recalc(vl82c480_t *dev)
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
for (uint8_t j = 0; j < 8; j += 2) {
|
||||
base = 0x000a0000 + (i << 16) + (j << 13);
|
||||
access = (dev->regs[0x0d + i] >> j) & 3;
|
||||
base = 0x000a0000 + (i << 16) + (j << 13);
|
||||
access = (dev->regs[0x0d + i] >> j) & 3;
|
||||
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access));
|
||||
shadowbios |= ((base >= 0xe0000) && (access & 0x02));
|
||||
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01));
|
||||
@@ -80,6 +82,37 @@ vl82c480_recalc(vl82c480_t *dev)
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
vl82c480_recalc_banks(vl82c480_t *dev)
|
||||
{
|
||||
uint32_t sizes[8] = { 0, 0, 1024, 2048, 4096, 8192, 16384, 32768 };
|
||||
uint8_t shifts[4] = { 0, 4, 0, 4 };
|
||||
uint8_t regs[4] = { 0x02, 0x02, 0x03, 0x03 };
|
||||
uint32_t total = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
uint8_t shift = shifts[i];
|
||||
uint8_t reg = regs[i];
|
||||
uint8_t cfg = (dev->regs[reg] >> shift) & 0x7;
|
||||
uint32_t size = sizes[cfg];
|
||||
|
||||
total += MIN(dev->banks[i], size);
|
||||
}
|
||||
|
||||
if (total > 1024) {
|
||||
mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000);
|
||||
mem_mapping_set_addr(&ram_high_mapping, 0x00100000, (total - 1024) << 10);
|
||||
} else {
|
||||
if (total >= 1024)
|
||||
mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000);
|
||||
else
|
||||
mem_mapping_disable(&ram_low_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
vl82c480_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -91,16 +124,24 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0xed:
|
||||
if (dev->idx >= 0x01 && dev->idx <= 0x24) {
|
||||
if (((dev->idx >= 0x01) && (dev->idx <= 0x19)) ||
|
||||
((dev->idx >= 0x20) && (dev->idx <= 0x24))) {
|
||||
switch (dev->idx) {
|
||||
default:
|
||||
dev->regs[dev->idx] = val;
|
||||
break;
|
||||
case 0x02: case 0x03:
|
||||
dev->regs[dev->idx] = val;
|
||||
if (!strcmp(machine_get_internal_name(), "martin"))
|
||||
vl82c480_recalc_banks(dev);
|
||||
break;
|
||||
case 0x04:
|
||||
if (dev->regs[0x00] == 0x98)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
if (!strcmp(machine_get_internal_name(), "martin"))
|
||||
dev->regs[dev->idx] &= 0x1f;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x10) | (val & 0xef);
|
||||
@@ -108,14 +149,9 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x07:
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x40) | (val & 0xbf);
|
||||
break;
|
||||
case 0x0d:
|
||||
case 0x0e:
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x0d ... 0x12:
|
||||
dev->regs[dev->idx] = val;
|
||||
vl82c480_recalc(dev);
|
||||
vl82c480_recalc_shadow(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -124,8 +160,8 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv)
|
||||
/* TODO: This is actually Fast A20 disable. */
|
||||
#if 0
|
||||
case 0xee:
|
||||
if (mem_a20_alt)
|
||||
outb(0x92, inb(0x92) & ~2);
|
||||
mem_a20_alt = 0x00;
|
||||
mem_a20_recalc();
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -146,14 +182,16 @@ vl82c480_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case 0xed:
|
||||
ret = dev->regs[dev->idx];
|
||||
if (((dev->idx >= 0x01) && (dev->idx <= 0x19)) ||
|
||||
((dev->idx >= 0x20) && (dev->idx <= 0x24)))
|
||||
ret = dev->regs[dev->idx];
|
||||
break;
|
||||
|
||||
/* TODO: This is actually Fast A20 enable. */
|
||||
#if 0
|
||||
case 0xee:
|
||||
if (!mem_a20_alt)
|
||||
outb(0x92, inb(0x92) | 2);
|
||||
mem_a20_alt = 0x02;
|
||||
mem_a20_recalc();
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -180,7 +218,9 @@ vl82c480_close(void *priv)
|
||||
static void *
|
||||
vl82c480_init(const device_t *info)
|
||||
{
|
||||
vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t));
|
||||
vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t));
|
||||
uint32_t sizes[8] = { 0, 0, 1024, 2048, 4096, 8192, 16384, 32768 };
|
||||
uint32_t ms = mem_size;
|
||||
|
||||
dev->regs[0x00] = info->local;
|
||||
dev->regs[0x01] = 0xff;
|
||||
@@ -191,9 +231,23 @@ vl82c480_init(const device_t *info)
|
||||
dev->regs[0x07] = 0x21;
|
||||
dev->regs[0x08] = 0x38;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
for (uint8_t j = 2; j < 7; j++) {
|
||||
if (ms >= sizes[j])
|
||||
dev->banks[i] = sizes[j];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
ms -= dev->banks[i];
|
||||
|
||||
if ((ms == 0) || (dev->banks[i] == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev);
|
||||
|
||||
device_add(&port_92_device);
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -390,6 +390,8 @@ ropPUSHF(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUS
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
uop_CALL_FUNC(ir, flags_rebuild);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
|
||||
uop_AND_IMM(ir, IREG_flags, IREG_flags, 0x7fd5);
|
||||
uop_OR_IMM(ir, IREG_flags, IREG_flags, 0x0002);
|
||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags);
|
||||
SUB_SP(ir, 2);
|
||||
|
||||
@@ -406,6 +408,8 @@ ropPUSHFD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNU
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
uop_CALL_FUNC(ir, flags_rebuild);
|
||||
|
||||
uop_AND_IMM(ir, IREG_flags, IREG_flags, 0x7fd5);
|
||||
uop_OR_IMM(ir, IREG_flags, IREG_flags, 0x0002);
|
||||
if (cpu_CR4_mask & CR4_VME)
|
||||
uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c);
|
||||
else if (CPUID)
|
||||
|
||||
@@ -121,6 +121,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||
if (cpu_state.eflags & VIF_FLAG)
|
||||
temp |= I_FLAG;
|
||||
temp = (temp & 0x7fd5) | 2;
|
||||
PUSH_W(temp);
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
@@ -128,6 +129,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
||||
}
|
||||
} else {
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||
PUSH_W(cpu_state.flags);
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
@@ -149,6 +151,7 @@ opPUSHFD(UNUSED(uint32_t fetchdat))
|
||||
else
|
||||
tempw = cpu_state.eflags & 4;
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
||||
@@ -160,23 +163,11 @@ opPOPF_186(UNUSED(uint32_t fetchdat))
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(msw & 1))
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
flags_extract();
|
||||
#ifdef USE_DEBUG_REGS_486
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
@@ -121,6 +121,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||
if (cpu_state.eflags & VIF_FLAG)
|
||||
temp |= I_FLAG;
|
||||
temp = (temp & 0x7fd5) | 2;
|
||||
PUSH_W(temp);
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
@@ -128,6 +129,7 @@ opPUSHF(UNUSED(uint32_t fetchdat))
|
||||
}
|
||||
} else {
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||
PUSH_W(cpu_state.flags);
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
@@ -149,6 +151,7 @@ opPUSHFD(UNUSED(uint32_t fetchdat))
|
||||
else
|
||||
tempw = cpu_state.eflags & 4;
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2;
|
||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
||||
@@ -160,23 +163,11 @@ opPOPF_186(UNUSED(uint32_t fetchdat))
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(msw & 1))
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
|
||||
10
src/device.c
10
src/device.c
@@ -897,8 +897,14 @@ device_is_valid(const device_t *device, int mch)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if ((device != NULL) && ((device->flags & DEVICE_BUS) != 0))
|
||||
ret = machine_has_bus(mch, device->flags & DEVICE_BUS);
|
||||
if ((device != NULL) && ((device->flags & DEVICE_BUS) != 0)) {
|
||||
/* Hide PCI devices on machines with only an internal PCI bus. */
|
||||
if ((device->flags & DEVICE_PCI) &&
|
||||
machine_has_flags(mch, MACHINE_PCI_INTERNAL))
|
||||
ret = 0;
|
||||
else
|
||||
ret = machine_has_bus(mch, device->flags & DEVICE_BUS);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1336,7 +1336,10 @@ write64_ami(void *priv, uint8_t val)
|
||||
kbc_at_log("ATkbc: set KBC lines P22-P23 (P2 bits 2-3) low\n");
|
||||
if (!(dev->flags & DEVICE_PCI))
|
||||
write_p2(dev, dev->p2 & ~(4 << (val & 0x01)));
|
||||
kbc_delay_to_ob(dev, dev->ob, 0, 0x00);
|
||||
if (strstr(machine_get_internal_name(), "sb486pv") != NULL)
|
||||
kbc_delay_to_ob(dev, 0x03, 0, 0x00);
|
||||
else
|
||||
kbc_delay_to_ob(dev, dev->ob, 0, 0x00);
|
||||
dev->pending++;
|
||||
return 0;
|
||||
|
||||
@@ -2149,6 +2152,12 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
dev->wantdata = 0;
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
|
||||
/*
|
||||
Explicitly clear IBF so that any preceding
|
||||
command is not executed.
|
||||
*/
|
||||
dev->status &= ~STAT_IFULL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -2160,11 +2169,36 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
dev->command = 0xd1;
|
||||
|
||||
/*
|
||||
Explicitly clear IBF so that any preceding
|
||||
command is not executed.
|
||||
*/
|
||||
dev->status &= ~STAT_IFULL;
|
||||
return;
|
||||
} else if (fast_reset && ((val & 0xf0) == 0xf0)) {
|
||||
pulse_output(dev, val & 0x0f);
|
||||
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
|
||||
/*
|
||||
Explicitly clear IBF so that any preceding
|
||||
command is not executed.
|
||||
*/
|
||||
dev->status &= ~STAT_IFULL;
|
||||
return;
|
||||
} else if (val == 0xad) {
|
||||
/* Fast track it because of the Bochs BIOS. */
|
||||
kbc_at_log("ATkbc: disable keyboard\n");
|
||||
set_enable_kbd(dev, 0);
|
||||
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
|
||||
/*
|
||||
Explicitly clear IBF so that any preceding
|
||||
command is not executed.
|
||||
*/
|
||||
dev->status &= ~STAT_IFULL;
|
||||
return;
|
||||
} else if (val == 0xae) {
|
||||
/* Fast track it because of the LG MultiNet. */
|
||||
@@ -2172,6 +2206,12 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
set_enable_kbd(dev, 1);
|
||||
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
|
||||
/*
|
||||
Explicitly clear IBF so that any preceding
|
||||
command is not executed.
|
||||
*/
|
||||
dev->status &= ~STAT_IFULL;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -58,7 +58,7 @@ kbc_at_dev_log(const char *fmt, ...)
|
||||
# define kbc_at_dev_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
void
|
||||
kbc_at_dev_queue_reset(atkbc_dev_t *dev, uint8_t reset_main)
|
||||
{
|
||||
if (reset_main) {
|
||||
@@ -95,10 +95,6 @@ kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main)
|
||||
dev->cmd_queue[dev->cmd_queue_end] = val;
|
||||
dev->cmd_queue_end = (dev->cmd_queue_end + 1) & 0xf;
|
||||
}
|
||||
|
||||
/* TODO: This should be done on actual send to host. */
|
||||
if (val != 0xfe)
|
||||
dev->last_scan_code = val;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -123,6 +119,8 @@ kbc_at_dev_poll(void *priv)
|
||||
(dev->queue_start != dev->queue_end)) {
|
||||
kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]);
|
||||
dev->port->out_new = dev->queue[dev->queue_start];
|
||||
if (dev->port->out_new != 0xfe)
|
||||
dev->last_scan_code = dev->port->out_new;
|
||||
dev->queue_start = (dev->queue_start + 1) & dev->fifo_mask;
|
||||
}
|
||||
if (dev->ignore || !(*dev->scan) || dev->port->wantcmd)
|
||||
@@ -143,6 +141,8 @@ kbc_at_dev_poll(void *priv)
|
||||
if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) {
|
||||
kbc_at_dev_log("%s: %02X (CMD ) on channel 1\n", dev->name, dev->cmd_queue[dev->cmd_queue_start]);
|
||||
dev->port->out_new = dev->cmd_queue[dev->cmd_queue_start];
|
||||
if (dev->port->out_new != 0xfe)
|
||||
dev->last_scan_code = dev->port->out_new;
|
||||
dev->cmd_queue_start = (dev->cmd_queue_start + 1) & 0xf;
|
||||
}
|
||||
if (dev->cmd_queue_start == dev->cmd_queue_end)
|
||||
@@ -166,6 +166,8 @@ kbc_at_dev_poll(void *priv)
|
||||
if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) {
|
||||
kbc_at_dev_log("%s: %02X (CMD ) on channel 1\n", dev->name, dev->cmd_queue[dev->cmd_queue_start]);
|
||||
dev->port->out_new = dev->cmd_queue[dev->cmd_queue_start];
|
||||
if (dev->port->out_new != 0xfe)
|
||||
dev->last_scan_code = dev->port->out_new;
|
||||
dev->cmd_queue_start = (dev->cmd_queue_start + 1) & 0xf;
|
||||
}
|
||||
if (dev->cmd_queue_start == dev->cmd_queue_end)
|
||||
|
||||
@@ -428,11 +428,11 @@ static const scancode scancode_set1[512] = {
|
||||
{ .mk = {0xe0, 0x57, 0 }, .brk = { 0xe0, 0xd7, 0 } }, /* 157 */
|
||||
{ .mk = {0xe0, 0x58, 0 }, .brk = { 0xe0, 0xd8, 0 } }, /* 158 */
|
||||
{ .mk = {0xe0, 0x59, 0 }, .brk = { 0xe0, 0xd9, 0 } }, /* 159 */
|
||||
{ .mk = {0xe0, 0x5a, 0 }, .brk = { 0xe0, 0xaa, 0 } }, /* 15a */
|
||||
{ .mk = {0xe0, 0x5a, 0 }, .brk = { 0xe0, 0xda, 0 } }, /* 15a */
|
||||
{ .mk = {0xe0, 0x5b, 0 }, .brk = { 0xe0, 0xdb, 0 } }, /* 15b */
|
||||
{ .mk = {0xe0, 0x5c, 0 }, .brk = { 0xe0, 0xdc, 0 } }, /* 15c */
|
||||
{ .mk = {0xe0, 0x5d, 0 }, .brk = { 0xe0, 0xdd, 0 } }, /* 15d */
|
||||
{ .mk = {0xe0, 0x5e, 0 }, .brk = { 0xe0, 0xee, 0 } }, /* 15e */
|
||||
{ .mk = {0xe0, 0x5e, 0 }, .brk = { 0xe0, 0xde, 0 } }, /* 15e */
|
||||
{ .mk = {0xe0, 0x5f, 0 }, .brk = { 0xe0, 0xdf, 0 } }, /* 15f */
|
||||
{ .mk = { 0 }, .brk = { 0 } }, /* 160 */
|
||||
{ .mk = {0xe0, 0x61, 0 }, .brk = { 0xe0, 0xe1, 0 } }, /* 161 */
|
||||
@@ -3494,7 +3494,6 @@ keyboard_at_invalid_cmd(atkbc_dev_t *dev)
|
||||
kbc_at_dev_queue_add(dev, inv_cmd_response, 0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
keyboard_at_write(void *priv)
|
||||
{
|
||||
@@ -3643,6 +3642,13 @@ keyboard_at_write(void *priv)
|
||||
case 0xf6: /* set defaults */
|
||||
keyboard_at_log("%s: set defaults%s\n",
|
||||
dev->name, (val == 0xf6) ? "" : " and disable keyboard");
|
||||
dev->port->out_new = -1;
|
||||
dev->port->wantcmd = 0;
|
||||
|
||||
kbc_at_dev_queue_reset(dev, 1);
|
||||
|
||||
dev->last_scan_code = 0x00;
|
||||
|
||||
keyboard_scan = !(val & 0x01);
|
||||
keyboard_at_log("%s: val = %02X, keyboard_scan = %i\n",
|
||||
dev->name, val, keyboard_scan);
|
||||
@@ -3712,7 +3718,6 @@ keyboard_at_write(void *priv)
|
||||
/* TODO: This is supposed to resend multiple bytes after some commands. */
|
||||
case 0xfe: /* resend last scan code */
|
||||
keyboard_at_log("%s: resend last scan code\n", dev->name);
|
||||
kbc_at_dev_queue_add(dev, 0xfa, 0);
|
||||
kbc_at_dev_queue_add(dev, dev->last_scan_code, 0);
|
||||
break;
|
||||
|
||||
@@ -3728,6 +3733,44 @@ keyboard_at_write(void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SCAN_CODE_TABLES_COMPARISON
|
||||
/* Non-translated to translated scan codes. */
|
||||
static const uint8_t nont_to_t[256] = {
|
||||
0x00, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
|
||||
0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
|
||||
0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
|
||||
0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
|
||||
0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
|
||||
0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
|
||||
0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
|
||||
0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
|
||||
0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
|
||||
0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
|
||||
0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
|
||||
0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
|
||||
0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
|
||||
0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
|
||||
0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
|
||||
0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
|
||||
0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
||||
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize the device for use by the user.
|
||||
*
|
||||
@@ -3777,6 +3820,138 @@ keyboard_at_init(const device_t *info)
|
||||
|
||||
inv_cmd_response = (dev->type & FLAG_PS2) ? 0xfe : 0xfa;
|
||||
|
||||
#ifdef SCAN_CODE_TABLES_COMPARISON
|
||||
pclog_toggle_suppr();
|
||||
|
||||
pclog("Scan code set 01 vs. 81 (make):\n===============================\n");
|
||||
for (int i = 0; i < 512; i++) {
|
||||
pclog("Scan code %03X:", i);
|
||||
int j = 0;
|
||||
do {
|
||||
if (scancode_set1[i].mk[j] == scancode_set81[i].mk[j])
|
||||
pclog(" --");
|
||||
else
|
||||
pclog(" (%02X != %02X)", scancode_set1[i].mk[j], scancode_set81[i].mk[j]);
|
||||
j++;
|
||||
} while ((scancode_set1[i].mk[j] != 0) && (scancode_set81[i].mk[j] != 0));
|
||||
pclog("\n");
|
||||
}
|
||||
|
||||
pclog("\nScan code set 01 vs. 81 (break):\n================================\n");
|
||||
for (int i = 0; i < 512; i++) {
|
||||
pclog("Scan code %03X:", i);
|
||||
int j = 0;
|
||||
do {
|
||||
if (scancode_set1[i].brk[j] == scancode_set81[i].brk[j])
|
||||
pclog(" --");
|
||||
else
|
||||
pclog(" (%02X != %02X)", scancode_set1[i].brk[j], scancode_set81[i].brk[j]);
|
||||
j++;
|
||||
} while ((scancode_set1[i].brk[j] != 0) && (scancode_set81[i].brk[j] != 0));
|
||||
pclog("\n");
|
||||
}
|
||||
|
||||
pclog("\nScan code set 02 vs. 82 (make):\n===============================\n");
|
||||
for (int i = 0; i < 512; i++) {
|
||||
pclog("Scan code %03X:", i);
|
||||
int j = 0;
|
||||
do {
|
||||
if (scancode_set2[i].mk[j] == scancode_set82[i].mk[j])
|
||||
pclog(" --");
|
||||
else
|
||||
pclog(" (%02X != %02X)", scancode_set2[i].mk[j], scancode_set82[i].mk[j]);
|
||||
j++;
|
||||
} while ((scancode_set2[i].mk[j] != 0) && (scancode_set82[i].mk[j] != 0));
|
||||
pclog("\n");
|
||||
}
|
||||
|
||||
pclog("\nScan code set 02 vs. 82 (break):\n================================\n");
|
||||
for (int i = 0; i < 512; i++) {
|
||||
pclog("Scan code %03X:", i);
|
||||
int j = 0;
|
||||
do {
|
||||
if (scancode_set2[i].brk[j] == scancode_set82[i].brk[j])
|
||||
pclog(" --");
|
||||
else
|
||||
pclog(" (%02X != %02X)", scancode_set2[i].brk[j], scancode_set82[i].brk[j]);
|
||||
j++;
|
||||
} while ((scancode_set2[i].brk[j] != 0) && (scancode_set82[i].brk[j] != 0));
|
||||
pclog("\n");
|
||||
}
|
||||
|
||||
pclog("\nScan code set 01 vs. 02 (make):\n===============================\n");
|
||||
for (int i = 0; i < 512; i++) {
|
||||
pclog("Scan code %03X:", i);
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
int was_f0 = 0;
|
||||
do {
|
||||
if (scancode_set2[i].mk[k] == 0xf0)
|
||||
was_f0 = 1;
|
||||
else {
|
||||
uint8_t code = nont_to_t[scancode_set2[i].mk[k]];
|
||||
|
||||
if (was_f0) {
|
||||
if (code & 0x80)
|
||||
code = 0x00;
|
||||
else
|
||||
code |= 0x80;
|
||||
|
||||
was_f0 = 0;
|
||||
}
|
||||
|
||||
if (scancode_set1[i].mk[j] == code)
|
||||
pclog(" --");
|
||||
else
|
||||
pclog(" (%02X != %02X)", scancode_set1[i].mk[j], code);
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
k++;
|
||||
} while ((scancode_set1[i].mk[j] != 0) && (scancode_set2[i].mk[k] != 0));
|
||||
pclog("\n");
|
||||
}
|
||||
|
||||
pclog("\nScan code set 01 vs. 02 (break):\n================================\n");
|
||||
for (int i = 0; i < 512; i++) {
|
||||
pclog("Scan code %03X:", i);
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
int was_f0 = 0;
|
||||
do {
|
||||
if (scancode_set2[i].brk[k] == 0xf0)
|
||||
was_f0 = 1;
|
||||
else {
|
||||
uint8_t code = nont_to_t[scancode_set2[i].brk[k]];
|
||||
|
||||
if (was_f0) {
|
||||
if (code & 0x80)
|
||||
code = 0x00;
|
||||
else
|
||||
code |= 0x80;
|
||||
|
||||
was_f0 = 0;
|
||||
}
|
||||
|
||||
if (scancode_set1[i].brk[j] == code)
|
||||
pclog(" --");
|
||||
else
|
||||
pclog(" (%02X != %02X)", scancode_set1[i].brk[j], code);
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
k++;
|
||||
} while ((scancode_set1[i].brk[j] != 0) && (scancode_set2[i].brk[k] != 0));
|
||||
pclog("\n");
|
||||
}
|
||||
|
||||
pclog_toggle_suppr();
|
||||
|
||||
fatal("Comparison finished\n");
|
||||
#endif
|
||||
|
||||
/* Return our private data to the I/O layer. */
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -333,13 +333,13 @@ ps2_poll(void *priv)
|
||||
atkbc_dev_t *dev = (atkbc_dev_t *) priv;
|
||||
int packet_size = (dev->flags & FLAG_INTMODE) ? 4 : 3;
|
||||
|
||||
int cond = (!mouse_capture && !video_fullscreen) || (!mouse_scan || !mouse_state_changed()) ||
|
||||
((dev->mode == MODE_STREAM) && (kbc_at_dev_queue_pos(dev, 1) >= (FIFO_SIZE - packet_size)));
|
||||
int cond = (mouse_capture || video_fullscreen) && mouse_scan && (dev->mode == MODE_STREAM) &&
|
||||
mouse_state_changed() && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size));
|
||||
|
||||
if (!cond && (dev->mode == MODE_STREAM))
|
||||
if (cond)
|
||||
ps2_report_coordinates(dev, 1);
|
||||
|
||||
return cond;
|
||||
return !cond;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -147,14 +147,17 @@ postcard_init(UNUSED(const device_t *info))
|
||||
|
||||
if (machine_has_bus(machine, MACHINE_BUS_MCA))
|
||||
postcard_port = 0x680; /* MCA machines */
|
||||
else if (strstr(machines[machine].name, " PS/2 ") || strstr(machine_getname_ex(machine), " PS/1 "))
|
||||
else if (strstr(machines[machine].name, " PS/2 ") ||
|
||||
strstr(machine_getname_ex(machine), " PS/1 "))
|
||||
postcard_port = 0x190; /* ISA PS/2 machines */
|
||||
else if (strstr(machines[machine].name, " IBM XT "))
|
||||
postcard_port = 0x60; /* IBM XT */
|
||||
else if (strstr(machines[machine].name, " IBM PCjr")) {
|
||||
postcard_port = 0x10; /* IBM PCjr */
|
||||
postcard_ports_num = 3; /* IBM PCjr error ports 11h and 12h */
|
||||
} else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI))
|
||||
} else if (strstr(machines[machine].name, " Compaq ") &&
|
||||
!strstr(machines[machine].name, " Presario ") &&
|
||||
!strstr(machines[machine].name, " ProSignia "))
|
||||
postcard_port = 0x84; /* ISA Compaq machines */
|
||||
else if (strstr(machines[machine].name, "Olivetti"))
|
||||
postcard_port = 0x378; /* Olivetti machines */
|
||||
|
||||
@@ -81,7 +81,6 @@ int fdc_current[FDC_MAX] = { 0, 0 };
|
||||
|
||||
volatile int fdcinited = 0;
|
||||
|
||||
// #define ENABLE_FDC_LOG 1
|
||||
#ifdef ENABLE_FDC_LOG
|
||||
int fdc_do_log = ENABLE_FDC_LOG;
|
||||
|
||||
|
||||
@@ -159,6 +159,9 @@ extern const device_t stpc_atlas_device;
|
||||
extern const device_t stpc_serial_device;
|
||||
extern const device_t stpc_lpt_device;
|
||||
|
||||
/* Symphony */
|
||||
extern const device_t sl82c461_device;
|
||||
|
||||
/* UMC */
|
||||
extern const device_t umc_8886f_device;
|
||||
extern const device_t umc_8886af_device;
|
||||
|
||||
@@ -291,6 +291,7 @@ extern void kbc_at_write_p(void *priv, uint8_t port, uint8_t mask, uint8_t v
|
||||
extern void kbc_at_set_fast_reset(uint8_t new_fast_reset);
|
||||
extern void kbc_at_handler(int set, void *priv);
|
||||
|
||||
extern void kbc_at_dev_queue_reset(atkbc_dev_t *dev, uint8_t reset_main);
|
||||
extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main);
|
||||
extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main);
|
||||
extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa);
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
/* Feature flags for advanced devices. */
|
||||
#define MACHINE_APM 0x00080000 /* sys has APM */
|
||||
#define MACHINE_ACPI 0x00100000 /* sys has ACPI */
|
||||
#define MACHINE_HWM 0x00200000 /* sys has hw monitor */
|
||||
#define MACHINE_PCI_INTERNAL 0x00200000 /* sys has only internal PCI */
|
||||
#define MACHINE_CARTRIDGE 0x00400000 /* sys has cartridge bays */
|
||||
/* Feature flags for internal storage controllers. */
|
||||
#define MACHINE_MFM 0x00800000 /* sys has int MFM/RLL */
|
||||
@@ -519,6 +519,7 @@ extern int machine_at_asus386_init(const machine_t *);
|
||||
extern int machine_at_ecs386_init(const machine_t *);
|
||||
extern int machine_at_spc6000a_init(const machine_t *);
|
||||
extern int machine_at_micronics386_init(const machine_t *);
|
||||
extern int machine_at_micronics386px_init(const machine_t *);
|
||||
extern int machine_at_ecs386v_init(const machine_t *);
|
||||
extern int machine_at_tandy4000_init(const machine_t *);
|
||||
|
||||
@@ -544,6 +545,7 @@ extern int machine_at_exp4349_init(const machine_t *);
|
||||
|
||||
extern int machine_at_vect486vl_init(const machine_t *);
|
||||
extern int machine_at_d824_init(const machine_t *);
|
||||
extern int machine_at_martin_init(const machine_t *);
|
||||
|
||||
extern int machine_at_403tg_init(const machine_t *);
|
||||
extern int machine_at_403tg_d_init(const machine_t *);
|
||||
@@ -554,6 +556,7 @@ extern int machine_at_aptiva510_init(const machine_t *);
|
||||
extern int machine_at_pc330_6573_init(const machine_t *);
|
||||
extern int machine_at_mvi486_init(const machine_t *);
|
||||
|
||||
extern int machine_at_dtk461_init(const machine_t *);
|
||||
extern int machine_at_sis401_init(const machine_t *);
|
||||
extern int machine_at_isa486_init(const machine_t *);
|
||||
extern int machine_at_av4_init(const machine_t *);
|
||||
@@ -585,6 +588,7 @@ extern int machine_at_sb486p_init(const machine_t *);
|
||||
extern int machine_at_486sp3_init(const machine_t *);
|
||||
extern int machine_at_486sp3c_init(const machine_t *);
|
||||
extern int machine_at_486sp3g_init(const machine_t *);
|
||||
extern int machine_at_sb486pv_init(const machine_t *);
|
||||
extern int machine_at_486ap4_init(const machine_t *);
|
||||
extern int machine_at_g486vpa_init(const machine_t *);
|
||||
extern int machine_at_486vipio2_init(const machine_t *);
|
||||
|
||||
@@ -99,6 +99,7 @@ extern const device_t ami_1994_nvr_device;
|
||||
extern const device_t ami_1995_nvr_device;
|
||||
extern const device_t via_nvr_device;
|
||||
extern const device_t p6rp4_nvr_device;
|
||||
extern const device_t martin_nvr_device;
|
||||
extern const device_t elt_nvr_device;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -71,7 +71,10 @@ extern const device_t fdc37m60x_370_device;
|
||||
/* ITE */
|
||||
extern const device_t it8661f_device;
|
||||
extern const device_t it8671f_device;
|
||||
|
||||
/* Intel */
|
||||
extern const device_t i82091aa_device;
|
||||
extern const device_t i82091aa_26e_device;
|
||||
extern const device_t i82091aa_398_device;
|
||||
extern const device_t i82091aa_ide_pri_device;
|
||||
extern const device_t i82091aa_ide_device;
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
#define AC97_CODEC_STAC9708 AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08)
|
||||
#define AC97_CODEC_STAC9721 AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09)
|
||||
#define AC97_CODEC_TR28023 AC97_VENDOR_ID('T', 'R', 'A', 0x03)
|
||||
#define AC97_CODEC_W83971D AC97_VENDOR_ID('W', 'E', 'C', 0x01)
|
||||
#define AC97_CODEC_WM9701A AC97_VENDOR_ID('W', 'M', 'L', 0x00)
|
||||
|
||||
typedef struct ac97_vendor_reg_t {
|
||||
@@ -150,6 +151,7 @@ extern const device_t cs4297a_device;
|
||||
extern const device_t stac9708_device;
|
||||
extern const device_t stac9721_device;
|
||||
extern const device_t tr28023_device;
|
||||
extern const device_t w83971d_device;
|
||||
extern const device_t wm9701a_device;
|
||||
|
||||
extern const device_t ac97_via_device;
|
||||
|
||||
@@ -281,6 +281,26 @@ machine_at_micronics386_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_micronics386px_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-LO.BIN",
|
||||
"roms/machines/micronics386/386-Micronics-09-00021-HI.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_init(model);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
machine_at_scat_init(const machine_t *model, int is_v4, int is_ami)
|
||||
{
|
||||
@@ -704,7 +724,9 @@ machine_at_cmdsl386sx25_init(const machine_t *model)
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&gd5402_onboard_device);
|
||||
|
||||
machine_at_common_ide_init(model);
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
device_add(&ali5105_device); /* The FDC is part of the ALi M5105. */
|
||||
device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */
|
||||
|
||||
@@ -134,6 +134,27 @@ machine_at_tandy4000_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_dtk461_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/dtk461/DTK.BIO",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&sl82c461_device);
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
machine_at_sis401_common_init(const machine_t *model)
|
||||
{
|
||||
@@ -391,14 +412,16 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
device_add(&vl82c480_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
device_add(&vl82c480_device);
|
||||
|
||||
device_add(&vl82c113_device);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
device_add(&fdc37c651_ide_device);
|
||||
|
||||
return ret;
|
||||
@@ -415,14 +438,18 @@ machine_at_d824_init(const machine_t *model)
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&vl82c480_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&gd5428_onboard_device);
|
||||
|
||||
device_add(&keyboard_ps2_device);
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
device_add(&vl82c480_device);
|
||||
|
||||
/*
|
||||
Technically, it should be the VL82C114 but we do not have
|
||||
a proper datasheet of it that tells us the registers.
|
||||
*/
|
||||
device_add(&vl82c113_device);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
device_add(&fdc37c651_device);
|
||||
@@ -430,6 +457,30 @@ machine_at_d824_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_martin_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/martin/NONSCSI.ROM",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
|
||||
device_add(&vl82c480_device);
|
||||
device_add(&vl82c113_device);
|
||||
|
||||
device_add(&ide_vlb_device);
|
||||
device_add(&fdc37c651_ide_device);
|
||||
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_acera1g_init(const machine_t *model)
|
||||
{
|
||||
@@ -705,7 +756,6 @@ machine_at_403tg_d_mr_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t pb450_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
@@ -1589,6 +1639,91 @@ machine_at_486sp3g_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t sb486pv_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "sb486pv",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "AMI 062594 (0108)", .internal_name = "sb486pv", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/41-0108-062594-SATURN2.rom", "" } },
|
||||
{ .name = "AMI 062594 (0301)", .internal_name = "sb486pv_94", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/0301-062594-SATURN2.rom", "" } },
|
||||
{ .name = "AMI 071595 (1301)", .internal_name = "sb486pv_95", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/amiboot.rom", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t sb486pv_device = {
|
||||
.name = "ICS SB486PV",
|
||||
.internal_name = "sb486pv_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = sb486pv_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_sb486pv_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);
|
||||
if (!strcmp(fn, "roms/machines/sb486pv/amiboot.rom"))
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
else
|
||||
ret = bios_load_linear_inverted(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
machine_at_common_init(model);
|
||||
// machine_at_common_init_ex(model, 2);
|
||||
|
||||
// device_add(&amstrad_megapc_nvr_device);
|
||||
device_add(&ide_pci_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_2);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0e, PCI_CARD_IDE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0f, PCI_CARD_VIDEO, 1, 2, 3, 4);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
device_add(&keyboard_ps2_ami_pci_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&ide_rz1000_pci_single_channel_device);
|
||||
device_add(&i82091aa_26e_device);
|
||||
if (!strcmp(fn, "roms/machines/sb486pv/amiboot.rom"))
|
||||
device_add(&intel_flash_bxt_device);
|
||||
else
|
||||
device_add(&intel_flash_bxt_ami_device);
|
||||
|
||||
device_add(&i420zx_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_486ap4_init(const machine_t *model)
|
||||
{
|
||||
@@ -1782,12 +1917,11 @@ machine_at_sbc490_init(const machine_t *model)
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x01, PCI_CARD_VIDEO, 4, 1, 2, 3);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
device_add(&ali1489_device);
|
||||
device_add(&fdc37c665_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&tgui9440_onboard_pci_device);
|
||||
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
device_add(&sst_flash_29ee010_device);
|
||||
|
||||
|
||||
@@ -61,11 +61,6 @@ enum {
|
||||
/*Very rough estimate*/
|
||||
#define VID_CLOCK (double) (651 * 416 * 60)
|
||||
|
||||
static uint8_t cga_crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Mapping of attributes to colours */
|
||||
static uint32_t amber;
|
||||
static uint32_t black;
|
||||
@@ -89,17 +84,14 @@ compaq_plasma_display_set(uint8_t internal)
|
||||
cpq_st_display_internal = internal;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaq_plasma_display_get(void)
|
||||
{
|
||||
return cpq_st_display_internal;
|
||||
}
|
||||
|
||||
typedef struct compaq_plasma_t {
|
||||
cga_t cga;
|
||||
mem_mapping_t font_ram_mapping;
|
||||
uint8_t *font_ram;
|
||||
uint8_t port_13c6;
|
||||
uint8_t port_23c6;
|
||||
uint8_t port_27c6;
|
||||
uint8_t internal_monitor;
|
||||
uint8_t attrmap;
|
||||
} compaq_plasma_t;
|
||||
|
||||
static int compaq_machine_type = 0;
|
||||
@@ -116,14 +108,14 @@ compaq_plasma_recalctimings(compaq_plasma_t *self)
|
||||
double _dispofftime;
|
||||
double disptime;
|
||||
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 1)) {
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
cga_recalctimings(&self->cga);
|
||||
return;
|
||||
}
|
||||
|
||||
disptime = 651;
|
||||
_dispontime = 640;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
disptime = 651;
|
||||
_dispontime = 640;
|
||||
_dispofftime = disptime - _dispontime;
|
||||
self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
|
||||
}
|
||||
@@ -143,10 +135,13 @@ compaq_plasma_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
self->cga.vram[addr & 0x7fff] = val;
|
||||
if (self->port_23c6 & 0x08)
|
||||
self->font_ram[addr & 0x1fff] = val;
|
||||
else
|
||||
self->cga.vram[addr & 0x7fff] = val;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
compaq_plasma_read(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -154,7 +149,11 @@ compaq_plasma_read(uint32_t addr, void *priv)
|
||||
uint8_t ret;
|
||||
|
||||
compaq_plasma_waitstates(&self->cga);
|
||||
ret = (self->cga.vram[addr & 0x7fff]);
|
||||
|
||||
if (self->port_23c6 & 0x08)
|
||||
ret = (self->font_ram[addr & 0x1fff]);
|
||||
else
|
||||
ret = (self->cga.vram[addr & 0x7fff]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -163,33 +162,23 @@ static void
|
||||
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
uint8_t old;
|
||||
|
||||
switch (addr) {
|
||||
/* Emulated CRTC, register select */
|
||||
case 0x3d0:
|
||||
case 0x3d2:
|
||||
case 0x3d4:
|
||||
case 0x3d6:
|
||||
cga_out(addr, val, &self->cga);
|
||||
break;
|
||||
|
||||
/* Emulated CRTC, value */
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
old = self->cga.crtc[self->cga.crtcreg];
|
||||
self->cga.crtc[self->cga.crtcreg] = val & cga_crtcmask[self->cga.crtcreg];
|
||||
|
||||
/* Register 0x12 controls the attribute mappings for the
|
||||
* plasma screen. */
|
||||
if (self->cga.crtcreg == 0x12) {
|
||||
self->attrmap = val;
|
||||
compaq_plasma_recalcattrs(self);
|
||||
break;
|
||||
}
|
||||
|
||||
if (old != val) {
|
||||
if (self->cga.crtcreg < 0xe || self->cga.crtcreg > 0x10) {
|
||||
self->cga.fullchange = changeframecount;
|
||||
compaq_plasma_recalctimings(self);
|
||||
}
|
||||
}
|
||||
case 0x3d7:
|
||||
cga_out(addr, val, &self->cga);
|
||||
compaq_plasma_recalctimings(self);
|
||||
break;
|
||||
case 0x3d8:
|
||||
case 0x3d9:
|
||||
@@ -197,15 +186,26 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
compaq_plasma_display_set((val & 8) ? 1 : 0);
|
||||
self->port_13c6 = val;
|
||||
compaq_plasma_display_set((self->port_13c6 & 0x08) ? 1 : 0);
|
||||
/*
|
||||
For bits 2-0, John gives 0 = CGA, 1 = EGA, 3 = MDA;
|
||||
Another source (Ralf Brown?) gives 4 = CGA, 5 = EGA, 7 = MDA;
|
||||
This leads me to believe bit 2 is not relevant to the mode.
|
||||
*/
|
||||
if ((val & 0x03) == 0x03)
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x08000);
|
||||
else
|
||||
mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x08000);
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
self->port_23c6 = val;
|
||||
if (val & 8) /* Disable internal CGA */
|
||||
mem_mapping_disable(&self->cga.mapping);
|
||||
else
|
||||
mem_mapping_enable(&self->cga.mapping);
|
||||
compaq_plasma_recalcattrs(self);
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
self->port_27c6 = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -222,37 +222,44 @@ compaq_plasma_in(uint16_t addr, void *priv)
|
||||
switch (addr) {
|
||||
case 0x3d4:
|
||||
case 0x3da:
|
||||
case 0x3db:
|
||||
case 0x3dc:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d1:
|
||||
case 0x3d3:
|
||||
case 0x3d5:
|
||||
if (self->cga.crtcreg == 0x12) {
|
||||
ret = self->attrmap & 0x0f;
|
||||
if (self->internal_monitor)
|
||||
ret |= 0x30; /* Plasma / CRT */
|
||||
} else
|
||||
ret = cga_in(addr, &self->cga);
|
||||
case 0x3d7:
|
||||
ret = cga_in(addr, &self->cga);
|
||||
break;
|
||||
|
||||
case 0x3d8:
|
||||
ret = self->cga.cgamode;
|
||||
break;
|
||||
|
||||
case 0x13c6:
|
||||
ret = compaq_plasma_display_get() ? 8 : 0;
|
||||
ret |= 4;
|
||||
ret = self->port_13c6;
|
||||
#if 0
|
||||
if ((self->cga.cgamode & 0x28) == 0x00)
|
||||
ret |= 0x04;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x17c6:
|
||||
ret = 0xe6;
|
||||
break;
|
||||
|
||||
case 0x1bc6:
|
||||
ret = 0;
|
||||
if (compaq_plasma_display_get()) {
|
||||
if ((self->cga.cgamode & 0x12) == 0x12) {
|
||||
if (self->port_23c6 & 8)
|
||||
ret |= 0x40;
|
||||
else
|
||||
ret |= 0x20;
|
||||
}
|
||||
}
|
||||
ret = 0x40;
|
||||
break;
|
||||
|
||||
case 0x23c6:
|
||||
ret = 0;
|
||||
ret = self->port_23c6;
|
||||
break;
|
||||
|
||||
case 0x27c6:
|
||||
ret = self->port_27c6 & 0x3f;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -276,6 +283,8 @@ compaq_plasma_poll(void *priv)
|
||||
int cursorline;
|
||||
int blink = 0;
|
||||
int underline = 0;
|
||||
int c;
|
||||
int x;
|
||||
uint32_t ink = 0;
|
||||
uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black;
|
||||
uint32_t bg = black;
|
||||
@@ -292,230 +301,303 @@ compaq_plasma_poll(void *priv)
|
||||
}
|
||||
|
||||
/* graphic mode and not mode 40h */
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 1)) {
|
||||
if (!self->internal_monitor && !(self->port_23c6 & 0x01)) {
|
||||
/* standard cga mode */
|
||||
cga_poll(&self->cga);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* mode 40h or text mode */
|
||||
if (!self->cga.linepos) {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine == 0)
|
||||
video_wait_for_buffer();
|
||||
|
||||
/* mode 40h or text mode */
|
||||
if (!self->cga.linepos) {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine == 0) {
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
if (self->cga.cgamode & 2) {
|
||||
if (self->cga.cgamode & 0x10) {
|
||||
/* 640x400 mode */
|
||||
if (self->port_23c6 & 1) /* 640*400 */ {
|
||||
addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7FFF];
|
||||
addr++;
|
||||
/* 80-col */
|
||||
if (self->cga.cgamode & 0x01) {
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) << 1;
|
||||
ma += (self->cga.displine >> 4) * 80;
|
||||
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
ink = (dat & 0x80) ? fg : bg;
|
||||
if (!(self->cga.cgamode & 8))
|
||||
ink = black;
|
||||
(buffer32->line[self->cga.displine])[x * 8 + c] = ink;
|
||||
dat <<= 1;
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = (((self->cga.crtc[0x0a] & 0x0f) << 1) <= sc) && (((self->cga.crtc[0x0b] & 0x0f) << 1) >= sc);
|
||||
|
||||
/* for each text column */
|
||||
for (x = 0; x < 80; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] ^= (amber ^ black);
|
||||
} else if ((self->port_23c6 >> 5) == 4) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 3) + c]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
}
|
||||
/* 40-col */
|
||||
else if (!(self->cga.cgamode & 0x02)) {
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) << 1;
|
||||
ma += (self->cga.displine >> 4) * 40;
|
||||
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = (((self->cga.crtc[0x0a] & 0x0f) << 1) <= sc) && (((self->cga.crtc[0x0b] & 0x0f) << 1) >= sc);
|
||||
|
||||
for (x = 0; x < 40; x++) {
|
||||
/* video output enabled */
|
||||
if (self->cga.cgamode & 0x08) {
|
||||
/* character */
|
||||
chr = self->cga.vram[(addr + (x << 1)) & 0x7fff];
|
||||
/* text attributes */
|
||||
attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff];
|
||||
} else {
|
||||
chr = 0x00;
|
||||
attr = 0x00;
|
||||
}
|
||||
uint8_t hi_bit = attr & 0x08;
|
||||
/* check if cursor has to be drawn */
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10));
|
||||
/* check if character underline mode should be set */
|
||||
underline = ((attr & 0x07) == 0x01);
|
||||
underline = underline || (((self->port_23c6 >> 5) == 2) && hi_bit);
|
||||
if (underline) {
|
||||
/* set forecolor to white */
|
||||
attr = attr | 0x7;
|
||||
}
|
||||
blink = 0;
|
||||
/* set foreground */
|
||||
cols[1] = blinkcols[attr][1];
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
blink = 1;
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
|
||||
/* character address */
|
||||
uint16_t chr_addr = ((chr * 16) + sc) & 0x0fff;
|
||||
if (((self->port_23c6 >> 5) == 3) && hi_bit)
|
||||
chr_addr |= 0x1000;
|
||||
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
|
||||
if (hi_bit) {
|
||||
if ((self->port_23c6 >> 5) == 1)
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] ^= (amber ^ black);
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] ^= (amber ^ black);
|
||||
}
|
||||
else if ((self->port_23c6 >> 5) == 4)
|
||||
for (c = 0; c < 8; c++) {
|
||||
uint32_t b = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 1) & 0x7f;
|
||||
uint32_t g = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 9) & 0x7f;
|
||||
uint32_t r = ((buffer32->line[self->cga.displine][(x << 4) + (c << 1)]) >> 17) & 0x7f;
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = b | (g << 8) || (r << 16);
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
}
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
if (self->cga.cgamode & 0x10) {
|
||||
/* 640x400 mode */
|
||||
if (self->port_23c6 & 0x01) /* 640*400 */ {
|
||||
addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
} else {
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
}
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
pattern = (dat & 0xC0) >> 6;
|
||||
if (!(self->cga.cgamode & 8))
|
||||
pattern = 0;
|
||||
|
||||
switch (pattern & 3) {
|
||||
case 0:
|
||||
ink0 = ink1 = black;
|
||||
break;
|
||||
case 1:
|
||||
if (self->cga.displine & 1) {
|
||||
ink0 = black;
|
||||
ink1 = black;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (self->cga.displine & 1) {
|
||||
ink0 = black;
|
||||
ink1 = amber;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ink0 = ink1 = amber;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
ink = (dat & 0x80) ? fg : bg;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
ink = black;
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = ink;
|
||||
dat <<= 1;
|
||||
}
|
||||
buffer32->line[self->cga.displine][x * 8 + 2 * c] = ink0;
|
||||
buffer32->line[self->cga.displine][x * 8 + 2 * c + 1] = ink1;
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (self->cga.cgamode & 1) {
|
||||
/* 80-col */
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) * 2;
|
||||
ma += (self->cga.displine >> 4) * 80;
|
||||
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc);
|
||||
|
||||
/* for each text column */
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
/* video output enabled */
|
||||
chr = self->cga.vram[(addr + 2 * x) & 0x7FFF];
|
||||
attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF];
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16));
|
||||
|
||||
blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6));
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = blinkcols[attr][1];
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if (blink) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1);
|
||||
for (uint8_t x = 0; x < 80; x++) {
|
||||
dat = self->cga.vram[addr & 0x7fff];
|
||||
addr++;
|
||||
|
||||
++ma;
|
||||
}
|
||||
} else { /* 40-col */
|
||||
sc = self->cga.displine & 0x0f;
|
||||
addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) * 2;
|
||||
ma += (self->cga.displine >> 4) * 40;
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
pattern = (dat & 0xC0) >> 6;
|
||||
if (!(self->cga.cgamode & 0x08))
|
||||
pattern = 0;
|
||||
|
||||
if ((self->cga.crtc[0x0a] & 0x60) == 0x20)
|
||||
cursorline = 0;
|
||||
else
|
||||
cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc);
|
||||
switch (pattern & 3) {
|
||||
case 0:
|
||||
ink0 = ink1 = black;
|
||||
break;
|
||||
case 1:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = black;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (self->cga.displine & 0x01) {
|
||||
ink0 = black;
|
||||
ink1 = amber;
|
||||
} else {
|
||||
ink0 = amber;
|
||||
ink1 = black;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ink0 = ink1 = amber;
|
||||
break;
|
||||
|
||||
for (uint8_t x = 0; x < 40; x++) {
|
||||
chr = self->cga.vram[(addr + 2 * x) & 0x7FFF];
|
||||
attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF];
|
||||
drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16));
|
||||
|
||||
blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6));
|
||||
/* blink active */
|
||||
if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = blinkcols[attr][1];
|
||||
cols[0] = blinkcols[attr][0];
|
||||
/* attribute 7 active and not cursor */
|
||||
if (blink) {
|
||||
/* set blinking */
|
||||
cols[1] = cols[0];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1)] = ink0;
|
||||
buffer32->line[self->cga.displine][(x << 3) + (c << 1) + 1] = ink1;
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Set intensity bit */
|
||||
cols[1] = normcols[attr][1];
|
||||
cols[0] = normcols[attr][0];
|
||||
}
|
||||
/* character underline active and 7th row of pixels in character height being drawn */
|
||||
if (underline && (sc == 7)) {
|
||||
/* for each pixel in character width */
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c * 2)] = buffer32->line[self->cga.displine][(x << 4) + (c * 2) + 1] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
} else {
|
||||
for (uint8_t c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
++ma;
|
||||
}
|
||||
}
|
||||
}
|
||||
self->cga.displine++;
|
||||
/* Hardcode a fixed refresh rate and VSYNC timing */
|
||||
if (self->cga.displine == 400) { /* Start of VSYNC */
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.cgadispon = 0;
|
||||
}
|
||||
if (self->cga.displine == 416) { /* End of VSYNC */
|
||||
self->cga.displine = 0;
|
||||
self->cga.cgastat &= ~8;
|
||||
self->cga.cgadispon = 1;
|
||||
}
|
||||
} else {
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
self->cga.displine++;
|
||||
/* Hardcode a fixed refresh rate and VSYNC timing */
|
||||
if (self->cga.displine == 400) { /* Start of VSYNC */
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.cgadispon = 0;
|
||||
}
|
||||
if (self->cga.displine == 416) { /* End of VSYNC */
|
||||
self->cga.displine = 0;
|
||||
self->cga.cgastat &= ~8;
|
||||
self->cga.cgadispon = 1;
|
||||
}
|
||||
} else {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
self->cga.linepos = 0;
|
||||
self->cga.linepos = 0;
|
||||
|
||||
if (self->cga.displine == 400) {
|
||||
/* Hardcode 640x400 window size */
|
||||
if ((640 != xsize) || (400 != ysize) || video_force_resize_get()) {
|
||||
if (self->cga.displine == 400) {
|
||||
xsize = 640;
|
||||
ysize = 400;
|
||||
if (xsize < 64)
|
||||
xsize = 656;
|
||||
if (ysize < 32)
|
||||
ysize = 200;
|
||||
set_screen_size(xsize, ysize);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
if ((self->cga.cgamode & 0x08) || video_force_resize_get()) {
|
||||
set_screen_size(xsize, ysize);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
/* Plasma specific */
|
||||
video_blit_memtoscreen(0, 0, xsize, ysize);
|
||||
frames++;
|
||||
|
||||
/* Fixed 640x400 resolution */
|
||||
video_res_x = 640;
|
||||
video_res_y = 400;
|
||||
|
||||
if (self->cga.cgamode & 0x02) {
|
||||
if (self->cga.cgamode & 0x10)
|
||||
video_bpp = 1;
|
||||
else
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 0;
|
||||
|
||||
self->cga.cgablink++;
|
||||
}
|
||||
video_blit_memtoscreen(0, 0, xsize, ysize);
|
||||
frames++;
|
||||
|
||||
/* Fixed 640x400 resolution */
|
||||
video_res_x = 640;
|
||||
video_res_y = 400;
|
||||
|
||||
if (self->cga.cgamode & 0x02) {
|
||||
if (self->cga.cgamode & 0x10)
|
||||
video_bpp = 1;
|
||||
else
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 0;
|
||||
|
||||
self->cga.cgablink++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -560,7 +642,7 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
|
||||
/* Set up colours */
|
||||
amber = makecol(0xff, 0x7d, 0x00);
|
||||
black = makecol(0x64, 0x0c, 0x00);
|
||||
black = makecol(0x64, 0x19, 0x00);
|
||||
|
||||
/* Initialize the attribute mapping. Start by defaulting everything
|
||||
* to black on amber, and with bold set by bit 3 */
|
||||
@@ -575,7 +657,7 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
for (n = 0x11; n <= 0xFF; n++) {
|
||||
if ((n & 7) == 0)
|
||||
continue;
|
||||
if (self->attrmap & 4) { /* Inverse */
|
||||
if ((self->port_23c6 >> 5) == 1) { /* Inverse */
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
} else { /* Normal */
|
||||
@@ -588,7 +670,7 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self)
|
||||
for (n = 0x01; n <= 0x0E; n++) {
|
||||
if (n == 7)
|
||||
continue;
|
||||
if (self->attrmap & 1) {
|
||||
if ((self->port_23c6 >> 5) == 1) {
|
||||
blinkcols[n][0] = normcols[n][0] = amber;
|
||||
blinkcols[n][1] = normcols[n][1] = black;
|
||||
blinkcols[n + 128][0] = amber;
|
||||
@@ -631,31 +713,31 @@ compaq_plasma_init(UNUSED(const device_t *info))
|
||||
{
|
||||
compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t));
|
||||
|
||||
cga_init(&self->cga);
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma);
|
||||
if (compaq_machine_type == COMPAQ_PORTABLEIII)
|
||||
loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2);
|
||||
else
|
||||
loadfont_ex("roms/machines/portableiii/P.2 Combined.bin", 11, 0x4b49);
|
||||
|
||||
self->cga.composite = 0;
|
||||
self->cga.revision = 0;
|
||||
|
||||
self->cga.vram = malloc(0x8000);
|
||||
self->internal_monitor = 1;
|
||||
self->font_ram = malloc(0x2000);
|
||||
|
||||
cga_comp_init(self->cga.revision);
|
||||
timer_add(&self->cga.timer, compaq_plasma_poll, self, 1);
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self);
|
||||
timer_set_callback(&self->cga.timer, compaq_plasma_poll);
|
||||
timer_set_p(&self->cga.timer, self);
|
||||
|
||||
mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000,
|
||||
compaq_plasma_read, NULL, NULL,
|
||||
compaq_plasma_write, NULL, NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, self);
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
io_sethandler(0x03c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x07c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x0bc6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
}
|
||||
io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x13c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x1bc6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
io_sethandler(0x23c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
|
||||
|
||||
/* Default attribute mapping is 4 */
|
||||
self->attrmap = 4;
|
||||
compaq_plasma_recalcattrs(self);
|
||||
|
||||
self->cga.cgastat = 0xf4;
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
self->cga.rgb_type = device_get_config_int("rgb_type");
|
||||
@@ -672,6 +754,7 @@ compaq_plasma_close(void *priv)
|
||||
compaq_plasma_t *self = (compaq_plasma_t *) priv;
|
||||
|
||||
free(self->cga.vram);
|
||||
free(self->font_ram);
|
||||
free(self);
|
||||
}
|
||||
|
||||
@@ -793,7 +876,8 @@ machine_at_compaq_init(const machine_t *model, int type)
|
||||
|
||||
switch (type) {
|
||||
case COMPAQ_PORTABLEII:
|
||||
machine_at_init(model);
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_at_compaq_device);
|
||||
break;
|
||||
|
||||
case COMPAQ_PORTABLEIII:
|
||||
@@ -801,7 +885,9 @@ machine_at_compaq_init(const machine_t *model, int type)
|
||||
device_add(&ide_isa_device);
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&compaq_plasma_device);
|
||||
machine_at_init(model);
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_at_compaq_device);
|
||||
break;
|
||||
|
||||
case COMPAQ_PORTABLEIII386:
|
||||
|
||||
@@ -69,6 +69,7 @@ extern const device_t pb450_device;
|
||||
extern const device_t jukopc_device;
|
||||
extern const device_t vendex_device;
|
||||
extern const device_t c5sbm2_device;
|
||||
extern const device_t sb486pv_device;
|
||||
|
||||
const machine_filter_t machine_types[] = {
|
||||
{ "None", MACHINE_TYPE_NONE },
|
||||
@@ -5435,7 +5436,7 @@ const machine_t machines[] = {
|
||||
},
|
||||
/* Has IBM AT KBC firmware. */
|
||||
{
|
||||
.name = "[ISA] Micronics 09-00021",
|
||||
.name = "[ISA] Micronics 09-00021 (Tandon BIOS)",
|
||||
.internal_name = "micronics386",
|
||||
.type = MACHINE_TYPE_386DX,
|
||||
.chipset = MACHINE_CHIPSET_DISCRETE,
|
||||
@@ -5474,6 +5475,46 @@ const machine_t machines[] = {
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has IBM AT KBC firmware. */
|
||||
{
|
||||
.name = "[ISA] Micronics 09-00021 (Phoenix BIOS)",
|
||||
.internal_name = "micronics386px",
|
||||
.type = MACHINE_TYPE_386DX,
|
||||
.chipset = MACHINE_CHIPSET_DISCRETE,
|
||||
.init = machine_at_micronics386px_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_386DX,
|
||||
.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_AT,
|
||||
.flags = MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 512,
|
||||
.max = 8192,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has IBM AT KBC firmware. */
|
||||
{
|
||||
.name = "[ISA] Tandy 4000",
|
||||
.internal_name = "tandy4000",
|
||||
@@ -6363,6 +6404,46 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMIKey F KBC firmware. */
|
||||
{
|
||||
.name = "[Symphony SL42C460] DTK PKM-0031Y",
|
||||
.internal_name = "dtk461",
|
||||
.type = MACHINE_TYPE_486,
|
||||
.chipset = MACHINE_CHIPSET_SYMPHONY_SL82C460,
|
||||
.init = machine_at_dtk461_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET1,
|
||||
.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_AT,
|
||||
.flags = MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 32768,
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* The chip is a Lance LT38C41, a clone of the Intel 8041, and the BIOS sends
|
||||
commands BC, BD, and C9 which exist on both AMIKey and Phoenix MultiKey/42,
|
||||
but it does not write a byte after C9, which is consistent with AMIKey, so
|
||||
@@ -6446,7 +6527,7 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has a standard IBM PS/2 KBC firmware or a clone thereof. */
|
||||
/* Has a VLSI VL82C114 Combination I/O which holds the KBC. */
|
||||
{
|
||||
.name = "[VLSI 82C481] Siemens Nixdorf D824",
|
||||
.internal_name = "d824",
|
||||
@@ -6474,7 +6555,7 @@ const machine_t machines[] = {
|
||||
.max = 32768,
|
||||
.step = 2048
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.nvrmask = 255,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
@@ -6693,6 +6774,46 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMI MegaKey KBC. */
|
||||
{
|
||||
.name = "[i420TX] J-Bond PCI400C-A",
|
||||
.internal_name = "pci400ca",
|
||||
.type = MACHINE_TYPE_486_S2,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_420TX,
|
||||
.init = machine_at_pci400ca_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET3,
|
||||
.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_PCI,
|
||||
.flags = MACHINE_SCSI,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 65536,
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = &keyboard_at_ami_device,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This has a standalone AMI Megakey 1993, which is type 'P'. */
|
||||
{
|
||||
.name = "[IMS 8848] Tekram G486IP",
|
||||
@@ -6854,13 +6975,13 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMI MegaKey KBC. */
|
||||
/* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */
|
||||
{
|
||||
.name = "[i420TX] J-Bond PCI400C-A",
|
||||
.internal_name = "pci400ca",
|
||||
.name = "[VLSI 82C480] ZEOS Martin",
|
||||
.internal_name = "martin",
|
||||
.type = MACHINE_TYPE_486_S2,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_420TX,
|
||||
.init = machine_at_pci400ca_init,
|
||||
.chipset = MACHINE_CHIPSET_VLSI_VL82C480,
|
||||
.init = machine_at_martin_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
@@ -6875,15 +6996,15 @@ const machine_t machines[] = {
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PCI,
|
||||
.flags = MACHINE_SCSI,
|
||||
.bus_flags = MACHINE_PS2_VLB,
|
||||
.flags = MACHINE_IDE | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.min = 2048,
|
||||
.max = 65536,
|
||||
.step = 1024
|
||||
.step = 2048
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = &keyboard_at_ami_device,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
@@ -6895,7 +7016,6 @@ const machine_t machines[] = {
|
||||
.net_device = NULL
|
||||
},
|
||||
|
||||
|
||||
/* 486 machines - Socket 3 */
|
||||
/* 486 machines with just the ISA slot */
|
||||
/* Has a Fujitsu MBL8042H KBC. */
|
||||
@@ -8396,6 +8516,47 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This has an AMI MEGAKey 'P' or 'R' keyboard controller. */
|
||||
{
|
||||
.name = "[i420ZX] ICS SB486PV",
|
||||
.internal_name = "sb486pv",
|
||||
.type = MACHINE_TYPE_486_S3_PCI,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_420ZX,
|
||||
.init = machine_at_sb486pv_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET3,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
/* Has PCI but no user-facing slots. */
|
||||
.bus_flags = MACHINE_PCI,
|
||||
.flags = MACHINE_PS2_KBC | MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM | MACHINE_PCI_INTERNAL,
|
||||
.ram = {
|
||||
.min = 2048,
|
||||
.max = 65536,
|
||||
.step = 2048
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = &sb486pv_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &gd5436_onboard_pci_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This most likely has a standalone AMI Megakey 1993, which is type 'P', like the below Tekram board. */
|
||||
{
|
||||
.name = "[IMS 8848] J-Bond PCI400C-B",
|
||||
|
||||
42
src/nvr_at.c
42
src/nvr_at.c
@@ -296,6 +296,7 @@
|
||||
#define FLAG_P6RP4_HACK 0x10
|
||||
#define FLAG_PIIX4 0x20
|
||||
#define FLAG_MULTI_BANK 0x40
|
||||
#define FLAG_MARTIN_HACK 0x80
|
||||
|
||||
typedef struct local_t {
|
||||
int8_t stat;
|
||||
@@ -733,6 +734,13 @@ nvr_read(uint16_t addr, void *priv)
|
||||
ret = REGD_VRT;
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
if (local->flags & FLAG_MARTIN_HACK)
|
||||
ret = nvr->regs[local->addr[addr_id]] | 0x02;
|
||||
else
|
||||
ret = nvr->regs[local->addr[addr_id]];
|
||||
break;
|
||||
|
||||
case 0x2c:
|
||||
if (!nvr->is_new && (local->flags & FLAG_AMI_1994_HACK))
|
||||
ret = nvr->regs[local->addr[addr_id]] & 0x7f;
|
||||
@@ -771,6 +779,17 @@ nvr_read(uint16_t addr, void *priv)
|
||||
ret = checksum >> 8;
|
||||
else
|
||||
ret = checksum & 0xff;
|
||||
} else if (!nvr->is_new && (local->flags & FLAG_MARTIN_HACK)) {
|
||||
for (i = 0x10; i <= 0x2d; i++) {
|
||||
if (i == 0x11)
|
||||
checksum += (nvr->regs[i] | 0x02);
|
||||
else
|
||||
checksum += nvr->regs[i];
|
||||
}
|
||||
if (local->addr[addr_id] == 0x2e)
|
||||
ret = checksum >> 8;
|
||||
else
|
||||
ret = checksum & 0xff;
|
||||
} else
|
||||
ret = nvr->regs[local->addr[addr_id]];
|
||||
break;
|
||||
@@ -1123,9 +1142,11 @@ nvr_at_init(const device_t *info)
|
||||
if (info->local & 0x10) {
|
||||
local->def = 0x00;
|
||||
local->flags |= FLAG_AMI_1992_HACK;
|
||||
} else if (info->local == 36)
|
||||
} else if ((info->local == 36) || (info->local == 68)) {
|
||||
local->def = 0x00;
|
||||
else
|
||||
if (info->local == 68)
|
||||
local->flags |= FLAG_MARTIN_HACK;
|
||||
} else
|
||||
local->def = 0xff;
|
||||
nvr->irq = 8;
|
||||
local->cent = RTC_CENTURY_AT;
|
||||
@@ -1160,6 +1181,9 @@ nvr_at_init(const device_t *info)
|
||||
/* Initialize the generic NVR. */
|
||||
nvr_init(nvr);
|
||||
|
||||
if (nvr->is_new && (local->flags & FLAG_MARTIN_HACK))
|
||||
nvr->regs[0x11] = nvr->regs[0x2f] = 0x02;
|
||||
|
||||
if (nvr_at_inited == 0) {
|
||||
/* Start the timers. */
|
||||
timer_add(&local->update_timer, timer_update, nvr, 0);
|
||||
@@ -1426,6 +1450,20 @@ const device_t amstrad_megapc_nvr_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t martin_nvr_device = {
|
||||
.name = "Zeos Martin NVRAM",
|
||||
.internal_name = "martin_nvr",
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 68,
|
||||
.init = nvr_at_init,
|
||||
.close = nvr_at_close,
|
||||
.reset = nvr_at_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = nvr_at_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t elt_nvr_device = {
|
||||
.name = "Epson Equity LT NVRAM",
|
||||
.internal_name = "elt_nvr",
|
||||
|
||||
@@ -849,8 +849,8 @@ msgstr "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、Richa
|
||||
msgid "Hardware not available"
|
||||
msgstr "硬件不可用"
|
||||
|
||||
msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection."
|
||||
msgstr "请确认 %1 已安装且使用兼容 libpcap 的网络连接。"
|
||||
msgid "Make sure %1 is installed and that you are on a %1-compatible network connection."
|
||||
msgstr "请确认 %1 已安装且使用兼容 %1 的网络连接。"
|
||||
|
||||
msgid "Invalid configuration"
|
||||
msgstr "无效配置"
|
||||
@@ -1240,7 +1240,7 @@ msgid "Host CD/DVD Drive (%1:)"
|
||||
msgstr "主机 CD/DVD 驱动器 (%1:)"
|
||||
|
||||
msgid "&Connected"
|
||||
msgstr ""
|
||||
msgstr "已连接(&C)"
|
||||
|
||||
msgid "Clear image history"
|
||||
msgstr "清除映像历史记录"
|
||||
@@ -1300,7 +1300,7 @@ msgid "\nFalling back to software rendering."
|
||||
msgstr "\n回到软件渲染。"
|
||||
|
||||
msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>"
|
||||
msgstr "<html><head/><body><p>选择媒体图像(光盘、软盘等)时,打开对话框将从与 86Box 配置文件相同的目录开始。这一设置可能只会在 macOS 上产生影响。</p></body></html>;"
|
||||
msgstr "<html><head/><body><p>选择媒体图像(光盘、软盘等)时,打开对话框将从与 86Box 配置文件相同的目录开始。这一设置可能只会在 macOS 上产生影响。</p></body></html>"
|
||||
|
||||
msgid "This machine might have been moved or copied."
|
||||
msgstr "这台机器可能被移动或复制过。"
|
||||
@@ -1315,7 +1315,7 @@ msgid "I Copied It"
|
||||
msgstr "我已复制这台机器"
|
||||
|
||||
msgid "86Box Monitor #"
|
||||
msgstr "86Box 监测器 "
|
||||
msgstr "86Box 监测器 #"
|
||||
|
||||
msgid "No MCA devices."
|
||||
msgstr "无 MCA 设备。"
|
||||
@@ -1804,7 +1804,7 @@ msgid "Five + Wheel"
|
||||
msgstr "五键+滚轮"
|
||||
|
||||
msgid "Five + 2 Wheels"
|
||||
msgstr ""
|
||||
msgstr "五键+双滚轮"
|
||||
|
||||
msgid "A3 - SMT2 Serial / SMT3(R)V"
|
||||
msgstr "A3 - SMT2 串行 / SMT3(R)V"
|
||||
@@ -2050,25 +2050,25 @@ msgid "[Generic] RAM Disk (max. speed)"
|
||||
msgstr "[Generic] RAM 磁盘 (最大速度)"
|
||||
|
||||
msgid "[Generic] 1989 (3500 RPM)"
|
||||
msgstr ""
|
||||
msgstr "[Generic] 1989 (3500 RPM)"
|
||||
|
||||
msgid "[Generic] 1992 (3600 RPM)"
|
||||
msgstr ""
|
||||
msgstr "[Generic] 1992 (3600 RPM)"
|
||||
|
||||
msgid "[Generic] 1994 (4500 RPM)"
|
||||
msgstr ""
|
||||
msgstr "[Generic] 1994 (4500 RPM)"
|
||||
|
||||
msgid "[Generic] 1996 (5400 RPM)"
|
||||
msgstr ""
|
||||
msgstr "[Generic] 1996 (5400 RPM)"
|
||||
|
||||
msgid "[Generic] 1997 (5400 RPM)"
|
||||
msgstr ""
|
||||
msgstr "[Generic] 1997 (5400 RPM)"
|
||||
|
||||
msgid "[Generic] 1998 (5400 RPM)"
|
||||
msgstr ""
|
||||
msgstr "[Generic] 1998 (5400 RPM)"
|
||||
|
||||
msgid "[Generic] 2000 (7200 RPM)"
|
||||
msgstr ""
|
||||
msgstr "[Generic] 2000 (7200 RPM)"
|
||||
|
||||
msgid "IBM 8514/A clone (ISA)"
|
||||
msgstr "IBM 8514/A 克隆 (ISA)"
|
||||
@@ -2076,6 +2076,12 @@ msgstr "IBM 8514/A 克隆 (ISA)"
|
||||
msgid "Vendor"
|
||||
msgstr "制造商"
|
||||
|
||||
msgid "30 Hz (JMP2 = 1)"
|
||||
msgstr "30 Hz (JMP2 = 1)"
|
||||
|
||||
msgid "60 Hz (JMP2 = 2)"
|
||||
msgstr "60 Hz (JMP2 = 2)"
|
||||
|
||||
msgid "Generic PC/XT Memory Expansion"
|
||||
msgstr "通用 PC/XT 内存扩展"
|
||||
|
||||
@@ -2089,61 +2095,61 @@ msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for t
|
||||
msgstr "仿真通用 ESC/P 点阵打印机需要使用 \"roms/printer/fonts\" 目录中的 TrueType 字体。"
|
||||
|
||||
msgid "Inhibit multimedia keys"
|
||||
msgstr ""
|
||||
msgstr "禁止多媒体按键"
|
||||
|
||||
msgid "Ask for confirmation before saving settings"
|
||||
msgstr ""
|
||||
msgstr "保存设置前要求用户确认"
|
||||
|
||||
msgid "Ask for confirmation before hard resetting"
|
||||
msgstr ""
|
||||
msgstr "硬重置前要求用户确认"
|
||||
|
||||
msgid "Ask for confirmation before quitting"
|
||||
msgstr ""
|
||||
msgstr "退出前要求用户确认"
|
||||
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
msgstr "选项"
|
||||
|
||||
msgid "Model"
|
||||
msgstr ""
|
||||
msgstr "模型"
|
||||
|
||||
msgid "Model:"
|
||||
msgstr ""
|
||||
msgstr "模型:"
|
||||
|
||||
msgid "Failed to initialize Vulkan renderer."
|
||||
msgstr ""
|
||||
msgstr "Vulkan 渲染器初始化失败。"
|
||||
|
||||
msgid "GLSL Error"
|
||||
msgstr ""
|
||||
msgstr "GLSL 错误"
|
||||
|
||||
msgid "Could not load shader: %1"
|
||||
msgstr ""
|
||||
msgstr "无法加载着色器:%1"
|
||||
|
||||
msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2"
|
||||
msgstr ""
|
||||
msgstr "OpenGL 版本需要达到 3.0 或更高。当前 GLSL 版本为 %1.%2"
|
||||
|
||||
msgid "Could not load texture: %1"
|
||||
msgstr ""
|
||||
msgstr "无法加载材质:%1"
|
||||
|
||||
msgid "Could not compile shader:\n\n%1"
|
||||
msgstr ""
|
||||
msgstr "无法编译着色器:\n\n%1"
|
||||
|
||||
msgid "Program not linked:\n\n%1"
|
||||
msgstr ""
|
||||
msgstr "程序未链接:\n\n%1"
|
||||
|
||||
msgid "Shader Manager"
|
||||
msgstr ""
|
||||
msgstr "着色器管理器"
|
||||
|
||||
msgid "Shader Configuration"
|
||||
msgstr ""
|
||||
msgstr "着色器配置"
|
||||
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "添加"
|
||||
|
||||
msgid "Move up"
|
||||
msgstr ""
|
||||
msgstr "上移"
|
||||
|
||||
msgid "Move down"
|
||||
msgstr ""
|
||||
msgstr "下移"
|
||||
|
||||
msgid "Could not load file %1"
|
||||
msgstr ""
|
||||
msgstr "无法加载文件 %1"
|
||||
|
||||
@@ -295,6 +295,20 @@ const device_t i82091aa_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t i82091aa_26e_device = {
|
||||
.name = "Intel 82091AA Super I/O (Port 26Eh)",
|
||||
.internal_name = "i82091aa_26e",
|
||||
.flags = 0,
|
||||
.local = 0x140,
|
||||
.init = i82091aa_init,
|
||||
.close = i82091aa_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t i82091aa_398_device = {
|
||||
.name = "Intel 82091AA Super I/O (Port 398h)",
|
||||
.internal_name = "i82091aa_398",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/sio.h>
|
||||
#include <86box/plat_unused.h>
|
||||
@@ -133,7 +134,10 @@ vl82c113_init(UNUSED(const device_t *info))
|
||||
{
|
||||
vl82c113_t *dev = (vl82c113_t *) calloc(1, sizeof(vl82c113_t));
|
||||
|
||||
dev->nvr = device_add(&at_nvr_device);
|
||||
if (!strcmp(machine_get_internal_name(), "martin"))
|
||||
dev->nvr = device_add(&martin_nvr_device);
|
||||
else
|
||||
dev->nvr = device_add(&amstrad_megapc_nvr_device);
|
||||
|
||||
dev->nvr_enabled = 1;
|
||||
dev->nvr_base = 0x0070;
|
||||
|
||||
@@ -68,7 +68,6 @@ static const struct {
|
||||
.device = &cs4297_device,
|
||||
.misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||
.reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B,
|
||||
.extid_flags = 0,
|
||||
.pcsr_mask = 0x7f,
|
||||
.vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5a, 0x0301, 0x0000}, {0}}
|
||||
},
|
||||
@@ -100,15 +99,18 @@ static const struct {
|
||||
{
|
||||
.device = &tr28023_device,
|
||||
.misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_POP | AC97_MS | AC97_LPBK,
|
||||
.reset_flags = 0,
|
||||
.extid_flags = 0,
|
||||
.pcsr_mask = 0x3f
|
||||
},
|
||||
{
|
||||
.device = &w83971d_device,
|
||||
.misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||
.reset_flags = (27 << AC97_3D_SHIFT),
|
||||
.pcsr_mask = 0x3f
|
||||
},
|
||||
{
|
||||
.device = &wm9701a_device,
|
||||
.misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK,
|
||||
.reset_flags = AC97_DAC_18B | AC97_ADC_18B,
|
||||
.extid_flags = 0,
|
||||
.pcsr_mask = 0x3f
|
||||
}
|
||||
// clang-format on
|
||||
@@ -284,8 +286,9 @@ line_gain:
|
||||
|
||||
case 0x22: /* 3D Control */
|
||||
switch (ac97_codecs[dev->model].reset_flags >> AC97_3D_SHIFT) {
|
||||
case 1: /* Analog Devices */
|
||||
case 6: /* Crystal */
|
||||
case 1: /* Analog Devices */
|
||||
case 6: /* Crystal */
|
||||
case 27: /* Winbond */
|
||||
val &= 0x000f;
|
||||
break;
|
||||
|
||||
@@ -764,6 +767,20 @@ const device_t tr28023_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t w83971d_device = {
|
||||
.name = "Winbond W83971D",
|
||||
.internal_name = "w83971d",
|
||||
.flags = DEVICE_AC97,
|
||||
.local = AC97_CODEC_W83971D,
|
||||
.init = ac97_codec_init,
|
||||
.close = ac97_codec_close,
|
||||
.reset = ac97_codec_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t wm9701a_device = {
|
||||
.name = "Wolfson WM9701A",
|
||||
.internal_name = "wm9701a",
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <86box/pci.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/i2c.h>
|
||||
@@ -4316,7 +4317,8 @@ gd54xx_init(const device_t *info)
|
||||
break;
|
||||
|
||||
case CIRRUS_ID_CLGD5436:
|
||||
if (info->local & 0x200) {
|
||||
if ((info->local & 0x200) &&
|
||||
!strstr(machine_get_internal_name(), "sb486pv")) {
|
||||
romfn = NULL;
|
||||
gd54xx->has_bios = 0;
|
||||
} else
|
||||
@@ -4461,8 +4463,8 @@ gd54xx_init(const device_t *info)
|
||||
}
|
||||
io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx);
|
||||
|
||||
if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) {
|
||||
if (romfn == NULL)
|
||||
if (gd54xx->pci && (id >= CIRRUS_ID_CLGD5430)) {
|
||||
if (info->local & 0x200)
|
||||
pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot);
|
||||
else
|
||||
pci_add_card(PCI_ADD_NORMAL, cl_pci_read, cl_pci_write, gd54xx, &gd54xx->pci_slot);
|
||||
|
||||
Reference in New Issue
Block a user