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

@@ -74,7 +74,7 @@ jobs:
fail-fast: false
matrix:
build:
- name: Regular
- name: Debug
dev-build: off
new-dynarec: off
type: Debug
@@ -82,17 +82,12 @@ jobs:
dev-build: on
new-dynarec: on
type: Debug
target-arch: ['Win32', 'x64', 'ARM', 'ARM64']
target-arch: ['Win32', 'x64', 'ARM64']
toolset: ['clangcl', 'v142']
exclude:
- target-arch: 'ARM'
build:
new-dynarec: off
- target-arch: 'ARM64'
build:
new-dynarec: off
- target-arch: 'ARM'
toolset: 'clangcl'
steps:
- uses: actions/checkout@v2

View File

@@ -45,6 +45,8 @@ option(DISCORD "Discord integration" ON)
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
option(DEV_BRANCH "Development branch" OFF)
CMAKE_DEPENDENT_OPTION(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
CMAKE_DEPENDENT_OPTION(CL5422 "Cirrus Logic CL-GD 5402/5420/5422" ON "DEV_BRANCH" OFF)

View File

@@ -4,7 +4,7 @@
operating systems and software designed for IBM PC systems and compatibles
from 1981 through fairly recent system designs based on the PCI bus.
86Box is released under the GNU General Public License, version 2 or later.
86Box is released under the GNU General Public License, version 2 only.
For more information, see the `COPYING` file.
The project maintainer is [OBattler](https://github.com/OBattler).

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

View File

@@ -3,7 +3,7 @@
"version-string": "3.0",
"homepage": "https://86box.net/",
"documentation": "http://86box.readthedocs.io/",
"license": "GPL-2.0-or-later",
"license": "GPL-2.0-only",
"dependencies": [
"freetype",
"libpng",