clang-format in src/

This commit is contained in:
Jasmine Iwanek
2022-09-18 17:11:43 -04:00
parent 2267153edd
commit e6dbaefeb1
35 changed files with 7113 additions and 7387 deletions

File diff suppressed because it is too large Load Diff

1819
src/acpi.c

File diff suppressed because it is too large Load Diff

View File

@@ -27,34 +27,30 @@
#include <86box/io.h> #include <86box/io.h>
#include <86box/apm.h> #include <86box/apm.h>
#ifdef ENABLE_APM_LOG #ifdef ENABLE_APM_LOG
int apm_do_log = ENABLE_APM_LOG; int apm_do_log = ENABLE_APM_LOG;
static void static void
apm_log(const char *fmt, ...) apm_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (apm_do_log) { if (apm_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define apm_log(fmt, ...) # define apm_log(fmt, ...)
#endif #endif
void void
apm_set_do_smi(apm_t *dev, uint8_t do_smi) apm_set_do_smi(apm_t *dev, uint8_t do_smi)
{ {
dev->do_smi = do_smi; dev->do_smi = do_smi;
} }
static void static void
apm_out(uint16_t port, uint8_t val, void *p) apm_out(uint16_t port, uint8_t val, void *p)
{ {
@@ -65,102 +61,98 @@ apm_out(uint16_t port, uint8_t val, void *p)
port &= 0x0001; port &= 0x0001;
if (port == 0x0000) { if (port == 0x0000) {
dev->cmd = val; dev->cmd = val;
if (dev->do_smi) if (dev->do_smi)
smi_raise(); smi_raise();
} else } else
dev->stat = val; dev->stat = val;
} }
static uint8_t static uint8_t
apm_in(uint16_t port, void *p) apm_in(uint16_t port, void *p)
{ {
apm_t *dev = (apm_t *) p; apm_t *dev = (apm_t *) p;
uint8_t ret = 0xff; uint8_t ret = 0xff;
port &= 0x0001; port &= 0x0001;
if (port == 0x0000) if (port == 0x0000)
ret = dev->cmd; ret = dev->cmd;
else else
ret = dev->stat; ret = dev->stat;
apm_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret); apm_log("[%04X:%08X] APM read: %04X = %02X\n", CS, cpu_state.pc, port, ret);
return ret; return ret;
} }
static void static void
apm_reset(void *p) apm_reset(void *p)
{ {
apm_t *dev = (apm_t *)p; apm_t *dev = (apm_t *) p;
dev->cmd = dev->stat = 0x00; dev->cmd = dev->stat = 0x00;
} }
static void static void
apm_close(void *p) apm_close(void *p)
{ {
apm_t *dev = (apm_t *)p; apm_t *dev = (apm_t *) p;
free(dev); free(dev);
} }
static void static void
*apm_init(const device_t *info) *
apm_init(const device_t *info)
{ {
apm_t *dev = (apm_t *) malloc(sizeof(apm_t)); apm_t *dev = (apm_t *) malloc(sizeof(apm_t));
memset(dev, 0, sizeof(apm_t)); memset(dev, 0, sizeof(apm_t));
if (info->local == 0) if (info->local == 0)
io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, dev); io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, dev);
return dev; return dev;
} }
const device_t apm_device = { const device_t apm_device = {
.name = "Advanced Power Management", .name = "Advanced Power Management",
.internal_name = "apm", .internal_name = "apm",
.flags = 0, .flags = 0,
.local = 0, .local = 0,
.init = apm_init, .init = apm_init,
.close = apm_close, .close = apm_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t apm_pci_device = { const device_t apm_pci_device = {
.name = "Advanced Power Management (PCI)", .name = "Advanced Power Management (PCI)",
.internal_name = "apm_pci", .internal_name = "apm_pci",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = 0, .local = 0,
.init = apm_init, .init = apm_init,
.close = apm_close, .close = apm_close,
.reset = apm_reset, .reset = apm_reset,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t apm_pci_acpi_device = { const device_t apm_pci_acpi_device = {
.name = "Advanced Power Management (PCI)", .name = "Advanced Power Management (PCI)",
.internal_name = "apm_pci_acpi", .internal_name = "apm_pci_acpi",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = 1, .local = 1,
.init = apm_init, .init = apm_init,
.close = apm_close, .close = apm_close,
.reset = apm_reset, .reset = apm_reset,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

View File

@@ -16,12 +16,12 @@
*/ */
#if defined(__arm__) || defined(__TARGET_ARCH_ARM) #if defined(__arm__) || defined(__TARGET_ARCH_ARM)
#error ARCH arm # error ARCH arm
#elif defined(__aarch64__) || defined(_M_ARM64) #elif defined(__aarch64__) || defined(_M_ARM64)
#error ARCH arm64 # error ARCH arm64
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) #elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error ARCH i386 # error ARCH i386
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#error ARCH x86_64 # error ARCH x86_64
#endif #endif
#error ARCH unknown #error ARCH unknown

View File

@@ -73,8 +73,7 @@
#include <86box/ui.h> #include <86box/ui.h>
#include <86box/snd_opl.h> #include <86box/snd_opl.h>
static int cx, cy, cw, ch;
static int cx, cy, cw, ch;
static ini_t config; static ini_t config;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */ /* TODO: Backwards compatibility, get rid of this when enough time has passed. */
@@ -104,8 +103,8 @@ static void
load_general(void) load_general(void)
{ {
ini_section_t cat = ini_find_section(config, "General"); ini_section_t cat = ini_find_section(config, "General");
char temp[512]; char temp[512];
char *p; char *p;
vid_resize = ini_section_get_int(cat, "vid_resize", 0); vid_resize = ini_section_get_int(cat, "vid_resize", 0);
if (vid_resize & ~3) if (vid_resize & ~3)
@@ -201,13 +200,13 @@ load_general(void)
window_remember = ini_section_get_int(cat, "window_remember", 0); window_remember = ini_section_get_int(cat, "window_remember", 0);
if (window_remember) { if (window_remember) {
p = ini_section_get_string(cat, "window_coordinates", NULL); p = ini_section_get_string(cat, "window_coordinates", NULL);
if (p == NULL) if (p == NULL)
p = "0, 0, 0, 0"; p = "0, 0, 0, 0";
sscanf(p, "%i, %i, %i, %i", &cw, &ch, &cx, &cy); sscanf(p, "%i, %i, %i, %i", &cw, &ch, &cx, &cy);
} else { } else {
cw = ch = cx = cy = 0; cw = ch = cx = cy = 0;
ini_section_delete_var(cat, "window_remember"); ini_section_delete_var(cat, "window_remember");
} }
ini_section_delete_var(cat, "window_coordinates"); ini_section_delete_var(cat, "window_coordinates");
@@ -218,8 +217,8 @@ static void
load_monitor(int monitor_index) load_monitor(int monitor_index)
{ {
ini_section_t cat; ini_section_t cat;
char name[512], temp[512]; char name[512], temp[512];
char *p = NULL; char *p = NULL;
sprintf(name, "Monitor #%i", monitor_index + 1); sprintf(name, "Monitor #%i", monitor_index + 1);
sprintf(temp, "%i, %i, %i, %i", cx, cy, cw, ch); sprintf(temp, "%i, %i, %i, %i", cx, cy, cw, ch);
@@ -229,7 +228,7 @@ load_monitor(int monitor_index)
p = ini_section_get_string(cat, "window_coordinates", NULL); p = ini_section_get_string(cat, "window_coordinates", NULL);
if (p == NULL) if (p == NULL)
p = temp; p = temp;
if (window_remember) { if (window_remember) {
sscanf(p, "%i, %i, %i, %i", sscanf(p, "%i, %i, %i, %i",
@@ -245,10 +244,10 @@ load_monitor(int monitor_index)
static void static void
load_machine(void) load_machine(void)
{ {
ini_section_t cat = ini_find_section(config, "Machine"); ini_section_t cat = ini_find_section(config, "Machine");
char *p, *migrate_from = NULL; char *p, *migrate_from = NULL;
int c, i, j, speed, legacy_mfg, legacy_cpu; int c, i, j, speed, legacy_mfg, legacy_cpu;
double multi; double multi;
p = ini_section_get_string(cat, "machine", NULL); p = ini_section_get_string(cat, "machine", NULL);
if (p != NULL) { if (p != NULL) {
@@ -525,8 +524,8 @@ static void
load_video(void) load_video(void)
{ {
ini_section_t cat = ini_find_section(config, "Video"); ini_section_t cat = ini_find_section(config, "Video");
char *p; char *p;
int free_p = 0; int free_p = 0;
if (machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { if (machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
ini_section_delete_var(cat, "gfxcard"); ini_section_delete_var(cat, "gfxcard");
@@ -551,13 +550,13 @@ load_video(void)
free(p); free(p);
} }
voodoo_enabled = !!ini_section_get_int(cat, "voodoo", 0); voodoo_enabled = !!ini_section_get_int(cat, "voodoo", 0);
ibm8514_enabled = !!ini_section_get_int(cat, "8514a", 0); ibm8514_enabled = !!ini_section_get_int(cat, "8514a", 0);
xga_enabled = !!ini_section_get_int(cat, "xga", 0); xga_enabled = !!ini_section_get_int(cat, "xga", 0);
show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1); show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1);
video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0); video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0);
p = ini_section_get_string(cat, "gfxcard_2", NULL); p = ini_section_get_string(cat, "gfxcard_2", NULL);
if (!p) if (!p)
p = "none"; p = "none";
gfxcard_2 = video_get_video_from_internal_name(p); gfxcard_2 = video_get_video_from_internal_name(p);
@@ -568,9 +567,9 @@ static void
load_input_devices(void) load_input_devices(void)
{ {
ini_section_t cat = ini_find_section(config, "Input devices"); ini_section_t cat = ini_find_section(config, "Input devices");
char temp[512]; char temp[512];
int c, d; int c, d;
char *p; char *p;
p = ini_section_get_string(cat, "mouse_type", NULL); p = ini_section_get_string(cat, "mouse_type", NULL);
if (p != NULL) if (p != NULL)
@@ -658,8 +657,8 @@ static void
load_sound(void) load_sound(void)
{ {
ini_section_t cat = ini_find_section(config, "Sound"); ini_section_t cat = ini_find_section(config, "Sound");
char temp[512]; char temp[512];
char *p; char *p;
p = ini_section_get_string(cat, "sndcard", NULL); p = ini_section_get_string(cat, "sndcard", NULL);
/* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */ /* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
@@ -712,9 +711,9 @@ static void
load_network(void) load_network(void)
{ {
ini_section_t cat = ini_find_section(config, "Network"); ini_section_t cat = ini_find_section(config, "Network");
char *p; char *p;
char temp[512]; char temp[512];
int c = 0, min = 0; int c = 0, min = 0;
/* Handle legacy configuration which supported only one NIC */ /* Handle legacy configuration which supported only one NIC */
p = ini_section_get_string(cat, "net_card", NULL); p = ini_section_get_string(cat, "net_card", NULL);
@@ -796,10 +795,9 @@ load_network(void)
strcpy(net_cards_conf[c].host_dev_name, "none"); strcpy(net_cards_conf[c].host_dev_name, "none");
} }
sprintf(temp, "net_%02i_link", c +1); sprintf(temp, "net_%02i_link", c + 1);
net_cards_conf[c].link_state = ini_section_get_int(cat, temp, net_cards_conf[c].link_state = ini_section_get_int(cat, temp,
(NET_LINK_10_HD|NET_LINK_10_FD|NET_LINK_100_HD|NET_LINK_100_FD|NET_LINK_1000_HD|NET_LINK_1000_FD)); (NET_LINK_10_HD | NET_LINK_10_FD | NET_LINK_100_HD | NET_LINK_100_FD | NET_LINK_1000_HD | NET_LINK_1000_FD));
} }
} }
@@ -808,9 +806,9 @@ static void
load_ports(void) load_ports(void)
{ {
ini_section_t cat = ini_find_section(config, "Ports (COM & LPT)"); ini_section_t cat = ini_find_section(config, "Ports (COM & LPT)");
char *p; char *p;
char temp[512]; char temp[512];
int c, d; int c, d;
for (c = 0; c < SERIAL_MAX; c++) { for (c = 0; c < SERIAL_MAX; c++) {
sprintf(temp, "serial%d_enabled", c + 1); sprintf(temp, "serial%d_enabled", c + 1);
@@ -846,9 +844,9 @@ static void
load_storage_controllers(void) load_storage_controllers(void)
{ {
ini_section_t cat = ini_find_section(config, "Storage controllers"); ini_section_t cat = ini_find_section(config, "Storage controllers");
char *p, temp[512]; char *p, temp[512];
int c, min = 0; int c, min = 0;
int free_p = 0; int free_p = 0;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */ /* TODO: Backwards compatibility, get rid of this when enough time has passed. */
backwards_compat2 = (cat == NULL); backwards_compat2 = (cat == NULL);
@@ -959,13 +957,13 @@ load_storage_controllers(void)
static void static void
load_hard_disks(void) load_hard_disks(void)
{ {
ini_section_t cat = ini_find_section(config, "Hard disks"); ini_section_t cat = ini_find_section(config, "Hard disks");
char temp[512], tmp2[512]; char temp[512], tmp2[512];
char s[512]; char s[512];
int c; int c;
char *p; char *p;
uint32_t max_spt, max_hpc, max_tracks; uint32_t max_spt, max_hpc, max_tracks;
uint32_t board = 0, dev = 0; uint32_t board = 0, dev = 0;
memset(temp, '\0', sizeof(temp)); memset(temp, '\0', sizeof(temp));
for (c = 0; c < HDD_NUM; c++) { for (c = 0; c < HDD_NUM; c++) {
@@ -1161,8 +1159,8 @@ static void
load_floppy_drives(void) load_floppy_drives(void)
{ {
ini_section_t cat = ini_find_section(config, "Floppy drives"); ini_section_t cat = ini_find_section(config, "Floppy drives");
char temp[512], *p; char temp[512], *p;
int c; int c;
if (!backwards_compat) if (!backwards_compat)
return; return;
@@ -1221,11 +1219,11 @@ load_floppy_drives(void)
static void static void
load_floppy_and_cdrom_drives(void) load_floppy_and_cdrom_drives(void)
{ {
ini_section_t cat = ini_find_section(config, "Floppy and CD-ROM drives"); ini_section_t cat = ini_find_section(config, "Floppy and CD-ROM drives");
char temp[512], tmp2[512], *p; char temp[512], tmp2[512], *p;
char s[512]; char s[512];
unsigned int board = 0, dev = 0; unsigned int board = 0, dev = 0;
int c, d = 0; int c, d = 0;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */ /* TODO: Backwards compatibility, get rid of this when enough time has passed. */
backwards_compat = (cat == NULL); backwards_compat = (cat == NULL);
@@ -1415,7 +1413,7 @@ load_floppy_and_cdrom_drives(void)
cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char)); cdrom[c].image_history[i] = (char *) calloc(MAX_IMAGE_PATH_LEN + 1, sizeof(char));
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL); p = ini_section_get_string(cat, temp, NULL);
if(p) { if (p) {
sprintf(cdrom[c].image_history[i], "%s", p); sprintf(cdrom[c].image_history[i], "%s", p);
} }
} }
@@ -1427,10 +1425,10 @@ static void
load_other_removable_devices(void) load_other_removable_devices(void)
{ {
ini_section_t cat = ini_find_section(config, "Other removable devices"); ini_section_t cat = ini_find_section(config, "Other removable devices");
char temp[512], tmp2[512], *p; char temp[512], tmp2[512], *p;
char s[512]; char s[512];
unsigned int board = 0, dev = 0; unsigned int board = 0, dev = 0;
int c, d = 0; int c, d = 0;
/* TODO: Backwards compatibility, get rid of this when enough time has passed. */ /* TODO: Backwards compatibility, get rid of this when enough time has passed. */
if (backwards_compat) { if (backwards_compat) {
@@ -1703,9 +1701,9 @@ static void
load_other_peripherals(void) load_other_peripherals(void)
{ {
ini_section_t cat = ini_find_section(config, "Other peripherals"); ini_section_t cat = ini_find_section(config, "Other peripherals");
char *p; char *p;
char temp[512]; char temp[512];
int c, free_p = 0; int c, free_p = 0;
if (backwards_compat2) { if (backwards_compat2) {
p = ini_section_get_string(cat, "scsicard", NULL); p = ini_section_get_string(cat, "scsicard", NULL);
@@ -1882,7 +1880,7 @@ static void
save_general(void) save_general(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "General"); ini_section_t cat = ini_find_or_create_section(config, "General");
char temp[512], buffer[512] = { 0 }; char temp[512], buffer[512] = { 0 };
char *va_name; char *va_name;
@@ -2058,8 +2056,8 @@ save_monitor(int monitor_index)
snprintf(cat, sizeof(cat), "Monitor #%i", monitor_index + 1); snprintf(cat, sizeof(cat), "Monitor #%i", monitor_index + 1);
if (window_remember) { if (window_remember) {
sprintf(temp, "%i, %i, %i, %i", sprintf(temp, "%i, %i, %i, %i",
monitor_settings[monitor_index].mon_window_x, monitor_settings[monitor_index].mon_window_y, monitor_settings[monitor_index].mon_window_x, monitor_settings[monitor_index].mon_window_y,
monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h); monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h);
ini_section_set_string(cat, "window_coordinates", temp); ini_section_set_string(cat, "window_coordinates", temp);
if (monitor_settings[monitor_index].mon_window_maximized != 0) { if (monitor_settings[monitor_index].mon_window_maximized != 0) {
@@ -2078,8 +2076,8 @@ static void
save_machine(void) save_machine(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Machine"); ini_section_t cat = ini_find_or_create_section(config, "Machine");
char *p; char *p;
int c, i = 0, legacy_mfg, legacy_cpu = -1, closest_legacy_cpu = -1; int c, i = 0, legacy_mfg, legacy_cpu = -1, closest_legacy_cpu = -1;
p = machine_get_internal_name(); p = machine_get_internal_name();
ini_section_set_string(cat, "machine", p); ini_section_set_string(cat, "machine", p);
@@ -2183,7 +2181,7 @@ save_video(void)
ini_section_t cat = ini_find_or_create_section(config, "Video"); ini_section_t cat = ini_find_or_create_section(config, "Video");
ini_section_set_string(cat, "gfxcard", ini_section_set_string(cat, "gfxcard",
video_get_internal_name(gfxcard)); video_get_internal_name(gfxcard));
if (voodoo_enabled == 0) if (voodoo_enabled == 0)
ini_section_delete_var(cat, "voodoo"); ini_section_delete_var(cat, "voodoo");
@@ -2223,8 +2221,8 @@ static void
save_input_devices(void) save_input_devices(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Input devices"); ini_section_t cat = ini_find_or_create_section(config, "Input devices");
char temp[512], tmp2[512]; char temp[512], tmp2[512];
int c, d; int c, d;
ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type));
@@ -2331,8 +2329,8 @@ save_sound(void)
static void static void
save_network(void) save_network(void)
{ {
int c = 0; int c = 0;
char temp[512]; char temp[512];
ini_section_t cat = ini_find_or_create_section(config, "Network"); ini_section_t cat = ini_find_or_create_section(config, "Network");
ini_section_delete_var(cat, "net_type"); ini_section_delete_var(cat, "net_type");
@@ -2352,7 +2350,7 @@ save_network(void)
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
} else { } else {
ini_section_set_string(cat, temp, ini_section_set_string(cat, temp,
(net_cards_conf[c].net_type == NET_TYPE_SLIRP) ? "slirp" : "pcap"); (net_cards_conf[c].net_type == NET_TYPE_SLIRP) ? "slirp" : "pcap");
} }
sprintf(temp, "net_%02i_host_device", c + 1); sprintf(temp, "net_%02i_host_device", c + 1);
@@ -2367,7 +2365,7 @@ save_network(void)
} }
sprintf(temp, "net_%02i_link", c + 1); sprintf(temp, "net_%02i_link", c + 1);
if (net_cards_conf[c].link_state == (NET_LINK_10_HD|NET_LINK_10_FD|NET_LINK_100_HD|NET_LINK_100_FD|NET_LINK_1000_HD|NET_LINK_1000_FD)) { if (net_cards_conf[c].link_state == (NET_LINK_10_HD | NET_LINK_10_FD | NET_LINK_100_HD | NET_LINK_100_FD | NET_LINK_1000_HD | NET_LINK_1000_FD)) {
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
} else { } else {
ini_section_set_int(cat, temp, net_cards_conf[c].link_state); ini_section_set_int(cat, temp, net_cards_conf[c].link_state);
@@ -2382,8 +2380,8 @@ static void
save_ports(void) save_ports(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Ports (COM & LPT)"); ini_section_t cat = ini_find_or_create_section(config, "Ports (COM & LPT)");
char temp[512]; char temp[512];
int c, d; int c, d;
for (c = 0; c < SERIAL_MAX; c++) { for (c = 0; c < SERIAL_MAX; c++) {
sprintf(temp, "serial%d_enabled", c + 1); sprintf(temp, "serial%d_enabled", c + 1);
@@ -2392,20 +2390,20 @@ save_ports(void)
else else
ini_section_set_int(cat, temp, com_ports[c].enabled); ini_section_set_int(cat, temp, com_ports[c].enabled);
/* /*
sprintf(temp, "serial%d_type", c + 1); sprintf(temp, "serial%d_type", c + 1);
if (!com_ports[c].enabled)) if (!com_ports[c].enabled))
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
// else // else
// ini_section_set_string(cat, temp, (char *) serial_type[c]) // ini_section_set_string(cat, temp, (char *) serial_type[c])
sprintf(temp, "serial%d_device", c + 1); sprintf(temp, "serial%d_device", c + 1);
if (com_ports[c].device == 0) if (com_ports[c].device == 0)
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
else else
ini_section_set_string(cat, temp, ini_section_set_string(cat, temp,
(char *) com_device_get_internal_name(com_ports[c].device)); (char *) com_device_get_internal_name(com_ports[c].device));
*/ */
} }
for (c = 0; c < PARALLEL_MAX; c++) { for (c = 0; c < PARALLEL_MAX; c++) {
@@ -2421,7 +2419,7 @@ save_ports(void)
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
else else
ini_section_set_string(cat, temp, ini_section_set_string(cat, temp,
(char *) lpt_device_get_internal_name(lpt_ports[c].device)); (char *) lpt_device_get_internal_name(lpt_ports[c].device));
} }
ini_delete_section_if_empty(config, cat); ini_delete_section_if_empty(config, cat);
@@ -2432,8 +2430,8 @@ static void
save_storage_controllers(void) save_storage_controllers(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Storage controllers"); ini_section_t cat = ini_find_or_create_section(config, "Storage controllers");
char temp[512]; char temp[512];
int c; int c;
ini_section_delete_var(cat, "scsicard"); ini_section_delete_var(cat, "scsicard");
@@ -2444,17 +2442,17 @@ save_storage_controllers(void)
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
else else
ini_section_set_string(cat, temp, ini_section_set_string(cat, temp,
scsi_card_get_internal_name(scsi_card_current[c])); scsi_card_get_internal_name(scsi_card_current[c]));
} }
if (fdc_type == FDC_INTERNAL) if (fdc_type == FDC_INTERNAL)
ini_section_delete_var(cat, "fdc"); ini_section_delete_var(cat, "fdc");
else else
ini_section_set_string(cat, "fdc", ini_section_set_string(cat, "fdc",
fdc_card_get_internal_name(fdc_type)); fdc_card_get_internal_name(fdc_type));
ini_section_set_string(cat, "hdc", ini_section_set_string(cat, "hdc",
hdc_get_internal_name(hdc_current)); hdc_get_internal_name(hdc_current));
if (ide_ter_enabled == 0) if (ide_ter_enabled == 0)
ini_section_delete_var(cat, "ide_ter"); ini_section_delete_var(cat, "ide_ter");
@@ -2522,8 +2520,8 @@ static void
save_other_peripherals(void) save_other_peripherals(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Other peripherals"); ini_section_t cat = ini_find_or_create_section(config, "Other peripherals");
char temp[512]; char temp[512];
int c; int c;
if (bugger_enabled == 0) if (bugger_enabled == 0)
ini_section_delete_var(cat, "bugger_enabled"); ini_section_delete_var(cat, "bugger_enabled");
@@ -2541,14 +2539,14 @@ save_other_peripherals(void)
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
else else
ini_section_set_string(cat, temp, ini_section_set_string(cat, temp,
(char *) isamem_get_internal_name(isamem_type[c])); (char *) isamem_get_internal_name(isamem_type[c]));
} }
if (isartc_type == 0) if (isartc_type == 0)
ini_section_delete_var(cat, "isartc_type"); ini_section_delete_var(cat, "isartc_type");
else else
ini_section_set_string(cat, "isartc_type", ini_section_set_string(cat, "isartc_type",
isartc_get_internal_name(isartc_type)); isartc_get_internal_name(isartc_type));
ini_delete_section_if_empty(config, cat); ini_delete_section_if_empty(config, cat);
} }
@@ -2558,9 +2556,9 @@ static void
save_hard_disks(void) save_hard_disks(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Hard disks"); ini_section_t cat = ini_find_or_create_section(config, "Hard disks");
char temp[32], tmp2[512]; char temp[32], tmp2[512];
char *p; char *p;
int c; int c;
memset(temp, 0x00, sizeof(temp)); memset(temp, 0x00, sizeof(temp));
for (c = 0; c < HDD_NUM; c++) { for (c = 0; c < HDD_NUM; c++) {
@@ -2637,8 +2635,8 @@ static void
save_floppy_and_cdrom_drives(void) save_floppy_and_cdrom_drives(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Floppy and CD-ROM drives"); ini_section_t cat = ini_find_or_create_section(config, "Floppy and CD-ROM drives");
char temp[512], tmp2[512]; char temp[512], tmp2[512];
int c; int c;
for (c = 0; c < FDD_NUM; c++) { for (c = 0; c < FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c + 1); sprintf(temp, "fdd_%02i_type", c + 1);
@@ -2646,7 +2644,7 @@ save_floppy_and_cdrom_drives(void)
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
else else
ini_section_set_string(cat, temp, ini_section_set_string(cat, temp,
fdd_get_internal_name(fdd_get_type(c))); fdd_get_internal_name(fdd_get_type(c)));
sprintf(temp, "fdd_%02i_fn", c + 1); sprintf(temp, "fdd_%02i_fn", c + 1);
if (strlen(floppyfns[c]) == 0) { if (strlen(floppyfns[c]) == 0) {
@@ -2733,7 +2731,7 @@ save_floppy_and_cdrom_drives(void)
for (int i = 0; i < MAX_PREV_IMAGES; i++) { for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1);
if((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) { if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) {
ini_section_delete_var(cat, temp); ini_section_delete_var(cat, temp);
} else { } else {
ini_section_set_string(cat, temp, cdrom[c].image_history[i]); ini_section_set_string(cat, temp, cdrom[c].image_history[i]);
@@ -2749,8 +2747,8 @@ static void
save_other_removable_devices(void) save_other_removable_devices(void)
{ {
ini_section_t cat = ini_find_or_create_section(config, "Other removable devices"); ini_section_t cat = ini_find_or_create_section(config, "Other removable devices");
char temp[512], tmp2[512]; char temp[512], tmp2[512];
int c; int c;
for (c = 0; c < ZIP_NUM; c++) { for (c = 0; c < ZIP_NUM; c++) {
sprintf(temp, "zip_%02i_parameters", c + 1); sprintf(temp, "zip_%02i_parameters", c + 1);

View File

@@ -35,130 +35,125 @@
#include <86box/dma.h> #include <86box/dma.h>
#include <86box/ddma.h> #include <86box/ddma.h>
#ifdef ENABLE_DDMA_LOG #ifdef ENABLE_DDMA_LOG
int ddma_do_log = ENABLE_DDMA_LOG; int ddma_do_log = ENABLE_DDMA_LOG;
static void static void
ddma_log(const char *fmt, ...) ddma_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (ddma_do_log) { if (ddma_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define ddma_log(fmt, ...) # define ddma_log(fmt, ...)
#endif #endif
static uint8_t static uint8_t
ddma_reg_read(uint16_t addr, void *p) ddma_reg_read(uint16_t addr, void *p)
{ {
ddma_channel_t *dev = (ddma_channel_t *) p; ddma_channel_t *dev = (ddma_channel_t *) p;
uint8_t ret = 0xff; uint8_t ret = 0xff;
int ch = dev->channel; int ch = dev->channel;
int dmab = (ch >= 4) ? 0xc0 : 0x00; int dmab = (ch >= 4) ? 0xc0 : 0x00;
switch (addr & 0x0f) { switch (addr & 0x0f) {
case 0x00: case 0x00:
ret = dma[ch].ac & 0xff; ret = dma[ch].ac & 0xff;
break; break;
case 0x01: case 0x01:
ret = (dma[ch].ac >> 8) & 0xff; ret = (dma[ch].ac >> 8) & 0xff;
break; break;
case 0x02: case 0x02:
ret = dma[ch].page; ret = dma[ch].page;
break; break;
case 0x04: case 0x04:
ret = dma[ch].cc & 0xff; ret = dma[ch].cc & 0xff;
break; break;
case 0x05: case 0x05:
ret = (dma[ch].cc >> 8) & 0xff; ret = (dma[ch].cc >> 8) & 0xff;
break; break;
case 0x09: case 0x09:
ret = inb(dmab + 0x08); ret = inb(dmab + 0x08);
break; break;
} }
return ret; return ret;
} }
static void static void
ddma_reg_write(uint16_t addr, uint8_t val, void *p) ddma_reg_write(uint16_t addr, uint8_t val, void *p)
{ {
ddma_channel_t *dev = (ddma_channel_t *) p; ddma_channel_t *dev = (ddma_channel_t *) p;
int ch = dev->channel; int ch = dev->channel;
int page_regs[4] = { 7, 3, 1, 2 }; int page_regs[4] = { 7, 3, 1, 2 };
int i, dmab = (ch >= 4) ? 0xc0 : 0x00; int i, dmab = (ch >= 4) ? 0xc0 : 0x00;
switch (addr & 0x0f) { switch (addr & 0x0f) {
case 0x00: case 0x00:
dma[ch].ab = (dma[ch].ab & 0xffff00) | val; dma[ch].ab = (dma[ch].ab & 0xffff00) | val;
dma[ch].ac = dma[ch].ab; dma[ch].ac = dma[ch].ab;
break; break;
case 0x01: case 0x01:
dma[ch].ab = (dma[ch].ab & 0xff00ff) | (val << 8); dma[ch].ab = (dma[ch].ab & 0xff00ff) | (val << 8);
dma[ch].ac = dma[ch].ab; dma[ch].ac = dma[ch].ab;
break; break;
case 0x02: case 0x02:
if (ch >= 4) if (ch >= 4)
outb(0x88 + page_regs[ch & 3], val); outb(0x88 + page_regs[ch & 3], val);
else else
outb(0x80 + page_regs[ch & 3], val); outb(0x80 + page_regs[ch & 3], val);
break; break;
case 0x04: case 0x04:
dma[ch].cb = (dma[ch].cb & 0xffff00) | val; dma[ch].cb = (dma[ch].cb & 0xffff00) | val;
dma[ch].cc = dma[ch].cb; dma[ch].cc = dma[ch].cb;
break; break;
case 0x05: case 0x05:
dma[ch].cb = (dma[ch].cb & 0xff00ff) | (val << 8); dma[ch].cb = (dma[ch].cb & 0xff00ff) | (val << 8);
dma[ch].cc = dma[ch].cb; dma[ch].cc = dma[ch].cb;
break; break;
case 0x08: case 0x08:
outb(dmab + 0x08, val); outb(dmab + 0x08, val);
break; break;
case 0x09: case 0x09:
outb(dmab + 0x09, val); outb(dmab + 0x09, val);
break; break;
case 0x0a: case 0x0a:
outb(dmab + 0x0a, val); outb(dmab + 0x0a, val);
break; break;
case 0x0b: case 0x0b:
outb(dmab + 0x0b, val); outb(dmab + 0x0b, val);
break; break;
case 0x0d: case 0x0d:
outb(dmab + 0x0d, val); outb(dmab + 0x0d, val);
break; break;
case 0x0e: case 0x0e:
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
outb(dmab + 0x0a, i); outb(dmab + 0x0a, i);
break; break;
case 0x0f: case 0x0f:
outb(dmab + 0x0a, (val << 2) | (ch & 3)); outb(dmab + 0x0a, (val << 2) | (ch & 3));
break; break;
} }
} }
void void
ddma_update_io_mapping(ddma_t *dev, int ch, uint8_t base_l, uint8_t base_h, int enable) ddma_update_io_mapping(ddma_t *dev, int ch, uint8_t base_l, uint8_t base_h, int enable)
{ {
if (dev->channels[ch].enable && (dev->channels[ch].io_base != 0x0000)) if (dev->channels[ch].enable && (dev->channels[ch].io_base != 0x0000))
io_removehandler(dev->channels[ch].io_base, 0x10, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->channels[ch]); io_removehandler(dev->channels[ch].io_base, 0x10, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->channels[ch]);
dev->channels[ch].io_base = base_l | (base_h << 8); dev->channels[ch].io_base = base_l | (base_h << 8);
dev->channels[ch].enable = enable; dev->channels[ch].enable = enable;
if (dev->channels[ch].enable && (dev->channels[ch].io_base != 0x0000)) if (dev->channels[ch].enable && (dev->channels[ch].io_base != 0x0000))
io_sethandler(dev->channels[ch].io_base, 0x10, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->channels[ch]); io_sethandler(dev->channels[ch].io_base, 0x10, ddma_reg_read, NULL, NULL, ddma_reg_write, NULL, NULL, &dev->channels[ch]);
} }
static void static void
ddma_close(void *priv) ddma_close(void *priv)
{ {
@@ -167,33 +162,33 @@ ddma_close(void *priv)
free(dev); free(dev);
} }
static void * static void *
ddma_init(const device_t *info) ddma_init(const device_t *info)
{ {
ddma_t *dev; ddma_t *dev;
int i; int i;
dev = (ddma_t *)malloc(sizeof(ddma_t)); dev = (ddma_t *) malloc(sizeof(ddma_t));
if (dev == NULL) return(NULL); if (dev == NULL)
return (NULL);
memset(dev, 0x00, sizeof(ddma_t)); memset(dev, 0x00, sizeof(ddma_t));
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
dev->channels[i].channel = i; dev->channels[i].channel = i;
return dev; return dev;
} }
const device_t ddma_device = { const device_t ddma_device = {
.name = "Distributed DMA", .name = "Distributed DMA",
.internal_name = "ddma", .internal_name = "ddma",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = 0, .local = 0,
.init = ddma_init, .init = ddma_init,
.close = ddma_close, .close = ddma_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

View File

@@ -53,35 +53,30 @@
#include <86box/rom.h> #include <86box/rom.h>
#include <86box/sound.h> #include <86box/sound.h>
#define DEVICE_MAX 256 /* max # of devices */
#define DEVICE_MAX 256 /* max # of devices */ static device_t *devices[DEVICE_MAX];
static void *device_priv[DEVICE_MAX];
static device_context_t device_current, device_prev;
static device_t *devices[DEVICE_MAX];
static void *device_priv[DEVICE_MAX];
static device_context_t device_current, device_prev;
#ifdef ENABLE_DEVICE_LOG #ifdef ENABLE_DEVICE_LOG
int device_do_log = ENABLE_DEVICE_LOG; int device_do_log = ENABLE_DEVICE_LOG;
static void static void
device_log(const char *fmt, ...) device_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (device_do_log) { if (device_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define device_log(fmt, ...) # define device_log(fmt, ...)
#endif #endif
/* Initialize the module for use. */ /* Initialize the module for use. */
void void
device_init(void) device_init(void)
@@ -89,7 +84,6 @@ device_init(void)
memset(devices, 0x00, sizeof(devices)); memset(devices, 0x00, sizeof(devices));
} }
void void
device_set_context(device_context_t *c, const device_t *d, int inst) device_set_context(device_context_t *c, const device_t *d, int inst)
{ {
@@ -98,21 +92,20 @@ device_set_context(device_context_t *c, const device_t *d, int inst)
memset(c, 0, sizeof(device_context_t)); memset(c, 0, sizeof(device_context_t));
c->dev = d; c->dev = d;
if (inst) { if (inst) {
sprintf(c->name, "%s #%i", d->name, inst); sprintf(c->name, "%s #%i", d->name, inst);
/* If this is the first instance and a numbered section is not present, but a non-numbered /* If this is the first instance and a numbered section is not present, but a non-numbered
section of the same name is, rename the non-numbered section to numbered. */ section of the same name is, rename the non-numbered section to numbered. */
if (inst == 1) { if (inst == 1) {
sec = config_find_section(c->name); sec = config_find_section(c->name);
single_sec = config_find_section((char *) d->name); single_sec = config_find_section((char *) d->name);
if ((sec == NULL) && (single_sec != NULL)) if ((sec == NULL) && (single_sec != NULL))
config_rename_section(single_sec, c->name); config_rename_section(single_sec, c->name);
} }
} else } else
sprintf(c->name, "%s", d->name); sprintf(c->name, "%s", d->name);
} }
static void static void
device_context_common(const device_t *d, int inst) device_context_common(const device_t *d, int inst)
{ {
@@ -120,98 +113,92 @@ device_context_common(const device_t *d, int inst)
device_set_context(&device_current, d, inst); device_set_context(&device_current, d, inst);
} }
void void
device_context(const device_t *d) device_context(const device_t *d)
{ {
device_context_common(d, 0); device_context_common(d, 0);
} }
void void
device_context_inst(const device_t *d, int inst) device_context_inst(const device_t *d, int inst)
{ {
device_context_common(d, inst); device_context_common(d, inst);
} }
void void
device_context_restore(void) device_context_restore(void)
{ {
memcpy(&device_current, &device_prev, sizeof(device_context_t)); memcpy(&device_current, &device_prev, sizeof(device_context_t));
} }
static void * static void *
device_add_common(const device_t *d, const device_t *cd, void *p, int inst) device_add_common(const device_t *d, const device_t *cd, void *p, int inst)
{ {
void *priv = NULL; void *priv = NULL;
int c; int c;
for (c = 0; c < 256; c++) { for (c = 0; c < 256; c++) {
if (!inst && (devices[c] == (device_t *) d)) { if (!inst && (devices[c] == (device_t *) d)) {
device_log("DEVICE: device already exists!\n"); device_log("DEVICE: device already exists!\n");
return (NULL); return (NULL);
} }
if (devices[c] == NULL) break; if (devices[c] == NULL)
break;
} }
if (c >= DEVICE_MAX) if (c >= DEVICE_MAX)
fatal("DEVICE: too many devices\n"); fatal("DEVICE: too many devices\n");
/* Do this so that a chained device_add will not identify the same ID /* Do this so that a chained device_add will not identify the same ID
its master device is already trying to assign. */ its master device is already trying to assign. */
devices[c] = (device_t *)d; devices[c] = (device_t *) d;
if (p == NULL) { if (p == NULL) {
memcpy(&device_prev, &device_current, sizeof(device_context_t)); memcpy(&device_prev, &device_current, sizeof(device_context_t));
device_set_context(&device_current, cd, inst); device_set_context(&device_current, cd, inst);
if (d->init != NULL) { if (d->init != NULL) {
priv = d->init(d); priv = d->init(d);
if (priv == NULL) { if (priv == NULL) {
if (d->name) if (d->name)
device_log("DEVICE: device '%s' init failed\n", d->name); device_log("DEVICE: device '%s' init failed\n", d->name);
else else
device_log("DEVICE: device init failed\n"); device_log("DEVICE: device init failed\n");
devices[c] = NULL; devices[c] = NULL;
device_priv[c] = NULL; device_priv[c] = NULL;
return(NULL); return (NULL);
} }
} }
if (d->name) if (d->name)
device_log("DEVICE: device '%s' init successful\n", d->name); device_log("DEVICE: device '%s' init successful\n", d->name);
else else
device_log("DEVICE: device init successful\n"); device_log("DEVICE: device init successful\n");
memcpy(&device_current, &device_prev, sizeof(device_context_t)); memcpy(&device_current, &device_prev, sizeof(device_context_t));
device_priv[c] = priv; device_priv[c] = priv;
} else } else
device_priv[c] = p; device_priv[c] = p;
return(priv); return (priv);
} }
char * char *
device_get_internal_name(const device_t *d) device_get_internal_name(const device_t *d)
{ {
if (d == NULL) if (d == NULL)
return ""; return "";
return (char *) d->internal_name; return (char *) d->internal_name;
} }
void * void *
device_add(const device_t *d) device_add(const device_t *d)
{ {
return device_add_common(d, d, NULL, 0); return device_add_common(d, d, NULL, 0);
} }
/* For devices that do not have an init function (internal video etc.) */ /* For devices that do not have an init function (internal video etc.) */
void void
device_add_ex(const device_t *d, void *priv) device_add_ex(const device_t *d, void *priv)
@@ -219,14 +206,12 @@ device_add_ex(const device_t *d, void *priv)
device_add_common(d, d, priv, 0); device_add_common(d, d, priv, 0);
} }
void * void *
device_add_inst(const device_t *d, int inst) device_add_inst(const device_t *d, int inst)
{ {
return device_add_common(d, d, NULL, inst); return device_add_common(d, d, NULL, inst);
} }
/* For devices that do not have an init function (internal video etc.) */ /* For devices that do not have an init function (internal video etc.) */
void void
device_add_inst_ex(const device_t *d, void *priv, int inst) device_add_inst_ex(const device_t *d, void *priv, int inst)
@@ -234,7 +219,6 @@ device_add_inst_ex(const device_t *d, void *priv, int inst)
device_add_common(d, d, priv, inst); device_add_common(d, d, priv, inst);
} }
/* These four are to add a device with another device's context - will be /* These four are to add a device with another device's context - will be
used to add machines' internal devices. */ used to add machines' internal devices. */
void * void *
@@ -243,7 +227,6 @@ device_cadd(const device_t *d, const device_t *cd)
return device_add_common(d, cd, NULL, 0); return device_add_common(d, cd, NULL, 0);
} }
/* For devices that do not have an init function (internal video etc.) */ /* For devices that do not have an init function (internal video etc.) */
void void
device_cadd_ex(const device_t *d, const device_t *cd, void *priv) device_cadd_ex(const device_t *d, const device_t *cd, void *priv)
@@ -251,14 +234,12 @@ device_cadd_ex(const device_t *d, const device_t *cd, void *priv)
device_add_common(d, cd, priv, 0); device_add_common(d, cd, priv, 0);
} }
void * void *
device_cadd_inst(const device_t *d, const device_t *cd, int inst) device_cadd_inst(const device_t *d, const device_t *cd, int inst)
{ {
return device_add_common(d, cd, NULL, inst); return device_add_common(d, cd, NULL, inst);
} }
/* For devices that do not have an init function (internal video etc.) */ /* For devices that do not have an init function (internal video etc.) */
void void
device_cadd_inst_ex(const device_t *d, const device_t *cd, void *priv, int inst) device_cadd_inst_ex(const device_t *d, const device_t *cd, void *priv, int inst)
@@ -266,173 +247,164 @@ device_cadd_inst_ex(const device_t *d, const device_t *cd, void *priv, int inst)
device_add_common(d, cd, priv, inst); device_add_common(d, cd, priv, inst);
} }
void void
device_close_all(void) device_close_all(void)
{ {
int c; int c;
for (c = (DEVICE_MAX - 1); c >= 0; c--) { for (c = (DEVICE_MAX - 1); c >= 0; c--) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if (devices[c]->name) if (devices[c]->name)
device_log("Closing device: \"%s\"...\n", devices[c]->name); device_log("Closing device: \"%s\"...\n", devices[c]->name);
if (devices[c]->close != NULL) if (devices[c]->close != NULL)
devices[c]->close(device_priv[c]); devices[c]->close(device_priv[c]);
devices[c] = device_priv[c] = NULL; devices[c] = device_priv[c] = NULL;
} }
} }
} }
void void
device_reset_all(void) device_reset_all(void)
{ {
int c; int c;
for (c = 0; c < DEVICE_MAX; c++) { for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if (devices[c]->reset != NULL) if (devices[c]->reset != NULL)
devices[c]->reset(device_priv[c]); devices[c]->reset(device_priv[c]);
} }
} }
} }
/* Reset all attached PCI devices - needed for PCI turbo reset control. */ /* Reset all attached PCI devices - needed for PCI turbo reset control. */
void void
device_reset_all_pci(void) device_reset_all_pci(void)
{ {
int c; int c;
for (c=0; c<DEVICE_MAX; c++) { for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if ((devices[c]->reset != NULL) && (devices[c]->flags & DEVICE_PCI)) if ((devices[c]->reset != NULL) && (devices[c]->flags & DEVICE_PCI))
devices[c]->reset(device_priv[c]); devices[c]->reset(device_priv[c]);
} }
} }
} }
void * void *
device_get_priv(const device_t *d) device_get_priv(const device_t *d)
{ {
int c; int c;
for (c = 0; c < DEVICE_MAX; c++) { for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if (devices[c] == d) if (devices[c] == d)
return(device_priv[c]); return (device_priv[c]);
} }
} }
return(NULL); return (NULL);
} }
int int
device_available(const device_t *d) device_available(const device_t *d)
{ {
device_config_t *config = NULL; device_config_t *config = NULL;
device_config_bios_t *bios = NULL; device_config_bios_t *bios = NULL;
int bf, roms_present = 0; int bf, roms_present = 0;
int i = 0; int i = 0;
if (d != NULL) { if (d != NULL) {
config = (device_config_t *) d->config; config = (device_config_t *) d->config;
if (config != NULL) { if (config != NULL) {
while (config->type != -1) { while (config->type != -1) {
if (config->type == CONFIG_BIOS) { if (config->type == CONFIG_BIOS) {
bios = (device_config_bios_t *) config->bios; bios = (device_config_bios_t *) config->bios;
/* Go through the ROM's in the device configuration. */ /* Go through the ROM's in the device configuration. */
while (bios->files_no != 0) { while (bios->files_no != 0) {
i = 0; i = 0;
for (bf = 0; bf < bios->files_no; bf++) for (bf = 0; bf < bios->files_no; bf++)
i += !!rom_present((char *) bios->files[bf]); i += !!rom_present((char *) bios->files[bf]);
if (i == bios->files_no) if (i == bios->files_no)
roms_present++; roms_present++;
bios++; bios++;
} }
return(roms_present ? -1 : 0); return (roms_present ? -1 : 0);
} }
config++; config++;
} }
} }
/* No CONFIG_BIOS field present, use the classic available(). */ /* No CONFIG_BIOS field present, use the classic available(). */
if (d->available != NULL) if (d->available != NULL)
return(d->available()); return (d->available());
else else
return(1); return (1);
} }
/* A NULL device is never available. */ /* A NULL device is never available. */
return(0); return (0);
} }
int int
device_has_config(const device_t *d) device_has_config(const device_t *d)
{ {
int c = 0; int c = 0;
device_config_t *config; device_config_t *config;
if (d == NULL) if (d == NULL)
return 0; return 0;
if (d->config == NULL) if (d->config == NULL)
return 0; return 0;
config = (device_config_t *) d->config; config = (device_config_t *) d->config;
while (config->type != -1) { while (config->type != -1) {
if (config->type != CONFIG_MAC) if (config->type != CONFIG_MAC)
c++; c++;
config++; config++;
} }
return (c > 0) ? 1 : 0; return (c > 0) ? 1 : 0;
} }
int int
device_poll(const device_t *d, int x, int y, int z, int b) device_poll(const device_t *d, int x, int y, int z, int b)
{ {
int c; int c;
for (c = 0; c < DEVICE_MAX; c++) { for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if (devices[c] == d) { if (devices[c] == d) {
if (devices[c]->poll) if (devices[c]->poll)
return(devices[c]->poll(x, y, z, b, device_priv[c])); return (devices[c]->poll(x, y, z, b, device_priv[c]));
} }
} }
} }
return(0); return (0);
} }
void void
device_register_pci_slot(const device_t *d, int device, int type, int inta, int intb, int intc, int intd) device_register_pci_slot(const device_t *d, int device, int type, int inta, int intb, int intc, int intd)
{ {
int c; int c;
for (c = 0; c < DEVICE_MAX; c++) { for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if (devices[c] == d) { if (devices[c] == d) {
if (devices[c]->register_pci_slot) if (devices[c]->register_pci_slot)
devices[c]->register_pci_slot(device, type, inta, intb, intc, intd, device_priv[c]); devices[c]->register_pci_slot(device, type, inta, intb, intc, intd, device_priv[c]);
return; return;
} }
} }
} }
return; return;
} }
void void
device_get_name(const device_t *d, int bus, char *name) device_get_name(const device_t *d, int bus, char *name)
{ {
@@ -440,344 +412,342 @@ device_get_name(const device_t *d, int bus, char *name)
char *tname, pbus[8] = { 0 }; char *tname, pbus[8] = { 0 };
if (d == NULL) if (d == NULL)
return; return;
name[0] = 0x00; name[0] = 0x00;
if (bus) { if (bus) {
if (d->flags & DEVICE_ISA) if (d->flags & DEVICE_ISA)
sbus = (d->flags & DEVICE_AT) ? "ISA16" : "ISA"; sbus = (d->flags & DEVICE_AT) ? "ISA16" : "ISA";
else if (d->flags & DEVICE_CBUS) else if (d->flags & DEVICE_CBUS)
sbus = "C-BUS"; sbus = "C-BUS";
else if (d->flags & DEVICE_MCA) else if (d->flags & DEVICE_MCA)
sbus = "MCA"; sbus = "MCA";
else if (d->flags & DEVICE_EISA) else if (d->flags & DEVICE_EISA)
sbus = "EISA"; sbus = "EISA";
else if (d->flags & DEVICE_VLB) else if (d->flags & DEVICE_VLB)
sbus = "VLB"; sbus = "VLB";
else if (d->flags & DEVICE_PCI) else if (d->flags & DEVICE_PCI)
sbus = "PCI"; sbus = "PCI";
else if (d->flags & DEVICE_AGP) else if (d->flags & DEVICE_AGP)
sbus = "AGP"; sbus = "AGP";
else if (d->flags & DEVICE_AC97) else if (d->flags & DEVICE_AC97)
sbus = "AMR"; sbus = "AMR";
else if (d->flags & DEVICE_COM) else if (d->flags & DEVICE_COM)
sbus = "COM"; sbus = "COM";
else if (d->flags & DEVICE_LPT) else if (d->flags & DEVICE_LPT)
sbus = "LPT"; sbus = "LPT";
if (sbus != NULL) { if (sbus != NULL) {
/* First concatenate [<Bus>] before the device's name. */ /* First concatenate [<Bus>] before the device's name. */
strcat(name, "["); strcat(name, "[");
strcat(name, sbus); strcat(name, sbus);
strcat(name, "] "); strcat(name, "] ");
/* Then change string from ISA16 to ISA if applicable. */ /* Then change string from ISA16 to ISA if applicable. */
if (!strcmp(sbus, "ISA16")) if (!strcmp(sbus, "ISA16"))
sbus = "ISA"; sbus = "ISA";
else if (!strcmp(sbus, "COM")|| !strcmp(sbus, "LPT")) { else if (!strcmp(sbus, "COM") || !strcmp(sbus, "LPT")) {
sbus = NULL; sbus = NULL;
strcat(name, d->name); strcat(name, d->name);
return; return;
} }
/* Generate the bus string with parentheses. */ /* Generate the bus string with parentheses. */
strcat(pbus, "("); strcat(pbus, "(");
strcat(pbus, sbus); strcat(pbus, sbus);
strcat(pbus, ")"); strcat(pbus, ")");
/* Allocate the temporary device name string and set it to all zeroes. */ /* Allocate the temporary device name string and set it to all zeroes. */
tname = (char *) malloc(strlen(d->name) + 1); tname = (char *) malloc(strlen(d->name) + 1);
memset(tname, 0x00, strlen(d->name) + 1); memset(tname, 0x00, strlen(d->name) + 1);
/* First strip the bus string with parentheses. */ /* First strip the bus string with parentheses. */
fbus = strstr(d->name, pbus); fbus = strstr(d->name, pbus);
if (fbus == d->name) if (fbus == d->name)
strcat(tname, d->name + strlen(pbus) + 1); strcat(tname, d->name + strlen(pbus) + 1);
else if (fbus == NULL) else if (fbus == NULL)
strcat(tname, d->name); strcat(tname, d->name);
else { else {
strncat(tname, d->name, fbus - d->name - 1); strncat(tname, d->name, fbus - d->name - 1);
strcat(tname, fbus + strlen(pbus)); strcat(tname, fbus + strlen(pbus));
} }
/* Then also strip the bus string with parentheses. */ /* Then also strip the bus string with parentheses. */
fbus = strstr(tname, sbus); fbus = strstr(tname, sbus);
if (fbus == tname) if (fbus == tname)
strcat(name, tname + strlen(sbus) + 1); strcat(name, tname + strlen(sbus) + 1);
/* Special case to not strip the "oPCI" from "Ensoniq AudioPCI" or /* Special case to not strip the "oPCI" from "Ensoniq AudioPCI" or
the "-ISA" from "AMD PCnet-ISA". */ the "-ISA" from "AMD PCnet-ISA". */
else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-')) else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-'))
strcat(name, tname); strcat(name, tname);
else { else {
strncat(name, tname, fbus - tname - 1); strncat(name, tname, fbus - tname - 1);
strcat(name, fbus + strlen(sbus)); strcat(name, fbus + strlen(sbus));
} }
/* Free the temporary device name string. */ /* Free the temporary device name string. */
free(tname); free(tname);
tname = NULL; tname = NULL;
} else } else
strcat(name, d->name); strcat(name, d->name);
} else } else
strcat(name, d->name); strcat(name, d->name);
} }
void void
device_speed_changed(void) device_speed_changed(void)
{ {
int c; int c;
for (c = 0; c < DEVICE_MAX; c++) { for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if (devices[c]->speed_changed != NULL) if (devices[c]->speed_changed != NULL)
devices[c]->speed_changed(device_priv[c]); devices[c]->speed_changed(device_priv[c]);
} }
} }
sound_speed_changed(); sound_speed_changed();
} }
void void
device_force_redraw(void) device_force_redraw(void)
{ {
int c; int c;
for (c = 0; c < DEVICE_MAX; c++) { for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) { if (devices[c] != NULL) {
if (devices[c]->force_redraw != NULL) if (devices[c]->force_redraw != NULL)
devices[c]->force_redraw(device_priv[c]); devices[c]->force_redraw(device_priv[c]);
} }
} }
} }
const char * const char *
device_get_config_string(const char *s) device_get_config_string(const char *s)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_string((char *) device_current.name, (char *) s, (char *) c->default_string)); return (config_get_string((char *) device_current.name, (char *) s, (char *) c->default_string));
c++; c++;
} }
return(NULL); return (NULL);
} }
int int
device_get_config_int(const char *s) device_get_config_int(const char *s)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_int((char *) device_current.name, (char *) s, c->default_int)); return (config_get_int((char *) device_current.name, (char *) s, c->default_int));
c++; c++;
} }
return(0); return (0);
} }
int int
device_get_config_int_ex(const char *s, int def) device_get_config_int_ex(const char *s, int def)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_int((char *) device_current.name, (char *) s, def)); return (config_get_int((char *) device_current.name, (char *) s, def));
c++; c++;
} }
return(def); return (def);
} }
int int
device_get_config_hex16(const char *s) device_get_config_hex16(const char *s)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_hex16((char *) device_current.name, (char *) s, c->default_int)); return (config_get_hex16((char *) device_current.name, (char *) s, c->default_int));
c++; c++;
} }
return(0); return (0);
} }
int int
device_get_config_hex20(const char *s) device_get_config_hex20(const char *s)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_hex20((char *) device_current.name, (char *) s, c->default_int)); return (config_get_hex20((char *) device_current.name, (char *) s, c->default_int));
c++; c++;
} }
return(0); return (0);
} }
int int
device_get_config_mac(const char *s, int def) device_get_config_mac(const char *s, int def)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_mac((char *) device_current.name, (char *) s, def)); return (config_get_mac((char *) device_current.name, (char *) s, def));
c++; c++;
} }
return(def); return (def);
} }
void void
device_set_config_int(const char *s, int val) device_set_config_int(const char *s, int val)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) { if (!strcmp(s, c->name)) {
config_set_int((char *) device_current.name, (char *) s, val); config_set_int((char *) device_current.name, (char *) s, val);
break; break;
} }
c++; c++;
} }
} }
void void
device_set_config_hex16(const char *s, int val) device_set_config_hex16(const char *s, int val)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) { if (!strcmp(s, c->name)) {
config_set_hex16((char *) device_current.name, (char *) s, val); config_set_hex16((char *) device_current.name, (char *) s, val);
break; break;
} }
c++; c++;
} }
} }
void void
device_set_config_hex20(const char *s, int val) device_set_config_hex20(const char *s, int val)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) { if (!strcmp(s, c->name)) {
config_set_hex20((char *) device_current.name, (char *) s, val); config_set_hex20((char *) device_current.name, (char *) s, val);
break; break;
} }
c++; c++;
} }
} }
void void
device_set_config_mac(const char *s, int val) device_set_config_mac(const char *s, int val)
{ {
const device_config_t *c = device_current.dev->config; const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) { if (!strcmp(s, c->name)) {
config_set_mac((char *) device_current.name, (char *) s, val); config_set_mac((char *) device_current.name, (char *) s, val);
break; break;
} }
c++; c++;
} }
} }
int int
device_is_valid(const device_t *device, int m) device_is_valid(const device_t *device, int m)
{ {
if (device == NULL) return(1); if (device == NULL)
return (1);
if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16)) return(0); if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16))
return (0);
if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS)) return(0); if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS))
return (0);
if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA)) return(0); if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA))
return (0);
if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA)) return(0); if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA))
return (0);
if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA)) return(0); if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA))
return (0);
if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB)) return(0); if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB))
return (0);
if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI)) return(0); if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI))
return (0);
if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP)) return(0); if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP))
return (0);
if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2)) return(0); if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2))
return (0);
if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97)) return(0); if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97))
return (0);
return(1); return (1);
} }
int int
machine_get_config_int(char *s) machine_get_config_int(char *s)
{ {
const device_t *d = machine_getdevice(machine); const device_t *d = machine_getdevice(machine);
const device_config_t *c; const device_config_t *c;
if (d == NULL) return(0); if (d == NULL)
return (0);
c = d->config; c = d->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_int((char *)d->name, s, c->default_int)); return (config_get_int((char *) d->name, s, c->default_int));
c++; c++;
} }
return(0); return (0);
} }
char * char *
machine_get_config_string(char *s) machine_get_config_string(char *s)
{ {
const device_t *d = machine_getdevice(machine); const device_t *d = machine_getdevice(machine);
const device_config_t *c; const device_config_t *c;
if (d == NULL) return(0); if (d == NULL)
return (0);
c = d->config; c = d->config;
while (c && c->type != -1) { while (c && c->type != -1) {
if (! strcmp(s, c->name)) if (!strcmp(s, c->name))
return(config_get_string((char *)d->name, s, (char *)c->default_string)); return (config_get_string((char *) d->name, s, (char *) c->default_string));
c++; c++;
} }
return(NULL); return (NULL);
} }

