Merge remote-tracking branch 'upstream/master' into feature/mtrr

This commit is contained in:
Jasmine Iwanek
2023-08-23 05:51:50 -04:00
242 changed files with 13878 additions and 10117 deletions

View File

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

View File

@@ -2,6 +2,7 @@
=====
[![Build Status](https://ci.86box.net/job/86Box/badge/icon)](https://ci.86box.net/job/86Box/)
[![License](https://img.shields.io/github/license/86Box/86Box)](COPYING) [![Latest release](https://img.shields.io/github/release/86Box/86Box.svg)](https://github.com/86Box/86Box/releases) [![Downloads](https://img.shields.io/github/downloads/86Box/86Box/total.svg)](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.

View File

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

View File

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

View File

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

View File

@@ -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 '=': \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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]), "--");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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