Merge branch 'main' of https://github.com/MaxwellS04/86Box
3
.github/workflows/cmake_macos.yml
vendored
@@ -69,7 +69,6 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
ninja
|
||||
sdl2
|
||||
rtmidi
|
||||
openal-soft
|
||||
@@ -162,12 +161,12 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
ninja
|
||||
sdl2
|
||||
rtmidi
|
||||
openal-soft
|
||||
fluidsynth
|
||||
libslirp
|
||||
vde
|
||||
libserialport
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
|
||||
8
.github/workflows/codeql_linux.yml
vendored
@@ -3,9 +3,7 @@ name: CodeQL Analysis (Linux)
|
||||
on:
|
||||
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
@@ -16,6 +14,7 @@ on:
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
@@ -26,6 +25,9 @@ on:
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
schedule:
|
||||
- cron: '22 11 * * 0'
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-linux:
|
||||
|
||||
8
.github/workflows/codeql_macos.yml
vendored
@@ -3,9 +3,7 @@ name: CodeQL Analysis (macos)
|
||||
on:
|
||||
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
@@ -16,6 +14,7 @@ on:
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
@@ -26,6 +25,9 @@ on:
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
schedule:
|
||||
- cron: '22 11 * * 0'
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-macos13-x86_64:
|
||||
|
||||
8
.github/workflows/codeql_windows_msys2.yml
vendored
@@ -3,9 +3,7 @@ name: CodeQL Analysis (Windows, msys2)
|
||||
on:
|
||||
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
@@ -16,6 +14,7 @@ on:
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
@@ -26,6 +25,9 @@ on:
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
schedule:
|
||||
- cron: '22 11 * * 0'
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-msys2:
|
||||
|
||||
@@ -137,6 +137,7 @@ option(GDBSTUB "Enable GDB stub server for debugging"
|
||||
option(DEV_BRANCH "Development branch" OFF)
|
||||
option(DISCORD "Discord Rich Presence support" ON)
|
||||
option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF)
|
||||
option(LIBASAN "Enable compilation with the addresss sanitizer" OFF)
|
||||
|
||||
if((ARCH STREQUAL "arm64") OR (ARCH STREQUAL "arm"))
|
||||
set(NEW_DYNAREC ON)
|
||||
@@ -223,4 +224,10 @@ if(NOT EMU_COPYRIGHT_YEAR)
|
||||
set(EMU_COPYRIGHT_YEAR 2024)
|
||||
endif()
|
||||
|
||||
# Libasan
|
||||
if(LIBASAN)
|
||||
add_compile_options(-fsanitize=address)
|
||||
add_link_options(-fsanitize=address)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
57
src/86box.c
@@ -253,6 +253,8 @@ struct accelKey def_acc_keys[NUM_ACCELS] = {
|
||||
.seq="Ctrl+Alt+M" }
|
||||
};
|
||||
|
||||
char vmm_path[1024] = { '\0'}; /* TEMPORARY - VM manager path to scan for VMs */
|
||||
int vmm_enabled = 0;
|
||||
|
||||
/* Statistics. */
|
||||
extern int mmuflush;
|
||||
@@ -600,8 +602,8 @@ pc_show_usage(char *s)
|
||||
#ifdef _WIN32
|
||||
"-D or --debug\t\t\t- force debug output logging\n"
|
||||
#endif
|
||||
#if 0
|
||||
"-E or --nographic\t\t- forces the old behavior\n"
|
||||
#if 1
|
||||
"-E or --vmmpath\t\t- vm manager path\n"
|
||||
#endif
|
||||
"-F or --fullscreen\t\t- start in fullscreen mode\n"
|
||||
"-G or --lang langid\t\t- start with specified language\n"
|
||||
@@ -637,7 +639,7 @@ pc_show_usage(char *s)
|
||||
ui_msgbox(MBX_ANSI | ((s == NULL) ? MBX_INFO : MBX_WARNING), p);
|
||||
#else
|
||||
if (s == NULL)
|
||||
pclog(p);
|
||||
pclog("%s", p);
|
||||
else
|
||||
ui_msgbox(MBX_ANSI | MBX_WARNING, p);
|
||||
#endif
|
||||
@@ -734,13 +736,18 @@ usage:
|
||||
} else if (!strcasecmp(argv[c], "--debug") || !strcasecmp(argv[c], "-D")) {
|
||||
force_debug = 1;
|
||||
#endif
|
||||
#ifdef ENABLE_NG
|
||||
} else if (!strcasecmp(argv[c], "--nographic") || !strcasecmp(argv[c], "-E")) {
|
||||
/* Currently does nothing, but if/when we implement a built-in manager,
|
||||
it's going to force the manager not to run, allowing the old usage
|
||||
without parameter. */
|
||||
ng = 1;
|
||||
#endif
|
||||
//#ifdef ENABLE_NG
|
||||
} else if (!strcasecmp(argv[c], "--vmmpath") ||
|
||||
!strcasecmp(argv[c], "-E")) {
|
||||
/* Using this variable for vm manager path
|
||||
Temporary solution!*/
|
||||
if ((c+1) == argc) goto usage;
|
||||
char *vp = argv[++c];
|
||||
if ((strlen(vp) + 1) >= sizeof(vmm_path))
|
||||
memcpy(vmm_path, vp, sizeof(vmm_path));
|
||||
else
|
||||
memcpy(vmm_path, vp, strlen(vp) + 1);
|
||||
//#endif
|
||||
} else if (!strcasecmp(argv[c], "--fullscreen") || !strcasecmp(argv[c], "-F")) {
|
||||
start_in_fullscreen = 1;
|
||||
} else if (!strcasecmp(argv[c], "--logfile") || !strcasecmp(argv[c], "-L")) {
|
||||
@@ -775,7 +782,11 @@ usage:
|
||||
goto usage;
|
||||
|
||||
temp2 = (char *) calloc(2048, 1);
|
||||
sscanf(argv[++c], "%c:%s", &drive, temp2);
|
||||
if (sscanf(argv[++c], "%c:%2047s", &drive, temp2) != 2) {
|
||||
fprintf(stderr, "Invalid input format for --image option.\n");
|
||||
free(temp2);
|
||||
goto usage;
|
||||
}
|
||||
if (drive > 0x40)
|
||||
drive = (drive & 0x1f) - 1;
|
||||
else
|
||||
@@ -1014,9 +1025,21 @@ usage:
|
||||
* This is where we start outputting to the log file,
|
||||
* if there is one. Create a little info header first.
|
||||
*/
|
||||
struct tm time_buf;
|
||||
|
||||
(void) time(&now);
|
||||
info = localtime(&now);
|
||||
strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info);
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(&time_buf, &now) == 0)
|
||||
info = &time_buf;
|
||||
#else
|
||||
info = localtime_r(&now, &time_buf);
|
||||
#endif
|
||||
|
||||
if (info)
|
||||
strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info);
|
||||
else
|
||||
strcpy(temp, "unknown");
|
||||
|
||||
pclog("#\n# %ls v%ls logfile, created %s\n#\n",
|
||||
EMU_NAME_W, EMU_VERSION_FULL_W, temp);
|
||||
pclog("# VM: %s\n#\n", vm_name);
|
||||
@@ -1027,6 +1050,10 @@ usage:
|
||||
}
|
||||
|
||||
pclog("# Configuration file: %s\n#\n\n", cfg_path);
|
||||
if (strlen(vmm_path) != 0) {
|
||||
vmm_enabled = 1;
|
||||
pclog("# VM Manager enabled. Path: %s\n", vmm_path);
|
||||
}
|
||||
/*
|
||||
* We are about to read the configuration file, which MAY
|
||||
* put data into global variables (the hard- and floppy
|
||||
@@ -1645,6 +1672,10 @@ pc_close(UNUSED(thread_t *ptr))
|
||||
scsi_disk_close();
|
||||
|
||||
gdbstub_close();
|
||||
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
mem_free();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
@@ -446,24 +446,36 @@ static int
|
||||
viso_fill_time(uint8_t *data, time_t time, int format, int longform)
|
||||
{
|
||||
uint8_t *p = data;
|
||||
struct tm *time_s = localtime(&time);
|
||||
if (!time_s) {
|
||||
/* localtime will return NULL if the time_t is negative (Windows)
|
||||
or way too far into 64-bit space (Linux). Fall back to epoch. */
|
||||
time_t epoch = 0;
|
||||
time_s = localtime(&epoch);
|
||||
if (UNLIKELY(!time_s))
|
||||
fatal("VISO: localtime(0) = NULL\n");
|
||||
struct tm time_s_buf;
|
||||
struct tm *time_s = NULL;
|
||||
time_t epoch = 0;
|
||||
|
||||
/* Force year clamping if the timestamp is known to be outside the supported ranges. */
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(&time_s_buf, &time) == 0)
|
||||
time_s = &time_s_buf;
|
||||
#else
|
||||
time_s = localtime_r(&time, &time_s_buf);
|
||||
#endif
|
||||
|
||||
if (!time_s) {
|
||||
/* localtime may return NULL if time is negative or out of range */
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(&time_s_buf, &epoch) == 0)
|
||||
time_s = &time_s_buf;
|
||||
#else
|
||||
time_s = localtime_r(&epoch, &time_s_buf);
|
||||
#endif
|
||||
if (!time_s)
|
||||
fatal("VISO: localtime fallback to epoch failed\n");
|
||||
|
||||
/* Force year clamping for out-of-range times */
|
||||
if (time < (longform ? -62135596800LL : -2208988800LL)) /* 0001-01-01 00:00:00 : 1900-01-01 00:00:00 */
|
||||
time_s->tm_year = -1901;
|
||||
else if (time > (longform ? 253402300799LL : 5869583999LL)) /* 9999-12-31 23:59:59 : 2155-12-31 23:59:59 */
|
||||
time_s->tm_year = 8100;
|
||||
}
|
||||
|
||||
/* Clamp year to the supported ranges, and assume the
|
||||
OS returns valid numbers in the other struct fields. */
|
||||
/* Clamp year within supported ranges */
|
||||
if (time_s->tm_year < (longform ? -1900 : 0)) {
|
||||
time_s->tm_year = longform ? -1900 : 0;
|
||||
time_s->tm_mon = time_s->tm_hour = time_s->tm_min = time_s->tm_sec = 0;
|
||||
@@ -476,18 +488,18 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
|
||||
time_s->tm_min = time_s->tm_sec = 59;
|
||||
}
|
||||
|
||||
/* Convert timestamp. */
|
||||
/* Convert timestamp */
|
||||
if (longform) {
|
||||
p += sprintf((char *) p, "%04u%02u%02u%02u%02u%02u00",
|
||||
1900 + time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday,
|
||||
p += sprintf((char *)p, "%04u%02u%02u%02u%02u%02u00",
|
||||
1900 + (unsigned)time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday,
|
||||
time_s->tm_hour, time_s->tm_min, time_s->tm_sec);
|
||||
} else {
|
||||
*p++ = time_s->tm_year; /* year since 1900 */
|
||||
*p++ = 1 + time_s->tm_mon; /* month */
|
||||
*p++ = time_s->tm_mday; /* day */
|
||||
*p++ = time_s->tm_hour; /* hour */
|
||||
*p++ = time_s->tm_min; /* minute */
|
||||
*p++ = time_s->tm_sec; /* second */
|
||||
*p++ = (uint8_t)time_s->tm_year; /* year since 1900 */
|
||||
*p++ = (uint8_t)(1 + time_s->tm_mon); /* month */
|
||||
*p++ = (uint8_t)time_s->tm_mday; /* day */
|
||||
*p++ = (uint8_t)time_s->tm_hour; /* hour */
|
||||
*p++ = (uint8_t)time_s->tm_min; /* minute */
|
||||
*p++ = (uint8_t)time_s->tm_sec; /* second */
|
||||
}
|
||||
if (format & VISO_FORMAT_ISO)
|
||||
*p++ = tz_offset; /* timezone (ISO only) */
|
||||
@@ -1034,8 +1046,15 @@ next_dir:
|
||||
the timezone offset for descriptors and file times to use. */
|
||||
tzset();
|
||||
time_t now = time(NULL);
|
||||
if (viso->format & VISO_FORMAT_ISO) /* timezones are ISO only */
|
||||
tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4);
|
||||
struct tm now_tm;
|
||||
if (viso->format & VISO_FORMAT_ISO) { /* timezones are ISO only */
|
||||
#ifdef _WIN32
|
||||
gmtime_s(&now_tm, &now); // Windows: output first param, input second
|
||||
#else
|
||||
gmtime_r(&now, &now_tm); // POSIX: input first param, output second
|
||||
#endif
|
||||
tz_offset = (now - mktime(&now_tm)) / (3600 / 4);
|
||||
}
|
||||
|
||||
/* Get root directory basename for the volume ID. */
|
||||
const char *basename = path_get_filename(viso->root_dir->path);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
add_library(chipset OBJECT
|
||||
82c100.c
|
||||
acc2036.c
|
||||
acc2168.c
|
||||
cs8220.c
|
||||
cs8230.c
|
||||
@@ -48,6 +49,7 @@ add_library(chipset OBJECT
|
||||
opti291.c
|
||||
opti391.c
|
||||
opti495.c
|
||||
opti498.c
|
||||
opti499.c
|
||||
opti602.c
|
||||
opti822.c
|
||||
|
||||
346
src/chipset/acc2036.c
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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 ACC 2036 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t virt;
|
||||
uint32_t phys;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
} ram_page_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reg;
|
||||
uint8_t regs[32];
|
||||
|
||||
ram_page_t ram_mid_pages[24];
|
||||
ram_page_t ems_pages[4];
|
||||
} acc2036_t;
|
||||
|
||||
static uint8_t
|
||||
acc2036_mem_read(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
acc2036_mem_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = *(uint16_t *) &(ram[addr]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_mem_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_mem_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *) &(ram[addr]) = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_recalc(acc2036_t *dev)
|
||||
{
|
||||
uint32_t ems_bases[4] = { 0x000c0000, 0x000c8000, 0x000d0000, 0x000e0000 };
|
||||
|
||||
int start_i = (ems_bases[dev->regs[0x0c] & 0x03] - 0x000a0000) >> 14;
|
||||
int end_i = start_i + 3;
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
mem_mapping_disable(&rp->mapping);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ram_page_t *ep = &dev->ems_pages[i];
|
||||
mem_mapping_disable(&ep->mapping);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
|
||||
if ((dev->regs[0x03] & 0x08) && (i >= start_i) && (i <= end_i)) {
|
||||
/* EMS */
|
||||
ram_page_t *ep = &dev->ems_pages[i - start_i];
|
||||
|
||||
mem_mapping_disable(&rp->mapping);
|
||||
mem_mapping_set_addr(&ep->mapping, ep->virt, 0x000040000);
|
||||
mem_mapping_set_exec(&ep->mapping, ram + ep->phys);
|
||||
mem_set_mem_state_both(ep->virt, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
int master_write;
|
||||
int master_read;
|
||||
int bit;
|
||||
int ew_flag;
|
||||
int er_flag;
|
||||
int flags;
|
||||
uint8_t val;
|
||||
|
||||
mem_mapping_set_addr(&rp->mapping, rp->virt, 0x000040000);
|
||||
mem_mapping_set_exec(&rp->mapping, ram + rp->phys);
|
||||
|
||||
if ((i >= 8) && (i <= 15)) {
|
||||
/* 0C0000-0DFFFF */
|
||||
master_write = dev->regs[0x02] & 0x08;
|
||||
master_read = dev->regs[0x02] & 0x04;
|
||||
bit = ((i - 8) >> 1);
|
||||
val = dev->regs[0x0d] & (1 << bit);
|
||||
if (i >= 12) {
|
||||
ew_flag = (dev->regs[0x07] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x07] & 0x80) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
} else {
|
||||
ew_flag = (dev->regs[0x07] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x07] & 0x40) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
}
|
||||
flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag;
|
||||
flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag;
|
||||
mem_set_mem_state_both(rp->virt, 0x00004000, flags);
|
||||
} else if (i > 15) {
|
||||
/* 0E0000-0FFFFF */
|
||||
master_write = dev->regs[0x02] & 0x02;
|
||||
master_read = dev->regs[0x02] & 0x01;
|
||||
bit = ((i - 8) >> 2);
|
||||
val = dev->regs[0x0c] & (1 << bit);
|
||||
if (i >= 20) {
|
||||
ew_flag = MEM_WRITE_EXTANY;
|
||||
er_flag = MEM_READ_EXTANY;
|
||||
} else {
|
||||
ew_flag = (dev->regs[0x0c] & 0x10) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x0c] & 0x10) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
}
|
||||
flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag;
|
||||
flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag;
|
||||
mem_set_mem_state_both(rp->virt, 0x00004000, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->regs[0x00] & 0x40)
|
||||
mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
for (int i = 0x01; i <= 0x06; i++) {
|
||||
uint32_t base = 0x00fe0000 - (i * 0x00010000);
|
||||
|
||||
if (dev->regs[i] & 0x40)
|
||||
mem_set_mem_state_both(base, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
if (dev->regs[i] & 0x80)
|
||||
mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
mem_remap_top(0);
|
||||
if (dev->regs[0x03] & 0x10) {
|
||||
if (dev->regs[0x02] & 0x0c)
|
||||
mem_remap_top(128);
|
||||
else if (dev->regs[0x02] & 0x03)
|
||||
mem_remap_top(256);
|
||||
else
|
||||
mem_remap_top(384);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
acc2036_in(uint16_t port, void *priv) {
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
uint8_t reg = dev->reg - 0x20;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port & 0x0001) switch (dev->reg) {
|
||||
default:
|
||||
break;
|
||||
case 0x20 ... 0x2e:
|
||||
case 0x31 ... 0x3f:
|
||||
ret = dev->regs[reg];
|
||||
break;
|
||||
} else
|
||||
ret = dev->reg;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_out(uint16_t port, uint8_t val, void *priv) {
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
uint8_t reg = dev->reg - 0x20;
|
||||
|
||||
if (port & 0x0001) switch (dev->reg) {
|
||||
default:
|
||||
break;
|
||||
case 0x20 ... 0x23:
|
||||
dev->regs[reg] = val;
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x24 ... 0x2b:
|
||||
dev->regs[reg] = val;
|
||||
dev->ems_pages[(reg - 0x04) >> 1].phys = ((dev->regs[reg & 0xfe] & 0x1f) << 19) |
|
||||
((dev->regs[reg | 0x01] & 0x1f) << 14);
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x2c: case 0x2d:
|
||||
dev->regs[reg] = val;
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x2e:
|
||||
dev->regs[reg] = val | 0x10;
|
||||
break;
|
||||
case 0x31:
|
||||
dev->regs[reg] = val;
|
||||
mem_a20_alt = (val & 0x01);
|
||||
mem_a20_recalc();
|
||||
flushmmucache();
|
||||
if (val & 0x02) {
|
||||
softresetx86(); /* Pulse reset! */
|
||||
cpu_set_edx();
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
case 0x32 ... 0x3f:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
} else
|
||||
dev->reg = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_close(void *priv)
|
||||
{
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
acc2036_init(UNUSED(const device_t *info))
|
||||
{
|
||||
acc2036_t *dev = (acc2036_t *) calloc(1, sizeof(acc2036_t));
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
|
||||
rp->virt = 0x000a0000 + (i << 14);
|
||||
rp->phys = 0x000a0000 + (i << 14);
|
||||
mem_mapping_add(&rp->mapping, rp->virt, 0x00004000,
|
||||
acc2036_mem_read, acc2036_mem_readw, NULL,
|
||||
acc2036_mem_write, acc2036_mem_writew, NULL,
|
||||
ram + rp->phys, MEM_MAPPING_INTERNAL, rp);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ram_page_t *ep = &dev->ems_pages[i];
|
||||
|
||||
ep->virt = 0x000d0000 + (i << 14);
|
||||
ep->phys = 0x00000000 + (i << 14);
|
||||
mem_mapping_add(&ep->mapping, ep->virt, 0x00004000,
|
||||
acc2036_mem_read, acc2036_mem_readw, NULL,
|
||||
acc2036_mem_write, acc2036_mem_writew, NULL,
|
||||
ram + ep->phys, MEM_MAPPING_INTERNAL, ep);
|
||||
mem_mapping_disable(&ep->mapping);
|
||||
}
|
||||
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
|
||||
dev->regs[0x00] = 0x02;
|
||||
dev->regs[0x0e] = 0x10;
|
||||
dev->regs[0x11] = 0x01;
|
||||
dev->regs[0x13] = 0x40;
|
||||
dev->regs[0x15] = 0x40;
|
||||
dev->regs[0x17] = 0x40;
|
||||
dev->regs[0x19] = 0x40;
|
||||
dev->regs[0x1b] = 0x40;
|
||||
dev->regs[0x1c] = 0x22;
|
||||
dev->regs[0x1d] = 0xc4;
|
||||
dev->regs[0x1f] = 0x30;
|
||||
acc2036_recalc(dev);
|
||||
|
||||
mem_a20_alt = 0x01;
|
||||
mem_a20_recalc();
|
||||
flushmmucache();
|
||||
|
||||
io_sethandler(0x00f2, 0x0002,
|
||||
acc2036_in, NULL, NULL, acc2036_out, NULL, NULL, dev);
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t acc2036_device = {
|
||||
.name = "ACC 2036",
|
||||
.internal_name = "acc2036",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = acc2036_init,
|
||||
.close = acc2036_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -158,7 +159,20 @@ opti283_shadow_recalc(opti283_t *dev)
|
||||
rom = dev->regs[0x11] & (1 << ((i >> 2) + 4));
|
||||
opti283_log("OPTI 283: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
|
||||
if (sh_enable && rom) {
|
||||
if (sh_copy) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
@@ -171,13 +185,8 @@ opti283_shadow_recalc(opti283_t *dev)
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
|
||||
if (sh_copy) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_EXTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
@@ -239,9 +248,21 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0x80) | (val & 0x7f);
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
case 0x14: {
|
||||
double bus_clk;
|
||||
switch (val & 0x01) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
fallthrough;
|
||||
}
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
@@ -310,6 +331,8 @@ opti283_init(UNUSED(const device_t *info))
|
||||
|
||||
opti283_shadow_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
*
|
||||
* Implementation of the OPTi 82C493/82C495 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -28,6 +27,7 @@
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
@@ -166,6 +166,27 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x26:
|
||||
opti495_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x25: {
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 3.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * 2.0) / 5.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +280,8 @@ opti495_init(const device_t *info)
|
||||
|
||||
io_sethandler(0x00e1, 0x0002, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -276,11 +299,25 @@ const device_t opti493_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti495_device = {
|
||||
const device_t opti495slc_device = {
|
||||
.name = "OPTi 82C495",
|
||||
.internal_name = "opti495",
|
||||
.internal_name = "opti495slc",
|
||||
.flags = 0,
|
||||
.local = OPTI495XLC,
|
||||
.local = OPTI495SLC,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti495sx_device = {
|
||||
.name = "OPTi 82C495SX",
|
||||
.internal_name = "opti495sx",
|
||||
.flags = 0,
|
||||
.local = OPTI495SX,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
|
||||
360
src/chipset/opti498.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C498 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_OPTI498_LOG
|
||||
int opti498_do_log = ENABLE_OPTI498_LOG;
|
||||
|
||||
static void
|
||||
opti498_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti498_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define opti498_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct mem_remapping_t {
|
||||
uint32_t phys;
|
||||
uint32_t virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
typedef struct opti498_t {
|
||||
uint8_t index;
|
||||
/* 0x30 for 496/497, 0x70 for 498. */
|
||||
uint8_t reg_base;
|
||||
uint8_t shadow_high;
|
||||
uint8_t regs[256];
|
||||
mem_remapping_t mem_remappings[2];
|
||||
mem_mapping_t mem_mappings[2];
|
||||
} opti498_t;
|
||||
|
||||
static uint8_t
|
||||
opti498_read_remapped_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_ram((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
opti498_read_remapped_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_ramw((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
opti498_read_remapped_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_raml((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_ram((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_ramw((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_raml((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_shadow_recalc(opti498_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t rbase;
|
||||
uint8_t sh_enable;
|
||||
uint8_t sh_mode;
|
||||
uint8_t rom;
|
||||
uint8_t sh_copy;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
dev->shadow_high = 0;
|
||||
|
||||
opti498_log("OPTI 498: %02X %02X %02X %02X\n", dev->regs[0x02], dev->regs[0x03], dev->regs[0x04], dev->regs[0x05]);
|
||||
|
||||
if (dev->regs[0x02] & 0x80) {
|
||||
if (dev->regs[0x04] & 0x02) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_EXTANY\n");
|
||||
} else {
|
||||
shadowbios_write = 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_INTERNAL\n");
|
||||
}
|
||||
} else {
|
||||
shadowbios = 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_INTERNAL, WRITE_DISABLED\n");
|
||||
}
|
||||
|
||||
sh_copy = dev->regs[0x02] & 0x08;
|
||||
for (uint8_t i = 0; i < 12; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (i >= 4)
|
||||
sh_enable = dev->regs[0x03] & (1 << (i - 4));
|
||||
else
|
||||
sh_enable = dev->regs[0x04] & (1 << (i + 4));
|
||||
sh_mode = dev->regs[0x02] & (1 << (i >> 2));
|
||||
rom = dev->regs[0x02] & (1 << ((i >> 2) + 4));
|
||||
opti498_log("OPTI 498: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
|
||||
if (sh_copy) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (sh_mode) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rbase = ((uint32_t) (dev->regs[0x05] & 0x3f)) << 20;
|
||||
|
||||
if (rbase > 0) {
|
||||
dev->mem_remappings[0].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[0], rbase, 0x00020000);
|
||||
|
||||
if (!dev->shadow_high) {
|
||||
rbase += 0x00020000;
|
||||
dev->mem_remappings[1].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[1], rbase, 0x00020000);
|
||||
} else
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
uint8_t reg = dev->index - dev->reg_base;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti498_log("OPTi 498: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
if ((reg >= 0x00) && (reg <= 0x0b)) switch (reg) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x00:
|
||||
dev->regs[reg] = (dev->regs[reg] & 0xc0) | (val & 0x3f);
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
case 0x07 ... 0x0b:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
dev->regs[reg] = val;
|
||||
opti498_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x06: {
|
||||
double bus_clk;
|
||||
dev->regs[reg] = val;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 8.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 5.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev->index = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti498_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
uint8_t reg = dev->index - dev->reg_base;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24) {
|
||||
if ((reg >= 0x00) && (reg <= 0x0b))
|
||||
ret = dev->regs[reg];
|
||||
|
||||
dev->index = 0xff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_close(void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
opti498_init(UNUSED(const device_t *info))
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) calloc(1, sizeof(opti498_t));
|
||||
|
||||
dev->reg_base = info->local & 0xff;
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x00] = 0x1f;
|
||||
dev->regs[0x01] = 0x8f;
|
||||
dev->regs[0x02] = 0xf0;
|
||||
dev->regs[0x07] = 0x70;
|
||||
dev->regs[0x09] = 0x70;
|
||||
|
||||
dev->mem_remappings[0].phys = 0x000a0000;
|
||||
dev->mem_remappings[1].phys = 0x000d0000;
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[0], 0, 0x00020000,
|
||||
opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml,
|
||||
opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[0].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[1], 0, 0x00020000,
|
||||
opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml,
|
||||
opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[1].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[1]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
|
||||
opti498_shadow_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 8.0));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t opti498_device = {
|
||||
.name = "OPTi 82C498",
|
||||
.internal_name = "opti498",
|
||||
.flags = 0,
|
||||
.local = 0x70,
|
||||
.init = opti498_init,
|
||||
.close = opti498_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -148,9 +149,28 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
case 0x20: {
|
||||
double coeff = (val & 0x10) ? 1.0 : 2.0;
|
||||
double bus_clk;
|
||||
switch (dev->regs[0x25] & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = (cpu_busspeed * coeff) / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = (cpu_busspeed * coeff) / 5.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = (cpu_busspeed * coeff) / 4.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * coeff) / 3.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !(val & 0x02);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
@@ -163,6 +183,28 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x2d:
|
||||
opti499_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x25: {
|
||||
double coeff = (dev->regs[0x20] & 0x10) ? 1.0 : 2.0;
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = (cpu_busspeed * coeff) / 8.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = (cpu_busspeed * coeff) / 6.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = (cpu_busspeed * coeff) / 5.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * coeff) / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,6 +271,8 @@ opti499_reset(void *priv)
|
||||
cpu_update_waitstates();
|
||||
|
||||
opti499_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round((cpu_busspeed * 2.0) / 6.0));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -182,6 +183,27 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0x25: {
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 5.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = cpu_busspeed / 3.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xe0:
|
||||
if (!(val & 0x01))
|
||||
dev->forced_green = 0;
|
||||
@@ -294,6 +316,8 @@ opti895_init(const device_t *info)
|
||||
|
||||
smram_enable(dev->smram, 0x00030000, 0x000b0000, 0x00010000, 0, 1);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -786,7 +786,7 @@ host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
codegen_addquad(block, (uintptr_t) p);
|
||||
codegen_addbyte3(block, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [R9]*/
|
||||
} else {
|
||||
fatal("host_x86_MOV32_REG_ABS - RAM offset = %016" PRIX64 " (p - ram = %016" PRIX64 ")\n", ram_offset, (uintptr_t) p - (uintptr_t) ram);
|
||||
fatal("host_x86_MOV32_REG_ABS - RAM offset = %016" PRIX64 " (p - ram = %016" PRIXPTR ")\n", ram_offset, (uintptr_t) p - (uintptr_t) ram);
|
||||
codegen_alloc_bytes(block, 6);
|
||||
codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/
|
||||
codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3));
|
||||
|
||||
@@ -660,6 +660,8 @@ load_network(void)
|
||||
nc->net_type = NET_TYPE_SLIRP;
|
||||
else if (!strcmp(p, "vde") || !strcmp(p, "2"))
|
||||
nc->net_type = NET_TYPE_VDE;
|
||||
else if (!strcmp(p, "tap") || !strcmp(p, "3"))
|
||||
nc->net_type = NET_TYPE_TAP;
|
||||
else
|
||||
nc->net_type = NET_TYPE_NONE;
|
||||
} else
|
||||
@@ -706,11 +708,12 @@ load_network(void)
|
||||
nc->net_type = NET_TYPE_SLIRP;
|
||||
else if (!strcmp(p, "vde") || !strcmp(p, "2"))
|
||||
nc->net_type = NET_TYPE_VDE;
|
||||
else if (!strcmp(p, "tap") || !strcmp(p, "3"))
|
||||
nc->net_type = NET_TYPE_TAP;
|
||||
else
|
||||
nc->net_type = NET_TYPE_NONE;
|
||||
} else
|
||||
nc->net_type = NET_TYPE_NONE;
|
||||
|
||||
sprintf(temp, "net_%02i_host_device", c + 1);
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p != NULL) {
|
||||
@@ -2433,7 +2436,9 @@ save_network(void)
|
||||
case NET_TYPE_VDE:
|
||||
ini_section_set_string(cat, temp, "vde");
|
||||
break;
|
||||
|
||||
case NET_TYPE_TAP:
|
||||
ini_section_set_string(cat, temp, "tap");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -264,6 +264,7 @@ opVPCEXT(uint32_t fetchdat)
|
||||
uint8_t b2;
|
||||
uint16_t cent;
|
||||
time_t now;
|
||||
struct tm tm_buf;
|
||||
struct tm *tm = NULL;
|
||||
|
||||
if (!is_vpc) /* only emulate this on Virtual PC machines */
|
||||
@@ -282,7 +283,16 @@ opVPCEXT(uint32_t fetchdat)
|
||||
/* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */
|
||||
if (b1 == 0x03) {
|
||||
(void) time(&now);
|
||||
tm = localtime(&now);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(&tm_buf, &now) == 0)
|
||||
tm = &tm_buf;
|
||||
#else
|
||||
tm = localtime_r(&now, &tm_buf);
|
||||
#endif
|
||||
|
||||
if (!tm)
|
||||
fatal("localtime() failed for host clock\n");
|
||||
}
|
||||
|
||||
if ((b1 == 0x07) && (b2 == 0x0b)) {
|
||||
|
||||
@@ -381,7 +381,7 @@ typedef struct {
|
||||
MMX_REG MM[8];
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# if defined(__APPLE__) && defined(__aarch64__)
|
||||
# if (defined(__APPLE__) && defined(__aarch64__)) || defined(__aarch64__)
|
||||
uint64_t old_fp_control;
|
||||
uint64_t new_fp_control;
|
||||
# else
|
||||
|
||||
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "primitiveTypes.h"
|
||||
|
||||
@@ -64,7 +65,7 @@ void softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t *
|
||||
{
|
||||
uint64_t wordJam;
|
||||
uint32_t wordDist;
|
||||
uint64_t *ptr;
|
||||
uint64_t *ptr = NULL;
|
||||
uint8_t i, innerDist;
|
||||
|
||||
wordJam = 0;
|
||||
@@ -89,7 +90,7 @@ void softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t *
|
||||
aPtr,
|
||||
innerDist,
|
||||
zPtr + indexMultiwordLoBut(4, wordDist)
|
||||
);
|
||||
);
|
||||
if (! wordDist) goto wordJam;
|
||||
} else {
|
||||
aPtr += indexWordLo(4 - wordDist);
|
||||
|
||||
@@ -41,7 +41,7 @@ add_library(dev OBJECT
|
||||
keyboard.c
|
||||
keyboard_at.c
|
||||
keyboard_xt.c
|
||||
../lpt.c
|
||||
lpt.c
|
||||
mouse.c
|
||||
mouse_bus.c
|
||||
mouse_microtouch_touchscreen.c
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <stdarg.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
@@ -334,13 +335,16 @@ hasp_close(void *priv)
|
||||
}
|
||||
|
||||
const lpt_device_t lpt_hasp_savquest_device = {
|
||||
.name = "Protection Dongle for Savage Quest",
|
||||
.internal_name = "dongle_savquest",
|
||||
.init = hasp_init_savquest,
|
||||
.close = hasp_close,
|
||||
.write_data = hasp_write_data,
|
||||
.write_ctrl = NULL,
|
||||
.read_data = NULL,
|
||||
.read_status = hasp_read_status,
|
||||
.read_ctrl = NULL
|
||||
.name = "Protection Dongle for Savage Quest",
|
||||
.internal_name = "dongle_savquest",
|
||||
.init = hasp_init_savquest,
|
||||
.close = hasp_close,
|
||||
.write_data = hasp_write_data,
|
||||
.write_ctrl = NULL,
|
||||
.autofeed = NULL,
|
||||
.strobe = NULL,
|
||||
.read_status = hasp_read_status,
|
||||
.read_ctrl = NULL,
|
||||
.epp_write_data = NULL,
|
||||
.epp_request_read = NULL
|
||||
};
|
||||
|
||||
@@ -156,7 +156,7 @@ isarom_init(const device_t *info)
|
||||
snprintf(dev->socket[i].nvr_path, sizeof(dev->socket[i].nvr_path), "isarom_%i_%i.nvr", dev->inst, i + 1);
|
||||
FILE *fp = nvr_fopen(dev->socket[i].nvr_path, "rb");
|
||||
if (fp != NULL) {
|
||||
fread(dev->socket[i].rom.rom, 1, dev->socket[i].size, fp);
|
||||
(void) !fread(dev->socket[i].rom.rom, 1, dev->socket[i].size, fp);
|
||||
fclose(fp);
|
||||
isarom_log("isarom[%u]: loaded %zu bytes from %s\n", dev->inst, read_bytes, dev->socket[i].nvr_path);
|
||||
} else
|
||||
|
||||
@@ -1817,8 +1817,6 @@ read_p1(atkbc_t *dev)
|
||||
Compaq: Reserved;
|
||||
NCR: DMA mode.
|
||||
*/
|
||||
kbc_at_log("ATkbc: read P1\n");
|
||||
|
||||
fixed_bits = 4;
|
||||
|
||||
/* The SMM handlers of Intel AMI Pentium BIOS'es expect bit 6 to be set. */
|
||||
@@ -2108,7 +2106,7 @@ kbc_at_process_cmd(void *priv)
|
||||
break;
|
||||
|
||||
case 0xc0: /* read P1 */
|
||||
kbc_at_log("ATkbc: read P2\n");
|
||||
kbc_at_log("ATkbc: read P1\n");
|
||||
kbc_delay_to_ob(dev, read_p1(dev), 0, 0x00);
|
||||
break;
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ enum {
|
||||
KBD_TYPE_ZENITH,
|
||||
KBD_TYPE_PRAVETZ,
|
||||
KBD_TYPE_HYUNDAI,
|
||||
KBD_TYPE_FE2010,
|
||||
KBD_TYPE_XTCLONE
|
||||
};
|
||||
|
||||
@@ -80,6 +81,7 @@ typedef struct xtkbd_t {
|
||||
uint8_t pa;
|
||||
uint8_t pb;
|
||||
uint8_t pd;
|
||||
uint8_t cfg;
|
||||
uint8_t clock;
|
||||
uint8_t key_waiting;
|
||||
uint8_t type;
|
||||
@@ -832,12 +834,26 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
|
||||
kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
|
||||
#endif
|
||||
break;
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
|
||||
case 0x62: /* Switch Register (aka Port C) */
|
||||
#ifdef ENABLE_KEYBOARD_XT_LOG
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
|
||||
kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10));
|
||||
break;
|
||||
#endif
|
||||
if (kbd->type == KBD_TYPE_FE2010) {
|
||||
kbd_log("XTkbd: Switch register in is %02X\n", val);
|
||||
if (!(kbd->cfg & 0x08))
|
||||
kbd->pd = (kbd->pd & 0x30) | (val & 0xcf);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
if (kbd->type == KBD_TYPE_FE2010) {
|
||||
kbd_log("XTkbd: Configuration register in is %02X\n", val);
|
||||
if (!(kbd->cfg & 0x08))
|
||||
kbd->cfg = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xc0 ... 0xcf: /* Pravetz Flags */
|
||||
kbd_log("XTkbd: Port %02X out: %02X\n", port, val);
|
||||
@@ -912,7 +928,12 @@ kbd_read(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 0x62: /* Switch Register (aka Port C) */
|
||||
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
|
||||
if (kbd->type == KBD_TYPE_FE2010) {
|
||||
if (kbd->pb & 0x04) /* PB2 */
|
||||
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
|
||||
else
|
||||
ret = kbd->pd >> 4;
|
||||
} else if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
|
||||
(kbd->type == KBD_TYPE_PRAVETZ)) {
|
||||
if (kbd->pb & 0x04) /* PB2 */
|
||||
switch (mem_size + isa_mem_size) {
|
||||
@@ -1037,7 +1058,7 @@ kbd_init(const device_t *info)
|
||||
(kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
|
||||
(kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) ||
|
||||
(kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) ||
|
||||
(kbd->type == KBD_TYPE_VTECH)) {
|
||||
(kbd->type == KBD_TYPE_VTECH) || (kbd->type == KBD_TYPE_FE2010)) {
|
||||
/* DIP switch readout: bit set = OFF, clear = ON. */
|
||||
if (kbd->type == KBD_TYPE_OLIVETTI)
|
||||
/* Olivetti M19
|
||||
@@ -1057,7 +1078,7 @@ kbd_init(const device_t *info)
|
||||
/* Switches 3, 4 - memory size. */
|
||||
if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
|
||||
(kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) ||
|
||||
(kbd->type == KBD_TYPE_TOSHIBA)) {
|
||||
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_FE2010)) {
|
||||
switch (mem_size) {
|
||||
case 256:
|
||||
kbd->pd |= 0x00;
|
||||
@@ -1356,7 +1377,7 @@ const device_t keyboard_xt_zenith_device = {
|
||||
|
||||
const device_t keyboard_xt_hyundai_device = {
|
||||
.name = "Hyundai XT Keyboard",
|
||||
.internal_name = "keyboard_x_hyundai",
|
||||
.internal_name = "keyboard_xt_hyundai",
|
||||
.flags = 0,
|
||||
.local = KBD_TYPE_HYUNDAI,
|
||||
.init = kbd_init,
|
||||
@@ -1368,6 +1389,20 @@ const device_t keyboard_xt_hyundai_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_xt_fe2010_device = {
|
||||
.name = "Faraday FE2010 XT Keyboard",
|
||||
.internal_name = "keyboard_xt_fe2010",
|
||||
.flags = 0,
|
||||
.local = KBD_TYPE_FE2010,
|
||||
.init = kbd_init,
|
||||
.close = kbd_close,
|
||||
.reset = kbd_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_xtclone_device = {
|
||||
.name = "XT (Clone) Keyboard",
|
||||
.internal_name = "keyboard_xtclone",
|
||||
|
||||
839
src/device/lpt.c
Normal file
@@ -0,0 +1,839 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/fifo.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/prt_devs.h>
|
||||
#include <86box/thread.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/network.h>
|
||||
|
||||
lpt_port_t lpt_ports[PARALLEL_MAX];
|
||||
|
||||
const lpt_device_t lpt_none_device = {
|
||||
.name = "None",
|
||||
.internal_name = "none",
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.write_data = NULL,
|
||||
.write_ctrl = NULL,
|
||||
.read_status = NULL,
|
||||
.read_ctrl = NULL
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *internal_name;
|
||||
const lpt_device_t *device;
|
||||
} lpt_devices[] = {
|
||||
// clang-format off
|
||||
{"none", &lpt_none_device },
|
||||
{"dss", &dss_device },
|
||||
{"lpt_dac", &lpt_dac_device },
|
||||
{"lpt_dac_stereo", &lpt_dac_stereo_device },
|
||||
{"text_prt", &lpt_prt_text_device },
|
||||
{"dot_matrix", &lpt_prt_escp_device },
|
||||
{"postscript", &lpt_prt_ps_device },
|
||||
#ifdef USE_PCL
|
||||
{"pcl", &lpt_prt_pcl_device },
|
||||
#endif
|
||||
{"plip", &lpt_plip_device },
|
||||
{"dongle_savquest", &lpt_hasp_savquest_device },
|
||||
{"", NULL }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
#ifdef ENABLE_LPT_LOG
|
||||
int lpt_do_log = ENABLE_LPT_LOG;
|
||||
|
||||
static void
|
||||
lpt_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (lpt_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define lpt_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
const char *
|
||||
lpt_device_get_name(const int id)
|
||||
{
|
||||
if (strlen(lpt_devices[id].internal_name) == 0)
|
||||
return NULL;
|
||||
if (lpt_devices[id].device == NULL)
|
||||
return "None";
|
||||
return lpt_devices[id].device->name;
|
||||
}
|
||||
|
||||
const char *
|
||||
lpt_device_get_internal_name(const int id)
|
||||
{
|
||||
if (strlen(lpt_devices[id].internal_name) == 0)
|
||||
return NULL;
|
||||
return lpt_devices[id].internal_name;
|
||||
}
|
||||
|
||||
int
|
||||
lpt_device_get_from_internal_name(const char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (strlen(lpt_devices[c].internal_name) != 0) {
|
||||
if (strcmp(lpt_devices[c].internal_name, s) == 0)
|
||||
return c;
|
||||
c++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_devices_init(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
lpt_ports[i].dt = (lpt_device_t *) lpt_devices[lpt_ports[i].device].device;
|
||||
|
||||
if (lpt_ports[i].dt && lpt_ports[i].dt->init)
|
||||
lpt_ports[i].priv = lpt_ports[i].dt->init(&lpt_ports[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_devices_close(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
lpt_port_t *dev = &lpt_ports[i];
|
||||
|
||||
if (lpt_ports[i].dt && lpt_ports[i].dt->close)
|
||||
dev->dt->close(dev->priv);
|
||||
|
||||
dev->dt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
lpt_get_ctrl_raw(const lpt_port_t *dev)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
if (dev->dt && dev->dt->read_ctrl && dev->priv)
|
||||
ret = (dev->dt->read_ctrl(dev->priv) & 0xef) | dev->enable_irq;
|
||||
else
|
||||
ret = 0xc0 | dev->ctrl | dev->enable_irq;
|
||||
|
||||
return ret & 0xdf;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
lpt_is_epp(const lpt_port_t *dev)
|
||||
{
|
||||
return (dev->epp || ((dev->ecp) && ((dev->ecr & 0xe0) == 0x80)));
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
lpt_get_ctrl(const lpt_port_t *dev)
|
||||
{
|
||||
uint8_t ret = lpt_get_ctrl_raw(dev);
|
||||
|
||||
if (!dev->ecp && !dev->epp)
|
||||
ret |= 0x20;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
lpt_write_fifo(lpt_port_t *dev, const uint8_t val, const uint8_t tag)
|
||||
{
|
||||
if (!fifo_get_full(dev->fifo)) {
|
||||
fifo_write_evt_tagged(tag, val, dev->fifo);
|
||||
|
||||
if (!timer_is_enabled(&dev->fifo_out_timer))
|
||||
timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lpt_ecp_update_irq(lpt_port_t *dev)
|
||||
{
|
||||
if (!(dev->ecr & 0x04) && ((dev->fifo_stat | dev->dma_stat) & 0x04))
|
||||
picintlevel(1 << dev->irq, &dev->irq_state);
|
||||
else
|
||||
picintclevel(1 << dev->irq, &dev->irq_state);
|
||||
}
|
||||
|
||||
static void
|
||||
lpt_autofeed(lpt_port_t *dev, const uint8_t val)
|
||||
{
|
||||
if (dev->dt && dev->dt->autofeed && dev->priv)
|
||||
dev->dt->autofeed(val, dev->priv);
|
||||
|
||||
dev->autofeed = val;
|
||||
}
|
||||
|
||||
static void
|
||||
lpt_strobe(lpt_port_t *dev, const uint8_t val)
|
||||
{
|
||||
if (dev->dt && dev->dt->strobe && dev->priv)
|
||||
dev->dt->strobe(dev->strobe, val, dev->priv);
|
||||
|
||||
dev->strobe = val;
|
||||
}
|
||||
|
||||
static void
|
||||
lpt_fifo_out_callback(void *priv)
|
||||
{
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
switch (dev->state) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case LPT_STATE_READ_DMA:
|
||||
;
|
||||
int ret = 0xff;
|
||||
|
||||
if (dev->dma == 0xff)
|
||||
ret = DMA_NODATA;
|
||||
else
|
||||
ret = dma_channel_read(dev->dma);
|
||||
|
||||
lpt_log("DMA %02X: %08X\n", dev->dma, ret);
|
||||
|
||||
if (ret != DMA_NODATA) {
|
||||
fifo_write_evt_tagged(0x01, (uint8_t) (ret & 0xff), dev->fifo);
|
||||
|
||||
if (ret & DMA_OVER)
|
||||
/* Internal flag to indicate we have finished the DMA reads. */
|
||||
dev->dma_stat = 0x08;
|
||||
}
|
||||
|
||||
timer_advance_u64(&dev->fifo_out_timer,
|
||||
(uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC));
|
||||
|
||||
if (dev->dma_stat || fifo_get_full(dev->fifo))
|
||||
dev->state = LPT_STATE_WRITE_FIFO;
|
||||
break;
|
||||
|
||||
case LPT_STATE_WRITE_FIFO:
|
||||
if (!fifo_get_empty(dev->fifo)) {
|
||||
uint8_t tag = 0x00;
|
||||
const uint8_t val = fifo_read_evt_tagged(&tag, dev->fifo);
|
||||
|
||||
lpt_log("FIFO: %02X, TAG = %02X\n", val, tag);
|
||||
|
||||
/* We do not currently support sending commands. */
|
||||
if (tag == 0x01) {
|
||||
if (dev->dt && dev->dt->write_data && dev->priv)
|
||||
dev->dt->write_data(val, dev->priv);
|
||||
|
||||
lpt_strobe(dev, 1);
|
||||
lpt_strobe(dev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->ecr & 0x08) {
|
||||
if (fifo_get_empty(dev->fifo)) {
|
||||
if (dev->dma_stat) {
|
||||
/* Now actually set the external flag. */
|
||||
dev->dma_stat = 0x04;
|
||||
dev->state = LPT_STATE_IDLE;
|
||||
lpt_ecp_update_irq(dev);
|
||||
lpt_autofeed(dev, 0);
|
||||
} else {
|
||||
dev->state = LPT_STATE_READ_DMA;
|
||||
|
||||
timer_advance_u64(&dev->fifo_out_timer,
|
||||
(uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC));
|
||||
}
|
||||
} else
|
||||
timer_advance_u64(&dev->fifo_out_timer,
|
||||
(uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC));
|
||||
} else if (!fifo_get_empty(dev->fifo))
|
||||
timer_advance_u64(&dev->fifo_out_timer,
|
||||
(uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC));
|
||||
else
|
||||
lpt_autofeed(dev, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_write(const uint16_t port, const uint8_t val, void *priv)
|
||||
{
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
uint16_t mask = 0x0407;
|
||||
|
||||
lpt_log("[W] %04X = %02X\n", port, val);
|
||||
|
||||
/* This is needed so the parallel port at 3BC works. */
|
||||
if (dev->addr & 0x0004)
|
||||
mask = 0x0403;
|
||||
|
||||
switch (port & mask) {
|
||||
case 0x0000:
|
||||
if (dev->ecp) {
|
||||
if ((dev->ecr & 0xe0) == 0x60)
|
||||
/* AFIFO */
|
||||
lpt_write_fifo(dev, val, 0x00);
|
||||
else if (!(dev->ecr & 0xc0) && (!(dev->ecr & 0x20) || !(lpt_get_ctrl_raw(dev) & 0x20)) &&
|
||||
dev->dt && dev->dt->write_data && dev->priv)
|
||||
/* DATAR */
|
||||
dev->dt->write_data(val, dev->priv);
|
||||
dev->dat = val;
|
||||
} else {
|
||||
/* DTR */
|
||||
if ((!dev->ext || !(lpt_get_ctrl_raw(dev) & 0x20)) && dev->dt &&
|
||||
dev->dt->write_data && dev->priv)
|
||||
dev->dt->write_data(val, dev->priv);
|
||||
dev->dat = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0001:
|
||||
break;
|
||||
|
||||
case 0x0002:
|
||||
if (dev->dt && dev->dt->write_ctrl && dev->priv) {
|
||||
if (dev->ecp)
|
||||
dev->dt->write_ctrl((val & 0xfc) | dev->autofeed | dev->strobe, dev->priv);
|
||||
else
|
||||
dev->dt->write_ctrl(val, dev->priv);
|
||||
}
|
||||
dev->ctrl = val;
|
||||
dev->enable_irq = val & 0x10;
|
||||
if (!(val & 0x10) && (dev->irq != 0xff))
|
||||
picintc(1 << dev->irq);
|
||||
dev->irq_state = 0;
|
||||
break;
|
||||
|
||||
case 0x0003:
|
||||
if (lpt_is_epp(dev)) {
|
||||
if (dev->dt && dev->dt->epp_write_data && dev->priv)
|
||||
dev->dt->epp_write_data(1, val, dev->priv);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0004 ... 0x0007:
|
||||
if (lpt_is_epp(dev)) {
|
||||
if (dev->dt && dev->dt->epp_write_data && dev->priv)
|
||||
dev->dt->epp_write_data(0, val, dev->priv);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0400: case 0x0404:
|
||||
switch (dev->ecr >> 5) {
|
||||
default:
|
||||
break;
|
||||
case 2:
|
||||
lpt_write_fifo(dev, val, 0x01);
|
||||
break;
|
||||
case 3:
|
||||
if (!(lpt_get_ctrl_raw(dev) & 0x20))
|
||||
lpt_write_fifo(dev, val, 0x01);
|
||||
break;
|
||||
case 6:
|
||||
/* TFIFO */
|
||||
if (!fifo_get_full(dev->fifo))
|
||||
fifo_write_evt(val, dev->fifo);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0402: case 0x0406:
|
||||
if (!(val & 0x0c))
|
||||
lpt_autofeed(dev, 0x00);
|
||||
else
|
||||
lpt_autofeed(dev, 0x02);
|
||||
|
||||
if ((dev->ecr & 0x04) && !(val & 0x04)) {
|
||||
dev->dma_stat = 0x00;
|
||||
fifo_reset(dev->fifo);
|
||||
if (val & 0x08) {
|
||||
dev->state = LPT_STATE_READ_DMA;
|
||||
dev->fifo_stat = 0x00;
|
||||
if (!timer_is_enabled(&dev->fifo_out_timer))
|
||||
timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC));
|
||||
} else {
|
||||
dev->state = LPT_STATE_WRITE_FIFO;
|
||||
if (lpt_get_ctrl_raw(dev) & 0x20)
|
||||
dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00;
|
||||
else
|
||||
dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04;
|
||||
}
|
||||
} else if ((val & 0x04) && !(dev->ecr & 0x04)) {
|
||||
if (timer_is_enabled(&dev->fifo_out_timer))
|
||||
timer_disable(&dev->fifo_out_timer);
|
||||
|
||||
dev->state = LPT_STATE_IDLE;
|
||||
}
|
||||
dev->ecr = val;
|
||||
lpt_ecp_update_irq(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lpt_fifo_d_ready_evt(void *priv)
|
||||
{
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
if (!(dev->ecr & 0x08)) {
|
||||
if (lpt_get_ctrl_raw(dev) & 0x20)
|
||||
dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00;
|
||||
else
|
||||
dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04;
|
||||
}
|
||||
|
||||
lpt_ecp_update_irq(dev);
|
||||
}
|
||||
|
||||
void
|
||||
lpt_write_to_fifo(void *priv, const uint8_t val)
|
||||
{
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
if (dev->ecp) {
|
||||
if (((dev->ecr & 0xe0) == 0x20) && (lpt_get_ctrl_raw(dev) & 0x20))
|
||||
dev->dat = val;
|
||||
else if (((dev->ecr & 0xe0) == 0x60) && (lpt_get_ctrl_raw(dev) & 0x20) &&
|
||||
!fifo_get_full(dev->fifo))
|
||||
fifo_write_evt_tagged(0x01, val, dev->fifo);
|
||||
|
||||
if (((dev->ecr & 0x0c) == 0x08) && (dev->dma != 0xff)) {
|
||||
const int ret = dma_channel_write(dev->dma, val);
|
||||
|
||||
if (ret & DMA_OVER)
|
||||
dev->dma_stat |= 0x04;
|
||||
}
|
||||
} else {
|
||||
if (dev->ext && (lpt_get_ctrl_raw(dev) & 0x20))
|
||||
dev->dat = val;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_write_to_dat(void *priv, const uint8_t val)
|
||||
{
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
dev->dat = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
lpt_read_fifo(const lpt_port_t *dev)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (!fifo_get_empty(dev->fifo))
|
||||
ret = fifo_read(dev->fifo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lpt_read_status(const int port)
|
||||
{
|
||||
lpt_port_t *dev = &lpt_ports[port];
|
||||
uint8_t low_bits = 0x07;
|
||||
uint8_t ret;
|
||||
|
||||
if (dev->ext) {
|
||||
low_bits = 0x03 | (dev->irq_state ? 0x00 : 0x04);
|
||||
if (dev->irq != 0xff)
|
||||
picintclevel(1 << dev->irq, &dev->irq_state);
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
if (dev->epp || dev->ecp) {
|
||||
low_bits = lpt_is_epp(dev) ? 0x02 : 0x03;
|
||||
if (lpt_get_ctrl_raw(dev) & 0x10)
|
||||
low_bits |= (dev->irq_state ? 0x00 : 0x04);
|
||||
else
|
||||
low_bits |= 0x04;
|
||||
}
|
||||
|
||||
if (dev->dt && dev->dt->read_status && dev->priv)
|
||||
ret = (dev->dt->read_status(dev->priv) & 0xf8) | low_bits;
|
||||
else
|
||||
ret = 0xd8 | low_bits;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lpt_read(const uint16_t port, void *priv)
|
||||
{
|
||||
const lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
uint16_t mask = 0x0407;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
/* This is needed so the parallel port at 3BC works. */
|
||||
if (dev->addr & 0x0004)
|
||||
mask = 0x0403;
|
||||
|
||||
switch (port & mask) {
|
||||
case 0x0000:
|
||||
if (dev->ecp) {
|
||||
if (!(dev->ecr & 0xc0))
|
||||
ret = dev->dat;
|
||||
} else {
|
||||
/* DTR */
|
||||
ret = dev->dat;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0001:
|
||||
ret = lpt_read_status(dev->id);
|
||||
break;
|
||||
|
||||
case 0x0002:
|
||||
ret = lpt_get_ctrl(dev);
|
||||
if (dev->ecp)
|
||||
ret = (ret & 0xfc) | (dev->ctrl & 0x03);
|
||||
break;
|
||||
|
||||
case 0x0003:
|
||||
if (lpt_is_epp(dev)) {
|
||||
if (dev->dt && dev->dt->epp_request_read && dev->priv)
|
||||
dev->dt->epp_request_read(1, dev->priv);
|
||||
ret = dev->dat;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0004 ... 0x0007:
|
||||
if (lpt_is_epp(dev)) {
|
||||
if (dev->dt && dev->dt->epp_request_read && dev->priv)
|
||||
dev->dt->epp_request_read(0, dev->priv);
|
||||
ret = dev->dat;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0400: case 0x0404:
|
||||
switch (dev->ecr >> 5) {
|
||||
default:
|
||||
break;
|
||||
case 3:
|
||||
if (lpt_get_ctrl_raw(dev) & 0x20)
|
||||
ret = lpt_read_fifo(dev);
|
||||
break;
|
||||
case 6:
|
||||
/* TFIFO */
|
||||
if (!fifo_get_empty(dev->fifo))
|
||||
ret = fifo_read_evt(dev->fifo);
|
||||
break;
|
||||
case 7:
|
||||
/* CNFGA */
|
||||
ret = 0x14;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0401: case 0x0405:
|
||||
if ((dev->ecr & 0xe0) == 0xe0) {
|
||||
/* CNFGB */
|
||||
ret = 0x08;
|
||||
ret |= (dev->irq_state ? 0x40 : 0x00);
|
||||
ret |= ((dev->irq == 0x05) ? 0x30 : 0x00);
|
||||
if ((dev->dma >= 1) && (dev->dma <= 3))
|
||||
ret |= dev->dma;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0402: case 0x0406:
|
||||
ret = dev->ecr | dev->fifo_stat | (dev->dma_stat & 0x04);
|
||||
ret |= (fifo_get_full(dev->fifo) ? 0x02 : 0x00);
|
||||
ret |= (fifo_get_empty(dev->fifo) ? 0x01 : 0x00);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lpt_log("[R] %04X = %02X\n", port, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lpt_read_port(const int port, const uint16_t reg)
|
||||
{
|
||||
lpt_port_t *dev = &(lpt_ports[port]);
|
||||
|
||||
return lpt_read(reg, dev);
|
||||
}
|
||||
|
||||
void
|
||||
lpt_irq(void *priv, const int raise)
|
||||
{
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
if (dev->enable_irq) {
|
||||
if (dev->irq != 0xff) {
|
||||
if (dev->ext) {
|
||||
if (raise)
|
||||
picintlevel(1 << dev->irq, &dev->irq_state);
|
||||
else
|
||||
picintclevel(1 << dev->irq, &dev->irq_state);
|
||||
} else {
|
||||
if (raise)
|
||||
picint(1 << dev->irq);
|
||||
else
|
||||
picintc(1 << dev->irq);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev->ext || (dev->irq == 0xff))
|
||||
dev->irq_state = raise;
|
||||
} else {
|
||||
if (dev->irq != 0xff) {
|
||||
if (dev->ext)
|
||||
picintclevel(1 << dev->irq, &dev->irq_state);
|
||||
else
|
||||
picintc(1 << dev->irq);
|
||||
}
|
||||
|
||||
dev->irq_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_set_ext(const int port, const uint8_t ext)
|
||||
{
|
||||
if (lpt_ports[port].enabled)
|
||||
lpt_ports[port].ext = ext;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_set_ecp(const int port, const uint8_t ecp)
|
||||
{
|
||||
if (lpt_ports[port].enabled) {
|
||||
const uint16_t addr = lpt_ports[port].addr;
|
||||
lpt_port_setup(port, 0xfff);
|
||||
lpt_ports[port].ecp = ecp;
|
||||
lpt_port_setup(port, addr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_set_epp(const int port, const uint8_t epp)
|
||||
{
|
||||
if (lpt_ports[port].enabled) {
|
||||
const uint16_t addr = lpt_ports[port].addr;
|
||||
lpt_port_setup(port, 0xfff);
|
||||
lpt_ports[port].epp = epp;
|
||||
lpt_port_setup(port, addr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_set_lv2(const int port, const uint8_t lv2)
|
||||
{
|
||||
if (lpt_ports[port].enabled) {
|
||||
const uint16_t addr = lpt_ports[port].addr;
|
||||
lpt_port_setup(port, 0xfff);
|
||||
lpt_ports[port].lv2 = lv2;
|
||||
lpt_port_setup(port, addr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_close(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
if (lpt_ports[i].enabled) {
|
||||
fifo_close(lpt_ports[i].fifo);
|
||||
lpt_ports[i].fifo = NULL;
|
||||
|
||||
timer_disable(&lpt_ports[i].fifo_out_timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_zero(lpt_port_t *dev)
|
||||
{
|
||||
lpt_port_t temp = { 0 };
|
||||
|
||||
temp.irq = dev->irq;
|
||||
temp.id = dev->id;
|
||||
temp.device = dev->device;
|
||||
temp.dt = dev->dt;
|
||||
temp.priv = dev->priv;
|
||||
temp.enabled = dev->enabled;
|
||||
temp.fifo = dev->fifo;
|
||||
temp.fifo_out_timer = dev->fifo_out_timer;
|
||||
|
||||
if (dev->enabled)
|
||||
lpt_port_remove(dev->id);
|
||||
|
||||
memset(dev, 0x00, sizeof(lpt_port_t));
|
||||
|
||||
dev->addr = 0xffff;
|
||||
dev->irq = temp.irq;
|
||||
dev->id = temp.id;
|
||||
dev->device = temp.device;
|
||||
dev->dt = temp.dt;
|
||||
dev->priv = temp.priv;
|
||||
dev->enabled = temp.enabled;
|
||||
dev->fifo = temp.fifo;
|
||||
dev->fifo_out_timer = temp.fifo_out_timer;
|
||||
|
||||
if (machine_has_bus(machine, MACHINE_BUS_MCA))
|
||||
dev->ext = 1;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_reset(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
if (lpt_ports[i].enabled)
|
||||
if (timer_is_enabled(&lpt_ports[i].fifo_out_timer))
|
||||
timer_disable(&lpt_ports[i].fifo_out_timer);
|
||||
|
||||
lpt_port_zero(&(lpt_ports[i]));
|
||||
|
||||
if (lpt_ports[i].enabled) {
|
||||
if (lpt_ports[i].irq_state) {
|
||||
if (lpt_ports[i].irq == 0xff)
|
||||
lpt_ports[i].irq_state = 0x00;
|
||||
else {
|
||||
picintclevel(lpt_ports[i].irq, &lpt_ports[i].irq_state);
|
||||
picintc(lpt_ports[i].irq);
|
||||
}
|
||||
}
|
||||
|
||||
lpt_ports[i].enable_irq = 0x00;
|
||||
lpt_ports[i].ext = !!(machine_has_bus(machine, MACHINE_BUS_MCA));
|
||||
lpt_ports[i].epp = 0;
|
||||
lpt_ports[i].ecp = 0;
|
||||
lpt_ports[i].ecr = 0x15;
|
||||
lpt_ports[i].dat = 0xff;
|
||||
lpt_ports[i].fifo_stat = 0x00;
|
||||
lpt_ports[i].dma_stat = 0x00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_init(void)
|
||||
{
|
||||
const uint16_t default_ports[PARALLEL_MAX] = { LPT1_ADDR, LPT2_ADDR, LPT_MDA_ADDR, LPT4_ADDR };
|
||||
const uint8_t default_irqs[PARALLEL_MAX] = { LPT1_IRQ, LPT2_IRQ, LPT_MDA_IRQ, LPT4_IRQ };
|
||||
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
lpt_ports[i].id = i;
|
||||
lpt_ports[i].dt = NULL;
|
||||
lpt_ports[i].priv = NULL;
|
||||
lpt_ports[i].fifo = NULL;
|
||||
memset(&lpt_ports[i].fifo_out_timer, 0x00, sizeof(pc_timer_t));
|
||||
|
||||
lpt_port_zero(&(lpt_ports[i]));
|
||||
|
||||
lpt_ports[i].addr = 0xffff;
|
||||
lpt_ports[i].irq = 0xff;
|
||||
lpt_ports[i].dma = 0xff;
|
||||
lpt_ports[i].enable_irq = 0x00;
|
||||
lpt_ports[i].ext = 0;
|
||||
lpt_ports[i].epp = 0;
|
||||
lpt_ports[i].ecp = 0;
|
||||
lpt_ports[i].ecr = 0x15;
|
||||
|
||||
if (lpt_ports[i].enabled) {
|
||||
lpt_port_setup(i, default_ports[i]);
|
||||
lpt_port_irq(i, default_irqs[i]);
|
||||
|
||||
lpt_ports[i].fifo = fifo16_init();
|
||||
|
||||
fifo_set_trigger_len(lpt_ports[i].fifo, 8);
|
||||
|
||||
fifo_set_d_ready_evt(lpt_ports[i].fifo, lpt_fifo_d_ready_evt);
|
||||
fifo_set_priv(lpt_ports[i].fifo, &lpt_ports[i]);
|
||||
|
||||
timer_add(&lpt_ports[i].fifo_out_timer, lpt_fifo_out_callback, &lpt_ports[i], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_setup(const int i, const uint16_t port)
|
||||
{
|
||||
if (lpt_ports[i].enabled) {
|
||||
if (lpt_ports[i].addr != 0xffff) {
|
||||
io_removehandler(lpt_ports[i].addr, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
io_removehandler(lpt_ports[i].addr + 0x0400, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
}
|
||||
if (port != 0xffff) {
|
||||
lpt_log("Set handler: %04X-%04X\n", port, port + 0x0003);
|
||||
io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
if (lpt_ports[i].epp)
|
||||
io_sethandler(lpt_ports[i].addr + 0x0003, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
if (lpt_ports[i].ecp || lpt_ports[i].lv2) {
|
||||
io_sethandler(port + 0x0400, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
if (lpt_ports[i].epp)
|
||||
io_sethandler(lpt_ports[i].addr + 0x0403, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
}
|
||||
}
|
||||
lpt_ports[i].addr = port;
|
||||
} else
|
||||
lpt_ports[i].addr = 0xffff;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_irq(const int i, const uint8_t irq)
|
||||
{
|
||||
if (lpt_ports[i].enabled)
|
||||
lpt_ports[i].irq = irq;
|
||||
else
|
||||
lpt_ports[i].irq = 0xff;
|
||||
|
||||
lpt_log("Port %i IRQ = %02X\n", i, irq);
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_dma(const int i, const uint8_t dma)
|
||||
{
|
||||
if (lpt_ports[i].enabled)
|
||||
lpt_ports[i].dma = dma;
|
||||
else
|
||||
lpt_ports[i].dma = 0xff;
|
||||
|
||||
lpt_log("Port %i DMA = %02X\n", i, dma);
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_remove(const int i)
|
||||
{
|
||||
if (lpt_ports[i].enabled && (lpt_ports[i].addr != 0xffff)) {
|
||||
io_removehandler(lpt_ports[i].addr, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
io_removehandler(lpt_ports[i].addr + 0x0400, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
|
||||
lpt_ports[i].addr = 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt1_remove_ams(void)
|
||||
{
|
||||
if (lpt_ports[0].enabled)
|
||||
io_removehandler(lpt_ports[0].addr + 1, 0x0002, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[0]);
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* Jasmine Iwanek <jasmine@iwanek.co.uk>
|
||||
*
|
||||
* Copyright 2021 Andreas J. Reichel.
|
||||
* Copyright 2021-2022 Jasmine Iwanek.
|
||||
* Copyright 2021-2025 Jasmine Iwanek.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -222,10 +222,15 @@ serial_passthrough_dev_init(const device_t *info)
|
||||
}
|
||||
|
||||
const char *serpt_mode_names[SERPT_MODES_MAX] = {
|
||||
[SERPT_MODE_VCON] = "vcon",
|
||||
[SERPT_MODE_TCPSRV] = "tcpsrv",
|
||||
[SERPT_MODE_TCPCLNT] = "tcpclnt",
|
||||
[SERPT_MODE_HOSTSER] = "hostser",
|
||||
#ifdef _WIN32
|
||||
[SERPT_MODE_NPIPE_SRV] = "npipesrv",
|
||||
[SERPT_MODE_NPIPE_CLNT] = "npipeclnt",
|
||||
#else
|
||||
[SERPT_MODE_VCON] = "vcon",
|
||||
#endif
|
||||
[SERPT_MODE_TCP_SRV] = "tcpsrv",
|
||||
[SERPT_MODE_TCP_CLNT] = "tcpclnt",
|
||||
[SERPT_MODE_HOSTSER] = "hostser",
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
@@ -240,19 +245,17 @@ static const device_config_t serial_passthrough_config[] = {
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
#ifdef _WIN32
|
||||
{ .description = "Named Pipe (Server)", .value = SERPT_MODE_VCON },
|
||||
#if 0 /* TODO */
|
||||
{ .description = "Named Pipe (Client)", .value = SERPT_MODE_VCON },
|
||||
#endif
|
||||
{ .description = "Named Pipe (Server)", .value = SERPT_MODE_NPIPE_SRV },
|
||||
{ .description = "Named Pipe (Client)", .value = SERPT_MODE_NPIPE_CLNT },
|
||||
#else /* _WIN32 */
|
||||
{ .description = "Pseudo Terminal/Virtual Console", .value = SERPT_MODE_VCON },
|
||||
{ .description = "Pseudo Terminal/Virtual Console", .value = SERPT_MODE_VCON },
|
||||
#endif /* _WIN32 */
|
||||
#if 0 /* TODO */
|
||||
{ .description = "TCP Server", .value = SERPT_MODE_TCPSRV },
|
||||
{ .description = "TCP Client", .value = SERPT_MODE_TCPCLNT },
|
||||
{ .description = "TCP Server", .value = SERPT_MODE_TCP_SRV },
|
||||
{ .description = "TCP Client", .value = SERPT_MODE_TCP_CLNT },
|
||||
#endif
|
||||
{ .description = "Host Serial Passthrough", .value = SERPT_MODE_HOSTSER },
|
||||
{ .description = "" }
|
||||
{ .description = "Host Serial Passthrough", .value = SERPT_MODE_HOSTSER },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
|
||||
@@ -56,35 +56,40 @@ static const struct {
|
||||
// clang-format off
|
||||
{ &device_none },
|
||||
{ &device_internal },
|
||||
{ &st506_xt_xebec_device },
|
||||
{ &st506_xt_wdxt_gen_device },
|
||||
/* ISA */
|
||||
{ &xtide_acculogic_device },
|
||||
{ &st506_xt_dtc5150x_device },
|
||||
{ &st506_xt_xebec_device },
|
||||
{ &xtide_device },
|
||||
{ &st506_xt_st11_m_device },
|
||||
{ &st506_xt_wd1002a_wx1_device },
|
||||
{ &st506_xt_wd1004a_wx1_device },
|
||||
{ &st506_at_wd1003_device },
|
||||
{ &st506_xt_st11_r_device },
|
||||
{ &st506_xt_victor_v86p_device },
|
||||
{ &st506_xt_wd1002a_27x_device },
|
||||
{ &st506_xt_wd1002a_wx1_device },
|
||||
{ &st506_xt_wd1004_27x_device },
|
||||
{ &st506_xt_wd1004a_27x_device },
|
||||
{ &st506_xt_victor_v86p_device },
|
||||
{ &esdi_at_wd1007vse1_device },
|
||||
{ &st506_xt_wd1004a_wx1_device },
|
||||
{ &xta_wdxt150_device },
|
||||
{ &st506_xt_wdxt_gen_device },
|
||||
/* ISA16 */
|
||||
{ &ide_isa_device },
|
||||
{ &ide_isa_2ch_device },
|
||||
{ &xtide_at_device },
|
||||
{ &xtide_at_2ch_device },
|
||||
{ &xtide_at_ps2_device },
|
||||
{ &xtide_at_ps2_2ch_device },
|
||||
{ &xta_wdxt150_device },
|
||||
{ &xtide_acculogic_device },
|
||||
{ &xtide_device },
|
||||
{ &st506_at_wd1003_device },
|
||||
{ &esdi_at_wd1007vse1_device },
|
||||
/* MCA */
|
||||
{ &esdi_ps2_device },
|
||||
{ &esdi_integrated_device },
|
||||
{ &ide_pci_device },
|
||||
{ &ide_pci_2ch_device },
|
||||
{ &mcide_device },
|
||||
/* VLB */
|
||||
{ &ide_vlb_device },
|
||||
{ &ide_vlb_2ch_device },
|
||||
{ &mcide_device },
|
||||
/* PCI */
|
||||
{ &ide_pci_device },
|
||||
{ &ide_pci_2ch_device },
|
||||
{ NULL }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -154,7 +154,7 @@ xtide_init(const device_t *info)
|
||||
sprintf(xtide->nvr_path, "xtide_%i.nvr", device_get_instance());
|
||||
FILE *fp = nvr_fopen(xtide->nvr_path, "rb");
|
||||
if (fp != NULL) {
|
||||
fread(xtide->bios_rom.rom, 1, 0x2000, fp);
|
||||
(void) !fread(xtide->bios_rom.rom, 1, 0x2000, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,9 @@ typedef struct hdd_image_t {
|
||||
hdd_image_t hdd_images[HDD_NUM];
|
||||
|
||||
static char empty_sector[512];
|
||||
#ifndef __unix__
|
||||
static char *empty_sector_1mb;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HDD_IMAGE_LOG
|
||||
int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG;
|
||||
|
||||
@@ -191,7 +191,7 @@ fdc_ctrl_reset(void *priv)
|
||||
fdc->step = 0;
|
||||
fdc->power_down = 0;
|
||||
|
||||
if (!fdc->lock) {
|
||||
if (!fdc->lock && !fdc->fifointest) {
|
||||
fdc->fifo = 0;
|
||||
fdc->tfifo = 1;
|
||||
|
||||
@@ -808,6 +808,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv)
|
||||
fdc->tfifo = 1;
|
||||
fdc->fifointest = 0;
|
||||
}
|
||||
fifo_reset(fdc->fifo_p);
|
||||
fifo_set_len(fdc->fifo_p, fdc->tfifo + 1);
|
||||
fifo_set_trigger_len(fdc->fifo_p, fdc->tfifo + 1);
|
||||
}
|
||||
return;
|
||||
case 4: /* DSR */
|
||||
|
||||
@@ -177,6 +177,8 @@ extern char usr_path[1024]; /* path (dir) of user data */
|
||||
extern char cfg_path[1024]; /* full path of config file */
|
||||
extern int open_dir_usr_path; /* default file open dialog directory of usr_path */
|
||||
extern char uuid[MAX_UUID_LEN]; /* UUID or machine identifier */
|
||||
extern char vmm_path[1024]; /* VM Manager path to scan (temporary) */
|
||||
extern int vmm_enabled;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
extern FILE *stdlog; /* file to log output to */
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define EMU_CHIPSET_H
|
||||
|
||||
/* ACC */
|
||||
extern const device_t acc2036_device;
|
||||
extern const device_t acc2168_device;
|
||||
|
||||
/* ALi */
|
||||
@@ -123,7 +124,9 @@ extern const device_t opti381_device;
|
||||
extern const device_t opti391_device;
|
||||
extern const device_t opti481_device;
|
||||
extern const device_t opti493_device;
|
||||
extern const device_t opti495_device;
|
||||
extern const device_t opti495slc_device;
|
||||
extern const device_t opti495sx_device;
|
||||
extern const device_t opti498_device;
|
||||
extern const device_t opti499_device;
|
||||
extern const device_t opti601_device;
|
||||
extern const device_t opti602_device;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef EMU_FLASH_H
|
||||
#define EMU_FLASH_H
|
||||
|
||||
extern const device_t amd_am28f010_flash_device;
|
||||
extern const device_t catalyst_flash_device;
|
||||
|
||||
extern const device_t intel_flash_bxt_ami_device;
|
||||
|
||||
@@ -228,6 +228,7 @@ extern const device_t keyboard_xt_lxt3_device;
|
||||
extern const device_t keyboard_xt_olivetti_device;
|
||||
extern const device_t keyboard_xt_zenith_device;
|
||||
extern const device_t keyboard_xt_hyundai_device;
|
||||
extern const device_t keyboard_xt_fe2010_device;
|
||||
extern const device_t keyboard_xtclone_device;
|
||||
extern const device_t keyboard_at_device;
|
||||
extern const device_t keyboard_at_ami_device;
|
||||
|
||||
@@ -25,14 +25,24 @@ typedef struct lpt_device_t {
|
||||
void (*close)(void *priv);
|
||||
void (*write_data)(uint8_t val, void *priv);
|
||||
void (*write_ctrl)(uint8_t val, void *priv);
|
||||
uint8_t (*read_data)(void *priv);
|
||||
void (*autofeed)(uint8_t val,void *priv);
|
||||
void (*strobe)(uint8_t old, uint8_t val,void *priv);
|
||||
uint8_t (*read_status)(void *priv);
|
||||
uint8_t (*read_ctrl)(void *priv);
|
||||
void (*epp_write_data)(uint8_t is_addr, uint8_t val, void *priv);
|
||||
void (*epp_request_read)(uint8_t is_addr, void *priv);
|
||||
} lpt_device_t;
|
||||
|
||||
extern void lpt_set_ext(int port, uint8_t ext);
|
||||
extern void lpt_set_ecp(int port, uint8_t ecp);
|
||||
extern void lpt_set_epp(int port, uint8_t epp);
|
||||
extern void lpt_set_lv2(int port, uint8_t lv2);
|
||||
extern void lpt_reset(void);
|
||||
extern void lpt_close(void);
|
||||
extern void lpt_init(void);
|
||||
extern void lpt_port_setup(int i, uint16_t port);
|
||||
extern void lpt_port_irq(int i, uint8_t irq);
|
||||
extern void lpt_port_dma(int i, uint8_t dma);
|
||||
extern void lpt_port_remove(int i);
|
||||
extern void lpt1_remove_ams(void);
|
||||
|
||||
@@ -68,31 +78,62 @@ void lpt_devices_close(void);
|
||||
typedef struct lpt_port_t {
|
||||
uint8_t enabled;
|
||||
uint8_t irq;
|
||||
uint8_t irq_state;
|
||||
uint8_t dma;
|
||||
uint8_t dat;
|
||||
uint8_t ctrl;
|
||||
uint8_t ext;
|
||||
uint8_t epp;
|
||||
uint8_t ecp;
|
||||
uint8_t ecr;
|
||||
uint8_t in_dat;
|
||||
uint8_t fifo_stat;
|
||||
uint8_t dma_stat;
|
||||
uint8_t state;
|
||||
uint8_t autofeed;
|
||||
uint8_t strobe;
|
||||
uint8_t lv2;
|
||||
uint8_t pad[7];
|
||||
uint16_t addr;
|
||||
uint16_t pad0;
|
||||
uint16_t id;
|
||||
uint16_t pad0[2];
|
||||
int device;
|
||||
int enable_irq;
|
||||
lpt_device_t *dt;
|
||||
#ifdef FIFO_H
|
||||
fifo16_t *fifo;
|
||||
#else
|
||||
void *fifo;
|
||||
#endif
|
||||
void *priv;
|
||||
|
||||
pc_timer_t fifo_out_timer;
|
||||
} lpt_port_t;
|
||||
|
||||
typedef enum {
|
||||
LPT_STATE_IDLE = 0,
|
||||
LPT_STATE_READ_DMA,
|
||||
LPT_STATE_WRITE_FIFO
|
||||
} lpt_state_t;
|
||||
|
||||
extern lpt_port_t lpt_ports[PARALLEL_MAX];
|
||||
|
||||
extern void lpt_write(uint16_t port, uint8_t val, void *priv);
|
||||
extern uint8_t lpt_read(uint16_t port, void *priv);
|
||||
extern void lpt_write(uint16_t port, uint8_t val, void *priv);
|
||||
|
||||
extern uint8_t lpt_read_port(int port, uint16_t reg);
|
||||
extern void lpt_write_to_fifo(void *priv, uint8_t val);
|
||||
|
||||
extern uint8_t lpt_read_status(int port);
|
||||
extern void lpt_irq(void *priv, int raise);
|
||||
extern uint8_t lpt_read(uint16_t port, void *priv);
|
||||
|
||||
extern uint8_t lpt_read_port(int port, uint16_t reg);
|
||||
|
||||
extern uint8_t lpt_read_status(int port);
|
||||
extern void lpt_irq(void *priv, int raise);
|
||||
|
||||
extern int lpt_device_get_from_internal_name(const char *s);
|
||||
|
||||
extern const char *lpt_device_get_name(int id);
|
||||
extern const char *lpt_device_get_internal_name(int id);
|
||||
|
||||
extern int lpt_device_get_from_internal_name(char *s);
|
||||
|
||||
extern const lpt_device_t lpt_dac_device;
|
||||
extern const lpt_device_t lpt_dac_stereo_device;
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PCJR_RGB 0
|
||||
#define PCJR_COMPOSITE 1
|
||||
#define PCJR_RGB 0
|
||||
#define PCJR_COMPOSITE 1
|
||||
#define PCJR_RGB_NO_BROWN 4
|
||||
#define PCJR_RGB_IBM_5153 5
|
||||
|
||||
typedef struct pcjr_s
|
||||
{
|
||||
|
||||
@@ -197,6 +197,7 @@ enum {
|
||||
MACHINE_CHIPSET_GC100A,
|
||||
MACHINE_CHIPSET_GC103,
|
||||
MACHINE_CHIPSET_HT18,
|
||||
MACHINE_CHIPSET_ACC_2036,
|
||||
MACHINE_CHIPSET_ACC_2168,
|
||||
MACHINE_CHIPSET_ALI_M1217,
|
||||
MACHINE_CHIPSET_ALI_M6117,
|
||||
@@ -240,7 +241,9 @@ enum {
|
||||
MACHINE_CHIPSET_OPTI_391,
|
||||
MACHINE_CHIPSET_OPTI_481,
|
||||
MACHINE_CHIPSET_OPTI_493,
|
||||
MACHINE_CHIPSET_OPTI_495,
|
||||
MACHINE_CHIPSET_OPTI_495SLC,
|
||||
MACHINE_CHIPSET_OPTI_495SX,
|
||||
MACHINE_CHIPSET_OPTI_498,
|
||||
MACHINE_CHIPSET_OPTI_499,
|
||||
MACHINE_CHIPSET_OPTI_895_802G,
|
||||
MACHINE_CHIPSET_OPTI_547_597,
|
||||
@@ -456,6 +459,7 @@ extern int machine_at_px286_init(const machine_t *);
|
||||
extern int machine_at_quadt286_init(const machine_t *);
|
||||
extern int machine_at_mr286_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pbl300sx_init(const machine_t *);
|
||||
extern int machine_at_neat_init(const machine_t *);
|
||||
extern int machine_at_neat_ami_init(const machine_t *);
|
||||
extern int machine_at_ataripc4_init(const machine_t *);
|
||||
@@ -465,6 +469,7 @@ extern int machine_at_quadt386sx_init(const machine_t *);
|
||||
extern int machine_at_award286_init(const machine_t *);
|
||||
extern int machine_at_gdc212m_init(const machine_t *);
|
||||
extern int machine_at_gw286ct_init(const machine_t *);
|
||||
extern int machine_at_drsm35286_init(const machine_t *);
|
||||
extern int machine_at_senor_scat286_init(const machine_t *);
|
||||
extern int machine_at_super286c_init(const machine_t *);
|
||||
extern int machine_at_super286tr_init(const machine_t *);
|
||||
@@ -475,6 +480,7 @@ extern int machine_at_kmxc02_init(const machine_t *);
|
||||
extern int machine_at_deskmaster286_init(const machine_t *);
|
||||
|
||||
extern int machine_at_dells200_init(const machine_t *);
|
||||
extern int machine_at_at122_init(const machine_t *);
|
||||
extern int machine_at_tuliptc7_init(const machine_t *);
|
||||
|
||||
extern int machine_at_pc8_init(const machine_t *);
|
||||
@@ -512,6 +518,7 @@ extern int machine_at_dataexpert386wb_init(const machine_t *);
|
||||
extern int machine_at_isa486c_init(const machine_t *);
|
||||
extern int machine_at_genoa486_init(const machine_t *);
|
||||
extern int machine_at_ga486l_init(const machine_t *);
|
||||
extern int machine_at_cobalt_init(const machine_t *);
|
||||
extern int machine_at_cougar_init(const machine_t *);
|
||||
|
||||
extern int machine_at_acc386_init(const machine_t *);
|
||||
@@ -544,6 +551,7 @@ extern int machine_at_winbios1429_init(const machine_t *);
|
||||
extern int machine_at_opti495_init(const machine_t *);
|
||||
extern int machine_at_opti495_ami_init(const machine_t *);
|
||||
extern int machine_at_opti495_mr_init(const machine_t *);
|
||||
extern int machine_at_c747_init(const machine_t *);
|
||||
extern int machine_at_exp4349_init(const machine_t *);
|
||||
|
||||
extern int machine_at_vect486vl_init(const machine_t *);
|
||||
@@ -564,6 +572,7 @@ extern int machine_at_dtk461_init(const machine_t *);
|
||||
extern int machine_at_sis401_init(const machine_t *);
|
||||
extern int machine_at_isa486_init(const machine_t *);
|
||||
extern int machine_at_av4_init(const machine_t *);
|
||||
extern int machine_at_advantage40xxd_init(const machine_t *);
|
||||
extern int machine_at_valuepoint433_init(const machine_t *);
|
||||
|
||||
extern int machine_at_vli486sv2g_init(const machine_t *);
|
||||
@@ -646,6 +655,7 @@ extern void machine_at_award_common_init(const machine_t *);
|
||||
|
||||
extern void machine_at_sp4_common_init(const machine_t *model);
|
||||
|
||||
extern int machine_at_v12p_init(const machine_t *);
|
||||
extern int machine_at_excaliburpci_init(const machine_t *);
|
||||
extern int machine_at_p5mp3_init(const machine_t *);
|
||||
extern int machine_at_dellxp60_init(const machine_t *);
|
||||
@@ -973,6 +983,7 @@ extern int machine_xt_kaypropc_init(const machine_t *);
|
||||
extern int machine_xt_sansx16_init(const machine_t *);
|
||||
extern int machine_xt_bw230_init(const machine_t *);
|
||||
extern int machine_xt_pb8810_init(const machine_t *);
|
||||
extern int machine_xt_tuliptc8_init(const machine_t *);
|
||||
|
||||
extern int machine_xt_v20xt_init(const machine_t *);
|
||||
|
||||
|
||||
@@ -265,12 +265,16 @@ extern uint32_t biosmask;
|
||||
extern uint32_t biosaddr;
|
||||
|
||||
extern int readlookup[256];
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
extern uintptr_t *readlookup2;
|
||||
#endif
|
||||
extern uintptr_t old_rl2;
|
||||
extern uint8_t uncached;
|
||||
extern int readlnext;
|
||||
extern int writelookup[256];
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
extern uintptr_t *writelookup2;
|
||||
#endif
|
||||
extern int writelnext;
|
||||
extern uint32_t ram_mapped_addr[64];
|
||||
extern uint8_t page_ff[4096];
|
||||
@@ -288,7 +292,16 @@ extern mem_mapping_t bios_high_mapping;
|
||||
extern uint32_t mem_logical_addr;
|
||||
|
||||
extern page_t *pages;
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
extern page_t **page_lookup;
|
||||
#endif
|
||||
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
/* The lookup tables. */
|
||||
extern page_t *page_lookup[1048576];
|
||||
extern uintptr_t readlookup2[1048576];
|
||||
extern uintptr_t writelookup2[1048576];
|
||||
#endif
|
||||
|
||||
extern uint32_t get_phys_virt;
|
||||
extern uint32_t get_phys_phys;
|
||||
@@ -457,6 +470,9 @@ extern void mem_a20_init(void);
|
||||
extern void mem_a20_recalc(void);
|
||||
|
||||
extern void mem_init(void);
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
extern void mem_free(void);
|
||||
#endif
|
||||
extern void mem_close(void);
|
||||
extern void mem_zero(void);
|
||||
extern void mem_reset(void);
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#define NET_TYPE_SLIRP 1 /* use the SLiRP port forwarder */
|
||||
#define NET_TYPE_PCAP 2 /* use the (Win)Pcap API */
|
||||
#define NET_TYPE_VDE 3 /* use the VDE plug API */
|
||||
#define NET_TYPE_TAP 4 /* use a linux TAP device */
|
||||
|
||||
#define NET_MAX_FRAME 1518
|
||||
/* Queue size must be a power of 2 */
|
||||
@@ -126,6 +127,7 @@ typedef struct netdrv_t {
|
||||
extern const netdrv_t net_pcap_drv;
|
||||
extern const netdrv_t net_slirp_drv;
|
||||
extern const netdrv_t net_vde_drv;
|
||||
extern const netdrv_t net_tap_drv;
|
||||
extern const netdrv_t net_null_drv;
|
||||
|
||||
struct _netcard_t {
|
||||
@@ -155,10 +157,11 @@ typedef struct {
|
||||
int has_slirp;
|
||||
int has_pcap;
|
||||
int has_vde;
|
||||
int has_tap;
|
||||
} network_devmap_t;
|
||||
|
||||
|
||||
#define HAS_NOSLIRP_NET(x) (x.has_pcap || x.has_vde)
|
||||
#define HAS_NOSLIRP_NET(x) (x.has_pcap || x.has_vde || x.has_tap)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
40
src/include/86box/renderdefs.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* definitions for renderers
|
||||
*
|
||||
* Authors: Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*/
|
||||
#ifndef EMU_RENDERDEFS_H
|
||||
#define EMU_RENDERDEFS_H
|
||||
|
||||
#define RENDERER_NAME_DEFAULT "default"
|
||||
#define RENDERER_NAME_SYSTEM "system"
|
||||
#define RENDERER_NAME_QT_SOFTWARE "qt_software"
|
||||
#define RENDERER_NAME_QT_OPENGL "qt_opengl"
|
||||
#define RENDERER_NAME_QT_OPENGLES "qt_opengles"
|
||||
#define RENDERER_NAME_QT_OPENGL3 "qt_opengl3"
|
||||
#define RENDERER_NAME_QT_VULKAN "qt_vulkan"
|
||||
#define RENDERER_NAME_VNC "vnc"
|
||||
|
||||
#define RENDERER_SOFTWARE 0
|
||||
#define RENDERER_OPENGL3 1
|
||||
#define RENDERER_VULKAN 2
|
||||
#define RENDERER_VNC 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EMU_RENDERDEFS_H*/
|
||||
@@ -13,7 +13,7 @@
|
||||
* Jasmine Iwanek <jasmine@iwanek.co.uk>
|
||||
*
|
||||
* Copyright 2021 Andreas J. Reichel.
|
||||
* Copyright 2021-2022 Jasmine Iwanek.
|
||||
* Copyright 2021-2025 Jasmine Iwanek.
|
||||
*/
|
||||
|
||||
#ifndef SERIAL_PASSTHROUGH_H
|
||||
@@ -28,10 +28,15 @@
|
||||
#include <86box/serial.h>
|
||||
|
||||
enum serial_passthrough_mode {
|
||||
SERPT_MODE_VCON, /*Named Pipe (Server) / Pseudo Terminal/Virtual Console */
|
||||
SERPT_MODE_TCPSRV, /* TCP Server (TODO) */
|
||||
SERPT_MODE_TCPCLNT, /* TCP Client (TODO) */
|
||||
SERPT_MODE_HOSTSER, /* Host Serial Passthrough */
|
||||
#ifdef _WIN32
|
||||
SERPT_MODE_NPIPE_SRV, /* Named Pipe (Server) */
|
||||
SERPT_MODE_NPIPE_CLNT, /* Named Pipe (Client) */
|
||||
#else
|
||||
SERPT_MODE_VCON, /* Pseudo Terminal/Virtual Console */
|
||||
#endif
|
||||
SERPT_MODE_TCP_SRV, /* TCP Server (TODO) */
|
||||
SERPT_MODE_TCP_CLNT, /* TCP Client (TODO) */
|
||||
SERPT_MODE_HOSTSER, /* Host Serial Passthrough */
|
||||
SERPT_MODES_MAX,
|
||||
};
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
extern const device_t acc3221_device;
|
||||
|
||||
/* Acer / ALi */
|
||||
extern const device_t ali5105_device;
|
||||
|
||||
extern const device_t ali5123_device;
|
||||
|
||||
/* Chips & Technologies */
|
||||
@@ -79,10 +77,13 @@ extern const device_t i82091aa_398_device;
|
||||
extern const device_t i82091aa_ide_pri_device;
|
||||
extern const device_t i82091aa_ide_device;
|
||||
|
||||
/* National Semiconductors */
|
||||
extern const device_t pc87310_device;
|
||||
extern const device_t pc87310_ide_device;
|
||||
/* National Semiconductors PC87310 / ALi M5105 */
|
||||
#define PC87310_IDE 0x0001
|
||||
#define PC87310_ALI 0x0002
|
||||
|
||||
extern const device_t pc87310_device;
|
||||
|
||||
/* National Semiconductors */
|
||||
extern const device_t pc87306_device;
|
||||
extern const device_t pc87311_device;
|
||||
extern const device_t pc87311_ide_device;
|
||||
@@ -92,6 +93,7 @@ extern const device_t pc87332_398_ide_device;
|
||||
extern const device_t pc87332_398_ide_sec_device;
|
||||
extern const device_t pc87332_398_ide_fdcon_device;
|
||||
|
||||
/* National Semiconductors PC87307 / PC87309 */
|
||||
#define PCX7307_PC87307 0x00c0
|
||||
#define PCX7307_PC97307 0x00cf
|
||||
|
||||
@@ -125,6 +127,10 @@ extern const device_t sio_detect_device;
|
||||
#endif /* USE_SIO_DETECT */
|
||||
|
||||
/* UMC */
|
||||
extern const device_t um82c862f_device;
|
||||
extern const device_t um82c862f_ide_device;
|
||||
extern const device_t um82c863f_device;
|
||||
extern const device_t um82c863f_ide_device;
|
||||
extern const device_t um8663af_device;
|
||||
extern const device_t um8663af_ide_device;
|
||||
extern const device_t um8663af_sec_device;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void *sid_init(uint8_t type);
|
||||
void *sid_init(uint8_t type, double range);
|
||||
void sid_close(void *priv);
|
||||
void sid_reset(void *priv);
|
||||
uint8_t sid_read(uint16_t addr, void *priv);
|
||||
|
||||
@@ -37,6 +37,13 @@ typedef enum {
|
||||
EXTENSIONS_MAX
|
||||
} ibm8514_extensions_t;
|
||||
|
||||
typedef enum {
|
||||
VGA_MODE = 0,
|
||||
IBM_MODE,
|
||||
ATI_MODE,
|
||||
MODE_MAX
|
||||
} ibm8514_mode_t;
|
||||
|
||||
typedef struct hwcursor8514_t {
|
||||
int ena;
|
||||
int x;
|
||||
@@ -202,6 +209,7 @@ typedef struct ibm8514_t {
|
||||
int split;
|
||||
int h_disp;
|
||||
int h_total;
|
||||
int h_sync_start;
|
||||
int h_sync_width;
|
||||
int h_disp_time;
|
||||
int rowoffset;
|
||||
@@ -260,6 +268,7 @@ typedef struct ibm8514_t {
|
||||
int ext_pitch;
|
||||
int ext_crt_pitch;
|
||||
ibm8514_extensions_t extensions;
|
||||
ibm8514_mode_t mode;
|
||||
int onboard;
|
||||
int linear;
|
||||
uint32_t vram_amount;
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
#ifndef VIDEO_ATI_MACH8_H
|
||||
#define VIDEO_ATI_MACH8_H
|
||||
|
||||
typedef enum {
|
||||
ATI_68875 = 0,
|
||||
ATI_68860,
|
||||
RAMDAC_MAX
|
||||
} mach_ramdac_type;
|
||||
|
||||
typedef struct mach_t {
|
||||
ati_eeprom_t eeprom;
|
||||
svga_t svga;
|
||||
@@ -39,7 +45,7 @@ typedef struct mach_t {
|
||||
uint8_t irq_state;
|
||||
|
||||
int index;
|
||||
int ramdac_type;
|
||||
mach_ramdac_type ramdac_type;
|
||||
int old_mode;
|
||||
|
||||
uint16_t config1;
|
||||
|
||||
@@ -136,6 +136,7 @@ typedef struct svga_t {
|
||||
int packed_4bpp;
|
||||
int ps_bit_bug;
|
||||
int ati_4color;
|
||||
int vblankend;
|
||||
|
||||
/*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 :
|
||||
0MB-1MB - VRAM
|
||||
@@ -281,6 +282,10 @@ typedef struct svga_t {
|
||||
you should set this flag when entering that mode*/
|
||||
int disable_blink;
|
||||
|
||||
/*Force special shifter bypass logic for 8-bpp lowres modes.
|
||||
Needed if the screen is squished on certain S3 cards.*/
|
||||
int force_shifter_bypass;
|
||||
|
||||
/*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/
|
||||
int force_dword_mode;
|
||||
|
||||
@@ -404,15 +409,15 @@ uint32_t svga_lookup_lut_ram(svga_t* svga, uint32_t val);
|
||||
|
||||
/* We need a way to add a device with a pointer to a parent device so it can attach itself to it, and
|
||||
possibly also a second ATi 68860 RAM DAC type that auto-sets SVGA render on RAM DAC render change. */
|
||||
extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga);
|
||||
extern uint8_t ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga);
|
||||
extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, int is_8514, void *priv, svga_t *svga);
|
||||
extern uint8_t ati68860_ramdac_in(uint16_t addr, int is_8514, void *priv, svga_t *svga);
|
||||
extern void ati68860_set_ramdac_type(void *priv, int type);
|
||||
extern void ati68860_ramdac_set_render(void *priv, svga_t *svga);
|
||||
extern void ati68860_ramdac_set_pallook(void *priv, int i, uint32_t col);
|
||||
extern void ati68860_hwcursor_draw(svga_t *svga, int displine);
|
||||
|
||||
extern void ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga);
|
||||
extern uint8_t ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga);
|
||||
extern void ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, int is_8514, void *priv, svga_t *svga);
|
||||
extern uint8_t ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, int is_8514, void *priv, svga_t *svga);
|
||||
|
||||
extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga);
|
||||
extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga);
|
||||
|
||||
@@ -58,10 +58,6 @@ extern void svga_render_8bpp_highres(svga_t *svga);
|
||||
extern void svga_render_8bpp_clone_highres(svga_t *svga);
|
||||
extern void svga_render_8bpp_tseng_lowres(svga_t *svga);
|
||||
extern void svga_render_8bpp_tseng_highres(svga_t *svga);
|
||||
extern void svga_render_8bpp_gs_lowres(svga_t *svga);
|
||||
extern void svga_render_8bpp_gs_highres(svga_t *svga);
|
||||
extern void svga_render_8bpp_rgb_lowres(svga_t *svga);
|
||||
extern void svga_render_8bpp_rgb_highres(svga_t *svga);
|
||||
extern void svga_render_15bpp_lowres(svga_t *svga);
|
||||
extern void svga_render_15bpp_highres(svga_t *svga);
|
||||
extern void svga_render_15bpp_mix_lowres(svga_t *svga);
|
||||
|
||||
@@ -75,6 +75,7 @@ enum {
|
||||
#define FONT_IBM_MDA_437_NORDIC_PATH "roms/video/mda/4733197.bin"
|
||||
#define FONT_KAM_PATH "roms/video/mda/kam.bin"
|
||||
#define FONT_KAMCL16_PATH "roms/video/mda/kamcl16.bin"
|
||||
#define FONT_TULIP_DGA_PATH "roms/video/mda/tulip-dga-bios.bin"
|
||||
|
||||
typedef struct video_timings_t {
|
||||
int type;
|
||||
@@ -357,12 +358,14 @@ extern const device_t chips_69000_onboard_device;
|
||||
|
||||
/* Cirrus Logic GD54xx */
|
||||
extern const device_t gd5401_isa_device;
|
||||
extern const device_t gd5401_onboard_device;
|
||||
extern const device_t gd5402_isa_device;
|
||||
extern const device_t gd5402_onboard_device;
|
||||
extern const device_t gd5420_isa_device;
|
||||
extern const device_t gd5420_onboard_device;
|
||||
extern const device_t gd5422_isa_device;
|
||||
extern const device_t gd5424_vlb_device;
|
||||
extern const device_t gd5424_onboard_device;
|
||||
extern const device_t gd5426_isa_device;
|
||||
extern const device_t gd5426_diamond_speedstar_pro_a1_isa_device;
|
||||
extern const device_t gd5426_vlb_device;
|
||||
@@ -472,6 +475,7 @@ extern const device_t if386jega_device;
|
||||
|
||||
/* Oak OTI-0x7 */
|
||||
extern const device_t oti037c_device;
|
||||
extern const device_t oti037_pbl300sx_device;
|
||||
extern const device_t oti067_device;
|
||||
extern const device_t oti067_acer386_device;
|
||||
extern const device_t oti067_ama932j_device;
|
||||
|
||||
264
src/lpt.c
@@ -1,264 +0,0 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/prt_devs.h>
|
||||
#include <86box/thread.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/network.h>
|
||||
|
||||
lpt_port_t lpt_ports[PARALLEL_MAX];
|
||||
|
||||
const lpt_device_t lpt_none_device = {
|
||||
.name = "None",
|
||||
.internal_name = "none",
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.write_data = NULL,
|
||||
.write_ctrl = NULL,
|
||||
.read_data = NULL,
|
||||
.read_status = NULL,
|
||||
.read_ctrl = NULL
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *internal_name;
|
||||
const lpt_device_t *device;
|
||||
} lpt_devices[] = {
|
||||
// clang-format off
|
||||
{"none", &lpt_none_device },
|
||||
{"dss", &dss_device },
|
||||
{"lpt_dac", &lpt_dac_device },
|
||||
{"lpt_dac_stereo", &lpt_dac_stereo_device },
|
||||
{"text_prt", &lpt_prt_text_device },
|
||||
{"dot_matrix", &lpt_prt_escp_device },
|
||||
{"postscript", &lpt_prt_ps_device },
|
||||
#ifdef USE_PCL
|
||||
{"pcl", &lpt_prt_pcl_device },
|
||||
#endif
|
||||
{"plip", &lpt_plip_device },
|
||||
{"dongle_savquest", &lpt_hasp_savquest_device },
|
||||
{"", NULL }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const char *
|
||||
lpt_device_get_name(int id)
|
||||
{
|
||||
if (strlen(lpt_devices[id].internal_name) == 0)
|
||||
return NULL;
|
||||
if (!lpt_devices[id].device)
|
||||
return "None";
|
||||
return lpt_devices[id].device->name;
|
||||
}
|
||||
|
||||
const char *
|
||||
lpt_device_get_internal_name(int id)
|
||||
{
|
||||
if (strlen(lpt_devices[id].internal_name) == 0)
|
||||
return NULL;
|
||||
return lpt_devices[id].internal_name;
|
||||
}
|
||||
|
||||
int
|
||||
lpt_device_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (strlen(lpt_devices[c].internal_name) != 0) {
|
||||
if (strcmp(lpt_devices[c].internal_name, s) == 0)
|
||||
return c;
|
||||
c++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_devices_init(void)
|
||||
{
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
lpt_ports[i].dt = (lpt_device_t *) lpt_devices[lpt_ports[i].device].device;
|
||||
|
||||
if (lpt_ports[i].dt && lpt_ports[i].dt->init)
|
||||
lpt_ports[i].priv = lpt_ports[i].dt->init(&lpt_ports[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_devices_close(void)
|
||||
{
|
||||
lpt_port_t *dev;
|
||||
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
dev = &lpt_ports[i];
|
||||
|
||||
if (lpt_ports[i].dt && lpt_ports[i].dt->close)
|
||||
dev->dt->close(dev->priv);
|
||||
|
||||
dev->dt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
switch (port & 3) {
|
||||
case 0:
|
||||
if (dev->dt && dev->dt->write_data && dev->priv)
|
||||
dev->dt->write_data(val, dev->priv);
|
||||
dev->dat = val;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (dev->dt && dev->dt->write_ctrl && dev->priv)
|
||||
dev->dt->write_ctrl(val, dev->priv);
|
||||
dev->ctrl = val;
|
||||
dev->enable_irq = val & 0x10;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lpt_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
switch (port & 3) {
|
||||
case 0:
|
||||
if (dev->dt && dev->dt->read_data && dev->priv)
|
||||
ret = dev->dt->read_data(dev->priv);
|
||||
else
|
||||
ret = dev->dat;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (dev->dt && dev->dt->read_status && dev->priv)
|
||||
ret = dev->dt->read_status(dev->priv) | 0x07;
|
||||
else
|
||||
ret = 0xdf;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (dev->dt && dev->dt->read_ctrl && dev->priv)
|
||||
ret = (dev->dt->read_ctrl(dev->priv) & 0xef) | dev->enable_irq;
|
||||
else
|
||||
ret = 0xe0 | dev->ctrl | dev->enable_irq;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lpt_read_port(int port, uint16_t reg)
|
||||
{
|
||||
lpt_port_t *dev = &(lpt_ports[port]);
|
||||
uint8_t ret = lpt_read(reg, dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lpt_read_status(int port)
|
||||
{
|
||||
lpt_port_t *dev = &(lpt_ports[port]);
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->dt && dev->dt->read_status && dev->priv)
|
||||
ret = dev->dt->read_status(dev->priv) | 0x07;
|
||||
else
|
||||
ret = 0xdf;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_irq(void *priv, int raise)
|
||||
{
|
||||
const lpt_port_t *dev = (lpt_port_t *) priv;
|
||||
|
||||
if (dev->enable_irq && (dev->irq != 0xff)) {
|
||||
if (raise)
|
||||
picint(1 << dev->irq);
|
||||
else
|
||||
picintc(1 << dev->irq);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_init(void)
|
||||
{
|
||||
uint16_t default_ports[PARALLEL_MAX] = { LPT1_ADDR, LPT2_ADDR, LPT_MDA_ADDR, LPT4_ADDR };
|
||||
uint8_t default_irqs[PARALLEL_MAX] = { LPT1_IRQ, LPT2_IRQ, LPT_MDA_IRQ, LPT4_IRQ };
|
||||
|
||||
for (uint8_t i = 0; i < PARALLEL_MAX; i++) {
|
||||
lpt_ports[i].addr = 0xffff;
|
||||
lpt_ports[i].irq = 0xff;
|
||||
lpt_ports[i].enable_irq = 0x10;
|
||||
|
||||
if (lpt_ports[i].enabled) {
|
||||
lpt_port_setup(i, default_ports[i]);
|
||||
lpt_port_irq(i, default_irqs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_setup(int i, uint16_t port)
|
||||
{
|
||||
if (lpt_ports[i].enabled) {
|
||||
if ((lpt_ports[i].addr != 0xffff) && (lpt_ports[i].addr != 0x0000))
|
||||
io_removehandler(lpt_ports[i].addr, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
if ((port != 0xffff) && (port != 0x0000))
|
||||
io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
lpt_ports[i].addr = port;
|
||||
} else
|
||||
lpt_ports[i].addr = 0xffff;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_irq(int i, uint8_t irq)
|
||||
{
|
||||
if (lpt_ports[i].enabled)
|
||||
lpt_ports[i].irq = irq;
|
||||
else
|
||||
lpt_ports[i].irq = 0xff;
|
||||
}
|
||||
|
||||
void
|
||||
lpt_port_remove(int i)
|
||||
{
|
||||
if (lpt_ports[i].enabled && (lpt_ports[i].addr != 0xffff)) {
|
||||
io_removehandler(lpt_ports[i].addr, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
|
||||
lpt_ports[i].addr = 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lpt1_remove_ams(void)
|
||||
{
|
||||
if (lpt_ports[0].enabled)
|
||||
io_removehandler(lpt_ports[0].addr + 1, 0x0002, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[0]);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ machine_at_ama932j_init(const machine_t *model)
|
||||
|
||||
machine_at_headland_common_init(model, 2);
|
||||
|
||||
device_add(&ali5105_device);
|
||||
device_add_params(&pc87310_device, (void *) (PC87310_ALI));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -169,6 +169,72 @@ machine_at_quadt386sx_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t pbl300sx_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios",
|
||||
.description = "BIOS Version",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "pbl300sx",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.bios = {
|
||||
{ .name = "1991", .internal_name = "pbl300sx_1991", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/V1.10_1113_910723.bin", "" } },
|
||||
{ .name = "1992", .internal_name = "pbl300sx", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/pb_l300sx_1992.bin", "" } },
|
||||
{ .files_no = 0 }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t pbl300sx_device = {
|
||||
.name = "Packard Bell Legend 300SX",
|
||||
.internal_name = "pbl300sx_device",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = pbl300sx_config
|
||||
};
|
||||
|
||||
int
|
||||
machine_at_pbl300sx_init(const machine_t *model)
|
||||
{
|
||||
int ret = 0;
|
||||
const char* fn;
|
||||
|
||||
/* No ROMs available */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&acc2036_device);
|
||||
|
||||
device_add(&keyboard_ps2_phoenix_device);
|
||||
device_add(&um82c862f_ide_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_neat_init(const machine_t *model)
|
||||
{
|
||||
@@ -292,6 +358,22 @@ machine_at_dells200_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_at122_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/at122/FINAL.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_ctat_common_init(model);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_tuliptc7_init(const machine_t *model)
|
||||
{
|
||||
@@ -447,6 +529,28 @@ machine_at_gw286ct_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_drsm35286_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/drsm35286/syab04-665821fb81363428830424.bin",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
device_add(&fdc37c651_ide_device);
|
||||
|
||||
machine_at_scat_init(model, 1, 0);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_senor_scat286_init(const machine_t *model)
|
||||
{
|
||||
@@ -776,7 +880,7 @@ machine_at_cmdsl386sx25_init(const machine_t *model)
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
device_add(&ali5105_device); /* The FDC is part of the ALi M5105. */
|
||||
device_add_params(&pc87310_device, (void *) (PC87310_ALI));
|
||||
device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */
|
||||
|
||||
device_add(&vlsi_scamp_device);
|
||||
@@ -926,7 +1030,7 @@ machine_at_acer100t_init(const machine_t *model)
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(&oti077_acer100t_device);
|
||||
|
||||
device_add(&ali5105_device);
|
||||
device_add_params(&pc87310_device, (void *) (PC87310_ALI));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ machine_at_acera1g_init(const machine_t *model)
|
||||
|
||||
device_add(&keyboard_ps2_acer_pci_device);
|
||||
|
||||
device_add(&ali5105_device);
|
||||
device_add_params(&pc87310_device, (void *) (PC87310_ALI));
|
||||
device_add(&ide_ali5213_device);
|
||||
|
||||
return ret;
|
||||
@@ -682,7 +682,7 @@ machine_at_opti495_init(const machine_t *model)
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti495_device);
|
||||
device_add(&opti495slc_device);
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
|
||||
@@ -697,7 +697,7 @@ machine_at_opti495_ami_common_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti495_device);
|
||||
device_add(&opti495sx_device);
|
||||
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
@@ -737,6 +737,32 @@ machine_at_opti495_mr_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_c747_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/c747/486-C747 Tandon.BIN",
|
||||
0x000f0000, 65536, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
/* The EFAR chipset is a rebrand of the OPTi 495SX. */
|
||||
device_add(&opti495sx_device);
|
||||
|
||||
/*
|
||||
No idea what KBC it actually has but this produces the
|
||||
desired behavior: command A9 does absolutely nothing.
|
||||
*/
|
||||
device_add(&keyboard_at_siemens_device);
|
||||
device_add(&um82c862f_ide_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_exp4349_init(const machine_t *model)
|
||||
{
|
||||
@@ -822,6 +848,7 @@ machine_at_403tg_d_mr_init(const machine_t *model)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t pb450_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
@@ -974,7 +1001,8 @@ machine_at_mvi486_init(const machine_t *model)
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti495_device);
|
||||
device_add(&opti498_device);
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&pc87311_ide_device);
|
||||
|
||||
@@ -1009,6 +1037,31 @@ machine_at_ami471_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_advantage40xxd_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/advantage40xxd/AST101.09A",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
device_add(&sis_85c471_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
device_add(&keyboard_ps2_phoenix_device);
|
||||
device_add(&um82c863f_ide_device);
|
||||
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_vli486sv2g_init(const machine_t *model)
|
||||
{
|
||||
@@ -2816,6 +2869,32 @@ machine_at_ga486l_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_cobalt_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/cobalt/Cobalt_2.3.BIN",
|
||||
0x000e0000, 131072, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&opti499_device);
|
||||
device_add(&ide_opti611_vlb_device);
|
||||
device_add(&ide_isa_sec_device);
|
||||
device_add(&fdc37c665_device);
|
||||
|
||||
device_add(&keyboard_ps2_ami_device);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_at_cougar_init(const machine_t *model)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,79 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/machine.h>
|
||||
|
||||
int
|
||||
machine_at_v12p_init(const machine_t *model)
|
||||
|
||||
{
|
||||
int ret = 0;
|
||||
const char* fn;
|
||||
|
||||
/* No ROMs available */
|
||||
if (!device_available(model->device))
|
||||
return ret;
|
||||
|
||||
device_context(model->device);
|
||||
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios_versions"), 0);
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SCSI, 1, 4, 3, 2);
|
||||
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 2, 1, 4, 3);
|
||||
pci_register_slot(0x03, PCI_CARD_NORMAL, 3, 2, 1, 4);
|
||||
pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 0, 0, 0);
|
||||
pci_register_slot(0x05, PCI_CARD_NORMAL, 0, 0, 0, 0);
|
||||
device_add(&i430lx_device);
|
||||
device_add(&keyboard_ps2_acer_pci_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add_params(&pc87310_device, (void *) (PC87310_ALI));
|
||||
device_add(&amd_am28f010_flash_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const device_config_t v12p_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "bios_versions",
|
||||
.description = "BIOS Versions",
|
||||
.type = CONFIG_BIOS,
|
||||
.default_string = "v12p_14",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.bios = {
|
||||
{ .name = "Core Version 1.2 Version R1.4", .internal_name = "v12p_14", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/v12p/v12p_14.bin", "" } },
|
||||
{ .name = "Core Version 1.2 Version R1.6", .internal_name = "v12p_16", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/v12p/v12p_16.bin", "" } },
|
||||
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
|
||||
const device_t v12p_device = {
|
||||
.name = "Acer V12P",
|
||||
.internal_name = "v12p",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &v12p_config[0]
|
||||
};
|
||||
|
||||
void
|
||||
machine_at_premiere_common_init(const machine_t *model, int pci_switch)
|
||||
{
|
||||
|
||||
@@ -96,21 +96,21 @@ machine_at_d842_init(const machine_t *model)
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
machine_at_common_init(model);
|
||||
machine_at_common_init(model);
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x03, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); /* Slot 01 */
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); /* Slot 02 */
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x03, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Onboard */
|
||||
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); /* Slot 01 */
|
||||
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); /* Slot 02 */
|
||||
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&i430nx_device);
|
||||
device_add(&sio_zb_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -127,18 +127,17 @@ static const device_config_t d842_config[] = {
|
||||
.spinner = { 0 }, /*W1*/
|
||||
.bios = {
|
||||
{ .name = "Version 1.03 Revision 1.03.842 (11/24/1994)", .internal_name = "d842", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842.bin", "" } },
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842.BIN", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.05.842 (03/15/1996)", .internal_name = "d842_mar96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_mar96.bin", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.06.842 (04/03/1998)", .internal_name = "d842_apr98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_apr98.bin", "" } },
|
||||
{ .name = "Version 4.04 Revision 1.07.842 (06/02/1998)", .internal_name = "d842_jun98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98.bin", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.09.842 (07/08/1996)", .internal_name = "d842_jul96", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Version 4.04 Revision 1.07.842 (06/02/1998)", .internal_name = "d842_jun98", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98.BIN", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.09.842 (07/08/1996)", .internal_name = "d842_jul96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jul96.bin", "" } },
|
||||
{ .name = "Version 1.03 Revision 1.10.842 (06/04/1998)", .internal_name = "d842_jun98_1", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98_1.bin", "" } },
|
||||
|
||||
{ .name = "Version 1.03 Revision 1.10.842 (06/04/1998)", .internal_name = "d842_jun98_1", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98_1.bin", "" } },
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
@@ -155,7 +154,7 @@ const device_t d842_device = {
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &d842_config[0]
|
||||
|
||||
@@ -628,25 +628,24 @@ machine_at_d943_init(const machine_t *model)
|
||||
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
|
||||
device_context_restore();
|
||||
|
||||
machine_at_common_init_ex(model, 2);
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
machine_at_common_init_ex(model, 2);
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
|
||||
pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0);
|
||||
pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1);
|
||||
pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4);
|
||||
pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4);
|
||||
device_add(&i430hx_device);
|
||||
device_add(&piix3_device);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
device_add(&fdc37c665_device);
|
||||
device_add(&intel_flash_bxt_device);
|
||||
spd_register(SPD_TYPE_EDO, 0x7, 256);
|
||||
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
spd_register(SPD_TYPE_EDO, 0x7, 256);
|
||||
|
||||
if (gfxcard[0] == VID_INTERNAL)
|
||||
device_add(machine_get_vid_device(machine));
|
||||
|
||||
if (sound_card_current[0] == SOUND_INTERNAL)
|
||||
@@ -670,11 +669,10 @@ static const device_config_t d943_config[] = {
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct96.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.03.943 (12/12/1996)", .internal_name = "d943_dec96", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_dec96.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.05.943 (09/04/1997)", .internal_name = "d943_sept97", .bios_type = BIOS_NORMAL,
|
||||
{ .name = "Version 4.05 Revision 1.05.943 (09/04/1997)", .internal_name = "d943_sept97", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_sept97.bin", "" } },
|
||||
{ .name = "Version 4.05 Revision 1.06.943 (10/29/1997)", .internal_name = "d943_oct97", .bios_type = BIOS_NORMAL,
|
||||
.files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct97.bin", "" } },
|
||||
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
@@ -691,7 +689,7 @@ const device_t d943_device = {
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = &d943_config[0]
|
||||
|
||||
@@ -782,9 +782,11 @@ static const device_config_t pcjr_config[] = {
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "RGB", .value = PCJR_RGB },
|
||||
{ .description = "Composite", .value = PCJR_COMPOSITE },
|
||||
{ .description = "" }
|
||||
{ .description = "RGB", .value = PCJR_RGB },
|
||||
{ .description = "Composite", .value = PCJR_COMPOSITE },
|
||||
{ .description = "RGB (no brown)", .value = PCJR_RGB_NO_BROWN },
|
||||
{ .description = "RGB (IBM 5153)", .value = PCJR_RGB_IBM_5153 },
|
||||
{ .description = "" }
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/port_6x.h>
|
||||
#include <86box/video.h>
|
||||
@@ -668,6 +669,34 @@ machine_xt_amixt_init(const machine_t *model)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_xt_tuliptc8_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/tuliptc8/tulip-bios_xt_compact_2.bin",
|
||||
0x000fc000, 16384, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
device_add(&keyboard_xt_fe2010_device);
|
||||
|
||||
if (fdc_current[0] == FDC_INTERNAL)
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
machine_common_init(model);
|
||||
|
||||
pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt);
|
||||
|
||||
nmi_init();
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
device_add(&amstrad_megapc_nvr_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions)
|
||||
// RTC
|
||||
|
||||
@@ -71,6 +71,8 @@ extern const device_t d842_device;
|
||||
extern const device_t d943_device;
|
||||
extern const device_t dells333sl_device;
|
||||
extern const device_t hot433a_device;
|
||||
extern const device_t pbl300sx_device;
|
||||
extern const device_t v12p_device;
|
||||
|
||||
const machine_filter_t machine_types[] = {
|
||||
{ "None", MACHINE_TYPE_NONE },
|
||||
@@ -107,6 +109,7 @@ const machine_filter_t machine_chipsets[] = {
|
||||
{ "Headland GC100A", MACHINE_CHIPSET_GC100A },
|
||||
{ "Headland GC103", MACHINE_CHIPSET_GC103 },
|
||||
{ "Headland HT18", MACHINE_CHIPSET_HT18 },
|
||||
{ "ACC 2036", MACHINE_CHIPSET_ACC_2036 },
|
||||
{ "ACC 2168", MACHINE_CHIPSET_ACC_2168 },
|
||||
{ "ALi M1217", MACHINE_CHIPSET_ALI_M1217 },
|
||||
{ "ALi M6117", MACHINE_CHIPSET_ALI_M6117 },
|
||||
@@ -150,7 +153,9 @@ const machine_filter_t machine_chipsets[] = {
|
||||
{ "OPTi 391", MACHINE_CHIPSET_OPTI_391 },
|
||||
{ "OPTi 481", MACHINE_CHIPSET_OPTI_481 },
|
||||
{ "OPTi 493", MACHINE_CHIPSET_OPTI_493 },
|
||||
{ "OPTi 495", MACHINE_CHIPSET_OPTI_495 },
|
||||
{ "OPTi 495SLC", MACHINE_CHIPSET_OPTI_495SLC },
|
||||
{ "OPTi 495SX", MACHINE_CHIPSET_OPTI_495SX },
|
||||
{ "OPTi 498", MACHINE_CHIPSET_OPTI_498 },
|
||||
{ "OPTi 499", MACHINE_CHIPSET_OPTI_499 },
|
||||
{ "OPTi 895/802G", MACHINE_CHIPSET_OPTI_895_802G },
|
||||
{ "OPTi 547/597", MACHINE_CHIPSET_OPTI_547_597 },
|
||||
@@ -2026,6 +2031,45 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
{
|
||||
.name = "[V20] Tulip PC Compact 2",
|
||||
.internal_name = "tuliptc8",
|
||||
.type = MACHINE_TYPE_8088,
|
||||
.chipset = MACHINE_CHIPSET_DISCRETE,
|
||||
.init = machine_xt_tuliptc8_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_8088,
|
||||
.block = CPU_BLOCK(CPU_8088),
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PC,
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 64,
|
||||
.max = 640,
|
||||
.step = 64
|
||||
},
|
||||
.nvrmask = 63,
|
||||
.kbc_device = &keyboard_xtclone_device,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
|
||||
/* 8086 Machines */
|
||||
{
|
||||
@@ -3098,7 +3142,7 @@ const machine_t machines[] = {
|
||||
},
|
||||
/* Has Olivetti KBC firmware. */
|
||||
{
|
||||
.name = "[ISA] Olivetti M290",
|
||||
.name = "[ISA] Olivetti M290/AT&T 6286 WGS",
|
||||
.internal_name = "m290",
|
||||
.type = MACHINE_TYPE_286,
|
||||
.chipset = MACHINE_CHIPSET_PROPRIETARY,
|
||||
@@ -3120,7 +3164,7 @@ const machine_t machines[] = {
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 640,
|
||||
.min = 1024,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
},
|
||||
@@ -3417,6 +3461,47 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC
|
||||
firmware. */
|
||||
{
|
||||
.name = "[C&T PC/AT] PC's Limited (Dell) 28608L/AT122",
|
||||
.internal_name = "at122",
|
||||
.type = MACHINE_TYPE_286,
|
||||
.chipset = MACHINE_CHIPSET_CT_AT,
|
||||
.init = machine_at_at122_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_286,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 6000000,
|
||||
.max_bus = 12000000,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 640,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC
|
||||
firmware. */
|
||||
{
|
||||
@@ -3897,6 +3982,45 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
{
|
||||
.name = "[SCAT] ICL DRS M35/286",
|
||||
.internal_name = "drsm35286",
|
||||
.type = MACHINE_TYPE_286,
|
||||
.chipset = MACHINE_CHIPSET_SCAT,
|
||||
.init = machine_at_drsm35286_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_286,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2,
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO,
|
||||
.ram = {
|
||||
.min = 512,
|
||||
.max = 5120,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &gd5401_onboard_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has IBM PS/2 Type 1 KBC firmware. */
|
||||
{
|
||||
.name = "[SCAT] Samsung SPC-4200P",
|
||||
@@ -4301,6 +4425,46 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Most likely has Phonenix KBC firmware. */
|
||||
{
|
||||
.name = "[ACC 2036] Packard Bell Legend 300SX",
|
||||
.internal_name = "pbl300sx",
|
||||
.type = MACHINE_TYPE_386SX,
|
||||
.chipset = MACHINE_CHIPSET_ACC_2036,
|
||||
.init = machine_at_pbl300sx_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_386SX,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2,
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 16384,
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = &pbl300sx_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &oti037_pbl300sx_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* This has an AMIKey-2, which is an updated version of type 'H'. */
|
||||
{
|
||||
.name = "[ALi M1217] Acrosser AR-B1374",
|
||||
@@ -5717,10 +5881,10 @@ const machine_t machines[] = {
|
||||
but the BIOS sends commands C9 without a parameter and D5, both of which are
|
||||
Phoenix MultiKey commands. */
|
||||
{
|
||||
.name = "[OPTi 495] U-Board OPTi 495SLC",
|
||||
.name = "[OPTi 495SLC] U-Board OPTi 495SLC",
|
||||
.internal_name = "award495",
|
||||
.type = MACHINE_TYPE_386DX,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SLC,
|
||||
.init = machine_at_opti495_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -5959,12 +6123,52 @@ const machine_t machines[] = {
|
||||
},
|
||||
|
||||
/* 386DX/486 machines */
|
||||
/* Has AMIKey F KBC firmware. The EFAR chipst is a rebrand of OPTi 495SX. */
|
||||
{
|
||||
.name = "[OPTi 495SX] CAF Technology C747",
|
||||
.internal_name = "c747",
|
||||
.type = MACHINE_TYPE_386DX_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SX,
|
||||
.init = machine_at_c747_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_386DX | CPU_PKG_SOCKET1,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_AT,
|
||||
.flags = MACHINE_APM | MACHINE_IDE,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 32768,
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMIKey F KBC firmware. */
|
||||
{
|
||||
.name = "[OPTi 495] DataExpert SX495",
|
||||
.name = "[OPTi 495SX] DataExpert SX495",
|
||||
.internal_name = "ami495",
|
||||
.type = MACHINE_TYPE_386DX_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SX,
|
||||
.init = machine_at_opti495_ami_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -6001,10 +6205,10 @@ const machine_t machines[] = {
|
||||
},
|
||||
/* Has AMIKey F KBC firmware (it's just the MR BIOS for the above machine). */
|
||||
{
|
||||
.name = "[OPTi 495] DataExpert SX495 (MR BIOS)",
|
||||
.name = "[OPTi 495SX] DataExpert SX495 (MR BIOS)",
|
||||
.internal_name = "mr495",
|
||||
.type = MACHINE_TYPE_386DX_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495SX,
|
||||
.init = machine_at_opti495_mr_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -6326,10 +6530,10 @@ const machine_t machines[] = {
|
||||
/* Uses some variant of Phoenix MultiKey/42 as the Intel 8242 chip has a Phoenix
|
||||
copyright. */
|
||||
{
|
||||
.name = "[OPTi 495] Mylex MVI486",
|
||||
.name = "[OPTi 498] Mylex MVI486",
|
||||
.internal_name = "mvi486",
|
||||
.type = MACHINE_TYPE_486,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_495,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_498,
|
||||
.init = machine_at_mvi486_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
@@ -6485,6 +6689,46 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has Phoenix KBC firmware. */
|
||||
{
|
||||
.name = "[SiS 471] AST Advantage! 40xxd",
|
||||
.internal_name = "advantage40xxd",
|
||||
.type = MACHINE_TYPE_486,
|
||||
.chipset = MACHINE_CHIPSET_SIS_471,
|
||||
.init = machine_at_advantage40xxd_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET1,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 2
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_VLB,
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 4096,
|
||||
.max = 36864,
|
||||
.step = 4096
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &gd5424_onboard_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMIKey F KBC firmware. */
|
||||
{
|
||||
.name = "[Symphony SL42C460] DTK PKM-0031Y",
|
||||
@@ -6975,6 +7219,45 @@ const machine_t machines[] = {
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
{
|
||||
.name = "[OPTi 499] Alaris Cobalt LPX",
|
||||
.internal_name = "cobalt",
|
||||
.type = MACHINE_TYPE_486_S2,
|
||||
.chipset = MACHINE_CHIPSET_OPTI_499,
|
||||
.init = machine_at_cobalt_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET3 | CPU_PKG_486BL,
|
||||
.block = CPU_BLOCK(CPU_P24T),
|
||||
.min_bus = 0,
|
||||
.max_bus = 0,
|
||||
.min_voltage = 0,
|
||||
.max_voltage = 0,
|
||||
.min_multi = 0,
|
||||
.max_multi = 0
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_VLB,
|
||||
.flags = MACHINE_APM | MACHINE_VIDEO | MACHINE_IDE_DUAL,
|
||||
.ram = {
|
||||
.min = 1024,
|
||||
.max = 65536,
|
||||
.step = 1024
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = NULL,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = &gd5428_vlb_onboard_device,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMIKey-2 'H' KBC firmware. */
|
||||
{
|
||||
.name = "[OPTi 499] Alaris COUGAR 486BL",
|
||||
@@ -9775,6 +10058,45 @@ const machine_t machines[] = {
|
||||
|
||||
/* Socket 4 machines */
|
||||
/* 430LX */
|
||||
{
|
||||
.name = "[i430LX] Acer V12P",
|
||||
.internal_name = "v12p",
|
||||
.type = MACHINE_TYPE_SOCKET4,
|
||||
.chipset = MACHINE_CHIPSET_INTEL_430LX,
|
||||
.init = machine_at_v12p_init,
|
||||
.p1_handler = NULL,
|
||||
.gpio_handler = NULL,
|
||||
.available_flag = MACHINE_AVAILABLE,
|
||||
.gpio_acpi_handler = NULL,
|
||||
.cpu = {
|
||||
.package = CPU_PKG_SOCKET4,
|
||||
.block = CPU_BLOCK_NONE,
|
||||
.min_bus = 60000000,
|
||||
.max_bus = 66666667,
|
||||
.min_voltage = 5000,
|
||||
.max_voltage = 5000,
|
||||
.min_multi = MACHINE_MULTIPLIER_FIXED,
|
||||
.max_multi = MACHINE_MULTIPLIER_FIXED
|
||||
},
|
||||
.bus_flags = MACHINE_PS2_PCI,
|
||||
.flags = MACHINE_IDE | MACHINE_APM,
|
||||
.ram = {
|
||||
.min = 2048,
|
||||
.max = 196608,
|
||||
.step = 2048
|
||||
},
|
||||
.nvrmask = 127,
|
||||
.kbc_device = NULL,
|
||||
.kbc_p1 = 0xff,
|
||||
.gpio = 0xffffffff,
|
||||
.gpio_acpi = 0xffffffff,
|
||||
.device = &v12p_device,
|
||||
.fdc_device = NULL,
|
||||
.sio_device = NULL,
|
||||
.vid_device = NULL,
|
||||
.snd_device = NULL,
|
||||
.net_device = NULL
|
||||
},
|
||||
/* Has AMIKey H KBC firmware (AMIKey-2), per POST screen with BIOS string
|
||||
shown in the manual. Has PS/2 mouse support with serial-style (DB9)
|
||||
connector.
|
||||
@@ -11968,7 +12290,7 @@ const machine_t machines[] = {
|
||||
.ram = {
|
||||
.min = 8192,
|
||||
.max = 131072,
|
||||
.step = 8192
|
||||
.step = 4096
|
||||
},
|
||||
.nvrmask = 511,
|
||||
.kbc_device = NULL,
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
|
||||
#define FLAG_WORD 4
|
||||
#define FLAG_BXB 2
|
||||
@@ -44,21 +45,22 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
CMD_SET_READ = 0x00,
|
||||
CMD_READ_SIGNATURE = 0x90,
|
||||
CMD_ERASE = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0x20,
|
||||
CMD_ERASE_VERIFY = 0xA0,
|
||||
CMD_PROGRAM = 0x40,
|
||||
CMD_PROGRAM_VERIFY = 0xC0,
|
||||
CMD_RESET = 0xFF
|
||||
CMD_SET_READ = 0x00,
|
||||
CMD_READ_AUTO_SELECT = 0x80,
|
||||
CMD_READ_SIGNATURE = 0x90,
|
||||
CMD_ERASE = 0x20,
|
||||
CMD_ERASE_CONFIRM = 0x20,
|
||||
CMD_ERASE_VERIFY = 0xA0,
|
||||
CMD_PROGRAM = 0x40,
|
||||
CMD_PROGRAM_VERIFY = 0xC0,
|
||||
CMD_RESET = 0xFF
|
||||
};
|
||||
|
||||
typedef struct flash_t {
|
||||
uint8_t command;
|
||||
uint8_t is_amd;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
uint8_t *array;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
@@ -83,11 +85,22 @@ flash_read(uint32_t addr, void *priv)
|
||||
ret = dev->array[addr];
|
||||
break;
|
||||
|
||||
case CMD_READ_AUTO_SELECT:
|
||||
if (!dev->is_amd)
|
||||
break;
|
||||
fallthrough;
|
||||
case CMD_READ_SIGNATURE:
|
||||
if (addr == 0x00000)
|
||||
ret = 0x31; /* CATALYST */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xB4; /* 28F010 */
|
||||
if (dev->is_amd) {
|
||||
if (addr == 0x00000)
|
||||
ret = 0x01; /* AMD */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xa7; /* Am28F010 */
|
||||
} else {
|
||||
if (addr == 0x00000)
|
||||
ret = 0x31; /* CATALYST */
|
||||
else if (addr == 0x00001)
|
||||
ret = 0xb4; /* 28F010 */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -205,6 +218,7 @@ catalyst_flash_init(UNUSED(const device_t *info))
|
||||
catalyst_flash_add_mappings(dev);
|
||||
|
||||
dev->command = CMD_RESET;
|
||||
dev->is_amd = info->local;
|
||||
|
||||
fp = nvr_fopen(flash_path, "rb");
|
||||
if (fp) {
|
||||
@@ -244,3 +258,17 @@ const device_t catalyst_flash_device = {
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t amd_am28f010_flash_device = {
|
||||
.name = "AMD Am28F010-D Flash BIOS",
|
||||
.internal_name = "amd_am28f010_flash",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = catalyst_flash_init,
|
||||
.close = catalyst_flash_close,
|
||||
.reset = catalyst_flash_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -67,7 +67,9 @@ mem_mapping_t bios_mapping;
|
||||
mem_mapping_t bios_high_mapping;
|
||||
|
||||
page_t *pages; /* RAM page table */
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
page_t **page_lookup; /* pagetable lookup */
|
||||
#endif
|
||||
uint32_t pages_sz; /* #pages in table */
|
||||
|
||||
uint8_t *ram; /* the virtual RAM */
|
||||
@@ -85,12 +87,23 @@ uint8_t *pccache2;
|
||||
|
||||
int readlnext;
|
||||
int readlookup[256];
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
uintptr_t *readlookup2;
|
||||
#endif
|
||||
uintptr_t old_rl2;
|
||||
uint8_t uncached = 0;
|
||||
int writelnext;
|
||||
int writelookup[256];
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
uintptr_t *writelookup2;
|
||||
#endif
|
||||
|
||||
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
|
||||
/* The lookup tables. */
|
||||
page_t *page_lookup[1048576] = { 0 };
|
||||
uintptr_t readlookup2[1048576] = { 0 };
|
||||
uintptr_t writelookup2[1048576] = { 0 };
|
||||
#endif
|
||||
|
||||
uint32_t mem_logical_addr;
|
||||
|
||||
@@ -2987,12 +3000,25 @@ mem_init(void)
|
||||
ram2 = NULL;
|
||||
pages = NULL;
|
||||
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
/* Allocate the lookup tables. */
|
||||
page_lookup = (page_t **) malloc((1 << 20) * sizeof(page_t *));
|
||||
readlookup2 = malloc((1 << 20) * sizeof(uintptr_t));
|
||||
writelookup2 = malloc((1 << 20) * sizeof(uintptr_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
void
|
||||
mem_free(void)
|
||||
{
|
||||
free(page_lookup);
|
||||
free(readlookup2);
|
||||
free(writelookup2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
umc_page_recalc(uint32_t c, uint32_t phys, int set)
|
||||
{
|
||||
|
||||
@@ -70,5 +70,14 @@ if (UNIX)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if (UNIX AND NOT APPLE) # Support for TAP on Linux and BSD, supposedly.
|
||||
find_path(HAS_TAP "linux/if_tun.h" PATHS ${TAP_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" )
|
||||
if(HAS_TAP)
|
||||
add_compile_definitions(HAS_TAP)
|
||||
list(APPEND net_sources net_tap.c)
|
||||
else()
|
||||
message(WARNING "TAP support not available. Are you on some BSD?")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(net OBJECT ${net_sources})
|
||||
|
||||
@@ -488,15 +488,18 @@ plip_close(void *priv)
|
||||
}
|
||||
|
||||
const lpt_device_t lpt_plip_device = {
|
||||
.name = "Parallel Line Internet Protocol",
|
||||
.internal_name = "plip",
|
||||
.init = plip_lpt_init,
|
||||
.close = plip_close,
|
||||
.write_data = plip_write_data,
|
||||
.write_ctrl = plip_write_ctrl,
|
||||
.read_data = NULL,
|
||||
.read_status = plip_read_status,
|
||||
.read_ctrl = NULL
|
||||
.name = "Parallel Line Internet Protocol",
|
||||
.internal_name = "plip",
|
||||
.init = plip_lpt_init,
|
||||
.close = plip_close,
|
||||
.write_data = plip_write_data,
|
||||
.write_ctrl = plip_write_ctrl,
|
||||
.autofeed = NULL,
|
||||
.strobe = NULL,
|
||||
.read_status = plip_read_status,
|
||||
.read_ctrl = NULL,
|
||||
.epp_write_data = NULL,
|
||||
.epp_request_read = NULL
|
||||
};
|
||||
|
||||
const device_t plip_device = {
|
||||
|
||||
353
src/network/net_tap.c
Normal file
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Linux TAP network interface for 86box.
|
||||
*
|
||||
* This file was created by looking at the VDE network backend
|
||||
* as a reference, credit to jguillaumes.
|
||||
*
|
||||
* Authors: Doug Johnson <dougvj@gmail.com>
|
||||
*
|
||||
*
|
||||
* Copyright 2023 Doug Johnson
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with
|
||||
* or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the entire
|
||||
* above notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names
|
||||
* of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# error TAP networking is only supported on Linux
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <stdbool.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/sockios.h>
|
||||
|
||||
#define HAVE_STDARG_H
|
||||
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_dynld.h>
|
||||
#include <86box/thread.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/network.h>
|
||||
#include <86box/net_event.h>
|
||||
|
||||
typedef struct net_tap_t {
|
||||
int fd; // tap device file descriptor
|
||||
netcard_t *card;
|
||||
thread_t *poll_tid;
|
||||
net_evt_t tx_event;
|
||||
net_evt_t stop_event;
|
||||
netpkt_t pkt_rx;
|
||||
netpkt_t pkts_tx[NET_QUEUE_LEN];
|
||||
} net_tap_t;
|
||||
|
||||
#ifdef ENABLE_TAP_LOG
|
||||
int tap_do_log = ENABLE_TAP_LOG;
|
||||
|
||||
|
||||
static void tap_logv(const char *fmt, va_list ap)
|
||||
{
|
||||
if (tap_do_log) {
|
||||
pclog_ex(fmt, ap);
|
||||
}
|
||||
}
|
||||
|
||||
static void tap_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (tap_do_log) {
|
||||
va_start(ap, fmt);
|
||||
tap_logv(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#else
|
||||
# define tap_log(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
# define tap_logv(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static void net_tap_thread(void *priv) {
|
||||
enum {
|
||||
NET_EVENT_STOP = 0,
|
||||
NET_EVENT_TX,
|
||||
NET_EVENT_RX,
|
||||
NET_EVENT_TAP,
|
||||
NET_EVENT_MAX,
|
||||
};
|
||||
net_tap_t *tap = priv;
|
||||
tap_log("TAP: poll thread started.\n");
|
||||
struct pollfd pfd[NET_EVENT_MAX];
|
||||
pfd[NET_EVENT_STOP].fd = net_event_get_fd(&tap->stop_event);
|
||||
pfd[NET_EVENT_STOP].events = POLLIN | POLLPRI;
|
||||
|
||||
pfd[NET_EVENT_TX].fd = net_event_get_fd(&tap->tx_event);
|
||||
pfd[NET_EVENT_TX].events = POLLIN | POLLPRI;
|
||||
|
||||
pfd[NET_EVENT_RX].fd = tap->fd;
|
||||
pfd[NET_EVENT_RX].events = POLLIN | POLLPRI;
|
||||
|
||||
pfd[NET_EVENT_TAP].fd = tap->fd;
|
||||
pfd[NET_EVENT_TAP].events = POLLERR | POLLHUP | POLLPRI;
|
||||
fcntl(tap->fd, F_SETFL, O_NONBLOCK);
|
||||
while(1) {
|
||||
ssize_t ret = poll(pfd, NET_EVENT_MAX, -1);
|
||||
if (ret < 0) {
|
||||
tap_log("TAP: poll error: %s\n", strerror(errno));
|
||||
net_event_set(&tap->stop_event);
|
||||
break;
|
||||
}
|
||||
if (pfd[NET_EVENT_TAP].revents) {
|
||||
tap_log("TAP: tap close/error event received.\n");
|
||||
net_event_set(&tap->stop_event);
|
||||
}
|
||||
if (pfd[NET_EVENT_TX].revents & POLLIN) {
|
||||
net_event_clear(&tap->tx_event);
|
||||
int packets = network_tx_popv(tap->card, tap->pkts_tx,
|
||||
NET_QUEUE_LEN);
|
||||
for(int i = 0; i < packets; i++) {
|
||||
netpkt_t *pkt = &tap->pkts_tx[i];
|
||||
ssize_t ret = write(tap->fd, pkt->data, pkt->len);
|
||||
if (ret < 0) {
|
||||
tap_log("TAP: write error: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pfd[NET_EVENT_RX].revents & POLLIN) {
|
||||
ssize_t len = read(tap->fd, tap->pkt_rx.data, NET_MAX_FRAME);
|
||||
if (len < 0) {
|
||||
tap_log("TAP: read error: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
tap->pkt_rx.len = len;
|
||||
network_rx_put_pkt(tap->card, &tap->pkt_rx);
|
||||
}
|
||||
if (pfd[NET_EVENT_STOP].revents & POLLIN) {
|
||||
net_event_clear(&tap->stop_event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void net_tap_close(void *priv)
|
||||
{
|
||||
if (!priv) {
|
||||
return;
|
||||
}
|
||||
net_tap_t *tap = priv;
|
||||
tap_log("TAP: closing.\n");
|
||||
net_event_set(&tap->stop_event);
|
||||
tap_log("TAP: waiting for poll thread to exit.\n");
|
||||
thread_wait(tap->poll_tid);
|
||||
tap_log("TAP: poll thread exited.\n");
|
||||
for(int i = 0; i < NET_QUEUE_LEN; i++) {
|
||||
free(tap->pkts_tx[i].data);
|
||||
}
|
||||
free(tap->pkt_rx.data);
|
||||
if (tap->fd >= 0) {
|
||||
close(tap->fd);
|
||||
}
|
||||
free(tap);
|
||||
}
|
||||
|
||||
void net_tap_error(char *errbuf, const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(errbuf, NET_DRV_ERRBUF_SIZE, format, ap);
|
||||
tap_log("TAP: %s", errbuf);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Error handling macro for the many ioctl calls we use in net_tap_alloc
|
||||
#define ioctl_or_fail(fd, request, argp) \
|
||||
do { \
|
||||
if ((err = ioctl(fd, request, argp)) < 0) { \
|
||||
tap_log("TAP: ioctl " #request " error: %s\n", strerror(errno)); \
|
||||
goto fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// Returns -ERRNO so we can get an idea what's wrong
|
||||
int net_tap_alloc(const uint8_t *mac_addr, const char* bridge_dev)
|
||||
{
|
||||
int fd;
|
||||
struct ifreq ifr = {0};
|
||||
if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
|
||||
tap_log("TAP: open error: %s\n", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
int err;
|
||||
if ((err = ioctl(fd, TUNSETIFF, &ifr)) < 0) {
|
||||
tap_log("TAP: ioctl TUNSETIFF error: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
// Create a socket for ioctl operations
|
||||
int sock;
|
||||
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
tap_log("TAP: socket error: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
// Bring the interface up
|
||||
tap_log("TAP: Bringing interface '%s' up.\n", ifr.ifr_name);
|
||||
ifr.ifr_flags = IFF_UP;
|
||||
ioctl_or_fail(sock, SIOCSIFFLAGS, &ifr);
|
||||
// Add interface to bridge, if specified
|
||||
if (bridge_dev && bridge_dev[0] != '\0') {
|
||||
// First see if the bridge exists
|
||||
struct ifreq ifr_bridge;
|
||||
//NOTE strncpy does not null terminate if the string is too long, I use
|
||||
// snprintf or strlcpy instead
|
||||
//strncpy(ifr_bridge.ifr_name, bridge_dev, IFNAMSIZ);
|
||||
snprintf(ifr_bridge.ifr_name, IFNAMSIZ, "%s", bridge_dev);
|
||||
if ((err = ioctl(sock, SIOCGIFINDEX, &ifr_bridge)) < 0) {
|
||||
if (errno != ENODEV) {
|
||||
tap_log("TAP: ioctl SIOCGIFINDEX error: %s\n", strerror(errno));
|
||||
goto fail;
|
||||
} else {
|
||||
// Create the bridge
|
||||
ioctl_or_fail(sock, SIOCBRADDBR, &ifr_bridge);
|
||||
// Set the bridge up
|
||||
ifr_bridge.ifr_flags = IFF_UP;
|
||||
ioctl_or_fail(sock, SIOCSIFFLAGS, &ifr_bridge);
|
||||
}
|
||||
}
|
||||
// Get TAP index
|
||||
ioctl_or_fail(sock, SIOCGIFINDEX, &ifr);
|
||||
// Add the tap device to the bridge
|
||||
ifr_bridge.ifr_ifindex = ifr.ifr_ifindex;
|
||||
ioctl_or_fail(sock, SIOCBRADDIF, &ifr_bridge);
|
||||
}
|
||||
// close the socket we used for ioctl operations
|
||||
close(sock);
|
||||
tap_log("Allocated tap device %s\n", ifr.ifr_name);
|
||||
return fd;
|
||||
// cleanup point used by ioctl_or_fail macro
|
||||
fail:
|
||||
close(sock);
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
void net_tap_in_available(void *priv)
|
||||
{
|
||||
net_tap_t *tap = priv;
|
||||
net_event_set(&tap->tx_event);
|
||||
}
|
||||
|
||||
void *
|
||||
net_tap_init(
|
||||
const netcard_t *card,
|
||||
const uint8_t *mac_addr,
|
||||
void *priv,
|
||||
char *netdrv_errbuf)
|
||||
{
|
||||
const char *bridge_dev = (void *) priv;
|
||||
int tap_fd = net_tap_alloc(mac_addr, bridge_dev);
|
||||
if (tap_fd < 0) {
|
||||
if (tap_fd == -EPERM) {
|
||||
net_tap_error(
|
||||
netdrv_errbuf,
|
||||
"No permissions to allocate tap device. "
|
||||
"Try adding NET_CAP_ADMIN,NET_CAP_RAW to 86box ("
|
||||
"sudo setcap 'CAP_NET_RAW,CAP_NET_ADMIN=eip')");
|
||||
} else {
|
||||
net_tap_error(
|
||||
netdrv_errbuf,
|
||||
"Unable to allocate TAP device: %s",
|
||||
strerror(-tap_fd));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (bridge_dev && bridge_dev[0] != '\0') {
|
||||
}
|
||||
net_tap_t *tap = calloc(1, sizeof(net_tap_t));
|
||||
if (!tap) {
|
||||
goto alloc_fail;
|
||||
}
|
||||
tap->pkt_rx.data = calloc(1, NET_MAX_FRAME);
|
||||
if (!tap->pkt_rx.data) {
|
||||
goto alloc_fail;
|
||||
}
|
||||
for(int i = 0; i < NET_QUEUE_LEN; i++) {
|
||||
tap->pkts_tx[i].data = calloc(1, NET_MAX_FRAME);
|
||||
if (!tap->pkts_tx[i].data) {
|
||||
goto alloc_fail;
|
||||
}
|
||||
}
|
||||
tap->fd = tap_fd;
|
||||
tap->card = (netcard_t *) card;
|
||||
net_event_init(&tap->tx_event);
|
||||
net_event_init(&tap->stop_event);
|
||||
tap->poll_tid = thread_create(net_tap_thread, tap);
|
||||
return tap;
|
||||
alloc_fail:
|
||||
net_tap_error(netdrv_errbuf, "Failed to allocate memory");
|
||||
close(tap_fd);
|
||||
free(tap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const netdrv_t net_tap_drv = {
|
||||
&net_tap_in_available,
|
||||
&net_tap_init,
|
||||
&net_tap_close,
|
||||
NULL
|
||||
};
|
||||
@@ -85,36 +85,43 @@ static const NETWORK_CARD net_cards[] = {
|
||||
// clang-format off
|
||||
{ &device_none },
|
||||
{ &device_internal },
|
||||
/* ISA */
|
||||
{ &threec501_device },
|
||||
{ &threec503_device },
|
||||
{ &pcnet_am79c960_device },
|
||||
{ &pcnet_am79c961_device },
|
||||
{ &de220p_device },
|
||||
{ &ne1000_compat_device },
|
||||
{ &ne2000_compat_device },
|
||||
{ &ne2000_compat_8bit_device },
|
||||
{ &ne1000_device },
|
||||
{ &ne2000_device },
|
||||
{ &pcnet_am79c960_eb_device },
|
||||
{ &rtl8019as_pnp_device },
|
||||
{ &wd8003e_device },
|
||||
{ &wd8003eb_device },
|
||||
{ &wd8013ebt_device },
|
||||
/* COM */
|
||||
{ &modem_device },
|
||||
/* LPT */
|
||||
{ &plip_device },
|
||||
/* ISA16 */
|
||||
{ &pcnet_am79c960_device },
|
||||
{ &pcnet_am79c961_device },
|
||||
{ &de220p_device },
|
||||
{ &ne2000_compat_device },
|
||||
{ &ne2000_device },
|
||||
{ &pcnet_am79c960_eb_device },
|
||||
{ &rtl8019as_pnp_device },
|
||||
/* MCA */
|
||||
{ ðernext_mc_device },
|
||||
{ &wd8003eta_device },
|
||||
{ &wd8003ea_device },
|
||||
{ &wd8013epa_device },
|
||||
/* VLB */
|
||||
{ &pcnet_am79c960_vlb_device },
|
||||
/* PCI */
|
||||
{ &pcnet_am79c973_device },
|
||||
{ &pcnet_am79c970a_device },
|
||||
{ &dec_tulip_21140_device },
|
||||
{ &dec_tulip_21040_device },
|
||||
{ &dec_tulip_device },
|
||||
{ &dec_tulip_21140_vpc_device },
|
||||
{ &rtl8029as_device },
|
||||
{ &rtl8139c_plus_device },
|
||||
{ &dec_tulip_21140_device },
|
||||
{ &dec_tulip_21140_vpc_device },
|
||||
{ &dec_tulip_21040_device },
|
||||
{ &pcnet_am79c960_vlb_device },
|
||||
{ &modem_device },
|
||||
{ NULL }
|
||||
// clang-format on
|
||||
};
|
||||
@@ -489,6 +496,12 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin
|
||||
card->host_drv = net_vde_drv;
|
||||
card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name, net_drv_error);
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAS_TAP
|
||||
case NET_TYPE_TAP:
|
||||
card->host_drv = net_tap_drv;
|
||||
card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name, net_drv_error);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
card->host_drv.priv = NULL;
|
||||
|
||||
23
src/nvr.c
@@ -310,18 +310,25 @@ nvr_close(void)
|
||||
void
|
||||
nvr_time_sync(void)
|
||||
{
|
||||
struct tm *tm;
|
||||
time_t now;
|
||||
struct tm tm;
|
||||
time_t now;
|
||||
|
||||
/* Get the current time of day, and convert to local time. */
|
||||
(void) time(&now);
|
||||
if (time_sync & TIME_SYNC_UTC)
|
||||
tm = gmtime(&now);
|
||||
else
|
||||
tm = localtime(&now);
|
||||
|
||||
/* Set the internal clock. */
|
||||
nvr_time_set(tm);
|
||||
#ifdef _WIN32
|
||||
if (time_sync & TIME_SYNC_UTC)
|
||||
gmtime_s(&tm, &now);
|
||||
else
|
||||
localtime_s(&tm, &now);
|
||||
#else
|
||||
if (time_sync & TIME_SYNC_UTC)
|
||||
gmtime_r(&now, &tm);
|
||||
else
|
||||
localtime_r(&now, &tm);
|
||||
#endif
|
||||
|
||||
nvr_time_set(&tm);
|
||||
}
|
||||
|
||||
/* Get current time from internal clock. */
|
||||
|
||||
@@ -1881,6 +1881,39 @@ write_data(uint8_t val, void *priv)
|
||||
dev->data = val;
|
||||
}
|
||||
|
||||
static void
|
||||
autofeed(uint8_t val, void *priv)
|
||||
{
|
||||
escp_t *dev = (escp_t *) priv;
|
||||
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
dev->autofeed = ((val & 0x02) > 0);
|
||||
}
|
||||
|
||||
static void
|
||||
strobe(uint8_t old, uint8_t val, void *priv)
|
||||
{
|
||||
escp_t *dev = (escp_t *) priv;
|
||||
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
/* Data is strobed to the parallel printer on the falling edge of the
|
||||
strobe bit. */
|
||||
if (!(val & 0x01) && (old & 0x01)) {
|
||||
/* Process incoming character. */
|
||||
handle_char(dev, dev->data);
|
||||
|
||||
/* ACK it, will be read on next READ STATUS. */
|
||||
dev->ack = 1;
|
||||
timer_set_delay_u64(&dev->pulse_timer, ISACONST);
|
||||
|
||||
timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_ctrl(uint8_t val, void *priv)
|
||||
{
|
||||
@@ -1919,14 +1952,6 @@ write_ctrl(uint8_t val, void *priv)
|
||||
dev->autofeed = ((val & 0x02) > 0);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
read_data(void *priv)
|
||||
{
|
||||
const escp_t *dev = (escp_t *) priv;
|
||||
|
||||
return dev->data;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
read_ctrl(void *priv)
|
||||
{
|
||||
@@ -2058,13 +2083,16 @@ escp_close(void *priv)
|
||||
}
|
||||
|
||||
const lpt_device_t lpt_prt_escp_device = {
|
||||
.name = "Generic ESC/P Dot-Matrix Printer",
|
||||
.internal_name = "dot_matrix",
|
||||
.init = escp_init,
|
||||
.close = escp_close,
|
||||
.write_data = write_data,
|
||||
.write_ctrl = write_ctrl,
|
||||
.read_data = read_data,
|
||||
.read_status = read_status,
|
||||
.read_ctrl = read_ctrl
|
||||
.name = "Generic ESC/P Dot-Matrix",
|
||||
.internal_name = "dot_matrix",
|
||||
.init = escp_init,
|
||||
.close = escp_close,
|
||||
.write_data = write_data,
|
||||
.write_ctrl = write_ctrl,
|
||||
.autofeed = autofeed,
|
||||
.strobe = strobe,
|
||||
.read_status = read_status,
|
||||
.read_ctrl = read_ctrl,
|
||||
.epp_write_data = NULL,
|
||||
.epp_request_read = NULL
|
||||
};
|
||||
|
||||
@@ -319,6 +319,35 @@ process_data(ps_t *dev)
|
||||
dev->buffer[dev->buffer_pos] = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ps_autofeed(uint8_t val, void *priv)
|
||||
{
|
||||
ps_t *dev = (ps_t *) priv;
|
||||
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
dev->autofeed = val & 0x02 ? true : false;
|
||||
}
|
||||
|
||||
static void
|
||||
ps_strobe(uint8_t old, uint8_t val, void *priv)
|
||||
{
|
||||
ps_t *dev = (ps_t *) priv;
|
||||
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
if (!(val & 0x01) && (old & 0x01)) {
|
||||
process_data(dev);
|
||||
|
||||
dev->ack = true;
|
||||
|
||||
timer_set_delay_u64(&dev->pulse_timer, ISACONST);
|
||||
timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ps_write_ctrl(uint8_t val, void *priv)
|
||||
{
|
||||
@@ -479,27 +508,33 @@ ps_close(void *priv)
|
||||
}
|
||||
|
||||
const lpt_device_t lpt_prt_ps_device = {
|
||||
.name = "Generic PostScript Printer",
|
||||
.internal_name = "postscript",
|
||||
.init = ps_init,
|
||||
.close = ps_close,
|
||||
.write_data = ps_write_data,
|
||||
.write_ctrl = ps_write_ctrl,
|
||||
.read_data = NULL,
|
||||
.read_status = ps_read_status,
|
||||
.read_ctrl = NULL
|
||||
.name = "Generic PostScript Printer",
|
||||
.internal_name = "postscript",
|
||||
.init = ps_init,
|
||||
.close = ps_close,
|
||||
.write_data = ps_write_data,
|
||||
.write_ctrl = ps_write_ctrl,
|
||||
.autofeed = ps_autofeed,
|
||||
.strobe = ps_strobe,
|
||||
.read_status = ps_read_status,
|
||||
.read_ctrl = NULL,
|
||||
.epp_write_data = NULL,
|
||||
.epp_request_read = NULL
|
||||
};
|
||||
|
||||
#ifdef USE_PCL
|
||||
const lpt_device_t lpt_prt_pcl_device = {
|
||||
.name = "Generic PCL5e Printer",
|
||||
.internal_name = "pcl",
|
||||
.init = pcl_init,
|
||||
.close = ps_close,
|
||||
.write_data = ps_write_data,
|
||||
.write_ctrl = ps_write_ctrl,
|
||||
.read_data = NULL,
|
||||
.read_status = ps_read_status,
|
||||
.read_ctrl = NULL
|
||||
.name = "Generic PCL5e Printer",
|
||||
.internal_name = "pcl",
|
||||
.init = pcl_init,
|
||||
.close = ps_close,
|
||||
.write_data = ps_write_data,
|
||||
.write_ctrl = ps_write_ctrl,
|
||||
.autofeed = ps_autofeed,
|
||||
.strobe = ps_strobe,
|
||||
.read_status = ps_read_status,
|
||||
.read_ctrl = NULL,
|
||||
.epp_write_data = NULL,
|
||||
.epp_request_read = NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -367,6 +367,38 @@ write_data(uint8_t val, void *priv)
|
||||
dev->data = val;
|
||||
}
|
||||
|
||||
static void
|
||||
autofeed(uint8_t val, void *priv)
|
||||
{
|
||||
prnt_t *dev = (prnt_t *) priv;
|
||||
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
/* set autofeed value */
|
||||
dev->autofeed = val & 0x02 ? 1 : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
strobe(uint8_t old, uint8_t val, void *priv)
|
||||
{
|
||||
prnt_t *dev = (prnt_t *) priv;
|
||||
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
if (!(val & 0x01) && (old & 0x01)) { /* STROBE */
|
||||
/* Process incoming character. */
|
||||
handle_char(dev);
|
||||
|
||||
/* ACK it, will be read on next READ STATUS. */
|
||||
dev->ack = 1;
|
||||
|
||||
timer_set_delay_u64(&dev->pulse_timer, ISACONST);
|
||||
timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
write_ctrl(uint8_t val, void *priv)
|
||||
{
|
||||
@@ -465,13 +497,16 @@ prnt_close(void *priv)
|
||||
}
|
||||
|
||||
const lpt_device_t lpt_prt_text_device = {
|
||||
.name = "Generic Text Printer",
|
||||
.internal_name = "text_prt",
|
||||
.init = prnt_init,
|
||||
.close = prnt_close,
|
||||
.write_data = write_data,
|
||||
.write_ctrl = write_ctrl,
|
||||
.read_data = NULL,
|
||||
.read_status = read_status,
|
||||
.read_ctrl = NULL
|
||||
.name = "Generic Text Printer",
|
||||
.internal_name = "text_prt",
|
||||
.init = prnt_init,
|
||||
.close = prnt_close,
|
||||
.write_data = write_data,
|
||||
.write_ctrl = write_ctrl,
|
||||
.autofeed = autofeed,
|
||||
.strobe = strobe,
|
||||
.read_status = read_status,
|
||||
.read_ctrl = NULL,
|
||||
.epp_write_data = NULL,
|
||||
.epp_request_read = NULL
|
||||
};
|
||||
|
||||
@@ -85,8 +85,6 @@ add_library(ui STATIC
|
||||
qt_renderercommon.hpp
|
||||
qt_softwarerenderer.cpp
|
||||
qt_softwarerenderer.hpp
|
||||
qt_hardwarerenderer.cpp
|
||||
qt_hardwarerenderer.hpp
|
||||
qt_openglrenderer.cpp
|
||||
qt_openglrenderer.hpp
|
||||
qt_glsl_parser.cpp
|
||||
@@ -189,6 +187,49 @@ add_library(ui STATIC
|
||||
qt_mediahistorymanager.cpp
|
||||
qt_mediahistorymanager.hpp
|
||||
|
||||
qt_updatecheck.cpp
|
||||
qt_updatecheck.hpp
|
||||
qt_updatecheckdialog.cpp
|
||||
qt_updatecheckdialog.hpp
|
||||
qt_updatecheckdialog.ui
|
||||
qt_updatedetails.cpp
|
||||
qt_updatedetails.hpp
|
||||
qt_updatedetails.ui
|
||||
qt_downloader.cpp
|
||||
qt_downloader.hpp
|
||||
|
||||
qt_vmmanager_clientsocket.cpp
|
||||
qt_vmmanager_clientsocket.hpp
|
||||
qt_vmmanager_serversocket.cpp
|
||||
qt_vmmanager_serversocket.hpp
|
||||
qt_vmmanager_protocol.cpp
|
||||
qt_vmmanager_protocol.hpp
|
||||
qt_vmmanager_details.hpp
|
||||
qt_vmmanager_details.cpp
|
||||
qt_vmmanager_details.ui
|
||||
qt_vmmanager_addmachine.cpp
|
||||
qt_vmmanager_addmachine.hpp
|
||||
qt_vmmanager_detailsection.cpp
|
||||
qt_vmmanager_detailsection.hpp
|
||||
qt_vmmanager_detailsection.ui
|
||||
qt_vmmanager_listviewdelegate.hpp
|
||||
qt_vmmanager_listviewdelegate.cpp
|
||||
qt_vmmanager_preferences.cpp
|
||||
qt_vmmanager_preferences.hpp
|
||||
qt_vmmanager_preferences.ui
|
||||
qt_vmmanager_main.hpp
|
||||
qt_vmmanager_main.cpp
|
||||
qt_vmmanager_main.ui
|
||||
qt_vmmanager_model.cpp
|
||||
qt_vmmanager_model.hpp
|
||||
qt_vmmanager_system.cpp
|
||||
qt_vmmanager_system.hpp
|
||||
qt_vmmanager_config.cpp
|
||||
qt_vmmanager_config.hpp
|
||||
qt_vmmanager_mainwindow.cpp
|
||||
qt_vmmanager_mainwindow.hpp
|
||||
qt_vmmanager_mainwindow.ui
|
||||
|
||||
../qt_resources.qrc
|
||||
./qdarkstyle/dark/darkstyle.qrc
|
||||
|
||||
|
||||
BIN
src/qt/assets/86box-wizard.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
src/qt/assets/systemicons/cpq_deskpro.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
src/qt/assets/systemicons/cpq_port_386.png
Normal file
|
After Width: | Height: | Size: 245 KiB |
BIN
src/qt/assets/systemicons/cpq_port_II.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
src/qt/assets/systemicons/cpq_port_III.png
Normal file
|
After Width: | Height: | Size: 198 KiB |
BIN
src/qt/assets/systemicons/cpq_portable.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
src/qt/assets/systemicons/cpq_pres_2240.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
src/qt/assets/systemicons/cpq_pres_4500.png
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
src/qt/assets/systemicons/ibm330.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
BIN
src/qt/assets/systemicons/ibm_at.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
src/qt/assets/systemicons/ibm_pc_81.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_pc_82.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_pcjr.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_ps2_m70.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
src/qt/assets/systemicons/ibm_ps2_m80.png
Normal file
|
After Width: | Height: | Size: 259 KiB |
BIN
src/qt/assets/systemicons/ibm_psvp_486.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
src/qt/assets/systemicons/ibm_psvp_p60.png
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
src/qt/assets/systemicons/ibm_xt_82.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/ibm_xt_86.png
Normal file
|
After Width: | Height: | Size: 289 KiB |
BIN
src/qt/assets/systemicons/olivetti_m19.png
Normal file
|
After Width: | Height: | Size: 257 KiB |
BIN
src/qt/assets/systemicons/olivetti_m21.png
Normal file
|
After Width: | Height: | Size: 317 KiB |
BIN
src/qt/assets/systemicons/olivetti_m24.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
src/qt/assets/systemicons/olivetti_m24sp.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
src/qt/assets/systemicons/os_archlinux_x2.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
src/qt/assets/systemicons/os_cloud_x2.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src/qt/assets/systemicons/os_debian_x2.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src/qt/assets/systemicons/os_dos_x2.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
src/qt/assets/systemicons/os_fedora_x2.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/qt/assets/systemicons/os_freebsd_x2.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/qt/assets/systemicons/os_gentoo_x2.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src/qt/assets/systemicons/os_jrockitve_x2.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
src/qt/assets/systemicons/os_l4_x2.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |