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

View File

@@ -16,12 +16,12 @@
*/
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
#error ARCH arm
# error ARCH arm
#elif defined(__aarch64__) || defined(_M_ARM64)
#error ARCH arm64
# error ARCH arm64
#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)
#error ARCH x86_64
# error ARCH x86_64
#endif
#error ARCH unknown

View File

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

View File

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

View File

@@ -53,35 +53,30 @@
#include <86box/rom.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
int device_do_log = ENABLE_DEVICE_LOG;
static void
device_log(const char *fmt, ...)
{
va_list ap;
if (device_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define device_log(fmt, ...)
# define device_log(fmt, ...)
#endif
/* Initialize the module for use. */
void
device_init(void)
@@ -89,7 +84,6 @@ device_init(void)
memset(devices, 0x00, sizeof(devices));
}
void
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));
c->dev = d;
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
section of the same name is, rename the non-numbered section to numbered. */
if (inst == 1) {
sec = config_find_section(c->name);
single_sec = config_find_section((char *) d->name);
if ((sec == NULL) && (single_sec != NULL))
config_rename_section(single_sec, c->name);
}
/* 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. */
if (inst == 1) {
sec = config_find_section(c->name);
single_sec = config_find_section((char *) d->name);
if ((sec == NULL) && (single_sec != NULL))
config_rename_section(single_sec, c->name);
}
} else
sprintf(c->name, "%s", d->name);
sprintf(c->name, "%s", d->name);
}
static void
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);
}
void
device_context(const device_t *d)
{
device_context_common(d, 0);
}
void
device_context_inst(const device_t *d, int inst)
{
device_context_common(d, inst);
}
void
device_context_restore(void)
{
memcpy(&device_current, &device_prev, sizeof(device_context_t));
}
static void *
device_add_common(const device_t *d, const device_t *cd, void *p, int inst)
{
void *priv = NULL;
int c;
int c;
for (c = 0; c < 256; c++) {
if (!inst && (devices[c] == (device_t *) d)) {
device_log("DEVICE: device already exists!\n");
return (NULL);
}
if (devices[c] == NULL) break;
if (!inst && (devices[c] == (device_t *) d)) {
device_log("DEVICE: device already exists!\n");
return (NULL);
}
if (devices[c] == NULL)
break;
}
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
its master device is already trying to assign. */
devices[c] = (device_t *)d;
devices[c] = (device_t *) d;
if (p == NULL) {
memcpy(&device_prev, &device_current, sizeof(device_context_t));
device_set_context(&device_current, cd, inst);
memcpy(&device_prev, &device_current, sizeof(device_context_t));
device_set_context(&device_current, cd, inst);
if (d->init != NULL) {
priv = d->init(d);
if (priv == NULL) {
if (d->name)
device_log("DEVICE: device '%s' init failed\n", d->name);
else
device_log("DEVICE: device init failed\n");
if (d->init != NULL) {
priv = d->init(d);
if (priv == NULL) {
if (d->name)
device_log("DEVICE: device '%s' init failed\n", d->name);
else
device_log("DEVICE: device init failed\n");
devices[c] = NULL;
device_priv[c] = NULL;
devices[c] = NULL;
device_priv[c] = NULL;
return(NULL);
}
}
return (NULL);
}
}
if (d->name)
device_log("DEVICE: device '%s' init successful\n", d->name);
else
device_log("DEVICE: device init successful\n");
if (d->name)
device_log("DEVICE: device '%s' init successful\n", d->name);
else
device_log("DEVICE: device init successful\n");
memcpy(&device_current, &device_prev, sizeof(device_context_t));
device_priv[c] = priv;
memcpy(&device_current, &device_prev, sizeof(device_context_t));
device_priv[c] = priv;
} else
device_priv[c] = p;
device_priv[c] = p;
return(priv);
return (priv);
}
char *
device_get_internal_name(const device_t *d)
{
if (d == NULL)
return "";
return "";
return (char *) d->internal_name;
}
void *
device_add(const device_t *d)
{
return device_add_common(d, d, NULL, 0);
}
/* For devices that do not have an init function (internal video etc.) */
void
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);
}
void *
device_add_inst(const device_t *d, int inst)
{
return device_add_common(d, d, NULL, inst);
}
/* For devices that do not have an init function (internal video etc.) */
void
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);
}
/* These four are to add a device with another device's context - will be
used to add machines' internal devices. */
void *
@@ -243,7 +227,6 @@ device_cadd(const device_t *d, const device_t *cd)
return device_add_common(d, cd, NULL, 0);
}
/* For devices that do not have an init function (internal video etc.) */
void
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);
}
void *
device_cadd_inst(const device_t *d, const device_t *cd, int inst)
{
return device_add_common(d, cd, NULL, inst);
}
/* For devices that do not have an init function (internal video etc.) */
void
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);
}
void
device_close_all(void)
{
int c;
for (c = (DEVICE_MAX - 1); c >= 0; c--) {
if (devices[c] != NULL) {
if (devices[c]->name)
device_log("Closing device: \"%s\"...\n", devices[c]->name);
if (devices[c]->close != NULL)
devices[c]->close(device_priv[c]);
devices[c] = device_priv[c] = NULL;
}
if (devices[c] != NULL) {
if (devices[c]->name)
device_log("Closing device: \"%s\"...\n", devices[c]->name);
if (devices[c]->close != NULL)
devices[c]->close(device_priv[c]);
devices[c] = device_priv[c] = NULL;
}
}
}
void
device_reset_all(void)
{
int c;
for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if (devices[c]->reset != NULL)
devices[c]->reset(device_priv[c]);
}
if (devices[c] != NULL) {
if (devices[c]->reset != NULL)
devices[c]->reset(device_priv[c]);
}
}
}
/* Reset all attached PCI devices - needed for PCI turbo reset control. */
void
device_reset_all_pci(void)
{
int c;
for (c=0; c<DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if ((devices[c]->reset != NULL) && (devices[c]->flags & DEVICE_PCI))
devices[c]->reset(device_priv[c]);
}
for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if ((devices[c]->reset != NULL) && (devices[c]->flags & DEVICE_PCI))
devices[c]->reset(device_priv[c]);
}
}
}
void *
device_get_priv(const device_t *d)
{
int c;
for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if (devices[c] == d)
return(device_priv[c]);
}
if (devices[c] != NULL) {
if (devices[c] == d)
return (device_priv[c]);
}
}
return(NULL);
return (NULL);
}
int
device_available(const device_t *d)
{
device_config_t *config = NULL;
device_config_bios_t *bios = NULL;
int bf, roms_present = 0;
int i = 0;
device_config_t *config = NULL;
device_config_bios_t *bios = NULL;
int bf, roms_present = 0;
int i = 0;
if (d != NULL) {
config = (device_config_t *) d->config;
if (config != NULL) {
while (config->type != -1) {
if (config->type == CONFIG_BIOS) {
bios = (device_config_bios_t *) config->bios;
config = (device_config_t *) d->config;
if (config != NULL) {
while (config->type != -1) {
if (config->type == CONFIG_BIOS) {
bios = (device_config_bios_t *) config->bios;
/* Go through the ROM's in the device configuration. */
while (bios->files_no != 0) {
i = 0;
for (bf = 0; bf < bios->files_no; bf++)
i += !!rom_present((char *) bios->files[bf]);
if (i == bios->files_no)
roms_present++;
bios++;
}
/* Go through the ROM's in the device configuration. */
while (bios->files_no != 0) {
i = 0;
for (bf = 0; bf < bios->files_no; bf++)
i += !!rom_present((char *) bios->files[bf]);
if (i == bios->files_no)
roms_present++;
bios++;
}
return(roms_present ? -1 : 0);
}
config++;
}
}
return (roms_present ? -1 : 0);
}
config++;
}
}
/* No CONFIG_BIOS field present, use the classic available(). */
if (d->available != NULL)
return(d->available());
else
return(1);
/* No CONFIG_BIOS field present, use the classic available(). */
if (d->available != NULL)
return (d->available());
else
return (1);
}
/* A NULL device is never available. */
return(0);
return (0);
}
int
device_has_config(const device_t *d)
{
int c = 0;
int c = 0;
device_config_t *config;
if (d == NULL)
return 0;
return 0;
if (d->config == NULL)
return 0;
return 0;
config = (device_config_t *) d->config;
while (config->type != -1) {
if (config->type != CONFIG_MAC)
c++;
config++;
if (config->type != CONFIG_MAC)
c++;
config++;
}
return (c > 0) ? 1 : 0;
}
int
device_poll(const device_t *d, int x, int y, int z, int b)
{
int c;
for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if (devices[c] == d) {
if (devices[c]->poll)
return(devices[c]->poll(x, y, z, b, device_priv[c]));
}
}
if (devices[c] != NULL) {
if (devices[c] == d) {
if (devices[c]->poll)
return (devices[c]->poll(x, y, z, b, device_priv[c]));
}
}
}
return(0);
return (0);
}
void
device_register_pci_slot(const device_t *d, int device, int type, int inta, int intb, int intc, int intd)
{
int c;
for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if (devices[c] == d) {
if (devices[c]->register_pci_slot)
devices[c]->register_pci_slot(device, type, inta, intb, intc, intd, device_priv[c]);
return;
}
}
if (devices[c] != NULL) {
if (devices[c] == d) {
if (devices[c]->register_pci_slot)
devices[c]->register_pci_slot(device, type, inta, intb, intc, intd, device_priv[c]);
return;
}
}
}
return;
}
void
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 };
if (d == NULL)
return;
return;
name[0] = 0x00;
if (bus) {
if (d->flags & DEVICE_ISA)
sbus = (d->flags & DEVICE_AT) ? "ISA16" : "ISA";
else if (d->flags & DEVICE_CBUS)
sbus = "C-BUS";
else if (d->flags & DEVICE_MCA)
sbus = "MCA";
else if (d->flags & DEVICE_EISA)
sbus = "EISA";
else if (d->flags & DEVICE_VLB)
sbus = "VLB";
else if (d->flags & DEVICE_PCI)
sbus = "PCI";
else if (d->flags & DEVICE_AGP)
sbus = "AGP";
else if (d->flags & DEVICE_AC97)
sbus = "AMR";
else if (d->flags & DEVICE_COM)
sbus = "COM";
else if (d->flags & DEVICE_LPT)
sbus = "LPT";
if (d->flags & DEVICE_ISA)
sbus = (d->flags & DEVICE_AT) ? "ISA16" : "ISA";
else if (d->flags & DEVICE_CBUS)
sbus = "C-BUS";
else if (d->flags & DEVICE_MCA)
sbus = "MCA";
else if (d->flags & DEVICE_EISA)
sbus = "EISA";
else if (d->flags & DEVICE_VLB)
sbus = "VLB";
else if (d->flags & DEVICE_PCI)
sbus = "PCI";
else if (d->flags & DEVICE_AGP)
sbus = "AGP";
else if (d->flags & DEVICE_AC97)
sbus = "AMR";
else if (d->flags & DEVICE_COM)
sbus = "COM";
else if (d->flags & DEVICE_LPT)
sbus = "LPT";
if (sbus != NULL) {
/* First concatenate [<Bus>] before the device's name. */
strcat(name, "[");
strcat(name, sbus);
strcat(name, "] ");
if (sbus != NULL) {
/* First concatenate [<Bus>] before the device's name. */
strcat(name, "[");
strcat(name, sbus);
strcat(name, "] ");
/* Then change string from ISA16 to ISA if applicable. */
if (!strcmp(sbus, "ISA16"))
sbus = "ISA";
else if (!strcmp(sbus, "COM")|| !strcmp(sbus, "LPT")) {
sbus = NULL;
strcat(name, d->name);
return;
}
/* Then change string from ISA16 to ISA if applicable. */
if (!strcmp(sbus, "ISA16"))
sbus = "ISA";
else if (!strcmp(sbus, "COM") || !strcmp(sbus, "LPT")) {
sbus = NULL;
strcat(name, d->name);
return;
}
/* Generate the bus string with parentheses. */
strcat(pbus, "(");
strcat(pbus, sbus);
strcat(pbus, ")");
/* Generate the bus string with parentheses. */
strcat(pbus, "(");
strcat(pbus, sbus);
strcat(pbus, ")");
/* Allocate the temporary device name string and set it to all zeroes. */
tname = (char *) malloc(strlen(d->name) + 1);
memset(tname, 0x00, strlen(d->name) + 1);
/* Allocate the temporary device name string and set it to all zeroes. */
tname = (char *) malloc(strlen(d->name) + 1);
memset(tname, 0x00, strlen(d->name) + 1);
/* First strip the bus string with parentheses. */
fbus = strstr(d->name, pbus);
if (fbus == d->name)
strcat(tname, d->name + strlen(pbus) + 1);
else if (fbus == NULL)
strcat(tname, d->name);
else {
strncat(tname, d->name, fbus - d->name - 1);
strcat(tname, fbus + strlen(pbus));
}
/* First strip the bus string with parentheses. */
fbus = strstr(d->name, pbus);
if (fbus == d->name)
strcat(tname, d->name + strlen(pbus) + 1);
else if (fbus == NULL)
strcat(tname, d->name);
else {
strncat(tname, d->name, fbus - d->name - 1);
strcat(tname, fbus + strlen(pbus));
}
/* Then also strip the bus string with parentheses. */
fbus = strstr(tname, sbus);
if (fbus == tname)
strcat(name, tname + strlen(sbus) + 1);
/* Special case to not strip the "oPCI" from "Ensoniq AudioPCI" or
the "-ISA" from "AMD PCnet-ISA". */
else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-'))
strcat(name, tname);
else {
strncat(name, tname, fbus - tname - 1);
strcat(name, fbus + strlen(sbus));
}
/* Then also strip the bus string with parentheses. */
fbus = strstr(tname, sbus);
if (fbus == tname)
strcat(name, tname + strlen(sbus) + 1);
/* Special case to not strip the "oPCI" from "Ensoniq AudioPCI" or
the "-ISA" from "AMD PCnet-ISA". */
else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-'))
strcat(name, tname);
else {
strncat(name, tname, fbus - tname - 1);
strcat(name, fbus + strlen(sbus));
}
/* Free the temporary device name string. */
free(tname);
tname = NULL;
} else
strcat(name, d->name);
/* Free the temporary device name string. */
free(tname);
tname = NULL;
} else
strcat(name, d->name);
} else
strcat(name, d->name);
strcat(name, d->name);
}
void
device_speed_changed(void)
{
int c;
for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if (devices[c]->speed_changed != NULL)
devices[c]->speed_changed(device_priv[c]);
}
if (devices[c] != NULL) {
if (devices[c]->speed_changed != NULL)
devices[c]->speed_changed(device_priv[c]);
}
}
sound_speed_changed();
}
void
device_force_redraw(void)
{
int c;
for (c = 0; c < DEVICE_MAX; c++) {
if (devices[c] != NULL) {
if (devices[c]->force_redraw != NULL)
devices[c]->force_redraw(device_priv[c]);
}
if (devices[c] != NULL) {
if (devices[c]->force_redraw != NULL)
devices[c]->force_redraw(device_priv[c]);
}
}
}
const char *
device_get_config_string(const char *s)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_string((char *) device_current.name, (char *) s, (char *) c->default_string));
if (!strcmp(s, c->name))
return (config_get_string((char *) device_current.name, (char *) s, (char *) c->default_string));
c++;
c++;
}
return(NULL);
return (NULL);
}
int
device_get_config_int(const char *s)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_int((char *) device_current.name, (char *) s, c->default_int));
if (!strcmp(s, c->name))
return (config_get_int((char *) device_current.name, (char *) s, c->default_int));
c++;
c++;
}
return(0);
return (0);
}
int
device_get_config_int_ex(const char *s, int def)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_int((char *) device_current.name, (char *) s, def));
if (!strcmp(s, c->name))
return (config_get_int((char *) device_current.name, (char *) s, def));
c++;
c++;
}
return(def);
return (def);
}
int
device_get_config_hex16(const char *s)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_hex16((char *) device_current.name, (char *) s, c->default_int));
if (!strcmp(s, c->name))
return (config_get_hex16((char *) device_current.name, (char *) s, c->default_int));
c++;
c++;
}
return(0);
return (0);
}
int
device_get_config_hex20(const char *s)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_hex20((char *) device_current.name, (char *) s, c->default_int));
if (!strcmp(s, c->name))
return (config_get_hex20((char *) device_current.name, (char *) s, c->default_int));
c++;
c++;
}
return(0);
return (0);
}
int
device_get_config_mac(const char *s, int def)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_mac((char *) device_current.name, (char *) s, def));
if (!strcmp(s, c->name))
return (config_get_mac((char *) device_current.name, (char *) s, def));
c++;
c++;
}
return(def);
return (def);
}
void
device_set_config_int(const char *s, int val)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name)) {
config_set_int((char *) device_current.name, (char *) s, val);
break;
}
if (!strcmp(s, c->name)) {
config_set_int((char *) device_current.name, (char *) s, val);
break;
}
c++;
c++;
}
}
void
device_set_config_hex16(const char *s, int val)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name)) {
config_set_hex16((char *) device_current.name, (char *) s, val);
break;
}
if (!strcmp(s, c->name)) {
config_set_hex16((char *) device_current.name, (char *) s, val);
break;
}
c++;
c++;
}
}
void
device_set_config_hex20(const char *s, int val)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name)) {
config_set_hex20((char *) device_current.name, (char *) s, val);
break;
}
if (!strcmp(s, c->name)) {
config_set_hex20((char *) device_current.name, (char *) s, val);
break;
}
c++;
c++;
}
}
void
device_set_config_mac(const char *s, int val)
{
const device_config_t *c = device_current.dev->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name)) {
config_set_mac((char *) device_current.name, (char *) s, val);
break;
}
if (!strcmp(s, c->name)) {
config_set_mac((char *) device_current.name, (char *) s, val);
break;
}
c++;
c++;
}
}
int
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
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;
if (d == NULL) return(0);
if (d == NULL)
return (0);
c = d->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_int((char *)d->name, s, c->default_int));
if (!strcmp(s, c->name))
return (config_get_int((char *) d->name, s, c->default_int));
c++;
c++;
}
return(0);
return (0);
}
char *
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;
if (d == NULL) return(0);
if (d == NULL)
return (0);
c = d->config;
while (c && c->type != -1) {
if (! strcmp(s, c->name))
return(config_get_string((char *)d->name, s, (char *)c->default_string));
if (!strcmp(s, c->name))
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/fifo8.h>
void fifo8_create(Fifo8 *fifo, uint32_t capacity)
void
fifo8_create(Fifo8 *fifo, uint32_t capacity)
{
fifo->data = (uint8_t *)malloc(capacity);
memset(fifo->data, 0, capacity);
fifo->data = (uint8_t *) malloc(capacity);
memset(fifo->data, 0, capacity);
fifo->capacity = capacity;
fifo->head = 0;
fifo->num = 0;
fifo->head = 0;
fifo->num = 0;
}
void fifo8_destroy(Fifo8 *fifo)
void
fifo8_destroy(Fifo8 *fifo)
{
if (fifo->data) {
free(fifo->data);
fifo->data = NULL;
}
free(fifo->data);
fifo->data = NULL;
}
}
void fifo8_push(Fifo8 *fifo, uint8_t data)
void
fifo8_push(Fifo8 *fifo, uint8_t data)
{
assert(fifo->num < fifo->capacity);
fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data;
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;
@@ -64,7 +68,8 @@ void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num)
fifo->num += num;
}
uint8_t fifo8_pop(Fifo8 *fifo)
uint8_t
fifo8_pop(Fifo8 *fifo)
{
uint8_t ret;
@@ -75,41 +80,47 @@ uint8_t fifo8_pop(Fifo8 *fifo)
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;
assert(max > 0 && max <= fifo->num);
*num = MIN(fifo->capacity - fifo->head, max);
ret = &fifo->data[fifo->head];
ret = &fifo->data[fifo->head];
fifo->head += *num;
fifo->head %= fifo->capacity;
fifo->num -= *num;
return ret;
}
void fifo8_reset(Fifo8 *fifo)
void
fifo8_reset(Fifo8 *fifo)
{
fifo->num = 0;
fifo->num = 0;
fifo->head = 0;
}
int fifo8_is_empty(Fifo8 *fifo)
int
fifo8_is_empty(Fifo8 *fifo)
{
return (fifo->num == 0);
}
int fifo8_is_full(Fifo8 *fifo)
int
fifo8_is_full(Fifo8 *fifo)
{
return (fifo->num == fifo->capacity);
}
uint32_t fifo8_num_free(Fifo8 *fifo)
uint32_t
fifo8_num_free(Fifo8 *fifo)
{
return fifo->capacity - fifo->num;
}
uint32_t fifo8_num_used(Fifo8 *fifo)
uint32_t
fifo8_num_used(Fifo8 *fifo)
{
return fifo->num;
}

