This commit is contained in:
RichardG867
2021-03-07 22:38:16 -03:00
71 changed files with 3046 additions and 591 deletions

View File

@@ -90,11 +90,23 @@ else()
add_subdirectory(codegen)
endif()
if(MINITRACE)
add_compile_definitions(MTR_ENABLED)
add_library(minitrace OBJECT minitrace/minitrace.c)
target_link_libraries(86Box minitrace)
endif()
install(TARGETS 86Box)
if(VCPKG_TOOLCHAIN)
x_vcpkg_install_local_dependencies(TARGETS 86Box DESTINATION "bin")
endif()
if(MSVC)
install(FILES $<TARGET_PDB_FILE:86Box>
CONFIGURATIONS Debug RelWithDebInfo
DESTINATION "bin")
endif()
add_subdirectory(device)
add_subdirectory(disk)
add_subdirectory(floppy)

View File

@@ -17,7 +17,8 @@ add_library(chipset OBJECT acc2168.c cs8230.c ali1217.c ali1429.c headland.c int
cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c
neat.c opti495.c opti895.c opti5x7.c scamp.c scat.c via_vt82c49x.c
via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c
stpc.c opti283.c opti291.c via_apollo.c via_pipc.c wd76c10.c
gc100.c olivetti_eva.c stpc.c
opti283.c opti291.c via_apollo.c via_pipc.c wd76c10.c
vl82c480.c)
if(M1489)

256
src/chipset/gc100.c Normal file
View File

