clang-format in src/
This commit is contained in:
1527
src/86box.c
1527
src/86box.c
File diff suppressed because it is too large
Load Diff
1819
src/acpi.c
1819
src/acpi.c
File diff suppressed because it is too large
Load Diff
88
src/apm.c
88
src/apm.c
@@ -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
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
220
src/config.c
220
src/config.c
@@ -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);
|
||||
|
||||
185
src/ddma.c
185
src/ddma.c
@@ -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
|
||||
};
|
||||
|
||||
586
src/device.c
586
src/device.c
@@ -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);
|
||||
}
|
||||
|
||||
51
src/fifo8.c
51
src/fifo8.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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\">"
|
||||
|
||||
@@ -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
614
src/io.c
@@ -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);
|
||||
|
||||
62
src/ioapic.c
62
src/ioapic.c
@@ -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
|
||||
};
|
||||
|
||||
65
src/log.c
65
src/log.c
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
128
src/mca.c
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
src/nmi.c
15
src/nmi.c
@@ -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
220
src/nvr.c
@@ -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));
|
||||
}
|
||||
|
||||
1250
src/nvr_at.c
1250
src/nvr_at.c
File diff suppressed because it is too large
Load Diff
119
src/nvr_ps2.c
119
src/nvr_ps2.c
@@ -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
|
||||
};
|
||||
|
||||
401
src/pci_dummy.c
401
src/pci_dummy.c
@@ -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
593
src/pic.c
@@ -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;
|
||||
|
||||
126
src/pit_fast.c
126
src/pit_fast.c
@@ -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 = {
|
||||
|
||||
122
src/port_6x.c
122
src/port_6x.c
@@ -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
|
||||
};
|
||||
|
||||
151
src/port_92.c
151
src/port_92.c
@@ -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
|
||||
};
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
#include <86box/pit.h>
|
||||
#include <86box/ppi.h>
|
||||
|
||||
|
||||
PPI ppi;
|
||||
int ppispeakon;
|
||||
|
||||
|
||||
void
|
||||
ppi_reset(void)
|
||||
{
|
||||
|
||||
74
src/random.c
74
src/random.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
150
src/timer.c
150
src/timer.c
@@ -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);
|
||||
}
|
||||
|
||||
468
src/upi42.c
468
src/upi42.c
@@ -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
484
src/usb.c
@@ -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
243
src/vnc.c
@@ -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)
|
||||
{
|
||||
|
||||
782
src/vnc_keymap.c
782
src/vnc_keymap.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user