View File

@@ -25,7 +25,7 @@
# include <unistd.h>
# else
# include <io.h>
# define ssize_t long
# define ssize_t long
# define strtok_r(a, b, c) strtok_s(a, b, c)
# endif
# include <winsock2.h>
@@ -121,8 +121,8 @@ typedef struct _gdbstub_client_ {
struct sockaddr_in addr;
char packet[16384], response[16384];
int has_packet: 1, first_packet_received: 1, ida_mode: 1, waiting_stop: 1,
packet_pos, response_pos;
int has_packet : 1, first_packet_received : 1, ida_mode : 1, waiting_stop : 1,
packet_pos, response_pos;
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 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 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
"<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"

View File

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

614
src/io.c
View File

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

View File

@@ -28,32 +28,28 @@
#include <86box/mem.h>
#include <86box/chipset.h>
typedef struct {
uint8_t dummy;
} ioapic_t;
#ifdef ENABLE_IOAPIC_LOG
int ioapic_do_log = ENABLE_IOAPIC_LOG;
static void
ioapic_log(const char *fmt, ...)
{
va_list ap;
if (ioapic_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define ioapic_log(fmt, ...)
# define ioapic_log(fmt, ...)
#endif
static void
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 */
if (val != 0xff)
return;
return;
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
memory; at a 16-byte boundary in all cases. Award writes both tables to the BIOS area. */
for (addr = 0xf0000; addr <= 0xfffff; addr += 16) {
/* check signature for the _MP_ table (Floating Point Structure) */
if (mem_readl_phys(addr) != 0x5f504d5f) /* ASCII "_MP_" */
continue;
/* check signature for the _MP_ table (Floating Point Structure) */
if (mem_readl_phys(addr) != 0x5f504d5f) /* ASCII "_MP_" */
continue;
/* read and check pointer to the PCMP table (Configuration Table) */
pcmp = mem_readl_phys(addr + 4);
if ((pcmp < 0xf0000) || (pcmp > 0xfffff) || (mem_readl_phys(pcmp) != 0x504d4350)) /* ASCII "PCMP" */
continue;
/* read and check pointer to the PCMP table (Configuration Table) */
pcmp = mem_readl_phys(addr + 4);
if ((pcmp < 0xf0000) || (pcmp > 0xfffff) || (mem_readl_phys(pcmp) != 0x504d4350)) /* ASCII "PCMP" */
continue;
/* patch over the signature on both tables */
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[pcmp] = ram[pcmp + 1] = ram[pcmp + 2] = ram[pcmp + 3] = 0xff;
/* patch over the signature on both tables */
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[pcmp] = ram[pcmp + 1] = ram[pcmp + 2] = ram[pcmp + 3] = 0xff;
break;
break;
}
}
static void
ioapic_reset(ioapic_t *dev)
{
}
static void
ioapic_close(void *priv)
{
ioapic_t *dev = (ioapic_t *) priv;
io_removehandler(0x80, 1,
NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL);
NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL);
free(dev);
}
static void *
ioapic_init(const device_t *info)
{
@@ -114,22 +107,21 @@ ioapic_init(const device_t *info)
ioapic_reset(dev);
io_sethandler(0x80, 1,
NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL);
NULL, NULL, NULL, ioapic_write, NULL, NULL, NULL);
return dev;
}
const device_t ioapic_device = {
.name = "I/O Advanced Programmable Interrupt Controller",
.name = "I/O Advanced Programmable Interrupt Controller",
.internal_name = "ioapic",
.flags = DEVICE_AT,
.local = 0,
.init = ioapic_init,
.close = ioapic_close,
.reset = NULL,
.flags = DEVICE_AT,
.local = 0,
.init = ioapic_init,
.close = ioapic_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

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

View File

@@ -26,21 +26,22 @@
machine_status_t machine_status;
void
machine_status_init() {
machine_status_init()
{
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;
}
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;
}
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;
}
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;
}
@@ -52,6 +53,6 @@ machine_status_init() {
for (size_t i = 0; i < NET_CARD_MAX; i++) {
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/mca.h>
void (*mca_card_write[8])(int addr, uint8_t val, void *priv);
uint8_t (*mca_card_read[8])(int addr, 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_feedb[8])(void *priv);
void (*mca_card_reset[8])(void *priv);
void *mca_priv[8];
void (*mca_card_reset[8])(void *priv);
void *mca_priv[8];
static int mca_index;
static int mca_nr_cards;
void mca_init(int nr_cards)
void
mca_init(int nr_cards)
{
int c;
int c;
for (c = 0; c < 8; c++) {
mca_card_read[c] = NULL;
mca_card_write[c] = NULL;
mca_card_reset[c] = NULL;
mca_priv[c] = NULL;
}
for (c = 0; c < 8; c++) {
mca_card_read[c] = NULL;
mca_card_write[c] = NULL;
mca_card_reset[c] = NULL;
mca_priv[c] = NULL;
}
mca_index = 0;
mca_nr_cards = nr_cards;
mca_index = 0;
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)
return 0xff;
if (!mca_card_read[mca_index])
return 0xff;
return mca_card_read[mca_index](port, mca_priv[mca_index]);
if (mca_index >= mca_nr_cards)
return 0xff;
if (!mca_card_read[mca_index])
return 0xff;
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)
return 0xff;
if (!mca_card_read[index])
return 0xff;
return mca_card_read[index](port, mca_priv[index]);
if (mca_index >= mca_nr_cards)
return 0xff;
if (!mca_card_read[index])
return 0xff;
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)
return;
if (mca_card_write[mca_index])
mca_card_write[mca_index](port, val, mca_priv[mca_index]);
if (mca_index >= mca_nr_cards)
return;
if (mca_card_write[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])
return !!(mca_card_feedb[mca_index](mca_priv[mca_index]));
else
return 0;
if (mca_card_feedb[mca_index])
return !!(mca_card_feedb[mca_index](mca_priv[mca_index]));
else
return 0;
}
void mca_reset(void)
void
mca_reset(void)
{
int c;
int c;
for (c = 0; c < 8; c++) {
if (mca_card_reset[c])
mca_card_reset[c](mca_priv[c]);
}
for (c = 0; c < 8; c++) {
if (mca_card_reset[c])
mca_card_reset[c](mca_priv[c]);
}
}
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)
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)
{
int c;
int c;
for (c = 0; c < mca_nr_cards; c++) {
if (!mca_card_read[c] && !mca_card_write[c]) {
mca_card_read[c] = read;
mca_card_write[c] = write;
mca_card_feedb[c] = feedb;
mca_card_reset[c] = reset;
mca_priv[c] = priv;
return;
}
}
for (c = 0; c < mca_nr_cards; c++) {
if (!mca_card_read[c] && !mca_card_write[c]) {
mca_card_read[c] = read;
mca_card_write[c] = write;
mca_card_feedb[c] = feedb;
mca_card_reset[c] = reset;
mca_priv[c] = priv;
return;
}
}
}

