Merge branch '86Box:master' into master

This commit is contained in:
toggo9
2025-05-16 18:16:24 +02:00
committed by GitHub
46 changed files with 1829 additions and 647 deletions

View File

@@ -26,9 +26,9 @@ Minimum system requirements and recommendations
* macOS version: macOS High Sierra 10.13 or newer
* 4 GB of RAM or higher
Performance may vary depending on both host and guest configuration. Most emulation logic is executed in a single thread; therefore, systems with better IPC (instructions per clock) generally should be able to emulate higher clock speeds.
Performance may vary depending on host and guest configuration. Most emulation logic is executed in a single thread. Therefore, systems with greater IPC (instructions per clock) capacity should be able to emulate higher clock speeds.
It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines.
For easier handling of multiple virtual machines, use a manager application:
* [Avalonia 86](https://github.com/notBald/Avalonia86) by [notBald](https://github.com/notBald) (Windows and Linux)
* [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only)
@@ -37,7 +37,7 @@ It is also recommended to use a manager application with 86Box for easier handli
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/Dungeonseeker/) (Linux focused, should work on Windows though untested)
* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only)
It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option.
To use 86Box on its own, use the `--vmpath`/`-P` command line option.
Getting started
---------------
@@ -47,7 +47,7 @@ See [our documentation](https://86box.readthedocs.io/en/latest/index.html) for a
Community
---------
We operate an IRC channel and a Discord server for discussing 86Box, its development and anything related to retro computing. We look forward to hearing from you!
We operate an IRC channel and a Discord server for discussing 86Box, its development, and anything related to retro computing. We look forward to hearing from you!
[![Visit our IRC channel](https://kiwiirc.com/buttons/irc.ringoflightning.net/86Box.png)](https://kiwiirc.com/client/irc.ringoflightning.net/?nick=86box|?#86Box)

View File

@@ -1250,20 +1250,48 @@ pc_send_ca(uint16_t sc)
if (keyboard_mode >= 0x81) {
/* Use R-Alt because PS/55 DOS and OS/2 assign L-Alt Kanji */
keyboard_input(1, 0x1D); /* Ctrl key pressed */
if (keyboard_get_in_reset())
return;
keyboard_input(1, 0x138); /* R-Alt key pressed */
if (keyboard_get_in_reset())
return;
keyboard_input(1, sc);
if (keyboard_get_in_reset())
return;
usleep(50000);
if (keyboard_get_in_reset())
return;
keyboard_input(0, sc);
if (keyboard_get_in_reset())
return;
keyboard_input(0, 0x138); /* R-Alt key released */
if (keyboard_get_in_reset())
return;
keyboard_input(0, 0x1D); /* Ctrl key released */
if (keyboard_get_in_reset())
return;
} else {
keyboard_input(1, 0x1D); /* Ctrl key pressed */
if (keyboard_get_in_reset())
return;
keyboard_input(1, 0x38); /* Alt key pressed */
if (keyboard_get_in_reset())
return;
keyboard_input(1, sc);
if (keyboard_get_in_reset())
return;
usleep(50000);
if (keyboard_get_in_reset())
return;
keyboard_input(0, sc);
if (keyboard_get_in_reset())
return;
keyboard_input(0, 0x38); /* Alt key released */
if (keyboard_get_in_reset())
return;
keyboard_input(0, 0x1D); /* Ctrl key released */
if (keyboard_get_in_reset())
return;
}
}

View File

@@ -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

362
src/chipset/sl82c461.c Normal file
View 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
};

View File

@@ -24,34 +24,37 @@
#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
vl82c480_shflags(uint8_t access)
vl82c480_shflags(uint8_t access, uint8_t access2)
{
int ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
int wp = ((access2 & 0x03) == 0x01);
switch (access) {
default:
case 0x00:
ret = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
ret = MEM_READ_EXTANY | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY);
break;
case 0x01:
ret = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
ret = MEM_READ_EXTANY | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL);
break;
case 0x02:
ret = MEM_READ_INTERNAL | MEM_WRITE_EXTANY;
ret = MEM_READ_INTERNAL | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_EXTANY);
break;
case 0x03:
ret = MEM_READ_INTERNAL | MEM_WRITE_INTERNAL;
ret = MEM_READ_INTERNAL | (wp ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL);
break;
}
@@ -59,27 +62,60 @@ vl82c480_shflags(uint8_t access)
}
static void
vl82c480_recalc(vl82c480_t *dev)
vl82c480_recalc_shadow(vl82c480_t *dev)
{
uint32_t base;
uint8_t access;
uint8_t access2;
shadowbios = 0;
shadowbios_write = 0;
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;
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access));
base = 0x000a0000 + (i << 16) + (j << 13);
access = (dev->regs[0x0d + i] >> j) & 3;
access2 = (dev->regs[0x13 + i] >> j) & 3;
mem_set_mem_state(base, 0x4000, vl82c480_shflags(access, access2));
shadowbios |= ((base >= 0xe0000) && (access & 0x02));
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01));
shadowbios_write |= ((base >= 0xe0000) && (access & 0x01) && !(access2 & 0x01));
}
}
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 +127,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 +152,11 @@ 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 ... 0x18:
dev->regs[dev->idx] = val;
vl82c480_recalc(dev);
vl82c480_recalc_shadow(dev);
if (dev->idx >= 0x13)
flushmmucache();
break;
}
}
@@ -124,8 +165,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 +187,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 +223,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 +236,27 @@ vl82c480_init(const device_t *info)
dev->regs[0x07] = 0x21;
dev->regs[0x08] = 0x38;
for (uint8_t i = 0; i < 4; i++) {
uint32_t size = 0;
for (uint8_t j = 2; i < 7; j++) {
if (ms >= sizes[j])
size = sizes[j];
else
break;
}
ms -= size;
dev->banks[i] = size;
if ((ms == 0) || (size == 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;
}

View File

@@ -780,8 +780,18 @@ host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
codegen_alloc_bytes(block, 8);
codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/
codegen_addlong(block, ram_offset);
} else if ((ram_offset < -2147483648LL) || (ram_offset > 2147483647LL) || !(block->flags & CODEBLOCK_NO_IMMEDIATES)) {
// fatal("host_x86_MOV32_REG_ABS - out of range\n");
// void *q = p;
//uint32_t *r = NULL;
// *r = 5; /* Crash deliberately. */
codegen_alloc_bytes(block, 8);
codegen_addbyte2(block, 0x49, 0xb9); /*MOV r9,(uintptr_t) p*/
codegen_addquad(block, (uintptr_t) p);
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [R9]*/
} else {
fatal("host_x86_MOV32_REG_ABS - out of range\n");
fatal("host_x86_MOV32_REG_ABS - RAM offset = %016" PRIX64 " (p - ram = %016" PRIX64 ")\n", ram_offset, (uintptr_t) p - (uintptr_t) ram);
codegen_alloc_bytes(block, 6);
codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/
codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3));