@@ -0,0 +1,256 @@
/*
* 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 G2 GC100/GC100A chipset.
* NOTE: As documentation is currently available only for the
* CG100 chipset, the GC100A chipset has been reverese-engineered.
* Thus, its behavior may not be fully accurate.
*
* Authors: EngiNerd <webmaster.crrc@yahoo.it>
*
* Copyright 2020-2021 EngiNerd
*/
#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 <86box/nmi.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/mem.h>
#include <86box/device.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/gameport.h>
#include <86box/ibm_5161.h>
#include <86box/keyboard.h>
#include <86box/rom.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/io.h>
#include <86box/video.h>
typedef struct
{
uint8_t reg[0x10];
} gc100_t;
#define ENABLE_GC100_LOG 1
#ifdef ENABLE_GC100_LOG
int gc100_do_log = ENABLE_GC100_LOG;
static void
gc100_log(const char *fmt, ...)
{
va_list ap;
if (gc100_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define gc100_log(fmt, ...)
#endif
static uint8_t
get_fdd_switch_settings(){
int i, fdd_count = 0;
for (i = 0; i < FDD_NUM; i++) {
if (fdd_get_flags(i))
fdd_count++;
}
if (!fdd_count)
return 0x00;
else
return ((fdd_count - 1) << 6) | 0x01;
}
static uint8_t
get_videomode_switch_settings(){
if (video_is_mda())
return 0x30;
else if (video_is_cga())
return 0x20; /* 0x10 would be 40x25 */
else
return 0x00;
}
static void
gc100_write(uint16_t port, uint8_t val, void *priv)
{
gc100_t *dev = (gc100_t *) priv;
uint16_t addr = port & 0xf;
dev->reg[addr] = val;
switch (addr)
{
/* addr 0x2
* bits 5-7: not used
* bit 4: intenal memory wait states
* bits 2-3: external memory wait states
* bits 0-1: i/o access wait states
*/
case 0x2:
break;
/* addr 0x3
* bits 1-7: not used
* bit 0: turbo 0 xt 1
*/
case 0x3:
if (val & 0x1)
cpu_dynamic_switch(0);
else
cpu_dynamic_switch(cpu);
break;
/* addr 0x5
* programmable dip-switches
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bits 2-3: memory size
* bit 1: fpu
* bit 0: not used
*/
/* addr 0x6 */
/* addr 0x7 */
}
gc100_log("GC100: Write %02x at %02x\n", val, port);
}
static uint8_t
gc100_read(uint16_t port, void *priv)
{
gc100_t *dev = (gc100_t *) priv;
uint8_t ret = 0xff;
uint16_t addr = port & 0xf;
ret = dev->reg[addr];
gc100_log("GC100: Read %02x at %02x\n", ret, port);
switch (addr)
{
/* addr 0x2
* bits 5-7: not used
* bit 4: intenal memory wait states
* bits 2-3: external memory wait states
* bits 0-1: i/o access wait states
*/
case 0x2:
break;
/* addr 0x3
* bits 1-7: not used
* bit 0: turbo 0 xt 1
*/
case 0x3:
break;
/* addr 0x5
* programmable dip-switches
* bits 6-7: floppy drive number
* bits 4-5: video mode
* bits 2-3: memory size
* bit 1: fpu
* bit 0: not used
*/
case 0x5:
ret = ret & 0x0c;
ret |= get_fdd_switch_settings();
ret |= get_videomode_switch_settings();
if (hasfpu)
ret |= 0x02;
break;
/* addr 0x6 */
/* addr 0x7 */
}
return ret;
}
static void
gc100_close(void *priv)
{
gc100_t *dev = (gc100_t *) priv;
free(dev);
}
static void *
gc100_init(const device_t *info)
{
gc100_t *dev = (gc100_t *) malloc(sizeof(gc100_t));
memset(dev, 0, sizeof(gc100_t));
dev->reg[0x2] = 0xff;
dev->reg[0x3] = 0x0;
dev->reg[0x5] = 0x0;
dev->reg[0x6] = 0x0;
dev->reg[0x7] = 0x0;
/* GC100A */
if(info->local) {
io_sethandler(0x0c2, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
io_sethandler(0x0c5, 0x03, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
}
/* GC100 */
else {
io_sethandler(0x022, 0x02, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
io_sethandler(0x025, 0x01, gc100_read, NULL, NULL, gc100_write, NULL, NULL, dev);
}
return dev;
}
const device_t gc100_device = {
"G2 GC100",
0,
0,
gc100_init, gc100_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
const device_t gc100a_device = {
"G2 GC100A",
0,
1,
gc100_init, gc100_close, NULL,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -8,7 +8,7 @@
*
* Implementation of the Intel 82335(KU82335) chipset.
*
* Copyright 2020 Tiseno100
* Copyright 2021 Tiseno100
*
*/
@@ -24,10 +24,7 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/chipset.h>
/* Shadow capabilities */
@@ -38,7 +35,7 @@
/* Granularity Register Enable & Recalc */
#define EXTENDED_GRANULARITY_ENABLED (dev->regs[0x2c] & 0x01)
#define GRANULARITY_RECALC ((dev->regs[0x2e] & (1 << (i+8))) ? ((dev->regs[0x2e] & (1 << i)) ? RO_SHADOW : RW_SHADOW) : DISABLED_SHADOW)
#define GRANULARITY_RECALC ((dev->regs[0x2e] & (1 << (i + 8))) ? ((dev->regs[0x2e] & (1 << i)) ? RO_SHADOW : RW_SHADOW) : DISABLED_SHADOW)
/* R/W operator for the Video RAM region */
#define DETERMINE_VIDEO_RAM_WRITE_ACCESS ((dev->regs[0x22] & (0x08 << 8)) ? RW_SHADOW : RO_SHADOW)
@@ -61,8 +58,8 @@ typedef struct
{
uint16_t regs[256],
cfg_locked;
cfg_locked;
} intel_82335_t;
@@ -73,10 +70,11 @@ intel_82335_log(const char *fmt, ...)
{
va_list ap;
if (intel_82335_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
if (intel_82335_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
@@ -86,92 +84,90 @@ intel_82335_log(const char *fmt, ...)
static void
intel_82335_write(uint16_t addr, uint16_t val, void *priv)
{
intel_82335_t *dev = (intel_82335_t *) priv;
intel_82335_t *dev = (intel_82335_t *)priv;
uint32_t romsize = 0, base = 0, i = 0, rc1_remap = 0, rc2_remap = 0;
dev->regs[addr] = val;
if(!dev->cfg_locked)
if (!dev->cfg_locked)
{
intel_82335_log("Register %02x: Write %04x\n", addr, val);
intel_82335_log("Register %02x: Write %04x\n", addr, val);
switch (addr) {
case 0x22: /* Memory Controller */
switch (addr)
{
case 0x22: /* Memory Controller */
/* Check if the ROM chips are 256 or 512Kbit (Just for Shadowing sanity) */
romsize = ROM_SIZE;
/* Check if the ROM chips are 256 or 512Kbit (Just for Shadowing sanity) */
romsize = ROM_SIZE;
if (!EXTENDED_GRANULARITY_ENABLED)
{
shadowbios = !!(dev->regs[0x22] & 0x01);
shadowbios_write = !!(dev->regs[0x22] & 0x01);
if (!EXTENDED_GRANULARITY_ENABLED)
{
shadowbios = !!(dev->regs[0x22] & 0x01);
shadowbios_write = !!(dev->regs[0x22] & 0x01);
/* Base System 512/640KB set */
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB);
/* Base System 512/640KB set */
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x22] & 0x08) ? ENABLE_TOP_128KB : DISABLE_TOP_128KB);
/* Video RAM shadow*/
mem_set_mem_state_both(0xa0000, 0x20000, (dev->regs[0x22] & (0x04 << 8)) ? DETERMINE_VIDEO_RAM_WRITE_ACCESS : DISABLED_SHADOW);
/* Video RAM shadow*/
mem_set_mem_state_both(0xa0000, 0x20000, (dev->regs[0x22] & (0x04 << 8)) ? DETERMINE_VIDEO_RAM_WRITE_ACCESS : DISABLED_SHADOW);
/* Option ROM shadow */
mem_set_mem_state_both(0xc0000, 0x20000, (dev->regs[0x22] & (0x02 << 8)) ? ENABLED_SHADOW : DISABLED_SHADOW);
/* Option ROM shadow */
mem_set_mem_state_both(0xc0000, 0x20000, (dev->regs[0x22] & (0x02 << 8)) ? ENABLED_SHADOW : DISABLED_SHADOW);
/* System ROM shadow */
mem_set_mem_state_both(0xe0000, 0x20000, (dev->regs[0x22] & 0x01) ? ENABLED_SHADOW : DISABLED_SHADOW);
}
break;
/* System ROM shadow */
mem_set_mem_state_both(0xe0000, 0x20000, (dev->regs[0x22] & 0x01) ? ENABLED_SHADOW : DISABLED_SHADOW);
}
break;
case 0x24: /* Roll Compare (Just top remapping. Not followed according to datasheet!) */
case 0x26:
rc1_remap = (dev->regs[0x24] & 0x01) ? DEFINE_RC1_REMAP_SIZE : 0;
rc2_remap = (dev->regs[0x26] & 0x01) ? DEFINE_RC2_REMAP_SIZE : 0;
mem_remap_top(rc1_remap+rc2_remap);
break;
case 0x24: /* Roll Compare (Just top remapping. Not followed according to datasheet!) */
case 0x26:
rc1_remap = (dev->regs[0x24] & 0x01) ? DEFINE_RC1_REMAP_SIZE : 0;
rc2_remap = (dev->regs[0x26] & 0x01) ? DEFINE_RC2_REMAP_SIZE : 0;
mem_remap_top(rc1_remap + rc2_remap);
break;
case 0x2e: /* Extended Granularity (Enabled if Bit 0 in Register 2Ch is set) */
if(EXTENDED_GRANULARITY_ENABLED)
{
for(i=0; i<8; i++)
{
base = 0xc0000 + (i << 15);
shadowbios = (dev->regs[0x2e] & (1 << (i+8))) && (base == romsize);
shadowbios_write = (dev->regs[0x2e] & (1 << i)) && (base == romsize);
mem_set_mem_state_both(base, 0x8000, GRANULARITY_RECALC);
}
break;
}
}
case 0x2e: /* Extended Granularity (Enabled if Bit 0 in Register 2Ch is set) */
if (EXTENDED_GRANULARITY_ENABLED)
{
for (i = 0; i < 8; i++)
{
base = 0xc0000 + (i << 15);
shadowbios = (dev->regs[0x2e] & (1 << (i + 8))) && (base == romsize);
shadowbios_write = (dev->regs[0x2e] & (1 << i)) && (base == romsize);
mem_set_mem_state_both(base, 0x8000, GRANULARITY_RECALC);
}
break;
}
}
}
/* Unlock/Lock configuration registers */
dev->cfg_locked = LOCK_STATUS;
}
static uint16_t
intel_82335_read(uint16_t addr, void *priv)
{
intel_82335_t *dev = (intel_82335_t *) priv;
intel_82335_t *dev = (intel_82335_t *)priv;
intel_82335_log("Register %02x: Read %04x\n", addr, dev->regs[addr]);
return dev->regs[addr];
}
static void
intel_82335_close(void *priv)
{
intel_82335_t *dev = (intel_82335_t *) priv;
intel_82335_t *dev = (intel_82335_t *)priv;
free(dev);
}
static void *
intel_82335_init(const device_t *info)
{
intel_82335_t *dev = (intel_82335_t *) malloc(sizeof(intel_82335_t));
intel_82335_t *dev = (intel_82335_t *)malloc(sizeof(intel_82335_t));
memset(dev, 0, sizeof(intel_82335_t));
memset(dev->regs, 0, sizeof(dev->regs));
@@ -195,17 +191,19 @@ intel_82335_init(const device_t *info)
io_sethandler(0x002c, 0x0001, NULL, intel_82335_read, NULL, NULL, intel_82335_write, NULL, dev);
/* Extended Granularity */
io_sethandler(0x002e, 0x0001, NULL, intel_82335_read, NULL, NULL, intel_82335_write, NULL, dev);
io_sethandler(0x002e, 0x0001, NULL, intel_82335_read, NULL, NULL, intel_82335_write, NULL, dev);
return dev;
}
const device_t intel_82335_device = {
"Intel 82335",
0,
0,
intel_82335_init, intel_82335_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
intel_82335_init,
intel_82335_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

166
src/chipset/olivetti_eva.c Normal file
View File

@@ -0,0 +1,166 @@
/*
* 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 Olivetti EVA (98/86) Gate Array.
*
* Note: This chipset has no datasheet, everything were done via
* reverse engineering the BIOS of various machines using it.
*
* Authors: EngiNerd <webmaster.crrc@yahoo.it>
*
* Copyright 2020-2021 EngiNerd
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/chipset.h>
#include <86box/video.h>
#include <86box/mem.h>
typedef struct
{
uint8_t reg_065;
uint8_t reg_067;
uint8_t reg_069;
} olivetti_eva_t;
#ifdef ENABLE_OLIVETTI_EVA_LOG
int olivetti_eva_do_log = ENABLE_OLIVETTI_EVA_LOG;
static void
olivetti_eva_log(const char *fmt, ...)
{
va_list ap;
if (olivetti_eva_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define olivetti_eva_log(fmt, ...)
#endif
static void
olivetti_eva_write(uint16_t addr, uint8_t val, void *priv)
{
olivetti_eva_t *dev = (olivetti_eva_t *) priv;
olivetti_eva_log("Olivetti EVA Gate Array: Write %02x at %02x\n", val, addr);
switch (addr) {
case 0x065:
dev->reg_065 = val;
break;
case 0x067:
dev->reg_067 = val;
break;
case 0x069:
dev->reg_069 = val;
/*
* Unfortunately, if triggered, the BIOS remapping function fails causing
* a fatal error. Therefore, this code section is currently commented.
*/
// if (val & 1){
// /*
// * Set the register to 7 or above for the BIOS to trigger the
// * memory remapping function if shadowing is active.
// */
// dev->reg_069 = 0x7;
// }
// if (val & 8) {
// /*
// * Activate shadowing for region e0000-fffff
// */
// mem_remap_top(256);
// mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
// }
break;
}
}
static uint8_t
olivetti_eva_read(uint16_t addr, void *priv)
{
olivetti_eva_t *dev = (olivetti_eva_t *) priv;
uint8_t ret = 0xff;
switch (addr) {
case 0x065:
ret = dev->reg_065;
break;
case 0x067:
/* never happens */
ret = dev->reg_067;
break;
case 0x069:
ret = dev->reg_069;
break;
}
olivetti_eva_log("Olivetti EVA Gate Array: Read %02x at %02x\n", ret, addr);
return ret;
}
static void
olivetti_eva_close(void *priv)
{
olivetti_eva_t *dev = (olivetti_eva_t *) priv;
free(dev);
}
static void *
olivetti_eva_init(const device_t *info)
{
olivetti_eva_t *dev = (olivetti_eva_t *) malloc(sizeof(olivetti_eva_t));
memset(dev, 0, sizeof(olivetti_eva_t));
/* GA98 registers */
dev->reg_065 = 0x00;
/* RAM page registers: never read, only set */
dev->reg_067 = 0x00;
/* RAM enable registers */
dev->reg_069 = 0x0;
io_sethandler(0x0065, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev);
io_sethandler(0x0067, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev);
io_sethandler(0x0069, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev);
/* When shadowing is not enabled in BIOS, all upper memory is available as XMS */
mem_remap_top(384);
/*
* Default settings when NVRAM is cleared activate shadowing.
* Thus, to avoid boot errors, remap only 256k from UMB to XMS.
* Remove this block once BIOS memory remapping works.
*/
mem_remap_top(256);
return dev;
}
const device_t olivetti_eva_device = {
"Olivetti EVA Gate Array",
0,
0,
olivetti_eva_init, olivetti_eva_close, NULL,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -6,13 +6,15 @@
*
* This file is part of the 86Box distribution.
*
* Implementation of the OPTi 82C546/82C547 & 82C596/82C597 chipsets.
* Implementation of the OPTi 82C546/82C547(Python) & 82C596/82C597(Cobra) chipsets.
* Authors: plant/nerd73
* Miran Grca, <mgrca8@gmail.com>
* Authors: plant/nerd73,
* Miran Grca, <mgrca8@gmail.com>
* Tiseno100
*
* Copyright 2020 plant/nerd73.
* Copyright 2020 Miran Grca.
* Copyright 2020 plant/nerd73.
* Copyright 2020 Miran Grca.
* Copyright 2021 Tiseno100.
*/
#include <stdarg.h>
#include <stdint.h>
@@ -26,142 +28,156 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
/* Shadow RAM */
/* Register 4h: C0000-CFFFF range | Register 5h: D0000-DFFFF range */
#define CURRENT_REGISTER dev->regs[4 + !!(i & 4)]
/*
Bits 7-6: xC000-xFFFF
Bits 5-4: x8000-xBFFF
Bits 3-2: x4000-x7FFF
Bits 0-1: x0000-x3FFF
x-y
0 0 Read/Write AT bus
1 0 Read from AT - Write to DRAM
1 1 Read from DRAM - Write to DRAM
0 1 Read from DRAM (write protected)
*/
#define CAN_READ (1 << (i - (4 * !!(i & 4))) * 2)
#define CAN_WRITE (1 << ((i - (4 * !!(i & 4))) * 2 + 1))
/* Shadow Recalc for the C/D segments */
#define SHADOW_RECALC (((CURRENT_REGISTER & CAN_READ) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((CURRENT_REGISTER & CAN_WRITE) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
/* Shadow Recalc for the E/F segments */
#define SHADOW_EF_RECALC (((dev->regs[6] & CAN_READ) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[6] & CAN_WRITE) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
typedef struct
{
uint8_t idx,
regs[16];
port_92_t *port_92;
uint8_t idx, regs[16];
} opti5x7_t;
#ifdef ENABLE_OPTI5X7_LOG
int opti5x7_do_log = ENABLE_OPTI5X7_LOG;
static void
opti5x7_log(const char *fmt, ...)
{
va_list ap;
if (opti5x7_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
if (opti5x7_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define opti5x7_log(fmt, ...)
#endif
static void
opti5x7_recalc(opti5x7_t *dev)
shadow_map(opti5x7_t *dev)
{
uint32_t base;
uint32_t i, shflags = 0;
uint32_t reg, lowest_bit;
shadowbios = 0;
shadowbios_write = 0;
for (i = 0; i < 8; i++) {
base = 0xc0000 + (i << 14);
lowest_bit = (i << 1) & 0x07;
reg = 0x04 + ((base >> 16) & 0x01);
shflags = (dev->regs[reg] & (1 << lowest_bit)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= (dev->regs[reg] & (1 << (lowest_bit + 1))) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state(base, 0x4000, shflags);
for (int i = 0; i < 8; i++)
{
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, SHADOW_RECALC);
if (i < 2)
mem_set_mem_state_both(0xe0000 + (i << 16), 0x10000, SHADOW_EF_RECALC);
}
shadowbios |= !!(dev->regs[0x06] & 0x05);
shadowbios_write |= !!(dev->regs[0x06] & 0x0a);
shflags = (dev->regs[0x06] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= (dev->regs[0x06] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state(0xe0000, 0x10000, shflags);
shflags = (dev->regs[0x06] & 0x04) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= (dev->regs[0x06] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state(0xf0000, 0x10000, shflags);
shadowbios = !!(dev->regs[0x06] & 5);
shadowbios_write = !!(dev->regs[0x06] & 0x0a);
flushmmucache();
}
static void
opti5x7_write(uint16_t addr, uint8_t val, void *priv)
{
opti5x7_t *dev = (opti5x7_t *) priv;
opti5x7_log("Write %02x to OPTi 5x7 address %02x\n", val, addr);
switch (addr) {
case 0x22:
dev->idx = val;
break;
case 0x24:
dev->regs[dev->idx] = val;
switch(dev->idx) {
case 0x02:
cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x04 & 0x08);
break;
{
opti5x7_t *dev = (opti5x7_t *)priv;
case 0x04:
case 0x05:
case 0x06:
opti5x7_recalc(dev);
break;
}
break;
switch (addr)
{
case 0x22:
dev->idx = val;
break;
case 0x24:
opti5x7_log("OPTi 5x7: dev->regs[%02x] = %02x\n", dev->idx, val);
switch (dev->idx)
{
case 0x00: /* DRAM Configuration Register #1 */
dev->regs[dev->idx] = val & 0x7f;
break;
case 0x01: /* DRAM Control Register #1 */
dev->regs[dev->idx] = val;
break;
case 0x02: /* Cache Control Register #1 */
dev->regs[dev->idx] = val;
cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x0c);
cpu_update_waitstates();
break;
case 0x03: /* Cache Control Register #2 */
dev->regs[dev->idx] = val;
break;
case 0x04: /* Shadow RAM Control Register #1 */
case 0x05: /* Shadow RAM Control Register #2 */
case 0x06: /* Shadow RAM Control Register #3 */
dev->regs[dev->idx] = val;
shadow_map(dev);
break;
case 0x07: /* Tag Test Register */
case 0x08: /* CPU Cache Control Register #1 */
case 0x09: /* System Memory Function Register #1 */
case 0x0a: /* System Memory Address Decode Register #1 */
case 0x0b: /* System Memory Address Decode Register #2 */
dev->regs[dev->idx] = val;
break;
case 0x0c: /* Extended DMA Register */
dev->regs[dev->idx] = val & 0xcf;
break;
case 0x0d: /* ROMCS# Register */
case 0x0e: /* Local Master Preemption Register */
case 0x0f: /* Deturbo Control Register #1 */
case 0x10: /* Cache Write-Hit Control Register */
case 0x11: /* Master Cycle Control Register */
dev->regs[dev->idx] = val;
break;
}
break;
}
}
static uint8_t
opti5x7_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
opti5x7_t *dev = (opti5x7_t *) priv;
opti5x7_t *dev = (opti5x7_t *)priv;
switch (addr) {
case 0x24:
opti5x7_log("Read from OPTi 5x7 register %02x\n", dev->idx);
ret = dev->regs[dev->idx];
break;
}
return ret;
return (addr == 0x24) ? dev->regs[dev->idx] : 0xff;
}
static void
opti5x7_close(void *priv)
{
opti5x7_t *dev = (opti5x7_t *) priv;
opti5x7_t *dev = (opti5x7_t *)priv;
free(dev);
}
static void *
opti5x7_init(const device_t *info)
{
opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t));
opti5x7_t *dev = (opti5x7_t *)malloc(sizeof(opti5x7_t));
memset(dev, 0, sizeof(opti5x7_t));
io_sethandler(0x0022, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev);
dev->port_92 = device_add(&port_92_device);
device_add(&port_92_device);
return dev;
}
@@ -170,7 +186,10 @@ const device_t opti5x7_device = {
"OPTi 82C5x6/82C5x7",
0,
0,
opti5x7_init, opti5x7_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
opti5x7_init,
opti5x7_close,
NULL,
{NULL},
NULL,
NULL,
NULL};

View File

@@ -537,7 +537,7 @@ cpu_set(void)
is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) ||
(cpu_s->cpu_type == CPU_PENTIUM2D);
/* The Samuel 2 datasheet claims it's Celeron-compatible. */
is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S);
is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S) || (cpu_s->cpu_type == CPU_EDEN);
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
is_cx6x86 = (cpu_s->cpu_type == CPU_Cx6x86) || (cpu_s->cpu_type == CPU_Cx6x86MX) ||
(cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_CxGX1);
@@ -1807,6 +1807,7 @@ cpu_set(void)
break;
case CPU_CYRIX3S:
case CPU_EDEN: /* This till proper timings get discovered */
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f);
#else
@@ -2600,6 +2601,65 @@ cpu_CPUID(void)
break;
}
break;
case CPU_EDEN:
switch (EAX)
{
case 0:
EAX = 1;
if (msr.fcr2 & (1 << 14))
{
EBX = msr.fcr3 >> 32;
ECX = msr.fcr3 & 0xffffffff;
EDX = msr.fcr2 >> 32;
}
else
{
EBX = 0x746e6543; /*CentaurHauls*/
ECX = 0x736c7561;
EDX = 0x48727561;
}
break;
case 1:
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
break;
case 0x80000000:
EAX = 0x80000006;
break;
case 0x80000001:
EAX = CPUID;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW;
if (cpu_has_feature(CPU_FEATURE_CX8))
EDX |= CPUID_CMPXCHG8B;
break;
case 0x80000002: /*Processor name string*/
case 0x80000003:
case 0x80000004:
EAX = 0x20414956; /*VIA Samuel 2*/
EBX = 0x756d6153;
ECX = 0x32206c65;
EDX = 0x00000000;
break;
case 0x80000005: /*Cache information*/
EBX = 0x08800880; /*TLBs*/
ECX = 0x40040120; /*L1 data cache*/
EDX = 0x40020120; /*L1 instruction cache*/
break;
case 0x80000006:
ECX = 0x40040120; /*L2 data cache*/
break;
default:
EAX = EBX = ECX = EDX = 0;
break;
}
break;
}
}
@@ -2714,6 +2774,7 @@ void cpu_RDMSR()
break;
case CPU_CYRIX3S:
case CPU_EDEN:
EAX = EDX = 0;
switch (ECX)
{
@@ -3318,6 +3379,7 @@ void cpu_WRMSR()
}
break;
case CPU_CYRIX3S:
case CPU_EDEN:
switch (ECX)
{
case 0x10:

View File

@@ -81,6 +81,7 @@ enum {
CPU_K6_2P,
CPU_K6_3P,
CPU_CYRIX3S,
CPU_EDEN,
CPU_PENTIUMPRO, /* 686 class CPUs */
CPU_PENTIUM2,
CPU_PENTIUM2D
@@ -108,7 +109,8 @@ enum {
CPU_PKG_SOCKET8 = (1 << 18),
CPU_PKG_SLOT1 = (1 << 19),
CPU_PKG_SLOT2 = (1 << 20),
CPU_PKG_SOCKET370 = (1 << 21)
CPU_PKG_SOCKET370 = (1 << 21),
CPU_PKG_EBGA368 = (1 << 22)
};

View File

@@ -967,6 +967,16 @@ const cpu_family_t cpu_families[] = {
{"733", CPU_CYRIX3S, fpus_internal, 733333333, 5.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 66, 66, 18, 18, 88},
{"", 0}
}
}, {
.package = CPU_PKG_EBGA368,
.manufacturer = "VIA",
.name = "Eden(Model 7)",
.internal_name = "c3_eden",
.cpus = (const CPU[]) {
{"100", CPU_EDEN, fpus_internal, 100000000, 1.5, 2050, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 9, 9, 4, 4, 12}, /* out of spec */
{"400", CPU_EDEN, fpus_internal, 400000000, 6.0, 2050, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 36, 36, 17, 17, 48},
{"600", CPU_EDEN, fpus_internal, 600000000, 6.0, 2050, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 18, 18, 72},
}
}, {
.package = 0,
}

View File

@@ -1207,9 +1207,12 @@ write64_generic(void *priv, uint8_t val)
* bit 6: display type (0 color, 1 mono)
* bit 5: power-on default speed (0 high, 1 low)
* bit 4: sense RAM size (0 unsupported, 1 512k on system board)
* bits 0-3: unused
* bit 3: coprocessor detect
* bit 2: unused
* bit 1: high/auto speed
* bit 0: dma mode
*/
add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits | (video_is_mda() ? 0x40 : 0x00)) & 0xdf);
add_to_kbc_queue_front(dev, (dev->input_port | fixed_bits | (video_is_mda() ? 0x40 : 0x00) | (hasfpu ? 0x08 : 0x00)) & 0xdf);
dev->input_port = ((dev->input_port + 1) & 3) |
(dev->input_port & 0xfc);
} else {
@@ -1507,6 +1510,29 @@ write60_quadtel(void *priv, uint8_t val)
return 1;
}
static uint8_t
write64_olivetti(void *priv, uint8_t val)
{
atkbd_t *dev = (atkbd_t *)priv;
switch (val) {
case 0x80: /* Olivetti-specific command */
/*
* bit 7: bus expansion board present (M300) / keyboard unlocked (M290)
* bits 4-6: ???
* bit 3: fast ram check (if inactive keyboard works erratically)
* bit 2: keyboard fuse present
* bits 0-1: ???
*/
add_to_kbc_queue_front(dev, (0x0c | ((is386) ? 0x00 : 0x80)) & 0xdf);
dev->input_port = ((dev->input_port + 1) & 3) |
(dev->input_port & 0xfc);
return 0;
}
return write64_generic(dev, val);
}
static uint8_t
write64_quadtel(void *priv, uint8_t val)
@@ -2137,7 +2163,6 @@ kbd_read(uint16_t port, void *priv)
ret |= 0x2; /* 0x10 would be 40x25 */
else
ret |= 0x0;
ret = 0xff;
} else {
/* bit 2 always on */
ret |= 0x4;
@@ -2291,13 +2316,16 @@ kbd_init(const device_t *info)
switch(dev->flags & KBC_VEN_MASK) {
case KBC_VEN_ACER:
case KBC_VEN_GENERIC:
case KBC_VEN_OLIVETTI:
case KBC_VEN_NCR:
case KBC_VEN_IBM_PS1:
case KBC_VEN_XI8088:
dev->write64_ven = write64_generic;
break;
case KBC_VEN_OLIVETTI:
dev->write64_ven = write64_olivetti;
break;
case KBC_VEN_AMI:
case KBC_VEN_INTEL_AMI:
case KBC_VEN_SAMSUNG:
@@ -2447,6 +2475,16 @@ const device_t keyboard_ps2_ami_device = {
{ NULL }, NULL, NULL, NULL
};
const device_t keyboard_ps2_olivetti_device = {
"PS/2 Keyboard (Olivetti)",
0,
KBC_TYPE_PS2_NOREF | KBC_VEN_OLIVETTI,
kbd_init,
kbd_close,
kbd_reset,
{ NULL }, NULL, NULL, NULL
};
const device_t keyboard_ps2_mca_device = {
"PS/2 Keyboard",
0,

View File

@@ -24,6 +24,8 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#define HAVE_STDARG_H
#include <wchar.h>
#include <86box/86box.h>
#include <86box/device.h>
@@ -598,7 +600,7 @@ kbd_read(uint16_t port, void *priv)
ret = ((mem_size-64) / 32) >> 4;
}
else if (kbd->type == 8 || kbd->type == 9) {
/* Olivetti M19 or Zenith Data Systems Z-151*/
/* Olivetti M19 or Zenith Data Systems Z-151 */
if (kbd->pb & 0x04)
ret = kbd->pd & 0xbf;
else

View File

@@ -484,14 +484,16 @@ serial_write(uint16_t addr, uint8_t val, void *p)
}
break;
case 5:
dev->lsr = val;
if (dev->lsr & 0x01)
dev->int_status |= SERIAL_INT_RECEIVE;
if (dev->lsr & 0x1e)
dev->int_status |= SERIAL_INT_LSR;
if (dev->lsr & 0x20)
dev->int_status |= SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
if (dev->mctrl & 0x10) {
dev->lsr = (dev->lsr & 0xe3) | (val & 0x1c);
if (dev->lsr & 0x01)
dev->int_status |= SERIAL_INT_RECEIVE;
if (dev->lsr & 0x1e)
dev->int_status |= SERIAL_INT_LSR;
if (dev->lsr & 0x20)
dev->int_status |= SERIAL_INT_TRANSMIT;
serial_update_ints(dev);
}
break;
case 6:
dev->msr = val;

View File

@@ -1245,7 +1245,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
}
return;
case 7:
if (!(fdc->flags & FDC_FLAG_TOSHIBA) && !(fdc->flags & FDC_FLAG_AT))
if (!(fdc->flags & FDC_FLAG_TOSHIBA) && !(fdc->flags & FDC_FLAG_AT) && !(fdc->flags & FDC_FLAG_UMC))
return;
fdc->rate = val & 0x03;
if (fdc->flags & FDC_FLAG_PS1)
@@ -1294,7 +1294,7 @@ fdc_read(uint16_t addr, void *priv)
ret = 0x00;
/* -Drive 2 Installed */
if (!fdd_get_type(1))
ret |= 80;
ret |= 0x80;
/* -Drive Select 1,0 */
switch (drive) {
case 0:
@@ -1313,6 +1313,12 @@ fdc_read(uint16_t addr, void *priv)
} else {
if (is486 || !fdc->enable_3f1)
ret = 0xff;
else{
if(fdc->flags & FDC_FLAG_UMC)
{
drive = real_drive(fdc, fdc->dor & 1);
ret = !fdd_is_dd(drive) ? ((fdc->dor & 1) ? 2 : 1) : 0;
}
else {
ret = 0x70;
@@ -1328,6 +1334,7 @@ fdc_read(uint16_t addr, void *priv)
if (fdc->dor & 0x20)
ret |= 2;
}
}
}
break;
case 2:
@@ -2166,6 +2173,11 @@ fdc_set_base(fdc_t *fdc, int base)
{
int super_io = (fdc->flags & FDC_FLAG_SUPERIO);
if (fdc->flags & FDC_FLAG_NSC) {
io_sethandler(base + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_sethandler(base + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
@@ -2173,13 +2185,16 @@ fdc_set_base(fdc_t *fdc, int base)
if (fdc->flags & FDC_FLAG_PCJR)
io_sethandler(base, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
if(fdc->flags & FDC_FLAG_UMC)
io_sethandler(base + 0x0001, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_sethandler(base + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_sethandler(base + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_sethandler(base + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
if ((fdc->flags & FDC_FLAG_TOSHIBA) || (fdc->flags & FDC_FLAG_UMC))
io_sethandler(base + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
}
fdc->base_address = base;
fdc_log("FDC Base address set%s (%04X)\n", super_io ? " for Super I/O" : "", fdc->base_address);
}
@@ -2191,6 +2206,11 @@ fdc_remove(fdc_t *fdc)
int super_io = (fdc->flags & FDC_FLAG_SUPERIO);
fdc_log("FDC Removed (%04X)\n", fdc->base_address);
if (fdc->flags & FDC_FLAG_NSC) {
io_removehandler(fdc->base_address + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
} else {
if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) {
io_removehandler(fdc->base_address + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
@@ -2198,14 +2218,17 @@ fdc_remove(fdc_t *fdc)
if (fdc->flags & FDC_FLAG_PCJR)
io_removehandler(fdc->base_address, 0x0010, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
else {
if(fdc->flags & FDC_FLAG_UMC)
io_removehandler(fdc->base_address + 0x0001, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0002, 0x0001, NULL, NULL, NULL, fdc_write, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0004, 0x0001, fdc_read, NULL, NULL, NULL, NULL, NULL, fdc);
io_removehandler(fdc->base_address + 0x0005, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
if (fdc->flags & FDC_FLAG_TOSHIBA)
if ((fdc->flags & FDC_FLAG_TOSHIBA) || (fdc->flags & FDC_FLAG_UMC))
io_removehandler(fdc->base_address + 0x0007, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc);
}
}
}
}
void
@@ -2433,3 +2456,13 @@ const device_t fdc_dp8473_device = {
fdc_reset,
{ NULL }, NULL, NULL
};
const device_t fdc_um8398_device = {
"UMC UM8398 Floppy Drive Controller",
0,
FDC_FLAG_UMC,
fdc_init,
fdc_close,
fdc_reset,
{ NULL }, NULL, NULL
};

View File

@@ -34,12 +34,56 @@
#define ROM_B215 L"roms/floppy/magitronic/Magitronic B215 - BIOS ROM.bin"
#define ROM_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
#define DRIVE_SELECT (int)(real_drive(dev->fdc_controller, i))
typedef struct
{
fdc_t *fdc_controller;
rom_t rom;
} b215_t;
static uint8_t
b215_read(uint16_t addr, void *priv)
{
b215_t *dev = (b215_t *)priv;
/*
Register 3F0h
Bit (3-2) for Drive B:
Bit (1-0) for Drive A:
0: 360KB
1: 1.2MB
2: 720KB
3: 1.44MB
4:
*/
int drive_spec[2];
for (int i = 0; i <= 1; i++)
{
if (fdd_is_525(DRIVE_SELECT))
{
if (!fdd_is_dd(DRIVE_SELECT))
drive_spec[i] = 1;
else if (fdd_doublestep_40(DRIVE_SELECT))
drive_spec[i] = 2;
else
drive_spec[i] = 0;
}
else
{
if (fdd_is_dd(DRIVE_SELECT) && !fdd_is_double_sided(DRIVE_SELECT))
drive_spec[i] = 0;
else if (fdd_is_dd(DRIVE_SELECT) && fdd_is_double_sided(DRIVE_SELECT))
drive_spec[i] = 2;
else
drive_spec[i] = 3;
}
}
return ((drive_spec[1] << 2) | drive_spec[0]) & 0x0f;
}
static void
b215_close(void *priv)
{
@@ -56,7 +100,8 @@ b215_init(const device_t *info)
rom_init(&dev->rom, ROM_B215, ROM_ADDR, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
device_add(&fdc_at_device);
dev->fdc_controller = device_add(&fdc_um8398_device);
io_sethandler(0x03f0, 1, b215_read, NULL, NULL, NULL, NULL, NULL, dev);
return dev;
}

View File

@@ -54,7 +54,7 @@ MiniMicro 4 uses a Zilog Z0765A08PSC(Clone of the NEC 765)
MiniMicro 1 uses a National Semiconductor DP8473(Clone of the NEC 765 with additional NSC commands)
Issues:
MiniMicro 4 WON'T WORK with XT machines. This statement has to be confirmed by someone with the real card itself.
MiniMicro 4 works only with a few XT machines. This statement has to be confirmed by someone with the real card itself.
MiniMicro 4 also won't work with the XT FDC which the Zilog claims to be.
*/
@@ -77,7 +77,7 @@ MiniMicro 4 also won't work with the XT FDC which the Zilog claims to be.
#include <86box/fdc_ext.h>
#define DTK_VARIANT ((info->local == 158) ? ROM_PII_158B : ROM_PII_151B)
#define DTK_CHIP ((info->local == 158) ? &fdc_at_device : &fdc_dp8473_device)
#define DTK_CHIP ((info->local == 158) ? &fdc_xt_device : &fdc_dp8473_device)
#define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff)
#define ROM_PII_151B L"roms/floppy/dtk/pii-151b.rom"
#define ROM_PII_158B L"roms/floppy/dtk/pii-158b.rom"

View File

@@ -46,6 +46,10 @@ extern const device_t scat_sx_device;
extern const device_t cs8230_device;
extern const device_t cs4031_device;
/* G2 */
extern const device_t gc100_device;
extern const device_t gc100a_device;
/* Headland */
extern const device_t headland_gc10x_device;
extern const device_t headland_ht18a_device;
@@ -141,4 +145,7 @@ extern const device_t wd76c10_device;
extern const device_t phoenix_486_jumper_device;
extern const device_t vpc2007_device;
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
extern const device_t olivetti_eva_device;
#endif
#endif /*EMU_CHIPSET_H*/

View File

@@ -34,6 +34,7 @@ extern int fdc_type;
#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */
#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */
#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */
#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */
typedef struct {
@@ -179,6 +180,7 @@ extern const device_t fdc_at_smc_device;
extern const device_t fdc_at_winbond_device;
extern const device_t fdc_at_nsc_device;
extern const device_t fdc_dp8473_device;
extern const device_t fdc_um8398_device;
#endif
#endif /*EMU_FDC_H*/

View File

@@ -82,6 +82,7 @@ extern const device_t keyboard_ps2_ps1_pci_device;
extern const device_t keyboard_ps2_ps2_device;
extern const device_t keyboard_ps2_xi8088_device;
extern const device_t keyboard_ps2_ami_device;
extern const device_t keyboard_ps2_olivetti_device;
extern const device_t keyboard_ps2_mca_device;
extern const device_t keyboard_ps2_mca_2_device;
extern const device_t keyboard_ps2_quadtel_device;

View File

@@ -106,6 +106,7 @@ enum {
MACHINE_TYPE_SLOT1,
MACHINE_TYPE_SLOT2,
MACHINE_TYPE_SOCKET370,
MACHINE_TYPE_EBGA368,
MACHINE_TYPE_MISC,
MACHINE_TYPE_MAX
};
@@ -255,6 +256,13 @@ extern int machine_at_spc4620p_init(const machine_t *);
extern int machine_at_kmxc02_init(const machine_t *);
extern int machine_at_deskmaster286_init(const machine_t *);
extern int machine_at_ncrpc8_init(const machine_t *);
extern int machine_at_ncr3302_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
extern int machine_at_olim290_init(const machine_t *);
#endif
extern int machine_at_shuttle386sx_init(const machine_t *);
extern int machine_at_adi386sx_init(const machine_t *);
extern int machine_at_commodore_sl386sx16_init(const machine_t *);
@@ -263,22 +271,24 @@ extern int machine_at_spc6033p_init(const machine_t *);
extern int machine_at_wd76c10_init(const machine_t *);
extern int machine_at_flytech386_init(const machine_t *);
extern int machine_at_olim290_init(const machine_t *);
extern int machine_at_ncrpc8_init(const machine_t *);
extern int machine_at_ncr3302_init(const machine_t *);
extern int machine_at_awardsx_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_M6117)
extern int machine_at_arb1375_init(const machine_t *);
extern int machine_at_pja511m_init(const machine_t *);
#endif
extern int machine_at_ncrpc916sx_init(const machine_t *);
extern int machine_at_olim300_08_init(const machine_t *);
extern int machine_at_olim300_15_init(const machine_t *);
#ifdef EMU_DEVICE_H
extern const device_t *at_ama932j_get_device(void);
extern const device_t *at_flytech386_get_device(void);
extern const device_t *at_commodore_sl386sx25_get_device(void);
extern const device_t *at_spc4620p_get_device(void);
extern const device_t *at_spc6033p_get_device(void);
extern const device_t *at_m300_08_get_device(void);
#endif
/* m_at_386dx_486.c */
@@ -523,6 +533,9 @@ extern int machine_at_603tcf_init(const machine_t *);
extern int machine_at_trinity371_init(const machine_t *);
extern int machine_at_p6bap_init(const machine_t *);
/* m_at_ebga368.c */
extern int machine_at_arb9673_init(const machine_t *);
/* m_at_misc.c */
extern int machine_at_vpc2007_init(const machine_t *);
@@ -611,8 +624,6 @@ extern int machine_xt_ncrpc4i_init(const machine_t *);
extern int machine_xt_mpc1600_init(const machine_t *);
extern int machine_xt_eaglepcspirit_init(const machine_t *);
extern int machine_xt_multitechpc700_init(const machine_t *);
extern int machine_xt_p3105_init(const machine_t *);
extern int machine_xt_p3120_init(const machine_t *);
extern int machine_xt_iskra3104_init(const machine_t *);
@@ -630,6 +641,9 @@ extern int machine_xt_laserxt_init(const machine_t *);
extern int machine_xt_lxt3_init(const machine_t *);
#endif
/* m_xt_philips.c */
extern int machine_xt_p3105_init(const machine_t *);
extern int machine_xt_p3120_init(const machine_t *);
/* m_xt_t1000.c */
extern int machine_xt_t1000_init(const machine_t *);
extern int machine_xt_t1200_init(const machine_t *);

View File

@@ -66,6 +66,11 @@ extern int dopause, /* system is paused */
doresize, /* screen resize requested */
quited, /* system exit requested */
mouse_capture; /* mouse is captured in app */
#ifdef MTR_ENABLED
extern int tracing_on;
#endif
extern uint64_t timer_freq;
extern int infocus;
extern char emu_version[200]; /* version ID string */
@@ -165,6 +170,11 @@ extern void startblit(void);
extern void endblit(void);
extern void take_screenshot(void);
#ifdef MTR_ENABLED
extern void init_trace(void);
extern void shutdown_trace(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -287,6 +287,11 @@
#define IDM_ACTION_EXIT 40014
#define IDM_ACTION_CTRL_ALT_ESC 40015
#define IDM_ACTION_PAUSE 40016
#ifdef MTR_ENABLED
#define IDM_ACTION_BEGIN_TRACE 40017
#define IDM_ACTION_END_TRACE 40018
#define IDM_ACTION_TRACE 40019
#endif
#define IDM_CONFIG 40020
#define IDM_CONFIG_LOAD 40021
#define IDM_CONFIG_SAVE 40022

View File

@@ -43,6 +43,8 @@ extern const device_t pc87307_15c_device;
extern const device_t pc87307_both_device;
extern const device_t pc87309_device;
extern const device_t pc87309_15c_device;
extern const device_t pc87310_device;
extern const device_t pc87310_ide_device;
extern const device_t pc87311_device;
extern const device_t pc87311_ide_device;
extern const device_t pc87332_device;

View File

@@ -77,6 +77,7 @@ extern const device_t cpqega_device;
extern const device_t sega_device;
extern const device_t atiega_device;
extern const device_t iskra_ega_device;
extern const device_t et2000_device;
#endif
extern int update_overscan;

View File

@@ -292,9 +292,11 @@ extern const device_t oti037c_device;
extern const device_t oti067_device;
extern const device_t oti067_acer386_device;
extern const device_t oti067_ama932j_device;
extern const device_t oti067_m300_device;
extern const device_t oti077_device;
/* Paradise/WD (S)VGA */
extern const device_t paradise_pvga1a_ncr3302_device;
extern const device_t paradise_pvga1a_pc2086_device;
extern const device_t paradise_pvga1a_pc3086_device;
extern const device_t paradise_pvga1a_device;

View File

@@ -0,0 +1,270 @@
// Minitrace
//
// Copyright 2014 by Henrik Rydgård
// http://www.github.com/hrydgard/minitrace
// Released under the MIT license.
//
// Ultra-light dependency free library for performance tracing C/C++ applications.
// Produces traces compatible with Google Chrome's trace viewer.
// Simply open "about:tracing" in Chrome and load the produced JSON.
//
// This contains far less template magic than the original libraries from Chrome
// because this is meant to be usable from C.
//
// See README.md for a tutorial.
//
// The trace format is documented here:
// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit
// More:
// http://www.altdevblogaday.com/2012/08/21/using-chrometracing-to-view-your-inline-profiling-data/
#ifndef MINITRACE_H
#define MINITRACE_H
#include <inttypes.h>
// If MTR_ENABLED is not defined, Minitrace does nothing and has near zero overhead.
// Preferably, set this flag in your build system. If you can't just uncomment this line.
// #define MTR_ENABLED
// By default, will collect up to 1000000 events, then you must flush.
// It's recommended that you simply call mtr_flush on a background thread
// occasionally. It's safe...ish.
#define INTERNAL_MINITRACE_BUFFER_SIZE 1000000
#ifdef __cplusplus
extern "C" {
#endif
// Initializes Minitrace. Must be called very early during startup of your executable,
// before any MTR_ statements.
void mtr_init(const char *json_file);
// Same as above, but allows passing in a custom stream (FILE *), as returned by
// fopen(). It should be opened for writing, preferably in binary mode to avoid
// processing of line endings (i.e. the "wb" mode).
void mtr_init_from_stream(void *stream);
// Shuts down minitrace cleanly, flushing the trace buffer.
void mtr_shutdown(void);
// Lets you enable and disable Minitrace at runtime.
// May cause strange discontinuities in the output.
// Minitrace is enabled on startup by default.
void mtr_start(void);
void mtr_stop(void);
// Flushes the collected data to disk, clearing the buffer for new data.
void mtr_flush(void);
// Returns the current time in seconds. Used internally by Minitrace. No caching.
double mtr_time_s(void);
// Registers a handler that will flush the trace on Ctrl+C.
// Works on Linux and MacOSX, and in Win32 console applications.
void mtr_register_sigint_handler(void);
// Utility function that should rarely be used.
// If str is semi dynamic, store it permanently in a small pool so we don't need to malloc it.
// The pool fills up fast though and performance isn't great.
// Returns a fixed string if the pool is full.
const char *mtr_pool_string(const char *str);
// Commented-out types will be supported in the future.
typedef enum {
MTR_ARG_TYPE_NONE = 0,
MTR_ARG_TYPE_INT = 1, // I
// MTR_ARG_TYPE_FLOAT = 2, // TODO
// MTR_ARG_TYPE_DOUBLE = 3, // TODO
MTR_ARG_TYPE_STRING_CONST = 8, // C
MTR_ARG_TYPE_STRING_COPY = 9,
// MTR_ARG_TYPE_JSON_COPY = 10,
} mtr_arg_type;
// TODO: Add support for more than one argument (metadata) per event
// Having more costs speed and memory.
#define MTR_MAX_ARGS 1
// Only use the macros to call these.
void internal_mtr_raw_event(const char *category, const char *name, char ph, void *id);
void internal_mtr_raw_event_arg(const char *category, const char *name, char ph, void *id, mtr_arg_type arg_type, const char *arg_name, void *arg_value);
#ifdef MTR_ENABLED
// c - category. Can be filtered by in trace viewer (or at least that's the intention).
// A good use is to pass __FILE__, there are macros further below that will do it for you.
// n - name. Pass __FUNCTION__ in most cases, unless you are marking up parts of one.
// Scopes. In C++, use MTR_SCOPE. In C, always match them within the same scope.
#define MTR_BEGIN(c, n) internal_mtr_raw_event(c, n, 'B', 0)
#define MTR_END(c, n) internal_mtr_raw_event(c, n, 'E', 0)
#define MTR_SCOPE(c, n) MTRScopedTrace ____mtr_scope(c, n)
#define MTR_SCOPE_LIMIT(c, n, l) MTRScopedTraceLimit ____mtr_scope(c, n, l)
// Async events. Can span threads. ID identifies which events to connect in the view.
#define MTR_START(c, n, id) internal_mtr_raw_event(c, n, 'S', (void *)(id))
#define MTR_STEP(c, n, id, step) internal_mtr_raw_event_arg(c, n, 'T', (void *)(id), MTR_ARG_TYPE_STRING_CONST, "step", (void *)(step))
#define MTR_FINISH(c, n, id) internal_mtr_raw_event(c, n, 'F', (void *)(id))
// Flow events. Like async events, but displayed in a more fancy way in the viewer.
#define MTR_FLOW_START(c, n, id) internal_mtr_raw_event(c, n, 's', (void *)(id))
#define MTR_FLOW_STEP(c, n, id, step) internal_mtr_raw_event_arg(c, n, 't', (void *)(id), MTR_ARG_TYPE_STRING_CONST, "step", (void *)(step))
#define MTR_FLOW_FINISH(c, n, id) internal_mtr_raw_event(c, n, 'f', (void *)(id))
// The same macros, but with a single named argument which shows up as metadata in the viewer.
// _I for int.
// _C is for a const string arg.
// _S will copy the string, freeing on flush (expensive but sometimes necessary).
// but required if the string was generated dynamically.
// Note that it's fine to match BEGIN_S with END and BEGIN with END_S, etc.
#define MTR_BEGIN_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
#define MTR_END_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
#define MTR_SCOPE_C(c, n, aname, astrval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
#define MTR_BEGIN_S(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
#define MTR_END_S(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
#define MTR_SCOPE_S(c, n, aname, astrval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
#define MTR_BEGIN_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
#define MTR_END_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
#define MTR_SCOPE_I(c, n, aname, aintval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
// Instant events. For things with no duration.
#define MTR_INSTANT(c, n) internal_mtr_raw_event(c, n, 'I', 0)
#define MTR_INSTANT_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'I', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
#define MTR_INSTANT_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'I', 0, MTR_ARG_TYPE_INT, aname, (void *)(aintval))
// Counters (can't do multi-value counters yet)
#define MTR_COUNTER(c, n, val) internal_mtr_raw_event_arg(c, n, 'C', 0, MTR_ARG_TYPE_INT, n, (void *)(intptr_t)(val))
// Metadata. Call at the start preferably. Must be const strings.
#define MTR_META_PROCESS_NAME(n) internal_mtr_raw_event_arg("", "process_name", 'M', 0, MTR_ARG_TYPE_STRING_COPY, "name", (void *)(n))
#define MTR_META_THREAD_NAME(n) internal_mtr_raw_event_arg("", "thread_name", 'M', 0, MTR_ARG_TYPE_STRING_COPY, "name", (void *)(n))
#define MTR_META_THREAD_SORT_INDEX(i) internal_mtr_raw_event_arg("", "thread_sort_index", 'M', 0, MTR_ARG_TYPE_INT, "sort_index", (void *)(i))
#else
#define MTR_BEGIN(c, n)
#define MTR_END(c, n)
#define MTR_SCOPE(c, n)
#define MTR_START(c, n, id)
#define MTR_STEP(c, n, id, step)
#define MTR_FINISH(c, n, id)
#define MTR_FLOW_START(c, n, id)
#define MTR_FLOW_STEP(c, n, id, step)
#define MTR_FLOW_FINISH(c, n, id)
#define MTR_INSTANT(c, n)
#define MTR_BEGIN_C(c, n, aname, astrval)
#define MTR_END_C(c, n, aname, astrval)
#define MTR_SCOPE_C(c, n, aname, astrval)
#define MTR_BEGIN_S(c, n, aname, astrval)
#define MTR_END_S(c, n, aname, astrval)
#define MTR_SCOPE_S(c, n, aname, astrval)
#define MTR_BEGIN_I(c, n, aname, aintval)
#define MTR_END_I(c, n, aname, aintval)
#define MTR_SCOPE_I(c, n, aname, aintval)
#define MTR_INSTANT(c, n)
#define MTR_INSTANT_C(c, n, aname, astrval)
#define MTR_INSTANT_I(c, n, aname, aintval)
// Counters (can't do multi-value counters yet)
#define MTR_COUNTER(c, n, val)
// Metadata. Call at the start preferably. Must be const strings.
#define MTR_META_PROCESS_NAME(n)
#define MTR_META_THREAD_NAME(n)
#define MTR_META_THREAD_SORT_INDEX(i)
#endif
// Shortcuts for simple function timing with automatic categories and names.
#define MTR_BEGIN_FUNC() MTR_BEGIN(__FILE__, __FUNCTION__)
#define MTR_END_FUNC() MTR_END(__FILE__, __FUNCTION__)
#define MTR_SCOPE_FUNC() MTR_SCOPE(__FILE__, __FUNCTION__)
#define MTR_INSTANT_FUNC() MTR_INSTANT(__FILE__, __FUNCTION__)
#define MTR_SCOPE_FUNC_LIMIT_S(l) MTRScopedTraceLimit ____mtr_scope(__FILE__, __FUNCTION__, l)
#define MTR_SCOPE_FUNC_LIMIT_MS(l) MTRScopedTraceLimit ____mtr_scope(__FILE__, __FUNCTION__, (double)l * 0.000001)
// Same, but with a single argument of the usual types.
#define MTR_BEGIN_FUNC_S(aname, arg) MTR_BEGIN_S(__FILE__, __FUNCTION__, aname, arg)
#define MTR_END_FUNC_S(aname, arg) MTR_END_S(__FILE__, __FUNCTION__, aname, arg)
#define MTR_SCOPE_FUNC_S(aname, arg) MTR_SCOPE_S(__FILE__, __FUNCTION__, aname, arg)
#define MTR_BEGIN_FUNC_C(aname, arg) MTR_BEGIN_C(__FILE__, __FUNCTION__, aname, arg)
#define MTR_END_FUNC_C(aname, arg) MTR_END_C(__FILE__, __FUNCTION__, aname, arg)
#define MTR_SCOPE_FUNC_C(aname, arg) MTR_SCOPE_C(__FILE__, __FUNCTION__, aname, arg)
#define MTR_BEGIN_FUNC_I(aname, arg) MTR_BEGIN_I(__FILE__, __FUNCTION__, aname, arg)
#define MTR_END_FUNC_I(aname, arg) MTR_END_I(__FILE__, __FUNCTION__, aname, arg)
#define MTR_SCOPE_FUNC_I(aname, arg) MTR_SCOPE_I(__FILE__, __FUNCTION__, aname, arg)
#ifdef __cplusplus
}
#ifdef MTR_ENABLED
// These are optimized to use X events (combined B and E). Much easier to do in C++ than in C.
class MTRScopedTrace {
public:
MTRScopedTrace(const char *category, const char *name)
: category_(category), name_(name) {
start_time_ = mtr_time_s();
}
~MTRScopedTrace() {
internal_mtr_raw_event(category_, name_, 'X', &start_time_);
}
private:
const char *category_;
const char *name_;
double start_time_;
};
// Only outputs a block if execution time exceeded the limit.
// TODO: This will effectively call mtr_time_s twice at the end, which is bad.
class MTRScopedTraceLimit {
public:
MTRScopedTraceLimit(const char *category, const char *name, double limit_s)
: category_(category), name_(name), limit_(limit_s) {
start_time_ = mtr_time_s();
}
~MTRScopedTraceLimit() {
double end_time = mtr_time_s();
if (end_time - start_time_ >= limit_) {
internal_mtr_raw_event(category_, name_, 'X', &start_time_);
}
}
private:
const char *category_;
const char *name_;
double start_time_;
double limit_;
};
class MTRScopedTraceArg {
public:
MTRScopedTraceArg(const char *category, const char *name, mtr_arg_type arg_type, const char *arg_name, void *arg_value)
: category_(category), name_(name) {
internal_mtr_raw_event_arg(category, name, 'B', 0, arg_type, arg_name, arg_value);
}
~MTRScopedTraceArg() {
internal_mtr_raw_event(category_, name_, 'E', 0);
}
private:
const char *category_;
const char *name_;
};
#endif
#endif
#endif

View File

@@ -14,12 +14,14 @@
#
add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c
m_xt_philips.c
m_xt_t1000.c m_xt_t1000_vid.c m_xt_xi8088.c m_xt_zenith.c m_pcjr.c
m_amstrad.c m_europc.c m_xt_olivetti.c m_tandy.c m_at.c m_at_commodore.c
m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c
m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c
m_at_socket4_5.c m_at_socket7.c m_at_sockets7.c m_at_socket8.c
m_at_slot1.c m_at_slot2.c m_at_socket370.c m_at_misc.c)
m_at_slot1.c m_at_slot2.c m_at_socket370.c m_at_ebga368.c
m_at_misc.c)
if(HEDAKA)
target_compile_definitions(mch PRIVATE USE_HEDAKA)

View File

@@ -35,10 +35,12 @@
#include <86box/rom.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/sio.h>
#include <86box/serial.h>
#include <86box/video.h>
#include <86box/vid_cga.h>
#include <86box/flash.h>
#include <86box/machine.h>
@@ -56,6 +58,8 @@ machine_at_mr286_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&keyboard_at_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -66,6 +70,8 @@ static void
machine_at_headland_common_init(int ht386)
{
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
if (ht386)
@@ -136,7 +142,10 @@ machine_at_quadt286_init(const machine_t *model)
machine_at_common_init(model);
device_add(&keyboard_at_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&headland_gc10x_device);
return ret;
@@ -157,6 +166,8 @@ machine_at_neat_init(const machine_t *model)
machine_at_init(model);
device_add(&neat_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -177,6 +188,8 @@ machine_at_neat_ami_init(const machine_t *model)
machine_at_common_init(model);
device_add(&neat_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&keyboard_at_ami_device);
@@ -198,7 +211,10 @@ machine_at_px286_init(const machine_t *model)
machine_at_common_init(model);
device_add(&keyboard_at_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&neat_device);
return ret;
@@ -219,6 +235,8 @@ machine_at_micronics386_init(const machine_t *model)
machine_at_init(model);
device_add(&neat_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -230,6 +248,8 @@ machine_at_scat_init(const machine_t *model, int is_v4)
{
machine_at_common_init(model);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
if (is_v4)
@@ -245,6 +265,8 @@ machine_at_scatsx_init(const machine_t *model)
machine_at_common_init(model);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&scat_sx_device);
@@ -434,6 +456,8 @@ machine_at_shuttle386sx_init(const machine_t *model)
device_add(&intel_82335_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -456,6 +480,8 @@ machine_at_adi386sx_init(const machine_t *model)
device_add(&intel_82335_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -502,7 +528,10 @@ machine_at_commodore_sl386sx16_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&keyboard_at_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&neat_device);
/* Two serial ports - on the real hardware SL386SX-16, they are on the single UMC UM82C452. */
device_add_inst(&ns16450_device, 1);
@@ -518,7 +547,10 @@ machine_at_scamp_common_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&keyboard_ps2_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&vlsi_scamp_device);
}
@@ -591,6 +623,8 @@ machine_at_awardsx_init(const machine_t *model)
machine_at_init(model);
device_add(&opti291_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -671,47 +705,6 @@ machine_at_pja511m_init(const machine_t *model)
}
#endif
static uint8_t
m290_read(uint16_t port, void *priv)
{
uint8_t ret = 0x0;
switch (port) {
/*
* port 69:
* dip-switch bank on mainboard (off=1)
* bit 3 - use OCG/CGA display adapter (off) / other display adapter (on)
*/
case 0x69:
if(video_is_cga())
ret |= 0x8|0x4;
ret |= 0x1|0x2;
}
return (ret);
}
int
machine_at_olim290_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&keyboard_at_device);
device_add(&fdc_at_device);
io_sethandler(0x069, 1, m290_read, NULL, NULL, NULL, NULL, NULL, NULL);
return ret;
}
/*
* Current bugs:
* - ctrl-alt-del produces an 8042 error
@@ -730,6 +723,8 @@ machine_at_ncrpc8_init(const machine_t *model)
machine_at_common_init(model);
device_add(&keyboard_at_ncr_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -758,10 +753,118 @@ machine_at_ncr3302_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&neat_device);
device_add(&keyboard_at_ncr_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
if (gfxcard == VID_INTERNAL)
device_add(&paradise_pvga1a_device);
device_add(&paradise_pvga1a_ncr3302_device);
return ret;
}
/*
* Current bugs:
* - soft-reboot after saving CMOS settings/pressing ctrl-alt-del produces an 8042 error
*/
int
machine_at_ncrpc916sx_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved(L"roms/machines/ncr_pc916sx/ncr_386sx_u46-17_7.3.bin",
L"roms/machines/ncr_pc916sx/ncr_386sx_u12-19_7.3.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&keyboard_at_ncr_device);
mem_remap_top(384);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
int
machine_at_olim290_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m290/m290_pep3_1.25.bin",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&keyboard_at_olivetti_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&olivetti_eva_device);
return ret;
}
#endif
const device_t *
at_m300_08_get_device(void)
{
return &oti067_m300_device;
}
int
machine_at_olim300_08_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m300_08/BIOS.ROM",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&opti283_device);
device_add(&keyboard_ps2_olivetti_device);
device_add(&pc87310_ide_device);
if (gfxcard == VID_INTERNAL)
device_add(&oti067_m300_device);
return ret;
}
/* Almost identical to M300-08, save for CPU speed, VRAM, and BIOS identification string */
int
machine_at_olim300_15_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m300_15/BIOS.ROM",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&opti283_device);
device_add(&keyboard_ps2_olivetti_device);
device_add(&pc87310_ide_device);
/* Stock VRAM is maxed out, so no need to expose video card config */
if (gfxcard == VID_INTERNAL)
device_add(&oti067_m300_device);
return ret;
}

View File

@@ -34,6 +34,7 @@
#include <86box/pci.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/rom.h>
#include <86box/sio.h>
#include <86box/hdc.h>
@@ -57,6 +58,8 @@ machine_at_acc386_init(const machine_t *model)
machine_at_common_init(model);
device_add(&acc2168_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -77,6 +80,8 @@ machine_at_asus386_init(const machine_t *model)
machine_at_common_init(model);
device_add(&rabbit_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -97,6 +102,8 @@ machine_at_sis401_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&sis_85c401_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -117,6 +124,8 @@ machine_at_av4_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&sis_85c460_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -137,6 +146,8 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2
machine_at_common_ide_init(model);
device_add(&sis_85c461_device);
device_add(&keyboard_ps2_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -157,7 +168,10 @@ machine_at_ecs386_init(const machine_t *model)
machine_at_common_init(model);
device_add(&cs8230_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&keyboard_at_ami_device);
return ret;
@@ -178,7 +192,10 @@ machine_at_spc6000a_init(const machine_t *model)
machine_at_common_init_ex(model, 1);
device_add(&cs8230_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&keyboard_at_samsung_device);
return ret;
@@ -200,6 +217,8 @@ machine_at_rycleopardlx_init(const machine_t *model)
device_add(&opti283_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -221,6 +240,8 @@ machine_at_486vchd_init(const machine_t *model)
device_add(&via_vt82c49x_device);
device_add(&keyboard_at_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -241,6 +262,8 @@ machine_at_cs4031_init(const machine_t *model)
machine_at_common_init(model);
device_add(&cs4031_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -326,9 +349,11 @@ machine_at_acera1g_init(const machine_t *model)
device_add(&ali1429_device);
device_add(&keyboard_ps2_acer_pci_device);
device_add(&fdc_at_device);
device_add(&ide_isa_2ch_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
@@ -348,6 +373,8 @@ machine_at_ali1429_common_init(const machine_t *model)
device_add(&ali1429_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
}
@@ -402,6 +429,8 @@ machine_at_opti495_init(const machine_t *model)
device_add(&opti495_device);
device_add(&keyboard_at_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -416,6 +445,8 @@ machine_at_opti495_ami_common_init(const machine_t *model)
device_add(&opti495_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
}
@@ -469,6 +500,8 @@ machine_at_403tg_init(const machine_t *model)
device_add(&opti895_device);
device_add(&keyboard_at_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
@@ -522,6 +555,8 @@ static void
machine_at_sis_85c471_common_init(const machine_t *model)
{
machine_at_common_init(model);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&sis_85c471_device);
@@ -884,6 +919,8 @@ machine_at_486ap4_init(const machine_t *model)
pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0b = Slot 3 */
pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 0c = Slot 4 */
device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&i420ex_device);

View File

@@ -45,6 +45,7 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/mem.h>
#include <86box/fdc_ext.h>
#include <86box/lpt.h>
#include <86box/rom.h>
#include <86box/serial.h>
@@ -108,7 +109,9 @@ machine_at_cmdpc_init(const machine_t *model)
mem_remap_top(384);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
cmd_uart = device_add(&i8250_device);
cbm_io_init();

View File

@@ -0,0 +1,71 @@
/*
* 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 VIA EBGA368 Based Single Board Computers.
*
* Note: 86Box doesn't emulate all the components a SBC may have.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Tiseno100
*
* Copyright 2016-2019 Miran Grca.
* Copyright 2021 Tiseno100.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/mem.h>
#include <86box/io.h>
#include <86box/rom.h>
#include <86box/pci.h>
#include <86box/device.h>
#include <86box/chipset.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/keyboard.h>
#include <86box/flash.h>
#include <86box/sio.h>
#include <86box/hwm.h>
#include <86box/spd.h>
#include <86box/video.h>
#include "cpu.h"
#include <86box/machine.h>
int
machine_at_arb9673_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/arb9673/W9673.v12",
0x00080000, 524288, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init_ex(model, 2);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4);
pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4);
pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1);
pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4);
device_add(&via_vt8601_device);
device_add(&via_vt82c686b_device);
device_add(&via_vt82c686_sio_device);
device_add(&via_vt82c686_hwm_device);
device_add(&keyboard_ps2_ami_pci_device);
device_add(&sst_flash_39sf040_device);
spd_register(SPD_TYPE_SDRAM, 0xf, 32);
return ret;
}

View File

@@ -28,6 +28,7 @@
#include <86box/pci.h>
#include <86box/device.h>
#include <86box/chipset.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/timer.h>
@@ -98,7 +99,10 @@ machine_at_award_common_init(const machine_t *model)
pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */
pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&keyboard_ps2_pci_device);
}

View File

@@ -163,6 +163,7 @@
#include "cpu.h"
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/machine.h>
#include <86box/m_at_t3100e.h>
@@ -761,8 +762,12 @@ int machine_at_t3100e_init(const machine_t *model)
machine_at_common_ide_init(model);
device_add(&keyboard_at_toshiba_device);
device_add(&fdc_at_device);
if (fdc_type == FDC_INTERNAL)
{
device_add(&fdc_at_device);
}
/* Hook up system control port */
io_sethandler(0x8084, 0x0001,
t3100e_sys_in, NULL, NULL,

View File

@@ -57,6 +57,7 @@
#include <86box/device.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/nvr.h>
#include <86box/nvr_ps2.h>
#include <86box/keyboard.h>
@@ -1259,6 +1260,8 @@ static void
machine_ps2_common_init(const machine_t *model)
{
machine_common_init(model);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
dma16_init();

View File

@@ -11,12 +11,13 @@
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/gameport.h>
#include <86box/ibm_5161.h>
#include <86box/keyboard.h>
#include <86box/rom.h>
#include <86box/machine.h>
#include <86box/chipset.h>
static void
machine_xt_common_init(const machine_t *model)
@@ -399,58 +400,3 @@ machine_xt_multitechpc700_init(const machine_t *model)
return ret;
}
/*
* Current bugs and limitations:
* - 640-768 conventional memory not usable (should be mapped at address d0000-effff)
*/
int
machine_xt_p3105_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/philips_p3105/philipsnms9100.bin",
0x000fc000, 16384, 0);
if (bios_only || !ret)
return ret;
device_add(&keyboard_pc_device);
machine_xt_common_init(model);
return ret;
}
/*
* Current bugs and limitations:
* - 640-768 conventional memory not usable (should be mapped at address d0000-effff)
* - BIOS detects 4 fdds, so hdd letter is E instead of C
*/
int
machine_xt_p3120_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/philips_p3120/philips_p3120.bin",
0x000f8000, 32768, 0);
if (bios_only || !ret)
return ret;
device_add(&keyboard_pc_device);
machine_common_init(model);
pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
nmi_init();
if (joystick_type)
device_add(&gameport_device);
return ret;
}

View File

@@ -16,6 +16,7 @@
#include <86box/timer.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/gameport.h>
#include <86box/keyboard.h>
@@ -169,6 +170,8 @@ machine_xt_lxt3_init(const machine_t *model)
pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt);
device_add(&keyboard_xt_lxt3_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type)

View File

@@ -724,6 +724,9 @@ machine_xt_olim24_init(const machine_t *model)
memset(m24_kbd, 0x00, sizeof(olim24_kbd_t));
machine_common_init(model);
/* On-board FDC can be disabled only on M24SP */
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_xt_device);
/* Address 66-67 = mainboard dip-switch settings */
@@ -771,7 +774,7 @@ machine_xt_olim240_init(const machine_t *model)
*/
device_add(&keyboard_at_olivetti_device);
/* FIXME: make sure this is correct?? */
/* FIXME: make sure this is correct?? */
device_add(&at_nvr_device);
if (fdc_type == FDC_INTERNAL)
@@ -790,6 +793,7 @@ machine_xt_olim240_init(const machine_t *model)
* Current bugs:
* - 640x400x2 graphics mode not supported (bit 0 of register 0x3de cannot be set)
* - optional mouse emulation missing
* - setting CPU speed at 4.77MHz sometimes throws a timer error. If the machine is hard-resetted, the error disappears.
*/
int
machine_xt_olim19_init(const machine_t *model)
@@ -809,6 +813,8 @@ machine_xt_olim19_init(const machine_t *model)
memset(vid, 0x00, sizeof(olim19_vid_t));
machine_common_init(model);
/* On-board FDC cannot be disabled */
device_add(&fdc_xt_device);
m19_vid_init(vid);
@@ -821,39 +827,3 @@ machine_xt_olim19_init(const machine_t *model)
return ret;
}
/* not working, returns timer error */
/* it appears to be a rebadged Hitachi HL 320 laptop */
int
machine_xt_olim15_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/olivetti_m15/oliv_m15.bin",
0x000fc000, 16384, 0);
if (bios_only || !ret)
return ret;
machine_common_init(model);
pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt);
device_add(&keyboard_xt_olivetti_device);
device_add(&cga_device);
/* FIXME: make sure this is correct?? */
//device_add(&at_nvr_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_xt_device);
if (joystick_type)
device_add(&gameport_device);
nmi_init();
return ret;
}

203
src/machine/m_xt_philips.c Normal file
View File

@@ -0,0 +1,203 @@
/*
* 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.
*
* Emulation of the Philips XT-compatible machines.
*
*
*
* Authors: EngiNerd <webmaster.crrc@yahoo.it>
*
* Copyright 2020-2021 EngiNerd.
*/
#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 <86box/nmi.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/mem.h>
#include <86box/device.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/gameport.h>
#include <86box/ibm_5161.h>
#include <86box/keyboard.h>
#include <86box/rom.h>
#include <86box/machine.h>
#include <86box/chipset.h>
#include <86box/io.h>
#include <86box/video.h>
typedef struct
{
uint8_t reg;
} philips_t;
#ifdef ENABLE_philips_LOG
int philips_do_log = ENABLE_philips_LOG;
static void
philips_log(const char *fmt, ...)
{
va_list ap;
if (philips_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define philips_log(fmt, ...)
#endif
static void
philips_write(uint16_t port, uint8_t val, void *priv)
{
philips_t *dev = (philips_t *) priv;
switch (port)
{
/* port 0xc0
* bit 7: turbo
* bits 4-5: rtc read/set (I2C Bus SDA/SCL?)
* bit 2: parity disabled
*/
case 0xc0:
dev->reg = val;
if (val & 0x80)
cpu_dynamic_switch(cpu);
else
cpu_dynamic_switch(0);
break;
}
philips_log("Philips XT Mainboard: Write %02x at %02x\n", val, port);
}
static uint8_t
philips_read(uint16_t port, void *priv)
{
philips_t *dev = (philips_t *) priv;
uint8_t ret = 0xff;
switch (port)
{
/* port 0xc0
* bit 7: turbo
* bits 4-5: rtc read/set
* bit 2: parity disabled
*/
case 0xc0:
ret = dev->reg;
break;
}
philips_log("Philips XT Mainboard: Read %02x at %02x\n", ret, port);
return ret;
}
static void
philips_close(void *priv)
{
philips_t *dev = (philips_t *) priv;
free(dev);
}
static void *
philips_init(const device_t *info)
{
philips_t *dev = (philips_t *) malloc(sizeof(philips_t));
memset(dev, 0, sizeof(philips_t));
dev->reg = 0x40;
io_sethandler(0x0c0, 0x01, philips_read, NULL, NULL, philips_write, NULL, NULL, dev);
return dev;
}
const device_t philips_device = {
"Philips XT Mainboard",
0,
0,
philips_init, philips_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
void
machine_xt_philips_common_init(const machine_t *model)
{
machine_common_init(model);
pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt);
/* On-board FDC cannot be disabled */
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type)
device_add(&gameport_device);
device_add(&keyboard_pc_device);
device_add(&philips_device);
device_add(&xta_hd20_device);
}
int
machine_xt_p3105_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/philips_p3105/philipsnms9100.bin",
0x000fc000, 16384, 0);
if (bios_only || !ret)
return ret;
machine_xt_philips_common_init(model);
return ret;
}
int
machine_xt_p3120_init(const machine_t *model)
{
int ret;
ret = bios_load_linear(L"roms/machines/philips_p3120/philips_p3120.bin",
0x000f8000, 32768, 0);
if (bios_only || !ret)
return ret;
machine_xt_philips_common_init(model);
device_add(&gc100a_device);
return ret;
}

View File

@@ -11,6 +11,7 @@
#include <86box/device.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/nmi.h>
#include <86box/nvr.h>
#include <86box/gameport.h>
@@ -172,7 +173,10 @@ machine_xt_xi8088_init(const machine_t *model)
/* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */
machine_common_init(model);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&keyboard_ps2_xi8088_device);
nmi_init();
device_add(&ibmat_nvr_device);

View File

@@ -50,6 +50,7 @@ const machine_type_t machine_types[] = {
{ "Slot 1", MACHINE_TYPE_SLOT1 },
{ "Slot 2", MACHINE_TYPE_SLOT2 },
{ "Socket 370", MACHINE_TYPE_SOCKET370 },
{ "EBGA 368", MACHINE_TYPE_EBGA368 },
{ "Miscellaneous", MACHINE_TYPE_MISC }
};
@@ -73,8 +74,7 @@ const machine_t machines[] = {
{ "[8088] NCR PC4i", "pc4i", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 640, 256, 0, machine_xt_ncrpc4i_init, NULL },
{ "[8088] Olivetti M19", "m19", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 256, 640, 256, 0, machine_xt_olim19_init, NULL },
{ "[8088] OpenXT", "openxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_open_xt_init, NULL },
{ "[8088] Philips P3105/NMS9100", "p3105", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 768, 256, 0, machine_xt_p3105_init, NULL },
{ "[8088] Philips P3120", "p3120", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 256, 768, 256, 0, machine_xt_p3120_init, NULL },
{ "[8088] Philips P3105/NMS9100", "p3105", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA, 256, 768, 256, 0, machine_xt_p3105_init, NULL },
{ "[8088] Phoenix XT clone", "pxxt", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 64, 640, 64, 0, machine_xt_pxxt_init, NULL },
{ "[8088] Schneider EuroPC", "europc", MACHINE_TYPE_8088, CPU_PKG_8088_EUROPC, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL },
{ "[8088] Tandy 1000", "tandy", MACHINE_TYPE_8088, CPU_PKG_8088_EUROPC, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_tandy_init, tandy1k_get_device },
@@ -87,6 +87,7 @@ const machine_t machines[] = {
{ "[8088] Zenith Data Systems Z-151/152/161", "zdsz151", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_z151_init, NULL },
{ "[8088] Zenith Data Systems Z-159", "zdsz159", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC, 128, 640, 64, 0, machine_xt_z159_init, NULL },
{ "[8088] Zenith Data Systems SupersPort (Z-184)", "zdsupers", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED, 128, 640, 128, 0, machine_xt_z184_init, z184_get_device },
{ "[GC100A] Philips P3120", "p3120", MACHINE_TYPE_8088, CPU_PKG_8088, 0, 0, 0, 0, 0, 0, 0, MACHINE_PC | MACHINE_XTA, 256, 768, 256, 0, machine_xt_p3120_init, NULL },
/* 8086 Machines */
{ "[8086] Amstrad PC1512", "pc1512", MACHINE_TYPE_8086, CPU_PKG_8086, 0, 8000000, 8000000, 0, 0, 0, 0, MACHINE_PC | MACHINE_VIDEO_FIXED | MACHINE_MOUSE, 512, 640, 128, 63, machine_pc1512_init, pc1512_get_device },
@@ -122,7 +123,9 @@ const machine_t machines[] = {
{ "[ISA] Compaq Portable III", "portableiii", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 640, 16384, 128, 127, machine_at_portableiii_init, at_cpqiii_get_device },
{ "[ISA] MR 286 clone", "mr286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 16384, 128, 127, machine_at_mr286_init, NULL },
{ "[ISA] NCR PC8/810/710/3390/3392", "pc8", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_ncrpc8_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
{ "[ISA] Olivetti M290", "m290", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 640, 16384, 128, 127, machine_at_olim290_init, NULL },
#endif
#if defined(DEV_BRANCH) && defined(USE_OPEN_AT)
{ "[ISA] OpenAT", "open_at", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 256, 15872, 128, 63, machine_at_open_at_init, NULL },
#endif
@@ -143,13 +146,14 @@ const machine_t machines[] = {
{ "[SCAT] Samsung SPC-4216P", "spc4216p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 1024, 5120,1024, 127, machine_at_spc4216p_init, NULL },
{ "[SCAT] Samsung SPC-4620P", "spc4620p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 5120,1024, 127, machine_at_spc4620p_init, NULL },
{ "[SCAT] Samsung Deskmaster 286", "deskmaster286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_deskmaster286_init, NULL },
/* 286 machines that utilize the MCA bus */
{ "[MCA] IBM PS/2 model 50", "ibmps2_m50", MACHINE_TYPE_286, CPU_PKG_286 | CPU_PKG_486SLC_IBM, 0, 10000000, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 10240,1024, 63, machine_ps2_model_50_init, NULL },
/* 386SX machines */
{ "[ISA] IBM PS/1 model 2121", "ibmps1_2121", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO_FIXED, 2048, 6144,1024, 63, machine_ps1_m2121_init, NULL },
{ "[ISA] IBM PS/1 m.2121+ISA", "ibmps1_2121_isa", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 6144,1024, 63, machine_ps1_m2121_init, NULL },
{ "[ISA] NCR PC916SX", "ncr_pc916sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 128, 127, machine_at_ncrpc916sx_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_M6117)
{ "[ALi M6117D] Acrosser AR-B1375", "arb1375", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_arb1375_init, NULL },
{ "[ALi M6117D] Acrosser PJ-A511M", "pja511m", MACHINE_TYPE_386SX, CPU_PKG_M6117, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 32768,1024, 127, machine_at_pja511m_init, NULL },
@@ -160,6 +164,8 @@ const machine_t machines[] = {
{ "[Intel 82335] Shuttle 386SX", "shuttle386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_shuttle386sx_init, NULL },
{ "[NEAT] Commodore SL386SX-16", "cmdsl386sx16", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 8192, 512, 127, machine_at_commodore_sl386sx16_init, NULL },
{ "[NEAT] DTK 386SX clone", "dtk386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_init, NULL },
{ "[OPTi 283] Olivetti M300-08", "olivetti_m300_08", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 20000000, 20000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 16384, 2048, 127, machine_at_olim300_08_init, at_m300_08_get_device },
{ "[OPTi 283] Olivetti M300-15", "olivetti_m300_15", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 25000000, 25000000, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 16384, 2048, 127, machine_at_olim300_15_init, NULL },
{ "[OPTi 291] DTK PPM-3333P", "awardsx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_awardsx_init, NULL },
{ "[SCAMP] Commodore SL386SX-25", "cmdsl386sx16", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127, machine_at_commodore_sl386sx25_init, at_commodore_sl386sx25_get_device },
{ "[SCAMP] Samsung SPC-6033P", "spc6033p", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 12288, 2048, 127, machine_at_spc6033p_init, at_spc6033p_get_device },
@@ -428,6 +434,10 @@ const machine_t machines[] = {
{ "[VIA Apollo Pro133A] Acorp 6VIA90AP", "6via90ap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1572864, 8192, 255, machine_at_6via90ap_init, NULL },
{ "[VIA Apollo ProMedia] Jetway 603TCF", "603tcf", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_603tcf_init, NULL },
/* EBGA368 machines */
/* VIA Apollo Pro */
{ "[VIA Apollo ProMedia] Acrosser AR-B9673", "arb9673", MACHINE_TYPE_EBGA368, CPU_PKG_EBGA368, 0, 66666667, 150000000, 1300, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 131072,131072, 0, 31, machine_at_arb9673_init, NULL },
/* Miscellaneous/Fake/Hypervisor machines */
{ "[i440BX] Microsoft Virtual PC 2007", "vpc2007", MACHINE_TYPE_MISC, CPU_PKG_SLOT1, CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), 0, 0, 0, 0, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_vpc2007_init, NULL },

541
src/minitrace/minitrace.c Normal file
View File

@@ -0,0 +1,541 @@
// minitrace
// Copyright 2014 by Henrik Rydgård
// http://www.github.com/hrydgard/minitrace
// Released under the MIT license.
// See minitrace.h for basic documentation.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#pragma warning (disable:4996)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifndef __MINGW32__
#define __thread __declspec(thread)
#endif
#define pthread_cond_t CONDITION_VARIABLE
#define pthread_cond_init(a) InitializeConditionVariable(a)
#define pthread_cond_wait(a, b) SleepConditionVariableCS(a, b, INFINITE)
#define pthread_cond_signal(a) WakeConditionVariable(a)
#define pthread_mutex_t CRITICAL_SECTION
#define pthread_mutex_init(a, b) InitializeCriticalSection(a)
#define pthread_mutex_lock(a) EnterCriticalSection(a)
#define pthread_mutex_unlock(a) LeaveCriticalSection(a)
#define pthread_mutex_destroy(a) DeleteCriticalSection(a)
#else
#include <signal.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#endif
#include <minitrace/minitrace.h>
#ifdef __GNUC__
#define ATTR_NORETURN __attribute__((noreturn))
#else
#define ATTR_NORETURN
#endif
#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])
#define TRUE 1
#define FALSE 0
// Ugh, this struct is already pretty heavy.
// Will probably need to move arguments to a second buffer to support more than one.
typedef struct raw_event {
const char *name;
const char *cat;
void *id;
int64_t ts;
uint32_t pid;
uint32_t tid;
char ph;
mtr_arg_type arg_type;
const char *arg_name;
union {
const char *a_str;
int a_int;
double a_double;
};
} raw_event_t;
static raw_event_t *event_buffer;
static raw_event_t *flush_buffer;
static volatile int event_count;
static __attribute__ ((aligned (32))) volatile long is_tracing = FALSE;
static __attribute__ ((aligned (32))) volatile long stop_flushing_requested = FALSE;
static int is_flushing = FALSE;
static int events_in_progress = 0;
static int64_t time_offset;
static int first_line = 1;
static FILE *f;
static __thread int cur_thread_id; // Thread local storage
static int cur_process_id;
static pthread_mutex_t mutex;
static pthread_mutex_t event_mutex;
static pthread_cond_t buffer_not_full_cond;
static pthread_cond_t buffer_full_cond;
#define STRING_POOL_SIZE 100
static char *str_pool[100];
// forward declaration
void mtr_flush_with_state(int);
// Tiny portability layer.
// Exposes:
// get_cur_thread_id()
// get_cur_process_id()
// mtr_time_s()
// pthread basics
#ifdef _WIN32
#define atomic_load(a) InterlockedOr((a), 0)
#define atomic_store(a, b) InterlockedExchange((a), b)
static int get_cur_thread_id() {
return (int)GetCurrentThreadId();
}
static int get_cur_process_id() {
return (int)GetCurrentProcessId();
}
static uint64_t _frequency = 0;
static uint64_t _starttime = 0;
double mtr_time_s() {
if (_frequency == 0) {
QueryPerformanceFrequency((LARGE_INTEGER*)&_frequency);
QueryPerformanceCounter((LARGE_INTEGER*)&_starttime);
}
__int64 time;
QueryPerformanceCounter((LARGE_INTEGER*)&time);
return ((double) (time - _starttime) / (double) _frequency);
}
// Ctrl+C handling for Windows console apps
static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) {
if (atomic_load(&is_tracing) && fdwCtrlType == CTRL_C_EVENT) {
printf("Ctrl-C detected! Flushing trace and shutting down.\n\n");
mtr_flush();
mtr_shutdown();
}
ExitProcess(1);
}
void mtr_register_sigint_handler() {
// For console apps:
SetConsoleCtrlHandler(&CtrlHandler, TRUE);
}
HANDLE thread_handle;
static DWORD WINAPI thread_flush_proc(void* param) {
while(TRUE) {
mtr_flush_with_state(FALSE);
if(atomic_load(&stop_flushing_requested)) {
break;
}
}
return 0;
}
static void init_flushing_thread(void) {
pthread_mutex_lock(&mutex);
is_flushing = FALSE;
pthread_mutex_unlock(&mutex);
thread_handle = CreateThread(NULL, 0, thread_flush_proc, (void*)0, 0, NULL);
}
static void join_flushing_thread(void) {
WaitForSingleObject(thread_handle, INFINITE);
}
#else
static inline int get_cur_thread_id() {
return (int)(intptr_t)pthread_self();
}
static inline int get_cur_process_id() {
return (int)getpid();
}
#if defined(BLACKBERRY)
double mtr_time_s() {
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time); // Linux must use CLOCK_MONOTONIC_RAW due to time warps
return time.tv_sec + time.tv_nsec / 1.0e9;
}
#else
double mtr_time_s() {
static time_t start;
struct timeval tv;
gettimeofday(&tv, NULL);
if (start == 0) {
start = tv.tv_sec;
}
tv.tv_sec -= start;
return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
}
#endif // !BLACKBERRY
static void termination_handler(int signum) ATTR_NORETURN;
static void termination_handler(int signum) {
(void) signum;
if (is_tracing) {
printf("Ctrl-C detected! Flushing trace and shutting down.\n\n");
mtr_flush();
fwrite("\n]}\n", 1, 4, f);
fclose(f);
}
exit(1);
}
void mtr_register_sigint_handler() {
#ifndef MTR_ENABLED
return;
#endif
// Avoid altering set-to-be-ignored handlers while registering.
if (signal(SIGINT, &termination_handler) == SIG_IGN)
signal(SIGINT, SIG_IGN);
}
#endif
void mtr_init_from_stream(void *stream) {
#ifndef MTR_ENABLED
return;
#endif
event_buffer = (raw_event_t *)malloc(INTERNAL_MINITRACE_BUFFER_SIZE * sizeof(raw_event_t));
flush_buffer = (raw_event_t *)malloc(INTERNAL_MINITRACE_BUFFER_SIZE * sizeof(raw_event_t));
event_count = 0;
f = (FILE *)stream;
const char *header = "{\"traceEvents\":[\n";
fwrite(header, 1, strlen(header), f);
time_offset = (uint64_t)(mtr_time_s() * 1000000);
first_line = 1;
pthread_mutex_init(&mutex, 0);
pthread_mutex_init(&event_mutex, 0);
}
void mtr_init(const char *json_file) {
#ifndef MTR_ENABLED
return;
#endif
mtr_init_from_stream(fopen(json_file, "wb"));
}
void mtr_shutdown() {
int i;
#ifndef MTR_ENABLED
return;
#endif
mtr_flush_with_state(TRUE);
fwrite("\n]}\n", 1, 4, f);
fclose(f);
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&event_mutex);
f = 0;
free(event_buffer);
event_buffer = 0;
for (i = 0; i < STRING_POOL_SIZE; i++) {
if (str_pool[i]) {
free(str_pool[i]);
str_pool[i] = 0;
}
}
}
const char *mtr_pool_string(const char *str) {
int i;
for (i = 0; i < STRING_POOL_SIZE; i++) {
if (!str_pool[i]) {
str_pool[i] = (char*)malloc(strlen(str) + 1);
strcpy(str_pool[i], str);
return str_pool[i];
} else {
if (!strcmp(str, str_pool[i]))
return str_pool[i];
}
}
return "string pool full";
}
void mtr_start() {
#ifndef MTR_ENABLED
return;
#endif
pthread_cond_init(&buffer_not_full_cond);
pthread_cond_init(&buffer_full_cond);
atomic_store(&is_tracing, TRUE);
init_flushing_thread();
}
void mtr_stop() {
#ifndef MTR_ENABLED
return;
#endif
atomic_store(&is_tracing, FALSE);
atomic_store(&stop_flushing_requested, TRUE);
pthread_cond_signal(&buffer_not_full_cond);
pthread_cond_signal(&buffer_full_cond);
join_flushing_thread();
atomic_store(&stop_flushing_requested, FALSE);
}
// TODO: fwrite more than one line at a time.
// Flushing is thread safe and process async
// using double-buffering mechanism.
// Aware: only one flushing process may be
// running at any point of time
void mtr_flush_with_state(int is_last) {
#ifndef MTR_ENABLED
return;
#endif
int i = 0;
char linebuf[1024];
char arg_buf[1024];
char id_buf[256];
int event_count_copy = 0;
int events_in_progress_copy = 1;
raw_event_t *event_buffer_tmp = NULL;
// small critical section to swap buffers
// - no any new events can be spawn while
// swapping since they tied to the same mutex
// - checks for any flushing in process
pthread_mutex_lock(&mutex);
// if not flushing already
if (is_flushing) {
pthread_mutex_unlock(&mutex);
return;
}
is_flushing = TRUE;
if(!is_last) {
while(event_count < INTERNAL_MINITRACE_BUFFER_SIZE && atomic_load(&is_tracing)) {
pthread_cond_wait(&buffer_full_cond, &mutex);
}
}
event_count_copy = event_count;
event_buffer_tmp = flush_buffer;
flush_buffer = event_buffer;
event_buffer = event_buffer_tmp;
event_count = 0;
// waiting for any unfinished events before swap
while (events_in_progress_copy != 0) {
pthread_mutex_lock(&event_mutex);
events_in_progress_copy = events_in_progress;
pthread_mutex_unlock(&event_mutex);
}
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&buffer_not_full_cond);
for (i = 0; i < event_count_copy; i++) {
raw_event_t *raw = &flush_buffer[i];
int len;
switch (raw->arg_type) {
case MTR_ARG_TYPE_INT:
snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":%i", raw->arg_name, raw->a_int);
break;
case MTR_ARG_TYPE_STRING_CONST:
snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":\"%s\"", raw->arg_name, raw->a_str);
break;
case MTR_ARG_TYPE_STRING_COPY:
if (strlen(raw->a_str) > 700) {
snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":\"%.*s\"", raw->arg_name, 700, raw->a_str);
} else {
snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":\"%s\"", raw->arg_name, raw->a_str);
}
break;
case MTR_ARG_TYPE_NONE:
arg_buf[0] = '\0';
break;
}
if (raw->id) {
switch (raw->ph) {
case 'S':
case 'T':
case 'F':
// TODO: Support full 64-bit pointers
snprintf(id_buf, ARRAY_SIZE(id_buf), ",\"id\":\"0x%08x\"", (uint32_t)(uintptr_t)raw->id);
break;
case 'X':
snprintf(id_buf, ARRAY_SIZE(id_buf), ",\"dur\":%i", (int)raw->a_double);
break;
}
} else {
id_buf[0] = 0;
}
const char *cat = raw->cat;
#ifdef _WIN32
// On Windows, we often end up with backslashes in category.
char temp[256];
{
int len = (int)strlen(cat);
int i;
if (len > 255) len = 255;
for (i = 0; i < len; i++) {
temp[i] = cat[i] == '\\' ? '/' : cat[i];
}
temp[len] = 0;
cat = temp;
}
#endif
len = snprintf(linebuf, ARRAY_SIZE(linebuf), "%s{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ",\"ph\":\"%c\",\"name\":\"%s\",\"args\":{%s}%s}",
first_line ? "" : ",\n",
cat, raw->pid, raw->tid, raw->ts - time_offset, raw->ph, raw->name, arg_buf, id_buf);
fwrite(linebuf, 1, len, f);
first_line = 0;
if (raw->arg_type == MTR_ARG_TYPE_STRING_COPY) {
free((void*)raw->a_str);
}
#ifdef MTR_COPY_EVENT_CATEGORY_AND_NAME
free(raw->name);
free(raw->cat);
#endif
}
pthread_mutex_lock(&mutex);
is_flushing = is_last;
pthread_mutex_unlock(&mutex);
}
void mtr_flush() {
mtr_flush_with_state(FALSE);
}
void internal_mtr_raw_event(const char *category, const char *name, char ph, void *id) {
#ifndef MTR_ENABLED
return;
#endif
if (!atomic_load(&is_tracing)) {
return;
}
pthread_mutex_lock(&mutex);
while(event_count >= INTERNAL_MINITRACE_BUFFER_SIZE && atomic_load(&is_tracing)) {
pthread_cond_wait(&buffer_not_full_cond, &mutex);
}
raw_event_t *ev = &event_buffer[event_count];
++event_count;
pthread_mutex_lock(&event_mutex);
++events_in_progress;
pthread_mutex_unlock(&event_mutex);
int local_event_count = event_count;
pthread_mutex_unlock(&mutex);
if(local_event_count >= INTERNAL_MINITRACE_BUFFER_SIZE) {
pthread_cond_signal(&buffer_full_cond);
}
double ts = mtr_time_s();
if (!cur_thread_id) {
cur_thread_id = get_cur_thread_id();
}
if (!cur_process_id) {
cur_process_id = get_cur_process_id();
}
#ifdef MTR_COPY_EVENT_CATEGORY_AND_NAME
const size_t category_len = strlen(category);
ev->cat = malloc(category_len + 1);
strcpy(ev->cat, category);
const size_t name_len = strlen(name);
ev->name = malloc(name_len + 1);
strcpy(ev->name, name);
#else
ev->cat = category;
ev->name = name;
#endif
ev->id = id;
ev->ph = ph;
if (ev->ph == 'X') {
double x;
memcpy(&x, id, sizeof(double));
ev->ts = (int64_t)(x * 1000000);
ev->a_double = (ts - x) * 1000000;
} else {
ev->ts = (int64_t)(ts * 1000000);
}
ev->tid = cur_thread_id;
ev->pid = cur_process_id;
ev->arg_type = MTR_ARG_TYPE_NONE;
pthread_mutex_lock(&event_mutex);
--events_in_progress;
pthread_mutex_unlock(&event_mutex);
}
void internal_mtr_raw_event_arg(const char *category, const char *name, char ph, void *id, mtr_arg_type arg_type, const char *arg_name, void *arg_value) {
#ifndef MTR_ENABLED
return;
#endif
if (!atomic_load(&is_tracing)) {
return;
}
pthread_mutex_lock(&mutex);
while(event_count >= INTERNAL_MINITRACE_BUFFER_SIZE && atomic_load(&is_tracing)) {
pthread_cond_wait(&buffer_not_full_cond, &mutex);
}
raw_event_t *ev = &event_buffer[event_count];
++event_count;
pthread_mutex_lock(&event_mutex);
++events_in_progress;
pthread_mutex_unlock(&event_mutex);
int local_event_count = event_count;
pthread_mutex_unlock(&mutex);
if(local_event_count >= INTERNAL_MINITRACE_BUFFER_SIZE) {
pthread_cond_signal(&buffer_full_cond);
}
if (!cur_thread_id) {
cur_thread_id = get_cur_thread_id();
}
if (!cur_process_id) {
cur_process_id = get_cur_process_id();
}
double ts = mtr_time_s();
#ifdef MTR_COPY_EVENT_CATEGORY_AND_NAME
const size_t category_len = strlen(category);
ev->cat = malloc(category_len + 1);
strcpy(ev->cat, category);
const size_t name_len = strlen(name);
ev->name = malloc(name_len + 1);
strcpy(ev->name, name);
#else
ev->cat = category;
ev->name = name;
#endif
ev->id = id;
ev->ts = (int64_t)(ts * 1000000);
ev->ph = ph;
ev->tid = cur_thread_id;
ev->pid = cur_process_id;
ev->arg_type = arg_type;
ev->arg_name = arg_name;
switch (arg_type) {
case MTR_ARG_TYPE_INT: ev->a_int = (int)(uintptr_t)arg_value; break;
case MTR_ARG_TYPE_STRING_CONST: ev->a_str = (const char*)arg_value; break;
case MTR_ARG_TYPE_STRING_COPY: ev->a_str = strdup((const char*)arg_value); break;
case MTR_ARG_TYPE_NONE: break;
}
pthread_mutex_lock(&event_mutex);
--events_in_progress;
pthread_mutex_unlock(&event_mutex);
}

View File

@@ -89,6 +89,9 @@ int dopause, /* system is paused */
uint64_t timer_freq;
char emu_version[200]; /* version ID string */
#ifdef MTR_ENABLED
int tracing_on = 0;
#endif
/* Commandline options. */
int dump_on_exit = 0; /* (O) dump regs on exit */

View File

@@ -56,6 +56,7 @@
#define SYM53C860_SDMS4_ROM L"roms/scsi/ncr53c8xx/860/8XX_64.ROM"
#define NCR53C875_SDMS3_ROM L"roms/scsi/ncr53c8xx/875/NCR307.BIN"
#define SYM53C875_SDMS4_ROM L"roms/scsi/ncr53c8xx/875/8XX_64.ROM"
// #define SYM53C875_SDMS4_ROM L"roms/scsi/ncr53c8xx/875/8xx_64.rom.419"
#define HA_ID 7
@@ -217,7 +218,7 @@ typedef enum
typedef struct {
wchar_t *nvr_path;
uint8_t pci_slot;
uint8_t chip;
uint8_t chip, wide;
int has_bios;
int BIOSBase;
rom_t bios;
@@ -314,6 +315,8 @@ typedef struct {
uint8_t regop;
uint32_t adder;
uint32_t bios_mask;
pc_timer_t timer;
#ifdef USE_WDTR
@@ -412,7 +415,7 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev)
dev->scntl0 = 0xc0;
dev->scntl1 = 0;
dev->scntl2 = 0;
if (dev->chip >= CHIP_825)
if (dev->wide)
dev->scntl3 = 8;
else
dev->scntl3 = 0;
@@ -439,7 +442,7 @@ ncr53c8xx_soft_reset(ncr53c8xx_t *dev)
dev->sstop = 1;
dev->gpcntl = 0x03;
if (dev->chip >= CHIP_825) {
if (dev->wide) {
/* This *IS* a wide SCSI controller, so reset all SCSI
devices. */
for (i = 0; i < 16; i++) {
@@ -1671,7 +1674,7 @@ ncr53c8xx_reg_writeb(ncr53c8xx_t *dev, uint32_t offset, uint8_t val)
dev->respid0 = val;
break;
case 0x4b: /* RESPID1 */
if (dev->chip >= CHIP_825)
if (dev->wide)
dev->respid1 = val;
break;
case 0x4d: /* STEST1 */
@@ -1723,19 +1726,19 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset)
case addr + 3: return (dev->name >> 24) & 0xff;
#define CASE_GET_REG32_COND(name, addr) \
case addr: if (dev->chip >= CHIP_825) \
case addr: if (dev->wide) \
return dev->name & 0xff; \
else \
return 0x00; \
case addr + 1: if (dev->chip >= CHIP_825) \
case addr + 1: if (dev->wide) \
return (dev->name >> 8) & 0xff; \
else \
return 0x00; \
case addr + 2: if (dev->chip >= CHIP_825) \
case addr + 2: if (dev->wide) \
return (dev->name >> 16) & 0xff; \
else \
return 0x00; \
case addr + 3: if (dev->chip >= CHIP_825) \
case addr + 3: if (dev->wide) \
return (dev->name >> 24) & 0xff; \
else \
return 0x00;
@@ -1819,12 +1822,12 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset)
tmp = dev->istat;
return tmp;
case 0x16: /* MBOX0 */
if (dev->chip >= CHIP_825)
if (dev->wide)
return 0x00;
ncr53c8xx_log("NCR 810: Read MBOX0 %02X\n", dev->mbox0);
return dev->mbox0;
case 0x17: /* MBOX1 */
if (dev->chip >= CHIP_825)
if (dev->wide)
return 0x00;
ncr53c8xx_log("NCR 810: Read MBOX1 %02X\n", dev->mbox1);
return dev->mbox1;
@@ -1899,12 +1902,12 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset)
ncr53c8xx_log("NCR 810: Read SIST1 %02X\n", tmp);
return tmp;
case 0x44: /* SLPAR */
if (dev->chip < CHIP_825)
if (!dev->wide)
return 0x00;
ncr53c8xx_log("NCR 810: Read SLPAR %02X\n", dev->stime0);
return dev->slpar;
case 0x45: /* SWIDE */
if (dev->chip < CHIP_825)
if (!dev->wide)
return 0x00;
ncr53c8xx_log("NCR 810: Read SWIDE %02X\n", dev->stime0);
return dev->swide;
@@ -1918,13 +1921,14 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset)
ncr53c8xx_log("NCR 810: Read STIME0 %02X\n", dev->stime0);
return dev->stime0;
case 0x4a: /* RESPID0 */
if (dev->chip >= CHIP_825)
if (dev->wide) {
ncr53c8xx_log("NCR 810: Read RESPID0 %02X\n", dev->respid0);
else
} else {
ncr53c8xx_log("NCR 810: Read RESPID %02X\n", dev->respid0);
}
return dev->respid0;
case 0x4b: /* RESPID1 */
if (dev->chip < CHIP_825)
if (!dev->wide)
return 0x00;
ncr53c8xx_log("NCR 810: Read RESPID1 %02X\n", dev->respid1);
return dev->respid1;
@@ -1943,13 +1947,14 @@ ncr53c8xx_reg_readb(ncr53c8xx_t *dev, uint32_t offset)
case 0x50: /* SIDL0 */
/* This is needed by the linux drivers. We currently only update it
during the MSG IN phase. */
if (dev->chip >= CHIP_825)
if (dev->wide) {
ncr53c8xx_log("NCR 810: Read SIDL0 %02X\n", dev->sidl0);
else
} else {
ncr53c8xx_log("NCR 810: Read SIDL %02X\n", dev->sidl0);
}
return dev->sidl0;
case 0x51: /* SIDL1 */
if (dev->chip < CHIP_825)
if (!dev->wide)
return 0x00;
ncr53c8xx_log("NCR 810: Read SIDL1 %02X\n", dev->sidl1);
return dev->sidl1;
@@ -2241,7 +2246,10 @@ ncr53c8xx_ram_set_addr(ncr53c8xx_t *dev, uint32_t base)
static void
ncr53c8xx_bios_set_addr(ncr53c8xx_t *dev, uint32_t base)
{
mem_mapping_set_addr(&dev->bios.mapping, base, 0x10000);
if (dev->has_bios == 2)
mem_mapping_set_addr(&dev->bios.mapping, base, 0x10000);
else if (dev->has_bios == 1)
mem_mapping_set_addr(&dev->bios.mapping, base, 0x04000);
}
@@ -2327,25 +2335,25 @@ ncr53c8xx_pci_read(int func, int addr, void *p)
case 0x18:
return 0; /*Memory space*/
case 0x19:
if (dev->chip == CHIP_815 || dev->chip < CHIP_825)
if (!dev->wide)
return 0;
return ncr53c8xx_pci_bar[2].addr_regs[1];
case 0x1A:
if (dev->chip == CHIP_815 || dev->chip < CHIP_825)
if (!dev->wide)
return 0;
return ncr53c8xx_pci_bar[2].addr_regs[2];
case 0x1B:
if (dev->chip == CHIP_815 || dev->chip < CHIP_825)
if (!dev->wide)
return 0;
return ncr53c8xx_pci_bar[2].addr_regs[3];
case 0x2C:
return 0x00;
case 0x2D:
if (dev->chip >= CHIP_825 || dev->chip != CHIP_815)
if (dev->wide)
return 0;
return 0x10;
case 0x2E:
if (dev->chip >= CHIP_825 || dev->chip != CHIP_815)
if (dev->wide)
return 0;
return 0x01;
case 0x2F:
@@ -2398,7 +2406,7 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p)
ncr53c8xx_mem_disable(dev);
if ((dev->MMIOBase != 0) && (val & PCI_COMMAND_MEM))
ncr53c8xx_mem_set_addr(dev, dev->MMIOBase);
if (dev->chip != CHIP_815 || dev->chip >= CHIP_825) {
if (dev->wide) {
ncr53c8xx_ram_disable(dev);
if ((dev->RAMBase != 0) && (val & PCI_COMMAND_MEM))
ncr53c8xx_ram_set_addr(dev, dev->RAMBase);
@@ -2442,8 +2450,8 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p)
/* Then let's set the PCI regs. */
ncr53c8xx_pci_bar[1].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */
ncr53c8xx_pci_bar[1].addr &= 0xfffcf000;
dev->MMIOBase = ncr53c8xx_pci_bar[1].addr & 0xfffcf000;
ncr53c8xx_pci_bar[1].addr &= 0xffffc000;
dev->MMIOBase = ncr53c8xx_pci_bar[1].addr & 0xffffc000;
/* Log the new base. */
ncr53c8xx_log("NCR53c8xx: New MMIO base is %08X\n" , dev->MMIOBase);
/* We're done, so get out of the here. */
@@ -2454,7 +2462,7 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p)
return;
case 0x19: case 0x1A: case 0x1B:
if (dev->chip == CHIP_815 || dev->chip < CHIP_825)
if (!dev->wide)
return;
/* RAM Base set. */
/* First, remove the old I/O. */
@@ -2462,8 +2470,8 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p)
/* Then let's set the PCI regs. */
ncr53c8xx_pci_bar[2].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */
ncr53c8xx_pci_bar[2].addr &= 0xfffcf000;
dev->RAMBase = ncr53c8xx_pci_bar[2].addr & 0xfffcf000;
ncr53c8xx_pci_bar[2].addr &= 0xfffff000;
dev->RAMBase = ncr53c8xx_pci_bar[2].addr & 0xfffff000;
/* Log the new base. */
ncr53c8xx_log("NCR53c8xx: New RAM base is %08X\n" , dev->RAMBase);
/* We're done, so get out of the here. */
@@ -2482,14 +2490,14 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p)
/* Then let's set the PCI regs. */
ncr53c8xx_pci_bar[3].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */
ncr53c8xx_pci_bar[3].addr &= 0xfffcf001;
dev->BIOSBase = ncr53c8xx_pci_bar[3].addr & 0xfffcf000;
ncr53c8xx_pci_bar[3].addr &= (dev->bios_mask | 0x00000001);
dev->BIOSBase = ncr53c8xx_pci_bar[3].addr & dev->bios_mask;
pclog("BIOS BAR: %08X\n", dev->BIOSBase | ncr53c8xx_pci_bar[3].addr_regs[0]);
/* Log the new base. */
ncr53c8xx_log("NCR53c8xx: New BIOS base is %08X\n" , dev->BIOSBase);
/* We're done, so get out of the here. */
if (ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01) {
if (ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01)
ncr53c8xx_bios_set_addr(dev, dev->BIOSBase);
}
return;
case 0x3C:
@@ -2513,54 +2521,63 @@ ncr53c8xx_init(const device_t *info)
dev->chip = info->local & 0xff;
if (info->local & 0x8000)
dev->has_bios = 0;
else
if ((dev->chip != CHIP_810) && (dev->chip != CHIP_820) && !(info->local & 0x8000))
dev->has_bios = device_get_config_int("bios");
else
dev->has_bios = 0;
if (dev->chip == CHIP_875) {
if (dev->has_bios == 2)
rom_init(&dev->bios, SYM53C875_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&dev->bios, SYM53C875_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else if (dev->has_bios == 1)
rom_init(&dev->bios, NCR53C875_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
dev->chip_rev = 0x04;
dev->nvr_path = L"ncr53c875.nvr";
dev->wide = 1;
} else if (dev->chip == CHIP_860) {
if (dev->has_bios == 2)
rom_init(&dev->bios, SYM53C860_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&dev->bios, SYM53C860_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else if (dev->has_bios == 1)
rom_init(&dev->bios, NCR53C860_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
dev->chip_rev = 0x04;
dev->nvr_path = L"ncr53c860.nvr";
dev->wide = 1;
} else if (dev->chip == CHIP_820) {
dev->nvr_path = L"ncr53c820.nvr";
dev->wide = 1;
} else if (dev->chip == CHIP_825) {
if (dev->has_bios == 2)
rom_init(&dev->bios, SYM53C825A_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&dev->bios, SYM53C825A_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else if (dev->has_bios == 1)
rom_init(&dev->bios, NCR53C825A_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
dev->chip_rev = 0x26;
dev->nvr_path = L"ncr53c825a.nvr";
dev->wide = 1;
} else if (dev->chip == CHIP_810) {
if (dev->has_bios == 2)
rom_init(&dev->bios, SYM53C810_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else if (dev->has_bios == 1)
rom_init(&dev->bios, NCR53C810_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
dev->nvr_path = L"ncr53c810.nvr";
dev->wide = 0;
} else if (dev->chip == CHIP_815) {
if (dev->has_bios == 2)
rom_init(&dev->bios, SYM53C815_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
rom_init(&dev->bios, SYM53C815_SDMS4_ROM, 0xd0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
else if (dev->has_bios == 1)
rom_init(&dev->bios, NCR53C815_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
dev->chip_rev = 0x04;
dev->nvr_path = L"ncr53c815.nvr";
dev->wide = 0;
}
ncr53c8xx_pci_bar[0].addr_regs[0] = 1;
ncr53c8xx_pci_bar[1].addr_regs[0] = 0;
ncr53c8xx_pci_regs[0x04] = 3;
if (dev->has_bios) {
if (dev->has_bios == 2) {
ncr53c8xx_pci_bar[3].addr = 0xffff0000;
dev->bios_mask = 0xffff0000;
} else if (dev->has_bios == 1) {
ncr53c8xx_pci_bar[3].addr = 0xffffc000;
dev->bios_mask = 0xffffc000;
} else {
ncr53c8xx_pci_bar[3].addr = 0;
ncr53c8xx_pci_bar[3].addr = 0x00000000;
dev->bios_mask = 0x00000000;
}
ncr53c8xx_mem_init(dev, 0x0fffff00);
@@ -2568,10 +2585,8 @@ ncr53c8xx_init(const device_t *info)
ncr53c8xx_pci_bar[2].addr_regs[0] = 0;
if (dev->chip >= CHIP_825 || (dev->chip != CHIP_815)) {
/* Need to make it align on a 16k boundary as that's this emulator's
memory mapping granularity. */
ncr53c8xx_ram_init(dev, 0x0fffc000);
if (dev->wide) {
ncr53c8xx_ram_init(dev, 0x0ffff000);
ncr53c8xx_ram_disable(dev);
}
@@ -2643,7 +2658,7 @@ const device_t ncr53c810_pci_device =
CHIP_810,
ncr53c8xx_init, ncr53c8xx_close, NULL,
{ NULL }, NULL, NULL,
ncr53c8xx_pci_config
NULL
};
const device_t ncr53c810_onboard_pci_device =
@@ -2666,6 +2681,16 @@ const device_t ncr53c815_pci_device =
ncr53c8xx_pci_config
};
const device_t ncr53c820_pci_device =
{
"NCR 53c820",
DEVICE_PCI,
CHIP_820,
ncr53c8xx_init, ncr53c8xx_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
const device_t ncr53c825a_pci_device =
{
"NCR 53c825A",

View File

@@ -15,7 +15,7 @@
add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c661.c
sio_fdc37c66x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c
sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87311.c sio_pc87332.c
sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c
sio_prime3b.c sio_prime3c.c
sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c
sio_vt82c686.c)

283
src/sio/sio_pc87310.c Normal file
View File

@@ -0,0 +1,283 @@
/*
* 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.
*
* Emulation of the NatSemi PC87310 Super I/O chip.
*
*
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Tiseno100
* EngiNerd <webmaster.crrc@yahoo.it>
*
* Copyright 2020 Miran Grca.
* Copyright 2020 Tiseno100
* Copyright 2021 EngiNerd.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/device.h>
#include <86box/lpt.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/pci.h>
#include <86box/rom.h>
#include <86box/serial.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/sio.h>
#define HAS_IDE_FUNCTIONALITY dev->ide_function
#ifdef ENABLE_PC87310_LOG
int pc87310_do_log = ENABLE_PC87310_LOG;
static void
pc87310_log(const char *fmt, ...)
{
va_list ap;
if (pc87310_do_log)
{
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define pc87310_log(fmt, ...)
#endif
typedef struct {
uint8_t tries, ide_function,
reg;
fdc_t *fdc;
serial_t *uart[2];
} pc87310_t;
static void
lpt1_handler(pc87310_t *dev)
{
int temp;
uint16_t lpt_port = 0x378;
uint8_t lpt_irq = 7;
/* bits 0-1:
* 00 378h
* 01 3bch
* 10 278h
* 11 disabled
*/
temp = dev->reg & 3;
switch (temp) {
case 0:
lpt_port = 0x378;
break;
case 1:
lpt_port = 0x3bc;
break;
case 2:
lpt_port = 0x278;
break;
case 3:
lpt_port = 0x000;
lpt_irq = 0xff;
break;
}
if (lpt_port)
lpt1_init(lpt_port);
lpt1_irq(lpt_irq);
}
static void
serial_handler(pc87310_t *dev, int uart)
{
int temp;
/* bit 2: disable serial port 1
* bit 3: disable serial port 2
* bit 4: swap serial ports
*/
temp = (dev->reg >> (2 + uart)) & 1;
//current serial port is enabled
if (!temp){
//configure serial port as COM2
if (((dev->reg >> 4) & 1) ^ uart)
serial_setup(dev->uart[uart], 0x2f8, 3);
// configure serial port as COM1
else
serial_setup(dev->uart[uart], 0x3f8, 4);
}
}
static void
pc87310_write(uint16_t port, uint8_t val, void *priv)
{
pc87310_t *dev = (pc87310_t *) priv;
uint8_t valxor;
// second write to config register
if (dev->tries) {
valxor = val ^ dev->reg;
dev->tries = 0;
dev->reg = val;
// first write to config register
} else {
dev->tries++;
return;
}
pc87310_log("SIO: written %01X\n", val);
/* reconfigure parallel port */
if (valxor & 0x03) {
lpt1_remove();
/* bits 0-1: 11 disable parallel port */
if (!((val & 1) && (val & 2)))
lpt1_handler(dev);
}
/* reconfigure serial ports */
if (valxor & 0x1c) {
serial_remove(dev->uart[0]);
serial_remove(dev->uart[1]);
/* bit 2: 1 disable first serial port */
if (!(val & 4))
serial_handler(dev, 0);
/* bit 3: 1 disable second serial port */
if (!(val & 8))
serial_handler(dev, 1);
}
/* reconfigure IDE controller */
if (valxor & 0x20) {
pc87310_log("SIO: HDC disabled\n");
ide_pri_disable();
/* bit 5: 1 disable ide controller */
if (!(val & 0x20) && HAS_IDE_FUNCTIONALITY) {
pc87310_log("SIO: HDC enabled\n");
ide_set_base(0, 0x1f0);
ide_set_side(0, 0x3f6);
ide_pri_enable();
}
}
/* reconfigure floppy disk controller */
if (valxor & 0x40) {
pc87310_log("SIO: FDC disabled\n");
fdc_remove(dev->fdc);
/* bit 6: 1 disable fdc */
if (!(val & 0x40)) {
pc87310_log("SIO: FDC enabled\n");
fdc_set_base(dev->fdc, 0x3f0);
}
}
return;
}
uint8_t
pc87310_read(uint16_t port, void *priv)
{
pc87310_t *dev = (pc87310_t *) priv;
uint8_t ret = 0xff;
dev->tries = 0;
ret = dev->reg;
pc87310_log("SIO: read %01X\n", ret);
return ret;
}
void
pc87310_reset(pc87310_t *dev)
{
dev->reg = 0x0;
dev->tries = 0;
/*
0 = 360 rpm @ 500 kbps for 3.5"
1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5"
*/
lpt1_remove();
lpt1_handler(dev);
serial_remove(dev->uart[0]);
serial_remove(dev->uart[1]);
serial_handler(dev, 0);
serial_handler(dev, 1);
fdc_reset(dev->fdc);
//ide_pri_enable();
}
static void
pc87310_close(void *priv)
{
pc87310_t *dev = (pc87310_t *) priv;
free(dev);
}
static void *
pc87310_init(const device_t *info)
{
pc87310_t *dev = (pc87310_t *) malloc(sizeof(pc87310_t));
memset(dev, 0, sizeof(pc87310_t));
/* Avoid conflicting with machines that make no use of the PC87310 Internal IDE */
HAS_IDE_FUNCTIONALITY = info->local;
dev->fdc = device_add(&fdc_at_nsc_device);
dev->uart[0] = device_add_inst(&ns16550_device, 1);
dev->uart[1] = device_add_inst(&ns16550_device, 2);
if (HAS_IDE_FUNCTIONALITY)
device_add(&ide_isa_device);
pc87310_reset(dev);
io_sethandler(0x3f3, 0x0001,
pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev);
return dev;
}
const device_t pc87310_device = {
"National Semiconductor PC87310 Super I/O",
0,
0,
pc87310_init, pc87310_close, NULL,
{ NULL }, NULL, NULL,
NULL
};
const device_t pc87310_ide_device = {
"National Semiconductor PC87310 Super I/O with IDE functionality",
0,
1,
pc87310_init, pc87310_close, NULL,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -33,10 +33,6 @@ if(NOT MSVC)
target_compile_options(vid PRIVATE "-msse2")
endif()
if(CL5422)
target_compile_definitions(vid PRIVATE USE_CL5422)
endif()
if(MGA)
target_compile_definitions(vid PRIVATE USE_MGA)
target_sources(vid PRIVATE vid_mga.c)

View File

@@ -138,7 +138,6 @@ cga_write(uint32_t addr, uint8_t val, void *p)
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
}
egawrites++;
cga_waitstates(cga);
}
@@ -154,7 +153,6 @@ cga_read(uint32_t addr, void *p)
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
}
egareads++;
return cga->vram[addr & 0x3fff];
}

View File

@@ -99,7 +99,6 @@ void colorplus_write(uint32_t addr, uint8_t val, void *p)
colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff];
colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff];
}
egawrites++;
cycles -= 4;
}
@@ -124,7 +123,6 @@ uint8_t colorplus_read(uint32_t addr, void *p)
colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff];
colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff];
}
egareads++;
return colorplus->cga.vram[addr & 0x7fff];
}

View File

@@ -43,6 +43,7 @@ void ega_doblit(int y1, int y2, int wx, int wy, ega_t *ega);
#define BIOS_SEGA_PATH L"roms/video/ega/lega.vbi"
#define BIOS_ATIEGA_PATH L"roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN"
#define BIOS_ISKRA_PATH L"roms/video/ega/143-02.bin", L"roms/video/ega/143-03.bin"
#define BIOS_TSENG_PATH L"roms/video/ega/EGA ET2000.BIN"
enum {
@@ -50,14 +51,15 @@ enum {
EGA_COMPAQ,
EGA_SUPEREGA,
EGA_ATI,
EGA_ISKRA
EGA_ISKRA,
EGA_TSENG
};
static video_timings_t timing_ega = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
static uint8_t ega_rotate[8][256];
static uint32_t pallook16[256], pallook64[256];
static int old_overscan_color = 0;
static int ega_type = 0, old_overscan_color = 0;
extern uint8_t edatlookup[4][4];
@@ -256,38 +258,48 @@ uint8_t ega_in(uint16_t addr, void *p)
break;
case 0x3c0:
ret = ega->attraddr | ega->attr_palette_enable;
if (ega_type)
ret = ega->attraddr | ega->attr_palette_enable;
break;
case 0x3c1:
ret = ega->attrregs[ega->attraddr];
if (ega_type)
ret = ega->attrregs[ega->attraddr];
break;
case 0x3c2:
ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00;
break;
case 0x3c4:
ret = ega->seqaddr;
if (ega_type)
ret = ega->seqaddr;
break;
case 0x3c5:
ret = ega->seqregs[ega->seqaddr & 0xf];
if (ega_type)
ret = ega->seqregs[ega->seqaddr & 0xf];
break;
case 0x3c8:
ret = 2;
if (ega_type)
ret = 2;
break;
case 0x3cc:
ret = ega->miscout;
if (ega_type)
ret = ega->miscout;
break;
case 0x3ce:
ret = ega->gdcaddr;
if (ega_type)
ret = ega->gdcaddr;
break;
case 0x3cf:
ret = ega->gdcreg[ega->gdcaddr & 0xf];
if (ega_type)
ret = ega->gdcreg[ega->gdcaddr & 0xf];
break;
case 0x3d0: case 0x3d4:
ret = ega->crtcreg;
if (ega_type)
ret = ega->crtcreg;
break;
case 0x3d1:
case 0x3d5:
ret = ega->crtc[ega->crtcreg];
if (ega_type)
ret = ega->crtc[ega->crtcreg];
break;
case 0x3da:
ega->attrff = 0;
@@ -731,7 +743,6 @@ ega_write(uint32_t addr, uint8_t val, void *p)
uint8_t vala, valb, valc, vald;
int writemask2 = ega->writemask;
egawrites++;
cycles -= video_timing_write_b;
if (addr >= 0xB0000) addr &= 0x7fff;
@@ -858,7 +869,6 @@ ega_read(uint32_t addr, void *p)
uint8_t temp, temp2, temp3, temp4;
int readplane = ega->readplane;
egareads++;
cycles -= video_timing_read_b;
if (addr >= 0xb0000) addr &= 0x7fff;
else addr &= 0xffff;
@@ -1021,6 +1031,12 @@ ega_standalone_init(const device_t *info)
ega->x_add = 8;
ega->y_add = 14;
if ((info->local == EGA_IBM) || (info->local == EGA_ISKRA) ||
(info->local == EGA_TSENG))
ega_type = 0;
else
ega_type = 1;
switch(info->local) {
case EGA_IBM:
default:
@@ -1043,6 +1059,10 @@ ega_standalone_init(const device_t *info)
rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
case EGA_TSENG:
rom_init(&ega->bios_rom, BIOS_TSENG_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
break;
}
if ((ega->bios_rom.rom[0x3ffe] == 0xaa) && (ega->bios_rom.rom[0x3fff] == 0x55)) {
@@ -1101,6 +1121,20 @@ atiega_standalone_available(void)
}
static int
iskra_ega_standalone_available(void)
{
return rom_present(L"roms/video/ega/143-02.bin") && rom_present(L"roms/video/ega/143-03.bin");
}
static int
et2000_standalone_available(void)
{
return rom_present(BIOS_TSENG_PATH);
}
static void
ega_close(void *p)
{
@@ -1250,8 +1284,20 @@ const device_t iskra_ega_device =
DEVICE_ISA,
EGA_ISKRA,
ega_standalone_init, ega_close, NULL,
{ ega_standalone_available },
{ iskra_ega_standalone_available },
ega_speed_changed,
NULL,
ega_config
};
};
const device_t et2000_device =
{
"Tseng Labs ET2000",
DEVICE_ISA,
EGA_TSENG,
ega_standalone_init, ega_close, NULL,
{ et2000_standalone_available },
ega_speed_changed,
NULL,
ega_config
};

View File

@@ -261,7 +261,6 @@ void
genius_write(uint32_t addr, uint8_t val, void *p)
{
genius_t *genius = (genius_t *)p;
egawrites++;
genius_waitstates();
if (genius->genius_control & 1) {
@@ -288,7 +287,6 @@ genius_read(uint32_t addr, void *p)
{
genius_t *genius = (genius_t *)p;
uint8_t ret;
egareads++;
genius_waitstates();
if (genius->genius_control & 1) {

View File

@@ -53,8 +53,12 @@ typedef struct ht216_t
uint32_t read_banks[2], write_banks[2];
uint8_t bg_latch[8];
uint8_t fg_latch[4];
uint8_t bg_plane_sel, fg_plane_sel;
uint8_t ht_regs[256];
uint8_t pos_regs[8];
} ht216_t;
@@ -94,7 +98,7 @@ uint8_t ht216_in(uint16_t addr, void *p);
#define BIOS_VIDEO7_VGA_1024I_PATH L"roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN"
static video_timings_t timing_v7vga_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10};
static video_timings_t timing_v7vga_vlb = {VIDEO_ISA, 5, 5, 9, 20, 20, 30};
static video_timings_t timing_v7vga_vlb = {VIDEO_BUS, 5, 5, 9, 20, 20, 30};
#ifdef ENABLE_HT216_LOG
@@ -140,6 +144,10 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
svga_recalctimings(svga);
break;
case 0x3c4:
svga->seqaddr = val;
break;
case 0x3c5:
if (svga->seqaddr == 4) {
svga->chain4 = val & 8;
@@ -152,6 +160,7 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
} else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable) {
old = ht216->ht_regs[svga->seqaddr & 0xff];
ht216->ht_regs[svga->seqaddr & 0xff] = val;
switch (svga->seqaddr & 0xff) {
case 0x83:
svga->attraddr = val & 0x1f;
@@ -161,6 +170,8 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
case 0x94:
case 0xff:
svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2;
if (svga->crtc[0x17] == 0xeb) /*Looks like that 1024x768 mono mode expects 512K of video memory*/
svga->hwcursor.addr += 0x40000;
break;
case 0x9c: case 0x9d:
svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8);
@@ -203,14 +214,41 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
case 0xe9:
ht216_remap(ht216);
break;
case 0xec:
ht216->fg_latch[0] = val;
break;
case 0xed:
ht216->fg_latch[1] = val;
break;
case 0xee:
ht216->fg_latch[2] = val;
break;
case 0xef:
ht216->fg_latch[3] = val;
break;
case 0xf0:
ht216->fg_latch[ht216->fg_plane_sel] = val;
ht216->fg_plane_sel = (ht216->fg_plane_sel + 1) & 3;
break;
case 0xf1:
ht216->bg_plane_sel = val & 3;
ht216->fg_plane_sel = (val & 0x30) >> 4;
break;
case 0xf2:
svga->latch.b[ht216->bg_plane_sel] = val;
ht216->bg_plane_sel = (ht216->bg_plane_sel + 1) & 3;
break;
case 0xf6:
svga->vram_display_mask = (val & 0x40) ? ht216->vram_mask : 0x3ffff;
/*Bits 18 and 19 of the display memory address*/
ht216_log("HT216 reg 0xf6 write = %02x, vram mask = %08x\n", val & 0x40, svga->vram_display_mask);
ht216_log("HT216 reg 0xf6 write = %02x, vram mask = %08x, cr17 = %02x\n", val & 0x40, svga->vram_display_mask, svga->crtc[0x17]);
ht216_remap(ht216);
svga->fullchange = changeframecount;
svga_recalctimings(svga);
svga_recalctimings(svga);
break;
case 0xf9:
@@ -218,10 +256,10 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
ht216_log("HT216 reg 0xf9 write = %02x\n", val & HT_REG_F9_XPSEL);
ht216_remap(ht216);
break;
case 0xfc:
svga->fullchange = changeframecount;
svga_recalctimings(svga);
svga_recalctimings(svga);
break;
}
switch (svga->seqaddr & 0xff) {
@@ -239,14 +277,14 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
}
break;
case 0x3cf:
if (svga->gdcaddr == 6) {
if (val & 8)
svga->banked_mask = 0x7fff;
else
svga->banked_mask = 0xffff;
}
break;
case 0x3cf:
if (svga->gdcaddr == 6) {
if (val & 8)
svga->banked_mask = 0x7fff;
else
svga->banked_mask = 0xffff;
}
break;
case 0x3D4:
svga->crtcreg = val & 0x3f;
@@ -263,7 +301,7 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
if (old != val) {
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
svga->fullchange = changeframecount;
svga_recalctimings(&ht216->svga);
svga_recalctimings(svga);
}
}
break;
@@ -289,6 +327,7 @@ ht216_in(uint16_t addr, void *p)
{
ht216_t *ht216 = (ht216_t *)p;
svga_t *svga = &ht216->svga;
uint8_t ret = 0xff;
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
addr ^= 0x60;
@@ -296,11 +335,14 @@ ht216_in(uint16_t addr, void *p)
switch (addr) {
case 0x3c2:
break;
case 0x3c4:
return svga->seqaddr;
case 0x3c5:
if (svga->seqaddr == 6)
if (svga->seqaddr == 6) {
return ht216->ext_reg_enable;
if (svga->seqaddr >= 0x80) {
} else if (svga->seqaddr >= 0x80) {
if (ht216->ext_reg_enable) {
switch (svga->seqaddr & 0xff) {
case 0x83:
@@ -319,6 +361,16 @@ ht216_in(uint16_t addr, void *p)
return svga->latch.b[2];
case 0xa3:
return svga->latch.b[3];
case 0xf0:
ret = ht216->fg_latch[ht216->fg_plane_sel];
ht216->fg_plane_sel = 0;
return ret;
case 0xf2:
ret = svga->latch.b[ht216->bg_plane_sel];
ht216->bg_plane_sel = 0;
return ret;
}
return ht216->ht_regs[svga->seqaddr & 0xff];
} else
@@ -326,6 +378,9 @@ ht216_in(uint16_t addr, void *p)
}
break;
case 0x3cc:
return ht216->misc;
case 0x3D4:
return svga->crtcreg;
case 0x3D5:
@@ -406,9 +461,16 @@ ht216_remap(ht216_t *ht216)
} else {
/*One bank used*/
/*Bit 17 of the video memory address*/
if (ht216->misc & HT_MISC_PAGE_SEL) {
ht216->read_bank_reg[0] |= 0x20;
ht216->write_bank_reg[0] |= 0x20;
if ((ht216->misc & HT_MISC_PAGE_SEL)) {
ht216_log("MISC = %02x, lowres = %02x, CR17 = %02x\n", ht216->misc, svga->lowres, svga->crtc[0x17]);
if ((ht216->misc == 0x63 && svga->crtc[0x17] != 0xa3 && ((svga->crtc[0x17] != 0xe3 && !(ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) ||
(ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE))) || (ht216->misc != 0x63)) {
ht216->read_bank_reg[0] |= 0x20;
ht216->write_bank_reg[0] |= 0x20;
} else {
ht216->read_bank_reg[0] &= ~0x20;
ht216->write_bank_reg[0] &= ~0x20;
}
} else {
ht216->read_bank_reg[0] &= ~0x20;
ht216->write_bank_reg[0] &= ~0x20;
@@ -439,12 +501,12 @@ ht216_remap(ht216_t *ht216)
if (bank & 4)
ht216->read_bank_reg[0] |= 0x40;
else
ht216->read_bank_reg[0] &= ~0x40;
ht216->read_bank_reg[0] &= ~0x40;
if (bank & 8)
ht216->read_bank_reg[0] |= 0x80;
else
ht216->read_bank_reg[0] &= ~0x80;
ht216->read_bank_reg[0] &= ~0x80;
if (svga->chain4) {
/*Bit 16 of the video memory address*/
@@ -456,30 +518,109 @@ ht216_remap(ht216_t *ht216)
ht216->write_bank_reg[0] &= ~0x10;
}
}
if (!svga->chain4) {
/*In linear modes, bits 4 and 5 are ignored*/
ht216->read_bank_reg[0] &= ~0x30;
ht216->write_bank_reg[0] &= ~0x30;
}
if (svga->chain4) {
ht216->read_bank_reg[0] |= ht216->ht_regs[0xe8];
ht216->write_bank_reg[0] |= ht216->ht_regs[0xe8];
}
ht216->read_banks[0] = ht216->read_bank_reg[0] << 12;
ht216->write_banks[0] = ht216->write_bank_reg[0] << 12;
ht216->write_banks[0] = ht216->write_bank_reg[0] << 12;
ht216->read_banks[1] = ht216->read_banks[0] + (svga->chain4 ? 0x8000 : 0x20000);
ht216->write_banks[1] = ht216->write_banks[0] + (svga->chain4 ? 0x8000 : 0x20000);
if (!svga->chain4) {
ht216->read_banks[0] >>= 2;
ht216->read_banks[1] >>= 2;
ht216->write_banks[0] >>= 2;
ht216->write_banks[1] >>= 2;
}
}
}
ht216_log("ReadBank0 = %06x, ReadBank1 = %06x, Misc Page Sel = %02x, F6 reg = %02x, F9 Sel = %02x, FC = %02x, E0 split = %02x, E8 = %02x, E9 = %02x, chain4 = %02x, banked mask = %04x\n", ht216->read_banks[0], ht216->read_banks[1], ht216->misc & HT_MISC_PAGE_SEL, bank, ht216->ht_regs[0xf9] & HT_REG_F9_XPSEL, ht216->ht_regs[0xfc] & (HT_REG_FC_ECOLRE | 2), ht216->ht_regs[0xe0] & HT_REG_E0_SBAE, ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], svga->chain4, svga->banked_mask);
ht216_log("ReadBank0 = %06x, ReadBank1 = %06x, Misc Page Sel = %02x, FF DRAM/VRAM = %02x, F6 reg = %02x, F9 Sel = %02x, FC = %02x, E0 split = %02x, E8 = %02x, E9 = %02x, chain4 = %02x, lowres = %02x, banked mask = %04x\n", ht216->read_banks[0], ht216->read_banks[1], ht216->misc & HT_MISC_PAGE_SEL, ht216->ht_regs[0xff] & 0x10, bank, ht216->ht_regs[0xf9] & HT_REG_F9_XPSEL, ht216->ht_regs[0xfc] & (HT_REG_FC_ECOLRE | 2), ht216->ht_regs[0xe0] & HT_REG_E0_SBAE, ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], svga->chain4, svga->lowres, svga->banked_mask);
}
}
void
ht216_1_2bpp_highres(svga_t *svga)
{
int changed_offset, x;
int oddeven;
uint32_t addr, *p;
uint8_t edat[4];
uint8_t dat;
if ((svga->displine + svga->y_add) < 0)
return;
changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
if (svga->firstline_draw == 2000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
addr = svga->ma;
oddeven = 0;
if (!(svga->crtc[0x17] & 0x40)) {
addr = (addr << 1) & svga->vram_mask;
if (svga->seqregs[1] & 4)
oddeven = (addr & 4) ? 1 : 0;
addr &= ~7;
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
addr |= 4;
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
addr |= 4;
}
if (!(svga->crtc[0x17] & 0x01))
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
if (!(svga->crtc[0x17] & 0x02))
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
if (svga->seqregs[1] & 4) {
edat[0] = svga->vram[addr | oddeven];
edat[2] = svga->vram[addr | oddeven | 0x2];
edat[1] = edat[3] = 0;
} else {
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
}
svga->ma += 4;
svga->ma &= svga->vram_mask;
if (svga->crtc[0x17] & 0x80) {
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
} else
memset(p, 0x00, 8 * sizeof(uint32_t));
p += 8;
}
}
}
void
ht216_recalctimings(svga_t *svga)
@@ -492,8 +633,7 @@ ht216_recalctimings(svga_t *svga)
case 6: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break;
case 10: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break;
}
svga->lowres = !(ht216->ht_regs[0xc8] & HT_REG_C8_E256);
svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12);
svga->interlace = ht216->ht_regs[0xe0] & 1;
@@ -504,13 +644,34 @@ ht216_recalctimings(svga_t *svga)
high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2);
ht216->adjust_cursor = 0;
if ((svga->bpp == 8) && (!svga->lowres || high_res_256)) {
if (high_res_256) {
svga->hdisp /= 2;
ht216->adjust_cursor = 1;
}
svga->render = svga_render_8bpp_highres;
if (svga->crtc[0x17] == 0xeb) {
svga->rowoffset <<= 1;
svga->render = ht216_1_2bpp_highres;
}
if (svga->bpp == 8) {
if (((ht216->ht_regs[0xc8] & HT_REG_C8_E256) || (svga->gdcreg[5] & 0x40)) && (!svga->lowres || (ht216->ht_regs[0xf6] & 0x80))) {
if (high_res_256) {
svga->hdisp >>= 1;
ht216->adjust_cursor = 1;
}
svga->render = svga_render_8bpp_highres;
} else if (svga->lowres) {
if (high_res_256) {
svga->hdisp >>= 1;
ht216->adjust_cursor = 1;
svga->render = svga_render_8bpp_highres;
} else {
svga->render = svga_render_8bpp_lowres;
}
}
}
if (svga->crtc[0x17] == 0xeb) /*Looks like that 1024x768 mono mode expects 512K of video memory*/
svga->vram_display_mask = 0x7ffff;
else
svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff;
}
@@ -581,7 +742,6 @@ extalu(int op, uint8_t input_a, uint8_t input_b)
return val;
}
static void
ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded)
{
@@ -603,7 +763,7 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u
else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) {
writemask2 = 1 << (addr & 3);
addr &= ~3;
} else if (svga->chain2_write) {
} else if (svga->chain2_write && (svga->crtc[0x17] != 0xeb)) {
writemask2 &= ~0xa;
if (addr & 1)
writemask2 <<= 1;
@@ -651,7 +811,7 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u
case 0x08:
case 0x0c:
for (i = 0; i < count; i++)
fg_data[i] = ht216->ht_regs[0xec + i];
fg_data[i] = ht216->fg_latch[i];
break;
}
@@ -805,7 +965,7 @@ ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bi
input_a = (ht216->ht_regs[0xf5] & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb];
break;
case 0x08:
input_a = ht216->ht_regs[0xec + (addr & 3)];
input_a = ht216->fg_latch[addr & 3];
break;
case 0x0c:
input_a = ht216->bg_latch[addr & 7];
@@ -904,8 +1064,6 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
cycles -= video_timing_write_b;
egawrites++;
addr &= 0xfffff;
val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7))));
@@ -964,13 +1122,17 @@ ht216_write(uint32_t addr, uint8_t val, void *p)
{
ht216_t *ht216 = (ht216_t *)p;
svga_t *svga = &ht216->svga;
uint32_t prev_addr = addr;
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1];
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3])
svga_write_linear(addr, val, svga);
else
if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000)
addr += 0x10000;
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3] && svga->crtc[0x17] != 0xeb) {
svga_write_linear(addr, val, svga);
} else
ht216_write_common(ht216, addr, val);
}
@@ -980,11 +1142,15 @@ ht216_writew(uint32_t addr, uint16_t val, void *p)
{
ht216_t *ht216 = (ht216_t *)p;
svga_t *svga = &ht216->svga;
uint32_t prev_addr = addr;
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1];
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3])
if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000)
addr += 0x10000;
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3] && svga->crtc[0x17] != 0xeb)
svga_writew_linear(addr, val, svga);
else {
ht216_write_common(ht216, addr, val);
@@ -998,11 +1164,15 @@ ht216_writel(uint32_t addr, uint32_t val, void *p)
{
ht216_t *ht216 = (ht216_t *)p;
svga_t *svga = &ht216->svga;
uint32_t prev_addr = addr;
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1];
addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1];
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3])
if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000)
addr += 0x10000;
if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3] && svga->crtc[0x17] != 0xeb)
svga_writel_linear(addr, val, svga);
else {
ht216_write_common(ht216, addr, val);
@@ -1084,8 +1254,6 @@ ht216_read_common(ht216_t *ht216, uint32_t addr)
cycles -= video_timing_read_b;
egareads++;
addr &= 0xfffff;
count = 2;
@@ -1105,7 +1273,7 @@ ht216_read_common(ht216_t *ht216, uint32_t addr)
for (i = 0; i < 8; i++)
ht216->bg_latch[i] = svga->vram[latch_addr | i];
return svga->vram[addr & svga->vram_mask];
} else if (svga->chain2_read) {
} else if (svga->chain2_read && (svga->crtc[0x17] != 0xeb)) {
readplane = (readplane & 2) | (addr & 1);
addr &= ~1;
addr <<= 2;
@@ -1132,9 +1300,10 @@ ht216_read_common(ht216_t *ht216, uint32_t addr)
or = addr & 4;
svga->latch.d[0] = ht216->bg_latch[0 | or] | (ht216->bg_latch[1 | or] << 8) |
(ht216->bg_latch[2 | or] << 16) | (ht216->bg_latch[3 | or] << 24);
if (svga->readmode) {
temp = 0xff;
for (pixel = 0; pixel < 8; pixel++) {
for (plane = 0; plane < 4; plane++) {
if (svga->colournocare & (1 << plane)) {
@@ -1158,10 +1327,14 @@ ht216_read(uint32_t addr, void *p)
{
ht216_t *ht216 = (ht216_t *)p;
svga_t *svga = &ht216->svga;
uint32_t prev_addr = addr;
addr &= svga->banked_mask;
addr = (addr & 0x7fff) + ht216->read_banks[(addr >> 15) & 1];
if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000)
addr += 0x10000;
return ht216_read_common(ht216, addr);
}
@@ -1177,7 +1350,6 @@ ht216_read_linear(uint32_t addr, void *p)
return ht216_read_common(ht216, (addr & 0xffff) | ((addr & 0xc0000) >> 2));
}
void
*ht216_init(const device_t *info, uint32_t mem_size, int has_rom)
{
@@ -1358,7 +1530,7 @@ const device_t g2_gc205_device =
const device_t v7_vga_1024i_device =
{
"Video 7 VGA 1024i",
"Video 7 VGA 1024i (HT208)",
DEVICE_ISA,
0x7140,
v7_vga_1024i_init,

View File

@@ -79,14 +79,12 @@ uint8_t mda_in(uint16_t addr, void *p)
void mda_write(uint32_t addr, uint8_t val, void *p)
{
mda_t *mda = (mda_t *)p;
egawrites++;
mda->vram[addr & 0xfff] = val;
}
uint8_t mda_read(uint32_t addr, void *p)
{
mda_t *mda = (mda_t *)p;
egareads++;
return mda->vram[addr & 0xfff];
}

View File

@@ -2130,8 +2130,6 @@ mystique_readb_linear(uint32_t addr, void *p)
{
svga_t *svga = (svga_t *)p;
egareads++;
cycles -= video_timing_read_b;
addr &= svga->decode_mask;
@@ -2147,8 +2145,6 @@ mystique_readw_linear(uint32_t addr, void *p)
{
svga_t *svga = (svga_t *)p;
egareads += 2;
cycles -= video_timing_read_w;
addr &= svga->decode_mask;
@@ -2164,8 +2160,6 @@ mystique_readl_linear(uint32_t addr, void *p)
{
svga_t *svga = (svga_t *)p;
egareads += 4;
cycles -= video_timing_read_l;
addr &= svga->decode_mask;
@@ -2181,8 +2175,6 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *p)
{
svga_t *svga = (svga_t *)p;
egawrites++;
cycles -= video_timing_write_b;
addr &= svga->decode_mask;
@@ -2199,8 +2191,6 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *p)
{
svga_t *svga = (svga_t *)p;
egawrites += 2;
cycles -= video_timing_write_w;
addr &= svga->decode_mask;
@@ -2217,8 +2207,6 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *p)
{
svga_t *svga = (svga_t *)p;
egawrites += 4;
cycles -= video_timing_write_l;
addr &= svga->decode_mask;

View File

@@ -118,7 +118,6 @@ nga_write(uint32_t addr, uint8_t val, void *priv)
nga->cga.charbuffer[offset] = nga->cga.vram[addr & 0x7fff];
nga->cga.charbuffer[offset | 1] = nga->cga.vram[addr & 0x7fff];
}
egawrites++;
nga_waitstates(&nga->cga);
}
@@ -144,7 +143,6 @@ nga_read(uint32_t addr, void *priv)
nga->cga.charbuffer[offset | 1] = nga->cga.vram[addr & 0x7fff];
}
egareads++;
return(ret);
}

View File

@@ -30,7 +30,9 @@
#include <86box/vid_svga.h>
#define BIOS_037C_PATH L"roms/video/oti/bios.bin"
#define BIOS_067_AMA932J_PATH L"roms/machines/ama932j/oti067.bin"
#define BIOS_067_AMA932J_PATH L"roms/machines/ama932j/oti067.bin"
#define BIOS_067_M300_08_PATH L"roms/machines/olivetti_m300_08/EVC_BIOS.ROM"
#define BIOS_067_M300_15_PATH L"roms/machines/olivetti_m300_15/EVC_BIOS.ROM"
#define BIOS_077_PATH L"roms/video/oti/oti077.vbi"
@@ -38,6 +40,7 @@ enum {
OTI_037C,
OTI_067 = 2,
OTI_067_AMA932J,
OTI_067_M300 = 4,
OTI_077 = 5
};
@@ -362,6 +365,16 @@ oti_init(const device_t *info)
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
break;
case OTI_067_M300:
if (rom_present(BIOS_067_M300_15_PATH))
romfn = BIOS_067_M300_15_PATH;
else
romfn = BIOS_067_M300_08_PATH;
oti->vram_size = device_get_config_int("memory");
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
break;
case OTI_067:
case OTI_077:
romfn = BIOS_077_PATH;
@@ -439,6 +452,15 @@ oti067_077_available(void)
return(rom_present(BIOS_077_PATH));
}
static int
oti067_m300_available(void)
{
if (rom_present(BIOS_067_M300_15_PATH))
return(rom_present(BIOS_067_M300_15_PATH));
else
return(rom_present(BIOS_067_M300_08_PATH));
}
static const device_config_t oti067_config[] =
{
@@ -531,6 +553,18 @@ const device_t oti067_device =
oti067_config
};
const device_t oti067_m300_device =
{
"Oak OTI-067 (Olivetti M300-08/15)",
DEVICE_ISA,
4,
oti_init, oti_close, NULL,
{ oti067_m300_available },
oti_speed_changed,
oti_force_redraw,
oti067_config
};
const device_t oti067_ama932j_device =
{
"Oak OTI-067 (AMA-932J)",

View File

@@ -166,7 +166,6 @@ ogc_write(uint32_t addr, uint8_t val, void *priv)
ogc->cga.charbuffer[offset] = ogc->cga.vram[addr & 0x7fff];
ogc->cga.charbuffer[offset | 1] = ogc->cga.vram[addr & 0x7fff];
}
egawrites++;
ogc_waitstates(&ogc->cga);
}
@@ -186,7 +185,6 @@ ogc_read(uint32_t addr, void *priv)
ogc->cga.charbuffer[offset | 1] = ogc->cga.vram[addr & 0x7fff];
}
egareads++;
return(ogc->cga.vram[addr & 0x7FFF]);
}