View File

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

220
src/nvr.c
View File

@@ -62,107 +62,100 @@
#include <86box/plat.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 nvr_t *saved_nvr = NULL;
static nvr_t *saved_nvr = NULL;
#ifdef ENABLE_NVR_LOG
int nvr_do_log = ENABLE_NVR_LOG;
static void
nvr_log(const char *fmt, ...)
{
va_list ap;
if (nvr_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define nvr_log(fmt, ...)
# define nvr_log(fmt, ...)
#endif
/* Determine whether or not the year is leap. */
int
nvr_is_leap(int year)
{
if (year % 400 == 0) return(1);
if (year % 100 == 0) return(0);
if (year % 4 == 0) return(1);
if (year % 400 == 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. */
int
nvr_get_days(int month, int year)
{
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. */
void
rtc_tick(void)
{
/* Ping the internal clock. */
if (++intclk.tm_sec == 60) {
intclk.tm_sec = 0;
if (++intclk.tm_min == 60) {
intclk.tm_min = 0;
if (++intclk.tm_hour == 24) {
intclk.tm_hour = 0;
if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon,
intclk.tm_year) + 1)) {
intclk.tm_mday = 1;
if (++intclk.tm_mon == 13) {
intclk.tm_mon = 1;
intclk.tm_year++;
}
}
}
}
intclk.tm_sec = 0;
if (++intclk.tm_min == 60) {
intclk.tm_min = 0;
if (++intclk.tm_hour == 24) {
intclk.tm_hour = 0;
if (++intclk.tm_mday == (nvr_get_days(intclk.tm_mon, intclk.tm_year) + 1)) {
intclk.tm_mday = 1;
if (++intclk.tm_mon == 13) {
intclk.tm_mon = 1;
intclk.tm_year++;
}
}
}
}
}
}
/* This is the RTC one-second timer. */
static void
onesec_timer(void *priv)
{
nvr_t *nvr = (nvr_t *)priv;
int is_at;
nvr_t *nvr = (nvr_t *) priv;
int is_at;
if (++nvr->onesec_cnt >= 100) {
/* Update the internal clock. */
is_at = IS_AT(machine);
if (!is_at)
rtc_tick();
/* Update the internal clock. */
is_at = IS_AT(machine);
if (!is_at)
rtc_tick();
/* Update the RTC device if needed. */
if (nvr->tick != NULL)
(*nvr->tick)(nvr);
/* Update the RTC device if needed. */
if (nvr->tick != NULL)
(*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. */
void
nvr_init(nvr_t *nvr)
@@ -170,18 +163,18 @@ nvr_init(nvr_t *nvr)
int c;
/* Set up the NVR file's name. */
c = strlen(machine_get_internal_name()) + 5;
nvr->fn = (char *)malloc(c + 1);
c = strlen(machine_get_internal_name()) + 5;
nvr->fn = (char *) malloc(c + 1);
sprintf(nvr->fn, "%s.nvr", machine_get_internal_name());
/* Initialize the internal clock as needed. */
memset(&intclk, 0x00, sizeof(intclk));
if (time_sync & TIME_SYNC_ENABLED) {
nvr_time_sync();
nvr_time_sync();
} else {
/* Reset the internal clock to 1980/01/01 00:00. */
intclk.tm_mon = 1;
intclk.tm_year = 1980;
/* Reset the internal clock to 1980/01/01 00:00. */
intclk.tm_mon = 1;
intclk.tm_year = 1980;
}
/* Set up our timer. */
@@ -194,10 +187,9 @@ nvr_init(nvr_t *nvr)
saved_nvr = nvr;
/* Try to load the saved data. */
(void)nvr_load();
(void) nvr_load();
}
/* Get path to the NVR folder. */
char *
nvr_path(char *str)
@@ -210,17 +202,16 @@ nvr_path(char *str)
strcat(temp, NVR_PATH);
/* Create the directory if needed. */
if (! plat_dir_check(temp))
plat_dir_create(temp);
if (!plat_dir_check(temp))
plat_dir_create(temp);
/* Now append the actual filename. */
path_slash(temp);
strcat(temp, str);
return(temp);
return (temp);
}
/*
* Load an NVR from file.
*
@@ -235,53 +226,52 @@ nvr_path(char *str)
int
nvr_load(void)
{
char *path;
FILE *fp;
uint8_t regs[NVR_MAXSIZE] = { 0 };
char *path;
FILE *fp;
uint8_t regs[NVR_MAXSIZE] = { 0 };
/* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0);
if (saved_nvr == NULL)
return (0);
/* Clear out any old data. */
memset(saved_nvr->regs, 0x00, sizeof(saved_nvr->regs));
/* Set the defaults. */
if (saved_nvr->reset != NULL)
saved_nvr->reset(saved_nvr);
saved_nvr->reset(saved_nvr);
/* Load the (relevant) part of the NVR contents. */
if (saved_nvr->size != 0) {
path = nvr_path(saved_nvr->fn);
nvr_log("NVR: loading from '%s'\n", path);
fp = plat_fopen(path, "rb");
saved_nvr->is_new = (fp == NULL);
if (fp != NULL) {
memcpy(regs, saved_nvr->regs, sizeof(regs));
/* Read NVR contents from file. */
if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) {
memcpy(saved_nvr->regs, regs, sizeof(regs));
saved_nvr->is_new = 1;
path = nvr_path(saved_nvr->fn);
nvr_log("NVR: loading from '%s'\n", path);
fp = plat_fopen(path, "rb");
saved_nvr->is_new = (fp == NULL);
if (fp != NULL) {
memcpy(regs, saved_nvr->regs, sizeof(regs));
/* Read NVR contents from file. */
if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) {
memcpy(saved_nvr->regs, regs, sizeof(regs));
saved_nvr->is_new = 1;
}
(void) fclose(fp);
}
(void)fclose(fp);
}
} else
saved_nvr->is_new = 1;
saved_nvr->is_new = 1;
/* Get the local RTC running! */
if (saved_nvr->start != NULL)
saved_nvr->start(saved_nvr);
saved_nvr->start(saved_nvr);
return(1);
return (1);
}
void
nvr_set_ven_save(void (*ven_save)(void))
{
saved_nvr->ven_save = ven_save;
}
/* Save the current NVR to a file. */
int
nvr_save(void)
@@ -290,94 +280,90 @@ nvr_save(void)
FILE *fp;
/* Make sure we have been initialized. */
if (saved_nvr == NULL) return(0);
if (saved_nvr == NULL)
return (0);
if (saved_nvr->size != 0) {
path = nvr_path(saved_nvr->fn);
nvr_log("NVR: saving to '%s'\n", path);
fp = plat_fopen(path, "wb");
if (fp != NULL) {
/* Save NVR contents to file. */
(void)fwrite(saved_nvr->regs, saved_nvr->size, 1, fp);
fclose(fp);
}
path = nvr_path(saved_nvr->fn);
nvr_log("NVR: saving to '%s'\n", path);
fp = plat_fopen(path, "wb");
if (fp != NULL) {
/* Save NVR contents to file. */
(void) fwrite(saved_nvr->regs, saved_nvr->size, 1, fp);
fclose(fp);
}
}
if (saved_nvr->ven_save)
saved_nvr->ven_save();
saved_nvr->ven_save();
/* Device is clean again. */
nvr_dosave = 0;
return(1);
return (1);
}
void
nvr_close(void)
{
saved_nvr = NULL;
}
void
nvr_time_sync(void)
{
struct tm *tm;
time_t now;
time_t now;
/* Get the current time of day, and convert to local time. */
(void)time(&now);
if(time_sync & TIME_SYNC_UTC)
tm = gmtime(&now);
(void) time(&now);
if (time_sync & TIME_SYNC_UTC)
tm = gmtime(&now);
else
tm = localtime(&now);
tm = localtime(&now);
/* Set the internal clock. */
nvr_time_set(tm);
}
/* Get current time from internal clock. */
void
nvr_time_get(struct tm *tm)
{
uint8_t dom, mon, sum, wd;
uint8_t dom, mon, sum, wd;
uint16_t cent, yr;
tm->tm_sec = intclk.tm_sec;
tm->tm_min = intclk.tm_min;
tm->tm_sec = intclk.tm_sec;
tm->tm_min = intclk.tm_min;
tm->tm_hour = intclk.tm_hour;
dom = intclk.tm_mday;
mon = intclk.tm_mon;
yr = (intclk.tm_year % 100);
cent = ((intclk.tm_year - yr) / 100) % 4;
sum = dom+mon+yr+cent;
wd = ((sum + 6) % 7);
dom = intclk.tm_mday;
mon = intclk.tm_mon;
yr = (intclk.tm_year % 100);
cent = ((intclk.tm_year - yr) / 100) % 4;
sum = dom + mon + yr + cent;
wd = ((sum + 6) % 7);
tm->tm_wday = wd;
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);
}
/* Set internal clock time. */
void
nvr_time_set(struct tm *tm)
{
intclk.tm_sec = tm->tm_sec;
intclk.tm_min = tm->tm_min;
intclk.tm_sec = tm->tm_sec;
intclk.tm_min = tm->tm_min;
intclk.tm_hour = tm->tm_hour;
intclk.tm_wday = tm->tm_wday;
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);
}
/* Open or create a file in the NVR area. */
FILE *
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/rom.h>
typedef struct {
int addr;
int addr;
uint8_t *ram;
int size;
uint8_t *ram;
int size;
char *fn;
char *fn;
} ps2_nvr_t;
static uint8_t
ps2_nvr_read(uint16_t port, void *priv)
{
ps2_nvr_t *nvr = (ps2_nvr_t *)priv;
uint8_t ret = 0xff;
ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
uint8_t ret = 0xff;
switch (port) {
case 0x74:
ret = nvr->addr & 0xff;
break;
case 0x74:
ret = nvr->addr & 0xff;
break;
case 0x75:
ret = nvr->addr >> 8;
break;
case 0x75:
ret = nvr->addr >> 8;
break;
case 0x76:
ret = nvr->ram[nvr->addr];
break;
case 0x76:
ret = nvr->ram[nvr->addr];
break;
}
return(ret);
return (ret);
}
static void
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) {
case 0x74:
nvr->addr = (nvr->addr & 0x1f00) | val;
break;
case 0x74:
nvr->addr = (nvr->addr & 0x1f00) | val;
break;
case 0x75:
nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8);
break;
case 0x75:
nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8);
break;
case 0x76:
nvr->ram[nvr->addr] = val;
break;
case 0x76:
nvr->ram[nvr->addr] = val;
break;
}
}
static void *
ps2_nvr_init(const device_t *info)
{
ps2_nvr_t *nvr;
FILE *f = NULL;
int c;
FILE *f = NULL;
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));
if (info->local)
@@ -121,38 +117,37 @@ ps2_nvr_init(const device_t *info)
nvr->size = 8192;
/* Set up the NVR file's name. */
c = strlen(machine_get_internal_name()) + 9;
nvr->fn = (char *)malloc(c + 1);
c = strlen(machine_get_internal_name()) + 9;
nvr->fn = (char *) malloc(c + 1);
sprintf(nvr->fn, "%s_sec.nvr", machine_get_internal_name());
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");
nvr->ram = (uint8_t *)malloc(nvr->size);
nvr->ram = (uint8_t *) malloc(nvr->size);
memset(nvr->ram, 0xff, nvr->size);
if (f != NULL) {
if (fread(nvr->ram, 1, nvr->size, f) != nvr->size)
fatal("ps2_nvr_init(): Error reading EEPROM data\n");
fclose(f);
if (fread(nvr->ram, 1, nvr->size, f) != nvr->size)
fatal("ps2_nvr_init(): Error reading EEPROM data\n");
fclose(f);
}
return(nvr);
return (nvr);
}
static void
ps2_nvr_close(void *priv)
{
ps2_nvr_t *nvr = (ps2_nvr_t *)priv;
FILE *f = NULL;
ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
FILE *f = NULL;
f = nvr_fopen(nvr->fn, "wb");
if (f != NULL) {
(void)fwrite(nvr->ram, nvr->size, 1, f);
fclose(f);
(void) fwrite(nvr->ram, nvr->size, 1, f);
fclose(f);
}
if (nvr->ram != NULL)
@@ -162,29 +157,29 @@ ps2_nvr_close(void *priv)
}
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",
.flags = 0,
.local = 0,
.init = ps2_nvr_init,
.close = ps2_nvr_close,
.reset = NULL,
.flags = 0,
.local = 0,
.init = ps2_nvr_init,
.close = ps2_nvr_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
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",
.flags = 0,
.local = 1,
.init = ps2_nvr_init,
.close = ps2_nvr_close,
.reset = NULL,
.flags = 0,
.local = 1,
.init = ps2_nvr_init,
.close = ps2_nvr_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = 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 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)
{
pci_set_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;
if (set) {
pci_set_irq(card, pci_regs[0x3D]);
} else {
pci_clear_irq(card, pci_regs[0x3D]);
}
}
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;
pclog("AB0B:071A: PCI_Write(%d, %04x, %02x)\n", func, addr, val);
switch(addr) {
case 0x04: /* PCI_COMMAND_LO */
valxor = (val & 0x03) ^ pci_regs[addr];
if (valxor & PCI_COMMAND_IO)
{
pci_dummy_io_remove();
if (((pci_bar[0].addr & 0xffe0) != 0) && (val & PCI_COMMAND_IO))
{
pci_dummy_io_set();
}
}
pci_regs[addr] = val & 0x03;
break;
switch (addr) {
case 0x04: /* PCI_COMMAND_LO */
valxor = (val & 0x03) ^ pci_regs[addr];
if (valxor & PCI_COMMAND_IO) {
pci_dummy_io_remove();
if (((pci_bar[0].addr & 0xffe0) != 0) && (val & PCI_COMMAND_IO)) {
pci_dummy_io_set();
}
}
pci_regs[addr] = val & 0x03;
break;
case 0x10: /* PCI_BAR */
val &= 0xe0; /* 0xe0 acc to RTL DS */
val |= 0x01; /* re-enable IOIN bit */
/*FALLTHROUGH*/
case 0x10: /* PCI_BAR */
val &= 0xe0; /* 0xe0 acc to RTL DS */
val |= 0x01; /* re-enable IOIN bit */
/*FALLTHROUGH*/
case 0x11: /* PCI_BAR */
case 0x12: /* PCI_BAR */
case 0x13: /* PCI_BAR */
/* Remove old I/O. */
pci_dummy_io_remove();
case 0x11: /* PCI_BAR */
case 0x12: /* PCI_BAR */
case 0x13: /* PCI_BAR */
/* Remove old I/O. */
pci_dummy_io_remove();
/* Set new I/O as per PCI request. */
pci_bar[0].addr_regs[addr & 3] = val;
/* Set new I/O as per PCI request. */
pci_bar[0].addr_regs[addr & 3] = val;
/* Then let's calculate the new I/O base. */
pci_bar[0].addr &= 0xffe0;
/* Then let's calculate the new I/O base. */
pci_bar[0].addr &= 0xffe0;
/* Log the new base. */
pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr);
/* Log the new base. */
pclog("AB0B:071A: PCI: new I/O base is %04X\n", pci_bar[0].addr);
/* We're done, so get out of the here. */
if (pci_regs[4] & PCI_COMMAND_IO)
{
if ((pci_bar[0].addr) != 0)
{
pci_dummy_io_set();
}
}
break;
/* We're done, so get out of the here. */
if (pci_regs[4] & PCI_COMMAND_IO) {
if ((pci_bar[0].addr) != 0) {
pci_dummy_io_set();
}
}
break;
case 0x3C: /* PCI_ILR */
pclog("AB0B:071A: IRQ now: %i\n", val);
pci_regs[addr] = val;
return;
case 0x3C: /* PCI_ILR */
pclog("AB0B:071A: IRQ now: %i\n", val);
pci_regs[addr] = val;
return;
}
}
void pci_dummy_init(void)
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_regs[0x04] = 0x03;
pci_bar[0].addr_regs[0] = 0x01;
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/acpi.h>
enum
{
enum {
STATE_NONE = 0,
STATE_ICW2,
STATE_ICW3,
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 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 uint16_t smi_irq_mask = 0x0000,
smi_irq_status = 0x0000;
static void (*update_pending)(void);
#ifdef ENABLE_PIC_LOG
int pic_do_log = ENABLE_PIC_LOG;
static void
pic_log(const char *fmt, ...)
{
va_list ap;
if (pic_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define pic_log(fmt, ...)
# define pic_log(fmt, ...)
#endif
void
pic_reset_smi_irq_mask(void)
{
smi_irq_mask = 0x0000;
}
void
pic_set_smi_irq_mask(int irq, int set)
{
if ((irq >= 0) && (irq <= 15)) {
if (set)
smi_irq_mask |= (1 << irq);
else
smi_irq_mask &= ~(1 << irq);
if (set)
smi_irq_mask |= (1 << irq);
else
smi_irq_mask &= ~(1 << irq);
}
}
@@ -105,15 +97,13 @@ pic_get_smi_irq_status(void)
return smi_irq_status;
}
void
pic_clear_smi_irq_status(int irq)
{
if ((irq >= 0) && (irq <= 15))
smi_irq_status &= ~(1 << irq);
smi_irq_status &= ~(1 << irq);
}
void
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);
if (port & 1)
val &= 0xde;
val &= 0xde;
else
val &= 0xf8;
val &= 0xf8;
dev->elcr = val;
pic_log("ELCR %i: %c %c %c %c %c %c %c %c\n",
port & 1,
(val & 1) ? 'L' : 'E',
(val & 2) ? 'L' : 'E',
(val & 4) ? 'L' : 'E',
(val & 8) ? 'L' : 'E',
(val & 0x10) ? 'L' : 'E',
(val & 0x20) ? 'L' : 'E',
(val & 0x40) ? 'L' : 'E',
(val & 0x80) ? 'L' : 'E');
port & 1,
(val & 1) ? 'L' : 'E',
(val & 2) ? 'L' : 'E',
(val & 4) ? 'L' : 'E',
(val & 8) ? 'L' : 'E',
(val & 0x10) ? 'L' : 'E',
(val & 0x20) ? 'L' : 'E',
(val & 0x40) ? 'L' : 'E',
(val & 0x80) ? 'L' : 'E');
}
uint8_t
pic_elcr_read(uint16_t port, void *priv)
{
@@ -151,110 +140,100 @@ pic_elcr_read(uint16_t port, void *priv)
return dev->elcr;
}
int
pic_elcr_get_enabled(void)
{
return elcr_enabled;
}
void
pic_elcr_set_enabled(int enabled)
{
elcr_enabled = enabled;
}
void
pic_elcr_io_handler(int set)
{
io_handler(set, 0x04d0, 0x0001,
pic_elcr_read, NULL, NULL,
pic_elcr_write, NULL, NULL, &pic);
pic_elcr_read, NULL, NULL,
pic_elcr_write, NULL, NULL, &pic);
io_handler(set, 0x04d1, 0x0001,
pic_elcr_read, NULL, NULL,
pic_elcr_write, NULL, NULL, &pic2);
pic_elcr_read, NULL, NULL,
pic_elcr_write, NULL, NULL, &pic2);
}
static uint8_t
pic_cascade_mode(pic_t *dev)
{
return !(dev->icw1 & 2);
}
static __inline uint8_t
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));
return pic_cascade_mode(dev) && (dev->is_master || ((dev->icw4 & 0x0c) == 0x0c)) &&
(dev->icw3 & (1 << channel));
return pic_cascade_mode(dev) && (dev->is_master || ((dev->icw4 & 0x0c) == 0x0c)) && (dev->icw3 & (1 << channel));
}
static __inline int
find_best_interrupt(pic_t *dev)
{
uint8_t b;
uint8_t intr;
int i, j;
int ret = -1;
int i, j;
int ret = -1;
for (i = 0; i < 8; i++) {
j = (i + dev->priority) & 7;
b = 1 << j;
j = (i + dev->priority) & 7;
b = 1 << j;
if (dev->isr & b)
break;
else if ((dev->state == 0) && ((dev->irr & ~dev->imr) & b)) {
ret = j;
break;
}
if (dev->isr & b)
break;
else if ((dev->state == 0) && ((dev->irr & ~dev->imr) & b)) {
ret = j;
break;
}
}
intr = dev->interrupt = (ret == -1) ? 0x17 : ret;
if (dev->at && (ret != 1)) {
if (dev == &pic2)
intr += 8;
if (dev == &pic2)
intr += 8;
if (cpu_fast_off_flags & (1u << intr))
cpu_fast_off_advance();
if (cpu_fast_off_flags & (1u << intr))
cpu_fast_off_advance();
}
return ret;
}
static __inline void
pic_update_pending_xt(void)
{
if (find_best_interrupt(&pic) != -1) {
latched++;
if (latched == 1)
timer_on_auto(&pic_timer, 0.35);
latched++;
if (latched == 1)
timer_on_auto(&pic_timer, 0.35);
} else if (latched == 0)
pic.int_pending = 0;
pic.int_pending = 0;
}
static __inline void
pic_update_pending_at(void)
{
pic2.int_pending = (find_best_interrupt(&pic2) != -1);
if (pic2.int_pending)
pic.irr |= (1 << pic2.icw3);
pic.irr |= (1 << pic2.icw3);
else
pic.irr &= ~(1 << pic2.icw3);
pic.irr &= ~(1 << pic2.icw3);
pic.int_pending = (find_best_interrupt(&pic) != -1);
}
static void
pic_callback(void *priv)
{
@@ -264,15 +243,14 @@ pic_callback(void *priv)
latched--;
if (latched > 0)
timer_on_auto(&pic_timer, 0.35);
timer_on_auto(&pic_timer, 0.35);
}
void
pic_reset()
{
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(&pic2, 0, sizeof(pic_t));
@@ -281,10 +259,10 @@ pic_reset()
pic.interrupt = pic2.interrupt = 0x17;
if (is_at)
pic.slaves[2] = &pic2;
pic.slaves[2] = &pic2;
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));
timer_add(&pic_timer, pic_callback, &pic, 0);
tmr_inited = 1;
@@ -294,76 +272,69 @@ pic_reset()
smi_irq_mask = smi_irq_status = 0x0000;
shadow = 0;
shadow = 0;
pic_pci = 0;
}
void
pic_set_shadow(int sh)
{
shadow = sh;
}
void
pic_set_pci_flag(int pci)
{
pic_pci = pci;
}
static uint8_t
pic_level_triggered(pic_t *dev, int irq)
{
if (elcr_enabled)
return !!(dev->elcr & (1 << irq));
return !!(dev->elcr & (1 << irq));
else
return !!(dev->icw1 & 8);
return !!(dev->icw1 & 8);
}
int
picint_is_level(int irq)
{
return pic_level_triggered(((irq > 7) ? &pic2 : &pic), irq & 7);
}
static void
pic_acknowledge(pic_t *dev)
{
int pic_int = dev->interrupt & 7;
int pic_int = dev->interrupt & 7;
int pic_int_num = 1 << pic_int;
dev->isr |= 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
priority with ISR bit set, that is also not masked if the PIC is in special mask mode. */
static uint8_t
pic_non_specific_find(pic_t *dev)
{
int i, j;
int i, j;
uint8_t b, irq = 0xff;
for (i = 0; i < 8; i++) {
j = (i + dev->priority) & 7;
b = (1 << j);
j = (i + dev->priority) & 7;
b = (1 << j);
if ((dev->isr & b) && (!dev->special_mask_mode || !(dev->imr & b))) {
irq = j;
break;
}
if ((dev->isr & b) && (!dev->special_mask_mode || !(dev->imr & b))) {
irq = j;
break;
}
}
return irq;
}
/* Do the EOI and rotation, if either is requested, on the given IRQ. */
static void
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);
if (irq != 0xff) {
if (eoi)
dev->isr &= ~b;
if (rotate)
dev->priority = (irq + 1) & 7;
if (eoi)
dev->isr &= ~b;
if (rotate)
dev->priority = (irq + 1) & 7;
update_pending();
update_pending();
}
}
/* Automatic non-specific EOI. */
static __inline void
pic_auto_non_specific_eoi(pic_t *dev)
@@ -388,75 +358,73 @@ pic_auto_non_specific_eoi(pic_t *dev)
uint8_t irq;
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. */
static void
pic_command(pic_t *dev)
{
uint8_t irq = 0xff;
if (dev->ocw2 & 0x60) { /* SL and/or EOI set */
if (dev->ocw2 & 0x40) /* SL set, specific priority level */
irq = (dev->ocw2 & 0x07);
else /* SL clear, non-specific priority level (find highest with ISR set) */
irq = pic_non_specific_find(dev);
if (dev->ocw2 & 0x60) { /* SL and/or EOI set */
if (dev->ocw2 & 0x40) /* SL set, specific priority level */
irq = (dev->ocw2 & 0x07);
else /* SL clear, non-specific priority level (find highest with ISR set) */
irq = pic_non_specific_find(dev);
pic_action(dev, irq, dev->ocw2 & 0x20, dev->ocw2 & 0x80);
} else /* SL and EOI clear */
dev->auto_eoi_rotate = !!(dev->ocw2 & 0x80);
} else /* SL and EOI clear */
dev->auto_eoi_rotate = !!(dev->ocw2 & 0x80);
}
uint8_t
pic_read(uint16_t addr, void *priv)
{
pic_t *dev = (pic_t *) priv;
if (shadow) {
/* VIA PIC shadow read */
if (addr & 0x0001)
dev->data_bus = ((dev->icw2 & 0xf8) >> 3) << 0;
else {
dev->data_bus = ((dev->ocw3 & 0x20) >> 5) << 4;
dev->data_bus |= ((dev->ocw2 & 0x80) >> 7) << 3;
dev->data_bus |= ((dev->icw4 & 0x10) >> 4) << 2;
dev->data_bus |= ((dev->icw4 & 0x02) >> 1) << 1;
dev->data_bus |= ((dev->icw4 & 0x08) >> 3) << 0;
}
/* VIA PIC shadow read */
if (addr & 0x0001)
dev->data_bus = ((dev->icw2 & 0xf8) >> 3) << 0;
else {
dev->data_bus = ((dev->ocw3 & 0x20) >> 5) << 4;
dev->data_bus |= ((dev->ocw2 & 0x80) >> 7) << 3;
dev->data_bus |= ((dev->icw4 & 0x10) >> 4) << 2;
dev->data_bus |= ((dev->icw4 & 0x02) >> 1) << 1;
dev->data_bus |= ((dev->icw4 & 0x08) >> 3) << 0;
}
} else {
/* Standard 8259 PIC read */
/* Standard 8259 PIC read */
#ifndef UNDEFINED_READ
/* Put the IRR on to the data bus by default until the real PIC is probed. */
dev->data_bus = dev->irr;
/* Put the IRR on to the data bus by default until the real PIC is probed. */
dev->data_bus = dev->irr;
#endif
if (dev->ocw3 & 0x04) {
dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */
if (dev->int_pending) {
dev->data_bus = 0x80 | (dev->interrupt & 7);
pic_acknowledge(dev);
dev->int_pending = 0;
update_pending();
} else
dev->data_bus = 0x00;
dev->ocw3 &= ~0x04;
} else if (addr & 0x0001)
dev->data_bus = dev->imr;
else if (dev->ocw3 & 0x02) {
if (dev->ocw3 & 0x01)
dev->data_bus = dev->isr;
if (dev->ocw3 & 0x04) {
dev->interrupt &= ~0x20; /* Freeze the interrupt until the poll is over. */
if (dev->int_pending) {
dev->data_bus = 0x80 | (dev->interrupt & 7);
pic_acknowledge(dev);
dev->int_pending = 0;
update_pending();
} else
dev->data_bus = 0x00;
dev->ocw3 &= ~0x04;
} else if (addr & 0x0001)
dev->data_bus = dev->imr;
else if (dev->ocw3 & 0x02) {
if (dev->ocw3 & 0x01)
dev->data_bus = dev->isr;
#ifdef UNDEFINED_READ
else
dev->data_bus = 0x00;
else
dev->data_bus = 0x00;
#endif
}
/* If A0 = 0, VIA shadow is disabled, and poll mode is disabled,
simply read whatever is currently on the data bus. */
}
/* If A0 = 0, VIA shadow is disabled, and poll mode is disabled,
simply read whatever is currently on the 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;
}
static void
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;
if (addr & 0x0001) {
switch (dev->state) {
case STATE_ICW2:
dev->icw2 = val;
if (pic_cascade_mode(dev))
dev->state = STATE_ICW3;
else
dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE;
break;
case STATE_ICW3:
dev->icw3 = val;
dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE;
break;
case STATE_ICW4:
dev->icw4 = val;
dev->state = STATE_NONE;
break;
case STATE_NONE:
dev->imr = val;
update_pending();
break;
}
switch (dev->state) {
case STATE_ICW2:
dev->icw2 = val;
if (pic_cascade_mode(dev))
dev->state = STATE_ICW3;
else
dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE;
break;
case STATE_ICW3:
dev->icw3 = val;
dev->state = (dev->icw1 & 1) ? STATE_ICW4 : STATE_NONE;
break;
case STATE_ICW4:
dev->icw4 = val;
dev->state = STATE_NONE;
break;
case STATE_NONE:
dev->imr = val;
update_pending();
break;
}
} else {
if (val & 0x10) {
/* Treat any write with any of the bits 7 to 5 set as invalid if PCI. */
if (pic_pci && (val & 0xe0))
return;
if (val & 0x10) {
/* Treat any write with any of the bits 7 to 5 set as invalid if PCI. */
if (pic_pci && (val & 0xe0))
return;
dev->icw1 = val;
dev->icw2 = dev->icw3 = 0x00;
if (!(dev->icw1 & 1))
dev->icw4 = 0x00;
dev->ocw2 = dev->ocw3 = 0x00;
dev->irr = dev->lines;
dev->imr = dev->isr = 0x00;
dev->ack_bytes = dev->priority = 0x00;
dev->auto_eoi_rotate = dev->special_mask_mode = 0x00;
dev->interrupt = 0x17;
dev->int_pending = 0x00;
dev->state = STATE_ICW2;
update_pending();
} else if (val & 0x08) {
dev->ocw3 = val;
if (dev->ocw3 & 0x04)
dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */
if (dev->ocw3 & 0x40)
dev->special_mask_mode = !!(dev->ocw3 & 0x20);
} else {
dev->ocw2 = val;
pic_command(dev);
}
dev->icw1 = val;
dev->icw2 = dev->icw3 = 0x00;
if (!(dev->icw1 & 1))
dev->icw4 = 0x00;
dev->ocw2 = dev->ocw3 = 0x00;
dev->irr = dev->lines;
dev->imr = dev->isr = 0x00;
dev->ack_bytes = dev->priority = 0x00;
dev->auto_eoi_rotate = dev->special_mask_mode = 0x00;
dev->interrupt = 0x17;
dev->int_pending = 0x00;
dev->state = STATE_ICW2;
update_pending();
} else if (val & 0x08) {
dev->ocw3 = val;
if (dev->ocw3 & 0x04)
dev->interrupt |= 0x20; /* Freeze the interrupt until the poll is over. */
if (dev->ocw3 & 0x40)
dev->special_mask_mode = !!(dev->ocw3 & 0x20);
} else {
dev->ocw2 = val;
pic_command(dev);
}
}
}
void
pic_set_pci(void)
{
int i;
for (i = 0x0024; i < 0x0040; i += 4) {
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, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
}
for (i = 0x1120; i < 0x1140; i += 4) {
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, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
io_sethandler(i + 0x0080, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
}
}
void
pic_init(void)
{
@@ -555,7 +520,6 @@ pic_init(void)
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
}
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);
}
void
pic2_init(void)
{
@@ -573,152 +536,145 @@ pic2_init(void)
pic.slaves[2] = &pic2;
}
void
picint_common(uint16_t num, int level, int set)
{
int i, raise;
int i, raise;
uint8_t b, slaves = 0;
/* Make sure to ignore all slave IRQ's, and in case of AT+,
translate IRQ 2 to IRQ 9. */
for (i = 0; i < 8; i++) {
b = (1 << i);
raise = num & b;
b = (1 << i);
raise = num & b;
if (pic.icw3 & b) {
slaves++;
if (pic.icw3 & b) {
slaves++;
if (raise) {
num &= ~b;
if (pic.at && (i == 2))
num |= (1 << 9);
}
}
if (raise) {
num &= ~b;
if (pic.at && (i == 2))
num |= (1 << 9);
}
}
}
if (!slaves)
num &= 0x00ff;
num &= 0x00ff;
if (!num) {
pic_log("Attempting to %s null IRQ\n", set ? "raise" : "lower");
return;
pic_log("Attempting to %s null IRQ\n", set ? "raise" : "lower");
return;
}
if (num & 0x0100)
acpi_rtc_status = !!set;
acpi_rtc_status = !!set;
if (set) {
if (smi_irq_mask & num) {
smi_raise();
smi_irq_status |= num;
}
if (smi_irq_mask & num) {
smi_raise();
smi_irq_status |= num;
}
if (num & 0xff00) {
if (level)
pic2.lines |= (num >> 8);
if (num & 0xff00) {
if (level)
pic2.lines |= (num >> 8);
pic2.irr |= (num >> 8);
}
pic2.irr |= (num >> 8);
}
if (num & 0x00ff) {
if (level)
pic.lines |= (num >> 8);
if (num & 0x00ff) {
if (level)
pic.lines |= (num >> 8);
pic.irr |= num;
}
pic.irr |= num;
}
} else {
smi_irq_status &= ~num;
smi_irq_status &= ~num;
if (num & 0xff00) {
pic2.lines &= ~(num >> 8);
pic2.irr &= ~(num >> 8);
}
if (num & 0xff00) {
pic2.lines &= ~(num >> 8);
pic2.irr &= ~(num >> 8);
}
if (num & 0x00ff) {
pic.lines &= ~num;
pic.irr &= ~num;
}
if (num & 0x00ff) {
pic.lines &= ~num;
pic.irr &= ~num;
}
}
if (!(pic.interrupt & 0x20) && !(pic2.interrupt & 0x20))
update_pending();
update_pending();
}
void
picint(uint16_t num)
{
picint_common(num, 0, 1);
}
void
picintlevel(uint16_t num)
{
picint_common(num, 1, 1);
}
void
picintc(uint16_t num)
{
picint_common(num, 0, 0);
}
static uint8_t
pic_i86_mode(pic_t *dev)
{
return !!(dev->icw4 & 1);
}
static uint8_t
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;
intr &= 0x07;
pic_log(" pic_irq_ack_read(%08X, %i)\n", dev, phase);
if (dev != NULL) {
if (phase == 0) {
dev->interrupt |= 0x20; /* Freeze it so it still takes interrupts but they do not
override the one currently being processed. */
pic_acknowledge(dev);
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else
dev->data_bus = pic_i86_mode(dev) ? 0xff : 0xcd;
} else if (pic_i86_mode(dev)) {
dev->int_pending = 0;
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else
dev->data_bus = intr + (dev->icw2 & 0xf8);
pic_auto_non_specific_eoi(dev);
} else if (phase == 1) {
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else if (dev->icw1 & 0x04)
dev->data_bus = (intr << 2) + (dev->icw1 & 0xe0);
else
dev->data_bus = (intr << 3) + (dev->icw1 & 0xc0);
} else if (phase == 2) {
dev->int_pending = 0;
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else
dev->data_bus = dev->icw2;
pic_auto_non_specific_eoi(dev);
}
if (phase == 0) {
dev->interrupt |= 0x20; /* Freeze it so it still takes interrupts but they do not
override the one currently being processed. */
pic_acknowledge(dev);
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else
dev->data_bus = pic_i86_mode(dev) ? 0xff : 0xcd;
} else if (pic_i86_mode(dev)) {
dev->int_pending = 0;
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else
dev->data_bus = intr + (dev->icw2 & 0xf8);
pic_auto_non_specific_eoi(dev);
} else if (phase == 1) {
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else if (dev->icw1 & 0x04)
dev->data_bus = (intr << 2) + (dev->icw1 & 0xe0);
else
dev->data_bus = (intr << 3) + (dev->icw1 & 0xc0);
} else if (phase == 2) {
dev->int_pending = 0;
if (slave)
dev->data_bus = pic_irq_ack_read(dev->slaves[intr], phase);
else
dev->data_bus = dev->icw2;
pic_auto_non_specific_eoi(dev);
}
}
return dev->data_bus;
}
uint8_t
pic_irq_ack(void)
{
@@ -726,63 +682,62 @@ pic_irq_ack(void)
/* Needed for Xi8088. */
if ((pic.ack_bytes == 0) && pic.int_pending && pic_slave_on(&pic, pic.interrupt)) {
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. */
fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt);
exit(-1);
return -1;
}
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. */
fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt);
exit(-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);
if (pic.ack_bytes == 0) {
/* Needed for Xi8088. */
if (pic.interrupt & 0x40)
pic2.interrupt = 0x17;
pic.interrupt = 0x17;
update_pending();
/* Needed for Xi8088. */
if (pic.interrupt & 0x40)
pic2.interrupt = 0x17;
pic.interrupt = 0x17;
update_pending();
}
return ret;
}
int
picinterrupt()
{
int i, ret = -1;
if (pic.int_pending) {
if (pic_slave_on(&pic, pic.interrupt)) {
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. */
fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt);
exit(-1);
return -1;
}
if (pic_slave_on(&pic, pic.interrupt)) {
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. */
fatal("IRQ %i pending on AT without a pending IRQ on PIC %i (normal)\n", pic.interrupt, pic.interrupt);
exit(-1);
return -1;
}
pic.interrupt |= 0x40; /* Mark slave pending. */
}
pic.interrupt |= 0x40; /* Mark slave pending. */
}
if ((pic.interrupt == 0) && (pit_devs[1].data != NULL))
pit_devs[1].set_gate(pit_devs[1].data, 0, 0);
if ((pic.interrupt == 0) && (pit_devs[1].data != NULL))
pit_devs[1].set_gate(pit_devs[1].data, 0, 0);
/* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */
for (i = 0; i < 2; i++) {
ret = pic_irq_ack_read(&pic, pic.ack_bytes);
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
/* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */
for (i = 0; i < 2; i++) {
ret = pic_irq_ack_read(&pic, pic.ack_bytes);
pic.ack_bytes = (pic.ack_bytes + 1) % (pic_i86_mode(&pic) ? 2 : 3);
if (pic.ack_bytes == 0) {
if (pic.interrupt & 0x40)
pic2.interrupt = 0x17;
pic.interrupt = 0x17;
update_pending();
}
}
if (pic.ack_bytes == 0) {
if (pic.interrupt & 0x40)
pic2.interrupt = 0x17;
pic.interrupt = 0x17;
update_pending();
}
}
}
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/video.h>
#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_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_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_CUSTOM_CLOCK 64 /* The PIT uses custom clock inputs provided by another provider. */
#define PIT_SECONDARY 128 /* The PIT is secondary (ports 0048-004B). */
#ifdef ENABLE_PIT_LOG
int pit_do_log = ENABLE_PIT_LOG;
@@ -61,7 +61,7 @@ pit_log(const char *fmt, ...)
}
}
#else
#define pit_log(fmt, ...)
# define pit_log(fmt, ...)
#endif
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)
return;
pitf_t *pit = (pitf_t *)data;
pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id];
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
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];
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)
return;
pitf_t *pit = (pitf_t *)data;
pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id];
ctr->out_func = func;
@@ -113,8 +113,8 @@ pitf_ctr_set_using_timer(void *data, int counter_id, int using_timer)
if (tsc > 0)
timer_process();
pitf_t *pit = (pitf_t *)data;
ctrf_t *ctr = &pit->counters[counter_id];
pitf_t *pit = (pitf_t *) data;
ctrf_t *ctr = &pit->counters[counter_id];
ctr->using_timer = using_timer;
}
@@ -266,7 +266,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate)
ctr->enabled = gate;
break;
}
ctr->gate = gate;
ctr->gate = gate;
ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled;
if (ctr->using_timer && !ctr->running)
pitf_dump_and_disable_timer(ctr);
@@ -275,7 +275,7 @@ pitf_set_gate_no_timer(ctrf_t *ctr, int gate)
static void
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];
if (ctr->disabled) {
@@ -375,7 +375,7 @@ pitf_ctr_latch_count(ctrf_t *ctr)
static __inline void
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;
}
@@ -383,7 +383,7 @@ static void
pitf_write(uint16_t addr, uint8_t val, void *priv)
{
pitf_t *dev = (pitf_t *) priv;
int t = (addr & 3);
int t = (addr & 3);
ctrf_t *ctr;
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
pitf_read(uint16_t addr, void *priv)
{
pitf_t *dev = (pitf_t *) priv;
pitf_t *dev = (pitf_t *) priv;
uint8_t ret = 0xff;
int t = (addr & 3);
ctrf_t *ctr;
ctrf_t *ctr;
switch (addr & 3) {
case 3: /* Control. */
@@ -548,7 +548,7 @@ pitf_timer_over(void *p)
static void
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];
if (ctr->thit || !ctr->enabled)
@@ -565,11 +565,11 @@ pitf_ctr_clock(void *data, int counter_id)
static void
ctr_reset(ctrf_t *ctr)
{
ctr->ctrl = 0;
ctr->m = 0;
ctr->gate = 0;
ctr->l = 0xffff;
ctr->thit = 1;
ctr->ctrl = 0;
ctr->m = 0;
ctr->gate = 0;
ctr->l = 0xffff;
ctr->thit = 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)) {
for (int i = 0; i < 3; 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 = {
.name = "Intel 8253/8253-5 Programmable Interval Timer",
.name = "Intel 8253/8253-5 Programmable Interval Timer",
.internal_name = "i8253_fast",
.flags = DEVICE_ISA,
.local = PIT_8253,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = PIT_8253,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t i8254_fast_device = {
.name = "Intel 8254 Programmable Interval Timer",
.name = "Intel 8254 Programmable Interval Timer",
.internal_name = "i8254_fast",
.flags = DEVICE_ISA,
.local = PIT_8254,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = PIT_8254,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
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",
.flags = DEVICE_ISA,
.local = PIT_8254 | PIT_SECONDARY,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = PIT_8254 | PIT_SECONDARY,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
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",
.flags = DEVICE_ISA,
.local = PIT_8254 | PIT_EXT_IO,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = PIT_8254 | PIT_EXT_IO,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
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",
.flags = DEVICE_ISA,
.local = PIT_8254 | PIT_PS2 | PIT_EXT_IO,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = PIT_8254 | PIT_PS2 | PIT_EXT_IO,
.init = pitf_init,
.close = pitf_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const pit_intf_t pit_fast_intf = {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

484
src/usb.c
View File

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

243
src/vnc.c
View File

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

File diff suppressed because it is too large Load Diff