View File

@@ -390,42 +390,18 @@ device_get_priv(const device_t *dev)
int
device_available(const device_t *dev)
{
if (dev != NULL) {
const device_config_t *config = dev->config;
if (config != NULL) {
while (config->type != CONFIG_END) {
if (config->type == CONFIG_BIOS) {
int roms_present = 0;
const device_config_bios_t *bios = (const device_config_bios_t *) config->bios;
/* Go through the ROM's in the device configuration. */
while ((bios != NULL) &&
(bios->name != NULL) &&
(bios->internal_name != NULL) &&
(bios->files_no != 0)) {
int i = 0;
for (uint8_t bf = 0; bf < bios->files_no; bf++)
i += !!rom_present(bios->files[bf]);
if (i == bios->files_no)
roms_present++;
bios++;
}
return (roms_present ? -1 : 0);
}
config++;
}
}
int ret = machine_device_available(dev);
if (ret == 0) {
/* No CONFIG_BIOS field present, use the classic available(). */
if (dev->available != NULL)
return (dev->available());
ret = (dev->available());
else
return 1;
}
ret = (dev != NULL);
} else
ret = (ret == -1);
/* A NULL device is never available. */
return 0;
return ret;
}
uint8_t
@@ -969,6 +945,36 @@ machine_get_config_string(char *str)
return ret;
}
int
machine_device_available(const device_t *dev)
{
if (dev != NULL) {
const device_config_t *config = dev->config;
if ((config != NULL) && (config->type == CONFIG_BIOS)) {
int roms_present = 0;
const device_config_bios_t *bios = (const device_config_bios_t *) config->bios;
/* Go through the ROM's in the device configuration. */
while ((bios != NULL) &&
(bios->name != NULL) &&
(bios->internal_name != NULL) &&
(bios->files_no != 0)) {
int i = 0;
for (uint8_t bf = 0; bf < bios->files_no; bf++)
i += !!rom_present(bios->files[bf]);
if (i == bios->files_no)
roms_present++;
bios++;
}
return (roms_present ? -1 : -2);
}
}
/* NULL device or no CONFIG_BIOS field, return 0. */
return 0;
}
const device_t *
device_context_get_device(void)
{

View File

@@ -2149,6 +2149,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 +2166,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 +2203,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;

View File

@@ -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)

View File