1794
src/dma.c

File diff suppressed because it is too large Load Diff

View File

@@ -21,31 +21,35 @@
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/fifo8.h> #include <86box/fifo8.h>
void fifo8_create(Fifo8 *fifo, uint32_t capacity) void
fifo8_create(Fifo8 *fifo, uint32_t capacity)
{ {
fifo->data = (uint8_t *)malloc(capacity); fifo->data = (uint8_t *) malloc(capacity);
memset(fifo->data, 0, capacity); memset(fifo->data, 0, capacity);
fifo->capacity = capacity; fifo->capacity = capacity;
fifo->head = 0; fifo->head = 0;
fifo->num = 0; fifo->num = 0;
} }
void fifo8_destroy(Fifo8 *fifo) void
fifo8_destroy(Fifo8 *fifo)
{ {
if (fifo->data) { if (fifo->data) {
free(fifo->data); free(fifo->data);
fifo->data = NULL; fifo->data = NULL;
} }
} }
void fifo8_push(Fifo8 *fifo, uint8_t data) void
fifo8_push(Fifo8 *fifo, uint8_t data)
{ {
assert(fifo->num < fifo->capacity); assert(fifo->num < fifo->capacity);
fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data; fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data;
fifo->num++; fifo->num++;
} }
void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num) void
fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num)
{ {
uint32_t start, avail; uint32_t start, avail;
@@ -64,7 +68,8 @@ void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num)
fifo->num += num; fifo->num += num;
} }
uint8_t fifo8_pop(Fifo8 *fifo) uint8_t
fifo8_pop(Fifo8 *fifo)
{ {
uint8_t ret; uint8_t ret;
@@ -75,41 +80,47 @@ uint8_t fifo8_pop(Fifo8 *fifo)
return ret; return ret;
} }
const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num) const uint8_t *
fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num)
{ {
uint8_t *ret; uint8_t *ret;
assert(max > 0 && max <= fifo->num); assert(max > 0 && max <= fifo->num);
*num = MIN(fifo->capacity - fifo->head, max); *num = MIN(fifo->capacity - fifo->head, max);
ret = &fifo->data[fifo->head]; ret = &fifo->data[fifo->head];
fifo->head += *num; fifo->head += *num;
fifo->head %= fifo->capacity; fifo->head %= fifo->capacity;
fifo->num -= *num; fifo->num -= *num;
return ret; return ret;
} }
void fifo8_reset(Fifo8 *fifo) void
fifo8_reset(Fifo8 *fifo)
{ {
fifo->num = 0; fifo->num = 0;
fifo->head = 0; fifo->head = 0;
} }
int fifo8_is_empty(Fifo8 *fifo) int
fifo8_is_empty(Fifo8 *fifo)
{ {
return (fifo->num == 0); return (fifo->num == 0);
} }
int fifo8_is_full(Fifo8 *fifo) int
fifo8_is_full(Fifo8 *fifo)
{ {
return (fifo->num == fifo->capacity); return (fifo->num == fifo->capacity);
} }
uint32_t fifo8_num_free(Fifo8 *fifo) uint32_t
fifo8_num_free(Fifo8 *fifo)
{ {
return fifo->capacity - fifo->num; return fifo->capacity - fifo->num;
} }
uint32_t fifo8_num_used(Fifo8 *fifo) uint32_t
fifo8_num_used(Fifo8 *fifo)
{ {
return fifo->num; return fifo->num;
} }

View File