View File

@@ -352,6 +352,16 @@ void *paradise_init(const device_t *info, uint32_t memsize)
return paradise;
}
static void *paradise_pvga1a_ncr3302_init(const device_t *info)
{
paradise_t *paradise = paradise_init(info, 1 << 18);
if (paradise)
rom_init(&paradise->bios_rom, L"roms/machines/ncr_3302/c000-wd_1987-1989-740011-003058-019c.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
return paradise;
}
static void *paradise_pvga1a_pc2086_init(const device_t *info)
{
paradise_t *paradise = paradise_init(info, 1 << 18);
@@ -361,6 +371,7 @@ static void *paradise_pvga1a_pc2086_init(const device_t *info)
return paradise;
}
static void *paradise_pvga1a_pc3086_init(const device_t *info)
{
paradise_t *paradise = paradise_init(info, 1 << 18);
@@ -464,7 +475,6 @@ void paradise_force_redraw(void *p)
paradise->svga.fullchange = changeframecount;
}
const device_t paradise_pvga1a_pc2086_device =
{
"Paradise PVGA1A (Amstrad PC2086)",
@@ -478,6 +488,7 @@ const device_t paradise_pvga1a_pc2086_device =
paradise_force_redraw,
NULL
};
const device_t paradise_pvga1a_pc3086_device =
{
"Paradise PVGA1A (Amstrad PC3086)",
@@ -516,6 +527,20 @@ static const device_config_t paradise_pvga1a_config[] =
}
};
const device_t paradise_pvga1a_ncr3302_device =
{
"Paradise PVGA1A (NCR 3302)",
0,
PVGA1A,
paradise_pvga1a_ncr3302_init,
paradise_close,
NULL,
{ NULL },
paradise_speed_changed,
paradise_force_redraw,
paradise_pvga1a_config
};
const device_t paradise_pvga1a_device =
{
"Paradise PVGA1A",

View File

@@ -343,7 +343,6 @@ sigma_write(uint32_t addr, uint8_t val, void *p)
sigma_t *sigma = (sigma_t *)p;
sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)] = val;
egawrites++;
cycles -= 4;
}
@@ -354,7 +353,6 @@ sigma_read(uint32_t addr, void *p)
sigma_t *sigma = (sigma_t *)p;
cycles -= 4;
egareads++;
return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)];
}

