mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 01:48:21 -07:00
Merge remote-tracking branch 'upstream/master' into feature/mtrr
This commit is contained in:
6
.github/workflows/cmake.yml
vendored
6
.github/workflows/cmake.yml
vendored
@@ -191,6 +191,10 @@ jobs:
|
||||
triplet: x64-windows-static
|
||||
toolchain: ./cmake/llvm-win32-x86_64.cmake
|
||||
vcvars: x64
|
||||
# - name: ARM
|
||||
# triplet: arm-windows-static
|
||||
# toolchain: ./cmake/llvm-win32-arm.cmake
|
||||
# vcvars: x64_arm
|
||||
- name: ARM64
|
||||
triplet: arm64-windows-static
|
||||
toolchain: ./cmake/llvm-win32-aarch64.cmake
|
||||
@@ -217,7 +221,7 @@ jobs:
|
||||
|
||||
- name: Setup NuGet Credentials
|
||||
run: >
|
||||
& (C:/vcpkg/vcpkg fetch nuget | tail -n 2)
|
||||
& (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2)
|
||||
sources add
|
||||
-source "https://nuget.pkg.github.com/86Box/index.json"
|
||||
-storepasswordincleartext
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
=====
|
||||
|
||||
[](https://ci.86box.net/job/86Box/)
|
||||
[](COPYING) [](https://github.com/86Box/86Box/releases) [](https://github.com/86Box/86Box/releases)
|
||||
|
||||
**86Box** is a low level x86 emulator that runs older operating systems and software designed for IBM PC systems and compatibles from 1981 through fairly recent system designs based on the PCI bus.
|
||||
|
||||
|
||||
@@ -173,8 +173,8 @@ int gfxcard[2] = { 0, 0 }; /* (C) graphic
|
||||
int show_second_monitors = 1; /* (C) show non-primary monitors */
|
||||
int sound_is_float = 1; /* (C) sound uses FP values */
|
||||
int voodoo_enabled = 0; /* (C) video option */
|
||||
int ibm8514_enabled = 0; /* (C) video option */
|
||||
int xga_enabled = 0; /* (C) video option */
|
||||
int ibm8514_standalone_enabled = 0; /* (C) video option */
|
||||
int xga_standalone_enabled = 0; /* (C) video option */
|
||||
uint32_t mem_size = 0; /* (C) memory size (Installed on system board)*/
|
||||
uint32_t isa_mem_size = 0; /* (C) memory size (ISA Memory Cards) */
|
||||
int cpu_use_dynarec = 0; /* (C) cpu uses/needs Dyna */
|
||||
|
||||
@@ -20,7 +20,8 @@ endif()
|
||||
|
||||
add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
|
||||
dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c
|
||||
mca.c usb.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c machine_status.c ini.c)
|
||||
mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c
|
||||
machine_status.c ini.c)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
|
||||
|
||||
@@ -1868,10 +1868,8 @@ cdrom_insert(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = &cdrom[id];
|
||||
|
||||
if (dev->bus_type) {
|
||||
if (dev->insert)
|
||||
dev->insert(dev->priv);
|
||||
}
|
||||
if (dev->bus_type && dev->insert)
|
||||
dev->insert(dev->priv);
|
||||
}
|
||||
|
||||
/* The mechanics of ejecting a CD-ROM from a drive. */
|
||||
|
||||
@@ -247,17 +247,28 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size)
|
||||
c -= 'a' - 'A'; \
|
||||
break; \
|
||||
\
|
||||
case ' ': \
|
||||
case '!': \
|
||||
case '"': \
|
||||
case '#': \
|
||||
case '$': \
|
||||
case '%': \
|
||||
case '&': \
|
||||
case '\'': \
|
||||
case '(': \
|
||||
case ')': \
|
||||
case '-': \
|
||||
case '@': \
|
||||
case '^': \
|
||||
case '`': \
|
||||
case '{': \
|
||||
case '}': \
|
||||
case '~': \
|
||||
/* Valid on all sets (non-complying DOS characters). */ \
|
||||
break; \
|
||||
\
|
||||
case ' ': \
|
||||
case '"': \
|
||||
case '+': \
|
||||
case ',': \
|
||||
case '-': \
|
||||
case '.': \
|
||||
case '<': \
|
||||
case '=': \
|
||||
|
||||
@@ -17,10 +17,10 @@ add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali14
|
||||
ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c
|
||||
compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
|
||||
intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
|
||||
opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c sis_85c496.c
|
||||
sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
|
||||
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c
|
||||
via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
|
||||
opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
|
||||
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c
|
||||
sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c
|
||||
umc_hb4.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
|
||||
|
||||
if(OLIVETTI)
|
||||
target_sources(chipset PRIVATE olivetti_eva.c)
|
||||
|
||||
@@ -70,7 +70,6 @@ typedef struct ali1543_t {
|
||||
sff8038i_t *ide_controller[2];
|
||||
smbus_ali7101_t *smbus;
|
||||
usb_t *usb;
|
||||
usb_params_t usb_params;
|
||||
|
||||
} ali1543_t;
|
||||
|
||||
@@ -1069,7 +1068,7 @@ ali7101_write(int func, int addr, uint8_t val, void *priv)
|
||||
|
||||
case 0x40:
|
||||
dev->pmu_conf[addr] = val & 0x1f;
|
||||
pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03));
|
||||
nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr);
|
||||
break;
|
||||
case 0x41:
|
||||
dev->pmu_conf[addr] = val & 0x10;
|
||||
@@ -1080,6 +1079,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv)
|
||||
/* TODO: Is the status R/W or R/WC? */
|
||||
case 0x42:
|
||||
dev->pmu_conf[addr] &= ~(val & 0x1f);
|
||||
if (val & 0x08)
|
||||
nvr_smi_status_clear(dev->nvr);
|
||||
break;
|
||||
case 0x43:
|
||||
dev->pmu_conf[addr] &= ~(val & 0x10);
|
||||
@@ -1217,8 +1218,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x77:
|
||||
/* TODO: If bit 1 is clear, then status bit is set even if SMI is disabled. */
|
||||
dev->pmu_conf[addr] = val;
|
||||
pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03));
|
||||
ali1543_log("PMU77: %02X\n", val);
|
||||
nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr);
|
||||
apm_set_do_smi(dev->acpi->apm, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x41] & 0x10));
|
||||
break;
|
||||
|
||||
@@ -1423,14 +1424,23 @@ ali7101_read(int func, int addr, void *priv)
|
||||
return 0xff;
|
||||
|
||||
/* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */
|
||||
if (addr == 0x43)
|
||||
ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00;
|
||||
else if (addr == 0x7f)
|
||||
ret = 0x80;
|
||||
else if (addr == 0xbc)
|
||||
ret = inb(0x70);
|
||||
else
|
||||
ret = dev->pmu_conf[addr];
|
||||
switch (addr) {
|
||||
default:
|
||||
ret = dev->pmu_conf[addr];
|
||||
break;
|
||||
case 0x42:
|
||||
ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00);
|
||||
break;
|
||||
case 0x43:
|
||||
ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00;
|
||||
break;
|
||||
case 0x7f:
|
||||
ret = 0x80;
|
||||
break;
|
||||
case 0xbc:
|
||||
ret = inb(0x70);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->pmu_conf[0x77] & 0x10) {
|
||||
switch (addr) {
|
||||
@@ -1472,17 +1482,6 @@ ali7101_read(int func, int addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
ali5237_usb_update_interrupt(usb_t* usb, void *priv)
|
||||
{
|
||||
ali1543_t *dev = (ali1543_t *) priv;
|
||||
|
||||
if (usb->irq_level)
|
||||
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
|
||||
else
|
||||
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10), &dev->mirq_states[4]);
|
||||
}
|
||||
|
||||
static void
|
||||
ali1543_reset(void *priv)
|
||||
{
|
||||
@@ -1633,10 +1632,7 @@ ali1543_init(const device_t *info)
|
||||
dev->smbus = device_add(&ali7101_smbus_device);
|
||||
|
||||
/* USB */
|
||||
dev->usb_params.parent_priv = dev;
|
||||
dev->usb_params.smi_handle = NULL;
|
||||
dev->usb_params.update_interrupt = ali5237_usb_update_interrupt;
|
||||
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
dev->type = info->local & 0xff;
|
||||
dev->offset = (info->local >> 8) & 0x7f;
|
||||
|
||||
@@ -100,9 +100,8 @@ typedef struct cpq_386_t {
|
||||
static uint8_t
|
||||
cpq_read_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
uint32_t old = addr;
|
||||
const cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
@@ -115,9 +114,8 @@ cpq_read_ram(uint32_t addr, void *priv)
|
||||
static uint16_t
|
||||
cpq_read_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
uint32_t old = addr;
|
||||
const cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
@@ -130,9 +128,8 @@ cpq_read_ramw(uint32_t addr, void *priv)
|
||||
static uint32_t
|
||||
cpq_read_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t ret = 0xffffffff;
|
||||
uint32_t old = addr;
|
||||
const cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
@@ -145,8 +142,7 @@ cpq_read_raml(uint32_t addr, void *priv)
|
||||
static void
|
||||
cpq_write_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t old = addr;
|
||||
const cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
@@ -157,8 +153,7 @@ cpq_write_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
static void
|
||||
cpq_write_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t old = addr;
|
||||
const cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
@@ -169,8 +164,7 @@ cpq_write_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
static void
|
||||
cpq_write_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
uint32_t old = addr;
|
||||
const cpq_ram_t *dev = (cpq_ram_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt_base) + dev->phys_base;
|
||||
|
||||
@@ -181,8 +175,8 @@ cpq_write_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
static uint8_t
|
||||
cpq_read_regs(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
const cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
@@ -195,6 +189,9 @@ cpq_read_regs(uint32_t addr, void *priv)
|
||||
/* RAM Setup Port (Read/Write) */
|
||||
ret = dev->regs[addr];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -203,7 +200,6 @@ cpq_read_regs(uint32_t addr, void *priv)
|
||||
static uint16_t
|
||||
cpq_read_regsw(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
ret = cpq_read_regs(addr, priv);
|
||||
@@ -215,7 +211,6 @@ cpq_read_regsw(uint32_t addr, void *priv)
|
||||
static uint32_t
|
||||
cpq_read_regsl(uint32_t addr, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
ret = cpq_read_regsw(addr, priv);
|
||||
@@ -306,8 +301,6 @@ cpq_recalc_ram(cpq_386_t *dev)
|
||||
uint8_t end;
|
||||
uint8_t k;
|
||||
uint32_t virt_base;
|
||||
uint32_t virt_addr;
|
||||
uint32_t phys_addr;
|
||||
cpq_ram_t *cram;
|
||||
|
||||
for (uint16_t i = 0x10; i < sys_min_high; i++)
|
||||
@@ -393,14 +386,15 @@ cpq_write_regs(uint32_t addr, uint8_t val, void *priv)
|
||||
cpq_recalc_cache(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cpq_write_regsw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
|
||||
cpq_write_regs(addr, val & 0xff, priv);
|
||||
cpq_write_regs(addr + 1, (val >> 8) & 0xff, priv);
|
||||
}
|
||||
@@ -408,8 +402,6 @@ cpq_write_regsw(uint32_t addr, uint16_t val, void *priv)
|
||||
static void
|
||||
cpq_write_regsl(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) priv;
|
||||
|
||||
cpq_write_regsw(addr, val & 0xff, priv);
|
||||
cpq_write_regsw(addr + 2, (val >> 16) & 0xff, priv);
|
||||
}
|
||||
@@ -436,11 +428,9 @@ compaq_ram_init(cpq_ram_t *dev)
|
||||
static void
|
||||
compaq_ram_diags_parse(cpq_386_t *dev)
|
||||
{
|
||||
uint8_t val = dev->regs[0x00000001];
|
||||
uint8_t val = dev->regs[0x00000001];
|
||||
uint32_t accum = 0x00100000;
|
||||
|
||||
val;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
dev->ram_bases[i] = accum;
|
||||
|
||||
@@ -451,6 +441,9 @@ compaq_ram_diags_parse(cpq_386_t *dev)
|
||||
case RAM_DIAG_H_SYS_RAM_4MB:
|
||||
dev->ram_sizes[i] = 0x00400000;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
dev->ram_sizes[i] -= 0x00100000;
|
||||
@@ -476,8 +469,6 @@ compaq_recalc_base_ram(cpq_386_t *dev)
|
||||
uint8_t low_end = 0x00;
|
||||
uint8_t high_start = 0x00;
|
||||
uint8_t high_end = 0x00;
|
||||
uint32_t phys_addr = 0x00000000;
|
||||
uint32_t virt_addr = 0x00000000;
|
||||
cpq_ram_t *cram;
|
||||
|
||||
switch (base_mem) {
|
||||
@@ -618,7 +609,7 @@ compaq_386_close(void *priv)
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_386_init(const device_t *info)
|
||||
compaq_386_init(UNUSED(const device_t *info))
|
||||
{
|
||||
cpq_386_t *dev = (cpq_386_t *) calloc(1, sizeof(cpq_386_t));
|
||||
|
||||
@@ -706,6 +697,9 @@ compaq_386_init(const device_t *info)
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
|
||||
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_4MB;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_1MB | RAM_DIAG_H_MOD_A_RAM_NONE |
|
||||
|
||||
@@ -522,7 +522,7 @@ i420ex_speed_changed(void *priv)
|
||||
if (te)
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
|
||||
te = timer_is_enabled(&dev->fast_off_timer);
|
||||
te = timer_is_on(&dev->fast_off_timer);
|
||||
|
||||
timer_stop(&dev->fast_off_timer);
|
||||
if (te)
|
||||
|
||||
@@ -66,7 +66,6 @@ typedef struct _piix_ {
|
||||
uint8_t max_func;
|
||||
uint8_t pci_slot;
|
||||
uint8_t no_mirq0;
|
||||
uint8_t usb_irq_state;
|
||||
uint8_t regs[4][256];
|
||||
uint8_t readout_regs[256];
|
||||
uint8_t board_config[2];
|
||||
@@ -84,7 +83,6 @@ typedef struct _piix_ {
|
||||
piix_io_trap_t io_traps[26];
|
||||
port_92_t *port_92;
|
||||
pc_timer_t fast_off_timer;
|
||||
usb_params_t usb_params;
|
||||
} piix_t;
|
||||
|
||||
#ifdef ENABLE_PIIX_LOG
|
||||
@@ -1443,17 +1441,6 @@ piix_fast_off_count(void *priv)
|
||||
dev->regs[0][0xaa] |= 0x20;
|
||||
}
|
||||
|
||||
static void
|
||||
piix_usb_update_interrupt(usb_t* usb, void *priv)
|
||||
{
|
||||
piix_t *dev = (piix_t *) priv;
|
||||
|
||||
if (usb->irq_level)
|
||||
pci_set_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->pci_slot, PCI_INTD, &dev->usb_irq_state);
|
||||
}
|
||||
|
||||
static void
|
||||
piix_reset(void *priv)
|
||||
{
|
||||
@@ -1554,10 +1541,10 @@ piix_speed_changed(void *priv)
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
int te = timer_is_enabled(&dev->fast_off_timer);
|
||||
int to = timer_is_on(&dev->fast_off_timer);
|
||||
|
||||
timer_stop(&dev->fast_off_timer);
|
||||
if (te)
|
||||
if (to)
|
||||
timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period);
|
||||
}
|
||||
|
||||
@@ -1598,12 +1585,8 @@ piix_init(const device_t *info)
|
||||
sff_set_irq_mode(dev->bm[1], 1, 2);
|
||||
}
|
||||
|
||||
if (dev->type >= 3) {
|
||||
dev->usb_params.parent_priv = dev;
|
||||
dev->usb_params.smi_handle = NULL;
|
||||
dev->usb_params.update_interrupt = piix_usb_update_interrupt;
|
||||
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
|
||||
}
|
||||
if (dev->type >= 3)
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
if (dev->type > 3) {
|
||||
dev->nvr = device_add(&piix4_nvr_device);
|
||||
|
||||
@@ -497,7 +497,7 @@ sio_speed_changed(void *priv)
|
||||
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
|
||||
|
||||
if (dev->id == 0x03) {
|
||||
te = timer_is_enabled(&dev->fast_off_timer);
|
||||
te = timer_is_on(&dev->fast_off_timer);
|
||||
|
||||
timer_stop(&dev->fast_off_timer);
|
||||
if (te)
|
||||
|
||||
238
src/chipset/opti602.c
Normal file
238
src/chipset/opti602.c
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C601/82C602 Buffer Devices.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#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/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct opti602_t {
|
||||
uint8_t idx;
|
||||
|
||||
uint8_t regs[256];
|
||||
uint8_t gpio[32];
|
||||
|
||||
uint16_t gpio_base;
|
||||
|
||||
uint16_t gpio_mask;
|
||||
uint16_t gpio_size;
|
||||
|
||||
nvr_t *nvr;
|
||||
} opti602_t;
|
||||
|
||||
#ifdef ENABLE_OPTI602_LOG
|
||||
int opti602_do_log = ENABLE_OPTI602_LOG;
|
||||
|
||||
static void
|
||||
opti602_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti602_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define opti602_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
opti602_gpio_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti602_t *dev = (opti602_t *) priv;
|
||||
|
||||
dev->gpio[addr - dev->gpio_base] = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti602_gpio_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti602_t *dev = (opti602_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->gpio[addr - dev->gpio_base];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
opti602_gpio_recalc(opti602_t *dev)
|
||||
{
|
||||
if (dev->gpio_base != 0x0000)
|
||||
io_removehandler(dev->gpio_base, dev->gpio_size, opti602_gpio_read, NULL, NULL, opti602_gpio_write, NULL, NULL, dev);
|
||||
|
||||
dev->gpio_base = dev->regs[0xf8];
|
||||
dev->gpio_base |= (((uint16_t) dev->regs[0xf7]) << 8);
|
||||
|
||||
dev->gpio_size = 1 << ((dev->regs[0xf9] >> 2) & 0x07);
|
||||
|
||||
dev->gpio_mask = ~(dev->gpio_size - 1);
|
||||
dev->gpio_base &= dev->gpio_mask;
|
||||
|
||||
dev->gpio_mask = ~dev->gpio_mask;
|
||||
|
||||
if (dev->gpio_base != 0x0000)
|
||||
io_sethandler(dev->gpio_base, dev->gpio_size, opti602_gpio_read, NULL, NULL, opti602_gpio_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
static void
|
||||
opti602_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti602_t *dev = (opti602_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx == 0xea) || ((dev->idx >= 0xf7) && (dev->idx <= 0xfa))) {
|
||||
dev->regs[dev->idx] = val;
|
||||
opti602_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
|
||||
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
|
||||
switch (dev->idx) {
|
||||
case 0xea:
|
||||
/* GREEN Power Port */
|
||||
break;
|
||||
|
||||
case 0xf7:
|
||||
case 0xf8:
|
||||
/* General Purpose Chip Select Registers */
|
||||
opti602_gpio_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0xf9:
|
||||
/* General Purpose Chip Select Register */
|
||||
nvr_bank_set(0, !!(val & 0x20), dev->nvr);
|
||||
opti602_gpio_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0xfa:
|
||||
/* GPM Port */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti602_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
const opti602_t *dev = (opti602_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x24:
|
||||
if ((dev->idx == 0xea) || ((dev->idx >= 0xf7) && (dev->idx <= 0xfa))) {
|
||||
ret = dev->regs[dev->idx];
|
||||
if ((dev->idx == 0xfa) && (dev->regs[0xf9] & 0x40))
|
||||
ret |= dev->regs[0xea];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
opti602_reset(void *priv)
|
||||
{
|
||||
opti602_t *dev = (opti602_t *) priv;
|
||||
|
||||
memset(dev->regs, 0x00, 256 * sizeof(uint8_t));
|
||||
memset(dev->gpio, 0x00, 32 * sizeof(uint8_t));
|
||||
|
||||
dev->regs[0xfa] = 0x07;
|
||||
|
||||
dev->gpio[0x01] |= 0xfe;
|
||||
|
||||
nvr_bank_set(0, 0, dev->nvr);
|
||||
opti602_gpio_recalc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
opti602_close(void *priv)
|
||||
{
|
||||
opti602_t *dev = (opti602_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
opti602_init(const device_t *info)
|
||||
{
|
||||
opti602_t *dev = (opti602_t *) calloc(1, sizeof(opti602_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti602_read, NULL, NULL, opti602_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti602_read, NULL, NULL, opti602_write, NULL, NULL, dev);
|
||||
|
||||
dev->nvr = device_add(&at_mb_nvr_device);
|
||||
|
||||
opti602_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t opti601_device = {
|
||||
.name = "OPTi 82C601",
|
||||
.internal_name = "opti601",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti602_init,
|
||||
.close = opti602_close,
|
||||
.reset = opti602_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti602_device = {
|
||||
.name = "OPTi 82C602",
|
||||
.internal_name = "opti602",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti602_init,
|
||||
.close = opti602_close,
|
||||
.reset = opti602_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -140,6 +140,8 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti895_t *dev = (opti895_t *) priv;
|
||||
|
||||
opti895_log("opti895_write(%04X, %08X)\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->idx = val;
|
||||
@@ -231,6 +233,8 @@ opti895_read(uint16_t addr, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
opti895_log("opti895_read(%04X) = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,9 +87,6 @@ typedef struct sis_5571_t {
|
||||
sff8038i_t *ide_drive[2];
|
||||
smram_t *smram;
|
||||
usb_t *usb;
|
||||
|
||||
usb_params_t usb_params;
|
||||
|
||||
} sis_5571_t;
|
||||
|
||||
static void
|
||||
@@ -669,43 +666,6 @@ pci_isa_bridge_read(int func, int addr, void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_usb_update_interrupt(usb_t* usb, void* priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
if (dev->pci_conf_sb[0][0x68] & 0x80) {
|
||||
/* TODO: Is the normal PCI interrupt inhibited when USB IRQ remapping is enabled? */
|
||||
switch (dev->pci_conf_sb[0][0x68] & 0x0F) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x08:
|
||||
case 0x0d:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (usb->irq_level)
|
||||
picint(1 << dev->pci_conf_sb[0][0x68] & 0x0f);
|
||||
else
|
||||
picintc(1 << dev->pci_conf_sb[0][0x68] & 0x0f);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (usb->irq_level)
|
||||
pci_set_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->sb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5571_usb_handle_smi(UNUSED(usb_t* usb), UNUSED(void* priv))
|
||||
{
|
||||
/* Left unimplemented for now. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_reset(void *priv)
|
||||
{
|
||||
@@ -790,10 +750,7 @@ sis_5571_init(UNUSED(const device_t *info))
|
||||
dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
/* USB */
|
||||
dev->usb_params.parent_priv = dev;
|
||||
dev->usb_params.update_interrupt = sis_5571_usb_update_interrupt;
|
||||
dev->usb_params.smi_handle = sis_5571_usb_handle_smi;
|
||||
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
sis_5571_reset(dev);
|
||||
|
||||
|
||||
@@ -73,9 +73,6 @@ typedef struct stpc_t {
|
||||
smram_t *smram;
|
||||
usb_t *usb;
|
||||
sff8038i_t *bm[2];
|
||||
|
||||
/* Miscellaneous */
|
||||
usb_params_t usb_params;
|
||||
} stpc_t;
|
||||
|
||||
typedef struct stpc_serial_t {
|
||||
@@ -898,17 +895,6 @@ stpc_setup(stpc_t *dev)
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
stpc_usb_update_interrupt(usb_t* usb, void* priv)
|
||||
{
|
||||
stpc_t *dev = (stpc_t *) priv;
|
||||
|
||||
if (usb->irq_level)
|
||||
pci_set_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
else
|
||||
pci_clear_irq(dev->usb_slot, PCI_INTA, &dev->usb_irq_state);
|
||||
}
|
||||
|
||||
static void
|
||||
stpc_close(void *priv)
|
||||
{
|
||||
@@ -934,12 +920,9 @@ stpc_init(const device_t *info)
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot);
|
||||
if (dev->local == STPC_ATLAS) {
|
||||
dev->usb_params.smi_handle = NULL;
|
||||
dev->usb_params.update_interrupt = stpc_usb_update_interrupt;
|
||||
dev->usb_params.parent_priv = dev;
|
||||
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot);
|
||||
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
|
||||
|
||||
dev->usb = device_add(&usb_device);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,12 @@
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Melissa Goad, <mszoopers@protonmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2020 Melissa Goad.
|
||||
* Copyright 2020 RichardG.
|
||||
* Copyright 2020 Tiseno100.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -10,14 +10,10 @@
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Melissa Goad, <mszoopers@protonmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2020 Melissa Goad.
|
||||
* Copyright 2020-2021 RichardG.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "x87.h"
|
||||
#include "386_common.h"
|
||||
#include "cpu.h"
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
# include "x86.h"
|
||||
# include "x86_flags.h"
|
||||
# include "x86_ops.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "x87.h"
|
||||
# include <86box/mem.h>
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
# include "x86.h"
|
||||
# include "x86_flags.h"
|
||||
# include "x86_ops.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "x87.h"
|
||||
/*ex*/
|
||||
# include <86box/nmi.h>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "x86_ops.h"
|
||||
#include "codegen.h"
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
# include "codegen_backend_arm_ops.h"
|
||||
# include "codegen_reg.h"
|
||||
# include "x86.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "x87.h"
|
||||
|
||||
# if defined(__linux__) || defined(__APPLE__)
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
# include "codegen_backend_arm64_ops.h"
|
||||
# include "codegen_reg.h"
|
||||
# include "x86.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "x87.h"
|
||||
|
||||
# if defined(__linux__) || defined(__APPLE__)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
# include <86box/mem.h>
|
||||
|
||||
# include "x86.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "x87.h"
|
||||
# include "386_common.h"
|
||||
# include "codegen.h"
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
# include <86box/mem.h>
|
||||
|
||||
# include "x86.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "x87.h"
|
||||
# include "386_common.h"
|
||||
# include "codegen.h"
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
# include "codegen_backend_x86-64_ops_sse.h"
|
||||
# include "codegen_reg.h"
|
||||
# include "x86.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
|
||||
# if defined(__linux__) || defined(__APPLE__)
|
||||
# include <sys/mman.h>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#if defined __amd64__ || defined _M_X64
|
||||
|
||||
# include <stdint.h>
|
||||
# include <inttypes.h>
|
||||
# include <86box/86box.h>
|
||||
# include "cpu.h"
|
||||
# include <86box/mem.h>
|
||||
@@ -125,7 +126,7 @@ host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data)
|
||||
codegen_alloc_bytes(block, 4);
|
||||
codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/
|
||||
} else
|
||||
fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data);
|
||||
fatal("ADD64_REG_IMM !is_imm8 %016" PRIx64 "\n", imm_data);
|
||||
}
|
||||
void
|
||||
host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
@@ -1614,7 +1615,7 @@ host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data)
|
||||
codegen_alloc_bytes(block, 4);
|
||||
codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/
|
||||
} else
|
||||
fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data);
|
||||
fatal("SUB64_REG_IMM !is_imm8 %016" PRIx64 "\n", imm_data);
|
||||
}
|
||||
void
|
||||
host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
# include <86box/mem.h>
|
||||
|
||||
# include "x86.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "x87.h"
|
||||
# include "386_common.h"
|
||||
# include "codegen.h"
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
# include "codegen_backend_x86_ops_sse.h"
|
||||
# include "codegen_reg.h"
|
||||
# include "x86.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
|
||||
# if defined(__linux__) || defined(__APPLE__)
|
||||
# include <sys/mman.h>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
# include "x86.h"
|
||||
# include "x86_ops.h"
|
||||
# include "x86seg_common.h"
|
||||
# include "x86seg.h"
|
||||
# include "386_common.h"
|
||||
# include "codegen.h"
|
||||
# include "codegen_allocator.h"
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "x87.h"
|
||||
|
||||
#include "386_common.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "x86_flags.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "x87.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "x87.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "x87.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "x87.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_accumulate.h"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <86box/mem.h>
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
|
||||
514
src/config.c
514
src/config.c
@@ -88,7 +88,7 @@ static ini_t config;
|
||||
static int backwards_compat = 0;
|
||||
static int backwards_compat2 = 0;
|
||||
|
||||
#define ENABLE_CONFIG_LOG 1
|
||||
#define ENABLE_CONFIG_LOG 1
|
||||
#ifdef ENABLE_CONFIG_LOG
|
||||
int config_do_log = ENABLE_CONFIG_LOG;
|
||||
|
||||
@@ -504,11 +504,6 @@ load_machine(void)
|
||||
fpu_type = fpu_get_type(cpu_f, cpu, p);
|
||||
|
||||
mem_size = ini_section_get_int(cat, "mem_size", 64);
|
||||
#if 0
|
||||
if (mem_size < ((machine_has_bus(machine, MACHINE_AT) &&
|
||||
(machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram))
|
||||
mem_size = (((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram);
|
||||
#endif
|
||||
|
||||
if (mem_size > machine_get_max_ram(machine))
|
||||
mem_size = machine_get_max_ram(machine);
|
||||
@@ -569,9 +564,16 @@ load_video(void)
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_8514A)) || video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_8514)
|
||||
ini_section_delete_var(cat, "8514a");
|
||||
if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_XGA)) || video_card_get_flags(gfxcard[0]) == VIDEO_FLAG_TYPE_XGA)
|
||||
ini_section_delete_var(cat, "xga");
|
||||
|
||||
voodoo_enabled = !!ini_section_get_int(cat, "voodoo", 0);
|
||||
ibm8514_enabled = !!ini_section_get_int(cat, "8514a", 0);
|
||||
xga_enabled = !!ini_section_get_int(cat, "xga", 0);
|
||||
ibm8514_standalone_enabled = !!ini_section_get_int(cat, "8514a", 0);
|
||||
ibm8514_active = ibm8514_standalone_enabled;
|
||||
xga_standalone_enabled = !!ini_section_get_int(cat, "xga", 0);
|
||||
xga_active = xga_standalone_enabled;
|
||||
show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1);
|
||||
video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0);
|
||||
|
||||
@@ -619,35 +621,35 @@ load_input_devices(void)
|
||||
else {
|
||||
c = ini_section_get_int(cat, "joystick_type", 8);
|
||||
switch (c) {
|
||||
case 1:
|
||||
case JS_TYPE_2AXIS_4BUTTON:
|
||||
joystick_type = joystick_get_from_internal_name("2axis_4button");
|
||||
break;
|
||||
case 2:
|
||||
case JS_TYPE_2AXIS_6BUTTON:
|
||||
joystick_type = joystick_get_from_internal_name("2axis_6button");
|
||||
break;
|
||||
case 3:
|
||||
case JS_TYPE_2AXIS_8BUTTON:
|
||||
joystick_type = joystick_get_from_internal_name("2axis_8button");
|
||||
break;
|
||||
case 4:
|
||||
case JS_TYPE_4AXIS_4BUTTON:
|
||||
joystick_type = joystick_get_from_internal_name("4axis_4button");
|
||||
break;
|
||||
case 5:
|
||||
case JS_TYPE_CH_FLIGHTSTICK_PRO:
|
||||
joystick_type = joystick_get_from_internal_name("ch_flightstick_pro");
|
||||
break;
|
||||
case 6:
|
||||
case JS_TYPE_SIDEWINDER_PAD:
|
||||
joystick_type = joystick_get_from_internal_name("sidewinder_pad");
|
||||
break;
|
||||
case 7:
|
||||
case JS_TYPE_THRUSTMASTER_FCS:
|
||||
joystick_type = joystick_get_from_internal_name("thrustmaster_fcs");
|
||||
break;
|
||||
default:
|
||||
joystick_type = 0;
|
||||
joystick_type = JS_TYPE_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
joystick_type = 0;
|
||||
joystick_type = JS_TYPE_NONE;
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
||||
sprintf(temp, "joystick_%i_nr", c);
|
||||
@@ -893,12 +895,6 @@ load_ports(void)
|
||||
sprintf(temp, "serial%d_enabled", c + 1);
|
||||
com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1);
|
||||
|
||||
#if 0
|
||||
sprintf(temp, "serial%d_device", c + 1);
|
||||
p = (char *) ini_section_get_string(cat, temp, "none");
|
||||
com_ports[c].device = com_device_get_from_internal_name(p);
|
||||
#endif
|
||||
|
||||
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
|
||||
serial_passthrough_enabled[c] = !!ini_section_get_int(cat, temp, 0);
|
||||
|
||||
@@ -1027,27 +1023,19 @@ load_storage_controllers(void)
|
||||
sprintf(temp, "cartridge_%02i_fn", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* NOTE:
|
||||
* Temporary hack to remove the absolute
|
||||
* path currently saved in most config
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c]));
|
||||
} else
|
||||
#endif
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_storage_controllers(): strlen(p) > 511\n");
|
||||
else
|
||||
strncpy(cart_fns[c], p, 511);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_storage_controllers(): strlen(p) > 511 (cart_fns[%i])\n", c);
|
||||
else
|
||||
strncpy(cart_fns[c], p, 511);
|
||||
} else
|
||||
path_append_filename(cart_fns[c], usr_path, p);
|
||||
path_normalize(cart_fns[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1198,34 +1186,24 @@ load_hard_disks(void)
|
||||
sprintf(temp, "hdd_%02i_fn", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* NOTE:
|
||||
* Temporary hack to remove the absolute
|
||||
* path currently saved in most config
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
/*
|
||||
* ANOTHER NOTE:
|
||||
* When loading differencing VHDs, the absolute path is required.
|
||||
* So we should not convert absolute paths to relative. -sards
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the CFG path. Just strip
|
||||
* that off for now...
|
||||
* NOTE:
|
||||
* When loading differencing VHDs, the absolute path is required.
|
||||
* So we should not convert absolute paths to relative. -sards
|
||||
*/
|
||||
wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn));
|
||||
} else
|
||||
#endif
|
||||
if (path_abs(p)) {
|
||||
strncpy(hdd[c].fn, p, sizeof(hdd[c].fn) - 1);
|
||||
} else {
|
||||
path_append_filename(hdd[c].fn, usr_path, p);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_hard_disks(): strlen(p) > 511 (hdd[%i].fn)\n", c);
|
||||
else
|
||||
strncpy(hdd[c].fn, p, 511);
|
||||
} else
|
||||
path_append_filename(hdd[c].fn, usr_path, p);
|
||||
path_normalize(hdd[c].fn);
|
||||
}
|
||||
path_normalize(hdd[c].fn);
|
||||
|
||||
sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1);
|
||||
hdd[c].vhd_blocksize = ini_section_get_int(cat, temp, 0);
|
||||
@@ -1284,30 +1262,22 @@ load_floppy_drives(void)
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* NOTE:
|
||||
* Temporary hack to remove the absolute
|
||||
* path currently saved in most config
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c]));
|
||||
} else
|
||||
#endif
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_floppy_drives(): strlen(p) > 511\n");
|
||||
else
|
||||
strncpy(floppyfns[c], p, 511);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
#if 0
|
||||
if (*wp != L'\0')
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_floppy_drives(): strlen(p) > 511 (floppyfns[%i])\n", c);
|
||||
else
|
||||
strncpy(floppyfns[c], p, 511);
|
||||
} else
|
||||
path_append_filename(floppyfns[c], usr_path, p);
|
||||
path_normalize(floppyfns[c]);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2)
|
||||
if (*p != '\0')
|
||||
config_log("Floppy%d: %ls\n", c, floppyfns[c]);
|
||||
#endif
|
||||
sprintf(temp, "fdd_%02i_writeprot", c + 1);
|
||||
@@ -1352,30 +1322,22 @@ load_floppy_and_cdrom_drives(void)
|
||||
sprintf(temp, "fdd_%02i_fn", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* NOTE:
|
||||
* Temporary hack to remove the absolute
|
||||
* path currently saved in most config
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c]));
|
||||
} else
|
||||
#endif
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511\n");
|
||||
else
|
||||
strncpy(floppyfns[c], p, 511);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
#if 0
|
||||
if (*wp != L'\0')
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (floppyfns[%i])\n", c);
|
||||
else
|
||||
strncpy(floppyfns[c], p, 511);
|
||||
} else
|
||||
path_append_filename(floppyfns[c], usr_path, p);
|
||||
path_normalize(floppyfns[c]);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2)
|
||||
if (*p != '\0')
|
||||
config_log("Floppy%d: %ls\n", c, floppyfns[c]);
|
||||
#endif
|
||||
sprintf(temp, "fdd_%02i_writeprot", c + 1);
|
||||
@@ -1385,7 +1347,8 @@ load_floppy_and_cdrom_drives(void)
|
||||
sprintf(temp, "fdd_%02i_check_bpb", c + 1);
|
||||
fdd_set_check_bpb(c, !!ini_section_get_int(cat, temp, 1));
|
||||
|
||||
/* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */
|
||||
/* Check whether each value is default, if yes, delete it so that only
|
||||
non-default values will later be saved. */
|
||||
if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) {
|
||||
sprintf(temp, "fdd_%02i_type", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
@@ -1411,7 +1374,16 @@ load_floppy_and_cdrom_drives(void)
|
||||
sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
sprintf(fdd_image_history[c][i], "%s", p);
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 255)
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 255 "
|
||||
"(fdd_image_history[%i][%i])\n", c, i);
|
||||
else
|
||||
snprintf(fdd_image_history[c][i], 255, "%s", p);
|
||||
} else
|
||||
snprintf(fdd_image_history[c][i], 255, "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(fdd_image_history[c][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1493,24 +1465,19 @@ load_floppy_and_cdrom_drives(void)
|
||||
sprintf(temp, "cdrom_%02i_image_path", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* NOTE:
|
||||
* Temporary hack to remove the absolute
|
||||
* path currently saved in most config
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path));
|
||||
} else
|
||||
#endif
|
||||
strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (cdrom[%i].image_path)\n", c);
|
||||
else
|
||||
strncpy(cdrom[c].image_path, p, 511);
|
||||
} else
|
||||
path_append_filename(cdrom[c].image_path, usr_path, p);
|
||||
path_normalize(cdrom[c].image_path);
|
||||
}
|
||||
|
||||
if (cdrom[c].host_drive && (cdrom[c].host_drive != 200))
|
||||
cdrom[c].host_drive = 0;
|
||||
@@ -1518,6 +1485,24 @@ load_floppy_and_cdrom_drives(void)
|
||||
if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0))
|
||||
cdrom[c].host_drive = 0;
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
|
||||
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 "
|
||||
"(cdrom[%i].image_history[%i])\n", c, i);
|
||||
else
|
||||
snprintf(cdrom[c].image_history[i], 511, "%s", p);
|
||||
} else
|
||||
snprintf(cdrom[c].image_history[i], 511, "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(cdrom[c].image_history[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the CD-ROM is disabled, delete all its variables. */
|
||||
if (cdrom[c].bus_type == CDROM_BUS_DISABLED) {
|
||||
sprintf(temp, "cdrom_%02i_host_drive", c + 1);
|
||||
@@ -1534,19 +1519,15 @@ load_floppy_and_cdrom_drives(void)
|
||||
|
||||
sprintf(temp, "cdrom_%02i_image_path", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_iso_path", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
|
||||
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
sprintf(cdrom[c].image_history[i], "%s", p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1557,7 +1538,7 @@ load_other_removable_devices(void)
|
||||
ini_section_t cat = ini_find_section(config, "Other removable devices");
|
||||
char temp[512];
|
||||
char tmp2[512];
|
||||
const char *p;
|
||||
char *p;
|
||||
char s[512];
|
||||
unsigned int board = 0;
|
||||
unsigned int dev = 0;
|
||||
@@ -1618,24 +1599,20 @@ load_other_removable_devices(void)
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
ini_section_delete_var(cat, temp);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* NOTE:
|
||||
* Temporary hack to remove the absolute
|
||||
* path currently saved in most config
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path));
|
||||
} else
|
||||
#endif
|
||||
strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_other_removable_devices(): strlen(p) > 511 (cdrom[%i].image_path)\n",
|
||||
c);
|
||||
else
|
||||
strncpy(cdrom[c].image_path, p, 511);
|
||||
} else
|
||||
path_append_filename(cdrom[c].image_path, usr_path, p);
|
||||
path_normalize(cdrom[c].image_path);
|
||||
}
|
||||
|
||||
if (cdrom[c].host_drive && (cdrom[c].host_drive != 200))
|
||||
cdrom[c].host_drive = 0;
|
||||
@@ -1705,26 +1682,40 @@ load_other_removable_devices(void)
|
||||
sprintf(temp, "zip_%02i_image_path", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* NOTE:
|
||||
* Temporary hack to remove the absolute
|
||||
* path currently saved in most config
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path));
|
||||
} else
|
||||
#endif
|
||||
strncpy(zip_drives[c].image_path, p, sizeof(zip_drives[c].image_path) - 1);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
/* If the CD-ROM is disabled, delete all its variables. */
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_other_removable_devices(): strlen(p) > 511 (zip_drives[%i].image_path)\n",
|
||||
c);
|
||||
else
|
||||
strncpy(zip_drives[c].image_path, p, 511);
|
||||
} else
|
||||
path_append_filename(zip_drives[c].image_path, usr_path, p);
|
||||
path_normalize(zip_drives[c].image_path);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
zip_drives[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
|
||||
sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_other_removable_devices(): strlen(p) > 511 "
|
||||
"(zip_drives[%i].image_history[%i])\n", c, i);
|
||||
else
|
||||
snprintf(zip_drives[c].image_history[i], 511, "%s", p);
|
||||
} else
|
||||
snprintf(zip_drives[c].image_history[i], 511, "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(zip_drives[c].image_history[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the ZIP drive is disabled, delete all its variables. */
|
||||
if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) {
|
||||
sprintf(temp, "zip_%02i_host_drive", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
@@ -1740,10 +1731,12 @@ load_other_removable_devices(void)
|
||||
|
||||
sprintf(temp, "zip_%02i_image_path", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
sprintf(temp, "zip_%02i_iso_path", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
@@ -1805,9 +1798,40 @@ load_other_removable_devices(void)
|
||||
sprintf(temp, "mo_%02i_image_path", c + 1);
|
||||
p = ini_section_get_string(cat, temp, "");
|
||||
|
||||
strncpy(mo_drives[c].image_path, p, sizeof(mo_drives[c].image_path) - 1);
|
||||
if (!strcmp(p, usr_path))
|
||||
p[0] = 0x00;
|
||||
|
||||
/* If the CD-ROM is disabled, delete all its variables. */
|
||||
if (p[0] != 0x00) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_other_removable_devices(): strlen(p) > 511 (mo_drives[%i].image_path)\n",
|
||||
c);
|
||||
else
|
||||
strncpy(mo_drives[c].image_path, p, 511);
|
||||
} else
|
||||
path_append_filename(mo_drives[c].image_path, usr_path, p);
|
||||
path_normalize(mo_drives[c].image_path);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
mo_drives[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
|
||||
sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_other_removable_devices(): strlen(p) > 511 "
|
||||
"(mo_drives[%i].image_history[%i])\n", c, i);
|
||||
else
|
||||
snprintf(mo_drives[c].image_history[i], 511, "%s", p);
|
||||
} else
|
||||
snprintf(mo_drives[c].image_history[i], 511, "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(mo_drives[c].image_history[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the MO drive is disabled, delete all its variables. */
|
||||
if (mo_drives[c].bus_type == MO_BUS_DISABLED) {
|
||||
sprintf(temp, "mo_%02i_host_drive", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
@@ -1823,10 +1847,12 @@ load_other_removable_devices(void)
|
||||
|
||||
sprintf(temp, "mo_%02i_image_path", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
sprintf(temp, "mo_%02i_iso_path", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2333,15 +2359,15 @@ save_video(void)
|
||||
else
|
||||
ini_section_set_int(cat, "voodoo", voodoo_enabled);
|
||||
|
||||
if (ibm8514_enabled == 0)
|
||||
if (ibm8514_standalone_enabled == 0)
|
||||
ini_section_delete_var(cat, "8514a");
|
||||
else
|
||||
ini_section_set_int(cat, "8514a", ibm8514_enabled);
|
||||
ini_section_set_int(cat, "8514a", ibm8514_standalone_enabled);
|
||||
|
||||
if (xga_enabled == 0)
|
||||
if (xga_standalone_enabled == 0)
|
||||
ini_section_delete_var(cat, "xga");
|
||||
else
|
||||
ini_section_set_int(cat, "xga", xga_enabled);
|
||||
ini_section_set_int(cat, "xga", xga_standalone_enabled);
|
||||
|
||||
if (gfxcard[1] == 0)
|
||||
ini_section_delete_var(cat, "gfxcard_2");
|
||||
@@ -2543,19 +2569,16 @@ save_network(void)
|
||||
ini_section_delete_var(cat, temp);
|
||||
else
|
||||
ini_section_set_string(cat, temp, net_cards_conf[c].host_dev_name);
|
||||
} else {
|
||||
#if 0
|
||||
ini_section_set_string(cat, temp, "none");
|
||||
#endif
|
||||
} else
|
||||
ini_section_delete_var(cat, temp);
|
||||
}
|
||||
|
||||
sprintf(temp, "net_%02i_link", c + 1);
|
||||
if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD | NET_LINK_100_HD | NET_LINK_100_FD | NET_LINK_1000_HD | NET_LINK_1000_FD)) {
|
||||
if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD |
|
||||
NET_LINK_100_HD | NET_LINK_100_FD |
|
||||
NET_LINK_1000_HD | NET_LINK_1000_FD))
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
else
|
||||
ini_section_set_int(cat, temp, net_cards_conf[c].link_state);
|
||||
}
|
||||
}
|
||||
|
||||
ini_delete_section_if_empty(config, cat);
|
||||
@@ -2577,21 +2600,6 @@ save_ports(void)
|
||||
else
|
||||
ini_section_set_int(cat, temp, com_ports[c].enabled);
|
||||
|
||||
#if 0
|
||||
sprintf(temp, "serial%d_type", c + 1);
|
||||
if (!com_ports[c].enabled))
|
||||
ini_section_delete_var(cat, temp);
|
||||
// else
|
||||
// ini_section_set_string(cat, temp, (char *) serial_type[c])
|
||||
|
||||
sprintf(temp, "serial%d_device", c + 1);
|
||||
if (com_ports[c].device == 0)
|
||||
ini_section_delete_var(cat, temp);
|
||||
else
|
||||
ini_section_set_string(cat, temp,
|
||||
(char *) com_device_get_internal_name(com_ports[c].device));
|
||||
#endif
|
||||
|
||||
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
|
||||
if (serial_passthrough_enabled[c]) {
|
||||
ini_section_set_int(cat, temp, 1);
|
||||
@@ -2868,7 +2876,11 @@ save_floppy_and_cdrom_drives(void)
|
||||
sprintf(temp, "fdd_%02i_writeprot", c + 1);
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_string(cat, temp, floppyfns[c]);
|
||||
path_normalize(floppyfns[c]);
|
||||
if (!strnicmp(floppyfns[c], usr_path, strlen(usr_path)))
|
||||
ini_section_set_string(cat, temp, &floppyfns[c][strlen(usr_path)]);
|
||||
else
|
||||
ini_section_set_string(cat, temp, floppyfns[c]);
|
||||
}
|
||||
|
||||
sprintf(temp, "fdd_%02i_writeprot", c + 1);
|
||||
@@ -2891,10 +2903,14 @@ save_floppy_and_cdrom_drives(void)
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
sprintf(temp, "fdd_%02i_image_history_%02i", c + 1, i + 1);
|
||||
if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0) {
|
||||
if ((fdd_image_history[c][i] == 0) || strlen(fdd_image_history[c][i]) == 0)
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_string(cat, temp, fdd_image_history[c][i]);
|
||||
else {
|
||||
path_normalize(fdd_image_history[c][i]);
|
||||
if (!strnicmp(fdd_image_history[c][i], usr_path, strlen(usr_path)))
|
||||
ini_section_set_string(cat, temp, &fdd_image_history[c][i][strlen(usr_path)]);
|
||||
else
|
||||
ini_section_set_string(cat, temp, fdd_image_history[c][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2923,16 +2939,14 @@ save_floppy_and_cdrom_drives(void)
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_parameters", c + 1);
|
||||
if (cdrom[c].bus_type == 0) {
|
||||
if (cdrom[c].bus_type == 0)
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else { /*In case one wants an ATAPI drive on SCSI and vice-versa.*/
|
||||
if (cdrom[c].bus_type == CDROM_BUS_ATAPI) {
|
||||
if (cdrom_drive_types[cdrom_get_type(c)].bus_type == BUS_TYPE_SCSI)
|
||||
cdrom[c].bus_type = CDROM_BUS_SCSI;
|
||||
} else if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
|
||||
if (cdrom_drive_types[cdrom_get_type(c)].bus_type == BUS_TYPE_IDE)
|
||||
cdrom[c].bus_type = CDROM_BUS_ATAPI;
|
||||
}
|
||||
else {
|
||||
/* In case one wants an ATAPI drive on SCSI and vice-versa. */
|
||||
if ((cdrom_drive_types[cdrom_get_type(c)].bus_type != BUS_TYPE_BOTH) &&
|
||||
(cdrom_drive_types[cdrom_get_type(c)].bus_type != cdrom[c].bus_type))
|
||||
cdrom[c].bus_type = cdrom_drive_types[cdrom_get_type(c)].bus_type;
|
||||
|
||||
sprintf(tmp2, "%u, %s", cdrom[c].sound_on,
|
||||
hdd_bus_to_string(cdrom[c].bus_type, 1));
|
||||
ini_section_set_string(cat, temp, tmp2);
|
||||
@@ -2960,18 +2974,26 @@ save_floppy_and_cdrom_drives(void)
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_image_path", c + 1);
|
||||
if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) {
|
||||
if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0))
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_string(cat, temp, cdrom[c].image_path);
|
||||
else {
|
||||
path_normalize(cdrom[c].image_path);
|
||||
if (!strnicmp(cdrom[c].image_path, usr_path, strlen(usr_path)))
|
||||
ini_section_set_string(cat, temp, &cdrom[c].image_path[strlen(usr_path)]);
|
||||
else
|
||||
ini_section_set_string(cat, temp, cdrom[c].image_path);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
|
||||
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
|
||||
if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) {
|
||||
if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0)
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_string(cat, temp, cdrom[c].image_history[i]);
|
||||
else {
|
||||
path_normalize(cdrom[c].image_history[i]);
|
||||
if (!strnicmp(cdrom[c].image_history[i], usr_path, strlen(usr_path)))
|
||||
ini_section_set_string(cat, temp, &cdrom[c].image_history[i][strlen(usr_path)]);
|
||||
else
|
||||
ini_section_set_string(cat, temp, cdrom[c].image_history[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3020,10 +3042,14 @@ save_other_removable_devices(void)
|
||||
}
|
||||
|
||||
sprintf(temp, "zip_%02i_image_path", c + 1);
|
||||
if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) {
|
||||
if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0))
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_string(cat, temp, zip_drives[c].image_path);
|
||||
else {
|
||||
path_normalize(zip_drives[c].image_path);
|
||||
if (!strnicmp(zip_drives[c].image_path, usr_path, strlen(usr_path)))
|
||||
ini_section_set_string(cat, temp, &zip_drives[c].image_path[strlen(usr_path)]);
|
||||
else
|
||||
ini_section_set_string(cat, temp, zip_drives[c].image_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3059,10 +3085,14 @@ save_other_removable_devices(void)
|
||||
}
|
||||
|
||||
sprintf(temp, "mo_%02i_image_path", c + 1);
|
||||
if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) {
|
||||
if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0))
|
||||
ini_section_delete_var(cat, temp);
|
||||
} else {
|
||||
ini_section_set_string(cat, temp, mo_drives[c].image_path);
|
||||
else {
|
||||
path_normalize(mo_drives[c].image_path);
|
||||
if (!strnicmp(mo_drives[c].image_path, usr_path, strlen(usr_path)))
|
||||
ini_section_set_string(cat, temp, &mo_drives[c].image_path[strlen(usr_path)]);
|
||||
else
|
||||
ini_section_set_string(cat, temp, mo_drives[c].image_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x87.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/nmi.h>
|
||||
@@ -28,6 +29,7 @@
|
||||
#ifndef OPS_286_386
|
||||
# define OPS_286_386
|
||||
#endif
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# include "codegen.h"
|
||||
@@ -77,7 +79,6 @@ x386_log(const char *fmt, ...)
|
||||
static __inline void
|
||||
fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (cpu_rm == 4) {
|
||||
uint8_t sib = rmdat >> 8;
|
||||
@@ -122,19 +123,11 @@ fetch_ea_32_long(uint32_t rmdat)
|
||||
cpu_state.eaaddr = getlong();
|
||||
}
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) {
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if (readlookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void
|
||||
fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (!cpu_mod && cpu_rm == 6) {
|
||||
cpu_state.eaaddr = getword();
|
||||
@@ -158,13 +151,6 @@ fetch_ea_16_long(uint32_t rmdat)
|
||||
}
|
||||
cpu_state.eaaddr &= 0xFFFF;
|
||||
}
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) {
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
if (readlookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr);
|
||||
if (writelookup2[addr >> 12] != (uintptr_t) -1)
|
||||
eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr);
|
||||
}
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) \
|
||||
@@ -225,11 +211,20 @@ fetch_ea_16_long(uint32_t rmdat)
|
||||
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
#define CHECK_READ_CS(size) \
|
||||
if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \
|
||||
((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !(cpu_state.seg_cs.access & 0x80)) \
|
||||
x86np("Read from seg not present", cpu_state.seg_cs.seg & 0xfffc); \
|
||||
|
||||
#include "386_ops.h"
|
||||
|
||||
void
|
||||
exec386_2386(int cycs)
|
||||
{
|
||||
int ol;
|
||||
|
||||
int vector;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
@@ -264,6 +259,8 @@ exec386_2386(int cycs)
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
ol = opcode_length[fetchdat & 0xff];
|
||||
CHECK_READ_CS(MIN(ol, 4));
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
#ifdef ENABLE_386_LOG
|
||||
@@ -296,7 +293,7 @@ exec386_2386(int cycs)
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt & ABRT_MASK;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
x86_doabrt_2386(tempi);
|
||||
if (cpu_state.abrt) {
|
||||
cpu_state.abrt = 0;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
@@ -304,7 +301,7 @@ exec386_2386(int cycs)
|
||||
#endif
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x386_log("Double fault\n");
|
||||
pmodeint(8, 0);
|
||||
pmodeint_2386(8, 0);
|
||||
if (cpu_state.abrt) {
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
@@ -347,7 +344,7 @@ exec386_2386(int cycs)
|
||||
if (vector != -1) {
|
||||
flags_rebuild();
|
||||
if (msw & 1)
|
||||
pmodeint(vector, 0);
|
||||
pmodeint_2386(vector, 0);
|
||||
else {
|
||||
writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags);
|
||||
writememw(ss, (SP - 4) & 0xFFFF, CS);
|
||||
@@ -357,7 +354,7 @@ exec386_2386(int cycs)
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
loadcs_2386(readmemw(0, addr + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -374,7 +371,7 @@ exec386_2386(int cycs)
|
||||
}
|
||||
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process_inline();
|
||||
timer_process();
|
||||
|
||||
#ifdef USE_GDBSTUB
|
||||
if (gdbstub_instruction())
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x87.h"
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/mem.h>
|
||||
@@ -23,9 +24,10 @@
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg.h"
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
@@ -1184,7 +1186,10 @@ enter_smm(int in_hlt)
|
||||
if (is_cxsmm) {
|
||||
cpu_state.pc = 0x0000;
|
||||
cpl_override = 1;
|
||||
cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
if (is486)
|
||||
cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
else
|
||||
cyrix_write_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
cpl_override = 0;
|
||||
cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4);
|
||||
cpu_state.seg_cs.base = cyrix.arr[3].base;
|
||||
@@ -1317,7 +1322,10 @@ leave_smm(void)
|
||||
saved_state[3] = readmeml(0, smram_state - 0x10);
|
||||
saved_state[4] = readmeml(0, smram_state - 0x14);
|
||||
saved_state[5] = readmeml(0, smram_state - 0x18);
|
||||
cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
if (is486)
|
||||
cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
else
|
||||
cyrix_load_seg_descriptor_2386(smram_state - 0x20, &cpu_state.seg_cs);
|
||||
saved_state[6] = readmeml(0, smram_state - 0x24);
|
||||
} else {
|
||||
for (uint8_t n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
|
||||
@@ -1403,7 +1411,7 @@ x86_int(int num)
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
|
||||
if (msw & 1)
|
||||
pmodeint(num, 0);
|
||||
is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0);
|
||||
else {
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
@@ -1436,7 +1444,7 @@ x86_int(int num)
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1453,7 +1461,7 @@ x86_int_sw(int num)
|
||||
cycles -= timing_int;
|
||||
|
||||
if (msw & 1)
|
||||
pmodeint(num, 1);
|
||||
is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1);
|
||||
else {
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
@@ -1478,7 +1486,7 @@ x86_int_sw(int num)
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
|
||||
cycles -= timing_int_rm;
|
||||
}
|
||||
}
|
||||
@@ -1520,7 +1528,7 @@ x86_int_sw_rm(int num)
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = new_pc;
|
||||
loadcs(new_cs);
|
||||
is486 ? loadcs(new_cs) : loadcs_2386(new_cs);
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
|
||||
@@ -225,19 +225,19 @@ int checkio(uint32_t port, int mask);
|
||||
static __inline uint8_t
|
||||
fastreadb(uint32_t a)
|
||||
{
|
||||
return readmembl(a);
|
||||
return readmembl_2386(a);
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
fastreadw(uint32_t a)
|
||||
{
|
||||
return readmemwl(a);
|
||||
return readmemwl_2386(a);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
fastreadl(uint32_t a)
|
||||
{
|
||||
return readmemll(a);
|
||||
return readmemll_2386(a);
|
||||
}
|
||||
#else
|
||||
static __inline uint8_t
|
||||
@@ -347,11 +347,11 @@ fastreadw_fetch(uint32_t a)
|
||||
if ((a & 0xFFF) > 0xFFE) {
|
||||
val = fastreadb(a);
|
||||
if (opcode_length[val & 0xff] > 1)
|
||||
val |= (fastreadb(a + 1) << 8);
|
||||
val |= ((uint16_t) fastreadb(a + 1) << 8);
|
||||
return val;
|
||||
}
|
||||
|
||||
return readmemwl(a);
|
||||
return readmemwl_2386(a);
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
@@ -359,14 +359,14 @@ fastreadl_fetch(uint32_t a)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if ((a & 0xFFF) > 0xFFC) {
|
||||
if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) {
|
||||
val = fastreadw_fetch(a);
|
||||
if (opcode_length[val & 0xff] > 2)
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
val |= ((uint32_t) fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
|
||||
return readmemll(a);
|
||||
return readmemll_2386(a);
|
||||
}
|
||||
#else
|
||||
static __inline uint16_t
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "x87.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
@@ -256,7 +258,7 @@ update_tsc(void)
|
||||
|
||||
if (cycdiff > 0) {
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process_inline();
|
||||
timer_process();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +784,7 @@ exec386_dynarec(int cycs)
|
||||
|
||||
if (cycdiff > 0) {
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process_inline();
|
||||
timer_process();
|
||||
}
|
||||
|
||||
# ifdef USE_GDBSTUB
|
||||
@@ -943,7 +945,7 @@ exec386(int cycs)
|
||||
}
|
||||
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process_inline();
|
||||
timer_process();
|
||||
|
||||
#ifdef USE_GDBSTUB
|
||||
if (gdbstub_instruction())
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <86box/timer.h>
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "x87.h"
|
||||
#include "x86_flags.h"
|
||||
#include <86box/io.h>
|
||||
|
||||
@@ -173,7 +173,6 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "x86seg.h"
|
||||
#include "x86_ops_arith.h"
|
||||
#include "x86_ops_atomic.h"
|
||||
#include "x86_ops_bcd.h"
|
||||
|
||||
@@ -487,21 +487,6 @@ cycles_biu(int bus, int init)
|
||||
BUS_CYCLE_NEXT;
|
||||
}
|
||||
|
||||
#ifdef REENIGNE_MODELING
|
||||
static void
|
||||
bus_init(void)
|
||||
{
|
||||
/* Replacement for the old access() stuff. */
|
||||
if ((BUS_CYCLE == BUS_T4) && last_was_code && (opcode != 0x8f) && (opcode != 0xc7) && (opcode != 0xcc) && (opcode != 0xcd) && (opcode != 0xce) && ((opcode & 0xf0) != 0xa0))
|
||||
cycles_idle(1);
|
||||
|
||||
cycles_idle(2);
|
||||
|
||||
while ((BUS_CYCLE == BUS_T2) || (BUS_CYCLE == BUS_T3))
|
||||
cycles_idle(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Bus:
|
||||
0 CPU cycles without bus access.
|
||||
1 CPU cycle T1-T4, bus access.
|
||||
@@ -561,10 +546,6 @@ resub_cycles(int old_cycles)
|
||||
static void
|
||||
cpu_io(int bits, int out, uint16_t port)
|
||||
{
|
||||
#ifdef REENIGNE_MODELING
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
if (out) {
|
||||
if (bits == 16) {
|
||||
if (is8086 && !(port & 1)) {
|
||||
@@ -608,10 +589,6 @@ readmemb(uint32_t s, uint16_t a)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
#ifdef REENIGNE_MODELING
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
bus_request_type = BUS_MEM;
|
||||
@@ -642,10 +619,6 @@ readmemw(uint32_t s, uint16_t a)
|
||||
{
|
||||
uint16_t ret;
|
||||
|
||||
#ifdef REENIGNE_MODELING
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
if (is8086 && !(a & 1)) {
|
||||
@@ -715,10 +688,6 @@ writememb(uint32_t s, uint32_t a, uint8_t v)
|
||||
{
|
||||
uint32_t addr = s + a;
|
||||
|
||||
#ifdef REENIGNE_MODELING
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
mem_data = v;
|
||||
@@ -736,10 +705,6 @@ writememw(uint32_t s, uint32_t a, uint16_t v)
|
||||
{
|
||||
uint32_t addr = s + a;
|
||||
|
||||
#ifdef REENIGNE_MODELING
|
||||
bus_init();
|
||||
#endif
|
||||
|
||||
mem_seg = s;
|
||||
mem_addr = a;
|
||||
mem_data = v;
|
||||
@@ -3463,11 +3428,15 @@ execx86(int cycs)
|
||||
|
||||
case 0xD4: /*AAM*/
|
||||
wait(1, 0);
|
||||
#ifdef NO_VARIANT_ON_NEC
|
||||
if (is_nec) {
|
||||
(void) pfq_fetchb();
|
||||
cpu_src = 10;
|
||||
} else
|
||||
cpu_src = pfq_fetchb();
|
||||
#else
|
||||
cpu_src = pfq_fetchb();
|
||||
#endif
|
||||
if (x86_div(AL, 0))
|
||||
set_pzs(16);
|
||||
break;
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
#
|
||||
|
||||
add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c
|
||||
386_dynarec.c x86_ops_mmx.c x86seg.c x87.c x87_timings.c 8080.c)
|
||||
386_dynarec.c x86_ops_mmx.c x86seg_common.c x86seg.c x86seg_2386.c x87.c
|
||||
x87_timings.c 8080.c)
|
||||
|
||||
if(AMD_K5)
|
||||
target_compile_definitions(cpu PRIVATE USE_AMD_K5)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x87.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x87.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/io.h>
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/pic.h>
|
||||
|
||||
@@ -590,7 +590,6 @@ extern uint64_t cpu_CR4_mask;
|
||||
extern uint64_t tsc;
|
||||
extern msr_t msr;
|
||||
extern uint8_t opcode;
|
||||
extern int cgate16;
|
||||
extern int cpl_override;
|
||||
extern int CPUID;
|
||||
extern uint64_t xt_cpu_multi;
|
||||
@@ -721,15 +720,6 @@ extern uint32_t cpu_fast_off_flags;
|
||||
/* Functions. */
|
||||
extern int cpu_has_feature(int feature);
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
extern void loadseg_dynarec(uint16_t seg, x86seg *s);
|
||||
extern int loadseg(uint16_t seg, x86seg *s);
|
||||
extern void loadcs(uint16_t seg);
|
||||
#else
|
||||
extern void loadseg(uint16_t seg, x86seg *s);
|
||||
extern void loadcs(uint16_t seg);
|
||||
#endif
|
||||
|
||||
extern char *cpu_current_pc(char *bufp);
|
||||
|
||||
extern void cpu_update_waitstates(void);
|
||||
@@ -758,19 +748,6 @@ extern void exec386_2386(int cycs);
|
||||
extern void exec386(int cycs);
|
||||
extern void exec386_dynarec(int cycs);
|
||||
extern int idivl(int32_t val);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
extern void loadcscall(uint16_t seg, uint32_t old_pc);
|
||||
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
||||
extern void pmodeint(int num, int soft);
|
||||
extern void pmoderetf(int is32, uint16_t off);
|
||||
extern void pmodeiret(int is32);
|
||||
#else
|
||||
extern void loadcscall(uint16_t seg);
|
||||
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
||||
extern void pmodeint(int num, int soft);
|
||||
extern void pmoderetf(int is32, uint16_t off);
|
||||
extern void pmodeiret(int is32);
|
||||
#endif
|
||||
extern void resetmcr(void);
|
||||
extern void resetx86(void);
|
||||
extern void refreshread(void);
|
||||
@@ -780,11 +757,6 @@ extern void hardresetx86(void);
|
||||
extern void x86_int(int num);
|
||||
extern void x86_int_sw(int num);
|
||||
extern int x86_int_sw_rm(int num);
|
||||
extern void x86de(char *s, uint16_t error);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
extern void x86np(char *s, uint16_t error);
|
||||
extern void x86ss(char *s, uint16_t error);
|
||||
extern void x86ts(char *s, uint16_t error);
|
||||
|
||||
#ifdef ENABLE_808X_LOG
|
||||
extern void dumpregs(int __force);
|
||||
|
||||
@@ -378,7 +378,7 @@ const cpu_family_t cpu_families[] = {
|
||||
}, {
|
||||
.package = CPU_PKG_SOCKET1,
|
||||
.manufacturer = "Intel",
|
||||
.name = "i486SX (SL-Enhanced)",
|
||||
.name = "i486SX-S",
|
||||
.internal_name = "i486sx_slenh",
|
||||
.cpus = (const CPU[]) {
|
||||
{"25", CPU_i486SX_SLENH, fpus_486sx, 25000000, 1, 5000, 0x423, 0x423, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
@@ -409,7 +409,7 @@ const cpu_family_t cpu_families[] = {
|
||||
}, {
|
||||
.package = CPU_PKG_SOCKET1,
|
||||
.manufacturer = "Intel",
|
||||
.name = "i486DX (SL-Enhanced)",
|
||||
.name = "i486DX-S",
|
||||
.internal_name = "i486dx_slenh",
|
||||
.cpus = (const CPU[]) {
|
||||
{"33", CPU_i486DX_SLENH, fpus_internal, 33333333, 1, 5000, 0x414, 0x414, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
@@ -430,7 +430,7 @@ const cpu_family_t cpu_families[] = {
|
||||
}, {
|
||||
.package = CPU_PKG_SOCKET1,
|
||||
.manufacturer = "Intel",
|
||||
.name = "i486DX2 (SL-Enhanced)",
|
||||
.name = "i486DX2-S",
|
||||
.internal_name = "i486dx2_slenh",
|
||||
.cpus = (const CPU[]) {
|
||||
{"40", CPU_i486DX_SLENH, fpus_internal, 40000000, 2, 5000, 0x435, 0x435, 0, CPU_SUPPORTS_DYNAREC, 7, 7,6,6, 5},
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include <86box/machine.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/dma.h>
|
||||
@@ -270,7 +272,10 @@ reset_common(int hard)
|
||||
cpu_state.eflags = 0;
|
||||
cgate32 = 0;
|
||||
if (is286) {
|
||||
loadcs(0xF000);
|
||||
if (is486)
|
||||
loadcs(0xF000);
|
||||
else
|
||||
loadcs_2386(0xF000);
|
||||
cpu_state.pc = 0xFFF0;
|
||||
if (hard) {
|
||||
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
|
||||
@@ -351,7 +356,7 @@ softresetx86(void)
|
||||
if (soft_reset_mask)
|
||||
return;
|
||||
|
||||
if (ibm8514_enabled || xga_enabled)
|
||||
if (ibm8514_active || xga_active)
|
||||
vga_on = 1;
|
||||
|
||||
reset_common(0);
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Second CPU header.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2018 leilei.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_X86_H
|
||||
#define EMU_X86_H
|
||||
|
||||
#define ABRT_MASK 0x3f
|
||||
/*An 'expected' exception is one that would be expected to occur on every execution
|
||||
of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is
|
||||
@@ -10,7 +33,7 @@
|
||||
#define ABRT_EXPECTED 0x80
|
||||
|
||||
extern uint8_t opcode;
|
||||
extern uint8_t opcode2;
|
||||
|
||||
extern uint8_t flags_p;
|
||||
extern uint8_t znptable8[256];
|
||||
|
||||
@@ -31,7 +54,6 @@ extern int trap;
|
||||
extern int optype;
|
||||
extern int stack32;
|
||||
extern int oldcpl;
|
||||
extern int cgate32;
|
||||
extern int cpl_override;
|
||||
extern int nmi_enable;
|
||||
extern int oddeven;
|
||||
@@ -75,24 +97,6 @@ extern uint32_t *eal_w;
|
||||
fetcheal(); \
|
||||
}
|
||||
|
||||
#define JMP 1
|
||||
#define CALL 2
|
||||
#define IRET 3
|
||||
#define OPTYPE_INT 4
|
||||
|
||||
enum {
|
||||
ABRT_NONE = 0,
|
||||
ABRT_GEN = 1,
|
||||
ABRT_TS = 0xA,
|
||||
ABRT_NP = 0xB,
|
||||
ABRT_SS = 0xC,
|
||||
ABRT_GPF = 0xD,
|
||||
ABRT_PF = 0xE,
|
||||
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
|
||||
};
|
||||
|
||||
extern void x86_doabrt(int x86_abrt);
|
||||
extern void x86illegal(void);
|
||||
extern void x86seg_reset(void);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
extern void x86gpf_expected(char *s, uint16_t error);
|
||||
|
||||
#endif /*EMU_X86_H*/
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
optype = CALL; \
|
||||
cgate16 = cgate32 = 0; \
|
||||
if (msw & 1) \
|
||||
loadcscall(new_seg, old_pc); \
|
||||
op_loadcscall(new_seg, old_pc); \
|
||||
else { \
|
||||
loadcs(new_seg); \
|
||||
op_loadcs(new_seg); \
|
||||
cycles -= timing_call_rm; \
|
||||
} \
|
||||
optype = 0; \
|
||||
@@ -54,9 +54,9 @@
|
||||
optype = CALL; \
|
||||
cgate16 = cgate32 = 0; \
|
||||
if (msw & 1) \
|
||||
loadcscall(new_seg, old_pc); \
|
||||
op_loadcscall(new_seg, old_pc); \
|
||||
else { \
|
||||
loadcs(new_seg); \
|
||||
op_loadcs(new_seg); \
|
||||
cycles -= timing_call_rm; \
|
||||
} \
|
||||
optype = 0; \
|
||||
@@ -103,9 +103,9 @@
|
||||
optype = CALL; \
|
||||
cgate16 = cgate32 = 0; \
|
||||
if (msw & 1) \
|
||||
loadcscall(new_seg); \
|
||||
op_loadcscall(new_seg); \
|
||||
else { \
|
||||
loadcs(new_seg); \
|
||||
op_loadcs(new_seg); \
|
||||
cycles -= timing_call_rm; \
|
||||
} \
|
||||
optype = 0; \
|
||||
@@ -148,9 +148,9 @@
|
||||
optype = CALL; \
|
||||
cgate16 = cgate32 = 0; \
|
||||
if (msw & 1) \
|
||||
loadcscall(new_seg); \
|
||||
op_loadcscall(new_seg); \
|
||||
else { \
|
||||
loadcs(new_seg); \
|
||||
op_loadcs(new_seg); \
|
||||
cycles -= timing_call_rm; \
|
||||
} \
|
||||
optype = 0; \
|
||||
@@ -362,14 +362,12 @@ opFF_w_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
loadcsjmp(new_cs, old_pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
op_loadcsjmp(new_cs, old_pc);
|
||||
#else
|
||||
loadcsjmp(new_cs, oxpc);
|
||||
op_loadcsjmp(new_cs, oxpc);
|
||||
#endif
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#endif
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
@@ -526,14 +524,12 @@ opFF_w_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
loadcsjmp(new_cs, old_pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
op_loadcsjmp(new_cs, old_pc);
|
||||
#else
|
||||
loadcsjmp(new_cs, oxpc);
|
||||
op_loadcsjmp(new_cs, oxpc);
|
||||
#endif
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#endif
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
@@ -691,14 +687,12 @@ opFF_l_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
loadcsjmp(new_cs, old_pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
op_loadcsjmp(new_cs, old_pc);
|
||||
#else
|
||||
loadcsjmp(new_cs, oxpc);
|
||||
op_loadcsjmp(new_cs, oxpc);
|
||||
#endif
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#endif
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
@@ -857,14 +851,12 @@ opFF_l_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
loadcsjmp(new_cs, old_pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
op_loadcsjmp(new_cs, old_pc);
|
||||
#else
|
||||
loadcsjmp(new_cs, oxpc);
|
||||
op_loadcsjmp(new_cs, oxpc);
|
||||
#endif
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#endif
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
|
||||
@@ -282,7 +282,7 @@ opJMP_far_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, old_pc);
|
||||
op_loadcsjmp(seg, old_pc);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
@@ -301,7 +301,7 @@ opJMP_far_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, old_pc);
|
||||
op_loadcsjmp(seg, old_pc);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/timer.h>
|
||||
#include "x86seg_common.h"
|
||||
#include "x86seg.h"
|
||||
#include "386_common.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg.h"
|
||||
|
||||
MMX_REG *MMP[8];
|
||||
uint16_t *MMEP[8];
|
||||
|
||||
@@ -178,13 +178,13 @@ opMOV_seg_w_a16(uint32_t fetchdat)
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
op_loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
op_loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
op_loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
@@ -198,10 +198,10 @@ opMOV_seg_w_a16(uint32_t fetchdat)
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
op_loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
op_loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -223,13 +223,13 @@ opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
op_loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
op_loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
op_loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
@@ -243,10 +243,10 @@ opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
op_loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
op_loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ opLDS_w_a16(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
op_loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
@@ -292,7 +292,7 @@ opLDS_w_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
op_loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
@@ -315,7 +315,7 @@ opLDS_l_a16(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
op_loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
@@ -338,7 +338,7 @@ opLDS_l_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds);
|
||||
op_loadseg(seg, &cpu_state.seg_ds);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
@@ -362,7 +362,7 @@ opLSS_w_a16(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
op_loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
@@ -385,7 +385,7 @@ opLSS_w_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
op_loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
@@ -408,7 +408,7 @@ opLSS_l_a16(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
op_loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
@@ -431,7 +431,7 @@ opLSS_l_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss);
|
||||
op_loadseg(seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
@@ -454,7 +454,7 @@ opLSS_l_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
op_loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = addr; \
|
||||
@@ -476,7 +476,7 @@ opLSS_l_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
op_loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].w = addr; \
|
||||
@@ -499,7 +499,7 @@ opLSS_l_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
op_loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = addr; \
|
||||
@@ -522,7 +522,7 @@ opLSS_l_a32(uint32_t fetchdat)
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(seg, &sel); \
|
||||
op_loadseg(seg, &sel); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.regs[cpu_reg].l = addr; \
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
|
||||
#define RETF_a16(stack_offset) \
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
|
||||
pmoderetf(0, stack_offset); \
|
||||
op_pmoderetf(0, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) { \
|
||||
cpu_state.pc = readmemw(ss, ESP); \
|
||||
loadcs(readmemw(ss, ESP + 2)); \
|
||||
op_loadcs(readmemw(ss, ESP + 2)); \
|
||||
} else { \
|
||||
cpu_state.pc = readmemw(ss, SP); \
|
||||
loadcs(readmemw(ss, SP + 2)); \
|
||||
op_loadcs(readmemw(ss, SP + 2)); \
|
||||
} \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
@@ -27,16 +27,16 @@
|
||||
|
||||
#define RETF_a32(stack_offset) \
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
|
||||
pmoderetf(1, stack_offset); \
|
||||
op_pmoderetf(1, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) { \
|
||||
cpu_state.pc = readmeml(ss, ESP); \
|
||||
loadcs(readmeml(ss, ESP + 4) & 0xffff); \
|
||||
op_loadcs(readmeml(ss, ESP + 4) & 0xffff); \
|
||||
} else { \
|
||||
cpu_state.pc = readmeml(ss, SP); \
|
||||
loadcs(readmeml(ss, SP + 4) & 0xffff); \
|
||||
op_loadcs(readmeml(ss, SP + 4) & 0xffff); \
|
||||
} \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
@@ -114,7 +114,7 @@ opIRET_186(uint32_t fetchdat)
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
op_pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
@@ -130,7 +130,7 @@ opIRET_186(uint32_t fetchdat)
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
@@ -154,7 +154,7 @@ opIRET_286(uint32_t fetchdat)
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
op_pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
@@ -170,7 +170,7 @@ opIRET_286(uint32_t fetchdat)
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
@@ -210,7 +210,7 @@ opIRET(uint32_t fetchdat)
|
||||
else
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
|
||||
loadcs(new_cs);
|
||||
op_loadcs(new_cs);
|
||||
cpu_state.pc = new_pc;
|
||||
|
||||
cycles -= timing_iret_rm;
|
||||
@@ -221,7 +221,7 @@ opIRET(uint32_t fetchdat)
|
||||
} else {
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(0);
|
||||
op_pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
@@ -237,7 +237,7 @@ opIRET(uint32_t fetchdat)
|
||||
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
}
|
||||
@@ -262,7 +262,7 @@ opIRETD(uint32_t fetchdat)
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
pmodeiret(1);
|
||||
op_pmodeiret(1);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
@@ -280,7 +280,7 @@ opIRETD(uint32_t fetchdat)
|
||||
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
|
||||
SP += 12;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
|
||||
@@ -610,7 +610,7 @@ opLEAVE_l(uint32_t fetchdat)
|
||||
temp_seg = POP_W(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(temp_seg, realseg); \
|
||||
op_loadseg(temp_seg, realseg); \
|
||||
if (cpu_state.abrt) \
|
||||
ESP = temp_esp; \
|
||||
CLOCK_CYCLES(is486 ? 3 : 7); \
|
||||
@@ -624,7 +624,7 @@ opLEAVE_l(uint32_t fetchdat)
|
||||
temp_seg = POP_L(); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
loadseg(temp_seg & 0xffff, realseg); \
|
||||
op_loadseg(temp_seg & 0xffff, realseg); \
|
||||
if (cpu_state.abrt) \
|
||||
ESP = temp_esp; \
|
||||
CLOCK_CYCLES(is486 ? 3 : 7); \
|
||||
@@ -651,7 +651,7 @@ opPOP_SS_w(uint32_t fetchdat)
|
||||
temp_seg = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(temp_seg, &cpu_state.seg_ss);
|
||||
op_loadseg(temp_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = temp_esp;
|
||||
return 1;
|
||||
@@ -679,7 +679,7 @@ opPOP_SS_l(uint32_t fetchdat)
|
||||
temp_seg = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
loadseg(temp_seg & 0xffff, &cpu_state.seg_ss);
|
||||
op_loadseg(temp_seg & 0xffff, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) {
|
||||
ESP = temp_esp;
|
||||
return 1;
|
||||
|
||||
221
src/cpu/x86seg.c
221
src/cpu/x86seg.c
@@ -36,17 +36,25 @@
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86seg.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "386_common.h"
|
||||
|
||||
uint8_t opcode2;
|
||||
|
||||
int cgate16;
|
||||
int cgate32;
|
||||
int intgatesize;
|
||||
|
||||
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32);
|
||||
|
||||
void pmodeint(int num, int soft);
|
||||
#ifdef OPS_286_386
|
||||
#define seg_readmembl readmembl_2386
|
||||
#define seg_readmemwl readmemwl_2386
|
||||
#define seg_readmemll readmemll_2386
|
||||
#define seg_writemembl writemembl_2386
|
||||
#define seg_writememwl writememwl_2386
|
||||
#define seg_writememll writememll_2386
|
||||
#else
|
||||
#define seg_readmembl readmembl_2386
|
||||
#define seg_readmemwl readmemwl_2386
|
||||
#define seg_readmemll readmemll_2386
|
||||
#define seg_writemembl writemembl_2386
|
||||
#define seg_writememwl writememwl_2386
|
||||
#define seg_writememll writememll_2386
|
||||
#endif
|
||||
|
||||
#define DPL ((segdat[2] >> 13) & 3)
|
||||
#define DPL2 ((segdat2[2] >> 13) & 3)
|
||||
@@ -70,41 +78,12 @@ x86seg_log(const char *fmt, ...)
|
||||
# define x86seg_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
seg_reset(x86seg *s)
|
||||
{
|
||||
s->access = 0x82;
|
||||
s->ar_high = 0x10;
|
||||
s->limit = 0xffff;
|
||||
s->limit_low = 0;
|
||||
s->limit_high = 0xffff;
|
||||
if (s == &cpu_state.seg_cs) {
|
||||
if (!cpu_inited)
|
||||
fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n");
|
||||
if (is6117)
|
||||
s->base = 0x03ff0000;
|
||||
else
|
||||
s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0;
|
||||
s->seg = is286 ? 0xf000 : 0xffff;
|
||||
} else {
|
||||
s->base = 0;
|
||||
s->seg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x86seg_reset(void)
|
||||
{
|
||||
seg_reset(&cpu_state.seg_cs);
|
||||
seg_reset(&cpu_state.seg_ds);
|
||||
seg_reset(&cpu_state.seg_es);
|
||||
seg_reset(&cpu_state.seg_fs);
|
||||
seg_reset(&cpu_state.seg_gs);
|
||||
seg_reset(&cpu_state.seg_ss);
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
x86_doabrt_2386(int x86_abrt)
|
||||
#else
|
||||
x86_doabrt(int x86_abrt)
|
||||
#endif
|
||||
{
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
CS = oldcs;
|
||||
@@ -114,7 +93,7 @@ x86_doabrt(int x86_abrt)
|
||||
cpu_state.seg_cs.ar_high = 0x10;
|
||||
|
||||
if (msw & 1)
|
||||
pmodeint(x86_abrt, 0);
|
||||
op_pmodeint(x86_abrt, 0);
|
||||
else {
|
||||
uint32_t addr = (x86_abrt << 2) + idt.base;
|
||||
if (stack32) {
|
||||
@@ -134,7 +113,7 @@ x86_doabrt(int x86_abrt)
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
op_loadcs(readmemw(0, addr + 2));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -160,52 +139,6 @@ x86_doabrt(int x86_abrt)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x86de(UNUSED(char *s), UNUSED(uint16_t error))
|
||||
{
|
||||
#ifdef BAD_CODE
|
||||
cpu_state.abrt = ABRT_DE;
|
||||
abrt_error = error;
|
||||
#else
|
||||
x86_int(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_GPF;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf_expected(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86ss(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_SS;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86ts(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_TS;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86np(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_NP;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
static void
|
||||
set_stack32(int s)
|
||||
{
|
||||
@@ -228,6 +161,7 @@ set_use32(int u)
|
||||
cpu_cur_status &= ~CPU_STATUS_USE32;
|
||||
}
|
||||
|
||||
#ifndef OPS_286_386
|
||||
void
|
||||
do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
{
|
||||
@@ -262,6 +196,7 @@ do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
do_seg_v86_init(x86seg *s)
|
||||
@@ -310,7 +245,7 @@ check_seg_valid(x86seg *s)
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
loadseg(0, s);
|
||||
op_loadseg(0, s);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -336,7 +271,11 @@ int
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
#ifdef OPS_286_386
|
||||
loadseg_2386(uint16_t seg, x86seg *s)
|
||||
#else
|
||||
loadseg(uint16_t seg, x86seg *s)
|
||||
#endif
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
@@ -534,7 +473,11 @@ loadseg(uint16_t seg, x86seg *s)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
loadcs_2386(uint16_t seg)
|
||||
#else
|
||||
loadcs(uint16_t seg)
|
||||
#endif
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
@@ -623,7 +566,11 @@ loadcs(uint16_t seg)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
loadcsjmp_2386(uint16_t seg, uint32_t old_pc)
|
||||
#else
|
||||
loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
#endif
|
||||
{
|
||||
uint16_t type;
|
||||
uint16_t seg2;
|
||||
@@ -783,7 +730,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
cpu_state.pc = old_pc;
|
||||
optype = JMP;
|
||||
cpl_override = 1;
|
||||
taskswitch286(seg, segdat, segdat[2] & 0x800);
|
||||
op_taskswitch286(seg, segdat, segdat[2] & 0x800);
|
||||
cpu_state.flags &= ~NT_FLAG;
|
||||
cpl_override = 0;
|
||||
return;
|
||||
@@ -810,7 +757,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PUSHW(uint16_t v)
|
||||
{
|
||||
if (stack32) {
|
||||
@@ -826,7 +773,7 @@ PUSHW(uint16_t v)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
PUSHL(uint32_t v)
|
||||
{
|
||||
if (cpu_16bitbus) {
|
||||
@@ -847,7 +794,7 @@ PUSHL(uint32_t v)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t
|
||||
static uint16_t
|
||||
POPW(void)
|
||||
{
|
||||
uint16_t tempw;
|
||||
@@ -865,7 +812,7 @@ POPW(void)
|
||||
return tempw;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
static uint32_t
|
||||
POPL(void)
|
||||
{
|
||||
uint32_t templ;
|
||||
@@ -890,6 +837,15 @@ POPL(void)
|
||||
return templ;
|
||||
}
|
||||
|
||||
#ifdef OPS_286_386
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
void
|
||||
loadcscall_2386(uint16_t seg, uint32_t old_pc)
|
||||
#else
|
||||
void
|
||||
loadcscall_2386(uint16_t seg)
|
||||
#endif
|
||||
#else
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
void
|
||||
loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
@@ -897,6 +853,7 @@ loadcscall(uint16_t seg, uint32_t old_pc)
|
||||
void
|
||||
loadcscall(uint16_t seg)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
uint16_t seg2;
|
||||
uint16_t newss;
|
||||
@@ -1225,7 +1182,7 @@ loadcscall(uint16_t seg)
|
||||
cpu_state.pc = oxpc;
|
||||
#endif
|
||||
cpl_override = 1;
|
||||
taskswitch286(seg, segdat, segdat[2] & 0x0800);
|
||||
op_taskswitch286(seg, segdat, segdat[2] & 0x0800);
|
||||
cpl_override = 0;
|
||||
break;
|
||||
|
||||
@@ -1251,7 +1208,11 @@ loadcscall(uint16_t seg)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
pmoderetf_2386(int is32, uint16_t off)
|
||||
#else
|
||||
pmoderetf(int is32, uint16_t off)
|
||||
#endif
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint16_t segdat2[4];
|
||||
@@ -1487,7 +1448,11 @@ pmoderetf(int is32, uint16_t off)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
pmodeint_2386(int num, int soft)
|
||||
#else
|
||||
pmodeint(int num, int soft)
|
||||
#endif
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint16_t segdat2[4];
|
||||
@@ -1518,7 +1483,7 @@ pmodeint(int num, int soft)
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
} else if (num == 0x0d)
|
||||
pmodeint(8, 0);
|
||||
op_pmodeint(8, 0);
|
||||
else
|
||||
x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft);
|
||||
x86seg_log("addr >= IDT.limit\n");
|
||||
@@ -1659,10 +1624,10 @@ pmodeint(int num, int soft)
|
||||
PUSHL(ES);
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
loadseg(0, &cpu_state.seg_ds);
|
||||
loadseg(0, &cpu_state.seg_es);
|
||||
loadseg(0, &cpu_state.seg_fs);
|
||||
loadseg(0, &cpu_state.seg_gs);
|
||||
op_loadseg(0, &cpu_state.seg_ds);
|
||||
op_loadseg(0, &cpu_state.seg_es);
|
||||
op_loadseg(0, &cpu_state.seg_fs);
|
||||
op_loadseg(0, &cpu_state.seg_gs);
|
||||
}
|
||||
PUSHL(oldss);
|
||||
PUSHL(oldsp);
|
||||
@@ -1764,7 +1729,7 @@ pmodeint(int num, int soft)
|
||||
}
|
||||
optype = OPTYPE_INT;
|
||||
cpl_override = 1;
|
||||
taskswitch286(seg, segdat2, segdat2[2] & 0x0800);
|
||||
op_taskswitch286(seg, segdat2, segdat2[2] & 0x0800);
|
||||
cpl_override = 0;
|
||||
break;
|
||||
|
||||
@@ -1775,7 +1740,11 @@ pmodeint(int num, int soft)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
pmodeiret_2386(int is32)
|
||||
#else
|
||||
pmodeiret(int is32)
|
||||
#endif
|
||||
{
|
||||
uint16_t newss;
|
||||
uint16_t seg = 0;
|
||||
@@ -1842,7 +1811,7 @@ pmodeiret(int is32)
|
||||
}
|
||||
cpl_override = 1;
|
||||
read_descriptor(addr, segdat, segdat32, 1);
|
||||
taskswitch286(seg, segdat, segdat[2] & 0x0800);
|
||||
op_taskswitch286(seg, segdat, segdat[2] & 0x0800);
|
||||
cpl_override = 0;
|
||||
return;
|
||||
}
|
||||
@@ -1876,14 +1845,14 @@ pmodeiret(int is32)
|
||||
}
|
||||
cpu_state.eflags = tempflags >> 16;
|
||||
cpu_cur_status |= CPU_STATUS_V86;
|
||||
loadseg(segs[0], &cpu_state.seg_es);
|
||||
op_loadseg(segs[0], &cpu_state.seg_es);
|
||||
do_seg_v86_init(&cpu_state.seg_es);
|
||||
loadseg(segs[1], &cpu_state.seg_ds);
|
||||
op_loadseg(segs[1], &cpu_state.seg_ds);
|
||||
do_seg_v86_init(&cpu_state.seg_ds);
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
loadseg(segs[2], &cpu_state.seg_fs);
|
||||
op_loadseg(segs[2], &cpu_state.seg_fs);
|
||||
do_seg_v86_init(&cpu_state.seg_fs);
|
||||
loadseg(segs[3], &cpu_state.seg_gs);
|
||||
op_loadseg(segs[3], &cpu_state.seg_gs);
|
||||
do_seg_v86_init(&cpu_state.seg_gs);
|
||||
|
||||
cpu_state.pc = newpc & 0xffff;
|
||||
@@ -1901,7 +1870,7 @@ pmodeiret(int is32)
|
||||
#endif
|
||||
|
||||
ESP = newsp;
|
||||
loadseg(newss, &cpu_state.seg_ss);
|
||||
op_loadseg(newss, &cpu_state.seg_ss);
|
||||
do_seg_v86_init(&cpu_state.seg_ss);
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
use32 = 0;
|
||||
@@ -2088,7 +2057,11 @@ pmodeiret(int is32)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32)
|
||||
#else
|
||||
taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
#endif
|
||||
{
|
||||
uint16_t tempw;
|
||||
uint16_t new_ldt;
|
||||
@@ -2235,7 +2208,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24);
|
||||
|
||||
if (cpu_state.eflags & VM_FLAG) {
|
||||
loadcs(new_cs);
|
||||
op_loadcs(new_cs);
|
||||
set_use32(0);
|
||||
cpu_cur_status |= CPU_STATUS_V86;
|
||||
} else {
|
||||
@@ -2299,11 +2272,11 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ESI = new_esi;
|
||||
EDI = new_edi;
|
||||
|
||||
loadseg(new_es, &cpu_state.seg_es);
|
||||
loadseg(new_ss, &cpu_state.seg_ss);
|
||||
loadseg(new_ds, &cpu_state.seg_ds);
|
||||
loadseg(new_fs, &cpu_state.seg_fs);
|
||||
loadseg(new_gs, &cpu_state.seg_gs);
|
||||
op_loadseg(new_es, &cpu_state.seg_es);
|
||||
op_loadseg(new_ss, &cpu_state.seg_ss);
|
||||
op_loadseg(new_ds, &cpu_state.seg_ds);
|
||||
op_loadseg(new_fs, &cpu_state.seg_fs);
|
||||
op_loadseg(new_gs, &cpu_state.seg_gs);
|
||||
} else {
|
||||
if (limit < 43) {
|
||||
x86ts(NULL, seg);
|
||||
@@ -2465,12 +2438,12 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ESI = new_esi | 0xffff0000;
|
||||
EDI = new_edi | 0xffff0000;
|
||||
|
||||
loadseg(new_es, &cpu_state.seg_es);
|
||||
loadseg(new_ss, &cpu_state.seg_ss);
|
||||
loadseg(new_ds, &cpu_state.seg_ds);
|
||||
op_loadseg(new_es, &cpu_state.seg_es);
|
||||
op_loadseg(new_ss, &cpu_state.seg_ss);
|
||||
op_loadseg(new_ds, &cpu_state.seg_ds);
|
||||
if (is386) {
|
||||
loadseg(0, &cpu_state.seg_fs);
|
||||
loadseg(0, &cpu_state.seg_gs);
|
||||
op_loadseg(0, &cpu_state.seg_fs);
|
||||
op_loadseg(0, &cpu_state.seg_gs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2482,7 +2455,11 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg)
|
||||
#else
|
||||
cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
#endif
|
||||
{
|
||||
uint32_t limit_raw = seg->limit;
|
||||
|
||||
@@ -2494,7 +2471,11 @@ cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
}
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg)
|
||||
#else
|
||||
cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg)
|
||||
#endif
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint16_t selector;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* x86 CPU segment emulation.
|
||||
* x86 CPU segment emulation header.
|
||||
*
|
||||
*
|
||||
*
|
||||
@@ -14,8 +14,82 @@
|
||||
*
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_X86SEG_H
|
||||
#define EMU_X86SEG_H
|
||||
|
||||
extern void do_seg_load(x86seg *s, uint16_t *segdat);
|
||||
#ifdef OPS_286_386
|
||||
|
||||
extern void x86_doabrt_2386(int x86_abrt);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
extern int loadseg_2386(uint16_t seg, x86seg *s);
|
||||
#else
|
||||
extern void loadseg_2386(uint16_t seg, x86seg *s);
|
||||
#endif
|
||||
extern void loadcs_2386(uint16_t seg);
|
||||
extern void loadcsjmp_2386(uint16_t seg, uint32_t old_pc);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
extern void loadcscall_2386(uint16_t seg, uint32_t old_pc);
|
||||
#else
|
||||
extern void loadcscall_2386(uint16_t seg);
|
||||
#endif
|
||||
extern void pmoderetf_2386(int is32, uint16_t off);
|
||||
extern void pmodeint_2386(int num, int soft);
|
||||
extern void pmodeiret_2386(int is32);
|
||||
extern void taskswitch286_2386(uint16_t seg, uint16_t *segdat, int is32);
|
||||
|
||||
/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */
|
||||
#define op_doabrt x86_doabrt_2386
|
||||
#define op_loadseg loadseg_2386
|
||||
#define op_loadcs loadcs_2386
|
||||
#define op_loadcsjmp loadcsjmp_2386
|
||||
#define op_loadcscall loadcscall_2386
|
||||
#define op_pmoderetf pmoderetf_2386
|
||||
#define op_pmodeint pmodeint_2386
|
||||
#define op_pmodeiret pmodeiret_2386
|
||||
#define op_taskswitch taskswitch_2386
|
||||
#define op_taskswitch286 taskswitch286_2386
|
||||
|
||||
#else
|
||||
|
||||
extern void x86_doabrt(int x86_abrt);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
extern int loadseg(uint16_t seg, x86seg *s);
|
||||
#else
|
||||
extern void loadseg(uint16_t seg, x86seg *s);
|
||||
#endif
|
||||
/* The prototype of loadcs_2386() is needed here for reset. */
|
||||
extern void loadcs_2386(uint16_t seg);
|
||||
extern void loadcs(uint16_t seg);
|
||||
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
extern void loadcscall(uint16_t seg, uint32_t old_pc);
|
||||
#else
|
||||
extern void loadcscall(uint16_t seg);
|
||||
#endif
|
||||
extern void pmoderetf(int is32, uint16_t off);
|
||||
/* The prototype of pmodeint_2386() is needed here for 386_common.c interrupts. */
|
||||
extern void pmodeint_2386(int num, int soft);
|
||||
extern void pmodeint(int num, int soft);
|
||||
extern void pmodeiret(int is32);
|
||||
extern void taskswitch286(uint16_t seg, uint16_t *segdat, int is32);
|
||||
|
||||
/* #define's to avoid long #ifdef blocks in x86_ops_*.h. */
|
||||
#define op_doabrt x86_doabrt
|
||||
#define op_loadseg loadseg
|
||||
#define op_loadcs loadcs
|
||||
#define op_loadcsjmp loadcsjmp
|
||||
#define op_loadcscall loadcscall
|
||||
#define op_pmoderetf pmoderetf
|
||||
#define op_pmodeint pmodeint
|
||||
#define op_pmodeiret pmodeiret
|
||||
#define op_taskswitch286 taskswitch286
|
||||
|
||||
#endif
|
||||
|
||||
extern void cyrix_write_seg_descriptor_2386(uint32_t addr, x86seg *seg);
|
||||
extern void cyrix_load_seg_descriptor_2386(uint32_t addr, x86seg *seg);
|
||||
|
||||
extern void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
|
||||
extern void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg);
|
||||
|
||||
#endif /*EMU_X86SEG_H*/
|
||||
|
||||
22
src/cpu/x86seg_2386.c
Normal file
22
src/cpu/x86seg_2386.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* x86 CPU segment emulation for the 286/386 interpreter.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#ifndef OPS_286_386
|
||||
# define OPS_286_386
|
||||
#endif
|
||||
#include "x86seg.c"
|
||||
123
src/cpu/x86seg_common.c
Normal file
123
src/cpu/x86seg_common.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* x86 CPU segment emulation commmon parts.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86seg_common.h"
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
uint8_t opcode2;
|
||||
|
||||
int cgate16;
|
||||
int cgate32;
|
||||
|
||||
int intgatesize;
|
||||
|
||||
static void
|
||||
seg_reset(x86seg *s)
|
||||
{
|
||||
s->access = 0x82;
|
||||
s->ar_high = 0x10;
|
||||
s->limit = 0xffff;
|
||||
s->limit_low = 0;
|
||||
s->limit_high = 0xffff;
|
||||
if (s == &cpu_state.seg_cs) {
|
||||
if (!cpu_inited)
|
||||
fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n");
|
||||
if (is6117)
|
||||
s->base = 0x03ff0000;
|
||||
else
|
||||
s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0;
|
||||
s->seg = is286 ? 0xf000 : 0xffff;
|
||||
} else {
|
||||
s->base = 0;
|
||||
s->seg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
x86seg_reset(void)
|
||||
{
|
||||
seg_reset(&cpu_state.seg_cs);
|
||||
seg_reset(&cpu_state.seg_ds);
|
||||
seg_reset(&cpu_state.seg_es);
|
||||
seg_reset(&cpu_state.seg_fs);
|
||||
seg_reset(&cpu_state.seg_gs);
|
||||
seg_reset(&cpu_state.seg_ss);
|
||||
}
|
||||
|
||||
void
|
||||
x86de(UNUSED(char *s), UNUSED(uint16_t error))
|
||||
{
|
||||
#ifdef BAD_CODE
|
||||
cpu_state.abrt = ABRT_DE;
|
||||
abrt_error = error;
|
||||
#else
|
||||
x86_int(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_GPF;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf_expected(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86ss(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_SS;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86ts(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_TS;
|
||||
abrt_error = error;
|
||||
}
|
||||
|
||||
void
|
||||
x86np(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
cpu_state.abrt = ABRT_NP;
|
||||
abrt_error = error;
|
||||
}
|
||||
52
src/cpu/x86seg_common.h
Normal file
52
src/cpu/x86seg_common.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* x86 CPU segment emulation common parts header.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_X86SEG_COMMON_H
|
||||
#define EMU_X86SEG_COMMON_H
|
||||
|
||||
#define JMP 1
|
||||
#define CALL 2
|
||||
#define IRET 3
|
||||
#define OPTYPE_INT 4
|
||||
|
||||
enum {
|
||||
ABRT_NONE = 0,
|
||||
ABRT_GEN = 1,
|
||||
ABRT_TS = 0xA,
|
||||
ABRT_NP = 0xB,
|
||||
ABRT_SS = 0xC,
|
||||
ABRT_GPF = 0xD,
|
||||
ABRT_PF = 0xE,
|
||||
ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */
|
||||
};
|
||||
|
||||
extern uint8_t opcode2;
|
||||
|
||||
extern int cgate16;
|
||||
extern int cgate32;
|
||||
|
||||
extern int intgatesize;
|
||||
|
||||
extern void x86seg_reset(void);
|
||||
extern void x86de(char *s, uint16_t error);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
extern void x86gpf_expected(char *s, uint16_t error);
|
||||
extern void x86np(char *s, uint16_t error);
|
||||
extern void x86ss(char *s, uint16_t error);
|
||||
extern void x86ts(char *s, uint16_t error);
|
||||
extern void do_seg_load(x86seg *s, uint16_t *segdat);
|
||||
|
||||
#endif /*EMU_X86SEG_COMMON_H*/
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86seg_common.h"
|
||||
#include "x87.h"
|
||||
#include "386_common.h"
|
||||
#include "softfloat/softfloat-specialize.h"
|
||||
|
||||
22
src/cpu/x886seg_2386.c
Normal file
22
src/cpu/x886seg_2386.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* x86 CPU segment emulation for the 286/386 interpreter.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#ifndef OPS_286_386
|
||||
# define OPS_286_386
|
||||
#endif
|
||||
#include "x86seg.c"
|
||||
26
src/device.c
26
src/device.c
@@ -731,27 +731,51 @@ device_is_valid(const device_t *device, int m)
|
||||
if (device == NULL)
|
||||
return 1;
|
||||
|
||||
if ((device->flags & DEVICE_PCJR) && !machine_has_bus(m, MACHINE_BUS_PCJR))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_XTKBC) && machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS))
|
||||
if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_HIL) && !machine_has_bus(m, MACHINE_BUS_HIL))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_OLB) && !machine_has_bus(m, MACHINE_BUS_OLB))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_USB) && !machine_has_bus(m, MACHINE_BUS_USB))
|
||||
return 0;
|
||||
|
||||
if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP))
|
||||
return 0;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86seg.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/pic.h>
|
||||
@@ -759,7 +760,7 @@ write_p2(atkbc_t *dev, uint8_t val)
|
||||
correctly despite A20 being gated when the CPU is reset, this will
|
||||
have to do. */
|
||||
else if (kbc_ven == KBC_VEN_SIEMENS)
|
||||
loadcs(0xF000);
|
||||
is486 ? loadcs(0xf000) : loadcs_2386(0xf000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
*
|
||||
* Implementation of PS/2 series Mouse devices.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2016-2023 Miran Grca.
|
||||
* Copyright 2017-2023 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -662,7 +662,7 @@ kbd_read(uint16_t port, void *priv)
|
||||
/* LaserXT = Always 512k RAM;
|
||||
LaserXT/3 = Bit 0: set = 512k, clear = 256k. */
|
||||
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
|
||||
if (kbd->type == KBD_TYPE_TOSHIBA)
|
||||
if (kbd->type == KBD_TYPE_VTECH)
|
||||
ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00);
|
||||
else
|
||||
#endif
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
*
|
||||
* Implementation of PS/2 series Mouse devices.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
*
|
||||
* TODO: Add the Genius Serial Mouse.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
@@ -193,8 +193,8 @@ sermouse_report_msystems(mouse_t *dev)
|
||||
dev->buf[0] |= (b & 0x02) ? 0x00 : 0x01; /* right button */
|
||||
dev->buf[1] = delta_x;
|
||||
dev->buf[2] = delta_y;
|
||||
dev->buf[2] = delta_x; /* same as byte 1 */
|
||||
dev->buf[3] = delta_y; /* same as byte 2 */
|
||||
dev->buf[3] = delta_x; /* same as byte 1 */
|
||||
dev->buf[4] = delta_y; /* same as byte 2 */
|
||||
|
||||
return 5;
|
||||
}
|
||||
@@ -215,8 +215,6 @@ sermouse_report_3bp(mouse_t *dev)
|
||||
dev->buf[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */
|
||||
dev->buf[1] = delta_x;
|
||||
dev->buf[2] = delta_y;
|
||||
dev->buf[2] = delta_x; /* same as byte 1 */
|
||||
dev->buf[3] = delta_y; /* same as byte 2 */
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -6,15 +6,16 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Phoenix 486 Jumper Readout
|
||||
* Implementation of the Phoenix 486 Jumper Readout.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
* Copyright 2020 Tiseno100
|
||||
* Copyright 2020-2023 Miran Grca.
|
||||
* Copyright 2020-2023 Tiseno100.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -29,13 +29,11 @@
|
||||
#include <86box/postcard.h>
|
||||
#include "cpu.h"
|
||||
|
||||
#define POSTCARDS_NUM 4
|
||||
#define POSTCARD_MASK (POSTCARDS_NUM - 1)
|
||||
uint8_t postcard_codes[POSTCARDS_NUM];
|
||||
|
||||
static uint16_t postcard_port;
|
||||
static uint8_t postcard_written[POSTCARDS_NUM];
|
||||
static uint8_t postcard_ports_num = 1;
|
||||
static uint8_t postcard_codes[POSTCARDS_NUM];
|
||||
static uint8_t postcard_prev_codes[POSTCARDS_NUM];
|
||||
#define UISTR_LEN 32
|
||||
static char postcard_str[UISTR_LEN]; /* UI output string */
|
||||
@@ -66,8 +64,10 @@ static void
|
||||
postcard_setui(void)
|
||||
{
|
||||
if (postcard_ports_num > 1) {
|
||||
char ps[2][POSTCARDS_NUM][3] = { { 0 },
|
||||
{ 0 } };
|
||||
char ps[2][POSTCARDS_NUM][3] = { { { 0 },
|
||||
{ 0 },
|
||||
} };
|
||||
|
||||
for (uint8_t i = 0; i < POSTCARDS_NUM; i++) {
|
||||
if (!postcard_written[i]) {
|
||||
snprintf(ps[0][i], sizeof(ps[0][i]), "--");
|
||||
|
||||
@@ -12,11 +12,9 @@
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
*/
|
||||
@@ -35,17 +33,20 @@
|
||||
#include <86box/pic.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/fifo.h>
|
||||
#include <86box/serial.h>
|
||||
#include <86box/mouse.h>
|
||||
|
||||
serial_port_t com_ports[SERIAL_MAX];
|
||||
|
||||
enum {
|
||||
SERIAL_INT_LSR = 1,
|
||||
SERIAL_INT_RECEIVE = 2,
|
||||
SERIAL_INT_TRANSMIT = 4,
|
||||
SERIAL_INT_MSR = 8,
|
||||
SERIAL_INT_TIMEOUT = 16
|
||||
SERIAL_INT_LSR = 1,
|
||||
SERIAL_INT_TIMEOUT = 2,
|
||||
SERIAL_INT_RECEIVE = 4,
|
||||
SERIAL_INT_TRANSMIT = 8,
|
||||
SERIAL_INT_MSR = 16,
|
||||
SERIAL_INT_RX_DMA_TC = 32,
|
||||
SERIAL_INT_TX_DMA_TC = 64
|
||||
};
|
||||
|
||||
void serial_update_ints(serial_t *dev);
|
||||
@@ -53,7 +54,7 @@ void serial_update_ints(serial_t *dev);
|
||||
static int next_inst = 0;
|
||||
static serial_device_t serial_devices[SERIAL_MAX];
|
||||
|
||||
// #define ENABLE_SERIAL_CONSOLE 1
|
||||
static void serial_xmit_d_empty_evt(void *priv);
|
||||
|
||||
#ifdef ENABLE_SERIAL_LOG
|
||||
int serial_do_log = ENABLE_SERIAL_LOG;
|
||||
@@ -76,16 +77,23 @@ serial_log(const char *fmt, ...)
|
||||
void
|
||||
serial_reset_port(serial_t *dev)
|
||||
{
|
||||
if (dev->type >= SERIAL_16550) {
|
||||
if (dev->fifo_enabled)
|
||||
fifo_reset_evt(dev->xmit_fifo);
|
||||
else
|
||||
fifo_reset(dev->xmit_fifo);
|
||||
}
|
||||
|
||||
dev->lsr = 0x60; /* Mark that both THR/FIFO and TXSR are empty. */
|
||||
dev->iir = dev->ier = dev->lcr = dev->fcr = 0;
|
||||
|
||||
dev->fifo_enabled = 0;
|
||||
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
|
||||
dev->xmit_fifo_end = dev->rcvr_fifo_end = 0;
|
||||
dev->rcvr_fifo_full = 0;
|
||||
dev->baud_cycles = 0;
|
||||
dev->out_new = 0xffff;
|
||||
memset(dev->xmit_fifo, 0, 16);
|
||||
memset(dev->rcvr_fifo, 0, 16);
|
||||
dev->baud_cycles = 0;
|
||||
dev->out_new = 0xffff;
|
||||
|
||||
dev->txsr_empty = 1;
|
||||
dev->thr_empty = 1;
|
||||
|
||||
serial_update_ints(dev);
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
@@ -112,7 +120,7 @@ serial_do_irq(serial_t *dev, int set)
|
||||
if (dev->irq != 0xff) {
|
||||
if (set || (dev->irq_state != !!set))
|
||||
picint_common(1 << dev->irq, !!(dev->type >= SERIAL_16450), set, &dev->irq_state);
|
||||
if (dev->type >= SERIAL_16450)
|
||||
if (dev->type < SERIAL_16450)
|
||||
dev->irq_state = !!set;
|
||||
}
|
||||
}
|
||||
@@ -120,33 +128,22 @@ serial_do_irq(serial_t *dev, int set)
|
||||
void
|
||||
serial_update_ints(serial_t *dev)
|
||||
{
|
||||
int stat = 0;
|
||||
/* TODO: The IRQ priorities are 6 - we need to find a way to treat timeout and receive
|
||||
as equal and still somehow distinguish them. */
|
||||
uint8_t ier_map[7] = { 0x04, 0x01, 0x01, 0x02, 0x08, 0x40, 0x80 };
|
||||
uint8_t iir_map[7] = { 0x06, 0x0c, 0x04, 0x02, 0x00, 0x0e, 0x0a };
|
||||
int i;
|
||||
|
||||
dev->iir = 1;
|
||||
dev->iir = (dev->iir & 0xf0) | 0x01;
|
||||
|
||||
if ((dev->ier & 4) && (dev->int_status & SERIAL_INT_LSR)) {
|
||||
/* Line status interrupt */
|
||||
stat = 1;
|
||||
dev->iir = 6;
|
||||
} else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_TIMEOUT)) {
|
||||
/* Received data available */
|
||||
stat = 1;
|
||||
dev->iir = 0x0c;
|
||||
} else if ((dev->ier & 1) && (dev->int_status & SERIAL_INT_RECEIVE)) {
|
||||
/* Received data available */
|
||||
stat = 1;
|
||||
dev->iir = 4;
|
||||
} else if ((dev->ier & 2) && (dev->int_status & SERIAL_INT_TRANSMIT)) {
|
||||
/* Transmit data empty */
|
||||
stat = 1;
|
||||
dev->iir = 2;
|
||||
} else if ((dev->ier & 8) && (dev->int_status & SERIAL_INT_MSR)) {
|
||||
/* Modem status interrupt */
|
||||
stat = 1;
|
||||
dev->iir = 0;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((dev->ier & ier_map[i]) && (dev->int_status & (1 << i))) {
|
||||
dev->iir = (dev->iir & 0xf0) | iir_map[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
serial_do_irq(dev, stat && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR)));
|
||||
serial_do_irq(dev, !(dev->iir & 0x01) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -163,60 +160,46 @@ serial_receive_timer(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
#if 0
|
||||
serial_log("serial_receive_timer()\n");
|
||||
#endif
|
||||
|
||||
timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period);
|
||||
|
||||
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
|
||||
if (dev->fifo_enabled) {
|
||||
/* FIFO mode. */
|
||||
|
||||
if (dev->out_new != 0xffff) {
|
||||
/* We have received a byte into the RSR. */
|
||||
|
||||
/* Clear FIFO timeout. */
|
||||
serial_clear_timeout(dev);
|
||||
|
||||
if (dev->rcvr_fifo_full) {
|
||||
/* Overrun - just discard the byte in the RSR. */
|
||||
serial_log("FIFO overrun\n");
|
||||
fifo_write_evt((uint8_t) (dev->out_new & 0xff), dev->rcvr_fifo);
|
||||
dev->out_new = 0xffff;
|
||||
|
||||
/* pclog("serial_receive_timer(): lsr = %02X, ier = %02X, iir = %02X, int_status = %02X\n",
|
||||
dev->lsr, dev->ier, dev->iir, dev->int_status); */
|
||||
|
||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
}
|
||||
} else {
|
||||
/* Non-FIFO mode. */
|
||||
if (dev->out_new != 0xffff) {
|
||||
/* We have received a byte into the RSR. */
|
||||
serial_log("Byte received: %04X\n", dev->out_new);
|
||||
|
||||
/* Indicate overrun. */
|
||||
if (dev->lsr & 0x01)
|
||||
dev->lsr |= 0x02;
|
||||
} else {
|
||||
/* We can input data into the FIFO. */
|
||||
dev->rcvr_fifo[dev->rcvr_fifo_end] = (uint8_t) (dev->out_new & 0xff);
|
||||
#if 0
|
||||
dev->rcvr_fifo_end = (dev->rcvr_fifo_end + 1) & 0x0f;
|
||||
#endif
|
||||
/* Do not wrap around, makes sure it still triggers the interrupt
|
||||
at 16 bytes. */
|
||||
dev->rcvr_fifo_end++;
|
||||
|
||||
serial_log("To FIFO: %02X (%i, %i, %i)\n", (uint8_t) (dev->out_new & 0xff),
|
||||
abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos),
|
||||
dev->rcvr_fifo_end, dev->rcvr_fifo_pos);
|
||||
dev->out_new = 0xffff;
|
||||
dev->dat = (uint8_t) (dev->out_new & 0xff);
|
||||
dev->out_new = 0xffff;
|
||||
|
||||
if (abs(dev->rcvr_fifo_end - dev->rcvr_fifo_pos) >= dev->rcvr_fifo_len) {
|
||||
/* We have >= trigger level bytes, raise Data Ready interrupt. */
|
||||
serial_log("We have >= %i bytes in the FIFO, data ready!\n", dev->rcvr_fifo_len);
|
||||
dev->lsr |= 0x01;
|
||||
dev->int_status |= SERIAL_INT_RECEIVE;
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
/* Raise Data Ready interrupt. */
|
||||
dev->lsr |= 0x01;
|
||||
dev->int_status |= SERIAL_INT_RECEIVE;
|
||||
|
||||
/* Now wrap around. */
|
||||
dev->rcvr_fifo_end &= 0x0f;
|
||||
|
||||
if (dev->rcvr_fifo_end == dev->rcvr_fifo_pos)
|
||||
dev->rcvr_fifo_full = 1;
|
||||
|
||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
}
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
}
|
||||
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -224,26 +207,8 @@ write_fifo(serial_t *dev, uint8_t dat)
|
||||
{
|
||||
serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat,
|
||||
(dev->type >= SERIAL_16550) && dev->fifo_enabled,
|
||||
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? (dev->rcvr_fifo_pos % dev->rcvr_fifo_len) : 0);
|
||||
|
||||
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
|
||||
/* FIFO mode. */
|
||||
|
||||
/* This is the first phase, we are sending the data to the RSR (Receiver Shift
|
||||
Register), from where it's going to get dispatched to the FIFO. */
|
||||
} else {
|
||||
/* Non-FIFO mode. */
|
||||
|
||||
/* Indicate overrun. */
|
||||
if (dev->lsr & 0x01)
|
||||
dev->lsr |= 0x02;
|
||||
|
||||
/* Raise Data Ready interrupt. */
|
||||
serial_log("To RHR: %02X\n", dat);
|
||||
dev->lsr |= 0x01;
|
||||
dev->int_status |= SERIAL_INT_RECEIVE;
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
|
||||
fifo_get_count(dev->rcvr_fifo) : 0);
|
||||
|
||||
/* Do this here, because in non-FIFO mode, this is read directly. */
|
||||
dev->out_new = (uint16_t) dat;
|
||||
@@ -252,7 +217,10 @@ write_fifo(serial_t *dev, uint8_t dat)
|
||||
void
|
||||
serial_write_fifo(serial_t *dev, uint8_t dat)
|
||||
{
|
||||
serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f);
|
||||
serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat,
|
||||
(dev->type >= SERIAL_16550) && dev->fifo_enabled,
|
||||
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
|
||||
fifo_get_count(dev->rcvr_fifo) : 0);
|
||||
|
||||
if (!(dev->mctrl & 0x10))
|
||||
write_fifo(dev, dat);
|
||||
@@ -265,48 +233,43 @@ serial_transmit(serial_t *dev, uint8_t val)
|
||||
write_fifo(dev, val);
|
||||
else if (dev->sd->dev_write)
|
||||
dev->sd->dev_write(dev, dev->sd->priv, val);
|
||||
|
||||
#ifdef ENABLE_SERIAL_CONSOLE
|
||||
if ((val >= ' ' && val <= '~') || val == '\r' || val == '\n') {
|
||||
fputc(val, stdout);
|
||||
if (val == '\n')
|
||||
fflush(stdout);
|
||||
} else {
|
||||
} else
|
||||
fprintf(stdout, "[%02X]", val);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
serial_move_to_txsr(serial_t *dev)
|
||||
{
|
||||
if (dev->fifo_enabled) {
|
||||
dev->txsr = dev->xmit_fifo[0];
|
||||
if (dev->xmit_fifo_pos > 0) {
|
||||
/* Move the entire fifo forward by one byte. */
|
||||
for (uint8_t i = 1; i < 16; i++)
|
||||
dev->xmit_fifo[i - 1] = dev->xmit_fifo[i];
|
||||
/* Decrease FIFO position. */
|
||||
dev->xmit_fifo_pos--;
|
||||
}
|
||||
} else {
|
||||
dev->txsr_empty = 0;
|
||||
if (dev->fifo_enabled)
|
||||
dev->txsr = fifo_read_evt(dev->xmit_fifo);
|
||||
else {
|
||||
dev->txsr = dev->thr;
|
||||
dev->thr = 0;
|
||||
dev->thr_empty = 1;
|
||||
serial_xmit_d_empty_evt(dev);
|
||||
}
|
||||
|
||||
dev->lsr &= ~0x40;
|
||||
serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis", dev->xmit_fifo_pos & 0x0f);
|
||||
serial_log("serial_move_to_txsr(): FIFO %sabled, FIFO pos = %i\n", dev->fifo_enabled ? "en" : "dis",
|
||||
fifo_get_count(dev->xmit_fifo) & 0x0f);
|
||||
|
||||
if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0)) {
|
||||
if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0)) {
|
||||
/* Update interrupts to signal THRE and that TXSR is no longer empty. */
|
||||
dev->lsr |= 0x20;
|
||||
dev->int_status |= SERIAL_INT_TRANSMIT;
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
if (dev->transmit_enabled & 2)
|
||||
dev->baud_cycles++;
|
||||
else
|
||||
dev->baud_cycles = 0; /* If not moving while transmitting, reset BAUDOUT cycle count. */
|
||||
if (!dev->fifo_enabled || (dev->xmit_fifo_pos == 0x0))
|
||||
if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0))
|
||||
dev->transmit_enabled &= ~1; /* Stop moving. */
|
||||
dev->transmit_enabled |= 2; /* Start transmitting. */
|
||||
}
|
||||
@@ -317,20 +280,18 @@ serial_process_txsr(serial_t *dev)
|
||||
serial_log("serial_process_txsr(): FIFO %sabled\n", dev->fifo_enabled ? "en" : "dis");
|
||||
serial_transmit(dev, dev->txsr);
|
||||
dev->txsr = 0;
|
||||
dev->txsr_empty = 1;
|
||||
serial_xmit_d_empty_evt(dev);
|
||||
/* Reset BAUDOUT cycle count. */
|
||||
dev->baud_cycles = 0;
|
||||
/* If FIFO is enabled and there are bytes left to transmit,
|
||||
continue with the FIFO, otherwise stop. */
|
||||
if (dev->fifo_enabled && (dev->xmit_fifo_pos != 0x0))
|
||||
if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) != 0x0))
|
||||
dev->transmit_enabled |= 1;
|
||||
else {
|
||||
/* Both FIFO/THR and TXSR are empty. */
|
||||
/* If bit 5 is set, also set bit 6 to mark both THR and shift register as empty. */
|
||||
if (dev->lsr & 0x20)
|
||||
dev->lsr |= 0x40;
|
||||
/* Both FIFO/THR and TXSR are empty. */
|
||||
else
|
||||
dev->transmit_enabled &= ~2;
|
||||
}
|
||||
dev->int_status &= ~SERIAL_INT_TRANSMIT;
|
||||
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
|
||||
@@ -370,9 +331,7 @@ serial_timeout_timer(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
#ifdef ENABLE_SERIAL_LOG
|
||||
serial_log("serial_timeout_timer()\n");
|
||||
#endif
|
||||
|
||||
dev->lsr |= 0x01;
|
||||
dev->int_status |= SERIAL_INT_TIMEOUT;
|
||||
@@ -384,9 +343,7 @@ serial_device_timeout(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
#ifdef ENABLE_SERIAL_LOG
|
||||
serial_log("serial_device_timeout()\n");
|
||||
#endif
|
||||
|
||||
if (!dev->fifo_enabled) {
|
||||
dev->lsr |= 0x10;
|
||||
@@ -398,23 +355,23 @@ serial_device_timeout(void *priv)
|
||||
static void
|
||||
serial_update_speed(serial_t *dev)
|
||||
{
|
||||
serial_log("serial_update_speed(%lf)\n", dev->transmit_period);
|
||||
timer_on_auto(&dev->receive_timer, /* dev->bits * */ dev->transmit_period);
|
||||
|
||||
if (dev->transmit_enabled & 3)
|
||||
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
|
||||
|
||||
if (timer_is_enabled(&dev->timeout_timer))
|
||||
if (timer_is_on(&dev->timeout_timer))
|
||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_reset_fifo(serial_t *dev)
|
||||
{
|
||||
dev->lsr = (dev->lsr & 0xfe) | 0x60;
|
||||
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) | SERIAL_INT_TRANSMIT;
|
||||
fifo_reset_evt(dev->xmit_fifo);
|
||||
fifo_reset_evt(dev->rcvr_fifo);
|
||||
|
||||
serial_update_ints(dev);
|
||||
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
|
||||
dev->rcvr_fifo_full = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -490,7 +447,6 @@ serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
uint8_t new_msr;
|
||||
uint8_t old;
|
||||
|
||||
// serial_log("UART: Write %02X to port %02X\n", val, addr);
|
||||
serial_log("UART: [%04X:%08X] Write %02X to port %02X\n", CS, cpu_state.pc, val, addr);
|
||||
|
||||
cycles -= ISA_CYCLES(8);
|
||||
@@ -504,21 +460,22 @@ serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Indicate FIFO/THR is no longer empty. */
|
||||
dev->lsr &= 0x9f;
|
||||
dev->int_status &= ~SERIAL_INT_TRANSMIT;
|
||||
serial_update_ints(dev);
|
||||
|
||||
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled && (dev->xmit_fifo_pos < 16)) {
|
||||
if (dev->fifo_enabled && (fifo_get_count(dev->xmit_fifo) < 16)) {
|
||||
/* FIFO mode, begin transmitting. */
|
||||
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
|
||||
dev->transmit_enabled |= 1; /* Start moving. */
|
||||
dev->xmit_fifo[dev->xmit_fifo_pos++] = val;
|
||||
} else {
|
||||
fifo_write_evt(val, dev->xmit_fifo);
|
||||
} else if (!dev->fifo_enabled) {
|
||||
/* Indicate THR is no longer empty. */
|
||||
dev->lsr &= 0x9f;
|
||||
dev->int_status &= ~SERIAL_INT_TRANSMIT;
|
||||
serial_update_ints(dev);
|
||||
|
||||
/* Non-FIFO mode, begin transmitting. */
|
||||
timer_on_auto(&dev->transmit_timer, dev->transmit_period);
|
||||
dev->transmit_enabled |= 1; /* Start moving. */
|
||||
dev->thr = val;
|
||||
dev->thr_empty = 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
@@ -539,42 +496,42 @@ serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
serial_reset_fifo(dev);
|
||||
dev->fcr = val & 0xf9;
|
||||
dev->fifo_enabled = val & 0x01;
|
||||
/* TODO: When switching modes, shouldn't we reset the LSR
|
||||
based on the new conditions? */
|
||||
if (!dev->fifo_enabled) {
|
||||
memset(dev->rcvr_fifo, 0, 14);
|
||||
memset(dev->xmit_fifo, 0, 16);
|
||||
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
|
||||
dev->rcvr_fifo_full = 0;
|
||||
dev->rcvr_fifo_len = 1;
|
||||
fifo_reset(dev->xmit_fifo);
|
||||
fifo_reset(dev->rcvr_fifo);
|
||||
break;
|
||||
}
|
||||
if (val & 0x02) {
|
||||
memset(dev->rcvr_fifo, 0, 14);
|
||||
dev->rcvr_fifo_pos = 0;
|
||||
dev->rcvr_fifo_end = 0;
|
||||
dev->rcvr_fifo_full = 0;
|
||||
if (dev->fifo_enabled)
|
||||
fifo_reset_evt(dev->rcvr_fifo);
|
||||
else
|
||||
fifo_reset(dev->rcvr_fifo);
|
||||
}
|
||||
if (val & 0x04) {
|
||||
memset(dev->xmit_fifo, 0, 16);
|
||||
dev->xmit_fifo_pos = 0;
|
||||
if (dev->fifo_enabled)
|
||||
fifo_reset_evt(dev->xmit_fifo);
|
||||
else
|
||||
fifo_reset(dev->xmit_fifo);
|
||||
}
|
||||
switch ((val >> 6) & 0x03) {
|
||||
case 0:
|
||||
dev->rcvr_fifo_len = 1;
|
||||
fifo_set_trigger_len(dev->rcvr_fifo, 1);
|
||||
break;
|
||||
case 1:
|
||||
dev->rcvr_fifo_len = 4;
|
||||
fifo_set_trigger_len(dev->rcvr_fifo, 4);
|
||||
break;
|
||||
case 2:
|
||||
dev->rcvr_fifo_len = 8;
|
||||
fifo_set_trigger_len(dev->rcvr_fifo, 8);
|
||||
break;
|
||||
case 3:
|
||||
dev->rcvr_fifo_len = 14;
|
||||
break;
|
||||
default:
|
||||
fifo_set_trigger_len(dev->rcvr_fifo, 14);
|
||||
break;
|
||||
}
|
||||
fifo_set_trigger_len(dev->xmit_fifo, 16);
|
||||
dev->out_new = 0xffff;
|
||||
serial_log("FIFO now %sabled, receive FIFO length = %i\n", dev->fifo_enabled ? "en" : "dis", dev->rcvr_fifo_len);
|
||||
serial_log("FIFO now %sabled\n", dev->fifo_enabled ? "en" : "dis");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -600,8 +557,10 @@ serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
break;
|
||||
case 4:
|
||||
if ((val & 2) && !(dev->mctrl & 2)) {
|
||||
if (dev->sd && dev->sd->rcr_callback)
|
||||
if (dev->sd && dev->sd->rcr_callback) {
|
||||
serial_log("RTS toggle callback\n");
|
||||
dev->sd->rcr_callback(dev, dev->sd->priv);
|
||||
}
|
||||
}
|
||||
if (!(val & 8) && (dev->mctrl & 8))
|
||||
serial_do_irq(dev, 0);
|
||||
@@ -624,8 +583,9 @@ serial_write(uint16_t addr, uint8_t val, void *p)
|
||||
|
||||
dev->msr = new_msr;
|
||||
|
||||
dev->xmit_fifo_pos = dev->rcvr_fifo_pos = 0;
|
||||
dev->rcvr_fifo_full = 0;
|
||||
/* TODO: Why reset the FIFO's here?! */
|
||||
fifo_reset(dev->xmit_fifo);
|
||||
fifo_reset(dev->rcvr_fifo);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
@@ -674,41 +634,16 @@ serial_read(uint16_t addr, void *p)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear timeout. */
|
||||
serial_clear_timeout(dev);
|
||||
|
||||
if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) {
|
||||
if (dev->fifo_enabled) {
|
||||
/* FIFO mode. */
|
||||
serial_clear_timeout(dev);
|
||||
ret = fifo_read_evt(dev->rcvr_fifo);
|
||||
|
||||
if (dev->rcvr_fifo_full || (dev->rcvr_fifo_pos != dev->rcvr_fifo_end)) {
|
||||
/* There is data in the FIFO. */
|
||||
ret = dev->rcvr_fifo[dev->rcvr_fifo_pos];
|
||||
dev->rcvr_fifo_pos = (dev->rcvr_fifo_pos + 1) & 0x0f;
|
||||
|
||||
/* Make sure to clear the FIFO full condition. */
|
||||
dev->rcvr_fifo_full = 0;
|
||||
|
||||
if (abs(dev->rcvr_fifo_pos - dev->rcvr_fifo_end) < dev->rcvr_fifo_len) {
|
||||
/* Amount of data in the FIFO below trigger level,
|
||||
clear Data Ready interrupt. */
|
||||
dev->int_status &= ~SERIAL_INT_RECEIVE;
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
|
||||
/* Make sure the Data Ready bit of the LSR is set if we still have
|
||||
bytes left in the FIFO. */
|
||||
if (dev->rcvr_fifo_pos != dev->rcvr_fifo_end) {
|
||||
dev->lsr |= 0x01;
|
||||
/* There are bytes left in the FIFO, activate the FIFO Timeout timer. */
|
||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
} else
|
||||
dev->lsr &= 0xfe;
|
||||
}
|
||||
if (dev->lsr & 0x01)
|
||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
} else {
|
||||
/* Non-FIFO mode. */
|
||||
|
||||
ret = (uint8_t) (dev->out_new & 0xffff);
|
||||
dev->out_new = 0xffff;
|
||||
ret = dev->dat;
|
||||
|
||||
/* Always clear Data Ready interrupt. */
|
||||
dev->lsr &= 0xfe;
|
||||
@@ -716,7 +651,7 @@ serial_read(uint16_t addr, void *p)
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
|
||||
// serial_log("Read data: %02X\n", ret);
|
||||
serial_log("Read data: %02X\n", ret);
|
||||
break;
|
||||
case 1:
|
||||
if (dev->lcr & 0x80)
|
||||
@@ -759,7 +694,6 @@ serial_read(uint16_t addr, void *p)
|
||||
break;
|
||||
}
|
||||
|
||||
// serial_log("UART: Read %02X from port %02X\n", ret, addr);
|
||||
serial_log("UART: [%04X:%08X] Read %02X from port %02X\n", CS, cpu_state.pc, ret, addr);
|
||||
return ret;
|
||||
}
|
||||
@@ -801,6 +735,42 @@ serial_setup(serial_t *dev, uint16_t addr, uint8_t irq)
|
||||
dev->irq = irq;
|
||||
}
|
||||
|
||||
static void
|
||||
serial_rcvr_d_empty_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
dev->lsr = (dev->lsr & 0xfe) | (fifo_get_empty(dev->rcvr_fifo) ? 0 : 1);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_rcvr_d_overrun_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_rcvr_d_ready_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
|
||||
(fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0);
|
||||
serial_update_ints(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_xmit_d_empty_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
uint8_t is_empty = dev->fifo_enabled ? fifo_get_empty(dev->xmit_fifo) : dev->thr_empty;
|
||||
|
||||
dev->lsr = (dev->lsr & 0x9f) | (is_empty << 5) | ((dev->txsr_empty && is_empty) << 6);
|
||||
dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) | (is_empty ? SERIAL_INT_TRANSMIT : 0);
|
||||
}
|
||||
|
||||
serial_t *
|
||||
serial_attach_ex(int port,
|
||||
void (*rcr_callback)(struct serial_s *serial, void *p),
|
||||
@@ -835,6 +805,9 @@ serial_close(void *priv)
|
||||
|
||||
next_inst--;
|
||||
|
||||
if (com_ports[dev->inst].enabled)
|
||||
fifo_close(dev->rcvr_fifo);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -843,27 +816,33 @@ serial_reset(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
timer_disable(&dev->transmit_timer);
|
||||
timer_disable(&dev->timeout_timer);
|
||||
timer_disable(&dev->receive_timer);
|
||||
if (com_ports[dev->inst].enabled) {
|
||||
timer_disable(&dev->transmit_timer);
|
||||
timer_disable(&dev->timeout_timer);
|
||||
timer_disable(&dev->receive_timer);
|
||||
|
||||
dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00;
|
||||
dev->iir = dev->ier = dev->lcr = dev->msr = 0x00;
|
||||
dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00;
|
||||
dev->fifo_enabled = dev->rcvr_fifo_len = dev->bits = dev->data_bits = 0x00;
|
||||
dev->baud_cycles = dev->rcvr_fifo_full = dev->txsr = dev->out = 0x00;
|
||||
dev->lsr = dev->thr = dev->mctrl = dev->rcr = 0x00;
|
||||
dev->iir = dev->ier = dev->lcr = dev->msr = 0x00;
|
||||
dev->dat = dev->int_status = dev->scratch = dev->fcr = 0x00;
|
||||
dev->fifo_enabled = dev->bits = 0x000;
|
||||
dev->data_bits = dev->baud_cycles = 0x00;
|
||||
dev->txsr = 0x00;
|
||||
dev->txsr_empty = 0x01;
|
||||
dev->thr_empty = 0x0001;
|
||||
|
||||
dev->dlab = dev->out_new = 0x0000;
|
||||
dev->dlab = dev->out_new = 0x0000;
|
||||
|
||||
dev->rcvr_fifo_pos = dev->xmit_fifo_pos = dev->rcvr_fifo_end = dev->xmit_fifo_end = 0x00;
|
||||
if (dev->rcvr_fifo != NULL)
|
||||
fifo_reset(dev->rcvr_fifo);
|
||||
|
||||
serial_reset_port(dev);
|
||||
serial_reset_port(dev);
|
||||
|
||||
dev->dlab = 96;
|
||||
dev->fcr = 0x06;
|
||||
dev->dlab = 96;
|
||||
dev->fcr = 0x06;
|
||||
|
||||
serial_transmit_period(dev);
|
||||
serial_update_speed(dev);
|
||||
serial_transmit_period(dev);
|
||||
serial_update_speed(dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
@@ -880,7 +859,6 @@ serial_init(const device_t *info)
|
||||
memset(&(serial_devices[next_inst]), 0, sizeof(serial_device_t));
|
||||
dev->sd = &(serial_devices[next_inst]);
|
||||
dev->sd->serial = dev;
|
||||
serial_reset_port(dev);
|
||||
if (next_inst == 3)
|
||||
serial_setup(dev, COM4_ADDR, COM4_IRQ);
|
||||
else if (next_inst == 2)
|
||||
@@ -902,6 +880,22 @@ serial_init(const device_t *info)
|
||||
timer_add(&dev->receive_timer, serial_receive_timer, dev, 0);
|
||||
serial_transmit_period(dev);
|
||||
serial_update_speed(dev);
|
||||
|
||||
dev->rcvr_fifo = fifo64_init();
|
||||
fifo_set_priv(dev->rcvr_fifo, dev);
|
||||
fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt);
|
||||
fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt);
|
||||
fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt);
|
||||
fifo_reset_evt(dev->rcvr_fifo);
|
||||
fifo_set_len(dev->rcvr_fifo, 16);
|
||||
|
||||
dev->xmit_fifo = fifo64_init();
|
||||
fifo_set_priv(dev->xmit_fifo, dev);
|
||||
fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt);
|
||||
fifo_reset_evt(dev->xmit_fifo);
|
||||
fifo_set_len(dev->xmit_fifo, 16);
|
||||
|
||||
serial_reset_port(dev);
|
||||
}
|
||||
|
||||
next_inst++;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/fifo.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/serial.h>
|
||||
#include <86box/serial_passthrough.h>
|
||||
@@ -78,7 +79,7 @@ host_to_serial_cb(void *priv)
|
||||
* can never fetch the bytes in time, so check if the fifo is full if in
|
||||
* fifo mode or if lsr has bit 0 set if not in fifo mode */
|
||||
if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) {
|
||||
if (dev->serial->rcvr_fifo_full) {
|
||||
if (fifo_get_full(dev->serial->rcvr_fifo)) {
|
||||
goto no_write_to_machine;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1939,7 +1939,7 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch)
|
||||
if ((ide->type == IDE_NONE) && ((ide_other->type == IDE_NONE) || !(ch & 1)))
|
||||
return 0x7f; /* Bit 7 pulled down, all other bits pulled up, per the spec. */
|
||||
else if ((ide->type == IDE_NONE) && (ch & 1))
|
||||
return 0x00; /* On real hardware, a slave with a present master always returns a status of 0x00. */
|
||||
return 0x7f /*0x00*/; /* On real hardware, a slave with a present master always returns a status of 0x00. */
|
||||
else if (ide->type == IDE_ATAPI)
|
||||
return (ide->sc->status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0);
|
||||
else
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdd.h>
|
||||
|
||||
#define HDC_TIME (50 * TIMER_USEC)
|
||||
#define HDC_TIME (250 * TIMER_USEC)
|
||||
|
||||
#define WD_REV_1_BIOS_FILE "roms/hdd/xta/idexywd2.bin"
|
||||
#define WD_REV_2_BIOS_FILE "roms/hdd/xta/infowdbios.rom"
|
||||
@@ -248,7 +248,6 @@ typedef struct hdc_t {
|
||||
uint8_t sense; /* current SENSE ERROR value */
|
||||
uint8_t status; /* current operational status */
|
||||
uint8_t intr;
|
||||
uint64_t callback;
|
||||
pc_timer_t timer;
|
||||
|
||||
/* Data transfer. */
|
||||
@@ -343,22 +342,6 @@ next_sector(hdc_t *dev, drive_t *drive)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xta_set_callback(hdc_t *dev, uint64_t callback)
|
||||
{
|
||||
if (!dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
dev->callback = callback;
|
||||
timer_set_delay_u64(&dev->timer, dev->callback);
|
||||
} else {
|
||||
dev->callback = 0;
|
||||
timer_disable(&dev->timer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the seek operation. */
|
||||
static void
|
||||
do_seek(hdc_t *dev, drive_t *drive, int cyl)
|
||||
@@ -457,9 +440,6 @@ hdc_callback(void *priv)
|
||||
int no_data = 0;
|
||||
int val;
|
||||
|
||||
/* Cancel timer. */
|
||||
xta_set_callback(dev, 0);
|
||||
|
||||
drive = &dev->drives[dcb->drvsel];
|
||||
dev->comp = (dcb->drvsel) ? COMP_DRIVE : 0x00;
|
||||
dev->status |= STAT_DCB;
|
||||
@@ -558,12 +538,12 @@ do_send:
|
||||
dev->buf_idx = 0;
|
||||
if (no_data) {
|
||||
/* Delay a bit, no actual transfer. */
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
} else {
|
||||
if (dev->intr & DMA_ENA) {
|
||||
/* DMA enabled. */
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
} else {
|
||||
/* Copy from sector to data. */
|
||||
memcpy(dev->data,
|
||||
@@ -586,14 +566,14 @@ do_send:
|
||||
xta_log("%s: CMD_READ_SECTORS out of data (idx=%d, len=%d)!\n", dev->name, dev->buf_idx, dev->buf_len);
|
||||
|
||||
dev->status |= (STAT_CD | STAT_IO | STAT_REQ);
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
return;
|
||||
}
|
||||
dev->buf_ptr++;
|
||||
dev->buf_idx++;
|
||||
}
|
||||
}
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
dev->state = STATE_SDONE;
|
||||
break;
|
||||
|
||||
@@ -654,7 +634,7 @@ do_recv:
|
||||
if (dev->intr & DMA_ENA) {
|
||||
/* DMA enabled. */
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
} else {
|
||||
/* No DMA, do PIO. */
|
||||
dev->buf_ptr = dev->data;
|
||||
@@ -673,7 +653,7 @@ do_recv:
|
||||
|
||||
xta_log("%s: CMD_WRITE_SECTORS out of data!\n", dev->name);
|
||||
dev->status |= (STAT_CD | STAT_IO | STAT_REQ);
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -681,7 +661,7 @@ do_recv:
|
||||
dev->buf_idx++;
|
||||
}
|
||||
dev->state = STATE_RDONE;
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -785,7 +765,7 @@ do_recv:
|
||||
dev->state = STATE_RDATA;
|
||||
if (dev->intr & DMA_ENA) {
|
||||
dev->buf_ptr = dev->sector_buf;
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
} else {
|
||||
dev->buf_ptr = dev->data;
|
||||
dev->status |= STAT_REQ;
|
||||
@@ -800,7 +780,7 @@ do_recv:
|
||||
if (val == DMA_NODATA) {
|
||||
xta_log("%s: CMD_WRITE_BUFFER out of data!\n", dev->name);
|
||||
dev->status |= (STAT_CD | STAT_IO | STAT_REQ);
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -808,7 +788,7 @@ do_recv:
|
||||
dev->buf_idx++;
|
||||
}
|
||||
dev->state = STATE_RDONE;
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, HDC_TIME);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -828,7 +808,7 @@ do_recv:
|
||||
switch (dev->state) {
|
||||
case STATE_IDLE:
|
||||
dev->state = STATE_RDONE;
|
||||
xta_set_callback(dev, 5 * HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, 5 * HDC_TIME);
|
||||
break;
|
||||
|
||||
case STATE_RDONE:
|
||||
@@ -845,7 +825,7 @@ do_recv:
|
||||
case STATE_IDLE:
|
||||
if (drive->present) {
|
||||
dev->state = STATE_RDONE;
|
||||
xta_set_callback(dev, 5 * HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, 5 * HDC_TIME);
|
||||
} else {
|
||||
dev->comp |= COMP_ERR;
|
||||
dev->sense = ERR_NOTRDY;
|
||||
@@ -866,7 +846,7 @@ do_recv:
|
||||
switch (dev->state) {
|
||||
case STATE_IDLE:
|
||||
dev->state = STATE_RDONE;
|
||||
xta_set_callback(dev, 10 * HDC_TIME);
|
||||
timer_advance_u64(&dev->timer, 10 * HDC_TIME);
|
||||
break;
|
||||
|
||||
case STATE_RDONE:
|
||||
@@ -911,7 +891,7 @@ hdc_read(uint16_t port, void *priv)
|
||||
/* All data sent. */
|
||||
dev->status &= ~STAT_REQ;
|
||||
dev->state = STATE_SDONE;
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_set_delay_u64(&dev->timer, HDC_TIME);
|
||||
}
|
||||
} else if (dev->state == STATE_COMPL) {
|
||||
xta_log("DCB=%02X status=%02X comp=%02X\n", dev->dcb.cmd, dev->status, dev->comp);
|
||||
@@ -969,7 +949,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv)
|
||||
else
|
||||
dev->state = STATE_IDLE;
|
||||
dev->status &= ~STAT_CD;
|
||||
xta_set_callback(dev, HDC_TIME);
|
||||
timer_set_delay_u64(&dev->timer, HDC_TIME);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -439,14 +439,13 @@ MVHDAPI int
|
||||
mvhd_file_is_vhd(FILE* f)
|
||||
{
|
||||
uint8_t con_str[8];
|
||||
size_t res;
|
||||
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END);
|
||||
res = fread(con_str, sizeof con_str, 1, f);
|
||||
(void) !fread(con_str, sizeof con_str, 1, f);
|
||||
if (mvhd_is_conectix_str(con_str)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
582
src/fifo.c
Normal file
582
src/fifo.c
Normal file
@@ -0,0 +1,582 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* FIFO infrastructure.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2023 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef FIFO_STANDALONE
|
||||
#define fatal printf
|
||||
#define pclog_ex printf
|
||||
#define pclog printf
|
||||
#include "include/86box/fifo.h"
|
||||
#else
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/fifo.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FIFO_LOG
|
||||
int fifo_do_log = ENABLE_FIFO_LOG;
|
||||
|
||||
static void
|
||||
fifo_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (fifo_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define fifo_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
int
|
||||
fifo_get_count(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
int ret = fifo->len;
|
||||
|
||||
if (fifo->end == fifo->start)
|
||||
ret = fifo->full ? fifo->len : 0;
|
||||
else
|
||||
ret = abs(fifo->end - fifo->start);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_write(uint8_t val, void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->d_full = fifo->d_empty = 0;
|
||||
fifo->d_ready = fifo->d_overrun = 0;
|
||||
|
||||
if (fifo->full)
|
||||
fifo->overrun = 1;
|
||||
else {
|
||||
fifo->buf[fifo->end] = val;
|
||||
fifo->end = (fifo->end + 1) & 0x0f;
|
||||
|
||||
if (fifo->end == fifo->start)
|
||||
fifo->full = 1;
|
||||
|
||||
fifo->empty = 0;
|
||||
|
||||
if (fifo_get_count(fifo) >= fifo->trigger_len)
|
||||
fifo->ready = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fifo_write_evt(uint8_t val, void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->d_full = fifo->d_empty = 0;
|
||||
fifo->d_ready = fifo->d_overrun = 0;
|
||||
|
||||
if (fifo->full) {
|
||||
fifo->d_overrun = (fifo->overrun != 1);
|
||||
fifo->overrun = 1;
|
||||
if (fifo->d_overrun && (fifo->d_overrun_evt != NULL))
|
||||
fifo->d_overrun_evt(fifo->priv);
|
||||
} else {
|
||||
fifo->buf[fifo->end] = val;
|
||||
fifo->end = (fifo->end + 1) & 0x0f;
|
||||
|
||||
if (fifo->end == fifo->start) {
|
||||
fifo->d_full = (fifo->full != 1);
|
||||
fifo->full = 1;
|
||||
if (fifo->d_full && (fifo->d_full_evt != NULL))
|
||||
fifo->d_full_evt(fifo->priv);
|
||||
}
|
||||
|
||||
fifo->d_empty = (fifo->empty != 0);
|
||||
fifo->empty = 0;
|
||||
if (fifo->d_empty && (fifo->d_empty_evt != NULL))
|
||||
fifo->d_empty_evt(fifo->priv);
|
||||
|
||||
if (fifo_get_count(fifo) >= fifo->trigger_len) {
|
||||
fifo->d_ready = (fifo->ready != 1);
|
||||
fifo->ready = 1;
|
||||
if (fifo->d_ready && (fifo->d_ready_evt != NULL))
|
||||
fifo->d_ready_evt(fifo->priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
fifo_read(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
uint8_t ret = 0x00;
|
||||
int count;
|
||||
|
||||
if (!fifo->empty) {
|
||||
ret = fifo->buf[fifo->start];
|
||||
fifo->start = (fifo->start + 1) & 0x0f;
|
||||
|
||||
fifo->full = 0;
|
||||
|
||||
count = fifo_get_count(fifo);
|
||||
|
||||
if (count < fifo->trigger_len) {
|
||||
fifo->ready = 0;
|
||||
|
||||
if (count == 0)
|
||||
fifo->empty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
fifo_read_evt(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
uint8_t ret = 0x00;
|
||||
int count;
|
||||
|
||||
fifo->d_full = fifo->d_empty = 0;
|
||||
fifo->d_ready = 0;
|
||||
|
||||
if (!fifo->empty) {
|
||||
ret = fifo->buf[fifo->start];
|
||||
fifo->start = (fifo->start + 1) & 0x0f;
|
||||
|
||||
fifo->d_full = (fifo->full != 0);
|
||||
fifo->full = 0;
|
||||
if (fifo->d_full && (fifo->d_full_evt != NULL))
|
||||
fifo->d_full_evt(fifo->priv);
|
||||
|
||||
count = fifo_get_count(fifo);
|
||||
|
||||
if (count < fifo->trigger_len) {
|
||||
fifo->d_ready = (fifo->ready != 0);
|
||||
fifo->ready = 0;
|
||||
if (fifo->d_ready && (fifo->d_ready_evt != NULL))
|
||||
fifo->d_ready_evt(fifo->priv);
|
||||
|
||||
if (count == 0) {
|
||||
fifo->d_empty = (fifo->empty != 1);
|
||||
fifo->empty = 1;
|
||||
if (fifo->d_empty && (fifo->d_empty_evt != NULL))
|
||||
fifo->d_empty_evt(fifo->priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_clear_overrun(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->d_overrun = (fifo->overrun != 0);
|
||||
fifo->overrun = 0;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_full(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
return fifo->full;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_d_full(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
int ret = fifo->d_full;
|
||||
|
||||
fifo->d_full = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_empty(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
return fifo->empty;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_d_empty(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
int ret = fifo->d_empty;
|
||||
|
||||
fifo->d_empty = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_overrun(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
return fifo->overrun;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_d_overrun(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
int ret = fifo->d_overrun;
|
||||
|
||||
fifo->d_overrun = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_ready(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
return fifo->ready;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_d_ready(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
int ret = fifo->d_ready;
|
||||
|
||||
fifo->d_ready = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
fifo_get_trigger_len(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
return fifo->trigger_len;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_set_trigger_len(void *priv, int trigger_len)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->trigger_len = trigger_len;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_set_len(void *priv, int len)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->len = len;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_set_d_full_evt(void *priv, void (*d_full_evt)(void *))
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->d_full_evt = d_full_evt;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_set_d_empty_evt(void *priv, void (*d_empty_evt)(void *))
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->d_empty_evt = d_empty_evt;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_set_d_overrun_evt(void *priv, void (*d_overrun_evt)(void *))
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->d_overrun_evt = d_overrun_evt;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_set_d_ready_evt(void *priv, void (*d_ready_evt)(void *))
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->d_ready_evt = d_ready_evt;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_set_priv(void *priv, void *sub_priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->priv = sub_priv;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_reset(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->start = fifo->end = 0;
|
||||
fifo->full = fifo->overrun = 0;
|
||||
fifo->empty = 1;
|
||||
fifo->ready = 0;
|
||||
}
|
||||
|
||||
void
|
||||
fifo_reset_evt(void *priv)
|
||||
{
|
||||
fifo_t *fifo = (fifo_t *) priv;
|
||||
|
||||
fifo->start = fifo->end = 0;
|
||||
fifo->full = fifo->overrun = 0;
|
||||
fifo->empty = 1;
|
||||
fifo->ready = 0;
|
||||
fifo->d_full = fifo->d_overrun = 0;
|
||||
fifo->d_empty = fifo->d_ready = 0;
|
||||
|
||||
if (fifo->d_full_evt != NULL)
|
||||
fifo->d_full_evt(fifo->priv);
|
||||
|
||||
if (fifo->d_overrun_evt != NULL)
|
||||
fifo->d_overrun_evt(fifo->priv);
|
||||
|
||||
if (fifo->d_empty_evt != NULL)
|
||||
fifo->d_empty_evt(fifo->priv);
|
||||
|
||||
if (fifo->d_ready_evt != NULL)
|
||||
fifo->d_ready_evt(fifo->priv);
|
||||
}
|
||||
|
||||
void
|
||||
fifo_close(void *priv)
|
||||
{
|
||||
free(priv);
|
||||
}
|
||||
|
||||
void *
|
||||
fifo_init(int len)
|
||||
{
|
||||
void *fifo = NULL;
|
||||
|
||||
if (len == 64)
|
||||
fifo = (void *) calloc(1, sizeof(fifo64_t));
|
||||
else if (len == 16)
|
||||
fifo = (void *) calloc(1, sizeof(fifo16_t));
|
||||
else {
|
||||
fatal("FIFO : Invalid FIFO length: %i\n", len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fifo == NULL)
|
||||
fatal("FIFO%i: Failed to allocate memory for the FIFO\n", len);
|
||||
else
|
||||
((fifo_t *) fifo)->len = len;
|
||||
|
||||
return fifo;
|
||||
}
|
||||
|
||||
#ifdef FIFO_STANDALONE
|
||||
enum {
|
||||
SERIAL_INT_LSR = 1,
|
||||
SERIAL_INT_RECEIVE = 2,
|
||||
SERIAL_INT_TRANSMIT = 4,
|
||||
SERIAL_INT_MSR = 8,
|
||||
SERIAL_INT_TIMEOUT = 16
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t lsr, int_status, tsr, tsr_empty;
|
||||
|
||||
fifo16_t *rcvr_fifo, *xmit_fifo;
|
||||
} serial_t;
|
||||
|
||||
static void
|
||||
serial_receive_timer(fifo16_t *f16, uint8_t val)
|
||||
{
|
||||
fifo_write_evt(val, f16);
|
||||
|
||||
printf("Write %02X to FIFO [F: %i, E: %i, O: %i, R: %i]\n", val,
|
||||
fifo_get_full(f16), fifo_get_empty(f16),
|
||||
fifo_get_overrun(f16), fifo_get_ready(f16));
|
||||
|
||||
/*
|
||||
if (fifo_get_d_overrun(f16))
|
||||
dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(f16) << 1);
|
||||
*/
|
||||
if (fifo_get_d_overrun(f16)) printf(" FIFO overrun state changed: %i -> %i\n",
|
||||
!fifo_get_overrun(f16), fifo_get_overrun(f16));
|
||||
|
||||
/*
|
||||
if (fifo_get_d_empty(f16)) {
|
||||
dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16);
|
||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
}
|
||||
*/
|
||||
if (fifo_get_d_empty(f16)) printf(" FIFO empty state changed: %i -> %i\n",
|
||||
!fifo_get_empty(f16), fifo_get_empty(f16));
|
||||
|
||||
/*
|
||||
if (fifo_get_d_ready(f16)) {
|
||||
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
|
||||
(fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0);
|
||||
serial_update_ints();
|
||||
}
|
||||
*/
|
||||
if (fifo_get_d_ready(f16)) printf(" FIFO ready state changed: %i -> %i\n",
|
||||
!fifo_get_ready(f16), fifo_get_ready(f16));
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
serial_read(fifo16_t *f16)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = fifo_read_evt(f16);
|
||||
|
||||
printf("Read %02X from FIFO [F: %i, E: %i, O: %i, R: %i]\n", ret,
|
||||
fifo_get_full(f16), fifo_get_empty(f16),
|
||||
fifo_get_overrun(f16), fifo_get_ready(f16));
|
||||
|
||||
/*
|
||||
if (fifo_get_d_ready(f16)) {
|
||||
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
|
||||
(fifo_get_ready(f16) ? SERIAL_INT_RECEIVE : 0);
|
||||
serial_update_ints();
|
||||
}
|
||||
*/
|
||||
if (fifo_get_d_ready(f16)) printf(" FIFO ready state changed: %i -> %i\n",
|
||||
!fifo_get_ready(f16), fifo_get_ready(f16));
|
||||
|
||||
/*
|
||||
if (fifo_get_d_empty(f16)) {
|
||||
dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(f16);
|
||||
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
}
|
||||
*/
|
||||
if (fifo_get_d_empty(f16)) printf(" FIFO empty state changed: %i -> %i\n",
|
||||
!fifo_get_empty(f16), fifo_get_empty(f16));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
serial_xmit_d_empty_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
dev->lsr = (dev->lsr & 0x9f) | (fifo_get_empty(dev->xmit_fifo) << 5) |
|
||||
((dev->tsr_empty && fifo_get_empty(dev->xmit_fifo)) << 6);
|
||||
dev->int_status = (dev->int_status & ~SERIAL_INT_TRANSMIT) |
|
||||
(fifo_get_empty(dev->xmit_fifo) ? SERIAL_INT_TRANSMIT : 0);
|
||||
// serial_update_ints();
|
||||
|
||||
printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr);
|
||||
printf("NS16550: serial_xmit_d_empty_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_rcvr_d_empty_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
dev->lsr = (dev->lsr & 0xfe) | !fifo_get_empty(dev->rcvr_fifo);
|
||||
// timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
|
||||
|
||||
printf("NS16550: serial_rcvr_d_empty_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_rcvr_d_overrun_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
dev->lsr = (dev->lsr & 0xfd) | (fifo_get_overrun(dev->rcvr_fifo) << 1);
|
||||
|
||||
printf("NS16550: serial_rcvr_d_overrun_evt(%08X): dev->lsr = %02X\n", priv, dev->lsr);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_rcvr_d_ready_evt(void *priv)
|
||||
{
|
||||
serial_t *dev = (serial_t *) priv;
|
||||
|
||||
dev->int_status = (dev->int_status & ~SERIAL_INT_RECEIVE) |
|
||||
(fifo_get_ready(dev->rcvr_fifo) ? SERIAL_INT_RECEIVE : 0);
|
||||
// serial_update_ints();
|
||||
|
||||
printf("NS16550: serial_rcvr_d_ready_evt(%08X): dev->int_status = %02X\n", priv, dev->int_status);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
uint8_t val, ret;
|
||||
|
||||
printf("Initializing serial...\n");
|
||||
serial_t *dev = (serial_t *) calloc(1, sizeof(serial_t));
|
||||
dev->tsr_empty = 1;
|
||||
|
||||
printf("Initializing dev->xmit_fifo...\n");
|
||||
dev->xmit_fifo = fifo16_init();
|
||||
fifo_set_trigger_len(dev->xmit_fifo, 255);
|
||||
|
||||
fifo_set_priv(dev->xmit_fifo, dev);
|
||||
fifo_set_d_empty_evt(dev->xmit_fifo, serial_xmit_d_empty_evt);
|
||||
|
||||
printf("\nResetting dev->xmit_fifo...\n");
|
||||
fifo_reset_evt(dev->xmit_fifo);
|
||||
|
||||
printf("\nInitializing dev->rcvr_fifo...\n");
|
||||
dev->rcvr_fifo = fifo16_init();
|
||||
fifo_set_trigger_len(dev->rcvr_fifo, 4);
|
||||
|
||||
fifo_set_priv(dev->rcvr_fifo, dev);
|
||||
fifo_set_d_empty_evt(dev->rcvr_fifo, serial_rcvr_d_empty_evt);
|
||||
fifo_set_d_overrun_evt(dev->rcvr_fifo, serial_rcvr_d_overrun_evt);
|
||||
fifo_set_d_ready_evt(dev->rcvr_fifo, serial_rcvr_d_ready_evt);
|
||||
|
||||
printf("\nResetting dev->rcvr_fifo...\n");
|
||||
fifo_reset_evt(dev->rcvr_fifo);
|
||||
|
||||
printf("\nSending/receiving data...\n");
|
||||
serial_receive_timer(dev->rcvr_fifo, '8');
|
||||
serial_receive_timer(dev->rcvr_fifo, '6');
|
||||
ret = serial_read(dev->rcvr_fifo);
|
||||
serial_receive_timer(dev->rcvr_fifo, 'B');
|
||||
ret = serial_read(dev->rcvr_fifo);
|
||||
serial_receive_timer(dev->rcvr_fifo, 'o');
|
||||
ret = serial_read(dev->rcvr_fifo);
|
||||
serial_receive_timer(dev->rcvr_fifo, 'x');
|
||||
ret = serial_read(dev->rcvr_fifo);
|
||||
ret = serial_read(dev->rcvr_fifo);
|
||||
|
||||
fifo_close(dev->rcvr_fifo);
|
||||
fifo_close(dev->xmit_fifo);
|
||||
|
||||
free(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -58,7 +58,7 @@ typedef struct _joystick_instance_ {
|
||||
void *dat;
|
||||
} joystick_instance_t;
|
||||
|
||||
int joystick_type = 0;
|
||||
int joystick_type = JS_TYPE_NONE;
|
||||
|
||||
static const joystick_if_t joystick_none = {
|
||||
.name = "None",
|
||||
@@ -128,21 +128,21 @@ int gameport_instance_id = 0;
|
||||
or writes, and ports at the standard 200h location are prioritized. */
|
||||
static gameport_t *active_gameports = NULL;
|
||||
|
||||
char *
|
||||
const char *
|
||||
joystick_get_name(int js)
|
||||
{
|
||||
if (!joysticks[js].joystick)
|
||||
return NULL;
|
||||
return (char *) joysticks[js].joystick->name;
|
||||
return joysticks[js].joystick->name;
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
joystick_get_internal_name(int js)
|
||||
{
|
||||
if (joysticks[js].joystick == NULL)
|
||||
return "";
|
||||
|
||||
return (char *) joysticks[js].joystick->internal_name;
|
||||
return joysticks[js].joystick->internal_name;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -151,7 +151,7 @@ joystick_get_from_internal_name(char *s)
|
||||
int c = 0;
|
||||
|
||||
while (joysticks[c].joystick != NULL) {
|
||||
if (!strcmp((char *) joysticks[c].joystick->internal_name, s))
|
||||
if (!strcmp(joysticks[c].joystick->internal_name, s))
|
||||
return c;
|
||||
c++;
|
||||
}
|
||||
@@ -183,22 +183,22 @@ joystick_get_pov_count(int js)
|
||||
return joysticks[js].joystick->pov_count;
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
joystick_get_axis_name(int js, int id)
|
||||
{
|
||||
return (char *) joysticks[js].joystick->axis_names[id];
|
||||
return joysticks[js].joystick->axis_names[id];
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
joystick_get_button_name(int js, int id)
|
||||
{
|
||||
return (char *) joysticks[js].joystick->button_names[id];
|
||||
return joysticks[js].joystick->button_names[id];
|
||||
}
|
||||
|
||||
char *
|
||||
const char *
|
||||
joystick_get_pov_name(int js, int id)
|
||||
{
|
||||
return (char *) joysticks[js].joystick->pov_names[id];
|
||||
return joysticks[js].joystick->pov_names[id];
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -410,7 +410,7 @@ tmacm_init(UNUSED(const device_t *info))
|
||||
dev = malloc(sizeof(gameport_t));
|
||||
memset(dev, 0x00, sizeof(gameport_t));
|
||||
|
||||
port = device_get_config_hex16("port1_addr");
|
||||
port = (uint16_t) device_get_config_hex16("port1_addr");
|
||||
switch (port) {
|
||||
case 0x201:
|
||||
dev = gameport_add(&gameport_201_device);
|
||||
@@ -428,7 +428,7 @@ tmacm_init(UNUSED(const device_t *info))
|
||||
break;
|
||||
}
|
||||
|
||||
port = device_get_config_hex16("port2_addr");
|
||||
port = (uint16_t) device_get_config_hex16("port2_addr");
|
||||
switch (port) {
|
||||
case 0x209:
|
||||
dev = gameport_add(&gameport_209_device);
|
||||
|
||||
@@ -75,8 +75,10 @@ enum {
|
||||
GDB_REG_ES,
|
||||
GDB_REG_FS,
|
||||
GDB_REG_GS,
|
||||
#if 0
|
||||
GDB_REG_FS_BASE,
|
||||
GDB_REG_GS_BASE,
|
||||
#endif
|
||||
GDB_REG_CR0,
|
||||
GDB_REG_CR2,
|
||||
GDB_REG_CR3,
|
||||
@@ -678,9 +680,11 @@ gdbstub_client_read_reg(int index, uint8_t *buf)
|
||||
*((uint16_t *) buf) = segment_regs[index - GDB_REG_CS]->seg;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case GDB_REG_FS_BASE ... GDB_REG_GS_BASE:
|
||||
*((uint32_t *) buf) = segment_regs[(index - 16) + (GDB_REG_FS - GDB_REG_CS)]->base;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GDB_REG_CR0 ... GDB_REG_CR4:
|
||||
*((uint32_t *) buf) = *cr_regs[index - GDB_REG_CR0];
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
/* Default language 0xFFFF = from system, 0x409 = en-US */
|
||||
#define DEFAULT_LANGUAGE 0x0409
|
||||
|
||||
#define POSTCARDS_NUM 4
|
||||
#define POSTCARD_MASK (POSTCARDS_NUM - 1)
|
||||
|
||||
#ifdef MIN
|
||||
# undef MIN
|
||||
#endif
|
||||
@@ -127,8 +130,8 @@ extern int isamem_type[]; /* (C) enable ISA mem cards */
|
||||
extern int isartc_type; /* (C) enable ISA RTC card */
|
||||
extern int sound_is_float; /* (C) sound uses FP values */
|
||||
extern int voodoo_enabled; /* (C) video option */
|
||||
extern int ibm8514_enabled; /* (C) video option */
|
||||
extern int xga_enabled; /* (C) video option */
|
||||
extern int ibm8514_standalone_enabled; /* (C) video option */
|
||||
extern int xga_standalone_enabled; /* (C) video option */
|
||||
extern uint32_t mem_size; /* (C) memory size (Installed on system board) */
|
||||
extern uint32_t isa_mem_size; /* (C) memory size (ISA Memory Cards) */
|
||||
extern int cpu; /* (C) cpu type */
|
||||
@@ -142,8 +145,6 @@ extern int confirm_exit; /* (C) enable exit confirmation */
|
||||
extern int confirm_save; /* (C) enable save confirmation */
|
||||
extern int enable_discord; /* (C) enable Discord integration */
|
||||
|
||||
extern int is_pentium; /* TODO: Move back to cpu/cpu.h when it's figured out,
|
||||
how to remove that hack from the ET4000/W32p. */
|
||||
extern int fixed_size_x;
|
||||
extern int fixed_size_y;
|
||||
extern double mouse_sensitivity; /* (C) Mouse sensitivity scale */
|
||||
@@ -178,7 +179,7 @@ extern void reset_screen_size_monitor(int monitor_index);
|
||||
extern void set_screen_size_natural(void);
|
||||
extern void update_mouse_msg(void);
|
||||
#if 0
|
||||
extern void pc_reload(wchar_t *fn);
|
||||
extern void pc_reload(wchar_t *fn);
|
||||
#endif
|
||||
extern int pc_init_modules(void);
|
||||
extern int pc_init(int argc, char *argv[]);
|
||||
@@ -207,7 +208,8 @@ extern double isa_timing;
|
||||
extern int io_delay;
|
||||
extern int framecountx;
|
||||
|
||||
extern volatile int cpu_thread_run;
|
||||
extern volatile int cpu_thread_run;
|
||||
extern uint8_t postcard_codes[POSTCARDS_NUM];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* 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.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user