@@ -25,7 +25,7 @@
# include <unistd.h> # include <unistd.h>
# else # else
# include <io.h> # include <io.h>
# define ssize_t long # define ssize_t long
# define strtok_r(a, b, c) strtok_s(a, b, c) # define strtok_r(a, b, c) strtok_s(a, b, c)
# endif # endif
# include <winsock2.h> # include <winsock2.h>
@@ -121,8 +121,8 @@ typedef struct _gdbstub_client_ {
struct sockaddr_in addr; struct sockaddr_in addr;
char packet[16384], response[16384]; char packet[16384], response[16384];
int has_packet: 1, first_packet_received: 1, ida_mode: 1, waiting_stop: 1, int has_packet : 1, first_packet_received : 1, ida_mode : 1, waiting_stop : 1,
packet_pos, response_pos; packet_pos, response_pos;
event_t *processed_event, *response_event; event_t *processed_event, *response_event;
@@ -162,7 +162,7 @@ gdbstub_log(const char *fmt, ...)
static x86seg *segment_regs[] = { &cpu_state.seg_cs, &cpu_state.seg_ss, &cpu_state.seg_ds, &cpu_state.seg_es, &cpu_state.seg_fs, &cpu_state.seg_gs }; static x86seg *segment_regs[] = { &cpu_state.seg_cs, &cpu_state.seg_ss, &cpu_state.seg_ds, &cpu_state.seg_es, &cpu_state.seg_fs, &cpu_state.seg_gs };
static uint32_t *cr_regs[] = { &cpu_state.CR0.l, &cr2, &cr3, &cr4 }; static uint32_t *cr_regs[] = { &cpu_state.CR0.l, &cr2, &cr3, &cr4 };
static void *fpu_regs[] = { &cpu_state.npxc, &cpu_state.npxs, NULL, &x87_pc_seg, &x87_pc_off, &x87_op_seg, &x87_op_off }; static void *fpu_regs[] = { &cpu_state.npxc, &cpu_state.npxs, NULL, &x87_pc_seg, &x87_pc_off, &x87_op_seg, &x87_op_off };
static char target_xml[] = /* QEMU gdb-xml/i386-32bit.xml with modifications (described in comments) */ static char target_xml[] = /* QEMU gdb-xml/i386-32bit.xml with modifications (described in comments) */
// clang-format off // clang-format off
"<?xml version=\"1.0\"?>" "<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"

View File

@@ -245,7 +245,7 @@ ini_close(ini_t ini)
sec = (section_t *) list->next; sec = (section_t *) list->next;
while (sec != NULL) { while (sec != NULL) {
ns = (section_t *) sec->list.next; ns = (section_t *) sec->list.next;
ent = (entry_t *) sec->entry_head.next; ent = (entry_t *) sec->entry_head.next;
while (ent != NULL) { while (ent != NULL) {

614
src/io.c
View File

@@ -30,286 +30,268 @@
#include "cpu.h" #include "cpu.h"
#include <86box/m_amstrad.h> #include <86box/m_amstrad.h>
#define NPORTS 65536 /* PC/AT supports 64K ports */
#define NPORTS 65536 /* PC/AT supports 64K ports */
typedef struct _io_ { typedef struct _io_ {
uint8_t (*inb)(uint16_t addr, void *priv); uint8_t (*inb)(uint16_t addr, void *priv);
uint16_t (*inw)(uint16_t addr, void *priv); uint16_t (*inw)(uint16_t addr, void *priv);
uint32_t (*inl)(uint16_t addr, void *priv); uint32_t (*inl)(uint16_t addr, void *priv);
void (*outb)(uint16_t addr, uint8_t val, void *priv); void (*outb)(uint16_t addr, uint8_t val, void *priv);
void (*outw)(uint16_t addr, uint16_t val, void *priv); void (*outw)(uint16_t addr, uint16_t val, void *priv);
void (*outl)(uint16_t addr, uint32_t val, void *priv); void (*outl)(uint16_t addr, uint32_t val, void *priv);
void *priv; void *priv;
struct _io_ *prev, *next; struct _io_ *prev, *next;
} io_t; } io_t;
typedef struct { typedef struct {
uint8_t enable; uint8_t enable;
uint16_t base, size; uint16_t base, size;
void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv),
*priv; *priv;
} io_trap_t; } io_trap_t;
int initialized = 0; int initialized = 0;
io_t *io[NPORTS], *io_last[NPORTS]; io_t *io[NPORTS], *io_last[NPORTS];
#ifdef ENABLE_IO_LOG #ifdef ENABLE_IO_LOG
int io_do_log = ENABLE_IO_LOG; int io_do_log = ENABLE_IO_LOG;
static void static void
io_log(const char *fmt, ...) io_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (io_do_log) { if (io_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define io_log(fmt, ...) # define io_log(fmt, ...)
#endif #endif
void void
io_init(void) io_init(void)
{ {
int c; int c;
io_t *p, *q; io_t *p, *q;
if (!initialized) { if (!initialized) {
for (c=0; c<NPORTS; c++) for (c = 0; c < NPORTS; c++)
io[c] = io_last[c] = NULL; io[c] = io_last[c] = NULL;
initialized = 1; initialized = 1;
} }
for (c=0; c<NPORTS; c++) { for (c = 0; c < NPORTS; c++) {
if (io_last[c]) { if (io_last[c]) {
/* Port c has at least one handler. */ /* Port c has at least one handler. */
p = io_last[c]; p = io_last[c];
/* After this loop, p will have the pointer to the first handler. */ /* After this loop, p will have the pointer to the first handler. */
while (p) { while (p) {
q = p->prev; q = p->prev;
free(p); free(p);
p = q; p = q;
} }
p = NULL; p = NULL;
} }
/* io[c] should be NULL. */ /* io[c] should be NULL. */
io[c] = io_last[c] = NULL; io[c] = io_last[c] = NULL;
} }
} }
void void
io_sethandler_common(uint16_t base, int size, io_sethandler_common(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv, int step) void *priv, int step)
{ {
int c; int c;
io_t *p, *q = NULL; io_t *p, *q = NULL;
for (c = 0; c < size; c += step) { for (c = 0; c < size; c += step) {
p = io_last[base + c]; p = io_last[base + c];
q = (io_t *) malloc(sizeof(io_t)); q = (io_t *) malloc(sizeof(io_t));
memset(q, 0, sizeof(io_t)); memset(q, 0, sizeof(io_t));
if (p) { if (p) {
p->next = q; p->next = q;
q->prev = p; q->prev = p;
} else { } else {
io[base + c] = q; io[base + c] = q;
q->prev = NULL; q->prev = NULL;
} }
q->inb = inb; q->inb = inb;
q->inw = inw; q->inw = inw;
q->inl = inl; q->inl = inl;
q->outb = outb; q->outb = outb;
q->outw = outw; q->outw = outw;
q->outl = outl; q->outl = outl;
q->priv = priv; q->priv = priv;
q->next = NULL; q->next = NULL;
io_last[base + c] = q; io_last[base + c] = q;
} }
} }
void void
io_removehandler_common(uint16_t base, int size, io_removehandler_common(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv, int step) void *priv, int step)
{ {
int c; int c;
io_t *p, *q; io_t *p, *q;
for (c = 0; c < size; c += step) { for (c = 0; c < size; c += step) {
p = io[base + c]; p = io[base + c];
if (!p) if (!p)
continue; continue;
while(p) { while (p) {
q = p->next; q = p->next;
if ((p->inb == inb) && (p->inw == inw) && if ((p->inb == inb) && (p->inw == inw) && (p->inl == inl) && (p->outb == outb) && (p->outw == outw) && (p->outl == outl) && (p->priv == priv)) {
(p->inl == inl) && (p->outb == outb) && if (p->prev)
(p->outw == outw) && (p->outl == outl) && p->prev->next = p->next;
(p->priv == priv)) { else
if (p->prev) io[base + c] = p->next;
p->prev->next = p->next; if (p->next)
else p->next->prev = p->prev;
io[base + c] = p->next; else
if (p->next) io_last[base + c] = p->prev;
p->next->prev = p->prev; free(p);
else p = NULL;
io_last[base + c] = p->prev; break;
free(p); }
p = NULL; p = q;
break; }
}
p = q;
}
} }
} }
void void
io_handler_common(int set, uint16_t base, int size, io_handler_common(int set, uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv, int step) void *priv, int step)
{ {
if (set) if (set)
io_sethandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, step); io_sethandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, step);
else else
io_removehandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, step); io_removehandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, step);
} }
void void
io_sethandler(uint16_t base, int size, io_sethandler(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv) void *priv)
{ {
io_sethandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 1); io_sethandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 1);
} }
void void
io_removehandler(uint16_t base, int size, io_removehandler(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv) void *priv)
{ {
io_removehandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 1); io_removehandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 1);
} }
void void
io_handler(int set, uint16_t base, int size, io_handler(int set, uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv) void *priv)
{ {
io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 1); io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 1);
} }
void void
io_sethandler_interleaved(uint16_t base, int size, io_sethandler_interleaved(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv) void *priv)
{ {
io_sethandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 2); io_sethandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 2);
} }
void void
io_removehandler_interleaved(uint16_t base, int size, io_removehandler_interleaved(uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv) void *priv)
{ {
io_removehandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 2); io_removehandler_common(base, size, inb, inw, inl, outb, outw, outl, priv, 2);
} }
void void
io_handler_interleaved(int set, uint16_t base, int size, io_handler_interleaved(int set, uint16_t base, int size,
uint8_t (*inb)(uint16_t addr, void *priv), uint8_t (*inb)(uint16_t addr, void *priv),
uint16_t (*inw)(uint16_t addr, void *priv), uint16_t (*inw)(uint16_t addr, void *priv),
uint32_t (*inl)(uint16_t addr, void *priv), uint32_t (*inl)(uint16_t addr, void *priv),
void (*outb)(uint16_t addr, uint8_t val, void *priv), void (*outb)(uint16_t addr, uint8_t val, void *priv),
void (*outw)(uint16_t addr, uint16_t val, void *priv), void (*outw)(uint16_t addr, uint16_t val, void *priv),
void (*outl)(uint16_t addr, uint32_t val, void *priv), void (*outl)(uint16_t addr, uint32_t val, void *priv),
void *priv) void *priv)
{ {
io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 2); io_handler_common(set, base, size, inb, inw, inl, outb, outw, outl, priv, 2);
} }
uint8_t uint8_t
inb(uint16_t port) inb(uint16_t port)
{ {
uint8_t ret = 0xff; uint8_t ret = 0xff;
io_t *p, *q; io_t *p, *q;
int found = 0; int found = 0;
int qfound = 0; int qfound = 0;
p = io[port]; p = io[port];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->inb) { if (p->inb) {
ret &= p->inb(port, p->priv); ret &= p->inb(port, p->priv);
found |= 1; found |= 1;
qfound++; qfound++;
} }
p = q; p = q;
} }
if (amstrad_latch & 0x80000000) { if (amstrad_latch & 0x80000000) {
@@ -322,41 +304,40 @@ inb(uint16_t port)
} }
if (!found) if (!found)
cycles -= io_delay; cycles -= io_delay;
/* TriGem 486-BIOS MHz output. */ /* TriGem 486-BIOS MHz output. */
/* if (port == 0x1ed) /* if (port == 0x1ed)
ret = 0xfe; */ ret = 0xfe; */
io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
return(ret); return (ret);
} }
void void
outb(uint16_t port, uint8_t val) outb(uint16_t port, uint8_t val)
{ {
io_t *p, *q; io_t *p, *q;
int found = 0; int found = 0;
int qfound = 0; int qfound = 0;
p = io[port]; p = io[port];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->outb) { if (p->outb) {
p->outb(port, val, p->priv); p->outb(port, val, p->priv);
found |= 1; found |= 1;
qfound++; qfound++;
} }
p = q; p = q;
} }
if (!found) { if (!found) {
cycles -= io_delay; cycles -= io_delay;
#ifdef USE_DYNAREC #ifdef USE_DYNAREC
if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed))) if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed)))
update_tsc(); update_tsc();
#endif #endif
} }
@@ -365,41 +346,40 @@ outb(uint16_t port, uint8_t val)
return; return;
} }
uint16_t uint16_t
inw(uint16_t port) inw(uint16_t port)
{ {
io_t *p, *q; io_t *p, *q;
uint16_t ret = 0xffff; uint16_t ret = 0xffff;
int found = 0; int found = 0;
int qfound = 0; int qfound = 0;
uint8_t ret8[2]; uint8_t ret8[2];
int i = 0; int i = 0;
p = io[port]; p = io[port];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->inw) { if (p->inw) {
ret &= p->inw(port, p->priv); ret &= p->inw(port, p->priv);
found |= 2; found |= 2;
qfound++; qfound++;
} }
p = q; p = q;
} }
ret8[0] = ret & 0xff; ret8[0] = ret & 0xff;
ret8[1] = (ret >> 8) & 0xff; ret8[1] = (ret >> 8) & 0xff;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
p = io[(port + i) & 0xffff]; p = io[(port + i) & 0xffff];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->inb && !p->inw) { if (p->inb && !p->inw) {
ret8[i] &= p->inb(port + i, p->priv); ret8[i] &= p->inb(port + i, p->priv);
found |= 1; found |= 1;
qfound++; qfound++;
} }
p = q; p = q;
} }
} }
ret = (ret8[1] << 8) | ret8[0]; ret = (ret8[1] << 8) | ret8[0];
@@ -413,51 +393,50 @@ inw(uint16_t port)
} }
if (!found) if (!found)
cycles -= io_delay; cycles -= io_delay;
io_log("[%04X:%08X] (%i, %i, %04i) in w(%04X) = %04X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); io_log("[%04X:%08X] (%i, %i, %04i) in w(%04X) = %04X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
return ret; return ret;
} }
void void
outw(uint16_t port, uint16_t val) outw(uint16_t port, uint16_t val)
{ {
io_t *p, *q; io_t *p, *q;
int found = 0; int found = 0;
int qfound = 0; int qfound = 0;
int i = 0; int i = 0;
p = io[port]; p = io[port];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->outw) { if (p->outw) {
p->outw(port, val, p->priv); p->outw(port, val, p->priv);
found |= 2; found |= 2;
qfound++; qfound++;
} }
p = q; p = q;
} }
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
p = io[(port + i) & 0xffff]; p = io[(port + i) & 0xffff];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->outb && !p->outw) { if (p->outb && !p->outw) {
p->outb(port + i, val >> (i << 3), p->priv); p->outb(port + i, val >> (i << 3), p->priv);
found |= 1; found |= 1;
qfound++; qfound++;
} }
p = q; p = q;
} }
} }
if (!found) { if (!found) {
cycles -= io_delay; cycles -= io_delay;
#ifdef USE_DYNAREC #ifdef USE_DYNAREC
if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed))) if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed)))
update_tsc(); update_tsc();
#endif #endif
} }
@@ -466,32 +445,31 @@ outw(uint16_t port, uint16_t val)
return; return;
} }
uint32_t uint32_t
inl(uint16_t port) inl(uint16_t port)
{ {
io_t *p, *q; io_t *p, *q;
uint32_t ret = 0xffffffff; uint32_t ret = 0xffffffff;
uint16_t ret16[2]; uint16_t ret16[2];
uint8_t ret8[4]; uint8_t ret8[4];
int found = 0; int found = 0;
int qfound = 0; int qfound = 0;
int i = 0; int i = 0;
p = io[port]; p = io[port];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->inl) { if (p->inl) {
ret &= p->inl(port, p->priv); ret &= p->inl(port, p->priv);
found |= 4; found |= 4;
qfound++; qfound++;
} }
p = q; p = q;
} }
ret16[0] = ret & 0xffff; ret16[0] = ret & 0xffff;
ret16[1] = (ret >> 16) & 0xffff; ret16[1] = (ret >> 16) & 0xffff;
p = io[port & 0xffff]; p = io[port & 0xffff];
while (p) { while (p) {
q = p->next; q = p->next;
if (p->inw && !p->inl) { if (p->inw && !p->inl) {
@@ -519,16 +497,16 @@ inl(uint16_t port)
ret8[2] = (ret >> 16) & 0xff; ret8[2] = (ret >> 16) & 0xff;
ret8[3] = (ret >> 24) & 0xff; ret8[3] = (ret >> 24) & 0xff;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
p = io[(port + i) & 0xffff]; p = io[(port + i) & 0xffff];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->inb && !p->inw && !p->inl) { if (p->inb && !p->inw && !p->inl) {
ret8[i] &= p->inb(port + i, p->priv); ret8[i] &= p->inb(port + i, p->priv);
found |= 1; found |= 1;
qfound++; qfound++;
} }
p = q; p = q;
} }
} }
ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0];
@@ -542,66 +520,65 @@ inl(uint16_t port)
} }
if (!found) if (!found)
cycles -= io_delay; cycles -= io_delay;
io_log("[%04X:%08X] (%i, %i, %04i) in l(%04X) = %08X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); io_log("[%04X:%08X] (%i, %i, %04i) in l(%04X) = %08X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
return ret; return ret;
} }
void void
outl(uint16_t port, uint32_t val) outl(uint16_t port, uint32_t val)
{ {
io_t *p, *q; io_t *p, *q;
int found = 0; int found = 0;
int qfound = 0; int qfound = 0;
int i = 0; int i = 0;
p = io[port]; p = io[port];
if (p) { if (p) {
while(p) { while (p) {
q = p->next; q = p->next;
if (p->outl) { if (p->outl) {
p->outl(port, val, p->priv); p->outl(port, val, p->priv);
found |= 4; found |= 4;
qfound++; qfound++;
} }
p = q; p = q;
} }
} }
for (i = 0; i < 4; i += 2) { for (i = 0; i < 4; i += 2) {
p = io[(port + i) & 0xffff]; p = io[(port + i) & 0xffff];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->outw && !p->outl) { if (p->outw && !p->outl) {
p->outw(port + i, val >> (i << 3), p->priv); p->outw(port + i, val >> (i << 3), p->priv);
found |= 2; found |= 2;
qfound++; qfound++;
} }
p = q; p = q;
} }
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
p = io[(port + i) & 0xffff]; p = io[(port + i) & 0xffff];
while(p) { while (p) {
q = p->next; q = p->next;
if (p->outb && !p->outw && !p->outl) { if (p->outb && !p->outw && !p->outl) {
p->outb(port + i, val >> (i << 3), p->priv); p->outb(port + i, val >> (i << 3), p->priv);
found |= 1; found |= 1;
qfound++; qfound++;
} }
p = q; p = q;
} }
} }
if (!found) { if (!found) {
cycles -= io_delay; cycles -= io_delay;
#ifdef USE_DYNAREC #ifdef USE_DYNAREC
if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed))) if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed)))
update_tsc(); update_tsc();
#endif #endif
} }
@@ -610,7 +587,6 @@ outl(uint16_t port, uint32_t val)
return; return;
} }
static uint8_t static uint8_t
io_trap_readb(uint16_t addr, void *priv) io_trap_readb(uint16_t addr, void *priv)
{ {
@@ -619,7 +595,6 @@ io_trap_readb(uint16_t addr, void *priv)
return 0xff; return 0xff;
} }
static uint16_t static uint16_t
io_trap_readw(uint16_t addr, void *priv) io_trap_readw(uint16_t addr, void *priv)
{ {
@@ -628,7 +603,6 @@ io_trap_readw(uint16_t addr, void *priv)
return 0xffff; return 0xffff;
} }
static uint32_t static uint32_t
io_trap_readl(uint16_t addr, void *priv) io_trap_readl(uint16_t addr, void *priv)
{ {
@@ -637,7 +611,6 @@ io_trap_readl(uint16_t addr, void *priv)
return 0xffffffff; return 0xffffffff;
} }
static void static void
io_trap_writeb(uint16_t addr, uint8_t val, void *priv) io_trap_writeb(uint16_t addr, uint8_t val, void *priv)
{ {
@@ -645,7 +618,6 @@ io_trap_writeb(uint16_t addr, uint8_t val, void *priv)
trap->func(1, addr, 1, val, trap->priv); trap->func(1, addr, 1, val, trap->priv);
} }
static void static void
io_trap_writew(uint16_t addr, uint16_t val, void *priv) io_trap_writew(uint16_t addr, uint16_t val, void *priv)
{ {
@@ -653,7 +625,6 @@ io_trap_writew(uint16_t addr, uint16_t val, void *priv)
trap->func(2, addr, 1, val, trap->priv); trap->func(2, addr, 1, val, trap->priv);
} }
static void static void
io_trap_writel(uint16_t addr, uint32_t val, void *priv) io_trap_writel(uint16_t addr, uint32_t val, void *priv)
{ {
@@ -661,61 +632,58 @@ io_trap_writel(uint16_t addr, uint32_t val, void *priv)
trap->func(4, addr, 1, val, trap->priv); trap->func(4, addr, 1, val, trap->priv);
} }
void * void *
io_trap_add(void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv), io_trap_add(void (*func)(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv),
void *priv) void *priv)
{ {
/* Instantiate new I/O trap. */ /* Instantiate new I/O trap. */
io_trap_t *trap = (io_trap_t *) malloc(sizeof(io_trap_t)); io_trap_t *trap = (io_trap_t *) malloc(sizeof(io_trap_t));
trap->enable = 0; trap->enable = 0;
trap->base = trap->size = 0; trap->base = trap->size = 0;
trap->func = func; trap->func = func;
trap->priv = priv; trap->priv = priv;
return trap; return trap;
} }
void void
io_trap_remap(void *handle, int enable, uint16_t addr, uint16_t size) io_trap_remap(void *handle, int enable, uint16_t addr, uint16_t size)
{ {
io_trap_t *trap = (io_trap_t *) handle; io_trap_t *trap = (io_trap_t *) handle;
if (!trap) if (!trap)
return; return;
io_log("I/O: Remapping trap from %04X-%04X (enable %d) to %04X-%04X (enable %d)\n", io_log("I/O: Remapping trap from %04X-%04X (enable %d) to %04X-%04X (enable %d)\n",
trap->base, trap->base + trap->size - 1, trap->enable, addr, addr + size - 1, enable); trap->base, trap->base + trap->size - 1, trap->enable, addr, addr + size - 1, enable);
/* Remove old I/O mapping. */ /* Remove old I/O mapping. */
if (trap->enable && trap->size) { if (trap->enable && trap->size) {
io_removehandler(trap->base, trap->size, io_removehandler(trap->base, trap->size,
io_trap_readb, io_trap_readw, io_trap_readl, io_trap_readb, io_trap_readw, io_trap_readl,
io_trap_writeb, io_trap_writew, io_trap_writel, io_trap_writeb, io_trap_writew, io_trap_writel,
trap); trap);
} }
/* Set trap enable flag, base address and size. */ /* Set trap enable flag, base address and size. */
trap->enable = !!enable; trap->enable = !!enable;
trap->base = addr; trap->base = addr;
trap->size = size; trap->size = size;
/* Add new I/O mapping. */ /* Add new I/O mapping. */
if (trap->enable && trap->size) { if (trap->enable && trap->size) {
io_sethandler(trap->base, trap->size, io_sethandler(trap->base, trap->size,
io_trap_readb, io_trap_readw, io_trap_readl, io_trap_readb, io_trap_readw, io_trap_readl,
io_trap_writeb, io_trap_writew, io_trap_writel, io_trap_writeb, io_trap_writew, io_trap_writel,
trap); trap);
} }
} }
void void
io_trap_remove(void *handle) io_trap_remove(void *handle)
{ {
io_trap_t *trap = (io_trap_t *) handle; io_trap_t *trap = (io_trap_t *) handle;
if (!trap) if (!trap)
return; return;
/* Unmap I/O trap before freeing it. */ /* Unmap I/O trap before freeing it. */
io_trap_remap(trap, 0, 0, 0); io_trap_remap(trap, 0, 0, 0);

View File

@@ -28,32 +28,28 @@
#include <86box/mem.h> #include <86box/mem.h>
#include <86box/chipset.h> #include <86box/chipset.h>
typedef struct { typedef struct {
uint8_t dummy; uint8_t dummy;
} ioapic_t; } ioapic_t;
#ifdef ENABLE_IOAPIC_LOG #ifdef ENABLE_IOAPIC_LOG
int ioapic_do_log = ENABLE_IOAPIC_LOG; int ioapic_do_log = ENABLE_IOAPIC_LOG;
static void static void
ioapic_log(const char *fmt, ...) ioapic_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (ioapic_do_log) { if (ioapic_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define ioapic_log(fmt, ...) # define ioapic_log(fmt, ...)
#endif #endif
static void static void
ioapic_write(uint16_t port, uint8_t val, void *priv) ioapic_write(uint16_t port, uint8_t val, void *priv)
{ {
@@ -61,50 +57,47 @@ ioapic_write(uint16_t port, uint8_t val, void *priv)
/* target POST FF, issued by Award before jumping to the bootloader */ /* target POST FF, issued by Award before jumping to the bootloader */
if (val != 0xff) if (val != 0xff)
return; return;
ioapic_log("IOAPIC: Caught POST %02X\n", val); ioapic_log("IOAPIC: Caught POST %02X\n", val);
/* The _MP_ table must be located in the BIOS area, the EBDA, or the last 1k of conventional /* The _MP_ table must be located in the BIOS area, the EBDA, or the last 1k of conventional
memory; at a 16-byte boundary in all cases. Award writes both tables to the BIOS area. */ memory; at a 16-byte boundary in all cases. Award writes both tables to the BIOS area. */
for (addr = 0xf0000; addr <= 0xfffff; addr += 16) { for (addr = 0xf0000; addr <= 0xfffff; addr += 16) {
/* check signature for the _MP_ table (Floating Point Structure) */ /* check signature for the _MP_ table (Floating Point Structure) */
if (mem_readl_phys(addr) != 0x5f504d5f) /* ASCII "_MP_" */ if (mem_readl_phys(addr) != 0x5f504d5f) /* ASCII "_MP_" */
continue; continue;
/* read and check pointer to the PCMP table (Configuration Table) */ /* read and check pointer to the PCMP table (Configuration Table) */
pcmp = mem_readl_phys(addr + 4); pcmp = mem_readl_phys(addr + 4);
if ((pcmp < 0xf0000) || (pcmp > 0xfffff) || (mem_readl_phys(pcmp) != 0x504d4350)) /* ASCII "PCMP" */ if ((pcmp < 0xf0000) || (pcmp > 0xfffff) || (mem_readl_phys(pcmp) != 0x504d4350)) /* ASCII "PCMP" */
continue; continue;
/* patch over the signature on both tables */ /* patch over the signature on both tables */
ioapic_log("IOAPIC: Patching _MP_ [%08x] and PCMP [%08x] tables\n", addr, pcmp); ioapic_log("IOAPIC: Patching _MP_ [%08x] and PCMP [%08x] tables\n", addr, pcmp);
ram[addr] = ram[addr + 1] = ram[addr + 2] = ram[addr + 3] = 0xff; ram[addr] = ram[addr + 1] = ram[addr + 2] = ram[addr + 3] = 0xff;
ram[pcmp] = ram[pcmp + 1] = ram[pcmp + 2] = ram[pcmp + 3] = 0xff; ram[pcmp] = ram[pcmp + 1] = ram[pcmp + 2] = ram[pcmp + 3] = 0xff;
break; break;
} }
} }
static void static void
ioapic_reset(ioapic_t *dev) ioapic_reset(ioapic_t *dev)
{ {
} }
static void static void
ioapic_close(void *priv) ioapic_close(void *priv)
{ {
ioapic_t *dev = (ioapic_t *) priv; ioapic_t *dev = (ioapic_t *) priv;
io_removehandler(0x80, 1, io_removehandler(0x80, 1,
NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL); NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL);
free(dev); free(dev);
} }
static void * static void *
ioapic_init(const device_t *info) ioapic_init(const device_t *info)
{ {
@@ -114,22 +107,21 @@ ioapic_init(const device_t *info)
ioapic_reset(dev); ioapic_reset(dev);
io_sethandler(0x80, 1, io_sethandler(0x80, 1,
NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL); NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL);
return dev; return dev;
} }
const device_t ioapic_device = { const device_t ioapic_device = {
.name = "I/O Advanced Programmable Interrupt Controller", .name = "I/O Advanced Programmable Interrupt Controller",
.internal_name = "ioapic", .internal_name = "ioapic",
.flags = DEVICE_AT, .flags = DEVICE_AT,
.local = 0, .local = 0,
.init = ioapic_init, .init = ioapic_init,
.close = ioapic_close, .close = ioapic_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

View File

@@ -34,17 +34,14 @@
#include <86box/version.h> #include <86box/version.h>
#include <86box/log.h> #include <86box/log.h>
#ifndef RELEASE_BUILD #ifndef RELEASE_BUILD
typedef struct typedef struct
{ {
char buff[1024], *dev_name; char buff[1024], *dev_name;
int seen, suppr_seen; int seen, suppr_seen;
} log_t; } log_t;
extern FILE *stdlog; /* file to log output to */
extern FILE *stdlog; /* file to log output to */
void void
log_set_suppr_seen(void *priv, int suppr_seen) log_set_suppr_seen(void *priv, int suppr_seen)
@@ -54,7 +51,6 @@ log_set_suppr_seen(void *priv, int suppr_seen)
log->suppr_seen = suppr_seen; log->suppr_seen = suppr_seen;
} }
void void
log_set_dev_name(void *priv, char *dev_name) log_set_dev_name(void *priv, char *dev_name)
{ {
@@ -63,19 +59,17 @@ log_set_dev_name(void *priv, char *dev_name)
log->dev_name = dev_name; log->dev_name = dev_name;
} }
static void static void
log_copy(log_t *log, char *dest, const char *src, size_t dest_size) log_copy(log_t *log, char *dest, const char *src, size_t dest_size)
{ {
memset(dest, 0x00, dest_size * sizeof(char)); memset(dest, 0x00, dest_size * sizeof(char));
if (log && log->dev_name && strcmp(log->dev_name, "")) { if (log && log->dev_name && strcmp(log->dev_name, "")) {
strcat(dest, log->dev_name); strcat(dest, log->dev_name);
strcat(dest, ": "); strcat(dest, ": ");
} }
strcat(dest, src); strcat(dest, src);
} }
/* /*
* Log something to the logfile or stdout. * Log something to the logfile or stdout.
* *
@@ -87,50 +81,49 @@ void
log_out(void *priv, const char *fmt, va_list ap) log_out(void *priv, const char *fmt, va_list ap)
{ {
log_t *log = (log_t *) priv; log_t *log = (log_t *) priv;
char temp[1024], fmt2[1024]; char temp[1024], fmt2[1024];
if (log == NULL) if (log == NULL)
return; return;
if (strcmp(fmt, "") == 0) if (strcmp(fmt, "") == 0)
return; return;
if (stdlog == NULL) { if (stdlog == NULL) {
if (log_path[0] != '\0') { if (log_path[0] != '\0') {
stdlog = plat_fopen(log_path, "w"); stdlog = plat_fopen(log_path, "w");
if (stdlog == NULL) if (stdlog == NULL)
stdlog = stdout; stdlog = stdout;
} else } else
stdlog = stdout; stdlog = stdout;
} }
vsprintf(temp, fmt, ap); vsprintf(temp, fmt, ap);
if (log->suppr_seen && ! strcmp(log->buff, temp)) if (log->suppr_seen && !strcmp(log->buff, temp))
log->seen++; log->seen++;
else { else {
if (log->suppr_seen && log->seen) { if (log->suppr_seen && log->seen) {
log_copy(log, fmt2, "*** %d repeats ***\n", 1024); log_copy(log, fmt2, "*** %d repeats ***\n", 1024);
fprintf(stdlog, fmt2, log->seen); fprintf(stdlog, fmt2, log->seen);
} }
log->seen = 0; log->seen = 0;
strcpy(log->buff, temp); strcpy(log->buff, temp);
log_copy(log, fmt2, temp, 1024); log_copy(log, fmt2, temp, 1024);
fprintf(stdlog, fmt2, ap); fprintf(stdlog, fmt2, ap);
} }
fflush(stdlog); fflush(stdlog);
} }
void void
log_fatal(void *priv, const char *fmt, ...) log_fatal(void *priv, const char *fmt, ...)
{ {
log_t *log = (log_t *) priv; log_t *log = (log_t *) priv;
char temp[1024], fmt2[1024]; char temp[1024], fmt2[1024];
va_list ap; va_list ap;
if (log == NULL) if (log == NULL)
return; return;
va_start(ap, fmt); va_start(ap, fmt);
log_copy(log, fmt2, fmt, 1024); log_copy(log, fmt2, fmt, 1024);
@@ -140,7 +133,6 @@ log_fatal(void *priv, const char *fmt, ...)
exit(-1); exit(-1);
} }
void * void *
log_open(char *dev_name) log_open(char *dev_name)
{ {
@@ -148,13 +140,12 @@ log_open(char *dev_name)
memset(log, 0, sizeof(log_t)); memset(log, 0, sizeof(log_t));
log->dev_name = dev_name; log->dev_name = dev_name;
log->suppr_seen = 1; log->suppr_seen = 1;
return (void *) log; return (void *) log;
} }
void void
log_close(void *priv) log_close(void *priv)
{ {

View File

@@ -26,21 +26,22 @@
machine_status_t machine_status; machine_status_t machine_status;
void void
machine_status_init() { machine_status_init()
{
for (size_t i = 0; i < FDD_NUM; ++i) { for (size_t i = 0; i < FDD_NUM; ++i) {
machine_status.fdd[i].empty = (strlen(floppyfns[i]) == 0); machine_status.fdd[i].empty = (strlen(floppyfns[i]) == 0);
machine_status.fdd[i].active = false; machine_status.fdd[i].active = false;
} }
for (size_t i = 0; i < CDROM_NUM; ++i) { for (size_t i = 0; i < CDROM_NUM; ++i) {
machine_status.cdrom[i].empty = cdrom[i].host_drive != 200 || (strlen(cdrom[i].image_path) == 0); machine_status.cdrom[i].empty = cdrom[i].host_drive != 200 || (strlen(cdrom[i].image_path) == 0);
machine_status.cdrom[i].active = false; machine_status.cdrom[i].active = false;
} }
for (size_t i = 0; i < ZIP_NUM; i++) { for (size_t i = 0; i < ZIP_NUM; i++) {
machine_status.zip[i].empty = (strlen(zip_drives[i].image_path) == 0); machine_status.zip[i].empty = (strlen(zip_drives[i].image_path) == 0);
machine_status.zip[i].active = false; machine_status.zip[i].active = false;
} }
for (size_t i = 0; i < MO_NUM; i++) { for (size_t i = 0; i < MO_NUM; i++) {
machine_status.mo[i].empty = (strlen(mo_drives[i].image_path) == 0); machine_status.mo[i].empty = (strlen(mo_drives[i].image_path) == 0);
machine_status.mo[i].active = false; machine_status.mo[i].active = false;
} }
@@ -52,6 +53,6 @@ machine_status_init() {
for (size_t i = 0; i < NET_CARD_MAX; i++) { for (size_t i = 0; i < NET_CARD_MAX; i++) {
machine_status.net[i].active = false; machine_status.net[i].active = false;
machine_status.net[i].empty = !network_is_connected(i); machine_status.net[i].empty = !network_is_connected(i);
} }
} }

128
src/mca.c
View File

@@ -5,99 +5,105 @@
#include <86box/io.h> #include <86box/io.h>
#include <86box/mca.h> #include <86box/mca.h>
void (*mca_card_write[8])(int addr, uint8_t val, void *priv);
void (*mca_card_write[8])(int addr, uint8_t val, void *priv); uint8_t (*mca_card_read[8])(int addr, void *priv);
uint8_t (*mca_card_read[8])(int addr, void *priv);
uint8_t (*mca_card_feedb[8])(void *priv); uint8_t (*mca_card_feedb[8])(void *priv);
void (*mca_card_reset[8])(void *priv); void (*mca_card_reset[8])(void *priv);
void *mca_priv[8]; void *mca_priv[8];
static int mca_index; static int mca_index;
static int mca_nr_cards; static int mca_nr_cards;
void
void mca_init(int nr_cards) mca_init(int nr_cards)
{ {
int c; int c;
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
mca_card_read[c] = NULL; mca_card_read[c] = NULL;
mca_card_write[c] = NULL; mca_card_write[c] = NULL;
mca_card_reset[c] = NULL; mca_card_reset[c] = NULL;
mca_priv[c] = NULL; mca_priv[c] = NULL;
} }
mca_index = 0; mca_index = 0;
mca_nr_cards = nr_cards; mca_nr_cards = nr_cards;
} }
void mca_set_index(int index) void
mca_set_index(int index)
{ {
mca_index = index; mca_index = index;
} }
uint8_t mca_read(uint16_t port) uint8_t
mca_read(uint16_t port)
{ {
if (mca_index >= mca_nr_cards) if (mca_index >= mca_nr_cards)
return 0xff; return 0xff;
if (!mca_card_read[mca_index]) if (!mca_card_read[mca_index])
return 0xff; return 0xff;
return mca_card_read[mca_index](port, mca_priv[mca_index]); return mca_card_read[mca_index](port, mca_priv[mca_index]);
} }
uint8_t mca_read_index(uint16_t port, int index) uint8_t
mca_read_index(uint16_t port, int index)
{ {
if (mca_index >= mca_nr_cards) if (mca_index >= mca_nr_cards)
return 0xff; return 0xff;
if (!mca_card_read[index]) if (!mca_card_read[index])
return 0xff; return 0xff;
return mca_card_read[index](port, mca_priv[index]); return mca_card_read[index](port, mca_priv[index]);
} }
int mca_get_nr_cards(void) int
mca_get_nr_cards(void)
{ {
return mca_nr_cards; return mca_nr_cards;
} }
void mca_write(uint16_t port, uint8_t val) void
mca_write(uint16_t port, uint8_t val)
{ {
if (mca_index >= mca_nr_cards) if (mca_index >= mca_nr_cards)
return; return;
if (mca_card_write[mca_index]) if (mca_card_write[mca_index])
mca_card_write[mca_index](port, val, mca_priv[mca_index]); mca_card_write[mca_index](port, val, mca_priv[mca_index]);
} }
uint8_t mca_feedb(void) uint8_t
mca_feedb(void)
{ {
if (mca_card_feedb[mca_index]) if (mca_card_feedb[mca_index])
return !!(mca_card_feedb[mca_index](mca_priv[mca_index])); return !!(mca_card_feedb[mca_index](mca_priv[mca_index]));
else else
return 0; return 0;
} }
void mca_reset(void) void
mca_reset(void)
{ {
int c; int c;
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
if (mca_card_reset[c]) if (mca_card_reset[c])
mca_card_reset[c](mca_priv[c]); mca_card_reset[c](mca_priv[c]);
} }
} }
void
void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), uint8_t (*feedb)(void *priv), void (*reset)(void *priv), void *priv) mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), uint8_t (*feedb)(void *priv), void (*reset)(void *priv), void *priv)
{ {
int c; int c;
for (c = 0; c < mca_nr_cards; c++) { for (c = 0; c < mca_nr_cards; c++) {
if (!mca_card_read[c] && !mca_card_write[c]) { if (!mca_card_read[c] && !mca_card_write[c]) {
mca_card_read[c] = read; mca_card_read[c] = read;
mca_card_write[c] = write; mca_card_write[c] = write;
mca_card_feedb[c] = feedb; mca_card_feedb[c] = feedb;
mca_card_reset[c] = reset; mca_card_reset[c] = reset;
mca_priv[c] = priv; mca_priv[c] = priv;
return; return;
} }
} }
} }

View File

@@ -8,18 +8,17 @@
#include <86box/io.h> #include <86box/io.h>
#include <86box/nmi.h> #include <86box/nmi.h>
int nmi_mask; int nmi_mask;
void
void nmi_write(uint16_t port, uint8_t val, void *p) nmi_write(uint16_t port, uint8_t val, void *p)
{ {
nmi_mask = val & 0x80; nmi_mask = val & 0x80;
} }
void
void nmi_init(void) nmi_init(void)
{ {
io_sethandler(0x00a0, 0x000f, NULL, NULL, NULL, nmi_write, NULL, NULL, NULL); io_sethandler(0x00a0, 0x000f, NULL, NULL, NULL, nmi_write, NULL, NULL, NULL);
nmi_mask = 0; nmi_mask = 0;
} }

220
src/nvr.c
View File

@@ -62,107 +62,100 @@
#include <86box/plat.h> #include <86box/plat.h>
#include <86box/nvr.h> #include <86box/nvr.h>
int nvr_dosave; /* NVR is dirty, needs saved */
int nvr_dosave; /* NVR is dirty, needs saved */ static int8_t days_in_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static int8_t days_in_month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
static struct tm intclk; static struct tm intclk;
static nvr_t *saved_nvr = NULL; static nvr_t *saved_nvr = NULL;
#ifdef ENABLE_NVR_LOG #ifdef ENABLE_NVR_LOG
int nvr_do_log = ENABLE_NVR_LOG; int nvr_do_log = ENABLE_NVR_LOG;
static void static void
nvr_log(const char *fmt, ...) nvr_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (nvr_do_log) { if (nvr_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define nvr_log(fmt, ...) # define nvr_log(fmt, ...)
#endif #endif
/* Determine whether or not the year is leap. */ /* Determine whether or not the year is leap. */
int int
nvr_is_leap(int year) nvr_is_leap(int year)
{ {
if (year % 400 == 0) return(1); if (year % 400 == 0)
if (year % 100 == 0) return(0); return (1);
if (year % 4 == 0) return(1); if (year % 100 == 0)
return (0);
if (year % 4 == 0)
return (1);
return(0); return (0);
} }
/* Determine the days in the current month. */ /* Determine the days in the current month. */
int int
nvr_get_days(int month, int year) nvr_get_days(int month, int year)
{ {
if (month != 2) if (month != 2)
return(days_in_month[month - 1]); return (days_in_month[month - 1]);
return(nvr_is_leap(year) ? 29 : 28); return (nvr_is_leap(year) ? 29 : 28);
} }
/* One more second has passed, update the internal clock. */ /* One more second has passed, update the internal clock. */
void void
rtc_tick(void) rtc_tick(void)
{ {
/* Ping the internal clock. */ /* Ping the internal clock. */
if (++intclk.tm_sec == 60) { if (++intclk.tm_sec == 60) {
intclk.tm_sec = 0; intclk.tm_sec = 0;
if (++intclk.tm_min == 60) { if (++intclk.tm_min == 60) {
intclk.tm_min = 0; intclk.tm_min = 0;
if (++intclk.tm_hour == 24) { if (++intclk.tm_hour == 24) {
intclk.tm_hour = 0; intclk.tm_hour = 0;
if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon, if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon, intclk.tm_year) + 1)) {
intclk.tm_year) + 1)) { intclk.tm_mday = 1;
intclk.tm_mday = 1; if (++intclk.tm_mon == 13) {
if (++intclk.tm_mon == 13) { intclk.tm_mon = 1;
intclk.tm_mon = 1; intclk.tm_year++;
intclk.tm_year++; }
} }
} }
} }
}
} }
} }
/* This is the RTC one-second timer. */ /* This is the RTC one-second timer. */
static void static void
onesec_timer(void *priv) onesec_timer(void *priv)
{ {
nvr_t *nvr = (nvr_t *)priv; nvr_t *nvr = (nvr_t *) priv;
int is_at; int is_at;
if (++nvr->onesec_cnt >= 100) { if (++nvr->onesec_cnt >= 100) {
/* Update the internal clock. */ /* Update the internal clock. */
is_at = IS_AT(machine); is_at = IS_AT(machine);
if (!is_at) if (!is_at)
rtc_tick(); rtc_tick();
/* Update the RTC device if needed. */ /* Update the RTC device if needed. */
if (nvr->tick != NULL) if (nvr->tick != NULL)
(*nvr->tick)(nvr); (*nvr->tick)(nvr);
nvr->onesec_cnt = 0; nvr->onesec_cnt = 0;
} }
timer_advance_u64(&nvr->onesec_time, (uint64_t)(10000ULL * TIMER_USEC)); timer_advance_u64(&nvr->onesec_time, (uint64_t) (10000ULL * TIMER_USEC));
} }
/* Initialize the generic NVRAM/RTC device. */ /* Initialize the generic NVRAM/RTC device. */
void void
nvr_init(nvr_t *nvr) nvr_init(nvr_t *nvr)
@@ -170,18 +163,18 @@ nvr_init(nvr_t *nvr)
int c; int c;
/* Set up the NVR file's name. */ /* Set up the NVR file's name. */
c = strlen(machine_get_internal_name()) + 5; c = strlen(machine_get_internal_name()) + 5;
nvr->fn = (char *)malloc(c + 1); nvr->fn = (char *) malloc(c + 1);
sprintf(nvr->fn, "%s.nvr", machine_get_internal_name()); sprintf(nvr->fn, "%s.nvr", machine_get_internal_name());
/* Initialize the internal clock as needed. */ /* Initialize the internal clock as needed. */
memset(&intclk, 0x00, sizeof(intclk)); memset(&intclk, 0x00, sizeof(intclk));
if (time_sync & TIME_SYNC_ENABLED) { if (time_sync & TIME_SYNC_ENABLED) {
nvr_time_sync(); nvr_time_sync();
} else { } else {
/* Reset the internal clock to 1980/01/01 00:00. */ /* Reset the internal clock to 1980/01/01 00:00. */
intclk.tm_mon = 1; intclk.tm_mon = 1;
intclk.tm_year = 1980; intclk.tm_year = 1980;
} }
/* Set up our timer. */ /* Set up our timer. */
@@ -194,10 +187,9 @@ nvr_init(nvr_t *nvr)
saved_nvr = nvr; saved_nvr = nvr;
/* Try to load the saved data. */ /* Try to load the saved data. */
(void)nvr_load(); (void) nvr_load();
} }
/* Get path to the NVR folder. */ /* Get path to the NVR folder. */
char * char *
nvr_path(char *str) nvr_path(char *str)
@@ -210,17 +202,16 @@ nvr_path(char *str)
strcat(temp, NVR_PATH); strcat(temp, NVR_PATH);
/* Create the directory if needed. */ /* Create the directory if needed. */
if (! plat_dir_check(temp)) if (!plat_dir_check(temp))
plat_dir_create(temp); plat_dir_create(temp);
/* Now append the actual filename. */ /* Now append the actual filename. */
path_slash(temp); path_slash(temp);
strcat(temp, str); strcat(temp, str);
return(temp); return (temp);
} }
/* /*
* Load an NVR from file. * Load an NVR from file.
* *
@@ -235,53 +226,52 @@ nvr_path(char *str)
int int
nvr_load(void) nvr_load(void)
{ {
char *path; char *path;
FILE *fp; FILE *fp;
uint8_t regs[NVR_MAXSIZE] = { 0 }; uint8_t regs[NVR_MAXSIZE] = { 0 };
/* Make sure we have been initialized. */ /* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0); if (saved_nvr == NULL)
return (0);
/* Clear out any old data. */ /* Clear out any old data. */
memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs)); memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs));
/* Set the defaults. */ /* Set the defaults. */
if (saved_nvr->reset != NULL) if (saved_nvr->reset != NULL)
saved_nvr->reset(saved_nvr); saved_nvr->reset(saved_nvr);
/* Load the (relevant) part of the NVR contents. */ /* Load the (relevant) part of the NVR contents. */
if (saved_nvr->size != 0) { if (saved_nvr->size != 0) {
path = nvr_path(saved_nvr->fn); path = nvr_path(saved_nvr->fn);
nvr_log("NVR: loading from '%s'\n", path); nvr_log("NVR: loading from '%s'\n", path);
fp = plat_fopen(path, "rb"); fp = plat_fopen(path, "rb");
saved_nvr->is_new = (fp == NULL); saved_nvr->is_new = (fp == NULL);
if (fp != NULL) { if (fp != NULL) {
memcpy(regs, saved_nvr->regs, sizeof(regs)); memcpy(regs, saved_nvr->regs, sizeof(regs));
/* Read NVR contents from file. */ /* Read NVR contents from file. */
if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) { if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) {
memcpy(saved_nvr->regs, regs, sizeof(regs)); memcpy(saved_nvr->regs, regs, sizeof(regs));
saved_nvr->is_new = 1; saved_nvr->is_new = 1;
}
(void) fclose(fp);
} }
(void)fclose(fp);
}
} else } else
saved_nvr->is_new = 1; saved_nvr->is_new = 1;
/* Get the local RTC running! */ /* Get the local RTC running! */
if (saved_nvr->start != NULL) if (saved_nvr->start != NULL)
saved_nvr->start(saved_nvr); saved_nvr->start(saved_nvr);
return(1); return (1);
} }
void void
nvr_set_ven_save(void (*ven_save)(void)) nvr_set_ven_save(void (*ven_save)(void))
{ {
saved_nvr->ven_save = ven_save; saved_nvr->ven_save = ven_save;
} }
/* Save the current NVR to a file. */ /* Save the current NVR to a file. */
int int
nvr_save(void) nvr_save(void)
@@ -290,94 +280,90 @@ nvr_save(void)
FILE *fp; FILE *fp;
/* Make sure we have been initialized. */ /* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0); if (saved_nvr == NULL)
return (0);
if (saved_nvr->size != 0) { if (saved_nvr->size != 0) {
path = nvr_path(saved_nvr->fn); path = nvr_path(saved_nvr->fn);
nvr_log("NVR: saving to '%s'\n", path); nvr_log("NVR: saving to '%s'\n", path);
fp = plat_fopen(path, "wb"); fp = plat_fopen(path, "wb");
if (fp != NULL) { if (fp != NULL) {
/* Save NVR contents to file. */ /* Save NVR contents to file. */
(void)fwrite(saved_nvr->regs, saved_nvr->size, 1, fp); (void) fwrite(saved_nvr->regs, saved_nvr->size, 1, fp);
fclose(fp); fclose(fp);
} }
} }
if (saved_nvr->ven_save) if (saved_nvr->ven_save)
saved_nvr->ven_save(); saved_nvr->ven_save();
/* Device is clean again. */ /* Device is clean again. */
nvr_dosave = 0; nvr_dosave = 0;
return(1); return (1);
} }
void void
nvr_close(void) nvr_close(void)
{ {
saved_nvr = NULL; saved_nvr = NULL;
} }
void void
nvr_time_sync(void) nvr_time_sync(void)
{ {
struct tm *tm; struct tm *tm;
time_t now; time_t now;
/* Get the current time of day, and convert to local time. */ /* Get the current time of day, and convert to local time. */
(void)time(&now); (void) time(&now);
if(time_sync & TIME_SYNC_UTC) if (time_sync & TIME_SYNC_UTC)
tm = gmtime(&now); tm = gmtime(&now);
else else
tm = localtime(&now); tm = localtime(&now);
/* Set the internal clock. */ /* Set the internal clock. */
nvr_time_set(tm); nvr_time_set(tm);
} }
/* Get current time from internal clock. */ /* Get current time from internal clock. */
void void
nvr_time_get(struct tm *tm) nvr_time_get(struct tm *tm)
{ {
uint8_t dom, mon, sum, wd; uint8_t dom, mon, sum, wd;
uint16_t cent, yr; uint16_t cent, yr;
tm->tm_sec = intclk.tm_sec; tm->tm_sec = intclk.tm_sec;
tm->tm_min = intclk.tm_min; tm->tm_min = intclk.tm_min;
tm->tm_hour = intclk.tm_hour; tm->tm_hour = intclk.tm_hour;
dom = intclk.tm_mday; dom = intclk.tm_mday;
mon = intclk.tm_mon; mon = intclk.tm_mon;
yr = (intclk.tm_year % 100); yr = (intclk.tm_year % 100);
cent = ((intclk.tm_year - yr) / 100) % 4; cent = ((intclk.tm_year - yr) / 100) % 4;
sum = dom+mon+yr+cent; sum = dom + mon + yr + cent;
wd = ((sum + 6) % 7); wd = ((sum + 6) % 7);
tm->tm_wday = wd; tm->tm_wday = wd;
tm->tm_mday = intclk.tm_mday; tm->tm_mday = intclk.tm_mday;
tm->tm_mon = (intclk.tm_mon - 1); tm->tm_mon = (intclk.tm_mon - 1);
tm->tm_year = (intclk.tm_year - 1900); tm->tm_year = (intclk.tm_year - 1900);
} }
/* Set internal clock time. */ /* Set internal clock time. */
void void
nvr_time_set(struct tm *tm) nvr_time_set(struct tm *tm)
{ {
intclk.tm_sec = tm->tm_sec; intclk.tm_sec = tm->tm_sec;
intclk.tm_min = tm->tm_min; intclk.tm_min = tm->tm_min;
intclk.tm_hour = tm->tm_hour; intclk.tm_hour = tm->tm_hour;
intclk.tm_wday = tm->tm_wday; intclk.tm_wday = tm->tm_wday;
intclk.tm_mday = tm->tm_mday; intclk.tm_mday = tm->tm_mday;
intclk.tm_mon = (tm->tm_mon + 1); intclk.tm_mon = (tm->tm_mon + 1);
intclk.tm_year = (tm->tm_year + 1900); intclk.tm_year = (tm->tm_year + 1900);
} }
/* Open or create a file in the NVR area. */ /* Open or create a file in the NVR area. */
FILE * FILE *
nvr_fopen(char *str, char *mode) nvr_fopen(char *str, char *mode)
{ {
return(plat_fopen(nvr_path(str), mode)); return (plat_fopen(nvr_path(str), mode));
} }