@@ -64,11 +64,12 @@ static int keydelay[512];
#endif
static scancode *scan_table; /* scancode table for keyboard */
static volatile uint8_t caps_lock = 0;
static volatile uint8_t num_lock = 0;
static volatile uint8_t scroll_lock = 0;
static volatile uint8_t kana_lock = 0;
static uint8_t shift = 0;
static volatile uint8_t caps_lock = 0;
static volatile uint8_t num_lock = 0;
static volatile uint8_t scroll_lock = 0;
static volatile uint8_t kana_lock = 0;
static volatile uint8_t kbd_in_reset = 0;
static uint8_t shift = 0;
static int key5576mode = 0;
@@ -106,11 +107,12 @@ static scconvtbl scconv55_8a[18 + 1] =
void
keyboard_init(void)
{
num_lock = 0;
caps_lock = 0;
scroll_lock = 0;
kana_lock = 0;
shift = 0;
num_lock = 0;
caps_lock = 0;
scroll_lock = 0;
kana_lock = 0;
shift = 0;
kbd_in_reset = 0;
memset(recv_key, 0x00, sizeof(recv_key));
memset(recv_key_ui, 0x00, sizeof(recv_key));
@@ -238,6 +240,9 @@ key_process(uint16_t scan, int down)
void
keyboard_input(int down, uint16_t scan)
{
if (kbd_in_reset)
return;
/* Special case for E1 1D, translate it to 0100 - special case. */
if ((scan >> 8) == 0xe1) {
if ((scan & 0xff) == 0x1d)
@@ -343,9 +348,9 @@ void
keyboard_all_up(void)
{
for (unsigned short i = 0; i < 0x200; i++) {
if (recv_key_ui[i]) {
if (recv_key_ui[i])
recv_key_ui[i] = 0;
}
if (recv_key[i]) {
recv_key[i] = 0;
key_process(i, 0);
@@ -353,6 +358,18 @@ keyboard_all_up(void)
}
}
void
keyboard_set_in_reset(uint8_t in_reset)
{
kbd_in_reset = in_reset;
}
uint8_t
keyboard_get_in_reset(void)
{
return kbd_in_reset;
}
static uint8_t
keyboard_do_break(uint16_t scan)
{

View File

@@ -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 */
@@ -3476,7 +3476,10 @@ keyboard_at_bat(void *priv)
keyboard_scan = 1;
keyboard_all_up();
keyboard_update_states(0, 0, 0, 0);
keyboard_set_in_reset(0);
kbc_at_dev_queue_add(dev, 0xaa, 0);
} else {
bat_counter--;
@@ -3491,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)
{
@@ -3640,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);
@@ -3709,11 +3718,11 @@ 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;
case 0xff: /* reset */
keyboard_set_in_reset(1);
kbc_at_dev_reset(dev, 1);
bat_counter = 1000;
break;
@@ -3724,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.
*
@@ -3773,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;
}

View File

@@ -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;
}
/*

View File

@@ -55,7 +55,6 @@ typedef struct rz1000_t {
static int next_id = 0;
#define ENABLE_RZ1000_LOG 1
#ifdef ENABLE_RZ1000_LOG
int rz1000_do_log = ENABLE_RZ1000_LOG;

View File

@@ -1106,6 +1106,36 @@ xta_close(void *priv)
static const device_config_t wdxt150_config[] = {
// clang-format off
{
.name = "bios_rev",
.description = "BIOS Revision",
.type = CONFIG_BIOS,
.default_string = "rev_1",
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.bios = {
{
.name = "Revision 1.0",
.internal_name = "rev_1",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { WD_REV_1_BIOS_FILE, "" }
},
{
.name = "Revision 2.0",
.internal_name = "rev_2",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { WD_REV_2_BIOS_FILE, "" }
},
{ .files_no = 0 }
},
},
{
.name = "base",
.description = "Address",
@@ -1151,36 +1181,6 @@ static const device_config_t wdxt150_config[] = {
},
.bios = { { 0 } }
},
{
.name = "bios_rev",
.description = "BIOS Revision",
.type = CONFIG_BIOS,
.default_string = "rev_1",
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.bios = {
{
.name = "Revision 1.0",
.internal_name = "rev_1",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { WD_REV_1_BIOS_FILE, "" }
},
{
.name = "Revision 2.0",
.internal_name = "rev_2",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { WD_REV_2_BIOS_FILE, "" }
},
{ .files_no = 0 }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format off
};

View File

@@ -252,6 +252,37 @@ xtide_at_close(void *priv)
// clang-format off
static const device_config_t xtide_config[] = {
{
.name = "bios",
.description = "BIOS Revision",
.type = CONFIG_BIOS,
.default_string = "xt",
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = {
{
.name = "Regular XT",
.internal_name = "xt",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { ROM_PATH_XT, "" }
},
{
.name = "XT+ (V20/V30/8018x)",
.internal_name = "xt_plus",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { ROM_PATH_XTP, "" }
},
{ .files_no = 0 }
},
},
{
.name = "base",
.description = "Address",
@@ -348,37 +379,6 @@ static const device_config_t xtide_config[] = {
},
.bios = { { 0 } }
},
{
.name = "bios",
.description = "BIOS Revision",
.type = CONFIG_BIOS,
.default_string = "xt",
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = {
{
.name = "Regular XT",
.internal_name = "xt",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { ROM_PATH_XT, "" }
},
{
.name = "XT+ (V20/V30/8018x)",
.internal_name = "xt_plus",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { ROM_PATH_XTP, "" }
},
{ .files_no = 0 }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
};

View File

@@ -279,6 +279,15 @@ fdc_is_mfm(fdc_t *fdc)
return fdc->mfm ? 1 : 0;
}
int
fdc_is_dma(fdc_t *fdc)
{
if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma)
return 0;
else
return 1;
}
void
fdc_request_next_sector_id(fdc_t *fdc)
{

View File

@@ -2414,16 +2414,28 @@ d86f_turbo_poll(int drive, int side)
case STATE_0C_READ_DATA:
case STATE_11_SCAN_DATA:
case STATE_16_VERIFY_DATA:
d86f_turbo_read(drive, side);
if (fdc_is_dma(d86f_fdc))
for (int i = 0; i < (128 << dev->last_sector.id.n); i++)
d86f_turbo_read(drive, side);
else
d86f_turbo_read(drive, side);
break;
case STATE_05_WRITE_DATA:
case STATE_09_WRITE_DATA:
d86f_turbo_write(drive, side);
if (fdc_is_dma(d86f_fdc))
for (int i = 0; i < (128 << dev->last_sector.id.n); i++)
d86f_turbo_write(drive, side);
else
d86f_turbo_write(drive, side);
break;
case STATE_0D_FORMAT_TRACK:
d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2)));
if (fdc_is_dma(d86f_fdc))
while (dev->state == STATE_0D_FORMAT_TRACK)
d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2)));
else
d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2)));
return;
case STATE_IDLE:

View File

@@ -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;

View File

@@ -239,6 +239,8 @@ extern const char *device_get_internal_name(const device_t *dev);
extern int machine_get_config_int(char *str);
extern const char *machine_get_config_string(char *str);
extern int machine_device_available(const device_t *dev);
extern const device_t device_none;
extern const device_t device_internal;

View File

@@ -206,6 +206,7 @@ extern int fdc_get_drive(fdc_t *fdc);
extern int fdc_get_perp(fdc_t *fdc);
extern int fdc_get_format_n(fdc_t *fdc);
extern int fdc_is_mfm(fdc_t *fdc);
extern int fdc_is_dma(fdc_t *fdc);
extern double fdc_get_hut(fdc_t *fdc);
extern double fdc_get_hlt(fdc_t *fdc);
extern void fdc_request_next_sector_id(fdc_t *fdc);

View File

@@ -273,6 +273,8 @@ extern void keyboard_input(int down, uint16_t scan);
extern void keyboard_all_up(void);
extern void keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl, uint8_t kl);
extern uint8_t keyboard_get_shift(void);
extern void keyboard_set_in_reset(uint8_t in_reset);
extern uint8_t keyboard_get_in_reset(void);
extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl, uint8_t *kl);
extern void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl);
extern int keyboard_recv(uint16_t key);
@@ -289,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);

View File

@@ -514,10 +514,12 @@ extern int machine_at_ga486l_init(const machine_t *);
extern int machine_at_cougar_init(const machine_t *);
extern int machine_at_acc386_init(const machine_t *);
extern int machine_at_asus386_3364k_init(const machine_t *);
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 *);
@@ -543,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 *);
@@ -553,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 *);

View File

@@ -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

View File

@@ -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;

View File

@@ -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. */

View File

@@ -72,6 +72,27 @@ machine_at_acc386_init(const machine_t *model)
return ret;
}
int
machine_at_asus386_3364k_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/asus386_3364k/am27c512dip28-64b53c26be3d8160533563.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&rabbit_device);
device_add(&keyboard_at_ami_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
int
machine_at_asus386_init(const machine_t *model)
{
@@ -113,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)
{
@@ -370,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;
@@ -394,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);
@@ -409,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)
{

View File

@@ -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;
@@ -97,7 +92,10 @@ compaq_plasma_display_get(void)
typedef struct compaq_plasma_t {
cga_t cga;
uint8_t ctl_mode;
uint8_t port_13c6;
uint8_t port_23c6;
uint8_t port_27c6;
uint8_t internal_monitor;
uint8_t attrmap;
} compaq_plasma_t;
@@ -116,16 +114,18 @@ 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;
self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32));
_dispofftime = disptime - _dispontime;
_dispontime *= CGACONST / 2;
_dispofftime *= CGACONST / 2;
self->cga.dispontime = (uint64_t) (_dispontime);
self->cga.dispofftime = (uint64_t) (_dispofftime);
}
static void
@@ -144,9 +144,9 @@ 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;
compaq_plasma_waitstates(&self->cga);
}
static uint8_t
compaq_plasma_read(uint32_t addr, void *priv)
{
@@ -163,49 +163,59 @@ static void
compaq_plasma_out(uint16_t addr, uint8_t val, void *priv)
{
compaq_plasma_t *self = (compaq_plasma_t *) priv;
uint8_t old;
if (self->port_23c6 & 0x08) {
if ((addr >= 0x3d0) && (addr <= 0x3dc))
addr ^= 0x60;
}
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];
case 0x3d7:
/* Register 0x12 controls the attribute mappings for the
* plasma screen. */
if (self->cga.crtcreg == 0x12) {
self->attrmap = val;
compaq_plasma_recalcattrs(self);
break;
return;
}
cga_out(addr, val, &self->cga);
if (old != val) {
if (self->cga.crtcreg < 0xe || self->cga.crtcreg > 0x10) {
self->cga.fullchange = changeframecount;
compaq_plasma_recalctimings(self);
}
}
compaq_plasma_recalctimings(self);
break;
case 0x3d8:
case 0x3d9:
case 0x3db:
case 0x3dc:
cga_out(addr, val, &self->cga);
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);
break;
case 0x23c6:
self->port_23c6 = val;
if (val & 8) /* Disable internal CGA */
mem_mapping_disable(&self->cga.mapping);
if (val & 0x08) /* Disable internal CGA */
mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x8000);
else
mem_mapping_enable(&self->cga.mapping);
mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x8000);
break;
case 0x27c6:
self->port_27c6 = val;
break;
default:
@@ -219,40 +229,53 @@ compaq_plasma_in(uint16_t addr, void *priv)
compaq_plasma_t *self = (compaq_plasma_t *) priv;
uint8_t ret = 0xff;
if (self->port_23c6 & 0x08) {
if ((addr >= 0x3d0) && (addr <= 0x3dc))
addr ^= 0x60;
}
switch (addr) {
case 0x3d4:
case 0x3da:
case 0x3db:
case 0x3dc:
ret = cga_in(addr, &self->cga);
break;
case 0x3d1:
case 0x3d3:
case 0x3d5:
case 0x3d7:
if (self->cga.crtcreg == 0x12) {
ret = self->attrmap & 0x0f;
if (self->internal_monitor)
if (compaq_plasma_display_get())
ret |= 0x30; /* Plasma / CRT */
} else
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;
break;
case 0x17c6:
ret = 0xf6;
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 +299,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 +317,252 @@ 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 = attr = 0;
/* 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 = (((self->port_23c6 >> 5) == 2) && (attr & 0x01) && !(attr & 0x06));
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];
blink = ((attr & 0x80) << 3) + 7 + 16;
}
/* 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[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
} else {
for (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];
}
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 = attr = 0;
/* 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 = (((self->port_23c6 >> 5) == 2) && (attr & 0x01) && !(attr & 0x06));
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];
blink = ((attr & 0x80) << 3) + 7 + 16;
}
/* character underline active and 7th row of pixels in character height being drawn */
if (underline && (self->cga.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[(fontdatm2[chr + self->cga.fontbase][sc] & (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[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
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:
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);
}
/* ogc 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 +607,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 */
@@ -631,12 +678,14 @@ compaq_plasma_init(UNUSED(const device_t *info))
{
compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t));
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);
cga_init(&self->cga);
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma);
self->cga.composite = 0;
self->cga.revision = 0;
@@ -644,12 +693,16 @@ compaq_plasma_init(UNUSED(const device_t *info))
self->internal_monitor = 1;
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);
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);
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, 0x000c, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self);
/* Default attribute mapping is 4 */
self->attrmap = 4;
@@ -793,7 +846,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 +855,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:

View File

@@ -825,13 +825,58 @@ machine_at_vectra54_init(const machine_t *model)
return ret;
}
static const device_config_t c5sbm2_config[] = {
// clang-format off
{
.name = "bios",
.description = "BIOS Version",
.type = CONFIG_BIOS,
.default_string = "5sbm2",
.default_int = 0,
.file_filter = "",
.spinner = { 0 },
.bios = {
{ .name = "4.50GP (07/17/1995)", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0717.BIN", "" } },
{ .name = "4.50PG (03/21/1996)", .internal_name = "5sbm2_450pg", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0326.BIN", "" } },
{ .name = "4.51PG (03/15/2000 Unicore Upgrade)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL,
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/2A5ICC3A.BIN", "" } },
{ .files_no = 0 }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t c5sbm2_device = {
.name = "Chaintech 5SBM/5SBM2 (M103)",
.internal_name = "5sbm2_device",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = c5sbm2_config
};
int
machine_at_5sbm2_init(const machine_t *model)
{
int ret;
int ret = 0;
const char* fn;
ret = bios_load_linear("roms/machines/5sbm2/5SBM0717.BIN",
0x000e0000, 131072, 0);
/* No ROMs available */
if (!device_available(model->device))
return ret;
device_context(model->device);
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
device_context_restore();
if (bios_only || !ret)
return ret;

View File

@@ -154,6 +154,14 @@ lxt_ems_write(uint32_t addr, uint8_t val, void *priv)
mem[addr & 0x3fff] = val;
}
static void
lxt_ems_writew(uint32_t addr, uint16_t val, void *priv)
{
uint8_t *mem = (uint8_t *) priv;
*(uint16_t *) &(mem[addr & 0x3fff]) = val;
}
static uint8_t
lxt_ems_read(uint32_t addr, void *priv)
{
@@ -165,6 +173,17 @@ lxt_ems_read(uint32_t addr, void *priv)
return ret;
}
static uint16_t
lxt_ems_readw(uint32_t addr, void *priv)
{
uint8_t *mem = (uint8_t *) priv;
uint16_t ret = 0xff;
ret = *(uint16_t *) &(mem[addr & 0x3fff]);
return ret;
}
static lxt_ems_board_t *
lxt_ems_init(lxt_t *parent, int en, uint16_t io, uint32_t mem)
{
@@ -186,10 +205,17 @@ lxt_ems_init(lxt_t *parent, int en, uint16_t io, uint32_t mem)
for (uint8_t i = 0; i < 4; i++) {
uint8_t *ptr = dev->ram + (i << 14);
mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000,
lxt_ems_read, NULL, NULL,
lxt_ems_write, NULL, NULL,
ptr, 0, ptr);
if (parent->is_lxt3)
mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000,
lxt_ems_read, lxt_ems_readw, NULL,
lxt_ems_write, lxt_ems_writew, NULL,
ptr, 0, ptr);
else
mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000,
lxt_ems_read, NULL, NULL,
lxt_ems_write, NULL, NULL,
ptr, 0, ptr);
mem_mapping_disable(&dev->ems[i].mapping);
dev->ems[i].page = 0x7f;

View File

@@ -139,18 +139,24 @@ machine_init(void)
int
machine_available(int m)
{
int ret;
int ret = 0;
const device_t *dev = machine_get_device(m);
bios_only = 1;
if (dev != NULL)
ret = machine_device_available(dev);
/*
Only via machine_init_ex() if the device is NULL or
it lacks a CONFIG_BIOS field (or the CONFIG_BIOS field
is not the first in list.
*/
if (ret == 0) {
bios_only = 1;
ret = device_available(dev);
/* Do not check via machine_init_ex() if the device is not NULL and
it has a CONFIG_BIOS field. */
if ((dev == NULL) || (ret != -1))
ret = machine_init_ex(m);
bios_only = 0;
bios_only = 0;
} else if (ret == -2)
ret = 0;
return !!ret;
}

View File

@@ -68,6 +68,7 @@ extern const device_t ibmxt286_device;
extern const device_t pb450_device;
extern const device_t jukopc_device;
extern const device_t vendex_device;
extern const device_t c5sbm2_device;
const machine_filter_t machine_types[] = {
{ "None", MACHINE_TYPE_NONE },
@@ -5434,7 +5435,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,
@@ -5473,6 +5474,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",
@@ -5632,6 +5673,46 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
/* Has Award KBC firmware. */
{
.name = "[SiS 310] ASUS 386/33-64K",
.internal_name = "asus386_3364k",
.type = MACHINE_TYPE_386DX,
.chipset = MACHINE_CHIPSET_SIS_310,
.init = machine_at_asus386_3364k_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 = 1024,
.max = 16384,
.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
},
/* Has AMIKey F KBC firmware. */
{
.name = "[SiS 310] ASUS ISA-386C",
@@ -6322,6 +6403,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
@@ -6405,7 +6526,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",
@@ -6433,7 +6554,7 @@ const machine_t machines[] = {
.max = 32768,
.step = 2048
},
.nvrmask = 127,
.nvrmask = 255,
.kbc_device = NULL,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
@@ -6652,6 +6773,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",
@@ -6813,13 +6974,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,
@@ -6834,15 +6995,15 @@ const machine_t machines[] = {
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PCI,
.flags = MACHINE_SCSI,
.bus_flags = MACHINE_PS2,
.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,
@@ -6854,7 +7015,6 @@ const machine_t machines[] = {
.net_device = NULL
},
/* 486 machines - Socket 3 */
/* 486 machines with just the ISA slot */
/* Has a Fujitsu MBL8042H KBC. */
@@ -11505,7 +11665,7 @@ const machine_t machines[] = {
/* SiS 5501 */
/* Has the Lance LT38C41 KBC. */
{
.name = "[SiS 5501] Chaintech 5SBM2 (M103)",
.name = "[SiS 5501] Chaintech 5SBM/5SBM2 (M103)",
.internal_name = "5sbm2",
.type = MACHINE_TYPE_SOCKET7_3V,
.chipset = MACHINE_CHIPSET_SIS_5501,
@@ -11528,7 +11688,7 @@ const machine_t machines[] = {
.flags = MACHINE_IDE_DUAL | MACHINE_APM,
.ram = {
.min = 8192,
.max = 262144,
.max = 131072,
.step = 8192
},
.nvrmask = 255,
@@ -11536,7 +11696,7 @@ const machine_t machines[] = {
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.device = &c5sbm2_device,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
@@ -14770,7 +14930,7 @@ const machine_t machines[] = {
.block = CPU_BLOCK_NONE,
.min_bus = 60000000,
.max_bus = 83333333,
.min_voltage = 1800,
.min_voltage = 2800,
.max_voltage = 3500,
.min_multi = 1.5,
.max_multi = 8.0

View File

@@ -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",

View File

@@ -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&gt"
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 串行 / SMT3RV"
@@ -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"

View File

@@ -322,12 +322,12 @@ MainWindow::MainWindow(QWidget *parent)
mouse_capture = state ? 1 : 0;
qt_mouse_capture(mouse_capture);
if (mouse_capture) {
this->grabKeyboard();
if (hook_enabled)
this->grabKeyboard();
if (ui->stackedWidget->mouse_capture_func)
ui->stackedWidget->mouse_capture_func(this->windowHandle());
} else {
if (!(windowState() & Qt::WindowActive))
this->releaseKeyboard();
this->releaseKeyboard();
if (ui->stackedWidget->mouse_uncapture_func) {
ui->stackedWidget->mouse_uncapture_func();
}
@@ -1479,23 +1479,6 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event)
releaseKeyboard();
} else if (event->type() == QEvent::WindowUnblocked) {
plat_pause(curdopause);
#ifdef __unix__
if (!QApplication::platformName().contains("wayland") && (this->windowState() & Qt::WindowActive)) {
this->grabKeyboard();
}
#endif
} else if (event->type() == QEvent::WindowActivate) {
#ifdef __unix__
if (!QApplication::platformName().contains("wayland")) {
this->grabKeyboard();
}
#endif
} else if (event->type() == QEvent::WindowDeactivate) {
#ifdef __unix__
if (!QApplication::platformName().contains("wayland")) {
this->releaseKeyboard();
}
#endif
}
}

View File

@@ -77,7 +77,7 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index)
m_monitor_index = monitor_index;
#if defined __unix__ && !defined __HAIKU__
char auto_mouse_type[16];
memset(auto_mouse_type, 0, sizeof (auto_mouse_type));
mousedata.mouse_type = getenv("EMU86BOX_MOUSE");
if (!mousedata.mouse_type || (mousedata.mouse_type[0] == '\0') || !stricmp(mousedata.mouse_type, "auto")) {
if (QApplication::platformName().contains("wayland"))

View File

@@ -137,6 +137,8 @@ private:
std::atomic_bool rendererTakesScreenshots;
std::atomic_bool switchInProgress{false};
char auto_mouse_type[16];
};
#endif // QT_RENDERERCONTAINER_HPP

View File

@@ -82,10 +82,12 @@ SOCKET
plat_netsocket_accept(SOCKET socket)
{
SOCKET clientsocket = accept(socket, NULL, NULL);
u_long yes = 1;
if (clientsocket == INVALID_SOCKET)
return -1;
ioctlsocket(clientsocket, FIONBIO, &yes);
return clientsocket;
}

View File

@@ -859,6 +859,37 @@ static const device_config_t ncr53c400_mmio_config[] = {
};
static const device_config_t rt1000b_config[] = {
{
.name = "bios_ver",
.description = "BIOS Revision",
.type = CONFIG_BIOS,
.default_string = "v8_10r",
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = {
{
.name = "Version 8.10R",
.internal_name = "v8_10r",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { RT1000B_810R_ROM, "" }
},
{
.name = "Version 8.20R",
.internal_name = "v8_20r",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { RT1000B_820R_ROM, "" }
},
{ .files_no = 0 }
},
},
{
.name = "bios_addr",
.description = "BIOS Address",
@@ -895,37 +926,6 @@ static const device_config_t rt1000b_config[] = {
},
.bios = { { 0 } }
},
{
.name = "bios_ver",
.description = "BIOS Revision",
.type = CONFIG_BIOS,
.default_string = "v8_10r",
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = {
{
.name = "Version 8.10R",
.internal_name = "v8_10r",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { RT1000B_810R_ROM, "" }
},
{
.name = "Version 8.20R",
.internal_name = "v8_20r",
.bios_type = BIOS_NORMAL,
.files_no = 1,
.local = 0,
.size = 8192,
.files = { RT1000B_820R_ROM, "" }
},
{ .files_no = 0 }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
};

View File

@@ -130,6 +130,7 @@ typedef struct {
int adapter_id;
int assign;
int present[8];
int id_connected;
int cmd_status;
int cir_status;
@@ -448,7 +449,6 @@ static void
spock_process_imm_cmd(spock_t *scsi)
{
int i;
int j = 0;
int adapter_id;
int phys_id;
int lun_id;
@@ -467,14 +467,23 @@ spock_process_imm_cmd(spock_t *scsi)
if (scsi->command & (1 << 23)) {
spock_log("Assign: adapter id=%d\n", adapter_id);
scsi->dev_id[adapter_id].phys_id = -1;
scsi->id_connected = 0;
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
} else {
if (phys_id != scsi->adapter_id) {
scsi->dev_id[adapter_id].phys_id = phys_id;
scsi->dev_id[adapter_id].lun_id = lun_id;
spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i.\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id);
if (scsi_device_present(&scsi_devices[scsi->bus][phys_id])) {
scsi->present[scsi->id_connected] = 1;
if (lun_id == 0)
scsi->id_connected++;
} else
scsi->present[scsi->id_connected] = 0;
spock_log("Assign: adapter dev=%d, scsi ID=%i, LUN=%i, attention devsel=%d, present=%d, connected=%d.\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id, scsi->attention & 0x0f, scsi->present[scsi->id_connected], scsi->id_connected);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
} else { /*Can not assign adapter*/
scsi->id_connected = 0;
spock_log("Assign: PUN=%d, cannot assign adapter.\n", phys_id);
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL);
}
@@ -495,35 +504,15 @@ spock_process_imm_cmd(spock_t *scsi)
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
case CMD_RESET:
scsi->id_connected = 0;
spock_log("Reset command, attention=%02x.\n", scsi->attention & 0x0f);
if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/
for (i = 0; i < 8; i++)
scsi_device_reset(&scsi_devices[scsi->bus][i]);
for (i = 6; i > -1; i--) {
if (scsi_device_present(&scsi_devices[scsi->bus][i])) {
spock_log("Adapter Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type);
scsi->present[j] = i;
j++;
} else {
scsi->present[j] = 0xff;
spock_log("Adapter Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type);
}
}
} else if ((scsi->attention & 0x0f) < 7) { /*Device reset*/
} else if ((scsi->attention & 0x0f) < 7) /*Device reset*/
scsi_device_reset(&scsi_devices[scsi->bus][scsi->attention & 0x0f]);
for (i = 6; i > -1; i--) {
if (scsi_device_present(&scsi_devices[scsi->bus][i])) {
spock_log("Device Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type);
scsi->present[j] = i;
j++;
} else {
scsi->present[j] = 0xff;
spock_log("Device Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type);
}
}
}
scsi->scb_state = 0;
spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE);
break;
@@ -538,7 +527,6 @@ static void
spock_execute_cmd(spock_t *scsi, scb_t *scb)
{
int c;
int j = 0;
int old_scb_state;
if (scsi->in_reset) {
@@ -556,17 +544,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
scsi->dev_id[c].phys_id = -1;
scsi->in_reset = 0;
for (c = 6; c >= 0; c--) {
if (scsi_device_present(&scsi_devices[scsi->bus][c])) {
spock_log("Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[c].phys_id, scsi_devices[scsi->bus][c].type);
scsi->present[j] = c;
j++;
} else {
scsi->present[j] = 0xff;
spock_log("Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[c].phys_id, scsi_devices[scsi->bus][c].type);
}
}
spock_log("Reset.\n");
return;
}
@@ -698,12 +676,15 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
break;
case CMD_DEVICE_INQUIRY:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Inquiry, ID=%d\n", scsi->cdb_id);
spock_log("Device Inquiry, ID=%d, connected=%d, present=%d.\n", scsi->cdb_id, scsi->id_connected, scsi->present[scsi->scb_id + 1]);
scsi->cdb[0] = GPCMD_INQUIRY;
scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/
scsi->cdb[2] = 0; /*Page code*/
@@ -718,13 +699,16 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_SEND_OTHER_SCSI:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2);
spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, CDB[0]=%02x, CDB_ID=%d, ID Present=%d.\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->cdb[0], scsi->cdb_id, scsi->present[scsi->scb_id]);
spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, LUN=%d, CDB[0]=%02x, CDB_ID=%d, ID Present=%d.\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->dev_id[scsi->scb_id].lun_id, scsi->cdb[0], scsi->cdb_id, scsi->present[scsi->scb_id + 1]);
scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/
scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6;
scsi->scsi_state = SCSI_STATE_SELECT;
@@ -732,10 +716,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_READ_DEVICE_CAPACITY:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY;
@@ -754,10 +741,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_READ_DATA:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id);
scsi->cdb[0] = GPCMD_READ_10;
@@ -776,10 +766,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_WRITE_DATA:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Write Data\n");
scsi->cdb[0] = GPCMD_WRITE_10;
@@ -798,10 +791,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_VERIFY:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Verify\n");
scsi->cdb[0] = GPCMD_VERIFY_10;
@@ -821,10 +817,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_WRITE_VERIFY:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Write with Verify\n");
scsi->cdb[0] = GPCMD_WRITE_AND_VERIFY_10;
@@ -843,10 +842,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
return;
case CMD_REQUEST_SENSE:
if (scsi->present[scsi->scb_id] != 0xff)
if (scsi->scb_id != 15) {
if (scsi->present[scsi->scb_id])
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
} else
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
else
scsi->cdb_id = 0xff;
spock_log("Device Request Sense, ID=%d\n", scsi->cdb_id);
scsi->cdb[0] = GPCMD_REQUEST_SENSE;
@@ -870,7 +872,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
if (scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id]) && (scsi->cdb_id != 0xff)) {
if (scsi->last_status == SCSI_STATUS_OK) {
scsi->scb_state = 3;
spock_log("Status is Good on device ID %d, cdb id = %d.\n", scsi->scb_id, scsi->cdb_id);
spock_log("Status is Good on device ID %d, cdb id = %d, devsel = %d.\n", scsi->scb_id, scsi->cdb_id, scsi->attention & 0x0f);
} else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x20;
@@ -905,7 +907,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
} else {
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE);
scsi->scb_state = 0;
spock_log("Complete SCB ID = %d.\n", scsi->attention & 0x0f);
spock_log("Complete SCB ID = %d.\n", scsi->scb_id);
}
break;
@@ -1084,10 +1086,10 @@ spock_callback(void *priv)
case 4:
case 0x0f: /*Start SCB*/
scsi->cmd_status = 1;
scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24);
scsi->scb_id = scsi->attention & 0x0f;
scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24);
scsi->scb_id = scsi->attention & 0x0f;
scsi->cmd_timer = SPOCK_TIME * 2;
spock_log("Start SCB at ID = %d, attention = %02x\n", scsi->scb_id, scsi->attention >> 4);
spock_log("Start SCB at ID = %d, attention = %02x, cdb_id = %d\n", scsi->scb_id, scsi->attention >> 4, scsi->cdb_id);
scsi->scb_state = 1;
break;
@@ -1182,6 +1184,7 @@ spock_reset(void *priv)
scsi->in_invalid = 0;
scsi->attention_wait = 0;
scsi->basic_ctrl = 0;
scsi->id_connected = 0;
spock_log("Actual Reset.\n");
}

View File

@@ -241,9 +241,14 @@ t128_callback(void *priv)
uint8_t c;
uint8_t temp;
uint8_t status;
double period = scsi_bus->period / 60.0;
if (scsi_bus->tx_mode != PIO_TX_BUS)
timer_on_auto(&t128->timer, scsi_bus->period / 60.0);
if (scsi_bus->tx_mode != PIO_TX_BUS) {
if (period >= 10.0)
timer_on_auto(&t128->timer, period);
else
timer_on_auto(&t128->timer, 10.0);
}
if (scsi_bus->data_wait & 1) {
scsi_bus->clear_req = 3;
@@ -287,7 +292,6 @@ t128_callback(void *priv)
t128->status &= ~0x02;
t128->pos = 0;
t128->host_pos = 0;
scsi_bus->data_repeat = 0;
t128_log("T128 Remaining blocks to be written=%d\n", t128->block_count);
if (scsi_bus->data_pos >= dev->buffer_length) {
t128->block_loaded = 0;
@@ -336,7 +340,6 @@ t128_callback(void *priv)
t128->status &= ~0x02;
t128->pos = 0;
t128->host_pos = 0;
scsi_bus->data_repeat = 0;
t128_log("T128 blocks read=%d, total len=%d\n", scsi_bus->data_pos, dev->buffer_length);
if (scsi_bus->data_pos >= dev->buffer_length) {
scsi_bus->bus_out |= BUS_REQ;

View File

@@ -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;

View File

@@ -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",

View File

@@ -792,14 +792,10 @@ pas16_in(uint16_t port, void *priv)
if ((scsi_bus->tx_mode == PIO_TX_BUS) && !(ret & 0x80))
ret |= 0x80;
if (ret & 0x80) {
if (scsi_bus->data_repeat < MIN(511, scsi_bus->total_len))
scsi_bus->data_repeat++;
} else {
if (scsi_bus->data_repeat == MIN(511, scsi_bus->total_len))
ret = 0x00;
}
pas16_log("%04X:%08X: Port %04x read ret=%02x, status=%02x, txmode=%x, repeat=%d.\n", CS, cpu_state.pc, port + pas16->base, ret, pas16->scsi->status & 0x06, scsi_bus->tx_mode, scsi_bus->data_repeat);
if ((pas16->scsi->status & 0x06) == 0x00)
ret = 0x00;
pas16_log("%04X:%08X: Port %04x read ret=%02x, status=%02x, txmode=%x, repeat=%d, total=%d.\n", CS, cpu_state.pc, port + pas16->base, ret, pas16->scsi->status & 0x06, scsi_bus->tx_mode, scsi_bus->data_repeat, MIN(511, scsi_bus->total_len));
}
break;
case 0x5c03:

View File

@@ -94,6 +94,8 @@ plat_netsocket_accept(SOCKET socket)
if (clientsocket == -1)
return -1;
fcntl(clientsocket, F_SETFL, fcntl(clientsocket, F_GETFL, 0) | O_NONBLOCK);
return clientsocket;
}

View File

@@ -942,22 +942,6 @@ et4000_kasan_available(void)
static const device_config_t et4000_tc6058af_config[] = {
// clang-format off
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 512,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "256 KB", .value = 256 },
{ .description = "512 KB", .value = 512 },
{ .description = "1 MB", .value = 1024 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "bios_ver",
.description = "BIOS Revision",
@@ -989,18 +973,12 @@ static const device_config_t et4000_tc6058af_config[] = {
{ .files_no = 0 }
}
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
static const device_config_t et4000_bios_config[] = {
// clang-format off
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 1024,
.default_int = 512,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
@@ -1011,6 +989,12 @@ static const device_config_t et4000_bios_config[] = {
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
static const device_config_t et4000_bios_config[] = {
// clang-format off
{
.name = "bios_ver",
.description = "BIOS Revision",
@@ -1042,6 +1026,22 @@ static const device_config_t et4000_bios_config[] = {
{ .files_no = 0 }
}
},
{
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 1024,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "256 KB", .value = 256 },
{ .description = "512 KB", .value = 512 },
{ .description = "1 MB", .value = 1024 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};

View File

@@ -1311,7 +1311,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
case 0xb148:
case 0xb2e8:
s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y);
if (s3->accel.multifunc[0xe] & 0x100) {
if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_VISION964)) {
s3->accel.b2e8_pix = 0;
if (s3->bpp == 3) {
if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) {
@@ -1353,7 +1353,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
case 0xb149:
case 0xb2e9:
s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y);
if (s3->accel.multifunc[0xe] & 0x100) {
if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_VISION964)) {
s3->accel.b2e8_pix = 0;
if (s3->bpp == 3) {
if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) {
@@ -8414,7 +8414,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
}
}
if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Pattern on pixtrans (911/924)*/
count = s3->accel.maj_axis_pcnt + 1;
s3->accel.temp_cnt = 16;
@@ -8806,8 +8805,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width);
if (!cpu_input && (frgd_mix == 3) && !vram_mask && !(s3->accel.multifunc[0xe] & 0x100) && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) {
s3_log("Special BitBLT.\n");
pclog("Special BitBLT.\n");
while (1) {
if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) {
READ(s3->accel.src + s3->accel.cx - s3->accel.minus, src_dat);
@@ -8851,7 +8849,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi
}
}
} else {
s3_log("Normal blit.\n");
s3_log("Normal blit, srcbase=%08x, dstbase=%08x, full=%04x, wrt_mask=%08x, extmultifunc0e=%03x, frgdmixval=%02x.\n", srcbase, dstbase, s3->accel.cmd, wrt_mask, s3->accel.multifunc[0x0e] & 0x180, s3->accel.frgd_mix);
while (count-- && (s3->accel.sy >= 0)) {
if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) {
if (vram_mask && (s3->accel.cmd & 0x10)) {
@@ -9842,8 +9840,8 @@ s3_init(const device_t *info)
break;
case S3_WINNER1000_805:
bios_fn = ROM_WINNER1000_805;
chip = S3_86C805;
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805);
chip = S3_86C801;
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801);
break;
case S3_86C805_ONBOARD:
bios_fn = NULL;