View File

@@ -108,6 +108,7 @@ video_cards[] = {
{ "tvga8900d", &tvga8900d_device },
{ "tvga9000b", &tvga9000b_device },
{ "tgkorvga", &et4000k_isa_device },
{ "et2000", &et2000_device },
{ "et4000ax", &et4000_isa_device },
{ "vga", &vga_device },
{ "v7_vga_1024i", &v7_vga_1024i_device },

View File

@@ -69,8 +69,13 @@ void vga_out(uint16_t addr, uint8_t val, void *p)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
svga->fullchange = 3;
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
} else {
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
}
break;

View File

@@ -1424,7 +1424,6 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p)
if (addr >= svga->vram_max)
return 0xff;
egareads++;
cycles -= video_timing_read_b;
// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
@@ -1457,7 +1456,6 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p)
if (addr >= svga->vram_max)
return 0xff;
egareads++;
cycles -= video_timing_read_w;
// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
@@ -1491,7 +1489,6 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p)
if (addr >= svga->vram_max)
return 0xff;
egareads++;
cycles -= video_timing_read_l;
// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
@@ -1523,8 +1520,6 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p)
if (addr >= svga->vram_max)
return;
egawrites++;
cycles -= video_timing_write_b;
svga->changedvram[addr >> 12] = changeframecount;
@@ -1561,8 +1556,6 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p)
if (addr >= svga->vram_max)
return;
egawrites++;
cycles -= video_timing_write_w;
svga->changedvram[addr >> 12] = changeframecount;
@@ -1607,8 +1600,6 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
if (addr >= svga->vram_max)
return;
egawrites += 4;
cycles -= video_timing_write_l;
svga->changedvram[addr >> 12] = changeframecount;