File diff suppressed because it is too large Load Diff

View File

@@ -49,70 +49,66 @@
#include <86box/nvr_ps2.h> #include <86box/nvr_ps2.h>
#include <86box/rom.h> #include <86box/rom.h>
typedef struct { typedef struct {
int addr; int addr;
uint8_t *ram; uint8_t *ram;
int size; int size;
char *fn; char *fn;
} ps2_nvr_t; } ps2_nvr_t;
static uint8_t static uint8_t
ps2_nvr_read(uint16_t port, void *priv) ps2_nvr_read(uint16_t port, void *priv)
{ {
ps2_nvr_t *nvr = (ps2_nvr_t *)priv; ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
uint8_t ret = 0xff; uint8_t ret = 0xff;
switch (port) { switch (port) {
case 0x74: case 0x74:
ret = nvr->addr & 0xff; ret = nvr->addr & 0xff;
break; break;
case 0x75: case 0x75:
ret = nvr->addr >> 8; ret = nvr->addr >> 8;
break; break;
case 0x76: case 0x76:
ret = nvr->ram[nvr->addr]; ret = nvr->ram[nvr->addr];
break; break;
} }
return(ret); return (ret);
} }
static void static void
ps2_nvr_write(uint16_t port, uint8_t val, void *priv) ps2_nvr_write(uint16_t port, uint8_t val, void *priv)
{ {
ps2_nvr_t *nvr = (ps2_nvr_t *)priv; ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
switch (port) { switch (port) {
case 0x74: case 0x74:
nvr->addr = (nvr->addr & 0x1f00) | val; nvr->addr = (nvr->addr & 0x1f00) | val;
break; break;
case 0x75: case 0x75:
nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8); nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8);
break; break;
case 0x76: case 0x76:
nvr->ram[nvr->addr] = val; nvr->ram[nvr->addr] = val;
break; break;
} }
} }
static void * static void *
ps2_nvr_init(const device_t *info) ps2_nvr_init(const device_t *info)
{ {
ps2_nvr_t *nvr; ps2_nvr_t *nvr;
FILE *f = NULL; FILE *f = NULL;
int c; int c;
nvr = (ps2_nvr_t *)malloc(sizeof(ps2_nvr_t)); nvr = (ps2_nvr_t *) malloc(sizeof(ps2_nvr_t));
memset(nvr, 0x00, sizeof(ps2_nvr_t)); memset(nvr, 0x00, sizeof(ps2_nvr_t));
if (info->local) if (info->local)
@@ -121,38 +117,37 @@ ps2_nvr_init(const device_t *info)
nvr->size = 8192; nvr->size = 8192;
/* Set up the NVR file's name. */ /* Set up the NVR file's name. */
c = strlen(machine_get_internal_name()) + 9; c = strlen(machine_get_internal_name()) + 9;
nvr->fn = (char *)malloc(c + 1); nvr->fn = (char *) malloc(c + 1);
sprintf(nvr->fn, "%s_sec.nvr", machine_get_internal_name()); sprintf(nvr->fn, "%s_sec.nvr", machine_get_internal_name());
io_sethandler(0x0074, 3, io_sethandler(0x0074, 3,
ps2_nvr_read,NULL,NULL, ps2_nvr_write,NULL,NULL, nvr); ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr);
f = nvr_fopen(nvr->fn, "rb"); f = nvr_fopen(nvr->fn, "rb");
nvr->ram = (uint8_t *)malloc(nvr->size); nvr->ram = (uint8_t *) malloc(nvr->size);
memset(nvr->ram, 0xff, nvr->size); memset(nvr->ram, 0xff, nvr->size);
if (f != NULL) { if (f != NULL) {
if (fread(nvr->ram, 1, nvr->size, f) != nvr->size) if (fread(nvr->ram, 1, nvr->size, f) != nvr->size)
fatal("ps2_nvr_init(): Error reading EEPROM data\n"); fatal("ps2_nvr_init(): Error reading EEPROM data\n");
fclose(f); fclose(f);
} }
return(nvr); return (nvr);
} }
static void static void
ps2_nvr_close(void *priv) ps2_nvr_close(void *priv)
{ {
ps2_nvr_t *nvr = (ps2_nvr_t *)priv; ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
FILE *f = NULL; FILE *f = NULL;
f = nvr_fopen(nvr->fn, "wb"); f = nvr_fopen(nvr->fn, "wb");
if (f != NULL) { if (f != NULL) {
(void)fwrite(nvr->ram, nvr->size, 1, f); (void) fwrite(nvr->ram, nvr->size, 1, f);
fclose(f); fclose(f);
} }
if (nvr->ram != NULL) if (nvr->ram != NULL)
@@ -162,29 +157,29 @@ ps2_nvr_close(void *priv)
} }
const device_t ps2_nvr_device = { const device_t ps2_nvr_device = {
.name = "PS/2 Secondary NVRAM for PS/2 Models 70-80", .name = "PS/2 Secondary NVRAM for PS/2 Models 70-80",
.internal_name = "ps2_nvr", .internal_name = "ps2_nvr",
.flags = 0, .flags = 0,
.local = 0, .local = 0,
.init = ps2_nvr_init, .init = ps2_nvr_init,
.close = ps2_nvr_close, .close = ps2_nvr_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t ps2_nvr_55ls_device = { const device_t ps2_nvr_55ls_device = {
.name = "PS/2 Secondary NVRAM for PS/2 Models 55LS-65SX", .name = "PS/2 Secondary NVRAM for PS/2 Models 55LS-65SX",
.internal_name = "ps2_nvr_55ls", .internal_name = "ps2_nvr_55ls",
.flags = 0, .flags = 0,
.local = 1, .local = 1,
.init = ps2_nvr_init, .init = ps2_nvr_init,
.close = ps2_nvr_close, .close = ps2_nvr_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

935
src/pci.c

File diff suppressed because it is too large Load Diff

View File

@@ -13,230 +13,225 @@ static uint8_t pci_regs[256];
static bar_t pci_bar[2]; static bar_t pci_bar[2];
static uint8_t interrupt_on = 0x00; static uint8_t interrupt_on = 0x00;
static uint8_t card = 0; static uint8_t card = 0;
static void pci_dummy_interrupt(int set) static void
pci_dummy_interrupt(int set)
{ {
if (set) if (set) {
{ pci_set_irq(card, pci_regs[0x3D]);
pci_set_irq(card, pci_regs[0x3D]); } else {
} pci_clear_irq(card, pci_regs[0x3D]);
else
{
pci_clear_irq(card, pci_regs[0x3D]);
}
}
static uint8_t pci_dummy_read(uint16_t Port, void *p)
{
uint8_t ret = 0;
switch(Port & 0x20)
{
case 0x00:
return 0x1A;
case 0x01:
return 0x07;
case 0x02:
return 0x0B;
case 0x03:
return 0xAB;
case 0x04:
return pci_regs[0x3C];
case 0x05:
return pci_regs[0x3D];
case 0x06:
ret = interrupt_on;
if (interrupt_on)
{
pci_dummy_interrupt(0);
interrupt_on = 0;
}
return ret;
default:
return 0x00;
}
}
static uint16_t pci_dummy_readw(uint16_t Port, void *p)
{
return pci_dummy_read(Port, p);
}
static uint32_t pci_dummy_readl(uint16_t Port, void *p)
{
return pci_dummy_read(Port, p);
}
static void pci_dummy_write(uint16_t Port, uint8_t Val, void *p)
{
switch(Port & 0x20)
{
case 0x06:
if (!interrupt_on)
{
interrupt_on = 1;
pci_dummy_interrupt(1);
}
return;
default:
return;
}
}
static void pci_dummy_writew(uint16_t Port, uint16_t Val, void *p)
{
pci_dummy_write(Port, Val & 0xFF, p);
}
static void pci_dummy_writel(uint16_t Port, uint32_t Val, void *p)
{
pci_dummy_write(Port, Val & 0xFF, p);
}
static void pci_dummy_io_remove(void)
{
io_removehandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL);
}
static void pci_dummy_io_set(void)
{
io_sethandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL);
}
static uint8_t pci_dummy_pci_read(int func, int addr, void *priv)
{
pclog("AB0B:071A: PCI_Read(%d, %04x)\n", func, addr);
switch(addr) {
case 0x00:
return 0x1A;
case 0x01:
return 0x07;
break;
case 0x02:
return 0x0B;
case 0x03:
return 0xAB;
case 0x04: /* PCI_COMMAND_LO */
case 0x05: /* PCI_COMMAND_HI */
return pci_regs[addr];
case 0x06: /* PCI_STATUS_LO */
case 0x07: /* PCI_STATUS_HI */
return pci_regs[addr];
case 0x08:
case 0x09:
return 0x00;
case 0x0A:
return pci_regs[addr];
case 0x0B:
return pci_regs[addr];
case 0x10: /* PCI_BAR 7:5 */
return (pci_bar[0].addr_regs[0] & 0xe0) | 0x01;
case 0x11: /* PCI_BAR 15:8 */
return pci_bar[0].addr_regs[1];
case 0x12: /* PCI_BAR 23:16 */
return pci_bar[0].addr_regs[2];
case 0x13: /* PCI_BAR 31:24 */
return pci_bar[0].addr_regs[3];
case 0x2C:
return 0x1A;
case 0x2D:
return 0x07;
case 0x2E:
return 0x0B;
case 0x2F:
return 0xAB;
case 0x3C: /* PCI_ILR */
return pci_regs[addr];
case 0x3D: /* PCI_IPR */
return pci_regs[addr];
default:
return 0x00;
} }
} }
static void pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv) static uint8_t
pci_dummy_read(uint16_t Port, void *p)
{
uint8_t ret = 0;
switch (Port & 0x20) {
case 0x00:
return 0x1A;
case 0x01:
return 0x07;
case 0x02:
return 0x0B;
case 0x03:
return 0xAB;
case 0x04:
return pci_regs[0x3C];
case 0x05:
return pci_regs[0x3D];
case 0x06:
ret = interrupt_on;
if (interrupt_on) {
pci_dummy_interrupt(0);
interrupt_on = 0;
}
return ret;
default:
return 0x00;
}
}
static uint16_t
pci_dummy_readw(uint16_t Port, void *p)
{
return pci_dummy_read(Port, p);
}
static uint32_t
pci_dummy_readl(uint16_t Port, void *p)
{
return pci_dummy_read(Port, p);
}
static void
pci_dummy_write(uint16_t Port, uint8_t Val, void *p)
{
switch (Port & 0x20) {
case 0x06:
if (!interrupt_on) {
interrupt_on = 1;
pci_dummy_interrupt(1);
}
return;
default:
return;
}
}
static void
pci_dummy_writew(uint16_t Port, uint16_t Val, void *p)
{
pci_dummy_write(Port, Val & 0xFF, p);
}
static void
pci_dummy_writel(uint16_t Port, uint32_t Val, void *p)
{
pci_dummy_write(Port, Val & 0xFF, p);
}
static void
pci_dummy_io_remove(void)
{
io_removehandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL);
}
static void
pci_dummy_io_set(void)
{
io_sethandler(pci_bar[0].addr, 0x0020, pci_dummy_read, pci_dummy_readw, pci_dummy_readl, pci_dummy_write, pci_dummy_writew, pci_dummy_writel, NULL);
}
static uint8_t
pci_dummy_pci_read(int func, int addr, void *priv)
{
pclog("AB0B:071A: PCI_Read(%d, %04x)\n", func, addr);
switch (addr) {
case 0x00:
return 0x1A;
case 0x01:
return 0x07;
break;
case 0x02:
return 0x0B;
case 0x03:
return 0xAB;
case 0x04: /* PCI_COMMAND_LO */
case 0x05: /* PCI_COMMAND_HI */
return pci_regs[addr];
case 0x06: /* PCI_STATUS_LO */
case 0x07: /* PCI_STATUS_HI */
return pci_regs[addr];
case 0x08:
case 0x09:
return 0x00;
case 0x0A:
return pci_regs[addr];
case 0x0B:
return pci_regs[addr];
case 0x10: /* PCI_BAR 7:5 */
return (pci_bar[0].addr_regs[0] & 0xe0) | 0x01;
case 0x11: /* PCI_BAR 15:8 */
return pci_bar[0].addr_regs[1];
case 0x12: /* PCI_BAR 23:16 */
return pci_bar[0].addr_regs[2];
case 0x13: /* PCI_BAR 31:24 */
return pci_bar[0].addr_regs[3];
case 0x2C:
return 0x1A;
case 0x2D:
return 0x07;
case 0x2E:
return 0x0B;
case 0x2F:
return 0xAB;
case 0x3C: /* PCI_ILR */
return pci_regs[addr];
case 0x3D: /* PCI_IPR */
return pci_regs[addr];
default:
return 0x00;
}
}
static void
pci_dummy_pci_write(int func, int addr, uint8_t val, void *priv)
{ {
uint8_t valxor; uint8_t valxor;
pclog("AB0B:071A: PCI_Write(%d, %04x, %02x)\n", func, addr, val); pclog("AB0B:071A: PCI_Write(%d, %04x, %02x)\n", func, addr, val);
switch(addr) { switch (addr) {
case 0x04: /* PCI_COMMAND_LO */ case 0x04: /* PCI_COMMAND_LO */
valxor = (val & 0x03) ^ pci_regs[addr]; valxor = (val & 0x03) ^ pci_regs[addr];
if (valxor & PCI_COMMAND_IO) if (valxor & PCI_COMMAND_IO) {
{ pci_dummy_io_remove();
pci_dummy_io_remove(); if (((pci_bar[0].addr & 0xffe0) != 0) && (val & PCI_COMMAND_IO)) {
if (((pci_bar[0].addr & 0xffe0) != 0) && (val & PCI_COMMAND_IO)) pci_dummy_io_set();
{ }
pci_dummy_io_set(); }
} pci_regs[addr] = val & 0x03;
} break;
pci_regs[addr] = val & 0x03;
break;
case 0x10: /* PCI_BAR */ case 0x10: /* PCI_BAR */
val &= 0xe0; /* 0xe0 acc to RTL DS */ val &= 0xe0; /* 0xe0 acc to RTL DS */
val |= 0x01; /* re-enable IOIN bit */ val |= 0x01; /* re-enable IOIN bit */
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case 0x11: /* PCI_BAR */ case 0x11: /* PCI_BAR */
case 0x12: /* PCI_BAR */ case 0x12: /* PCI_BAR */
case 0x13: /* PCI_BAR */ case 0x13: /* PCI_BAR */
/* Remove old I/O. */ /* Remove old I/O. */
pci_dummy_io_remove(); pci_dummy_io_remove();
/* Set new I/O as per PCI request. */ /* Set new I/O as per PCI request. */
pci_bar[0].addr_regs[addr & 3] = val; pci_bar[0].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */ /* Then let's calculate the new I/O base. */
pci_bar[0].addr &= 0xffe0; pci_bar[0].addr &= 0xffe0;
/* Log the new base. */ /* Log the new base. */
pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr); pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr);
/* We're done, so get out of the here. */ /* We're done, so get out of the here. */
if (pci_regs[4] & PCI_COMMAND_IO) if (pci_regs[4] & PCI_COMMAND_IO) {
{ if ((pci_bar[0].addr) != 0) {
if ((pci_bar[0].addr) != 0) pci_dummy_io_set();
{ }
pci_dummy_io_set(); }
} break;
}
break;
case 0x3C: /* PCI_ILR */ case 0x3C: /* PCI_ILR */
pclog("AB0B:071A: IRQ now: %i\n", val); pclog("AB0B:071A: IRQ now: %i\n", val);
pci_regs[addr] = val; pci_regs[addr] = val;
return; return;
} }
} }
void
void pci_dummy_init(void) pci_dummy_init(void)
{ {
card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, NULL); card = pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, NULL);
pci_bar[0].addr_regs[0] = 0x01; pci_bar[0].addr_regs[0] = 0x01;
pci_regs[0x04] = 0x03; pci_regs[0x04] = 0x03;
pci_regs[0x3D] = PCI_INTD; pci_regs[0x3D] = PCI_INTD;
} }

593
src/pic.c
View File

@@ -36,66 +36,58 @@
#include <86box/nvr.h> #include <86box/nvr.h>
#include <86box/acpi.h> #include <86box/acpi.h>
enum {
enum
{
STATE_NONE = 0, STATE_NONE = 0,
STATE_ICW2, STATE_ICW2,
STATE_ICW3, STATE_ICW3,
STATE_ICW4 STATE_ICW4
}; };
pic_t pic, pic2;
pic_t pic, pic2; static pc_timer_t pic_timer;
static int shadow = 0, elcr_enabled = 0,
tmr_inited = 0, latched = 0,
pic_pci = 0;
static pc_timer_t pic_timer; static uint16_t smi_irq_mask = 0x0000,
smi_irq_status = 0x0000;
static int shadow = 0, elcr_enabled = 0,
tmr_inited = 0, latched = 0,
pic_pci = 0;
static uint16_t smi_irq_mask = 0x0000,
smi_irq_status = 0x0000;
static void (*update_pending)(void);
static void (*update_pending)(void);
#ifdef ENABLE_PIC_LOG #ifdef ENABLE_PIC_LOG
int pic_do_log = ENABLE_PIC_LOG; int pic_do_log = ENABLE_PIC_LOG;
static void static void
pic_log(const char *fmt, ...) pic_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (pic_do_log) { if (pic_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define pic_log(fmt, ...) # define pic_log(fmt, ...)
#endif #endif
void void
pic_reset_smi_irq_mask(void) pic_reset_smi_irq_mask(void)
{ {
smi_irq_mask = 0x0000; smi_irq_mask = 0x0000;
} }
void void
pic_set_smi_irq_mask(int irq, int set) pic_set_smi_irq_mask(int irq, int set)
{ {
if ((irq >= 0) && (irq <= 15)) { if ((irq >= 0) && (irq <= 15)) {
if (set) if (set)
smi_irq_mask |= (1 << irq); smi_irq_mask |= (1 << irq);
else else
smi_irq_mask &= ~(1 << irq); smi_irq_mask &= ~(1 << irq);
} }
} }
@@ -105,15 +97,13 @@ pic_get_smi_irq_status(void)
return smi_irq_status; return smi_irq_status;
} }
void void
pic_clear_smi_irq_status(int irq) pic_clear_smi_irq_status(int irq)
{ {
if ((irq >= 0) && (irq <= 15)) if ((irq >= 0) && (irq <= 15))
smi_irq_status &= ~(1 << irq); smi_irq_status &= ~(1 << irq);
} }
void void
pic_elcr_write(uint16_t port, uint8_t val, void *priv) pic_elcr_write(uint16_t port, uint8_t val, void *priv)
{ {
@@ -122,25 +112,24 @@ pic_elcr_write(uint16_t port, uint8_t val, void *priv)
pic_log("ELCR%i: WRITE %02X\n", port & 1, val); pic_log("ELCR%i: WRITE %02X\n", port & 1, val);
if (port & 1) if (port & 1)
val &= 0xde; val &= 0xde;
else else
val &= 0xf8; val &= 0xf8;
dev->elcr = val; dev->elcr = val;
pic_log("ELCR %i: %c %c %c %c %c %c %c %c\n", pic_log("ELCR %i: %c %c %c %c %c %c %c %c\n",
port & 1, port & 1,
(val & 1) ? 'L' : 'E', (val & 1) ? 'L' : 'E',
(val & 2) ? 'L' : 'E', (val & 2) ? 'L' : 'E',
(val & 4) ? 'L' : 'E', (val & 4) ? 'L' : 'E',
(val & 8) ? 'L' : 'E', (val & 8) ? 'L' : 'E',
(val & 0x10) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E',
(val & 0x20) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E',
(val & 0x40) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E',
(val & 0x80) ? 'L' : 'E'); (val & 0x80) ? 'L' : 'E');
} }
uint8_t uint8_t
pic_elcr_read(uint16_t port, void *priv) pic_elcr_read(uint16_t port, void *priv)
{ {
@@ -151,110 +140,100 @@ pic_elcr_read(uint16_t port, void *priv)
return dev->elcr; return dev->elcr;
} }
int int
pic_elcr_get_enabled(void) pic_elcr_get_enabled(void)
{ {
return elcr_enabled; return elcr_enabled;
} }
void void
pic_elcr_set_enabled(int enabled) pic_elcr_set_enabled(int enabled)
{ {
elcr_enabled = enabled; elcr_enabled = enabled;
} }
void void
pic_elcr_io_handler(int set) pic_elcr_io_handler(int set)
{ {
io_handler(set, 0x04d0, 0x0001, io_handler(set, 0x04d0, 0x0001,
pic_elcr_read, NULL, NULL, pic_elcr_read, NULL, NULL,
pic_elcr_write, NULL, NULL, &pic); pic_elcr_write, NULL, NULL, &pic);
io_handler(set, 0x04d1, 0x0001, io_handler(set, 0x04d1, 0x0001,
pic_elcr_read, NULL, NULL, pic_elcr_read, NULL, NULL,
pic_elcr_write, NULL, NULL, &pic2); pic_elcr_write, NULL, NULL, &pic2);
} }
static uint8_t static uint8_t
pic_cascade_mode(pic_t *dev) pic_cascade_mode(pic_t *dev)
{ {
return !(dev->icw1 & 2); return !(dev->icw1 & 2);
} }
static __inline uint8_t static __inline uint8_t
pic_slave_on(pic_t *dev, int channel) pic_slave_on(pic_t *dev, int channel)
{ {
pic_log("pic_slave_on(%i): %i, %02X, %02X\n", channel, pic_cascade_mode(dev), dev->icw4 & 0x0c, dev->icw3 & (1 << channel)); pic_log("pic_slave_on(%i): %i, %02X, %02X\n", channel, pic_cascade_mode(dev), dev->icw4 & 0x0c, dev->icw3 & (1 << channel));
return pic_cascade_mode(dev) && (dev->is_master || ((dev->icw4 & 0x0c) == 0x0c)) && return pic_cascade_mode(dev) && (dev->is_master || ((dev->icw4 & 0x0c) == 0x0c)) && (dev->icw3 & (1 << channel));
(dev->icw3 & (1 << channel));
} }
static __inline int static __inline int
find_best_interrupt(pic_t *dev) find_best_interrupt(pic_t *dev)
{ {
uint8_t b; uint8_t b;
uint8_t intr; uint8_t intr;
int i, j; int i, j;
int ret = -1; int ret = -1;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
j = (i + dev->priority) & 7; j = (i + dev->priority) & 7;
b = 1 << j; b = 1 << j;
if (dev->isr & b) if (dev->isr & b)
break; break;
else if ((dev->state == 0) && ((dev->irr & ~dev->imr) & b)) { else if ((dev->state == 0) && ((dev->irr & ~dev->imr) & b)) {
ret = j; ret = j;
break; break;
} }
} }
intr = dev->interrupt = (ret == -1) ? 0x17 : ret; intr = dev->interrupt = (ret == -1) ? 0x17 : ret;
if (dev->at && (ret != 1)) { if (dev->at && (ret != 1)) {
if (dev == &pic2) if (dev == &pic2)
intr += 8; intr += 8;
if (cpu_fast_off_flags & (1u << intr)) if (cpu_fast_off_flags & (1u << intr))
cpu_fast_off_advance(); cpu_fast_off_advance();
} }
return ret; return ret;
} }
static __inline void static __inline void
pic_update_pending_xt(void) pic_update_pending_xt(void)
{ {
if (find_best_interrupt(&pic) != -1) { if (find_best_interrupt(&pic) != -1) {
latched++; latched++;
if (latched == 1) if (latched == 1)
timer_on_auto(&pic_timer, 0.35); timer_on_auto(&pic_timer, 0.35);
} else if (latched == 0) } else if (latched == 0)
pic.int_pending = 0; pic.int_pending = 0;
} }
static __inline void static __inline void
pic_update_pending_at(void) pic_update_pending_at(void)
{ {
pic2.int_pending = (find_best_interrupt(&pic2) != -1); pic2.int_pending = (find_best_interrupt(&pic2) != -1);
if (pic2.int_pending) if (pic2.int_pending)
pic.irr |= (1 << pic2.icw3); pic.irr |= (1 << pic2.icw3);
else else
pic.irr &= ~(1 << pic2.icw3); pic.irr &= ~(1 << pic2.icw3);
pic.int_pending = (find_best_interrupt(&pic) != -1); pic.int_pending = (find_best_interrupt(&pic) != -1);
} }
static void static void
pic_callback(void *priv) pic_callback(void *priv)
{ {
@@ -264,15 +243,14 @@ pic_callback(void *priv)
latched--; latched--;
if (latched > 0) if (latched > 0)
timer_on_auto(&pic_timer, 0.35); timer_on_auto(&pic_timer, 0.35);
} }
void void
pic_reset() pic_reset()
{ {
int is_at = IS_AT(machine); int is_at = IS_AT(machine);
is_at = is_at || !strcmp(machine_get_internal_name(), "xi8088"); is_at = is_at || !strcmp(machine_get_internal_name(), "xi8088");
memset(&pic, 0, sizeof(pic_t)); memset(&pic, 0, sizeof(pic_t));
memset(&pic2, 0, sizeof(pic_t)); memset(&pic2, 0, sizeof(pic_t));
@@ -281,10 +259,10 @@ pic_reset()
pic.interrupt = pic2.interrupt = 0x17; pic.interrupt = pic2.interrupt = 0x17;
if (is_at) if (is_at)
pic.slaves[2] = &pic2; pic.slaves[2] = &pic2;
if (tmr_inited) if (tmr_inited)
timer_on_auto(&pic_timer, 0.0); timer_on_auto(&pic_timer, 0.0);
memset(&pic_timer, 0x00, sizeof(pc_timer_t)); memset(&pic_timer, 0x00, sizeof(pc_timer_t));
timer_add(&pic_timer, pic_callback, &pic, 0); timer_add(&pic_timer, pic_callback, &pic, 0);
tmr_inited = 1; tmr_inited = 1;
@@ -294,76 +272,69 @@ pic_reset()
smi_irq_mask = smi_irq_status = 0x0000; smi_irq_mask = smi_irq_status = 0x0000;
shadow = 0; shadow = 0;
pic_pci = 0; pic_pci = 0;
} }
void void
pic_set_shadow(int sh) pic_set_shadow(int sh)
{ {
shadow = sh; shadow = sh;
} }
void void
pic_set_pci_flag(int pci) pic_set_pci_flag(int pci)
{ {
pic_pci = pci; pic_pci = pci;
} }
static uint8_t static uint8_t
pic_level_triggered(pic_t *dev, int irq) pic_level_triggered(pic_t *dev, int irq)
{ {
if (elcr_enabled) if (elcr_enabled)
return !!(dev->elcr & (1 << irq)); return !!(dev->elcr & (1 << irq));
else else
return !!(dev->icw1 & 8); return !!(dev->icw1 & 8);
} }
int int
picint_is_level(int irq) picint_is_level(int irq)
{ {
return pic_level_triggered(((irq > 7) ? &pic2 : &pic), irq & 7); return pic_level_triggered(((irq > 7) ? &pic2 : &pic), irq & 7);
} }
static void static void
pic_acknowledge(pic_t *dev) pic_acknowledge(pic_t *dev)
{ {
int pic_int = dev->interrupt & 7; int pic_int = dev->interrupt & 7;
int pic_int_num = 1 << pic_int; int pic_int_num = 1 << pic_int;
dev->isr |= pic_int_num; dev->isr |= pic_int_num;
if (!pic_level_triggered(dev, pic_int) || !(dev->lines & pic_int_num)) if (!pic_level_triggered(dev, pic_int) || !(dev->lines & pic_int_num))
dev->irr &= ~pic_int_num; dev->irr &= ~pic_int_num;
} }
/* Find IRQ for non-specific EOI (either by command or automatic) by finding the highest IRQ /* Find IRQ for non-specific EOI (either by command or automatic) by finding the highest IRQ
priority with ISR bit set, that is also not masked if the PIC is in special mask mode. */ priority with ISR bit set, that is also not masked if the PIC is in special mask mode. */
static uint8_t static uint8_t
pic_non_specific_find(pic_t *dev) pic_non_specific_find(pic_t *dev)
{ {
int i, j; int i, j;
uint8_t b, irq = 0xff; uint8_t b, irq = 0xff;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
j = (i + dev->priority) & 7; j = (i + dev->priority) & 7;
b = (1 << j); b = (1 << j);
if ((dev->isr & b) && (!dev->special_mask_mode || !(dev->imr & b))) { if ((dev->isr & b) && (!dev->special_mask_mode || !(dev->imr & b))) {
irq = j; irq = j;
break; break;
} }
} }
return irq; return irq;
} }
/* Do the EOI and rotation, if either is requested, on the given IRQ. */ /* Do the EOI and rotation, if either is requested, on the given IRQ. */
static void static void
pic_action(pic_t *dev, uint8_t irq, uint8_t eoi, uint8_t rotate) pic_action(pic_t *dev, uint8_t irq, uint8_t eoi, uint8_t rotate)
@@ -371,16 +342,15 @@ pic_action(pic_t *dev, uint8_t irq, uint8_t eoi, uint8_t rotate)
uint8_t b = (1 << irq); uint8_t b = (1 << irq);
if (irq != 0xff) { if (irq != 0xff) {
if (eoi) if (eoi)
dev->isr &= ~b; dev->isr &= ~b;
if (rotate) if (rotate)
dev->priority = (irq + 1) & 7; dev->priority = (irq + 1) & 7;
update_pending(); update_pending();
} }
} }
/* Automatic non-specific EOI. */ /* Automatic non-specific EOI. */
static __inline void static __inline void
pic_auto_non_specific_eoi(pic_t *dev) pic_auto_non_specific_eoi(pic_t *dev)
@@ -388,75 +358,73 @@ pic_auto_non_specific_eoi(pic_t *dev)
uint8_t irq; uint8_t irq;
if (dev->icw4 & 2) { if (dev->icw4 & 2) {
irq = pic_non_specific_find(dev); irq = pic_non_specific_find(dev);
pic_action(dev, irq, 1, dev->auto_eoi_rotate); pic_action(dev, irq, 1, dev->auto_eoi_rotate);
} }
} }
/* Do the PIC command specified by bits 7-5 of the value written to the OCW2 register. */ /* Do the PIC command specified by bits 7-5 of the value written to the OCW2 register. */
static void static void
pic_command(pic_t *dev) pic_command(pic_t *dev)
{ {
uint8_t irq = 0xff; uint8_t irq = 0xff;
if (dev->ocw2 & 0x60) { /* SL and/or EOI set */ if (dev->ocw2 & 0x60) { /* SL and/or EOI set */
if (dev->ocw2 & 0x40) /* SL set, specific priority level */ if (dev->ocw2 & 0x40) /* SL set, specific priority level */
irq = (dev->ocw2 & 0x07); irq = (dev->ocw2 & 0x07);
else /* SL clear, non-specific priority level (find highest with ISR set) */ else /* SL clear, non-specific priority level (find highest with ISR set) */
irq = pic_non_specific_find(dev); irq = pic_non_specific_find(dev);
pic_action(dev, irq, dev->ocw2 & 0x20, dev->ocw2 & 0x80); pic_action(dev, irq, dev->ocw2 & 0x20, dev->ocw2 & 0x80);
} else /* SL and EOI clear */ } else /* SL and EOI clear */
dev->auto_eoi_rotate = !!(dev->ocw2 & 0x80); dev->auto_eoi_rotate = !!(dev->ocw2 & 0x80);
} }
uint8_t uint8_t
pic_read(uint16_t addr, void *priv) pic_read(uint16_t addr, void *priv)
{ {
pic_t *dev = (pic_t *) priv; pic_t *dev = (pic_t *) priv;
if (shadow) { if (shadow) {
/* VIA PIC shadow read */ /* VIA PIC shadow read */
if (addr & 0x0001) if (addr & 0x0001)
dev->data_bus = ((dev->icw2 & 0xf8) >> 3) << 0; dev->data_bus = ((dev->icw2 & 0xf8) >> 3) << 0;
else { else {
dev->data_bus = ((dev->ocw3 & 0x20) >> 5) << 4; dev->data_bus = ((dev->ocw3 & 0x20) >> 5) << 4;
dev->data_bus |= ((dev->ocw2 & 0x80) >> 7) << 3; dev->data_bus |= ((dev->ocw2 & 0x80) >> 7) << 3;
dev->data_bus |= ((dev->icw4 & 0x10) >> 4) << 2; dev->data_bus |= ((dev->icw4 & 0x10) >> 4) << 2;
dev->data_bus |= ((dev->icw4 & 0x02) >> 1) << 1; dev->data_bus |= ((dev->icw4 & 0x02) >> 1) << 1;
dev->data_bus |= ((dev->icw4 & 0x08) >> 3) << 0; dev->data_bus |= ((dev->icw4 & 0x08) >> 3) << 0;
} }
} else { } else {
/* Standard 8259 PIC read */ /* Standard 8259 PIC read */
#ifndef UNDEFINED_READ #ifndef UNDEFINED_READ
/* Put the IRR on to the data bus by default until the real PIC is probed. */ /* Put the IRR on to the data bus by default until the real PIC is probed. */
dev->data_bus = dev->irr; dev->data_bus = dev->irr;
#endif #endif
if (dev->ocw3 & 0x04) { if (dev->ocw3 & 0x04) {
dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */ dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */
if (dev->int_pending) { if (dev->int_pending) {
dev->data_bus = 0x80 | (dev->interrupt & 7); dev->data_bus = 0x80 | (dev->interrupt & 7);
pic_acknowledge(dev); pic_acknowledge(dev);
dev->int_pending = 0; dev->int_pending = 0;
update_pending(); update_pending();
} else } else
dev->data_bus = 0x00; dev->data_bus = 0x00;
dev->ocw3 &= ~0x04; dev->ocw3 &= ~0x04;
} else if (addr & 0x0001) } else if (addr & 0x0001)
dev->data_bus = dev->imr; dev->data_bus = dev->imr;
else if (dev->ocw3 & 0x02) { else if (dev->ocw3 & 0x02) {
if (dev->ocw3 & 0x01) if (dev->ocw3 & 0x01)
dev->data_bus = dev->isr; dev->data_bus = dev->isr;
#ifdef UNDEFINED_READ #ifdef UNDEFINED_READ
else else
dev->data_bus = 0x00; dev->data_bus = 0x00;
#endif #endif
} }
/* If A0 = 0, VIA shadow is disabled, and poll mode is disabled, /* If A0 = 0, VIA shadow is disabled, and poll mode is disabled,
simply read whatever is currently on the data bus. */ simply read whatever is currently on the data bus. */
} }
pic_log("pic_read(%04X, %08X) = %02X\n", addr, priv, dev->data_bus); pic_log("pic_read(%04X, %08X) = %02X\n", addr, priv, dev->data_bus);
@@ -464,7 +432,6 @@ pic_read(uint16_t addr, void *priv)
return dev->data_bus; return dev->data_bus;
} }
static void static void
pic_write(uint16_t addr, uint8_t val, void *priv) pic_write(uint16_t addr, uint8_t val, void *priv)
{ {
@@ -475,77 +442,75 @@ pic_write(uint16_t addr, uint8_t val, void *priv)
dev->data_bus = val; dev->data_bus = val;
if (addr & 0x0001) { if (addr & 0x0001) {
switch (dev->state) { switch (dev->state) {
case STATE_ICW2: case STATE_ICW2:
dev->icw2 = val; dev->icw2 = val;
if (pic_cascade_mode(dev)) if (pic_cascade_mode(dev))
dev->state = STATE_ICW3; dev->state = STATE_ICW3;
else else
dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE; dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE;
break; break;
case STATE_ICW3: case STATE_ICW3:
dev->icw3 = val; dev->icw3 = val;
dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE; dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE;
break; break;
case STATE_ICW4: case STATE_ICW4:
dev->icw4 = val; dev->icw4 = val;
dev->state = STATE_NONE; dev->state = STATE_NONE;
break; break;
case STATE_NONE: case STATE_NONE:
dev->imr = val; dev->imr = val;
update_pending(); update_pending();
break; break;
} }
} else { } else {
if (val & 0x10) { if (val & 0x10) {
/* Treat any write with any of the bits 7 to 5 set as invalid if PCI. */ /* Treat any write with any of the bits 7 to 5 set as invalid if PCI. */
if (pic_pci && (val & 0xe0)) if (pic_pci && (val & 0xe0))
return; return;
dev->icw1 = val; dev->icw1 = val;
dev->icw2 = dev->icw3 = 0x00; dev->icw2 = dev->icw3 = 0x00;
if (!(dev->icw1 & 1)) if (!(dev->icw1 & 1))
dev->icw4 = 0x00; dev->icw4 = 0x00;
dev->ocw2 = dev->ocw3 = 0x00; dev->ocw2 = dev->ocw3 = 0x00;
dev->irr = dev->lines; dev->irr = dev->lines;
dev->imr = dev->isr = 0x00; dev->imr = dev->isr = 0x00;
dev->ack_bytes = dev->priority = 0x00; dev->ack_bytes = dev->priority = 0x00;
dev->auto_eoi_rotate = dev->special_mask_mode = 0x00; dev->auto_eoi_rotate = dev->special_mask_mode = 0x00;
dev->interrupt = 0x17; dev->interrupt = 0x17;
dev->int_pending = 0x00; dev->int_pending = 0x00;
dev->state = STATE_ICW2; dev->state = STATE_ICW2;
update_pending(); update_pending();
} else if (val & 0x08) { } else if (val & 0x08) {
dev->ocw3 = val; dev->ocw3 = val;
if (dev->ocw3 & 0x04) if (dev->ocw3 & 0x04)
dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */ dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */
if (dev->ocw3 & 0x40) if (dev->ocw3 & 0x40)
dev->special_mask_mode = !!(dev->ocw3 & 0x20); dev->special_mask_mode = !!(dev->ocw3 & 0x20);
} else { } else {
dev->ocw2 = val; dev->ocw2 = val;
pic_command(dev); pic_command(dev);
} }
} }
} }
void void
pic_set_pci(void) pic_set_pci(void)
{ {
int i; int i;
for (i = 0x0024; i < 0x0040; i += 4) { for (i = 0x0024; i < 0x0040; i += 4) {
io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
} }
for (i = 0x1120; i < 0x1140; i += 4) { for (i = 0x1120; i < 0x1140; i += 4) {
io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); io_sethandler(i, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2); io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
} }
} }
void void
pic_init(void) pic_init(void)
{ {
@@ -555,7 +520,6 @@ pic_init(void)
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
} }
void void
pic_init_pcjr(void) pic_init_pcjr(void)
{ {
@@ -565,7 +529,6 @@ pic_init_pcjr(void)
io_sethandler(0x0020, 0x0008, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic); io_sethandler(0x0020, 0x0008, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
} }
void void
pic2_init(void) pic2_init(void)
{ {
@@ -573,152 +536,145 @@ pic2_init(void)
pic.slaves[2] = &pic2; pic.slaves[2] = &pic2;
} }
void void
picint_common(uint16_t num, int level, int set) picint_common(uint16_t num, int level, int set)
{ {
int i, raise; int i, raise;
uint8_t b, slaves = 0; uint8_t b, slaves = 0;
/* Make sure to ignore all slave IRQ's, and in case of AT+, /* Make sure to ignore all slave IRQ's, and in case of AT+,
translate IRQ 2 to IRQ 9. */ translate IRQ 2 to IRQ 9. */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
b = (1 << i); b = (1 << i);
raise = num & b; raise = num & b;
if (pic.icw3 & b) { if (pic.icw3 & b) {
slaves++; slaves++;
if (raise) { if (raise) {
num &= ~b; num &= ~b;
if (pic.at && (i == 2)) if (pic.at && (i == 2))
num |= (1 << 9); num |= (1 << 9);
} }
} }
} }
if (!slaves) if (!slaves)
num &= 0x00ff; num &= 0x00ff;
if (!num) { if (!num) {
pic_log("Attempting to %s null IRQ\n", set ? "raise" : "lower"); pic_log("Attempting to %s null IRQ\n", set ? "raise" : "lower");
return; return;
} }
if (num & 0x0100) if (num & 0x0100)
acpi_rtc_status = !!set; acpi_rtc_status = !!set;
if (set) { if (set) {
if (smi_irq_mask & num) { if (smi_irq_mask & num) {
smi_raise(); smi_raise();
smi_irq_status |= num; smi_irq_status |= num;
} }
if (num & 0xff00) { if (num & 0xff00) {
if (level) if (level)
pic2.lines |= (num >> 8); pic2.lines |= (num >> 8);
pic2.irr |= (num >> 8); pic2.irr |= (num >> 8);
} }
if (num & 0x00ff) { if (num & 0x00ff) {
if (level) if (level)
pic.lines |= (num >> 8); pic.lines |= (num >> 8);
pic.irr |= num; pic.irr |= num;
} }
} else { } else {
smi_irq_status &= ~num; smi_irq_status &= ~num;
if (num & 0xff00) { if (num & 0xff00) {
pic2.lines &= ~(num >> 8); pic2.lines &= ~(num >> 8);
pic2.irr &= ~(num >> 8); pic2.irr &= ~(num >> 8);
} }
if (num & 0x00ff) { if (num & 0x00ff) {
pic.lines &= ~num; pic.lines &= ~num;
pic.irr &= ~num; pic.irr &= ~num;
} }
} }
if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20)) if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20))
update_pending(); update_pending();
} }
void void
picint(uint16_t num) picint(uint16_t num)
{ {
picint_common(num, 0, 1); picint_common(num, 0, 1);
} }
void void
picintlevel(uint16_t num) picintlevel(uint16_t num)
{ {
picint_common(num, 1, 1); picint_common(num, 1, 1);
} }
void void
picintc(uint16_t num) picintc(uint16_t num)
{ {
picint_common(num, 0, 0); picint_common(num, 0, 0);
} }
static uint8_t static uint8_t
pic_i86_mode(pic_t *dev) pic_i86_mode(pic_t *dev)
{ {
return !!(dev->icw4 & 1); return !!(dev->icw4 & 1);
} }
static uint8_t static uint8_t
pic_irq_ack_read(pic_t *dev, int phase) pic_irq_ack_read(pic_t *dev, int phase)
{ {
uint8_t intr = dev->interrupt & 0x47; uint8_t intr = dev->interrupt & 0x47;
uint8_t slave = intr & 0x40; uint8_t slave = intr & 0x40;
intr &= 0x07; intr &= 0x07;
pic_log(" pic_irq_ack_read(%08X, %i)\n", dev, phase); pic_log(" pic_irq_ack_read(%08X, %i)\n", dev, phase);
if (dev != NULL) { if (dev != NULL) {
if (phase == 0) { if (phase == 0) {
dev->interrupt |= 0x20; /* Freeze it so it still takes interrupts but they do not dev->interrupt |= 0x20; /* Freeze it so it still takes interrupts but they do not
override the one currently being processed. */ override the one currently being processed. */
pic_acknowledge(dev); pic_acknowledge(dev);
if (slave) if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else else
dev->data_bus = pic_i86_mode(dev) ? 0xff : 0xcd; dev->data_bus = pic_i86_mode(dev) ? 0xff : 0xcd;
} else if (pic_i86_mode(dev)) { } else if (pic_i86_mode(dev)) {
dev->int_pending = 0; dev->int_pending = 0;
if (slave) if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else else
dev->data_bus = intr + (dev->icw2 & 0xf8); dev->data_bus = intr + (dev->icw2 & 0xf8);
pic_auto_non_specific_eoi(dev); pic_auto_non_specific_eoi(dev);
} else if (phase == 1) { } else if (phase == 1) {
if (slave) if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else if (dev->icw1 & 0x04) else if (dev->icw1 & 0x04)
dev->data_bus = (intr << 2) + (dev->icw1 & 0xe0); dev->data_bus = (intr << 2) + (dev->icw1 & 0xe0);
else else
dev->data_bus = (intr << 3) + (dev->icw1 & 0xc0); dev->data_bus = (intr << 3) + (dev->icw1 & 0xc0);
} else if (phase == 2) { } else if (phase == 2) {
dev->int_pending = 0; dev->int_pending = 0;
if (slave) if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase); dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else else
dev->data_bus = dev->icw2; dev->data_bus = dev->icw2;
pic_auto_non_specific_eoi(dev); pic_auto_non_specific_eoi(dev);
} }
} }
return dev->data_bus; return dev->data_bus;
} }
uint8_t uint8_t
pic_irq_ack(void) pic_irq_ack(void)
{ {
@@ -726,63 +682,62 @@ pic_irq_ack(void)
/* Needed for Xi8088. */ /* Needed for Xi8088. */
if ((pic.ack_bytes == 0) && pic.int_pending && pic_slave_on(&pic, pic.interrupt)) { if ((pic.ack_bytes == 0) && pic.int_pending && pic_slave_on(&pic, pic.interrupt)) {
if (!pic.slaves[pic.interrupt]->int_pending) { if (!pic.slaves[pic.interrupt]->int_pending) {
/* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */ /* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */
fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt); fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt);
exit(-1); exit(-1);
return -1; return -1;
} }
pic.interrupt |= 0x40; /* Mark slave pending. */ pic.interrupt |= 0x40; /* Mark slave pending. */
} }
ret = pic_irq_ack_read(&pic, pic.ack_bytes); ret = pic_irq_ack_read(&pic, pic.ack_bytes);
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3); pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
if (pic.ack_bytes == 0) { if (pic.ack_bytes == 0) {
/* Needed for Xi8088. */ /* Needed for Xi8088. */
if (pic.interrupt & 0x40) if (pic.interrupt & 0x40)
pic2.interrupt = 0x17; pic2.interrupt = 0x17;
pic.interrupt = 0x17; pic.interrupt = 0x17;
update_pending(); update_pending();
} }
return ret; return ret;
} }
int int
picinterrupt() picinterrupt()
{ {
int i, ret = -1; int i, ret = -1;
if (pic.int_pending) { if (pic.int_pending) {
if (pic_slave_on(&pic, pic.interrupt)) { if (pic_slave_on(&pic, pic.interrupt)) {
if (!pic.slaves[pic.interrupt]->int_pending) { if (!pic.slaves[pic.interrupt]->int_pending) {
/* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */ /* If we are on AT, IRQ 2 is pending, and we cannot find a pending IRQ on PIC 2, fatal out. */
fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt); fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt);
exit(-1); exit(-1);
return -1; return -1;
} }
pic.interrupt |= 0x40; /* Mark slave pending. */ pic.interrupt |= 0x40; /* Mark slave pending. */
} }
if ((pic.interrupt == 0) && (pit_devs[1].data != NULL)) if ((pic.interrupt == 0) && (pit_devs[1].data != NULL))
pit_devs[1].set_gate(pit_devs[1].data, 0, 0); pit_devs[1].set_gate(pit_devs[1].data, 0, 0);
/* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */ /* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
ret = pic_irq_ack_read(&pic, pic.ack_bytes); ret = pic_irq_ack_read(&pic, pic.ack_bytes);
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3); pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
if (pic.ack_bytes == 0) { if (pic.ack_bytes == 0) {
if (pic.interrupt & 0x40) if (pic.interrupt & 0x40)
pic2.interrupt = 0x17; pic2.interrupt = 0x17;
pic.interrupt = 0x17; pic.interrupt = 0x17;
update_pending(); update_pending();
} }
} }
} }
return ret; return ret;

1148
src/pit.c

File diff suppressed because it is too large Load Diff

View File

@@ -41,10 +41,10 @@
#include <86box/snd_speaker.h> #include <86box/snd_speaker.h>
#include <86box/video.h> #include <86box/video.h>
#define PIT_PS2 16 /* The PIT is the PS/2's second PIT. */ #define PIT_PS2 16 /* The PIT is the PS/2's second PIT. */
#define PIT_EXT_IO 32 /* The PIT has externally specified port I/O. */ #define PIT_EXT_IO 32 /* The PIT has externally specified port I/O. */
#define PIT_CUSTOM_CLOCK 64 /* The PIT uses custom clock inputs provided by another provider. */ #define PIT_CUSTOM_CLOCK 64 /* The PIT uses custom clock inputs provided by another provider. */
#define PIT_SECONDARY 128 /* The PIT is secondary (ports 0048-004B). */ #define PIT_SECONDARY 128 /* The PIT is secondary (ports 0048-004B). */
#ifdef ENABLE_PIT_LOG #ifdef ENABLE_PIT_LOG
int pit_do_log = ENABLE_PIT_LOG; int pit_do_log = ENABLE_PIT_LOG;
@@ -61,7 +61,7 @@ pit_log(const char *fmt, ...)
} }
} }
#else #else
#define pit_log(fmt, ...) # define pit_log(fmt, ...)
#endif #endif
static void static void
@@ -81,7 +81,7 @@ pitf_ctr_set_load_func(void *data, int counter_id, void (*func)(uint8_t new_m, i
if (data == NULL) if (data == NULL)
return; return;
pitf_t *pit = (pitf_t *)data; pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id]; ctrf_t *ctr = &pit->counters[counter_id];
ctr->load_func = func; ctr->load_func = func;
@@ -90,7 +90,7 @@ pitf_ctr_set_load_func(void *data, int counter_id, void (*func)(uint8_t new_m, i
static uint16_t static uint16_t
pitf_ctr_get_count(void *data, int counter_id) pitf_ctr_get_count(void *data, int counter_id)
{ {
pitf_t *pit = (pitf_t *)data; pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id]; ctrf_t *ctr = &pit->counters[counter_id];
return (uint16_t) ctr->l; return (uint16_t) ctr->l;
} }
@@ -101,7 +101,7 @@ pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int
if (data == NULL) if (data == NULL)
return; return;
pitf_t *pit = (pitf_t *)data; pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id]; ctrf_t *ctr = &pit->counters[counter_id];
ctr->out_func = func; ctr->out_func = func;
@@ -113,8 +113,8 @@ pitf_ctr_set_using_timer(void *data, int counter_id, int using_timer)
if (tsc > 0) if (tsc > 0)
timer_process(); timer_process();
pitf_t *pit = (pitf_t *)data; pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id]; ctrf_t *ctr = &pit->counters[counter_id];
ctr->using_timer = using_timer; ctr->using_timer = using_timer;
} }
@@ -266,7 +266,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate)
ctr->enabled = gate; ctr->enabled = gate;
break; break;
} }
ctr->gate = gate; ctr->gate = gate;
ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled; ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled;
if (ctr->using_timer && !ctr->running) if (ctr->using_timer && !ctr->running)
pitf_dump_and_disable_timer(ctr); pitf_dump_and_disable_timer(ctr);
@@ -275,7 +275,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate)
static void static void
pitf_ctr_set_gate(void *data, int counter_id, int gate) pitf_ctr_set_gate(void *data, int counter_id, int gate)
{ {
pitf_t *pit = (pitf_t *)data; pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id]; ctrf_t *ctr = &pit->counters[counter_id];
if (ctr->disabled) { if (ctr->disabled) {
@@ -375,7 +375,7 @@ pitf_ctr_latch_count(ctrf_t *ctr)
static __inline void static __inline void
pitf_ctr_latch_status(ctrf_t *ctr) pitf_ctr_latch_status(ctrf_t *ctr)
{ {
ctr->read_status = (ctr->ctrl & 0x3f) | (ctr->out ? 0x80 : 0); ctr->read_status = (ctr->ctrl & 0x3f) | (ctr->out ? 0x80 : 0);
ctr->do_read_status = 1; ctr->do_read_status = 1;
} }
@@ -383,7 +383,7 @@ static void
pitf_write(uint16_t addr, uint8_t val, void *priv) pitf_write(uint16_t addr, uint8_t val, void *priv)
{ {
pitf_t *dev = (pitf_t *) priv; pitf_t *dev = (pitf_t *) priv;
int t = (addr & 3); int t = (addr & 3);
ctrf_t *ctr; ctrf_t *ctr;
pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
@@ -479,10 +479,10 @@ pitf_write(uint16_t addr, uint8_t val, void *priv)
static uint8_t static uint8_t
pitf_read(uint16_t addr, void *priv) pitf_read(uint16_t addr, void *priv)
{ {
pitf_t *dev = (pitf_t *) priv; pitf_t *dev = (pitf_t *) priv;
uint8_t ret = 0xff; uint8_t ret = 0xff;
int t = (addr & 3); int t = (addr & 3);
ctrf_t *ctr; ctrf_t *ctr;
switch (addr & 3) { switch (addr & 3) {
case 3: /* Control. */ case 3: /* Control. */
@@ -548,7 +548,7 @@ pitf_timer_over(void *p)
static void static void
pitf_ctr_clock(void *data, int counter_id) pitf_ctr_clock(void *data, int counter_id)
{ {
pitf_t *pit = (pitf_t *)data; pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id]; ctrf_t *ctr = &pit->counters[counter_id];
if (ctr->thit || !ctr->enabled) if (ctr->thit || !ctr->enabled)
@@ -565,11 +565,11 @@ pitf_ctr_clock(void *data, int counter_id)
static void static void
ctr_reset(ctrf_t *ctr) ctr_reset(ctrf_t *ctr)
{ {
ctr->ctrl = 0; ctr->ctrl = 0;
ctr->m = 0; ctr->m = 0;
ctr->gate = 0; ctr->gate = 0;
ctr->l = 0xffff; ctr->l = 0xffff;
ctr->thit = 1; ctr->thit = 1;
ctr->using_timer = 1; ctr->using_timer = 1;
} }
@@ -613,7 +613,7 @@ pitf_init(const device_t *info)
if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
ctrf_t *ctr = &dev->counters[i]; ctrf_t *ctr = &dev->counters[i];
timer_add(&ctr->timer, pitf_timer_over, (void *)ctr, 0); timer_add(&ctr->timer, pitf_timer_over, (void *) ctr, 0);
} }
} }
@@ -626,73 +626,73 @@ pitf_init(const device_t *info)
} }
const device_t i8253_fast_device = { const device_t i8253_fast_device = {
.name = "Intel 8253/8253-5 Programmable Interval Timer", .name = "Intel 8253/8253-5 Programmable Interval Timer",
.internal_name = "i8253_fast", .internal_name = "i8253_fast",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = PIT_8253, .local = PIT_8253,
.init = pitf_init, .init = pitf_init,
.close = pitf_close, .close = pitf_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t i8254_fast_device = { const device_t i8254_fast_device = {
.name = "Intel 8254 Programmable Interval Timer", .name = "Intel 8254 Programmable Interval Timer",
.internal_name = "i8254_fast", .internal_name = "i8254_fast",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = PIT_8254, .local = PIT_8254,
.init = pitf_init, .init = pitf_init,
.close = pitf_close, .close = pitf_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t i8254_sec_fast_device = { const device_t i8254_sec_fast_device = {
.name = "Intel 8254 Programmable Interval Timer (Secondary)", .name = "Intel 8254 Programmable Interval Timer (Secondary)",
.internal_name = "i8254_sec_fast", .internal_name = "i8254_sec_fast",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = PIT_8254 | PIT_SECONDARY, .local = PIT_8254 | PIT_SECONDARY,
.init = pitf_init, .init = pitf_init,
.close = pitf_close, .close = pitf_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t i8254_ext_io_fast_device = { const device_t i8254_ext_io_fast_device = {
.name = "Intel 8254 Programmable Interval Timer (External I/O)", .name = "Intel 8254 Programmable Interval Timer (External I/O)",
.internal_name = "i8254_ext_io_fast", .internal_name = "i8254_ext_io_fast",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = PIT_8254 | PIT_EXT_IO, .local = PIT_8254 | PIT_EXT_IO,
.init = pitf_init, .init = pitf_init,
.close = pitf_close, .close = pitf_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t i8254_ps2_fast_device = { const device_t i8254_ps2_fast_device = {
.name = "Intel 8254 Programmable Interval Timer (PS/2)", .name = "Intel 8254 Programmable Interval Timer (PS/2)",
.internal_name = "i8254_ps2_fast", .internal_name = "i8254_ps2_fast",
.flags = DEVICE_ISA, .flags = DEVICE_ISA,
.local = PIT_8254 | PIT_PS2 | PIT_EXT_IO, .local = PIT_8254 | PIT_PS2 | PIT_EXT_IO,
.init = pitf_init, .init = pitf_init,
.close = pitf_close, .close = pitf_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const pit_intf_t pit_fast_intf = { const pit_intf_t pit_fast_intf = {

View File

@@ -35,14 +35,12 @@
#include <86box/video.h> #include <86box/video.h>
#include <86box/port_6x.h> #include <86box/port_6x.h>
#define PS2_REFRESH_TIME (16 * TIMER_USEC)
#define PS2_REFRESH_TIME (16 * TIMER_USEC) #define PORT_6X_TURBO 1
#define PORT_6X_EXT_REF 2
#define PORT_6X_TURBO 1 #define PORT_6X_MIRROR 4
#define PORT_6X_EXT_REF 2 #define PORT_6X_SWA 8
#define PORT_6X_MIRROR 4
#define PORT_6X_SWA 8
static void static void
port_6x_write(uint16_t port, uint8_t val, void *priv) port_6x_write(uint16_t port, uint8_t val, void *priv)
@@ -52,22 +50,22 @@ port_6x_write(uint16_t port, uint8_t val, void *priv)
port &= 3; port &= 3;
if ((port == 3) && (dev->flags & PORT_6X_MIRROR)) if ((port == 3) && (dev->flags & PORT_6X_MIRROR))
port = 1; port = 1;
switch (port) { switch (port) {
case 1: case 1:
ppi.pb = (ppi.pb & 0x10) | (val & 0x0f); ppi.pb = (ppi.pb & 0x10) | (val & 0x0f);
speaker_update(); speaker_update();
speaker_gated = val & 1; speaker_gated = val & 1;
speaker_enable = val & 2; speaker_enable = val & 2;
if (speaker_enable) if (speaker_enable)
was_speaker_enable = 1; was_speaker_enable = 1;
pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1);
if (dev->flags & PORT_6X_TURBO) if (dev->flags & PORT_6X_TURBO)
xi8088_turbo_set(!!(val & 0x04)); xi8088_turbo_set(!!(val & 0x04));
break; break;
} }
} }
@@ -79,14 +77,14 @@ port_61_read_simple(uint16_t port, void *priv)
if (ppispeakon) if (ppispeakon)
ret |= 0x20; ret |= 0x20;
return(ret); return (ret);
} }
static uint8_t static uint8_t
port_61_read(uint16_t port, void *priv) port_61_read(uint16_t port, void *priv)
{ {
port_6x_t *dev = (port_6x_t *) priv; port_6x_t *dev = (port_6x_t *) priv;
uint8_t ret = 0xff; uint8_t ret = 0xff;
if (dev->flags & PORT_6X_EXT_REF) { if (dev->flags & PORT_6X_EXT_REF) {
ret = ppi.pb & 0x0f; ret = ppi.pb & 0x0f;
@@ -102,7 +100,7 @@ port_61_read(uint16_t port, void *priv)
if (dev->flags & PORT_6X_TURBO) if (dev->flags & PORT_6X_TURBO)
ret = (ret & 0xfb) | (xi8088_turbo_get() ? 0x04 : 0x00); ret = (ret & 0xfb) | (xi8088_turbo_get() ? 0x04 : 0x00);
return(ret); return (ret);
} }
static uint8_t static uint8_t
@@ -138,7 +136,7 @@ port_62_read(uint16_t port, void *priv)
ret |= 0x02; ret |= 0x02;
} }
return(ret); return (ret);
} }
static void static void
@@ -150,7 +148,6 @@ port_6x_refresh(void *priv)
timer_advance_u64(&dev->refresh_timer, PS2_REFRESH_TIME); timer_advance_u64(&dev->refresh_timer, PS2_REFRESH_TIME);
} }
static void static void
port_6x_close(void *priv) port_6x_close(void *priv)
{ {
@@ -161,7 +158,6 @@ port_6x_close(void *priv)
free(dev); free(dev);
} }
void * void *
port_6x_init(const device_t *info) port_6x_init(const device_t *info)
{ {
@@ -173,16 +169,16 @@ port_6x_init(const device_t *info)
if (dev->flags & (PORT_6X_TURBO | PORT_6X_EXT_REF)) { if (dev->flags & (PORT_6X_TURBO | PORT_6X_EXT_REF)) {
io_sethandler(0x0061, 1, port_61_read, NULL, NULL, port_6x_write, NULL, NULL, dev); io_sethandler(0x0061, 1, port_61_read, NULL, NULL, port_6x_write, NULL, NULL, dev);
if (dev->flags & PORT_6X_EXT_REF) if (dev->flags & PORT_6X_EXT_REF)
timer_add(&dev->refresh_timer, port_6x_refresh, dev, 1); timer_add(&dev->refresh_timer, port_6x_refresh, dev, 1);
if (dev->flags & PORT_6X_MIRROR) if (dev->flags & PORT_6X_MIRROR)
io_sethandler(0x0063, 1, port_61_read, NULL, NULL, port_6x_write, NULL, NULL, dev); io_sethandler(0x0063, 1, port_61_read, NULL, NULL, port_6x_write, NULL, NULL, dev);
} else { } else {
io_sethandler(0x0061, 1, port_61_read_simple, NULL, NULL, port_6x_write, NULL, NULL, dev); io_sethandler(0x0061, 1, port_61_read_simple, NULL, NULL, port_6x_write, NULL, NULL, dev);
if (dev->flags & PORT_6X_MIRROR) if (dev->flags & PORT_6X_MIRROR)
io_sethandler(0x0063, 1, port_61_read_simple, NULL, NULL, port_6x_write, NULL, NULL, dev); io_sethandler(0x0063, 1, port_61_read_simple, NULL, NULL, port_6x_write, NULL, NULL, dev);
} }
if (dev->flags & PORT_6X_SWA) if (dev->flags & PORT_6X_SWA)
@@ -192,57 +188,57 @@ port_6x_init(const device_t *info)
} }
const device_t port_6x_device = { const device_t port_6x_device = {
.name = "Port 6x Registers", .name = "Port 6x Registers",
.internal_name = "port_6x", .internal_name = "port_6x",
.flags = 0, .flags = 0,
.local = 0, .local = 0,
.init = port_6x_init, .init = port_6x_init,
.close = port_6x_close, .close = port_6x_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t port_6x_xi8088_device = { const device_t port_6x_xi8088_device = {
.name = "Port 6x Registers (Xi8088)", .name = "Port 6x Registers (Xi8088)",
.internal_name = "port_6x_xi8088", .internal_name = "port_6x_xi8088",
.flags = 0, .flags = 0,
.local = PORT_6X_TURBO | PORT_6X_EXT_REF | PORT_6X_MIRROR, .local = PORT_6X_TURBO | PORT_6X_EXT_REF | PORT_6X_MIRROR,
.init = port_6x_init, .init = port_6x_init,
.close = port_6x_close, .close = port_6x_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t port_6x_ps2_device = { const device_t port_6x_ps2_device = {
.name = "Port 6x Registers (IBM PS/2)", .name = "Port 6x Registers (IBM PS/2)",
.internal_name = "port_6x_ps2", .internal_name = "port_6x_ps2",
.flags = 0, .flags = 0,
.local = PORT_6X_EXT_REF, .local = PORT_6X_EXT_REF,
.init = port_6x_init, .init = port_6x_init,
.close = port_6x_close, .close = port_6x_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t port_6x_olivetti_device = { const device_t port_6x_olivetti_device = {
.name = "Port 6x Registers (Olivetti)", .name = "Port 6x Registers (Olivetti)",
.internal_name = "port_6x_olivetti", .internal_name = "port_6x_olivetti",
.flags = 0, .flags = 0,
.local = PORT_6X_SWA, .local = PORT_6X_SWA,
.init = port_6x_init, .init = port_6x_init,
.close = port_6x_close, .close = port_6x_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

View File

@@ -30,50 +30,45 @@
#include <86box/pit.h> #include <86box/pit.h>
#include <86box/port_92.h> #include <86box/port_92.h>
#define PORT_92_INV 1
#define PORT_92_INV 1 #define PORT_92_WORD 2
#define PORT_92_WORD 2 #define PORT_92_PCI 4
#define PORT_92_PCI 4 #define PORT_92_RESET 8
#define PORT_92_RESET 8 #define PORT_92_A20 16
#define PORT_92_A20 16
static uint8_t static uint8_t
port_92_readb(uint16_t port, void *priv) port_92_readb(uint16_t port, void *priv)
{ {
uint8_t ret = 0x00; uint8_t ret = 0x00;
port_92_t *dev = (port_92_t *) priv; port_92_t *dev = (port_92_t *) priv;
if (port == 0x92) { if (port == 0x92) {
/* Return bit 1 directly from mem_a20_alt, so the /* Return bit 1 directly from mem_a20_alt, so the
pin can be reset independently of the device. */ pin can be reset independently of the device. */
ret = (dev->reg & ~0x03) | (mem_a20_alt & 2) | ret = (dev->reg & ~0x03) | (mem_a20_alt & 2) | (cpu_alt_reset & 1);
(cpu_alt_reset & 1);
if (dev->flags & PORT_92_INV) if (dev->flags & PORT_92_INV)
ret |= 0xfc; ret |= 0xfc;
else if (dev->flags & PORT_92_PCI) else if (dev->flags & PORT_92_PCI)
ret |= 0x24; /* Intel SIO datasheet says bits 2 and 5 are always 1. */ ret |= 0x24; /* Intel SIO datasheet says bits 2 and 5 are always 1. */
} else if (dev->flags & PORT_92_INV) } else if (dev->flags & PORT_92_INV)
ret = 0xff; ret = 0xff;
return ret; return ret;
} }
static uint16_t static uint16_t
port_92_readw(uint16_t port, void *priv) port_92_readw(uint16_t port, void *priv)
{ {
uint16_t ret = 0xffff; uint16_t ret = 0xffff;
port_92_t *dev = (port_92_t *) priv; port_92_t *dev = (port_92_t *) priv;
if (!(dev->flags & PORT_92_PCI)) if (!(dev->flags & PORT_92_PCI))
ret = port_92_readb(port, priv); ret = port_92_readb(port, priv);
return ret; return ret;
} }
static void static void
port_92_pulse(void *priv) port_92_pulse(void *priv)
{ {
@@ -81,44 +76,41 @@ port_92_pulse(void *priv)
cpu_set_edx(); cpu_set_edx();
} }
static void static void
port_92_writeb(uint16_t port, uint8_t val, void *priv) port_92_writeb(uint16_t port, uint8_t val, void *priv)
{ {
port_92_t *dev = (port_92_t *) priv; port_92_t *dev = (port_92_t *) priv;
if (port != 0x92) if (port != 0x92)
return; return;
dev->reg = val & 0x03; dev->reg = val & 0x03;
if ((mem_a20_alt ^ val) & 2) { if ((mem_a20_alt ^ val) & 2) {
mem_a20_alt = (val & 2); mem_a20_alt = (val & 2);
mem_a20_recalc(); mem_a20_recalc();
} }
if ((~cpu_alt_reset & val) & 1) if ((~cpu_alt_reset & val) & 1)
timer_set_delay_u64(&dev->pulse_timer, dev->pulse_period); timer_set_delay_u64(&dev->pulse_timer, dev->pulse_period);
else if (!(val & 1)) else if (!(val & 1))
timer_disable(&dev->pulse_timer); timer_disable(&dev->pulse_timer);
cpu_alt_reset = (val & 1); cpu_alt_reset = (val & 1);
if (dev->flags & PORT_92_INV) if (dev->flags & PORT_92_INV)
dev->reg |= 0xfc; dev->reg |= 0xfc;
} }
static void static void
port_92_writew(uint16_t port, uint16_t val, void *priv) port_92_writew(uint16_t port, uint16_t val, void *priv)
{ {
port_92_t *dev = (port_92_t *) priv; port_92_t *dev = (port_92_t *) priv;
if (!(dev->flags & PORT_92_PCI)) if (!(dev->flags & PORT_92_PCI))
port_92_writeb(port, val & 0xff, priv); port_92_writeb(port, val & 0xff, priv);
} }
void void
port_92_set_period(void *priv, uint64_t pulse_period) port_92_set_period(void *priv, uint64_t pulse_period)
{ {
@@ -127,7 +119,6 @@ port_92_set_period(void *priv, uint64_t pulse_period)
dev->pulse_period = pulse_period; dev->pulse_period = pulse_period;
} }
void void
port_92_set_features(void *priv, int reset, int a20) port_92_set_features(void *priv, int reset, int a20)
{ {
@@ -136,48 +127,45 @@ port_92_set_features(void *priv, int reset, int a20)
dev->flags &= ~(PORT_92_RESET | PORT_92_A20); dev->flags &= ~(PORT_92_RESET | PORT_92_A20);
if (reset) if (reset)
dev->flags |= PORT_92_RESET; dev->flags |= PORT_92_RESET;
timer_disable(&dev->pulse_timer); timer_disable(&dev->pulse_timer);
if (a20) { if (a20) {
dev->flags |= PORT_92_A20; dev->flags |= PORT_92_A20;
mem_a20_alt = (dev->reg & 2); mem_a20_alt = (dev->reg & 2);
} else } else
mem_a20_alt = 0; mem_a20_alt = 0;
mem_a20_recalc(); mem_a20_recalc();
} }
void void
port_92_add(void *priv) port_92_add(void *priv)
{ {
port_92_t *dev = (port_92_t *) priv; port_92_t *dev = (port_92_t *) priv;
if (dev->flags & (PORT_92_WORD | PORT_92_PCI)) if (dev->flags & (PORT_92_WORD | PORT_92_PCI))
io_sethandler(0x0092, 2, io_sethandler(0x0092, 2,
port_92_readb, port_92_readw, NULL, port_92_writeb, port_92_writew, NULL, dev); port_92_readb, port_92_readw, NULL, port_92_writeb, port_92_writew, NULL, dev);
else else
io_sethandler(0x0092, 1, io_sethandler(0x0092, 1,
port_92_readb, NULL, NULL, port_92_writeb, NULL, NULL, dev); port_92_readb, NULL, NULL, port_92_writeb, NULL, NULL, dev);
} }
void void
port_92_remove(void *priv) port_92_remove(void *priv)
{ {
port_92_t *dev = (port_92_t *) priv; port_92_t *dev = (port_92_t *) priv;
if (dev->flags & (PORT_92_WORD | PORT_92_PCI)) if (dev->flags & (PORT_92_WORD | PORT_92_PCI))
io_removehandler(0x0092, 2, io_removehandler(0x0092, 2,
port_92_readb, port_92_readw, NULL, port_92_writeb, port_92_writew, NULL, dev); port_92_readb, port_92_readw, NULL, port_92_writeb, port_92_writew, NULL, dev);
else else
io_removehandler(0x0092, 1, io_removehandler(0x0092, 1,
port_92_readb, NULL, NULL, port_92_writeb, NULL, NULL, dev); port_92_readb, NULL, NULL, port_92_writeb, NULL, NULL, dev);
} }
static void static void
port_92_close(void *priv) port_92_close(void *priv)
{ {
@@ -188,7 +176,6 @@ port_92_close(void *priv)
free(dev); free(dev);
} }
void * void *
port_92_init(const device_t *info) port_92_init(const device_t *info)
{ {
@@ -199,7 +186,7 @@ port_92_init(const device_t *info)
timer_add(&dev->pulse_timer, port_92_pulse, dev, 0); timer_add(&dev->pulse_timer, port_92_pulse, dev, 0);
dev->reg = 0; dev->reg = 0;
mem_a20_alt = 0; mem_a20_alt = 0;
mem_a20_recalc(); mem_a20_recalc();
@@ -209,7 +196,7 @@ port_92_init(const device_t *info)
port_92_add(dev); port_92_add(dev);
dev->pulse_period = (uint64_t) (4.0 * SYSCLK * (double)(1ULL << 32ULL)); dev->pulse_period = (uint64_t) (4.0 * SYSCLK * (double) (1ULL << 32ULL));
dev->flags |= (PORT_92_RESET | PORT_92_A20); dev->flags |= (PORT_92_RESET | PORT_92_A20);
@@ -217,57 +204,57 @@ port_92_init(const device_t *info)
} }
const device_t port_92_device = { const device_t port_92_device = {
.name = "Port 92 Register", .name = "Port 92 Register",
.internal_name = "port_92", .internal_name = "port_92",
.flags = 0, .flags = 0,
.local = 0, .local = 0,
.init = port_92_init, .init = port_92_init,
.close = port_92_close, .close = port_92_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t port_92_inv_device = { const device_t port_92_inv_device = {
.name = "Port 92 Register (inverted bits 2-7)", .name = "Port 92 Register (inverted bits 2-7)",
.internal_name = "port_92_inv", .internal_name = "port_92_inv",
.flags = 0, .flags = 0,
.local = PORT_92_INV, .local = PORT_92_INV,
.init = port_92_init, .init = port_92_init,
.close = port_92_close, .close = port_92_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t port_92_word_device = { const device_t port_92_word_device = {
.name = "Port 92 Register (16-bit)", .name = "Port 92 Register (16-bit)",
.internal_name = "port_92_word", .internal_name = "port_92_word",
.flags = 0, .flags = 0,
.local = PORT_92_WORD, .local = PORT_92_WORD,
.init = port_92_init, .init = port_92_init,
.close = port_92_close, .close = port_92_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t port_92_pci_device = { const device_t port_92_pci_device = {
.name = "Port 92 Register (PCI)", .name = "Port 92 Register (PCI)",
.internal_name = "port_92_pci", .internal_name = "port_92_pci",
.flags = 0, .flags = 0,
.local = PORT_92_PCI, .local = PORT_92_PCI,
.init = port_92_init, .init = port_92_init,
.close = port_92_close, .close = port_92_close,
.reset = NULL, .reset = NULL,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

View File

@@ -15,11 +15,9 @@
#include <86box/pit.h> #include <86box/pit.h>
#include <86box/ppi.h> #include <86box/ppi.h>
PPI ppi; PPI ppi;
int ppispeakon; int ppispeakon;
void void
ppi_reset(void) ppi_reset(void)
{ {

View File

@@ -18,79 +18,83 @@
#include <stdlib.h> #include <stdlib.h>
#include <86box/random.h> #include <86box/random.h>
#if !(defined(__i386__) || defined (__x86_64__)) #if !(defined(__i386__) || defined(__x86_64__))
#include <time.h> # include <time.h>
#endif #endif
uint32_t preconst = 0x6ED9EBA1; uint32_t preconst = 0x6ED9EBA1;
static __inline uint32_t
static __inline uint32_t rotl32c (uint32_t x, uint32_t n) rotl32c(uint32_t x, uint32_t n)
{ {
#if 0 #if 0
assert (n<32); assert (n<32);
#endif #endif
return (x<<n) | (x>>(-n&31)); return (x << n) | (x >> (-n & 31));
} }
static __inline uint32_t rotr32c (uint32_t x, uint32_t n) static __inline uint32_t
rotr32c(uint32_t x, uint32_t n)
{ {
#if 0 #if 0
assert (n<32); assert (n<32);
#endif #endif
return (x>>n) | (x<<(-n&31)); return (x >> n) | (x << (-n & 31));
} }
#define ROTATE_LEFT rotl32c #define ROTATE_LEFT rotl32c
#define ROTATE_RIGHT rotr32c #define ROTATE_RIGHT rotr32c
static __inline unsigned long long rdtsc(void) static __inline unsigned long long
rdtsc(void)
{ {
#if defined(__i386__) || defined (__x86_64__) #if defined(__i386__) || defined(__x86_64__)
unsigned hi, lo; unsigned hi, lo;
#ifdef _MSC_VER # ifdef _MSC_VER
__asm { __asm {
rdtsc rdtsc
mov hi, edx ; EDX:EAX is already standard return!! mov hi, edx ; EDX:EAX is already standard return!!
mov lo, eax mov lo, eax
} }
# else
__asm__ __volatile__("rdtsc"
: "=a"(lo), "=d"(hi));
# endif
return ((unsigned long long) lo) | (((unsigned long long) hi) << 32);
#else #else
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); return time(NULL);
#endif
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
#else
return time(NULL);
#endif #endif
} }
static uint32_t RDTSC(void) static uint32_t
RDTSC(void)
{ {
return (uint32_t) (rdtsc()); return (uint32_t) (rdtsc());
} }
static void
static void random_twist(uint32_t *val) random_twist(uint32_t *val)
{ {
*val = ROTATE_LEFT(*val, rand() % 32); *val = ROTATE_LEFT(*val, rand() % 32);
*val ^= 0x5A827999; *val ^= 0x5A827999;
*val = ROTATE_RIGHT(*val, rand() % 32); *val = ROTATE_RIGHT(*val, rand() % 32);
*val ^= 0x4ED32706; *val ^= 0x4ED32706;
} }
uint8_t
uint8_t random_generate(void) random_generate(void)
{ {
uint16_t r = 0; uint16_t r = 0;
r = (RDTSC() ^ ROTATE_LEFT(preconst, rand() % 32)) % 256; r = (RDTSC() ^ ROTATE_LEFT(preconst, rand() % 32)) % 256;
random_twist(&preconst); random_twist(&preconst);
return (r & 0xff); return (r & 0xff);
} }
void
void random_init(void) random_init(void)
{ {
uint32_t seed = RDTSC(); uint32_t seed = RDTSC();
srand(seed); srand(seed);
return; return;
} }

View File

@@ -5,11 +5,10 @@
#include <86box/plat.h> #include <86box/plat.h>
#include <86box/thread.h> #include <86box/thread.h>
struct event_cpp11_t struct event_cpp11_t {
{
std::condition_variable cond; std::condition_variable cond;
std::mutex mutex; std::mutex mutex;
bool state = false; bool state = false;
}; };
extern "C" { extern "C" {
@@ -18,7 +17,7 @@ thread_t *
thread_create(void (*thread_rout)(void *param), void *param) thread_create(void (*thread_rout)(void *param), void *param)
{ {
auto thread = new std::thread([thread_rout, param] { auto thread = new std::thread([thread_rout, param] {
thread_rout(param); thread_rout(param);
}); });
return thread; return thread;
} }
@@ -26,8 +25,9 @@ thread_create(void (*thread_rout)(void *param), void *param)
int int
thread_wait(thread_t *arg) thread_wait(thread_t *arg)
{ {
if (!arg) return 0; if (!arg)
auto thread = reinterpret_cast<std::thread*>(arg); return 0;
auto thread = reinterpret_cast<std::thread *>(arg);
thread->join(); thread->join();
return 0; return 0;
} }
@@ -43,9 +43,9 @@ int
thread_test_mutex(mutex_t *_mutex) thread_test_mutex(mutex_t *_mutex)
{ {
if (_mutex == nullptr) if (_mutex == nullptr)
return 0; return 0;
auto mutex = reinterpret_cast<std::mutex*>(_mutex); auto mutex = reinterpret_cast<std::mutex *>(_mutex);
return mutex->try_lock() ? 1 : 0; return mutex->try_lock() ? 1 : 0;
} }
@@ -53,30 +53,28 @@ int
thread_wait_mutex(mutex_t *_mutex) thread_wait_mutex(mutex_t *_mutex)
{ {
if (_mutex == nullptr) if (_mutex == nullptr)
return 0; return 0;
auto mutex = reinterpret_cast<std::mutex*>(_mutex); auto mutex = reinterpret_cast<std::mutex *>(_mutex);
mutex->lock(); mutex->lock();
return 1; return 1;
} }
int int
thread_release_mutex(mutex_t *_mutex) thread_release_mutex(mutex_t *_mutex)
{ {
if (_mutex == nullptr) if (_mutex == nullptr)
return 0; return 0;
auto mutex = reinterpret_cast<std::mutex*>(_mutex); auto mutex = reinterpret_cast<std::mutex *>(_mutex);
mutex->unlock(); mutex->unlock();
return 1; return 1;
} }
void void
thread_close_mutex(mutex_t *_mutex) thread_close_mutex(mutex_t *_mutex)
{ {
auto mutex = reinterpret_cast<std::mutex*>(_mutex); auto mutex = reinterpret_cast<std::mutex *>(_mutex);
delete mutex; delete mutex;
} }
@@ -90,13 +88,13 @@ thread_create_event()
int int
thread_wait_event(event_t *handle, int timeout) thread_wait_event(event_t *handle, int timeout)
{ {
auto event = reinterpret_cast<event_cpp11_t*>(handle); auto event = reinterpret_cast<event_cpp11_t *>(handle);
auto lock = std::unique_lock<std::mutex>(event->mutex); auto lock = std::unique_lock<std::mutex>(event->mutex);
if (timeout < 0) { if (timeout < 0) {
event->cond.wait(lock, [event] { return event->state; }); event->cond.wait(lock, [event] { return event->state; });
} else { } else {
auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
std::cv_status status; std::cv_status status;
do { do {
@@ -113,9 +111,9 @@ thread_wait_event(event_t *handle, int timeout)
void void
thread_set_event(event_t *handle) thread_set_event(event_t *handle)
{ {
auto event = reinterpret_cast<event_cpp11_t*>(handle); auto event = reinterpret_cast<event_cpp11_t *>(handle);
{ {
auto lock = std::unique_lock<std::mutex>(event->mutex); auto lock = std::unique_lock<std::mutex>(event->mutex);
event->state = true; event->state = true;
} }
event->cond.notify_all(); event->cond.notify_all();
@@ -124,16 +122,15 @@ thread_set_event(event_t *handle)
void void
thread_reset_event(event_t *handle) thread_reset_event(event_t *handle)
{ {
auto event = reinterpret_cast<event_cpp11_t*>(handle); auto event = reinterpret_cast<event_cpp11_t *>(handle);
auto lock = std::unique_lock<std::mutex>(event->mutex); auto lock = std::unique_lock<std::mutex>(event->mutex);
event->state = false; event->state = false;
} }
void void
thread_destroy_event(event_t *handle) thread_destroy_event(event_t *handle)
{ {
auto event = reinterpret_cast<event_cpp11_t*>(handle); auto event = reinterpret_cast<event_cpp11_t *>(handle);
delete event; delete event;
} }
} }

View File

@@ -5,7 +5,6 @@
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/timer.h> #include <86box/timer.h>
uint64_t TIMER_USEC; uint64_t TIMER_USEC;
uint32_t timer_target; uint32_t timer_target;
@@ -16,29 +15,28 @@ pc_timer_t *timer_head = NULL;
/* Are we initialized? */ /* Are we initialized? */
int timer_inited = 0; int timer_inited = 0;
void void
timer_enable(pc_timer_t *timer) timer_enable(pc_timer_t *timer)
{ {
pc_timer_t *timer_node = timer_head; pc_timer_t *timer_node = timer_head;
if (!timer_inited || (timer == NULL)) if (!timer_inited || (timer == NULL))
return; return;
if (timer->flags & TIMER_ENABLED) if (timer->flags & TIMER_ENABLED)
timer_disable(timer); timer_disable(timer);
if (timer->next || timer->prev) if (timer->next || timer->prev)
fatal("timer_enable - timer->next\n"); fatal("timer_enable - timer->next\n");
timer->flags |= TIMER_ENABLED; timer->flags |= TIMER_ENABLED;
/*List currently empty - add to head*/ /*List currently empty - add to head*/
if (!timer_head) { if (!timer_head) {
timer_head = timer; timer_head = timer;
timer->next = timer->prev = NULL; timer->next = timer->prev = NULL;
timer_target = timer_head->ts.ts32.integer; timer_target = timer_head->ts.ts32.integer;
return; return;
} }
if (TIMER_LESS_THAN(timer, timer_head)) { if (TIMER_LESS_THAN(timer, timer_head)) {
@@ -57,83 +55,80 @@ timer_enable(pc_timer_t *timer)
} }
pc_timer_t *prev = timer_head; pc_timer_t *prev = timer_head;
timer_node = timer_head->next; timer_node = timer_head->next;
while(1) { while (1) {
/*Timer expires before timer_node. Add to list in front of timer_node*/ /*Timer expires before timer_node. Add to list in front of timer_node*/
if (TIMER_LESS_THAN(timer, timer_node)) { if (TIMER_LESS_THAN(timer, timer_node)) {
timer->next = timer_node; timer->next = timer_node;
timer->prev = prev; timer->prev = prev;
timer_node->prev = timer; timer_node->prev = timer;
prev->next = timer; prev->next = timer;
return; return;
} }
/*timer_node is last in the list. Add timer to end of list*/ /*timer_node is last in the list. Add timer to end of list*/
if (!timer_node->next) { if (!timer_node->next) {
timer_node->next = timer; timer_node->next = timer;
timer->prev = timer_node; timer->prev = timer_node;
return; return;
} }
prev = timer_node; prev = timer_node;
timer_node = timer_node->next; timer_node = timer_node->next;
} }
} }
void void
timer_disable(pc_timer_t *timer) timer_disable(pc_timer_t *timer)
{ {
if (!timer_inited || (timer == NULL) || !(timer->flags & TIMER_ENABLED)) if (!timer_inited || (timer == NULL) || !(timer->flags & TIMER_ENABLED))
return; return;
if (!timer->next && !timer->prev && timer != timer_head) if (!timer->next && !timer->prev && timer != timer_head)
fatal("timer_disable - !timer->next\n"); fatal("timer_disable - !timer->next\n");
timer->flags &= ~TIMER_ENABLED; timer->flags &= ~TIMER_ENABLED;
if (timer->prev) if (timer->prev)
timer->prev->next = timer->next; timer->prev->next = timer->next;
else else
timer_head = timer->next; timer_head = timer->next;
if (timer->next) if (timer->next)
timer->next->prev = timer->prev; timer->next->prev = timer->prev;
timer->prev = timer->next = NULL; timer->prev = timer->next = NULL;
} }
void void
timer_process(void) timer_process(void)
{ {
pc_timer_t *timer; pc_timer_t *timer;
if (!timer_head) if (!timer_head)
return; return;
while(1) { while (1) {
timer = timer_head; timer = timer_head;
if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) if (!TIMER_LESS_THAN_VAL(timer, (uint32_t) tsc))
break; break;
timer_head = timer->next; timer_head = timer->next;
if (timer_head) if (timer_head)
timer_head->prev = NULL; timer_head->prev = NULL;
timer->next = timer->prev = NULL; timer->next = timer->prev = NULL;
timer->flags &= ~TIMER_ENABLED; timer->flags &= ~TIMER_ENABLED;
if (timer->flags & TIMER_SPLIT) if (timer->flags & TIMER_SPLIT)
timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */
else if (timer->callback != NULL) /* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */ else if (timer->callback != NULL) /* Make sure it's no NULL, so that we can have a NULL callback when no operation is needed. */
timer->callback(timer->p); timer->callback(timer->p);
} }
timer_target = timer_head->ts.ts32.integer; timer_target = timer_head->ts.ts32.integer;
} }
void void
timer_close(void) timer_close(void)
{ {
@@ -143,9 +138,9 @@ timer_close(void)
timers that are not in malloc'd structs don't keep pointing timers that are not in malloc'd structs don't keep pointing
to timers that may be in malloc'd structs. */ to timers that may be in malloc'd structs. */
while (t != NULL) { while (t != NULL) {
r = t; r = t;
r->prev = r->next = NULL; r->prev = r->next = NULL;
t = r->next; t = r->next;
} }
timer_head = NULL; timer_head = NULL;
@@ -153,97 +148,90 @@ timer_close(void)
timer_inited = 0; timer_inited = 0;
} }
void void
timer_init(void) timer_init(void)
{ {
timer_target = 0ULL; timer_target = 0ULL;
tsc = 0; tsc = 0;
timer_inited = 1; timer_inited = 1;
} }
void void
timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer) timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer)
{ {
memset(timer, 0, sizeof(pc_timer_t)); memset(timer, 0, sizeof(pc_timer_t));
timer->callback = callback; timer->callback = callback;
timer->p = p; timer->p = p;
timer->flags = 0; timer->flags = 0;
timer->prev = timer->next = NULL; timer->prev = timer->next = NULL;
if (start_timer) if (start_timer)
timer_set_delay_u64(timer, 0); timer_set_delay_u64(timer, 0);
} }
/* The API for big timer periods starts here. */ /* The API for big timer periods starts here. */
void void
timer_stop(pc_timer_t *timer) timer_stop(pc_timer_t *timer)
{ {
if (!timer_inited || (timer == NULL)) if (!timer_inited || (timer == NULL))
return; return;
timer->period = 0.0; timer->period = 0.0;
timer_disable(timer); timer_disable(timer);
timer->flags &= ~TIMER_SPLIT; timer->flags &= ~TIMER_SPLIT;
} }
static void static void
timer_do_period(pc_timer_t *timer, uint64_t period, int start) timer_do_period(pc_timer_t *timer, uint64_t period, int start)
{ {
if (!timer_inited || (timer == NULL)) if (!timer_inited || (timer == NULL))
return; return;
if (start) if (start)
timer_set_delay_u64(timer, period); timer_set_delay_u64(timer, period);
else else
timer_advance_u64(timer, period); timer_advance_u64(timer, period);
} }
void void
timer_advance_ex(pc_timer_t *timer, int start) timer_advance_ex(pc_timer_t *timer, int start)
{ {
if (!timer_inited || (timer == NULL)) if (!timer_inited || (timer == NULL))
return; return;
if (timer->period > MAX_USEC) { if (timer->period > MAX_USEC) {
timer_do_period(timer, MAX_USEC64 * TIMER_USEC, start); timer_do_period(timer, MAX_USEC64 * TIMER_USEC, start);
timer->period -= MAX_USEC; timer->period -= MAX_USEC;
timer->flags |= TIMER_SPLIT; timer->flags |= TIMER_SPLIT;
} else { } else {
if (timer->period > 0.0) if (timer->period > 0.0)
timer_do_period(timer, (uint64_t) (timer->period * ((double) TIMER_USEC)), start); timer_do_period(timer, (uint64_t) (timer->period * ((double) TIMER_USEC)), start);
else else
timer_disable(timer); timer_disable(timer);
timer->period = 0.0; timer->period = 0.0;
timer->flags &= ~TIMER_SPLIT; timer->flags &= ~TIMER_SPLIT;
} }
} }
void void
timer_on(pc_timer_t *timer, double period, int start) timer_on(pc_timer_t *timer, double period, int start)
{ {
if (!timer_inited || (timer == NULL)) if (!timer_inited || (timer == NULL))
return; return;
timer->period = period; timer->period = period;
timer_advance_ex(timer, start); timer_advance_ex(timer, start);
} }
void void
timer_on_auto(pc_timer_t *timer, double period) timer_on_auto(pc_timer_t *timer, double period)
{ {
if (!timer_inited || (timer == NULL)) if (!timer_inited || (timer == NULL))
return; return;
if (period > 0.0) if (period > 0.0)
timer_on(timer, period, (timer->period == 0.0)); timer_on(timer, period, (timer->period == 0.0));
else else
timer_stop(timer); timer_stop(timer);
} }

View File

@@ -31,18 +31,16 @@
fflush(stdout); \ fflush(stdout); \
} }
#else #else
#include <stdarg.h> # include <stdarg.h>
#define HAVE_STDARG_H # define HAVE_STDARG_H
#include <86box/86box.h> # include <86box/86box.h>
#include <86box/device.h> # include <86box/device.h>
#include <86box/io.h> # include <86box/io.h>
#include <86box/timer.h> # include <86box/timer.h>
# ifdef ENABLE_UPI42_LOG
#ifdef ENABLE_UPI42_LOG
int upi42_do_log = ENABLE_UPI42_LOG; int upi42_do_log = ENABLE_UPI42_LOG;
void void
upi42_log(const char *fmt, ...) upi42_log(const char *fmt, ...)
{ {
@@ -54,9 +52,9 @@ upi42_log(const char *fmt, ...)
va_end(ap); va_end(ap);
} }
} }
#else # else
#define upi42_log(fmt, ...) # define upi42_log(fmt, ...)
#endif # endif
#endif #endif
#define UPI42_REG(upi42, r, op) ((upi42->psw & 0x10) ? (upi42->ram[24 + ((r) &7)] op) : (upi42->ram[(r) &7] op)) #define UPI42_REG(upi42, r, op) ((upi42->psw & 0x10) ? (upi42->ram[24 + ((r) &7)] op) : (upi42->ram[(r) &7] op))
@@ -97,7 +95,7 @@ typedef struct _upi42_ {
int cycs; /* cycle counter */ int cycs; /* cycle counter */
#ifndef UPI42_STANDALONE #ifndef UPI42_STANDALONE
uint8_t ram_index; uint8_t ram_index;
uint16_t rom_index; uint16_t rom_index;
#endif #endif
} upi42_t; } upi42_t;
@@ -1178,275 +1176,273 @@ upi42_write(uint16_t port, uint8_t val, void *priv)
int i; int i;
switch (port) { switch (port) {
/* Write to data port. */ /* Write to data port. */
case 0x0060: case 0x0060:
case 0x0160: case 0x0160:
upi42_dbb_write(0, val, upi42); upi42_dbb_write(0, val, upi42);
break; break;
/* RAM Index. */ /* RAM Index. */
case 0x0162: case 0x0162:
upi42->ram_index = val & upi42->rammask; upi42->ram_index = val & upi42->rammask;
break; break;
/* RAM. */ /* RAM. */
case 0x0163: case 0x0163:
upi42->ram[upi42->ram_index & upi42->rammask] = val; upi42->ram[upi42->ram_index & upi42->rammask] = val;
break; break;
/* Write to command port. */ /* Write to command port. */
case 0x0064: case 0x0064:
case 0x0164: case 0x0164:
upi42_cmd_write(0, val, upi42); upi42_cmd_write(0, val, upi42);
break; break;
/* Input ports. */ /* Input ports. */
case 0x0180 ... 0x0187: case 0x0180 ... 0x0187:
upi42->ports_in[addr & 0x0007] = val; upi42->ports_in[addr & 0x0007] = val;
break; break;
/* Output ports. */ /* Output ports. */
case 0x0188 ... 0x018f: case 0x0188 ... 0x018f:
upi42->ports_out[addr & 0x0007] = val; upi42->ports_out[addr & 0x0007] = val;
break; break;
/* 4 = T0, 5 = T1. */ /* 4 = T0, 5 = T1. */
case 0x0194: case 0x0194:
upi42->t0 = (val >> 4) & 0x01; upi42->t0 = (val >> 4) & 0x01;
upi42->t1 = (val >> 5) & 0x01; upi42->t1 = (val >> 5) & 0x01;
break; break;
/* Program counter. */ /* Program counter. */
case 0x0196: case 0x0196:
upi42->pc = (upi42->pc & 0xff00) | val; upi42->pc = (upi42->pc & 0xff00) | val;
break; break;
case 0x0197: case 0x0197:
upi42->pc = (upi42->pc & 0x00ff) | (val << 8); upi42->pc = (upi42->pc & 0x00ff) | (val << 8);
break; break;
/* Input data buffer. */ /* Input data buffer. */
case 0x019a: case 0x019a:
upi42->dbb_in = val; upi42->dbb_in = val;
break; break;
/* Output data buffer. */ /* Output data buffer. */
case 0x019b: case 0x019b:
upi42->dbb_out = val; upi42->dbb_out = val;
break; break;
/* ROM Index. */ /* ROM Index. */
case 0x01a0: case 0x01a0:
upi42->rom_index = (upi42->rom_index & 0xff00) | val; upi42->rom_index = (upi42->rom_index & 0xff00) | val;
break; break;
case 0x01a1: case 0x01a1:
upi42->rom_index = (upi42->rom_index & 0x00ff) | (val << 8); upi42->rom_index = (upi42->rom_index & 0x00ff) | (val << 8);
break; break;
/* Hard reset. */ /* Hard reset. */
case 0x01a2: case 0x01a2:
temp_type = upi42->type; temp_type = upi42->type;
temp_rom = upi42->rom; temp_rom = upi42->rom;
upi42_do_init(temp_type, temp_rom); upi42_do_init(temp_type, temp_rom);
break; break;
/* Soft reset. */ /* Soft reset. */
case 0x01a3: case 0x01a3:
upi42_reset(upi42); upi42_reset(upi42);
break; break;
/* ROM. */ /* ROM. */
case 0x01a4: case 0x01a4:
upi42->rom[upi42->rom_index & upi42->rommask] = val; upi42->rom[upi42->rom_index & upi42->rommask] = val;
break; break;
case 0x01a5: case 0x01a5:
upi42->rom[(upi42->rom_index + 1) & upi42->rommask] = val; upi42->rom[(upi42->rom_index + 1) & upi42->rommask] = val;
break; break;
case 0x01a6: case 0x01a6:
upi42->rom[(upi42->rom_index + 2) & upi42->rommask] = val; upi42->rom[(upi42->rom_index + 2) & upi42->rommask] = val;
break; break;
case 0x01a7: case 0x01a7:
upi42->rom[(upi42->rom_index + 3) & upi42->rommask] = val; upi42->rom[(upi42->rom_index + 3) & upi42->rommask] = val;
break; break;
/* Pause. */ /* Pause. */
case 0x01a8: case 0x01a8:
break; break;
/* Resume. */ /* Resume. */
case 0x01a9: case 0x01a9:
break; break;
/* Bus master ROM: 0 = direction (0 = to memory, 1 = from memory). */ /* Bus master ROM: 0 = direction (0 = to memory, 1 = from memory). */
case 0x01aa: case 0x01aa:
if (val & 0x01) { if (val & 0x01) {
for (i = 0; i <= upi42->rommask; i += 4) for (i = 0; i <= upi42->rommask; i += 4)
*(uint32_t *) &(upi42->rom[i]) = mem_readl_phys(upi42->ram_addr + i); *(uint32_t *) &(upi42->rom[i]) = mem_readl_phys(upi42->ram_addr + i);
} else { } else {
for (i = 0; i <= upi42->rommask; i += 4) for (i = 0; i <= upi42->rommask; i += 4)
mem_writel_phys(upi42->ram_addr + i, *(uint32_t *) &(upi42->rom[i])); mem_writel_phys(upi42->ram_addr + i, *(uint32_t *) &(upi42->rom[i]));
} }
upi42->bm_stat = (val & 0x01) | 0x02; upi42->bm_stat = (val & 0x01) | 0x02;
break; break;
} }
} }
static uint8_t static uint8_t
upi42_read(uint16_t port, void *priv) upi42_read(uint16_t port, void *priv)
{ {
upi42_t *upi42 = (upi42_t *) priv; upi42_t *upi42 = (upi42_t *) priv;
uint8_t ret = 0xff; uint8_t ret = 0xff;
switch (port) { switch (port) {
/* Type. */ /* Type. */
case 0x015c: case 0x015c:
ret = upi42->type & 0xff; ret = upi42->type & 0xff;
break; break;
case 0x015d: case 0x015d:
ret = upi42->type >> 8; ret = upi42->type >> 8;
break; break;
case 0x015e: case 0x015e:
ret = upi42->type >> 16; ret = upi42->type >> 16;
break; break;
case 0x015f: case 0x015f:
ret = upi42->type >> 24; ret = upi42->type >> 24;
break; break;
/* Read from data port and reset OBF. */ /* Read from data port and reset OBF. */
case 0x0060: case 0x0060:
case 0x0160: case 0x0160:
ret = upi42->dbb_out; ret = upi42->dbb_out;
upi42->sts &= ~0x01; /* clear OBF */ upi42->sts &= ~0x01; /* clear OBF */
break; break;
/* RAM Mask. */ /* RAM Mask. */
case 0x0161: case 0x0161:
ret = upi42->rammask; ret = upi42->rammask;
break; break;
/* RAM Index. */ /* RAM Index. */
case 0x0162: case 0x0162:
ret = upi42->ram_index; ret = upi42->ram_index;
break; break;
/* RAM. */ /* RAM. */
case 0x0163: case 0x0163:
ret = upi42->ram[upi42->ram_index & upi42->rammask]; ret = upi42->ram[upi42->ram_index & upi42->rammask];
break; break;
/* Read status. */ /* Read status. */
case 0x0064: case 0x0064:
case 0x0164: case 0x0164:
ret = upi42->sts; ret = upi42->sts;
break; break;
/* Input ports. */ /* Input ports. */
case 0x0180 ... 0x0187: case 0x0180 ... 0x0187:
ret = upi42->ports_in[addr & 0x0007]; ret = upi42->ports_in[addr & 0x0007];
break; break;
/* Output ports. */ /* Output ports. */
case 0x0188 ... 0x018f: case 0x0188 ... 0x018f:
ret = upi42->ports_out[addr & 0x0007]; ret = upi42->ports_out[addr & 0x0007];
break; break;
/* Accumulator. */ /* Accumulator. */
case 0x0190: case 0x0190:
ret = upi42->a; ret = upi42->a;
break; break;
/* Timer counter. */ /* Timer counter. */
case 0x0191: case 0x0191:
ret = upi42->t; ret = upi42->t;
break; break;
/* Program status word. */ /* Program status word. */
case 0x0192: case 0x0192:
ret = upi42->psw; ret = upi42->psw;
break; break;
/* 0-4 = Prescaler, 5 = TF, 6 = Skip Timer Inc, 7 = Run Timer. */ /* 0-4 = Prescaler, 5 = TF, 6 = Skip Timer Inc, 7 = Run Timer. */
case 0x0193: case 0x0193:
ret = (upi42->prescaler & 0x1f) || ((upi42->tf & 0x01) << 5) || ((upi42->skip_timer_inc & 0x01) << 6) || ((upi42->run_timer & 0x01) << 7); ret = (upi42->prescaler & 0x1f) || ((upi42->tf & 0x01) << 5) || ((upi42->skip_timer_inc & 0x01) << 6) || ((upi42->run_timer & 0x01) << 7);
break; break;
/* 0 = I, 1 = I Raise, 2 = TCNTI Raise, 3 = IRQ Mask, 4 = T0, 5 = T1, 6 = Flags, 7 = DBF. */ /* 0 = I, 1 = I Raise, 2 = TCNTI Raise, 3 = IRQ Mask, 4 = T0, 5 = T1, 6 = Flags, 7 = DBF. */
case 0x0194: case 0x0194:
ret = (upi42->i & 0x01) || ((upi42->i_raise & 0x01) << 1) || ((upi42->tcnti_raise & 0x01) << 2) || ((upi42->irq_mask & 0x01) << 3) || ret = (upi42->i & 0x01) || ((upi42->i_raise & 0x01) << 1) || ((upi42->tcnti_raise & 0x01) << 2) || ((upi42->irq_mask & 0x01) << 3) || ((upi42->t0 & 0x01) << 4) || ((upi42->t1 & 0x01) << 5) || ((upi42->flags & 0x01) << 6) || ((upi42->dbf & 0x01) << 7);
((upi42->t0 & 0x01) << 4) || ((upi42->t1 & 0x01) << 5) || ((upi42->flags & 0x01) << 6) || ((upi42->dbf & 0x01) << 7); break;
break;
/* 0 = Suspend. */ /* 0 = Suspend. */
case 0x0195: case 0x0195:
ret = (upi42->suspend & 0x01); ret = (upi42->suspend & 0x01);
break; break;
/* Program counter. */ /* Program counter. */
case 0x0196: case 0x0196:
ret = upi42->pc & 0xff; ret = upi42->pc & 0xff;
break; break;
case 0x0197: case 0x0197:
ret = upi42->pc >> 8; ret = upi42->pc >> 8;
break; break;
/* ROM Mask. */ /* ROM Mask. */
case 0x0198: case 0x0198:
ret = upi42->rommask & 0xff; ret = upi42->rommask & 0xff;
break; break;
case 0x0199: case 0x0199:
ret = upi42->rommask >> 8; ret = upi42->rommask >> 8;
break; break;
/* Input data buffer. */ /* Input data buffer. */
case 0x019a: case 0x019a:
ret = upi42->dbb_in; ret = upi42->dbb_in;
break; break;
/* Output data buffer. */ /* Output data buffer. */
case 0x019b: case 0x019b:
ret = upi42->dbb_out; ret = upi42->dbb_out;
break; break;
/* Cycle counter. */ /* Cycle counter. */
case 0x019c: case 0x019c:
ret = upi42->cycs & 0xff; ret = upi42->cycs & 0xff;
break; break;
case 0x019d: case 0x019d:
ret = upi42->cycs >> 8; ret = upi42->cycs >> 8;
break; break;
case 0x019e: case 0x019e:
ret = upi42->cycs >> 16; ret = upi42->cycs >> 16;
break; break;
case 0x019f: case 0x019f:
ret = upi42->cycs >> 24; ret = upi42->cycs >> 24;
break; break;
/* ROM Index. */ /* ROM Index. */
case 0x01a0: case 0x01a0:
ret = upi42->rom_index & 0xff; ret = upi42->rom_index & 0xff;
break; break;
case 0x01a1: case 0x01a1:
ret = upi42->rom_index >> 8; ret = upi42->rom_index >> 8;
break; break;
/* ROM. */ /* ROM. */
case 0x01a4: case 0x01a4:
ret = upi42->rom[upi42->rom_index & upi42->rommask]; ret = upi42->rom[upi42->rom_index & upi42->rommask];
break; break;
case 0x01a5: case 0x01a5:
ret = upi42->rom[(upi42->rom_index + 1) & upi42->rommask]; ret = upi42->rom[(upi42->rom_index + 1) & upi42->rommask];
break; break;
case 0x01a6: case 0x01a6:
ret = upi42->rom[(upi42->rom_index + 2) & upi42->rommask]; ret = upi42->rom[(upi42->rom_index + 2) & upi42->rommask];
break; break;
case 0x01a7: case 0x01a7:
ret = upi42->rom[(upi42->rom_index + 3) & upi42->rommask]; ret = upi42->rom[(upi42->rom_index + 3) & upi42->rommask];
break; break;
/* Bus master status: 0 = direction, 1 = finished. */ /* Bus master status: 0 = direction, 1 = finished. */
case 0x01ab: case 0x01ab:
ret = upi42->bm_stat; ret = upi42->bm_stat;
break; break;
} }
return ret; return ret;

484
src/usb.c
View File

@@ -29,31 +29,28 @@
#include <86box/usb.h> #include <86box/usb.h>
#include "cpu.h" #include "cpu.h"
#ifdef ENABLE_USB_LOG #ifdef ENABLE_USB_LOG
int usb_do_log = ENABLE_USB_LOG; int usb_do_log = ENABLE_USB_LOG;
static void static void
usb_log(const char *fmt, ...) usb_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (usb_do_log) { if (usb_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define usb_log(fmt, ...) # define usb_log(fmt, ...)
#endif #endif
static uint8_t static uint8_t
uhci_reg_read(uint16_t addr, void *p) uhci_reg_read(uint16_t addr, void *p)
{ {
usb_t *dev = (usb_t *) p; usb_t *dev = (usb_t *) p;
uint8_t ret, *regs = dev->uhci_io; uint8_t ret, *regs = dev->uhci_io;
addr &= 0x0000001f; addr &= 0x0000001f;
@@ -63,83 +60,81 @@ uhci_reg_read(uint16_t addr, void *p)
return ret; return ret;
} }
static void static void
uhci_reg_write(uint16_t addr, uint8_t val, void *p) uhci_reg_write(uint16_t addr, uint8_t val, void *p)
{ {
usb_t *dev = (usb_t *) p; usb_t *dev = (usb_t *) p;
uint8_t *regs = dev->uhci_io; uint8_t *regs = dev->uhci_io;
addr &= 0x0000001f; addr &= 0x0000001f;
switch (addr) { switch (addr) {
case 0x02: case 0x02:
regs[0x02] &= ~(val & 0x3f); regs[0x02] &= ~(val & 0x3f);
break; break;
case 0x04: case 0x04:
regs[0x04] = (val & 0x0f); regs[0x04] = (val & 0x0f);
break; break;
case 0x09: case 0x09:
regs[0x09] = (val & 0xf0); regs[0x09] = (val & 0xf0);
break; break;
case 0x0a: case 0x0b: case 0x0a:
regs[addr] = val; case 0x0b:
break; regs[addr] = val;
case 0x0c: break;
regs[0x0c] = (val & 0x7f); case 0x0c:
break; regs[0x0c] = (val & 0x7f);
break;
} }
} }
static void static void
uhci_reg_writew(uint16_t addr, uint16_t val, void *p) uhci_reg_writew(uint16_t addr, uint16_t val, void *p)
{ {
usb_t *dev = (usb_t *) p; usb_t *dev = (usb_t *) p;
uint16_t *regs = (uint16_t *) dev->uhci_io; uint16_t *regs = (uint16_t *) dev->uhci_io;
addr &= 0x0000001f; addr &= 0x0000001f;
switch (addr) { switch (addr) {
case 0x00: case 0x00:
if ((val & 0x0001) && !(regs[0x00] & 0x0001)) if ((val & 0x0001) && !(regs[0x00] & 0x0001))
regs[0x01] &= ~0x20; regs[0x01] &= ~0x20;
else if (!(val & 0x0001)) else if (!(val & 0x0001))
regs[0x01] |= 0x20; regs[0x01] |= 0x20;
regs[0x00] = (val & 0x00ff); regs[0x00] = (val & 0x00ff);
break; break;
case 0x06: case 0x06:
regs[0x03] = (val & 0x07ff); regs[0x03] = (val & 0x07ff);
break; break;
case 0x10: case 0x12: case 0x10:
regs[addr >> 1] = ((regs[addr >> 1] & 0xedbb) | (val & 0x1244)) & ~(val & 0x080a); case 0x12:
break; regs[addr >> 1] = ((regs[addr >> 1] & 0xedbb) | (val & 0x1244)) & ~(val & 0x080a);
default: break;
uhci_reg_write(addr, val & 0xff, p); default:
uhci_reg_write(addr + 1, (val >> 8) & 0xff, p); uhci_reg_write(addr, val & 0xff, p);
break; uhci_reg_write(addr + 1, (val >> 8) & 0xff, p);
break;
} }
} }
void void
uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable) uhci_update_io_mapping(usb_t *dev, uint8_t base_l, uint8_t base_h, int enable)
{ {
if (dev->uhci_enable && (dev->uhci_io_base != 0x0000)) if (dev->uhci_enable && (dev->uhci_io_base != 0x0000))
io_removehandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev); io_removehandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev);
dev->uhci_io_base = base_l | (base_h << 8); dev->uhci_io_base = base_l | (base_h << 8);
dev->uhci_enable = enable; dev->uhci_enable = enable;
if (dev->uhci_enable && (dev->uhci_io_base != 0x0000)) if (dev->uhci_enable && (dev->uhci_io_base != 0x0000))
io_sethandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev); io_sethandler(dev->uhci_io_base, 0x20, uhci_reg_read, NULL, NULL, uhci_reg_write, uhci_reg_writew, NULL, dev);
} }
static uint8_t static uint8_t
ohci_mmio_read(uint32_t addr, void *p) ohci_mmio_read(uint32_t addr, void *p)
{ {
usb_t *dev = (usb_t *) p; usb_t *dev = (usb_t *) p;
uint8_t ret = 0x00; uint8_t ret = 0x00;
addr &= 0x00000fff; addr &= 0x00000fff;
@@ -147,210 +142,222 @@ ohci_mmio_read(uint32_t addr, void *p)
ret = dev->ohci_mmio[addr]; ret = dev->ohci_mmio[addr];
if (addr == 0x101) if (addr == 0x101)
ret = (ret & 0xfe) | (!!mem_a20_key); ret = (ret & 0xfe) | (!!mem_a20_key);
return ret; return ret;
} }
static void static void
ohci_mmio_write(uint32_t addr, uint8_t val, void *p) ohci_mmio_write(uint32_t addr, uint8_t val, void *p)
{ {
usb_t *dev = (usb_t *) p; usb_t *dev = (usb_t *) p;
uint8_t old; uint8_t old;
addr &= 0x00000fff; addr &= 0x00000fff;
switch (addr) { switch (addr) {
case 0x04: case 0x04:
if ((val & 0xc0) == 0x00) { if ((val & 0xc0) == 0x00) {
/* UsbReset */ /* UsbReset */
dev->ohci_mmio[0x56] = dev->ohci_mmio[0x5a] = 0x16; dev->ohci_mmio[0x56] = dev->ohci_mmio[0x5a] = 0x16;
} }
break; break;
case 0x08: /* HCCOMMANDSTATUS */ case 0x08: /* HCCOMMANDSTATUS */
/* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */ /* bit OwnershipChangeRequest triggers an ownership change (SMM <-> OS) */
if (val & 0x08) { if (val & 0x08) {
dev->ohci_mmio[0x0f] = 0x40; dev->ohci_mmio[0x0f] = 0x40;
if ((dev->ohci_mmio[0x13] & 0xc0) == 0xc0) if ((dev->ohci_mmio[0x13] & 0xc0) == 0xc0)
smi_raise(); smi_raise();
} }
/* bit HostControllerReset must be cleared for the controller to be seen as initialized */ /* bit HostControllerReset must be cleared for the controller to be seen as initialized */
if (val & 0x01) { if (val & 0x01) {
memset(dev->ohci_mmio, 0x00, 4096); memset(dev->ohci_mmio, 0x00, 4096);
dev->ohci_mmio[0x00] = 0x10; dev->ohci_mmio[0x00] = 0x10;
dev->ohci_mmio[0x01] = 0x01; dev->ohci_mmio[0x01] = 0x01;
dev->ohci_mmio[0x48] = 0x02; dev->ohci_mmio[0x48] = 0x02;
val &= ~0x01; val &= ~0x01;
} }
break; break;
case 0x0c: case 0x0c:
dev->ohci_mmio[addr] &= ~(val & 0x7f); dev->ohci_mmio[addr] &= ~(val & 0x7f);
return; return;
case 0x0d: case 0x0e: case 0x0d:
return; case 0x0e:
case 0x0f: return;
dev->ohci_mmio[addr] &= ~(val & 0x40); case 0x0f:
return; dev->ohci_mmio[addr] &= ~(val & 0x40);
case 0x3b: return;
dev->ohci_mmio[addr] = (val & 0x80); case 0x3b:
return; dev->ohci_mmio[addr] = (val & 0x80);
case 0x39: case 0x41: return;
dev->ohci_mmio[addr] = (val & 0x3f); case 0x39:
return; case 0x41:
case 0x45: dev->ohci_mmio[addr] = (val & 0x3f);
dev->ohci_mmio[addr] = (val & 0x0f); return;
return; case 0x45:
case 0x3a: dev->ohci_mmio[addr] = (val & 0x0f);
case 0x3e: case 0x3f: case 0x42: case 0x43: return;
case 0x46: case 0x47: case 0x48: case 0x4a: case 0x3a:
return; case 0x3e:
case 0x49: case 0x3f:
dev->ohci_mmio[addr] = (val & 0x1b); case 0x42:
if (val & 0x02) { case 0x43:
dev->ohci_mmio[0x55] |= 0x01; case 0x46:
dev->ohci_mmio[0x59] |= 0x01; case 0x47:
} case 0x48:
return; case 0x4a:
case 0x4b: return;
dev->ohci_mmio[addr] = (val & 0x03); case 0x49:
return; dev->ohci_mmio[addr] = (val & 0x1b);
case 0x4c: case 0x4e: if (val & 0x02) {
dev->ohci_mmio[addr] = (val & 0x06); dev->ohci_mmio[0x55] |= 0x01;
if ((addr == 0x4c) && !(val & 0x04)) { dev->ohci_mmio[0x59] |= 0x01;
if (!(dev->ohci_mmio[0x58] & 0x01)) }
dev->ohci_mmio[0x5a] |= 0x01; return;
dev->ohci_mmio[0x58] |= 0x01; case 0x4b:
} if ((addr == 0x4c) && !(val & 0x02)) { dev->ohci_mmio[addr] = (val & 0x03);
if (!(dev->ohci_mmio[0x54] & 0x01)) return;
dev->ohci_mmio[0x56] |= 0x01; case 0x4c:
dev->ohci_mmio[0x54] |= 0x01; case 0x4e:
} dev->ohci_mmio[addr] = (val & 0x06);
return; if ((addr == 0x4c) && !(val & 0x04)) {
case 0x4d: case 0x4f: if (!(dev->ohci_mmio[0x58] & 0x01))
return; dev->ohci_mmio[0x5a] |= 0x01;
case 0x50: dev->ohci_mmio[0x58] |= 0x01;
if (val & 0x01) { }
if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { if ((addr == 0x4c) && !(val & 0x02)) {
dev->ohci_mmio[0x55] &= ~0x01; if (!(dev->ohci_mmio[0x54] & 0x01))
dev->ohci_mmio[0x54] &= ~0x17; dev->ohci_mmio[0x56] |= 0x01;
dev->ohci_mmio[0x56] &= ~0x17; dev->ohci_mmio[0x54] |= 0x01;
dev->ohci_mmio[0x59] &= ~0x01; }
dev->ohci_mmio[0x58] &= ~0x17; return;
dev->ohci_mmio[0x5a] &= ~0x17; case 0x4d:
} else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { case 0x4f:
if (!(dev->ohci_mmio[0x4e] & 0x02)) { return;
dev->ohci_mmio[0x55] &= ~0x01; case 0x50:
dev->ohci_mmio[0x54] &= ~0x17; if (val & 0x01) {
dev->ohci_mmio[0x56] &= ~0x17; if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) {
} dev->ohci_mmio[0x55] &= ~0x01;
if (!(dev->ohci_mmio[0x4e] & 0x04)) { dev->ohci_mmio[0x54] &= ~0x17;
dev->ohci_mmio[0x59] &= ~0x01; dev->ohci_mmio[0x56] &= ~0x17;
dev->ohci_mmio[0x58] &= ~0x17; dev->ohci_mmio[0x59] &= ~0x01;
dev->ohci_mmio[0x5a] &= ~0x17; dev->ohci_mmio[0x58] &= ~0x17;
} dev->ohci_mmio[0x5a] &= ~0x17;
} } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) {
} if (!(dev->ohci_mmio[0x4e] & 0x02)) {
return; dev->ohci_mmio[0x55] &= ~0x01;
case 0x51: dev->ohci_mmio[0x54] &= ~0x17;
if (val & 0x80) dev->ohci_mmio[0x56] &= ~0x17;
dev->ohci_mmio[addr] |= 0x80; }
return; if (!(dev->ohci_mmio[0x4e] & 0x04)) {
case 0x52: dev->ohci_mmio[0x59] &= ~0x01;
dev->ohci_mmio[addr] &= ~(val & 0x02); dev->ohci_mmio[0x58] &= ~0x17;
if (val & 0x01) { dev->ohci_mmio[0x5a] &= ~0x17;
if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) { }
dev->ohci_mmio[0x55] |= 0x01; }
dev->ohci_mmio[0x59] |= 0x01; }
} else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) { return;
if (!(dev->ohci_mmio[0x4e] & 0x02)) case 0x51:
dev->ohci_mmio[0x55] |= 0x01; if (val & 0x80)
if (!(dev->ohci_mmio[0x4e] & 0x04)) dev->ohci_mmio[addr] |= 0x80;
dev->ohci_mmio[0x59] |= 0x01; return;
} case 0x52:
} dev->ohci_mmio[addr] &= ~(val & 0x02);
return; if (val & 0x01) {
case 0x53: if ((dev->ohci_mmio[0x49] & 0x03) == 0x00) {
if (val & 0x80) dev->ohci_mmio[0x55] |= 0x01;
dev->ohci_mmio[0x51] &= ~0x80; dev->ohci_mmio[0x59] |= 0x01;
return; } else if ((dev->ohci_mmio[0x49] & 0x03) == 0x01) {
case 0x54: case 0x58: if (!(dev->ohci_mmio[0x4e] & 0x02))
old = dev->ohci_mmio[addr]; dev->ohci_mmio[0x55] |= 0x01;
if (!(dev->ohci_mmio[0x4e] & 0x04))
dev->ohci_mmio[0x59] |= 0x01;
}
}
return;
case 0x53:
if (val & 0x80)
dev->ohci_mmio[0x51] &= ~0x80;
return;
case 0x54:
case 0x58:
old = dev->ohci_mmio[addr];
if (val & 0x10) { if (val & 0x10) {
if (old & 0x01) { if (old & 0x01) {
dev->ohci_mmio[addr] |= 0x10; dev->ohci_mmio[addr] |= 0x10;
/* TODO: The clear should be on a 10 ms timer. */ /* TODO: The clear should be on a 10 ms timer. */
dev->ohci_mmio[addr] &= ~0x10; dev->ohci_mmio[addr] &= ~0x10;
dev->ohci_mmio[addr + 2] |= 0x10; dev->ohci_mmio[addr + 2] |= 0x10;
} else } else
dev->ohci_mmio[addr + 2] |= 0x01; dev->ohci_mmio[addr + 2] |= 0x01;
} }
if (val & 0x08) if (val & 0x08)
dev->ohci_mmio[addr] &= ~0x04; dev->ohci_mmio[addr] &= ~0x04;
if (val & 0x04) if (val & 0x04)
dev->ohci_mmio[addr] |= 0x04; dev->ohci_mmio[addr] |= 0x04;
if (val & 0x02) { if (val & 0x02) {
if (old & 0x01) if (old & 0x01)
dev->ohci_mmio[addr] |= 0x02; dev->ohci_mmio[addr] |= 0x02;
else else
dev->ohci_mmio[addr + 2] |= 0x01; dev->ohci_mmio[addr + 2] |= 0x01;
} }
if (val & 0x01) { if (val & 0x01) {
if (old & 0x01) if (old & 0x01)
dev->ohci_mmio[addr] &= ~0x02; dev->ohci_mmio[addr] &= ~0x02;
else else
dev->ohci_mmio[addr + 2] |= 0x01; dev->ohci_mmio[addr + 2] |= 0x01;
} }
if (!(dev->ohci_mmio[addr] & 0x04) && (old & 0x04)) if (!(dev->ohci_mmio[addr] & 0x04) && (old & 0x04))
dev->ohci_mmio[addr + 2] |= 0x04; dev->ohci_mmio[addr + 2] |= 0x04;
/* if (!(dev->ohci_mmio[addr] & 0x02)) /* if (!(dev->ohci_mmio[addr] & 0x02))
dev->ohci_mmio[addr + 2] |= 0x02; */ dev->ohci_mmio[addr + 2] |= 0x02; */
return; return;
case 0x55: case 0x55:
if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) {
dev->ohci_mmio[addr] &= ~0x01; dev->ohci_mmio[addr] &= ~0x01;
dev->ohci_mmio[0x54] &= ~0x17; dev->ohci_mmio[0x54] &= ~0x17;
dev->ohci_mmio[0x56] &= ~0x17; dev->ohci_mmio[0x56] &= ~0x17;
} if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) { }
dev->ohci_mmio[addr] |= 0x01; if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x02)) {
dev->ohci_mmio[0x58] &= ~0x17; dev->ohci_mmio[addr] |= 0x01;
dev->ohci_mmio[0x5a] &= ~0x17; dev->ohci_mmio[0x58] &= ~0x17;
} dev->ohci_mmio[0x5a] &= ~0x17;
return; }
case 0x59: return;
if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) case 0x59:
dev->ohci_mmio[addr] &= ~0x01; if ((val & 0x02) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04))
if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04)) dev->ohci_mmio[addr] &= ~0x01;
dev->ohci_mmio[addr] |= 0x01; if ((val & 0x01) && ((dev->ohci_mmio[0x49] & 0x03) == 0x00) && (dev->ohci_mmio[0x4e] & 0x04))
return; dev->ohci_mmio[addr] |= 0x01;
case 0x56: case 0x5a: return;
dev->ohci_mmio[addr] &= ~(val & 0x1f); case 0x56:
return; case 0x5a:
case 0x57: case 0x5b: dev->ohci_mmio[addr] &= ~(val & 0x1f);
return; return;
case 0x57:
case 0x5b:
return;
} }
dev->ohci_mmio[addr] = val; dev->ohci_mmio[addr] = val;
} }
void void
ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable) ohci_update_mem_mapping(usb_t *dev, uint8_t base1, uint8_t base2, uint8_t base3, int enable)
{ {
if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000)) if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000))
mem_mapping_disable(&dev->ohci_mmio_mapping); mem_mapping_disable(&dev->ohci_mmio_mapping);
dev->ohci_mem_base = ((base1 << 8) | (base2 << 16) | (base3 << 24)) & 0xfffff000; dev->ohci_mem_base = ((base1 << 8) | (base2 << 16) | (base3 << 24)) & 0xfffff000;
dev->ohci_enable = enable; dev->ohci_enable = enable;
if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000)) if (dev->ohci_enable && (dev->ohci_mem_base != 0x00000000))
mem_mapping_set_addr(&dev->ohci_mmio_mapping, dev->ohci_mem_base, 0x1000); mem_mapping_set_addr(&dev->ohci_mmio_mapping, dev->ohci_mem_base, 0x1000);
} }
static void static void
usb_reset(void *priv) usb_reset(void *priv)
{ {
@@ -372,7 +379,6 @@ usb_reset(void *priv)
dev->ohci_enable = 0; dev->ohci_enable = 0;
} }
static void static void
usb_close(void *priv) usb_close(void *priv)
{ {
@@ -381,14 +387,14 @@ usb_close(void *priv)
free(dev); free(dev);
} }
static void * static void *
usb_init(const device_t *info) usb_init(const device_t *info)
{ {
usb_t *dev; usb_t *dev;
dev = (usb_t *)malloc(sizeof(usb_t)); dev = (usb_t *) malloc(sizeof(usb_t));
if (dev == NULL) return(NULL); if (dev == NULL)
return (NULL);
memset(dev, 0x00, sizeof(usb_t)); memset(dev, 0x00, sizeof(usb_t));
memset(dev->uhci_io, 0x00, 128); memset(dev->uhci_io, 0x00, 128);
@@ -401,24 +407,24 @@ usb_init(const device_t *info)
dev->ohci_mmio[0x48] = 0x02; dev->ohci_mmio[0x48] = 0x02;
mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0, mem_mapping_add(&dev->ohci_mmio_mapping, 0, 0,
ohci_mmio_read, NULL, NULL, ohci_mmio_read, NULL, NULL,
ohci_mmio_write, NULL, NULL, ohci_mmio_write, NULL, NULL,
NULL, MEM_MAPPING_EXTERNAL, dev); NULL, MEM_MAPPING_EXTERNAL, dev);
usb_reset(dev); usb_reset(dev);
return dev; return dev;
} }
const device_t usb_device = { const device_t usb_device = {
.name = "Universal Serial Bus", .name = "Universal Serial Bus",
.internal_name = "usb", .internal_name = "usb",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = 0, .local = 0,
.init = usb_init, .init = usb_init,
.close = usb_close, .close = usb_close,
.reset = usb_reset, .reset = usb_reset,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };

243
src/vnc.c
View File

@@ -32,97 +32,90 @@
#include <86box/ui.h> #include <86box/ui.h>
#include <86box/vnc.h> #include <86box/vnc.h>
#define VNC_MIN_X 320
#define VNC_MAX_X 2048
#define VNC_MIN_Y 200
#define VNC_MAX_Y 2048
#define VNC_MIN_X 320 static rfbScreenInfoPtr rfb = NULL;
#define VNC_MAX_X 2048 static int clients;
#define VNC_MIN_Y 200 static int updatingSize;
#define VNC_MAX_Y 2048 static int allowedX,
allowedY;
static int ptr_x, ptr_y, ptr_but;
static rfbScreenInfoPtr rfb = NULL;
static int clients;
static int updatingSize;
static int allowedX,
allowedY;
static int ptr_x, ptr_y, ptr_but;
#ifdef ENABLE_VNC_LOG #ifdef ENABLE_VNC_LOG
int vnc_do_log = ENABLE_VNC_LOG; int vnc_do_log = ENABLE_VNC_LOG;
static void static void
vnc_log(const char *fmt, ...) vnc_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (vnc_do_log) { if (vnc_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define vnc_log(fmt, ...) # define vnc_log(fmt, ...)
#endif #endif
static void static void
vnc_kbdevent(rfbBool down, rfbKeySym k, rfbClientPtr cl) vnc_kbdevent(rfbBool down, rfbKeySym k, rfbClientPtr cl)
{ {
(void)cl; (void) cl;
/* Handle it through the lookup tables. */ /* Handle it through the lookup tables. */
vnc_kbinput(down?1:0, (int)k); vnc_kbinput(down ? 1 : 0, (int) k);
} }
static void static void
vnc_ptrevent(int but, int x, int y, rfbClientPtr cl) vnc_ptrevent(int but, int x, int y, rfbClientPtr cl)
{ {
if (x>=0 && x<allowedX && y>=0 && y<allowedY) { if (x >= 0 && x < allowedX && y >= 0 && y < allowedY) {
/* VNC uses absolute positions within the window, no deltas. */ /* VNC uses absolute positions within the window, no deltas. */
if (x != ptr_x || y != ptr_y) { if (x != ptr_x || y != ptr_y) {
mouse_x += (x - ptr_x) / 100; mouse_x += (x - ptr_x) / 100;
mouse_y += (y - ptr_y) / 100; mouse_y += (y - ptr_y) / 100;
ptr_x = x; ptr_y = y; ptr_x = x;
} ptr_y = y;
}
if (but != ptr_but) { if (but != ptr_but) {
mouse_buttons = 0; mouse_buttons = 0;
if (but & 0x01) if (but & 0x01)
mouse_buttons |= 0x01; mouse_buttons |= 0x01;
if (but & 0x02) if (but & 0x02)
mouse_buttons |= 0x04; mouse_buttons |= 0x04;
if (but & 0x04) if (but & 0x04)
mouse_buttons |= 0x02; mouse_buttons |= 0x02;
ptr_but = but; ptr_but = but;
} }
} }
rfbDefaultPtrAddEvent(but, x, y, cl); rfbDefaultPtrAddEvent(but, x, y, cl);
} }
static void static void
vnc_clientgone(rfbClientPtr cl) vnc_clientgone(rfbClientPtr cl)
{ {
vnc_log("VNC: client disconnected: %s\n", cl->host); vnc_log("VNC: client disconnected: %s\n", cl->host);
if (clients > 0) if (clients > 0)
clients--; clients--;
if (clients == 0) { if (clients == 0) {
/* No more clients, pause the emulator. */ /* No more clients, pause the emulator. */
vnc_log("VNC: no clients, pausing..\n"); vnc_log("VNC: no clients, pausing..\n");
/* Disable the mouse. */ /* Disable the mouse. */
plat_mouse_capture(0); plat_mouse_capture(0);
plat_pause(1); plat_pause(1);
} }
} }
static enum rfbNewClientAction static enum rfbNewClientAction
vnc_newclient(rfbClientPtr cl) vnc_newclient(rfbClientPtr cl)
{ {
@@ -131,114 +124,111 @@ vnc_newclient(rfbClientPtr cl)
vnc_log("VNC: new client: %s\n", cl->host); vnc_log("VNC: new client: %s\n", cl->host);
if (++clients == 1) { if (++clients == 1) {
/* Reset the mouse. */ /* Reset the mouse. */
ptr_x = allowedX/2; ptr_x = allowedX / 2;
ptr_y = allowedY/2; ptr_y = allowedY / 2;
mouse_x = mouse_y = mouse_z = 0; mouse_x = mouse_y = mouse_z = 0;
mouse_buttons = 0x00; mouse_buttons = 0x00;
/* We now have clients, un-pause the emulator if needed. */ /* We now have clients, un-pause the emulator if needed. */
vnc_log("VNC: unpausing..\n"); vnc_log("VNC: unpausing..\n");
/* Enable the mouse. */ /* Enable the mouse. */
plat_mouse_capture(1); plat_mouse_capture(1);
plat_pause(0); plat_pause(0);
} }
/* For now, we always accept clients. */ /* For now, we always accept clients. */
return(RFB_CLIENT_ACCEPT); return (RFB_CLIENT_ACCEPT);
} }
static void static void
vnc_display(rfbClientPtr cl) vnc_display(rfbClientPtr cl)
{ {
/* Avoid race condition between resize and update. */ /* Avoid race condition between resize and update. */
if (!updatingSize && cl->newFBSizePending) { if (!updatingSize && cl->newFBSizePending) {
updatingSize = 1; updatingSize = 1;
} else if (updatingSize && !cl->newFBSizePending) { } else if (updatingSize && !cl->newFBSizePending) {
updatingSize = 0; updatingSize = 0;
allowedX = rfb->width; allowedX = rfb->width;
allowedY = rfb->height; allowedY = rfb->height;
} }
} }
static void static void
vnc_blit(int x, int y, int w, int h, int monitor_index) vnc_blit(int x, int y, int w, int h, int monitor_index)
{ {
uint32_t *p; uint32_t *p;
int yy; int yy;
if (monitor_index || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL)) { if (monitor_index || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL)) {
video_blit_complete_monitor(monitor_index); video_blit_complete_monitor(monitor_index);
return; return;
} }
for (yy=0; yy<h; yy++) { for (yy = 0; yy < h; yy++) {
p = (uint32_t *)&(((uint32_t *)rfb->frameBuffer)[yy*VNC_MAX_X]); p = (uint32_t *) &(((uint32_t *) rfb->frameBuffer)[yy * VNC_MAX_X]);
if ((y+yy) >= 0 && (y+yy) < VNC_MAX_Y) if ((y + yy) >= 0 && (y + yy) < VNC_MAX_Y)
video_copy(p, &(buffer32->line[yy]), w*sizeof(uint32_t)); video_copy(p, &(buffer32->line[yy]), w * sizeof(uint32_t));
} }
if (screenshots) if (screenshots)
video_screenshot((uint32_t *) rfb->frameBuffer, 0, 0, VNC_MAX_X); video_screenshot((uint32_t *) rfb->frameBuffer, 0, 0, VNC_MAX_X);
video_blit_complete_monitor(monitor_index); video_blit_complete_monitor(monitor_index);
if (! updatingSize) if (!updatingSize)
rfbMarkRectAsModified(rfb, 0,0, allowedX,allowedY); rfbMarkRectAsModified(rfb, 0, 0, allowedX, allowedY);
} }
/* Initialize VNC for operation. */ /* Initialize VNC for operation. */
int int
vnc_init(UNUSED(void *arg)) vnc_init(UNUSED(void *arg))
{ {
static char title[128]; static char title[128];
rfbPixelFormat rpf = { rfbPixelFormat rpf = {
/* /*
* Screen format: * Screen format:
* 32bpp; 32 depth; * 32bpp; 32 depth;
* little endian; * little endian;
* true color; * true color;
* max 255 R/G/B; * max 255 R/G/B;
* red shift 16; green shift 8; blue shift 0; * red shift 16; green shift 8; blue shift 0;
* padding * padding
*/ */
32, 32, 0, 1, 255,255,255, 16, 8, 0, 0, 0 32, 32, 0, 1, 255, 255, 255, 16, 8, 0, 0, 0
}; };
plat_pause(1); plat_pause(1);
cgapal_rebuild_monitor(0); cgapal_rebuild_monitor(0);
if (rfb == NULL) { if (rfb == NULL) {
wcstombs(title, ui_window_title(NULL), sizeof(title)); wcstombs(title, ui_window_title(NULL), sizeof(title));
updatingSize = 0; updatingSize = 0;
allowedX = scrnsz_x; allowedX = scrnsz_x;
allowedY = scrnsz_y; allowedY = scrnsz_y;
rfb = rfbGetScreen(0, NULL, VNC_MAX_X, VNC_MAX_Y, 8, 3, 4); rfb = rfbGetScreen(0, NULL, VNC_MAX_X, VNC_MAX_Y, 8, 3, 4);
rfb->desktopName = title; rfb->desktopName = title;
rfb->frameBuffer = (char *)malloc(VNC_MAX_X*VNC_MAX_Y*4); rfb->frameBuffer = (char *) malloc(VNC_MAX_X * VNC_MAX_Y * 4);
rfb->serverFormat = rpf; rfb->serverFormat = rpf;
rfb->alwaysShared = TRUE; rfb->alwaysShared = TRUE;
rfb->displayHook = vnc_display; rfb->displayHook = vnc_display;
rfb->ptrAddEvent = vnc_ptrevent; rfb->ptrAddEvent = vnc_ptrevent;
rfb->kbdAddEvent = vnc_kbdevent; rfb->kbdAddEvent = vnc_kbdevent;
rfb->newClientHook = vnc_newclient; rfb->newClientHook = vnc_newclient;
/* Set up our current resolution. */ /* Set up our current resolution. */
rfb->width = allowedX; rfb->width = allowedX;
rfb->height = allowedY; rfb->height = allowedY;
rfbInitServer(rfb); rfbInitServer(rfb);
rfbRunEventLoop(rfb, -1, TRUE); rfbRunEventLoop(rfb, -1, TRUE);
} }
/* Set up our BLIT handlers. */ /* Set up our BLIT handlers. */
@@ -248,66 +238,63 @@ vnc_init(UNUSED(void *arg))
vnc_log("VNC: init complete.\n"); vnc_log("VNC: init complete.\n");
return(1); return (1);
} }
void void
vnc_close(void) vnc_close(void)
{ {
video_setblit(NULL); video_setblit(NULL);
if (rfb != NULL) { if (rfb != NULL) {
free(rfb->frameBuffer); free(rfb->frameBuffer);
rfbScreenCleanup(rfb); rfbScreenCleanup(rfb);
rfb = NULL; rfb = NULL;
} }
} }
void void
vnc_resize(int x, int y) vnc_resize(int x, int y)
{ {
rfbClientIteratorPtr iterator; rfbClientIteratorPtr iterator;
rfbClientPtr cl; rfbClientPtr cl;
if (rfb == NULL) return; if (rfb == NULL)
return;
/* TightVNC doesn't like certain sizes.. */ /* TightVNC doesn't like certain sizes.. */
if (x < VNC_MIN_X || x > VNC_MAX_X || y < VNC_MIN_Y || y > VNC_MAX_Y) { if (x < VNC_MIN_X || x > VNC_MAX_X || y < VNC_MIN_Y || y > VNC_MAX_Y) {
vnc_log("VNC: invalid resoltion %dx%d requested!\n", x, y); vnc_log("VNC: invalid resoltion %dx%d requested!\n", x, y);
return; return;
} }
if ((x != rfb->width || y != rfb->height) && x > 160 && y > 0) { if ((x != rfb->width || y != rfb->height) && x > 160 && y > 0) {
vnc_log("VNC: updating resolution: %dx%d\n", x, y); vnc_log("VNC: updating resolution: %dx%d\n", x, y);
allowedX = (rfb->width < x) ? rfb->width : x; allowedX = (rfb->width < x) ? rfb->width : x;
allowedY = (rfb->width < y) ? rfb->width : y; allowedY = (rfb->width < y) ? rfb->width : y;
rfb->width = x; rfb->width = x;
rfb->height = y; rfb->height = y;
iterator = rfbGetClientIterator(rfb); iterator = rfbGetClientIterator(rfb);
while ((cl = rfbClientIteratorNext(iterator)) != NULL) { while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
LOCK(cl->updateMutex); LOCK(cl->updateMutex);
cl->newFBSizePending = 1; cl->newFBSizePending = 1;
UNLOCK(cl->updateMutex); UNLOCK(cl->updateMutex);
} }
} }
} }
/* Tell them to pause if we have no clients. */ /* Tell them to pause if we have no clients. */
int int
vnc_pause(void) vnc_pause(void)
{ {
return((clients > 0) ? 0 : 1); return ((clients > 0) ? 0 : 1);
} }
void void
vnc_take_screenshot(wchar_t *fn) vnc_take_screenshot(wchar_t *fn)
{ {

File diff suppressed because it is too large Load Diff