View File

@@ -1071,7 +1071,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_I2:
if (!(val & (1 << 31)))
{
@@ -1087,7 +1086,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q0:
if (!(val & (1 << 31)))
{
@@ -1103,7 +1101,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q2:
if (!(val & (1 << 31)))
{
@@ -1150,7 +1147,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_I3:
if (!(val & (1 << 31)))
{
@@ -1166,7 +1162,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q1:
if (!(val & (1 << 31)))
{
@@ -1182,7 +1177,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
}
break;
}
break;
case SST_nccTable0_Q3:
if (!(val & (1 << 31)))
{

View File

@@ -459,7 +459,6 @@ void wy700_checkchanges(wy700_t *wy700)
void wy700_write(uint32_t addr, uint8_t val, void *p)
{
wy700_t *wy700 = (wy700_t *)p;
egawrites++;
if (wy700->wy700_mode & 0x80) /* High-res mode. */
{
@@ -483,7 +482,6 @@ void wy700_write(uint32_t addr, uint8_t val, void *p)
uint8_t wy700_read(uint32_t addr, void *p)
{
wy700_t *wy700 = (wy700_t *)p;
egareads++;
if (wy700->wy700_mode & 0x80) /* High-res mode. */
{
addr &= 0xFFFF;

View File

@@ -70,6 +70,7 @@
#include <86box/video.h>
#include <86box/vid_svga.h>
#include <minitrace/minitrace.h>
volatile int screenshots = 0;
bitmap_t *buffer32 = NULL;
@@ -84,6 +85,7 @@ dbcs_font_t *fontdatksc5601_user = NULL; /* Korean KSC-5601 user defined font */
uint32_t pal_lookup[256];
int xsize = 1,
ysize = 1;
int egareads = 0, egawrites = 0;
int cga_palette = 0,
herc_blend = 0;
uint32_t *video_6to8 = NULL,
@@ -91,9 +93,7 @@ uint32_t *video_6to8 = NULL,
*video_8to32 = NULL,
*video_15to32 = NULL,
*video_16to32 = NULL;
int egareads = 0,
egawrites = 0,
changeframecount = 2;
int changeframecount = 2;
int frames = 0;
int fullchange = 0;
uint8_t edatlookup[4][4];
@@ -285,6 +285,7 @@ void blit_thread(void *param)
while (1) {
thread_wait_event(blit_data.wake_blit_thread, -1);
thread_reset_event(blit_data.wake_blit_thread);
MTR_BEGIN("video", "blit_thread");
if (blit_func)
blit_func(blit_data.x, blit_data.y,
@@ -292,6 +293,7 @@ void blit_thread(void *param)
blit_data.w, blit_data.h);
blit_data.busy = 0;
MTR_END("video", "blit_thread");
thread_set_event(blit_data.blit_complete);
}
}
@@ -448,6 +450,7 @@ void
video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
{
int yy;
MTR_BEGIN("video", "video_blit_memtoscreen");
if (y2 > 0) {
for (yy = y1; yy < y2; yy++) {
@@ -482,6 +485,7 @@ video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
blit_data.h = h;
thread_set_event(blit_data.wake_blit_thread);
MTR_END("video", "video_blit_memtoscreen");
}

View File

@@ -122,6 +122,11 @@ BEGIN
# endif
MENUITEM SEPARATOR
MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT
#ifdef MTR_ENABLED
MENUITEM SEPARATOR
MENUITEM "Begin trace\tCtrl+T", IDM_ACTION_BEGIN_TRACE
MENUITEM "End trace\tCtrl+T", IDM_ACTION_END_TRACE
#endif
END
#if defined(ENABLE_LOG_TOGGLES) || defined(ENABLE_LOG_COMMANDS)
POPUP "&Logging"
@@ -262,6 +267,9 @@ BEGIN
#endif
#ifdef ENABLE_LOG_BREAKPOINT
VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY
#endif
#ifdef MTR_ENABLED
"T", IDM_ACTION_TRACE, CONTROL, VIRTKEY
#endif
VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT
VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL

View File

@@ -99,6 +99,9 @@ ifeq ($(DEV_BUILD), y)
ifndef USE_VECT486VL
USE_VECT486VL := y
endif
ifndef OLIVETTI
OLIVETTI := y
endif
else
ifndef DEBUG
DEBUG := n
@@ -172,6 +175,9 @@ else
ifndef USE_VECT486VL
USE_VECT486VL := n
endif
ifndef OLIVETTI
OLIVETTI := n
endif
endif
# Defaults for several build options (possibly defined in a chained file.)
@@ -284,7 +290,7 @@ endif
#########################################################################
# Nothing should need changing from here on.. #
#########################################################################
VPATH := $(EXPATH) . $(CODEGEN) cpu \
VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu \
cdrom chipset device disk disk/minivhd floppy \
game machine mem printer \
sio sound \
@@ -482,6 +488,12 @@ RFLAGS += -DUSE_DISCORD
DISCORDOBJ := win_discord.o
endif
ifeq ($(MINITRACE), y)
OPTS += -DMTR_ENABLED
RFLAGS += -DMTR_ENABLED
MINITRACEOBJ := minitrace.o
endif
# Options for the DEV branch.
ifeq ($(DEV_BRANCH), y)
OPTS += -DDEV_BRANCH
@@ -575,6 +587,11 @@ ifeq ($(USE_VECT486VL), y)
OPTS += -DUSE_VECT486VL
endif
ifeq ($(OLIVETTI), y)
OPTS += -DUSE_OLIVETTI
endif
endif
@@ -607,11 +624,13 @@ CPUOBJ := cpu.o cpu_table.o \
CHIPSETOBJ := acc2168.o cs8230.o ali1217.o ali1429.o headland.o intel_82335.o cs4031.o \
intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \
neat.o opti495.o opti895.o opti5x7.o scamp.o scat.o via_vt82c49x.o via_vt82c505.o \
gc100.o olivetti_eva.o \
sis_85c310.o sis_85c4xx.o sis_85c496.o sis_85c50x.o stpc.o opti283.o opti291.o \
via_apollo.o via_pipc.o wd76c10.o vl82c480.o
MCHOBJ := machine.o machine_table.o \
m_xt.o m_xt_compaq.o \
m_xt_philips.o \
m_xt_t1000.o m_xt_t1000_vid.o \
m_xt_xi8088.o m_xt_zenith.o \
m_pcjr.o \
@@ -625,6 +644,7 @@ MCHOBJ := machine.o machine_table.o \
m_at_286_386sx.o m_at_386dx_486.o \
m_at_socket4_5.o m_at_socket7.o m_at_sockets7.o \
m_at_socket8.o m_at_slot1.o m_at_slot2.o m_at_socket370.o \
m_at_ebga368.o \
m_at_misc.o
DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm_5161.o isamem.o isartc.o \
@@ -633,14 +653,14 @@ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm
keyboard.o \
keyboard_xt.o keyboard_at.o \
mouse.o \
mouse_bus.o \
mouse_bus.o \
mouse_serial.o mouse_ps2.o \
phoenix_486_jumper.o
SIOOBJ := sio_acc3221.o \
sio_f82c710.o sio_82091aa.o \
sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87311.o sio_pc87332.o \
sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87310.o sio_pc87311.o sio_pc87332.o \
sio_prime3b.o sio_prime3c.o \
sio_w83787f.o \
sio_w83877f.o sio_w83977f.o \
@@ -781,7 +801,7 @@ OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \
$(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \
$(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) \
$(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) \
$(DISCORDOBJ)
$(DISCORDOBJ) $(MINITRACEOBJ)
ifdef EXOBJ
OBJ += $(EXOBJ)
endif

View File

@@ -49,7 +49,9 @@
#include <86box/win_sdl.h>
#include <86box/win.h>
#include <86box/version.h>
#ifdef MTR_ENABLED
#include <minitrace/minitrace.h>
#endif
typedef struct {
WCHAR str[512];
@@ -217,6 +219,21 @@ plat_get_string(int i)
return((wchar_t *)str);
}
#ifdef MTR_ENABLED
void
init_trace(void)
{
mtr_init("trace.json");
mtr_start();
}
void
shutdown_trace(void)
{
mtr_stop();
mtr_shutdown();
}
#endif
/* Create a console if we don't already have one. */
static void

View File

@@ -48,6 +48,9 @@
# include <86box/win_discord.h>
#endif
#ifdef MTR_ENABLED
#include <minitrace/minitrace.h>
#endif
#define TIMER_1SEC 1 /* ID of the one-second timer */
@@ -294,6 +297,9 @@ ResetAllMenus(void)
else
EnableMenuItem(menuMain, IDM_DISCORD, MF_DISABLED);
#endif
#ifdef MTR_ENABLED
EnableMenuItem(menuMain, IDM_ACTION_END_TRACE, MF_DISABLED);
#endif
}
@@ -378,6 +384,19 @@ plat_power_off(void)
exit(-1);
}
#ifdef MTR_ENABLED
static void
handle_trace(HMENU hmenu, int trace)
{
EnableMenuItem(hmenu, IDM_ACTION_BEGIN_TRACE, trace? MF_GRAYED : MF_ENABLED);
EnableMenuItem(hmenu, IDM_ACTION_END_TRACE, trace? MF_ENABLED : MF_GRAYED);
if (trace) {
init_trace();
} else {
shutdown_trace();
}
}
#endif
/* Catch WM_INPUT messages for 'current focus' window. */
#if defined(__amd64__) || defined(__aarch64__)
@@ -466,6 +485,8 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
int i;
RECT rect, *rect_p;
WINDOWPOS *pos;
int temp_x, temp_y;
if (input_proc(hwnd, message, wParam, lParam) == 0)
@@ -489,6 +510,15 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
take_screenshot();
break;
#ifdef MTR_ENABLED
case IDM_ACTION_BEGIN_TRACE:
case IDM_ACTION_END_TRACE:
case IDM_ACTION_TRACE:
tracing_on = !tracing_on;
handle_trace(hmenu, tracing_on);
break;
#endif
case IDM_ACTION_HRESET:
win_notify_dlg_open();
if (confirm_reset)
@@ -581,16 +611,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
temp_x = unscaled_size_x;
temp_y = unscaled_size_y;
}
/* Main Window. */
ResizeWindowByClientArea(hwnd, temp_x, temp_y + sbar_height);
/* Render window. */
MoveWindow(hwndRender, 0, 0, temp_x, temp_y, TRUE);
GetWindowRect(hwndRender, &rect);
/* Status bar. */
MoveWindow(hwndSBAR, 0, rect.bottom, temp_x, 17, TRUE);
if (mouse_capture) {
ClipCursor(&rect);
}
@@ -812,70 +835,53 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
doresize = 1;
break;
case WM_SIZE:
if (user_resize && !vid_resize)
break;
case WM_WINDOWPOSCHANGED:
pos = (WINDOWPOS*)lParam;
GetClientRect(hwndMain, &rect);
temp_x = (lParam & 0xFFFF);
temp_y = (lParam >> 16);
if ((temp_x <= 0) || (temp_y <= 0)) {
if (IsIconic(hwndMain)) {
plat_vidapi_enable(0);
minimized = 1;
break;
} else if (minimized == 1) {
return(0);
} else if (minimized) {
minimized = 0;
video_force_resize_set(1);
}
plat_vidapi_enable(0);
temp_y -= sbar_height;
if (temp_y < 1)
temp_y = 1;
if (vid_resize && ((temp_x != scrnsz_x) || (temp_y != scrnsz_y))) {
scrnsz_x = temp_x;
scrnsz_y = temp_y;
doresize = 1;
}
MoveWindow(hwndRender, 0, 0, temp_x, temp_y, TRUE);
GetWindowRect(hwndRender, &rect);
/* Status bar. */
MoveWindow(hwndSBAR, 0, rect.bottom, temp_x, 17, TRUE);
plat_vidsize(temp_x, temp_y);
if (mouse_capture) {
ClipCursor(&rect);
}
if (window_remember) {
GetWindowRect(hwnd, &rect);
window_x = rect.left;
window_y = rect.top;
window_w = rect.right - rect.left;
window_h = rect.bottom - rect.top;
window_x = pos->x;
window_y = pos->y;
window_w = pos->cx;
window_h = pos->cy;
save_window_pos = 1;
config_save();
}
plat_vidapi_enable(2);
config_save();
break;
if (!(pos->flags & SWP_NOSIZE)) {
plat_vidapi_enable(0);
case WM_MOVE:
if (window_remember) {
GetWindowRect(hwnd, &rect);
window_x = rect.left;
window_y = rect.top;
window_w = rect.right - rect.left;
window_h = rect.bottom - rect.top;
save_window_pos = 1;
MoveWindow(hwndSBAR, 0, rect.bottom - sbar_height, sbar_height, rect.right, TRUE);
MoveWindow(hwndRender, 0, 0, rect.right, rect.bottom - sbar_height, TRUE);
GetClientRect(hwndRender, &rect);
if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) {
scrnsz_x = rect.right;
scrnsz_y = rect.bottom;
doresize = 1;
}
plat_vidsize(rect.right, rect.bottom);
if (mouse_capture) {
GetWindowRect(hwndRender, &rect);
ClipCursor(&rect);
}
plat_vidapi_enable(2);
}
break;
return(0);
case WM_TIMER:
if (wParam == TIMER_1SEC)
pc_onesec();
@@ -1231,9 +1237,16 @@ ui_init(int nCmdShow)
SetWindowLongPtr(hwnd, GWL_STYLE,
(WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX));
/* Move to the last-saved position if needed. */
/* Create the Machine Rendering window. */
hwndRender = CreateWindow(/*L"STATIC"*/ SUB_CLASS_NAME, NULL, WS_CHILD|SS_BITMAP,
0, 0, 1, 1, hwnd, NULL, hinstance, NULL);
/* Initiate a resize in order to properly arrange all controls.
Move to the last-saved position if needed. */
if (window_remember)
MoveWindow(hwnd, window_x, window_y, window_w, window_h, TRUE);
else
ResizeWindowByClientArea(hwndMain, scrnsz_x, scrnsz_y + sbar_height);
/* Reset all menus to their defaults. */
ResetAllMenus();
@@ -1274,11 +1287,6 @@ ui_init(int nCmdShow)
*/
ghMutex = CreateMutex(NULL, FALSE, NULL);
/* Create the Machine Rendering window. */
hwndRender = CreateWindow(/*L"STATIC"*/ SUB_CLASS_NAME, NULL, WS_CHILD|SS_BITMAP,
0, 0, 1, 1, hwnd, NULL, hinstance, NULL);
MoveWindow(hwndRender, 0, 0, scrnsz_x, scrnsz_y, TRUE);
/* All done, fire up the actual emulated machine. */
if (! pc_init_modules()) {
/* Dang, no ROMs found at all! */
@@ -1463,8 +1471,6 @@ plat_pause(int p)
void
plat_resize(int x, int y)
{
RECT r;
/* First, see if we should resize the UI window. */
if (!vid_resize) {
@@ -1474,15 +1480,6 @@ plat_resize(int x, int y)
y = MulDiv(y, dpi, 96);
}
ResizeWindowByClientArea(hwndMain, x, y + sbar_height);
MoveWindow(hwndRender, 0, 0, x, y, TRUE);
GetWindowRect(hwndRender, &r);
MoveWindow(hwndSBAR, 0, y, x, 17, TRUE);
if (mouse_capture) {
ClipCursor(&r);
}
}
}