Merge branch '86Box:master' into master

This commit is contained in:
starfrost
2025-07-10 17:36:07 +01:00
committed by GitHub
58 changed files with 960 additions and 759 deletions

View File

@@ -188,7 +188,6 @@ int gfxcard[GFXCARD_MAX] = { 0, 0 }; /* (C) graphic
int show_second_monitors = 1; /* (C) show non-primary monitors */
int sound_is_float = 1; /* (C) sound uses FP values */
int voodoo_enabled = 0; /* (C) video option */
int lba_enhancer_enabled = 0; /* (C) enable Vision Systems LBA Enhancer */
int ibm8514_standalone_enabled = 0; /* (C) video option */
int xga_standalone_enabled = 0; /* (C) video option */
int da2_standalone_enabled = 0; /* (C) video option */
@@ -217,12 +216,15 @@ int test_mode = 0; /* (C) Test mo
char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */
int sound_muted = 0; /* (C) Is sound muted? */
int inhibit_multimedia_keys; /* (C) Inhibit multimedia keys on Windows. */
int force_10ms; /* (C) Force 10ms CPU frame intervals. */
int other_ide_present = 0; /* IDE controllers from non-IDE cards are
present */
int other_scsi_present = 0; /* SCSI controllers from non-SCSI cards are
present */
int is_pcjr = 0; /* The current machine is PCjr. */
// Accelerator key array
struct accelKey acc_keys[NUM_ACCELS];
@@ -1532,9 +1534,6 @@ pc_reset_hard_init(void)
if (unittester_enabled)
device_add(&unittester_device);
if (lba_enhancer_enabled)
device_add(&lba_enhancer_device);
if (novell_keycard_enabled)
device_add(&novell_keycard_device);
@@ -1592,19 +1591,19 @@ update_mouse_msg(void)
*(wcp - 1) = L'\0';
mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1);
#ifdef _WIN32
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls",
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i.%%i%%%% - %ls",
plat_get_string(STRING_MOUSE_CAPTURE));
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls",
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i.%%i%%%% - %ls",
(mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB));
wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2]));
#else
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls",
EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu,
plat_get_string(STRING_MOUSE_CAPTURE));
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls",
EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu,
(mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB));
swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls",
swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls",
EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu);
#endif
}
@@ -1714,7 +1713,7 @@ pc_run(void)
/* Run a block of code. */
startblit();
cpu_exec((int32_t) cpu_s->rspeed / 100);
cpu_exec((int32_t) cpu_s->rspeed / (force_10ms ? 100 : 1000));
ack_pause();
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
if (gdbstub_step == GDBSTUB_EXEC) {
@@ -1729,14 +1728,14 @@ pc_run(void)
/* Done with this frame, update statistics. */
framecount++;
if (++framecountx >= 100) {
if (++framecountx >= (force_10ms ? 100 : 1000)) {
framecountx = 0;
frames = 0;
}
if (title_update) {
mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture;
swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps);
swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10), force_10ms ? 0 : (fps % 10));
#ifdef __APPLE__
/* Needed due to modifying the UI on the non-main thread is a big no-no. */
dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title);

View File

@@ -144,6 +144,8 @@ load_general(void)
video_grayscale = ini_section_get_int(cat, "video_grayscale", 0);
video_graytype = ini_section_get_int(cat, "video_graytype", 0);
force_10ms = !!ini_section_get_int(cat, "force_10ms", 0);
rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0);
update_icons = ini_section_get_int(cat, "update_icons", 1);
@@ -263,7 +265,9 @@ load_machine(void)
if (p != NULL) {
migrate_from = p;
/* Migrate renamed machines. */
if (!strcmp(p, "430nx"))
if (!strcmp(p, "tandy"))
machine = machine_get_machine_from_internal_name("tandy1000sx");
else if (!strcmp(p, "430nx"))
machine = machine_get_machine_from_internal_name("586ip");
else if (!strcmp(p, "586mc1"))
machine = machine_get_machine_from_internal_name("586is");
@@ -990,11 +994,6 @@ load_storage_controllers(void)
}
}
}
lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0);
if (!lba_enhancer_enabled)
ini_section_delete_var(cat, "lba_enhancer_enabled");
}
/* Load "Hard Disks" section. */
@@ -1211,14 +1210,20 @@ load_floppy_and_cdrom_drives(void)
unsigned int board = 0;
unsigned int dev = 0;
int c;
int d = 0;
int d;
int count = cdrom_get_type_count();
memset(temp, 0x00, sizeof(temp));
for (c = 0; c < FDD_NUM; c++) {
sprintf(temp, "fdd_%02i_type", c + 1);
p = ini_section_get_string(cat, temp, (c < 2) ? "525_2dd" : "none");
fdd_set_type(c, fdd_get_from_internal_name(p));
if (!strcmp(p, "525_2hd_ps2"))
d = fdd_get_from_internal_name("525_2hd");
else if (!strcmp(p, "35_2hd_ps2"))
d = fdd_get_from_internal_name("35_2hd");
else
d = fdd_get_from_internal_name(p);
fdd_set_type(c, d);
if (fdd_get_type(c) > 13)
fdd_set_type(c, 13);
@@ -1297,6 +1302,7 @@ load_floppy_and_cdrom_drives(void)
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_parameters", c + 1);
d = 0;
p = ini_section_get_string(cat, temp, NULL);
if (p != NULL)
sscanf(p, "%01u, %s", &d, s);
@@ -1725,6 +1731,17 @@ load_other_peripherals(void)
ini_section_delete_var(cat, temp);
}
/* Backwards compatibility for standalone LBA Enhancer from v4.2 and older. */
if (ini_section_get_int(ini_find_section(config, "Storage controllers"), "lba_enhancer_enabled", 0) == 1) {
/* Migrate to the first available ISA ROM slot. */
for (uint8_t c = 0; c < ISAROM_MAX; c++) {
if (!isarom_type[c]) {
isarom_type[c] = isarom_get_from_internal_name("lba_enhancer");
break;
}
}
}
p = ini_section_get_string(cat, "isartc_type", "none");
isartc_type = isartc_get_from_internal_name(p);
@@ -1947,6 +1964,10 @@ save_general(void)
const char *va_name;
ini_section_set_int(cat, "force_10ms", force_10ms);
if (force_10ms == 0)
ini_section_delete_var(cat, "force_10ms");
ini_section_set_int(cat, "inhibit_multimedia_keys", inhibit_multimedia_keys);
if (inhibit_multimedia_keys == 0)
ini_section_delete_var(cat, "inhibit_multimedia_keys");
@@ -2691,10 +2712,19 @@ save_storage_controllers(void)
}
}
if (lba_enhancer_enabled == 0)
/* Downgrade compatibility for standalone LBA Enhancer from v4.2 and older. */
int card_id = isarom_get_from_internal_name("lba_enhancer");
for (c = 0; c < ISAROM_MAX; c++) {
if (isarom_type[c] == card_id) {
/* A special value of 2 still enables the cards on older versions,
but lets newer versions know that they've already been migrated. */
ini_section_set_int(cat, "lba_enhancer_enabled", 2);
card_id = 0; /* mark as found */
break;
}
}
if (card_id > 0) /* not found */
ini_section_delete_var(cat, "lba_enhancer_enabled");
else
ini_section_set_int(cat, "lba_enhancer_enabled", 1);
ini_delete_section_if_empty(config, cat);
}

View File

@@ -739,7 +739,7 @@ exec386_dynarec(int32_t cycs)
uint64_t oldtsc;
uint64_t delta;
int32_t cyc_period = cycs / 2000; /*5us*/
int32_t cyc_period = cycs / (force_10ms ? 2000 : 200); /*5us*/
# ifdef USE_ACYCS
acycs = 0;

View File

@@ -1226,22 +1226,24 @@ custom_nmi(void)
}
static int
irq_pending(void)
irq_pending(int nec_hlt)
{
uint8_t temp;
int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt;
temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint);
temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || (i_flag && pic.int_pending && !noint);
return temp;
}
static void
check_interrupts(void)
check_interrupts(int nec_hlt)
{
int temp;
int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt;
if (irq_pending()) {
if ((cpu_state.flags & T_FLAG) && !noint) {
if (irq_pending(nec_hlt)) {
if ((cpu_state.flags & T_FLAG) && !(noint & 1)) {
interrupt(1);
return;
}
@@ -1256,7 +1258,7 @@ check_interrupts(void)
#endif
return;
}
if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) {
if (i_flag && pic.int_pending && !noint) {
repeating = 0;
completed = 1;
ovr_seg = NULL;
@@ -1289,7 +1291,7 @@ rep_action(int bits)
return 0;
wait_cycs(2, 0);
t = CX;
if (irq_pending() && (repeating != 0)) {
if (irq_pending(0) && (repeating != 0)) {
access(71, bits);
pfq_clear();
if (is_nec && (ovr_seg != NULL))
@@ -3008,9 +3010,9 @@ execx86(int cycs)
wait_cycs(2, 0);
wait_cycs(5, 0);
#ifdef NO_HACK
if (irq_pending()) {
if (irq_pending(0)) {
wait_cycs(7, 0);
check_interrupts();
check_interrupts(0);
} else {
repeating = 1;
completed = 0;
@@ -3018,7 +3020,7 @@ execx86(int cycs)
}
#else
wait_cycs(7, 0);
check_interrupts();
check_interrupts(0);
#endif
break;
case 0x9C: /*PUSHF*/
@@ -3029,16 +3031,19 @@ execx86(int cycs)
tempw = (cpu_state.flags & 0x0fd7) | 0xf000;
push(&tempw);
break;
case 0x9D: /*POPF*/
case 0x9D: { /*POPF*/
uint16_t old_flags = cpu_state.flags;
access(25, 16);
if (is_nec && cpu_md_write_disable)
cpu_state.flags = pop() | 0x8002;
else
cpu_state.flags = pop() | 0x0002;
wait_cycs(1, 0);
if ((old_flags ^ cpu_state.flags) & T_FLAG)
noint = 1;
sync_to_i8080();
break;
case 0x9E: /*SAHF*/
} case 0x9E: /*SAHF*/
wait_cycs(1, 0);
cpu_state.flags = (cpu_state.flags & 0xff02) | AH;
wait_cycs(2, 0);
@@ -3307,7 +3312,7 @@ execx86(int cycs)
else
cpu_state.flags = pop() | 0x0002;
wait_cycs(5, 0);
noint = 1;
noint = 2;
nmi_enable = 1;
if (is_nec && !(cpu_state.flags & MD_FLAG))
sync_to_i8080();
@@ -3647,9 +3652,9 @@ execx86(int cycs)
pfq_clear();
}
wait_cycs(1, 0);
if (irq_pending()) {
if (irq_pending(is_nec)) {
wait_cycs(cycles & 1, 0);
check_interrupts();
check_interrupts(is_nec);
} else {
repeating = 1;
completed = 0;
@@ -3848,7 +3853,7 @@ exec_completed:
if (in_lock)
clear_lock = 1;
clock_end();
check_interrupts();
check_interrupts(0);
if (noint)
noint = 0;

View File

@@ -688,6 +688,23 @@ const cpu_family_t cpu_families[] = {
.cache_write_cycles = 0,
.atclk_div = 1
},
{
.name = "8",
.cpu_type = CPU_V20,
.fpus = fpus_8088,
.rspeed = 8000000,
.multi = 1,
.voltage = 5000,
.edx_reset = 0,
.cpuid_model = 0,
.cyrix_id = 0,
.cpu_flags = 0,
.mem_read_cycles = 0,
.mem_write_cycles = 0,
.cache_read_cycles = 0,
.cache_write_cycles = 0,
.atclk_div = 1
},
{
.name = "10",
.cpu_type = CPU_V20,
@@ -911,10 +928,10 @@ const cpu_family_t cpu_families[] = {
.internal_name = "necv30",
.cpus = (const CPU[]) {
{
.name = "5",
.name = "7.16",
.cpu_type = CPU_V30,
.fpus = fpus_80186,
.rspeed = 5000000,
.rspeed = 7159092,
.multi = 1,
.voltage = 5000,
.edx_reset = 0,
@@ -944,6 +961,23 @@ const cpu_family_t cpu_families[] = {
.cache_write_cycles = 0,
.atclk_div = 1
},
{
.name = "9.54",
.cpu_type = CPU_V30,
.fpus = fpus_80186,
.rspeed = 9545456,
.multi = 1,
.voltage = 5000,
.edx_reset = 0,
.cpuid_model = 0,
.cyrix_id = 0,
.cpu_flags = 0,
.mem_read_cycles = 0,
.mem_write_cycles = 0,
.cache_read_cycles = 0,
.cache_write_cycles = 0,
.atclk_div = 1
},
{
.name = "10",
.cpu_type = CPU_V30,

View File

@@ -26,9 +26,14 @@
#include <86box/nvr.h>
#include <86box/isarom.h>
#define ISAROM_CARD 0
#define ISAROM_CARD_DUAL 1
#define ISAROM_CARD_QUAD 2
enum {
ISAROM_CARD = 0,
ISAROM_CARD_DUAL,
ISAROM_CARD_QUAD,
ISAROM_CARD_LBA_ENHANCER
};
#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin"
#ifdef ENABLE_ISAROM_LOG
int isarom_do_log = ENABLE_ISAROM_LOG;
@@ -56,7 +61,7 @@ typedef struct isarom_t {
uint32_t size;
uint32_t len;
char nvr_path[64];
uint8_t wp;
uint8_t writable;
} socket[4];
uint8_t inst;
uint8_t type;
@@ -65,11 +70,14 @@ typedef struct isarom_t {
static inline uint8_t
get_limit(uint8_t type)
{
if (type == ISAROM_CARD_DUAL)
return 2;
if (type == ISAROM_CARD_QUAD)
return 4;
return 1;
switch (type) {
case ISAROM_CARD_DUAL:
return 2;
case ISAROM_CARD_QUAD:
return 4;
default:
return 1;
}
}
static inline void
@@ -92,12 +100,13 @@ isarom_close(void *priv)
if (!priv)
return;
for (uint8_t i = 0; i < get_limit(dev->type); i++)
if (dev->socket[i].rom.rom) {
for (uint8_t i = 0; i < get_limit(dev->type); i++) {
if (dev->socket[i].writable) {
isarom_log("isarom[%u]: saving NVR for socket %u -> %s (%u bytes)\n",
dev->inst, i, dev->socket[i].nvr_path, dev->socket[i].size);
isarom_save_nvr(dev->socket[i].nvr_path, dev->socket[i].rom.rom, dev->socket[i].size);
}
}
free(dev);
}
@@ -115,32 +124,42 @@ isarom_init(const device_t *info)
isarom_log("isarom[%u]: initializing device (type=%u)\n", dev->inst, dev->type);
for (uint8_t i = 0; i < get_limit(dev->type); i++) {
char key_fn[12];
char key_addr[14];
char key_size[14];
char key_writes[22];
char str[22];
char suffix[4] = "";
if (i > 0)
snprintf(suffix, sizeof(suffix), "%d", i + 1);
snprintf(key_fn, sizeof(key_fn), "bios_fn%s", suffix);
snprintf(key_addr, sizeof(key_addr), "bios_addr%s", suffix);
snprintf(key_size, sizeof(key_size), "bios_size%s", suffix);
snprintf(key_writes, sizeof(key_writes), "rom_writes_enabled%s", suffix);
snprintf(str, sizeof(str), "bios_addr%s", suffix);
dev->socket[i].addr = device_get_config_hex20(str);
dev->socket[i].fn = device_get_config_string(key_fn);
dev->socket[i].addr = device_get_config_hex20(key_addr);
dev->socket[i].size = device_get_config_int(key_size);
// Note: 2K is the smallest ROM I've found, but 86box's memory granularity is 4k, the number below is fine
// as we'll end up allocating no less than 4k due to the device config limits.
dev->socket[i].len = (dev->socket[i].size > 2048) ? dev->socket[i].size - 1 : 0;
dev->socket[i].wp = (uint8_t) device_get_config_int(key_writes) ? 1 : 0;
switch (dev->type) {
case ISAROM_CARD_LBA_ENHANCER:
dev->socket[i].fn = BIOS_LBA_ENHANCER;
dev->socket[i].size = 0x4000;
break;
isarom_log("isarom[%u]: socket %u: addr=0x%05X size=%u wp=%u fn=%s\n",
default:
snprintf(str, sizeof(str), "bios_fn%s", suffix);
dev->socket[i].fn = device_get_config_string(str);
snprintf(str, sizeof(str), "bios_size%s", suffix);
dev->socket[i].size = device_get_config_int(str);
snprintf(str, sizeof(str), "rom_writes_enabled%s", suffix);
if (device_get_config_int(str))
dev->socket[i].writable = 1;
break;
}
/* Note: 2K is the smallest ROM I've found, but 86Box's memory granularity is 4K, the number
below is fine as we'll end up allocating no less than 4K due to the device config limits. */
dev->socket[i].len = (dev->socket[i].size > 0) ? ((dev->socket[i].size - 1) | MEM_GRANULARITY_MASK) : 0;
isarom_log("isarom[%u]: socket %u: addr=0x%05X size=%u writable=%u fn=%s\n",
dev->inst, i, dev->socket[i].addr, dev->socket[i].size,
dev->socket[i].wp, dev->socket[i].fn ? dev->socket[i].fn : "(null)");
dev->socket[i].writable, dev->socket[i].fn ? dev->socket[i].fn : "(null)");
if (dev->socket[i].addr != 0 && dev->socket[i].fn != NULL) {
if ((dev->socket[i].addr != 0) && (dev->socket[i].fn != NULL)) {
rom_init(&dev->socket[i].rom,
dev->socket[i].fn,
dev->socket[i].addr,
@@ -151,7 +170,7 @@ isarom_init(const device_t *info)
isarom_log("isarom[%u]: ROM initialized for socket %u\n", dev->inst, i);
if (dev->socket[i].wp) {
if (dev->socket[i].writable) {
mem_mapping_set_write_handler(&dev->socket[i].rom.mapping, rom_write, rom_writew, rom_writel);
snprintf(dev->socket[i].nvr_path, sizeof(dev->socket[i].nvr_path), "isarom_%i_%i.nvr", dev->inst, i + 1);
FILE *fp = nvr_fopen(dev->socket[i].nvr_path, "rb");
@@ -168,6 +187,12 @@ isarom_init(const device_t *info)
return dev;
}
static int
isarom_lba_enhancer_available(void)
{
return rom_present(BIOS_LBA_ENHANCER);
}
#define BIOS_FILE_FILTER "ROM files (*.bin *.rom)|*.bin,*.rom"
#define BIOS_ADDR_SELECTION { \
@@ -528,6 +553,29 @@ static const device_config_t isarom_quad_config[] = {
},
{ .name = "", .description = "", .type = CONFIG_END }
};
static const device_config_t lba_enhancer_config[] = {
{
.name = "bios_addr",
.description = "BIOS Address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0xc8000,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "C800H", .value = 0xc8000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "D000H", .value = 0xd0000 },
{ .description = "D400H", .value = 0xd4000 },
{ .description = "D800H", .value = 0xd8000 },
{ .description = "DC00H", .value = 0xdc000 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
};
// clang-format on
static const device_t isarom_device = {
@@ -572,15 +620,30 @@ static const device_t isarom_quad_device = {
.config = isarom_quad_config
};
static const device_t lba_enhancer_device = {
.name = "Vision Systems LBA Enhancer",
.internal_name = "lba_enhancer",
.flags = DEVICE_ISA,
.local = ISAROM_CARD_LBA_ENHANCER,
.init = isarom_init,
.close = isarom_close,
.reset = NULL,
.available = isarom_lba_enhancer_available,
.speed_changed = NULL,
.force_redraw = NULL,
.config = lba_enhancer_config
};
static const struct {
const device_t *dev;
} boards[] = {
// clang-format off
{ &device_none },
{ &isarom_device },
{ &isarom_dual_device },
{ &isarom_quad_device },
{ NULL }
{ &device_none },
{ &isarom_device },
{ &isarom_dual_device },
{ &isarom_quad_device },
{ &lba_enhancer_device },
{ NULL }
// clang-format on
};

View File

@@ -626,34 +626,29 @@ lpt_set_ext(const int port, const uint8_t ext)
void
lpt_set_ecp(const int port, const uint8_t ecp)
{
if (lpt_ports[port].enabled) {
const uint16_t addr = lpt_ports[port].addr;
lpt_port_setup(port, 0xfff);
if (lpt_ports[port].enabled)
lpt_ports[port].ecp = ecp;
lpt_port_setup(port, addr);
}
}
void
lpt_set_epp(const int port, const uint8_t epp)
{
if (lpt_ports[port].enabled) {
const uint16_t addr = lpt_ports[port].addr;
lpt_port_setup(port, 0xfff);
if (lpt_ports[port].enabled)
lpt_ports[port].epp = epp;
lpt_port_setup(port, addr);
}
}
void
lpt_set_lv2(const int port, const uint8_t lv2)
{
if (lpt_ports[port].enabled) {
const uint16_t addr = lpt_ports[port].addr;
lpt_port_setup(port, 0xfff);
if (lpt_ports[port].enabled)
lpt_ports[port].lv2 = lv2;
lpt_port_setup(port, addr);
}
}
void
lpt_set_fifo_threshold(const int port, const int threshold)
{
if (lpt_ports[port].enabled)
fifo_set_trigger_len(lpt_ports[port].fifo, threshold);
}
void
@@ -778,19 +773,19 @@ void
lpt_port_setup(const int i, const uint16_t port)
{
if (lpt_ports[i].enabled) {
if (lpt_ports[i].addr != 0xffff) {
if ((lpt_ports[i].addr != 0x0000) && (lpt_ports[i].addr != 0xffff)) {
io_removehandler(lpt_ports[i].addr, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
io_removehandler(lpt_ports[i].addr + 0x0400, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
}
if (port != 0xffff) {
if ((port != 0x0000) && (port != 0xffff)) {
lpt_log("Set handler: %04X-%04X\n", port, port + 0x0003);
io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
if (lpt_ports[i].epp)
io_sethandler(lpt_ports[i].addr + 0x0003, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
io_sethandler(port + 0x0003, 0x0005, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
if (lpt_ports[i].ecp || lpt_ports[i].lv2) {
io_sethandler(port + 0x0400, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
if (lpt_ports[i].epp)
io_sethandler(lpt_ports[i].addr + 0x0403, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
io_sethandler(port + 0x0404, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]);
}
}
lpt_ports[i].addr = port;

View File

@@ -35,7 +35,6 @@ add_library(hdd OBJECT
hdc_ide_sff8038i.c
hdc_ide_um8673f.c
hdc_ide_w83769f.c
lba_enhancer.c
)
add_library(zip OBJECT zip.c)

View File

@@ -1,100 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Vision Systems LBA Enhancer emulation.
*
*
*
* Authors: Cacodemon345
*
* Copyright 2024 Cacodemon345
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/plat_unused.h>
typedef struct lba_enhancer_t
{
rom_t rom;
} lba_enhancer_t;
#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin"
void
lba_enhancer_close(void* priv)
{
free(priv);
return;
}
void *
lba_enhancer_init(UNUSED(const device_t *info))
{
lba_enhancer_t *dev = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t));
rom_init(&dev->rom, BIOS_LBA_ENHANCER,
device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
return dev;
}
static int
lba_enhancer_available(void)
{
return rom_present(BIOS_LBA_ENHANCER);
}
// clang-format off
static const device_config_t lba_enhancer_config[] = {
{
.name = "bios_addr",
.description = "BIOS Address",
.type = CONFIG_HEX20,
.default_string = NULL,
.default_int = 0xc8000,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "C800H", .value = 0xc8000 },
{ .description = "CC00H", .value = 0xcc000 },
{ .description = "D000H", .value = 0xd0000 },
{ .description = "D400H", .value = 0xd4000 },
{ .description = "D800H", .value = 0xd8000 },
{ .description = "DC00H", .value = 0xdc000 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
};
// clang-format on
const device_t lba_enhancer_device = {
.name = "Vision Systems LBA Enhancer",
.internal_name = "lba_enhancer",
.flags = DEVICE_ISA16,
.local = 0,
.init = lba_enhancer_init,
.close = lba_enhancer_close,
.reset = NULL,
.available = lba_enhancer_available,
.speed_changed = NULL,
.force_redraw = NULL,
.config = lba_enhancer_config
};

View File

@@ -212,18 +212,9 @@ int
fdd_get_from_internal_name(char *s)
{
int c = 0;
char *n;
/* TODO: Remove this once the migration period is over. */
if (!strcmp(s, "525_2hd_ps2"))
n = "525_2hd";
else if (!strcmp(s, "35_2hd_ps2"))
n = "35_2hd";
else
n = s;
while (strlen(drive_types[c].internal_name)) {
if (!strcmp((char *) drive_types[c].internal_name, n))
if (!strcmp((char *) drive_types[c].internal_name, s))
return c;
c++;
}

View File

@@ -252,7 +252,7 @@ gameport_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), void *priv)
/* Notify the interface. */
joystick->intf->write(joystick->dat);
cycles -= ISA_CYCLES(8);
cycles -= ISA_CYCLES((8 << is_pcjr));
}
static uint8_t
@@ -268,7 +268,7 @@ gameport_read(UNUSED(uint16_t addr), void *priv)
/* Merge axis state with button state. */
uint8_t ret = joystick->state | joystick->intf->read(joystick->dat);
cycles -= ISA_CYCLES(8);
cycles -= ISA_CYCLES((8 << is_pcjr));
return ret;
}
@@ -306,6 +306,9 @@ gameport_remap(void *priv, uint16_t address)
gameport_t *dev = (gameport_t *) priv;
gameport_t *other_dev;
if (dev == NULL)
return;
if (dev->addr) {
/* Remove this port from the active ports list. */
if (active_gameports == dev) {

View File

@@ -149,13 +149,14 @@ extern int fpu_type; /* (C) fpu type */
extern int fpu_softfloat; /* (C) fpu uses softfloat */
extern int time_sync; /* (C) enable time sync */
extern int hdd_format_type; /* (C) hard disk file format */
extern int lba_enhancer_enabled; /* (C) enable Vision Systems LBA Enhancer */
extern int confirm_reset; /* (C) enable reset confirmation */
extern int confirm_exit; /* (C) enable exit confirmation */
extern int confirm_save; /* (C) enable save confirmation */
extern int enable_discord; /* (C) enable Discord integration */
extern int force_10ms; /* (C) force 10ms CPU frame interval */
extern int other_ide_present; /* IDE controllers from non-IDE cards are present */
extern int other_scsi_present; /* SCSI controllers from non-SCSI cards are present */
extern int is_pcjr; /* The current machine is PCjr. */
extern int hard_reset_pending;
extern int fixed_size_x;

View File

@@ -112,9 +112,6 @@ extern const device_t xtide_acculogic_device; /* xtide_ps2 */
extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */
extern const device_t xtide_at_ps2_2ch_device; /* xtide_at_ps2_2ch */
/* Miscellaneous */
extern const device_t lba_enhancer_device;
extern void hdc_init(void);
extern void hdc_reset(void);

View File

@@ -37,6 +37,7 @@ extern void lpt_set_ext(int port, uint8_t ext);
extern void lpt_set_ecp(int port, uint8_t ecp);
extern void lpt_set_epp(int port, uint8_t epp);
extern void lpt_set_lv2(int port, uint8_t lv2);
extern void lpt_set_fifo_threshold(int port, int threshold);
extern void lpt_reset(void);
extern void lpt_close(void);
extern void lpt_init(void);

View File

@@ -483,6 +483,8 @@ extern void mem_remap_top_nomid(int kb);
extern void umc_smram_recalc(uint32_t start, int set);
extern void pcjr_waitstates(void *);
extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO];
extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];

View File

@@ -41,89 +41,89 @@ typedef struct dp8390_t {
/* Command Register - 00h read/write */
struct CR_t {
int stop; /* STP - Software Reset command */
int start; /* START - start the NIC */
int tx_packet; /* TXP - initiate packet transmission */
bool stop; /* STP - Software Reset command */
bool start; /* START - start the NIC */
bool tx_packet; /* TXP - initiate packet transmission */
uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */
uint8_t pgsel; /* PS0,PS1 - Page select */
} CR;
/* Interrupt Status Register - 07h read/write */
struct ISR_t {
int pkt_rx; /* PRX - packet received with no errors */
int pkt_tx; /* PTX - packet txed with no errors */
int rx_err; /* RXE - packet rxed with 1 or more errors */
int tx_err; /* TXE - packet txed " " " " " */
int overwrite; /* OVW - rx buffer resources exhausted */
int cnt_oflow; /* CNT - network tally counter MSB's set */
int rdma_done; /* RDC - remote DMA complete */
int reset; /* RST - reset status */
bool pkt_rx; /* PRX - packet received with no errors */
bool pkt_tx; /* PTX - packet txed with no errors */
bool rx_err; /* RXE - packet rxed with 1 or more errors */
bool tx_err; /* TXE - packet txed " " " " " */
bool overwrite; /* OVW - rx buffer resources exhausted */
bool cnt_oflow; /* CNT - network tally counter MSB's set */
bool rdma_done; /* RDC - remote DMA complete */
bool reset; /* RST - reset status */
} ISR;
/* Interrupt Mask Register - 0fh write */
struct IMR_t {
int rx_inte; /* PRXE - packet rx interrupt enable */
int tx_inte; /* PTXE - packet tx interrput enable */
int rxerr_inte; /* RXEE - rx error interrupt enable */
int txerr_inte; /* TXEE - tx error interrupt enable */
int overw_inte; /* OVWE - overwrite warn int enable */
int cofl_inte; /* CNTE - counter o'flow int enable */
int rdma_inte; /* RDCE - remote DMA complete int enable */
int reserved; /* D7 - reserved */
bool rx_inte; /* PRXE - packet rx interrupt enable */
bool tx_inte; /* PTXE - packet tx interrput enable */
bool rxerr_inte; /* RXEE - rx error interrupt enable */
bool txerr_inte; /* TXEE - tx error interrupt enable */
bool overw_inte; /* OVWE - overwrite warn int enable */
bool cofl_inte; /* CNTE - counter o'flow int enable */
bool rdma_inte; /* RDCE - remote DMA complete int enable */
bool reserved; /* D7 - reserved */
} IMR;
/* Data Configuration Register - 0eh write */
struct DCR_t {
int wdsize; /* WTS - 8/16-bit select */
int endian; /* BOS - byte-order select */
int longaddr; /* LAS - long-address select */
int loop; /* LS - loopback select */
int auto_rx; /* AR - auto-remove rx pkts with remote DMA */
bool wdsize; /* WTS - 8/16-bit select */
bool endian; /* BOS - byte-order select */
bool longaddr; /* LAS - long-address select */
bool loop; /* LS - loopback select */
bool auto_rx; /* AR - auto-remove rx pkts with remote DMA */
uint8_t fifo_size; /* FT0,FT1 - fifo threshold */
} DCR;
/* Transmit Configuration Register - 0dh write */
struct TCR_t {
int crc_disable; /* CRC - inhibit tx CRC */
bool crc_disable; /* CRC - inhibit tx CRC */
uint8_t loop_cntl; /* LB0,LB1 - loopback control */
int ext_stoptx; /* ATD - allow tx disable by external mcast */
int coll_prio; /* OFST - backoff algorithm select */
bool ext_stoptx; /* ATD - allow tx disable by external mcast */
bool coll_prio; /* OFST - backoff algorithm select */
uint8_t reserved; /* D5,D6,D7 - reserved */
} TCR;
/* Transmit Status Register - 04h read */
struct TSR_t {
int tx_ok; /* PTX - tx complete without error */
int reserved; /* D1 - reserved */
int collided; /* COL - tx collided >= 1 times */
int aborted; /* ABT - aborted due to excessive collisions */
int no_carrier; /* CRS - carrier-sense lost */
int fifo_ur; /* FU - FIFO underrun */
int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */
int ow_coll; /* OWC - out-of-window collision */
bool tx_ok; /* PTX - tx complete without error */
bool reserved; /* D1 - reserved */
bool collided; /* COL - tx collided >= 1 times */
bool aborted; /* ABT - aborted due to excessive collisions */
bool no_carrier; /* CRS - carrier-sense lost */
bool fifo_ur; /* FU - FIFO underrun */
bool cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */
bool ow_coll; /* OWC - out-of-window collision */
} TSR;
/* Receive Configuration Register - 0ch write */
struct RCR_t {
int errors_ok; /* SEP - accept pkts with rx errors */
int runts_ok; /* AR - accept < 64-byte runts */
int broadcast; /* AB - accept eth broadcast address */
int multicast; /* AM - check mcast hash array */
int promisc; /* PRO - accept all packets */
int monitor; /* MON - check pkts, but don't rx */
bool errors_ok; /* SEP - accept pkts with rx errors */
bool runts_ok; /* AR - accept < 64-byte runts */
bool broadcast; /* AB - accept eth broadcast address */
bool multicast; /* AM - check mcast hash array */
bool promisc; /* PRO - accept all packets */
bool monitor; /* MON - check pkts, but don't rx */
uint8_t reserved; /* D6,D7 - reserved */
} RCR;
/* Receive Status Register - 0ch read */
struct RSR_t {
int rx_ok; /* PRX - rx complete without error */
int bad_crc; /* CRC - Bad CRC detected */
int bad_falign; /* FAE - frame alignment error */
int fifo_or; /* FO - FIFO overrun */
int rx_missed; /* MPA - missed packet error */
int rx_mbit; /* PHY - unicast or mcast/bcast address match */
int rx_disabled; /* DIS - set when in monitor mode */
int deferred; /* DFR - collision active */
bool rx_ok; /* PRX - rx complete without error */
bool bad_crc; /* CRC - Bad CRC detected */
bool bad_falign; /* FAE - frame alignment error */
bool fifo_or; /* FO - FIFO overrun */
bool rx_missed; /* MPA - missed packet error */
bool rx_mbit; /* PHY - unicast or mcast/bcast address match */
bool rx_disabled; /* DIS - set when in monitor mode */
bool deferred; /* DFR - collision active */
} RSR;
uint16_t local_dma; /* 01,02h read ; current local DMA addr */

View File

@@ -20,7 +20,6 @@
#ifdef EMU_DEVICE_H
extern const device_t xga_device;
extern const device_t xga_isa_device;
extern const device_t inmos_isa_device;
#endif
#endif /*VIDEO_XGA_DEVICE_H*/

View File

@@ -391,46 +391,6 @@ machine_at_tuliptc7_init(const machine_t *model)
return ret;
}
int
machine_at_micronics386_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN",
"roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_init(model);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
int
machine_at_micronics386px_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-LO.BIN",
"roms/machines/micronics386/386-Micronics-09-00021-HI.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_init(model);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
static void
machine_at_scat_init(const machine_t *model, int is_v4, int is_ami)
{

View File

@@ -2919,3 +2919,45 @@ machine_at_cougar_init(const machine_t *model)
return ret;
}
int
machine_at_micronics386_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN",
"roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_init(model);
device_add(&port_92_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
int
machine_at_micronics386px_init(const machine_t *model)
{
int ret;
ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-LO.BIN",
"roms/machines/micronics386/386-Micronics-09-00021-HI.BIN",
0x000f0000, 65536, 0);
if (bios_only || !ret)
return ret;
machine_at_init(model);
device_add(&port_92_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}

View File

@@ -95,7 +95,7 @@ machine_at_d842_init(const machine_t *model)
fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios_versions"), 0);
ret = bios_load_linear(fn, 0x000e0000, 131072, 0);
device_context_restore();
machine_at_common_init(model);
device_add(&ide_pci_2ch_device);
@@ -195,10 +195,10 @@ machine_at_p54np4_init(const machine_t *model)
pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 06 = Slot 1 */
pci_register_slot(0x05, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 05 = Slot 2 */
pci_register_slot(0x04, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 04 = Slot 3 */
pci_register_slot(0x03, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 03 = Slot 4 */
pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 07 = Slot 1 */
pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 06 = Slot 2 */
pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */
pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 04 = Slot 4 */
pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0);
device_add(&i430nx_device);
device_add(&sio_zb_device);
@@ -237,7 +237,7 @@ machine_at_tek932_init(const machine_t *model)
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE);

View File

@@ -829,6 +829,8 @@ machine_pcjr_init(UNUSED(const machine_t *model))
pcjr = calloc(1, sizeof(pcjr_t));
is_pcjr = 1;
pic_init_pcjr();
pit_common_init(0, pit_irq0_timer_pcjr, NULL);

View File

@@ -123,6 +123,8 @@ machine_init_ex(int m)
pci_flags = 0x00000000;
}
is_pcjr = 0;
/* All good, boot the machine! */
if (machines[m].init)
ret = machines[m].init(&machines[m]);

View File

@@ -1565,7 +1565,7 @@ const machine_t machines[] = {
},
{
.name = "[8088] Tandy 1000 SX",
.internal_name = "tandy",
.internal_name = "tandy1000sx",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_PROPRIETARY,
.init = machine_tandy1000sx_init,

View File

@@ -1840,6 +1840,9 @@ mem_read_ram(uint32_t addr, UNUSED(void *priv))
mem_log("Read B %02X from %08X\n", ram[addr], addr);
#endif
if (is_pcjr)
pcjr_waitstates(NULL);
if (cpu_use_exec)
addreadlookup(mem_logical_addr, addr);
@@ -2100,6 +2103,9 @@ mem_write_ram(uint32_t addr, uint8_t val, UNUSED(void *priv))
if ((addr >= 0xa0000) && (addr <= 0xbffff))
mem_log("Write B %02X to %08X\n", val, addr);
#endif
if (is_pcjr)
pcjr_waitstates(NULL);
if (cpu_use_exec) {
addwritelookup(mem_logical_addr, addr);
mem_write_ramb_page(addr, val, &pages[addr >> 12]);

View File

@@ -45,6 +45,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <wchar.h>
#include <time.h>

View File

@@ -19,6 +19,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <wchar.h>
#include <time.h>
@@ -198,6 +199,11 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val)
if (dev->TCR.loop_cntl) {
dp8390_rx_common(dev, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap],
dev->tx_bytes);
if (dev->IMR.rx_inte && !dev->ISR.pkt_tx && dev->interrupt)
dev->interrupt(dev->priv, 1);
dev->ISR.pkt_tx = 1;
}
} else if (val & 0x04) {
if (dev->CR.stop || (!dev->CR.start && (dev->flags & DP8390_FLAG_CHECK_CR))) {
@@ -220,12 +226,6 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val)
if (!(dev->card->link_state & NET_LINK_DOWN))
network_tx(dev->card, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dev->tx_bytes);
/* some more debug */
#ifdef ENABLE_DP8390_LOG
if (dev->tx_timer_active)
dp8390_log("DP8390: CR write, tx timer still active\n");
#endif
dp8390_tx(dev, val);
}
@@ -247,12 +247,12 @@ dp8390_tx(dp8390_t *dev, UNUSED(uint32_t val))
{
dev->CR.tx_packet = 0;
dev->TSR.tx_ok = 1;
dev->ISR.pkt_tx = 1;
/* Generate an interrupt if not masked */
if (dev->IMR.tx_inte && dev->interrupt)
if (dev->IMR.tx_inte && !dev->ISR.pkt_tx && dev->interrupt)
dev->interrupt(dev->priv, 1);
dev->tx_timer_active = 0;
dev->ISR.pkt_tx = 1;
}
/*
@@ -960,7 +960,6 @@ dp8390_reset(dp8390_t *dev)
memset(&dev->TCR, 0x00, sizeof(dev->TCR));
memset(&dev->TSR, 0x00, sizeof(dev->TSR));
memset(&dev->RSR, 0x00, sizeof(dev->RSR));
dev->tx_timer_active = 0;
dev->local_dma = 0;
dev->page_start = 0;
dev->page_stop = 0;

View File

@@ -48,6 +48,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <wchar.h>
#include <time.h>
@@ -933,7 +934,7 @@ nic_init(const device_t *info)
if (dev->board != NE2K_ETHERNEXT_MC) {
dev->base_address = device_get_config_hex16("base");
dev->base_irq = device_get_config_int("irq");
if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) ||
if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) ||
(dev->board == NE2K_NE2000_COMPAT_8BIT) ) {
dev->bios_addr = device_get_config_hex20("bios_addr");
dev->has_bios = !!dev->bios_addr;
@@ -1061,7 +1062,7 @@ nic_init(const device_t *info)
break;
}
if (set_oui) {
/* See if we have a local MAC address configured. */
mac_oui = device_get_config_mac("mac_oui", -1);
@@ -1742,7 +1743,7 @@ const device_t ne2000_compat_device = {
const device_t ne2000_compat_8bit_device = {
.name = "NE2000 Compatible 8-bit",
.internal_name = "ne2k8",
.flags = DEVICE_ISA,
.flags = DEVICE_ISA,
.local = NE2K_NE2000_COMPAT_8BIT,
.init = nic_init,
.close = nic_close,

View File

@@ -44,6 +44,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <wchar.h>
#include <time.h>

View File

@@ -247,7 +247,7 @@ ctr_tick(ctr_t *ctr, void *priv)
ctr_decrease_count(ctr);
} else
ctr->count -= (ctr->newcount ? 1 : 2);
if (ctr->count < 0) {
if (ctr->count == 0) {
ctr_set_out(ctr, 0, pit);
ctr_load_count(ctr);
ctr->state = 3;
@@ -266,7 +266,7 @@ ctr_tick(ctr_t *ctr, void *priv)
ctr_decrease_count(ctr);
} else
ctr->count -= (ctr->newcount ? 3 : 2);
if (ctr->count < 0) {
if (ctr->count == 0) {
ctr_set_out(ctr, 1, pit);
ctr_load_count(ctr);
ctr->state = 2;
@@ -334,7 +334,7 @@ ctr_set_state_1(ctr_t *ctr)
{
uint8_t mode = (ctr->m & 0x03);
int do_reload = !!ctr->incomplete || (mode == 0) || (ctr->state == 0);
ctr->incomplete = 0;
if (do_reload)
@@ -358,8 +358,18 @@ ctr_load(ctr_t *ctr)
else
ctr_set_state_1(ctr);
if (ctr->load_func != NULL)
ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000);
if (ctr->load_func != NULL) {
uint32_t count = ctr->l ? ctr->l : 0x10000;
if (ctr->bcd) {
uint32_t bcd_count = (((count >> 16) & 0xf) * 10000) |
(((count >> 12) & 0xf) * 1000 ) |
(((count >> 8 ) & 0xf) * 100 ) |
(((count >> 4 ) & 0xf) * 10 ) |
(count & 0xf);
ctr->load_func(ctr->m, bcd_count);
} else
ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000);
}
pit_log("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch);
}
@@ -540,7 +550,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv)
ctr_t *ctr;
if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) {
pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv);
pit_log("[%04X:%08X] pit_write(%04X, %02X, %016" PRIX64 ")\n",
CS, cpu_state.pc, addr, val, (uint64_t) (uintptr_t) priv);
}
switch (addr & 3) {
@@ -788,7 +799,8 @@ pit_read(uint16_t addr, void *priv)
}
if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) {
pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret);
pit_log("[%04X:%08X] pit_read(%04X, %016" PRIX64 ") = %02X\n",
CS, cpu_state.pc, addr, (uint64_t) (uintptr_t) priv, ret);
}
return ret;

View File

@@ -1906,6 +1906,13 @@ strobe(uint8_t old, uint8_t val, void *priv)
/* Process incoming character. */
handle_char(dev, dev->data);
if (timer_is_enabled(&dev->timeout_timer)) {
timer_disable(&dev->timeout_timer);
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
}
/* ACK it, will be read on next READ STATUS. */
dev->ack = 1;
timer_set_delay_u64(&dev->pulse_timer, ISACONST);
@@ -1940,6 +1947,13 @@ write_ctrl(uint8_t val, void *priv)
/* Process incoming character. */
handle_char(dev, dev->data);
if (timer_is_enabled(&dev->timeout_timer)) {
timer_disable(&dev->timeout_timer);
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
}
/* ACK it, will be read on next READ STATUS. */
dev->ack = 1;
timer_set_delay_u64(&dev->pulse_timer, ISACONST);

View File

@@ -34,6 +34,7 @@
#include <86box/plat_dynld.h>
#include <86box/ui.h>
#include <86box/prt_devs.h>
#include "cpu.h"
#ifdef _WIN32
# define GSDLLAPI __stdcall
@@ -341,6 +342,14 @@ ps_strobe(uint8_t old, uint8_t val, void *priv)
if (!(val & 0x01) && (old & 0x01)) {
process_data(dev);
if (timer_is_enabled(&dev->timeout_timer)) {
timer_disable(&dev->timeout_timer);
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
}
dev->ack = true;
timer_set_delay_u64(&dev->pulse_timer, ISACONST);
@@ -371,6 +380,14 @@ ps_write_ctrl(uint8_t val, void *priv)
if (!(val & 0x01) && (dev->ctrl & 0x01)) {
process_data(dev);
if (timer_is_enabled(&dev->timeout_timer)) {
timer_disable(&dev->timeout_timer);
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
}
dev->ack = true;
timer_set_delay_u64(&dev->pulse_timer, ISACONST);

View File

@@ -63,6 +63,7 @@
#include <86box/lpt.h>
#include <86box/printer.h>
#include <86box/prt_devs.h>
#include "cpu.h"
#define FULL_PAGE 1 /* set if no top/bot margins */
@@ -391,6 +392,14 @@ strobe(uint8_t old, uint8_t val, void *priv)
/* Process incoming character. */
handle_char(dev);
if (timer_is_enabled(&dev->timeout_timer)) {
timer_disable(&dev->timeout_timer);
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
}
/* ACK it, will be read on next READ STATUS. */
dev->ack = 1;
@@ -429,6 +438,14 @@ write_ctrl(uint8_t val, void *priv)
/* ACK it, will be read on next READ STATUS. */
dev->ack = 1;
if (timer_is_enabled(&dev->timeout_timer)) {
timer_disable(&dev->timeout_timer);
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
update_tsc();
#endif
}
timer_set_delay_u64(&dev->pulse_timer, ISACONST);
timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC);
}

View File

@@ -102,6 +102,8 @@ bool cpu_thread_running = false;
void qt_set_sequence_auto_mnemonic(bool b);
#ifdef Q_OS_WINDOWS
bool acp_utf8 = false;
static void
keyboard_getkeymap()
{
@@ -435,6 +437,9 @@ main_thread_fn()
int frames;
QThread::currentThread()->setPriority(QThread::HighestPriority);
#ifdef _WIN32
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
#endif
plat_set_thread_name(nullptr, "main_thread_fn");
framecountx = 0;
// title_update = 1;
@@ -446,14 +451,14 @@ main_thread_fn()
const uint64_t new_time = elapsed_timer.elapsed();
#ifdef USE_GDBSTUB
if (gdbstub_next_asap && (drawits <= 0))
drawits = 10;
drawits = force_10ms ? 10 : 1;
else
#endif
drawits += static_cast<int>(new_time - old_time);
old_time = new_time;
if (drawits > 0 && !dopause) {
/* Yes, so do one frame now. */
drawits -= 10;
drawits -= force_10ms ? 10 : 1;
if (drawits > 50)
drawits = 0;
@@ -472,8 +477,8 @@ main_thread_fn()
break;
}
#endif
/* Every 200 frames we save the machine status. */
if (++frames >= 200 && nvr_dosave) {
/* Every 2 emulated seconds we save the machine status. */
if (++frames >= (force_10ms ? 200 : 2000) && nvr_dosave) {
qt_nvr_save();
nvr_dosave = 0;
frames = 0;
@@ -515,6 +520,13 @@ extern bool windows_is_light_theme();
int
main(int argc, char *argv[])
{
#ifdef Q_OS_WINDOWS
/* Check if Windows supports UTF-8 */
if (GetACP() == CP_UTF8)
acp_utf8 = 1;
else
acp_utf8 = 0;
#endif
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
@@ -530,6 +542,9 @@ main(int argc, char *argv[])
#ifdef Q_OS_WINDOWS
Q_INIT_RESOURCE(darkstyle);
if (QFile(QApplication::applicationDirPath() + "/opengl32.dll").exists()) {
qputenv("QT_OPENGL_DLL", QFileInfo(QApplication::applicationDirPath() + "/opengl32.dll").absoluteFilePath().toUtf8());
}
QApplication::setAttribute(Qt::AA_NativeWindows);
if (!windows_is_light_theme()) {

View File

@@ -177,14 +177,28 @@ do_stop(void)
#endif
}
extern bool acp_utf8;
void
plat_get_exe_name(char *s, int size)
{
#ifdef Q_OS_WINDOWS
wchar_t *temp;
if (acp_utf8)
GetModuleFileNameA(NULL, s, size);
else {
temp = (wchar_t*)calloc(size, sizeof(wchar_t));
GetModuleFileNameW(NULL, temp, size);
c16stombs(s, (uint16_t*)temp, size);
free(temp);
}
#else
QByteArray exepath_temp = QCoreApplication::applicationDirPath().toLocal8Bit();
memcpy(s, exepath_temp.data(), std::min((qsizetype) exepath_temp.size(), (qsizetype) size));
path_slash(s);
#endif
}
uint32_t

View File

@@ -152,11 +152,8 @@ SettingsDisplay::on_pushButtonConfigure8514_clicked()
void
SettingsDisplay::on_pushButtonConfigureXga_clicked()
{
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) {
if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0)
DeviceConfig::ConfigureDevice(&xga_device);
} else {
DeviceConfig::ConfigureDevice(&xga_isa_device);
}
}
void
@@ -189,7 +186,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index)
bool videoCardHasXga = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_XGA) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_XGA));
bool machineSupports8514 = ((machineHasIsa16 || machineHasMca) && !videoCardHas8514);
bool machineSupportsXga = (((machineHasIsa16 && device_available(&xga_isa_device)) || (machineHasMca && device_available(&xga_device))) && !videoCardHasXga);
bool machineSupportsXga = ((machineHasMca && device_available(&xga_device)) && !videoCardHasXga);
bool machineSupportsDa2 = machineHasMca && device_available(&ps55da2_device);
ui->checkBox8514->setEnabled(machineSupports8514);

View File

@@ -117,6 +117,9 @@ SettingsMachine::SettingsMachine(QWidget *parent)
ui->comboBoxMachineType->setCurrentIndex(-1);
ui->comboBoxMachineType->setCurrentIndex(selectedMachineType);
ui->radioButtonLargerFrames->setChecked(force_10ms);
ui->radioButtonSmallerFrames->setChecked(!force_10ms);
#ifndef USE_DYNAREC
ui->checkBoxDynamicRecompiler->setEnabled(false);
ui->checkBoxDynamicRecompiler->setVisible(false);
@@ -137,6 +140,7 @@ SettingsMachine::save()
fpu_type = ui->comboBoxFPU->currentData().toInt();
cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0;
fpu_softfloat = ui->checkBoxFPUSoftfloat->isChecked() ? 1 : 0;
force_10ms = ui->radioButtonLargerFrames->isChecked() ? 1 : 0;
int64_t temp_mem_size;
if (machine_get_ram_granularity(machine) < 1024)
@@ -359,3 +363,15 @@ void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) {
ui->softFloatWarningText->setVisible(false);
}
}
void SettingsMachine::on_radioButtonSmallerFrames_clicked()
{
ui->radioButtonLargerFrames->setChecked(false);
}
void SettingsMachine::on_radioButtonLargerFrames_clicked()
{
ui->radioButtonSmallerFrames->setChecked(false);
}

View File

@@ -28,6 +28,10 @@ private slots:
void on_comboBoxMachineType_currentIndexChanged(int index);
void on_checkBoxFPUSoftfloat_stateChanged(int state);
void on_radioButtonSmallerFrames_clicked();
void on_radioButtonLargerFrames_clicked();
private:
Ui::SettingsMachine *ui;
};

View File

@@ -41,7 +41,6 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QComboBox" name="comboBoxMachineType">
<property name="maxVisibleItems">
@@ -49,7 +48,6 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@@ -57,7 +55,6 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
@@ -65,7 +62,6 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBoxFPU">
<property name="maxVisibleItems">
@@ -73,7 +69,6 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBoxRAM">
<property name="sizePolicy">
@@ -84,7 +79,6 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
@@ -92,7 +86,6 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
@@ -100,7 +93,6 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
@@ -129,18 +121,16 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Frequency:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxSpeed">
<property name="sizePolicy">
@@ -157,7 +147,6 @@
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
@@ -165,7 +154,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
@@ -173,7 +161,6 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
@@ -196,7 +183,6 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonConfigure">
<property name="sizePolicy">
@@ -213,7 +199,6 @@
</layout>
</widget>
</item>
<item row="4" column="1">
<widget class="QWidget" name="widget_4" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
@@ -268,7 +253,6 @@
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="dynamicRecompilerLayout">
<item>
@@ -286,7 +270,6 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="softFloatLayout">
<item>
@@ -302,7 +285,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="softFloatWarningIcon">
<property name="text">
@@ -310,7 +292,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="softFloatWarningText">
<property name="text">
@@ -321,7 +302,7 @@
<item>
<spacer name="softFloatHorizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -333,39 +314,102 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Time synchronization</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="radioButtonDisabled">
<property name="text">
<string>Disabled</string>
<widget class="QFrame" name="horizontalFrame">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Time synchronization</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QRadioButton" name="radioButtonDisabled">
<property name="text">
<string>Disabled</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="radioButtonUTC">
<property name="text">
<string>Enabled (UTC)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="radioButtonLocalTime">
<property name="text">
<string>Enabled (local time)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonLocalTime">
<property name="text">
<string>Enabled (local time)</string>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>CPU frame size</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="radioButtonLargerFrames">
<property name="text">
<string>Larger frames (less smooth)</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonSmallerFrames">
<property name="text">
<string>Smaller frames (smoother)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonUTC">
<property name="text">
<string>Enabled (UTC)</string>
<item row="1" column="0" colspan="3">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
</widget>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
@@ -373,7 +417,7 @@
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>

View File

@@ -142,7 +142,9 @@ SettingsNetwork::save()
for (int i = 0; i < NET_CARD_MAX; ++i) {
auto *cbox = findChild<QComboBox *>(QString("comboBoxNIC%1").arg(i + 1));
auto *socket_line = findChild<QLineEdit *>(QString("socketVDENIC%1").arg(i + 1));
#if defined(__unix__) || defined(__APPLE__)
auto *bridge_line = findChild<QLineEdit *>(QString("bridgeTAPNIC%1").arg(i + 1));
#endif
net_cards_conf[i].device_num = cbox->currentData().toInt();
cbox = findChild<QComboBox *>(QString("comboBoxNet%1").arg(i + 1));
net_cards_conf[i].net_type = cbox->currentData().toInt();

View File

@@ -62,7 +62,6 @@ SettingsStorageControllers::save()
ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0;
ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0;
cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0;
lba_enhancer_enabled = ui->checkBoxLbaEnhancer->isChecked() ? 1 : 0;
}
void
@@ -232,9 +231,6 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId)
ui->checkBoxCassette->setChecked(false);
ui->checkBoxCassette->setEnabled(false);
}
ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device));
ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked());
}
void
@@ -365,15 +361,3 @@ SettingsStorageControllers::on_pushButtonSCSI4_clicked()
{
DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4);
}
void
SettingsStorageControllers::on_checkBoxLbaEnhancer_stateChanged(int arg1)
{
ui->pushButtonConfigureLbaEnhancer->setEnabled(arg1 != 0);
}
void
SettingsStorageControllers::on_pushButtonConfigureLbaEnhancer_clicked()
{
DeviceConfig::ConfigureDevice(&lba_enhancer_device);
}

View File

@@ -44,9 +44,6 @@ private slots:
void on_comboBoxSCSI4_currentIndexChanged(int index);
void on_pushButtonSCSI4_clicked();
void on_checkBoxLbaEnhancer_stateChanged(int arg1);
void on_pushButtonConfigureLbaEnhancer_clicked();
private:
Ui::SettingsStorageControllers *ui;
int machineId = 0;

View File

@@ -257,43 +257,6 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="checkBoxLbaEnhancer">
<property name="text">
<string>Vision Systems LBA Enhancer</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonConfigureLbaEnhancer">
<property name="text">
<string>Configure</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View File

@@ -69,7 +69,11 @@ public slots:
void searchSystems(const QString &text) const;
void newMachineWizard();
void addNewSystem(const QString &name, const QString &dir, const QString &configFile = {});
#if __GNUC__ >= 11
[[nodiscard]] QStringList getSearchCompletionList() const;
#else
QStringList getSearchCompletionList() const;
#endif
void modelDataChange();
void onPreferencesUpdated();

View File

@@ -45,8 +45,10 @@ static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS];
void
joystick_init(void)
{
#ifdef _WIN32
/* This is needed for SDL's Windows raw input backend to work properly without SDL video. */
SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1");
#endif
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) {
return;

View File

@@ -81,28 +81,61 @@ ali5123_fdc_handler(ali5123_t *dev)
static void
ali5123_lpt_handler(ali5123_t *dev)
{
uint16_t ld_port = 0;
uint16_t ld_port = 0x0000;
uint16_t mask = 0xfffc;
uint8_t global_enable = !(dev->regs[0x22] & (1 << 3));
uint8_t local_enable = !!dev->ld_regs[3][0x30];
uint8_t lpt_irq = dev->ld_regs[3][0x70];
uint8_t lpt_dma = dev->ld_regs[3][0x74];
uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07;
if (lpt_irq > 15)
lpt_irq = 0xff;
if (lpt_dma == 4)
if (lpt_dma >= 4)
lpt_dma = 0xff;
lpt1_remove();
lpt_set_epp(0, !!(dev->ld_regs[3][0xf0] & 0x01));
lpt_set_ecp(0, !!(dev->ld_regs[3][0xf0] & 0x02));
lpt_set_ext(0, !(dev->ld_regs[3][0xf0] & 0x04) || !!(dev->ld_regs[3][0xf1] & 0x80));
lpt_set_fifo_threshold(0, (dev->ld_regs[3][0xf0] & 0x78) >> 3);
if ((lpt_mode == 0x04) && (dev->ld_regs[3][0xf1] & 0x80))
lpt_mode = 0x00;
switch (lpt_mode) {
default:
case 0x04:
lpt_set_epp(0, 0);
lpt_set_ecp(0, 0);
lpt_set_ext(0, 0);
break;
case 0x00:
lpt_set_epp(0, 0);
lpt_set_ecp(0, 0);
lpt_set_ext(0, 1);
break;
case 0x01: case 0x05:
mask = 0xfff8;
lpt_set_epp(0, 1);
lpt_set_ecp(0, 0);
lpt_set_ext(0, 0);
break;
case 0x02:
lpt_set_epp(0, 0);
lpt_set_ecp(0, 1);
lpt_set_ext(0, 0);
break;
case 0x03: case 0x07:
mask = 0xfff8;
lpt_set_epp(0, 1);
lpt_set_ecp(0, 1);
lpt_set_ext(0, 0);
break;
}
if (global_enable && local_enable) {
ld_port = make_port(dev, 3) & 0xFFFC;
if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC))
ld_port = (make_port(dev, 3) & 0xfffc) & mask;
if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask)))
lpt1_setup(ld_port);
}
lpt1_irq(lpt_irq);
lpt_port_dma(0, lpt_dma);
}
static void

View File

@@ -123,6 +123,8 @@ lpt1_handler(pc87306_t *dev)
uint8_t lpt_irq = LPT2_IRQ;
uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1);
lpt1_remove();
if (lpt_dma == 0x00)
lpt_dma = 0xff;
@@ -157,17 +159,17 @@ lpt1_handler(pc87306_t *dev)
if (dev->regs[0x1b] & 0x10)
lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5;
lpt_set_ext(0, !!(dev->regs[0x02] & 0x80));
lpt_set_epp(0, !!(dev->regs[0x04] & 0x01));
lpt_set_ecp(0, !!(dev->regs[0x04] & 0x04));
if (lpt_port)
lpt1_setup(lpt_port);
lpt1_irq(lpt_irq);
lpt_port_dma(0, lpt_dma);
lpt_set_ext(0, !!(dev->regs[0x02] & 0x80));
lpt_set_epp(0, !!(dev->regs[0x04] & 0x01));
lpt_set_ecp(0, !!(dev->regs[0x04] & 0x04));
}
static void
@@ -386,7 +388,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv)
if (valxor & 0x70) {
lpt1_remove();
if (!(val & 0x40))
dev->regs[0x19] = 0xEF;
dev->regs[0x19] = 0xef;
if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1))
lpt1_handler(dev);
}

View File

@@ -246,7 +246,7 @@ gus_midi_update_int_status(gus_t *gus)
}
void
writegus(uint16_t addr, uint8_t val, void *priv)
gus_write(uint16_t addr, uint8_t val, void *priv)
{
gus_t *gus = (gus_t *) priv;
int c;
@@ -703,7 +703,7 @@ writegus(uint16_t addr, uint8_t val, void *priv)
}
uint8_t
readgus(uint16_t addr, void *priv)
gus_read(uint16_t addr, void *priv)
{
gus_t *gus = (gus_t *) priv;
uint8_t val = 0xff;
@@ -1357,10 +1357,10 @@ gus_init(UNUSED(const device_t *info))
gus->base = device_get_config_hex16("base");
io_sethandler(gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(0x0100 + gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(0x0506 + gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
io_sethandler(0x0100 + gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
io_sethandler(0x0506 + gus->base, 0x0001, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
io_sethandler(0x0388, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
if (gus->type == GUS_MAX) {
ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231);

View File

@@ -1152,11 +1152,14 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv)
else if ((val & 0x06) == 0x02)
mpu401_change_addr(sb->mpu, 0);
}
sb->gameport_addr = 0;
gameport_remap(sb->gameport, 0);
if (!(val & 0x01)) {
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, 0x200);
if (sb->gameport != NULL) {
gameport_remap(sb->gameport, 0);
if (!(val & 0x01)) {
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, 0x200);
}
}
}
break;
@@ -1619,7 +1622,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv)
ess_fm_midi_write, NULL, NULL,
ess);
gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200);
if (ess->gameport != NULL)
gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200);
if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) {
/* Not on ES1688. */
@@ -2864,11 +2868,17 @@ sb_init(UNUSED(const device_t *info))
sb_dsp_init(&sb->dsp, model, SB_SUBTYPE_DEFAULT, sb);
sb_dsp_setaddr(&sb->dsp, addr);
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
sb_dsp_setdma8(&sb->dsp, 1); // SB 1, SB1.5 and 2 don't support DMA3
if (mixer_addr > 0x0000)
sb_ct1335_mixer_reset(sb);
if (device_get_config_int("gameport")) {
sb->gameport = gameport_add(&gameport_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
}
/* DSP I/O handler is activated in sb_dsp_setaddr */
if (sb->opl_enabled) {
// TODO: See if this applies to the SB1.5 as well
@@ -2948,6 +2958,12 @@ sb_mcv_init(UNUSED(const device_t *info))
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
if (device_get_config_int("gameport")) {
sb->gameport = gameport_add(&gameport_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
}
return sb;
}
@@ -3030,6 +3046,12 @@ sb_pro_v1_init(UNUSED(const device_t *info))
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
if (device_get_config_int("gameport")) {
sb->gameport = gameport_add(&gameport_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
}
return sb;
}
@@ -3084,6 +3106,12 @@ sb_pro_v2_init(UNUSED(const device_t *info))
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
if (device_get_config_int("gameport")) {
sb->gameport = gameport_add(&gameport_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
}
return sb;
}
@@ -3117,6 +3145,12 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
if (device_get_config_int("gameport")) {
sb->gameport = gameport_add(&gameport_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
}
return sb;
}
@@ -3201,9 +3235,17 @@ sb_16_init(UNUSED(const device_t *info))
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
sb->gameport = gameport_add(&gameport_pnp_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
if (info->local == FM_YMF289B) {
sb->gameport = gameport_add(&gameport_pnp_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
} else {
if (device_get_config_int("gameport")) {
sb->gameport = gameport_add(&gameport_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
}
}
return sb;
}
@@ -3481,7 +3523,6 @@ sb_16_compat_init(const device_t *info)
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local);
sb_dsp_set_mpu(&sb->dsp, sb->mpu);
@@ -3549,8 +3590,6 @@ sb_awe32_init(UNUSED(const device_t *info))
uint16_t emu_addr = device_get_config_hex16("emu_base");
int onboard_ram = device_get_config_int("onboard_ram");
memset(sb, 0x00, sizeof(sb_t));
sb->opl_enabled = device_get_config_int("opl");
if (sb->opl_enabled)
fm_driver_get(FM_YMF262, &sb->opl);
@@ -3594,7 +3633,6 @@ sb_awe32_init(UNUSED(const device_t *info))
if (mpu_addr) {
sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t));
memset(sb->mpu, 0, sizeof(mpu_t));
mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART,
device_get_config_int("receive_input401"));
} else
@@ -3606,9 +3644,11 @@ sb_awe32_init(UNUSED(const device_t *info))
if (device_get_config_int("receive_input"))
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
sb->gameport = gameport_add(&gameport_pnp_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
if (device_get_config_int("gameport")) {
sb->gameport = gameport_add(&gameport_device);
sb->gameport_addr = 0x200;
gameport_remap(sb->gameport, sb->gameport_addr);
}
return sb;
}
@@ -3870,9 +3910,11 @@ ess_x688_init(UNUSED(const device_t *info))
sb_dsp_set_mpu(&ess->dsp, ess->mpu);
}
ess->gameport = gameport_add(&gameport_pnp_device);
ess->gameport_addr = 0x200;
gameport_remap(ess->gameport, ess->gameport_addr);
if (device_get_config_int("gameport")) {
ess->gameport = gameport_add(&gameport_device);
ess->gameport_addr = 0x200;
gameport_remap(ess->gameport, ess->gameport_addr);
}
if (ide_base > 0x0000) {
device_add(&ide_qua_pnp_device);
@@ -4118,18 +4160,14 @@ static const device_config_t sb_config[] = {
.bios = { { 0 } }
},
{
.name = "dma",
.description = "DMA",
.type = CONFIG_SELECTION,
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 1,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "DMA 1", .value = 1 },
{ .description = "DMA 3", .value = 3 },
{ .description = "" }
},
.selection = { { 0 } },
.bios = { { 0 } }
},
{
@@ -4153,7 +4191,7 @@ static const device_config_t sb_config[] = {
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
},
{ .name = "", .description = "", .type = CONFIG_END }
};
@@ -4178,8 +4216,8 @@ static const device_config_t sb15_config[] = {
.bios = { { 0 } }
},
{
.name = "irq",
.description = "IRQ",
.name = "irq",
.description = "IRQ",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 7,
@@ -4195,18 +4233,14 @@ static const device_config_t sb15_config[] = {
.bios = { { 0 } }
},
{
.name = "dma",
.description = "DMA",
.type = CONFIG_SELECTION,
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 1,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "DMA 1", .value = 1 },
{ .description = "DMA 3", .value = 3 },
{ .description = "" }
},
.selection = { { 0 } },
.bios = { { 0 } }
},
{
@@ -4247,8 +4281,8 @@ static const device_config_t sb15_config[] = {
static const device_config_t sb2_config[] = {
{
.name = "base",
.description = "Address",
.name = "base",
.description = "Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x220,
@@ -4295,18 +4329,14 @@ static const device_config_t sb2_config[] = {
.bios = { { 0 } }
},
{
.name = "dma",
.description = "DMA",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 1,
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "DMA 1", .value = 1 },
{ .description = "DMA 3", .value = 3 },
{ .description = "" }
},
.selection = { { 0 } },
.bios = { { 0 } }
},
{
@@ -4367,7 +4397,7 @@ static const device_config_t sb_mcv_config[] = {
.name = "dma",
.description = "DMA",
.type = CONFIG_SELECTION,
.default_string = "",
.default_string = NULL,
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
@@ -4378,6 +4408,17 @@ static const device_config_t sb_mcv_config[] = {
},
.bios = { { 0 } }
},
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "opl",
.description = "Enable OPL",
@@ -4452,6 +4493,17 @@ static const device_config_t sb_pro_config[] = {
},
.bios = { { 0 } }
},
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "opl",
.description = "Enable OPL",
@@ -4478,6 +4530,17 @@ static const device_config_t sb_pro_config[] = {
};
static const device_config_t sb_pro_mcv_config[] = {
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "receive_input",
.description = "Receive MIDI input",
@@ -4575,6 +4638,17 @@ static const device_config_t sb_16_config[] = {
},
.bios = { { 0 } }
},
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "opl",
.description = "Enable OPL",
@@ -4857,6 +4931,17 @@ static const device_config_t sb_awe32_config[] = {
},
.bios = { { 0 } }
},
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "opl",
.description = "Enable OPL",
@@ -5186,6 +5271,17 @@ static const device_config_t ess_688_config[] = {
},
.bios = { { 0 } }
},
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "ide_ctrl",
.description = "IDE Controller",
@@ -5269,6 +5365,17 @@ static const device_config_t ess_1688_config[] = {
},
.bios = { { 0 } }
},
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "ide_ctrl",
.description = "IDE Controller",
@@ -5343,7 +5450,7 @@ static const device_config_t ess_1688_pnp_config[] = {
.name = "control_pc_speaker",
.description = "Control PC speaker",
.type = CONFIG_BINARY,
.default_string = "",
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
@@ -5354,7 +5461,7 @@ static const device_config_t ess_1688_pnp_config[] = {
.name = "receive_input",
.description = "Receive MIDI input",
.type = CONFIG_BINARY,
.default_string = "",
.default_string = NULL,
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
@@ -5365,7 +5472,7 @@ static const device_config_t ess_1688_pnp_config[] = {
.name = "receive_input401",
.description = "Receive MIDI input (MPU-401)",
.type = CONFIG_BINARY,
.default_string = "",
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },

View File

@@ -56,7 +56,7 @@ speaker_update(void)
int32_t val;
double amplitude;
amplitude = ((speaker_count / 64.0) * 10240.0) - 5120.0;
amplitude = ((speaker_count / 256.0) * 10240.0) - 5120.0;
if (amplitude > 5120.0)
amplitude = 5120.0;

View File

@@ -157,14 +157,13 @@ static const device_config_t ssi2001_config[] = {
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 1,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
{
.name = "sid_config",
.description = "SID Model",
.type = CONFIG_HEX16,
@@ -201,7 +200,7 @@ static const device_config_t entertainer_config[] = {
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 1,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },

View File

@@ -270,7 +270,7 @@ mach_log(const char *fmt, ...)
static int
mach_pixel_write(mach_t *mach)
{
if (mach->accel.dp_config & 1)
if (mach->accel.dp_config & 0x01)
return 1;
return 0;
@@ -279,7 +279,7 @@ mach_pixel_write(mach_t *mach)
static int
mach_pixel_read(mach_t *mach)
{
if (mach->accel.dp_config & 1)
if (mach->accel.dp_config & 0x01)
return 0;
return 1;
@@ -4303,6 +4303,10 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in
dev->force_busy = 0;
else if ((mono_src == 2) || (frgd_sel == 2) || (bkgd_sel == 2))
dev->force_busy = 0;
else if (!dev->accel.cmd_back)
dev->force_busy = 0;
mach_log("2Force Busy=%d, frgdsel=%d, bkgdsel=%d, monosrc=%d, read=%d, dpconfig=%04x, back=%d.\n", dev->force_busy, frgd_sel, bkgd_sel, mono_src, mach_pixel_read(mach), mach->accel.dp_config, dev->accel.cmd_back);
break;
case 5:
if (dev->accel.sx >= mach->accel.width)

View File

@@ -155,7 +155,13 @@ quadcolor_out(uint16_t addr, uint8_t val, void *priv)
case 0x3de:
/* NOTE: the polarity of this register is the opposite of what the manual says */
if (quadcolor->has_quadcolor_2)
quadcolor->quadcolor_2_oe = !(val & 0x10);
/*
NOTE: PC Paintbrush writes FF and then gets stuck if it doesn't get enabled,
and then it expects to disable it with 0x00. The only way to square this
with the inverted polarity note above is if that was a value other than
0x00 with bit 4 clear.
*/
quadcolor->quadcolor_2_oe = ((!(val & 0x10)) || (val == 0xff)) && (val != 0x00);
return;
default:
@@ -290,22 +296,15 @@ quadcolor_render(quadcolor_t *quadcolor, int line)
int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS);
if (((quadcolor->cgamode & highres_graphics_flag) == highres_graphics_flag)) {
for (column = 0; column < 8; ++column) {
buffer32->line[line][column] = 0;
if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES)
buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 8] = (quadcolor->quadcolor_ctrl & 15); /* TODO: Is Quadcolor bg color actually relevant, here? */
else
buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 8] = (quadcolor->quadcolor_ctrl & 15); /* TODO: Is Quadcolor bg color actually relevant, here? */
}
} else {
for (column = 0; column < 8; ++column) {
buffer32->line[line][column] = (quadcolor->cgacol & 15) + 16;
if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES)
buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 8] = (quadcolor->cgacol & 15) + 16;
else
buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 8] = (quadcolor->cgacol & 15) + 16;
}
cols[0] = ((quadcolor->cgamode & highres_graphics_flag) == highres_graphics_flag) ? (quadcolor->quadcolor_ctrl & 15) :
(quadcolor->cgacol & 15);
for (column = 0; column < 8; ++column) {
buffer32->line[line][column] = cols[0];
if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES)
buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 8] = cols[0];
else
buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 8] = cols[0];
}
if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) { /* 80-column text */
for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) {
@@ -322,20 +321,24 @@ quadcolor_render(quadcolor_t *quadcolor, int line)
cols[1] = cols[0];
} else
cols[0] = (attr >> 4) + 16;
uint8_t charline = quadcolor->scanline & 7;
if (drawcursor) {
for (column = 0; column < 8; column++) {
buffer32->line[line][(x << 3) + column + 8]
= (cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15) | get_next_qc2_pixel(quadcolor);
dat = (cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0] ^ 15);
buffer32->line[line][(x << 3) + column + 8] =
dat | get_next_qc2_pixel(quadcolor);
}
} else {
for (column = 0; column < 8; column++) {
buffer32->line[line][(x << 3) + column + 8]
= cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] | get_next_qc2_pixel(quadcolor);
dat = cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0];
buffer32->line[line][(x << 3) + column + 8] =
dat | get_next_qc2_pixel(quadcolor);
}
}
quadcolor->memaddr++;
}
} else if (!(quadcolor->cgamode & CGA_MODE_FLAG_GRAPHICS)) { /* not graphics (nor 80-column text) => 40-column text */
} else if (!(quadcolor->cgamode & CGA_MODE_FLAG_GRAPHICS)) {
/* Not graphics (nor 80-column text) => 40-column text. */
for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) {
if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) {
chr = quadcolor->vram[(quadcolor->page_offset ^ (quadcolor->memaddr << 1)) & DEVICE_VRAM_MASK];
@@ -351,23 +354,27 @@ quadcolor_render(quadcolor_t *quadcolor, int line)
} else
cols[0] = (attr >> 4) + 16;
quadcolor->memaddr++;
uint8_t charline = quadcolor->scanline & 7;
if (drawcursor) {
for (column = 0; column < 8; column++) {
dat = (cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15);
buffer32->line[line][(x << 4) + (column << 1) + 8] = dat | get_next_qc2_pixel(quadcolor);
buffer32->line[line][(x << 4) + (column << 1) + 9] = dat | get_next_qc2_pixel(quadcolor);
dat = (cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0] ^ 15);
buffer32->line[line][(x << 4) + (column << 1) + 8] =
dat | get_next_qc2_pixel(quadcolor);
buffer32->line[line][(x << 4) + (column << 1) + 9] =
dat | get_next_qc2_pixel(quadcolor);
}
} else {
for (column = 0; column < 8; column++) {
dat = cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0];
buffer32->line[line][(x << 4) + (column << 1) + 8] = dat | get_next_qc2_pixel(quadcolor);
buffer32->line[line][(x << 4) + (column << 1) + 9] = dat | get_next_qc2_pixel(quadcolor);
dat = cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0];
buffer32->line[line][(x << 4) + (column << 1) + 8] =
dat | get_next_qc2_pixel(quadcolor);
buffer32->line[line][(x << 4) + (column << 1) + 9] =
dat | get_next_qc2_pixel(quadcolor);
}
}
}
} else if (!(quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { /* not hi-res (but graphics) => 4-color mode */
} else if (!(quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) {
/* Not hi-res (but graphics) => 4-color mode. */
cols[0] = (quadcolor->cgacol & 15) | 16;
col = (quadcolor->cgacol & 16) ? 24 : 16;
if (quadcolor->cgamode & CGA_MODE_FLAG_BW) {
@@ -385,8 +392,10 @@ quadcolor_render(quadcolor_t *quadcolor, int line)
}
for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) {
if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)
dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000))] << 8) |
quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000) + 1)];
dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) +
((quadcolor->scanline & 1) * 0x2000))] << 8) |
quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) +
((quadcolor->scanline & 1) * 0x2000) + 1)];
else
dat = 0;
quadcolor->memaddr++;
@@ -396,15 +405,20 @@ quadcolor_render(quadcolor_t *quadcolor, int line)
dat <<= 2;
}
}
} else { /* 2-color hi-res graphics mode */
cols[0] = quadcolor->quadcolor_ctrl & 15; /* background color (Quadcolor-specific) */;
} else {
/* 2-color hi-res graphics mode. */
/* Background color (Quadcolor-specific). */
cols[0] = quadcolor->quadcolor_ctrl & 15;
cols[1] = (quadcolor->cgacol & 15) + 16;
for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) {
if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) /* video enabled */
dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000))] << 8) |
quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000) + 1)];
dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) +
((quadcolor->scanline & 1) * 0x2000))] << 8) |
quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) +
((quadcolor->scanline & 1) * 0x2000) + 1)];
else
dat = quadcolor->quadcolor_ctrl & 15; /* TODO: Is Quadcolor bg color actually relevant, here? Probably. See QC2 manual p.46 1. */;
/* TODO: Is Quadcolor bg color actually relevant, here? Probably. See QC2 manual p.46 1. */
dat = quadcolor->quadcolor_ctrl & 15;
quadcolor->memaddr++;
for (column = 0; column < 16; column++) {
buffer32->line[line][(x << 4) + column + 8] = cols[dat >> 15] | get_next_qc2_pixel(quadcolor);

View File

@@ -1895,7 +1895,7 @@ const device_t cpqega_device = {
};
const device_t sega_device = {
.name = "SuperEGA",
.name = "Chips & Technologies SuperEGA",
.internal_name = "superega",
.flags = DEVICE_ISA,
.local = EGA_SUPEREGA,

View File

@@ -35,6 +35,8 @@
#include <86box/video.h>
#include <86box/vid_cga.h>
#include <86box/vid_cga_comp.h>
#include <86box/plat_unused.h>
#include "cpu.h"
#include <86box/m_pcjr.h>
@@ -194,6 +196,16 @@ vid_in(uint16_t addr, void *priv)
return ret;
}
void
pcjr_waitstates(UNUSED(void *priv))
{
int ws_array[16] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5 };
int ws;
ws = ws_array[cycles & 0xf];
cycles -= ws;
}
static void
vid_write(uint32_t addr, uint8_t val, void *priv)
{
@@ -202,6 +214,8 @@ vid_write(uint32_t addr, uint8_t val, void *priv)
if (pcjr->memctrl == -1)
return;
pcjr_waitstates(NULL);
pcjr->b8000[addr & 0x3fff] = val;
}
@@ -213,6 +227,8 @@ vid_read(uint32_t addr, void *priv)
if (pcjr->memctrl == -1)
return 0xff;
pcjr_waitstates(NULL);
return (pcjr->b8000[addr & 0x3fff]);
}

View File

@@ -1101,8 +1101,8 @@ svga_recalctimings(svga_t *svga)
if (xga_active && (svga->xga != NULL)) {
if (xga->on) {
disptime_xga = xga->h_total ? xga->h_total : TIMER_USEC;
_dispontime_xga = xga->h_disp;
disptime_xga = xga->h_total;
_dispontime_xga = xga->h_disp_time;
}
}

View File

@@ -58,7 +58,7 @@ svga_render_null(svga_t *svga)
void
svga_render_blank(svga_t *svga)
{
if ((svga->displine + svga->y_add) < 0)
if ((svga->displine + svga->y_add) < 0 || (svga->displine + svga->y_add) >= 2048)
return;
if (svga->firstline_draw == 2000)

View File

@@ -53,39 +53,42 @@ video_cards[] = {
{ .device = &device_none, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &device_internal, .flags = VIDEO_FLAG_TYPE_NONE },
/* ISA */
{ .device = &ati18800_wonder_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ati18800_vga88_device, .flags = VIDEO_FLAG_TYPE_NONE },
#ifdef USE_XL24
{ .device = &ati28800_wonderxl24_device, .flags = VIDEO_FLAG_TYPE_NONE },
#endif /* USE_XL24 */
{ .device = &ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &compaq_ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ati28800_wonder1024d_xl_plus_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &atiega800p_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &mach8_vga_isa_device, .flags = VIDEO_FLAG_TYPE_8514 },
{ .device = &mach32_isa_device, .flags = VIDEO_FLAG_TYPE_8514 },
{ .device = &ati28800k_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ati18800_vga88_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &compaq_ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ati28800_wonder1024d_xl_plus_device, .flags = VIDEO_FLAG_TYPE_NONE },
#ifdef USE_XL24
{ .device = &ati28800_wonderxl24_device, .flags = VIDEO_FLAG_TYPE_NONE },
#endif /* USE_XL24 */
{ .device = &ati18800_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ati18800_wonder_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &cga_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &quadcolor_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &sega_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &jega_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5401_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &gd5402_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &colorplus_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &compaq_cga_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &compaq_cga_2_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &cpqega_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ega_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &g2_gc205_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &hercules_device, .flags = VIDEO_FLAG_TYPE_MDA },
{ .device = &herculesplus_device, .flags = VIDEO_FLAG_TYPE_MDA },
{ .device = &incolor_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &cga_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ega_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &mda_device, .flags = VIDEO_FLAG_TYPE_MDA },
{ .device = &pgc_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &vga_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &im1024_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &iskra_ega_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &jega_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000_kasan_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &mda_device, .flags = VIDEO_FLAG_TYPE_MDA },
{ .device = &genius_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &oti037c_device, .flags = VIDEO_FLAG_TYPE_NONE },
@@ -94,9 +97,8 @@ video_cards[] = {
{ .device = &paradise_pvga1a_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &paradise_wd90c11_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &paradise_wd90c30_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &colorplus_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &pgc_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &cga_pravetz_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &quadcolor_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &realtek_rtg3105_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &realtek_rtg3106_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &sigma_device, .flags = VIDEO_FLAG_TYPE_NONE },
@@ -104,13 +106,11 @@ video_cards[] = {
{ .device = &tvga8900d_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &tvga8900dr_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &tvga9000b_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000k_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et2000_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et3000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000_tc6058af_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &et4000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &vga_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &v7_vga_1024i_device, .flags = VIDEO_FLAG_TYPE_NONE },
{ .device = &wy700_device, .flags = VIDEO_FLAG_TYPE_NONE },
/* ISA16 */

View File

@@ -35,6 +35,7 @@
#include <86box/vid_svga_render.h>
#include <86box/vid_xga_device.h>
#include "cpu.h"
#include <86box/plat.h>
#include <86box/plat_unused.h>
#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN"
@@ -161,31 +162,19 @@ xga_updatemapping(svga_t *svga)
switch (xga->op_mode & 7) {
case 0:
xga_log("XGA: VGA mode address decode disabled.\n");
mem_mapping_disable(&xga->linear_mapping);
break;
case 1:
xga_log("XGA: VGA mode address decode enabled.\n");
if (xga->base_addr_1mb) {
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
mem_mapping_enable(&xga->linear_mapping);
} else if (xga->linear_base) {
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
mem_mapping_enable(&xga->linear_mapping);
} else
mem_mapping_disable(&xga->linear_mapping);
mem_mapping_disable(&xga->linear_mapping);
break;
case 2:
xga_log("XGA: 132-Column mode address decode disabled.\n");
mem_mapping_disable(&xga->linear_mapping);
break;
case 3:
xga_log("XGA: 132-Column mode address decode enabled.\n");
if (xga->base_addr_1mb) {
mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000);
mem_mapping_enable(&xga->linear_mapping);
} else if (xga->linear_base) {
mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000);
mem_mapping_enable(&xga->linear_mapping);
} else
mem_mapping_disable(&xga->linear_mapping);
mem_mapping_disable(&xga->linear_mapping);
break;
default:
xga_log("XGA: Extended Graphics mode, ap=%d.\n", xga->aperture_cntl);
@@ -225,12 +214,14 @@ xga_updatemapping(svga_t *svga)
}
break;
case 1:
mem_mapping_disable(&xga->linear_mapping);
xga_log("XGA: 64KB aperture at A0000.\n");
mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel);
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
xga->banked_mask = 0xffff;
break;
case 2:
mem_mapping_disable(&xga->linear_mapping);
xga_log("XGA: 64KB aperture at B0000.\n");
mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel);
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x10000);
@@ -276,6 +267,7 @@ xga_recalctimings(svga_t *svga)
xga->v_blankstart = xga->vblankstart + 1;
xga->h_disp = (xga->hdisp + 1) << 3;
xga->h_disp_time = xga->h_disp >> 3;
xga->rowoffset = xga->pix_map_width;
@@ -292,7 +284,6 @@ xga_recalctimings(svga_t *svga)
xga->memaddr_latch = xga->disp_start_addr;
xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x, dispcntl2=%02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80, xga->disp_cntl_2 & 0xc0);
switch ((xga->clk_sel_1 >> 2) & 3) {
case 0:
@@ -329,6 +320,8 @@ xga_recalctimings(svga_t *svga)
svga->render_xga = xga_render_blank;
break;
}
xga_log("XGA: H_TOTAL=%d, rowoffset=%x, rowcount=%x, memaddr_latch=%06x, bpp type=%d.\n", xga->h_total, xga->rowoffset, xga->rowcount, xga->memaddr_latch, xga->disp_cntl_2 & 7);
}
}
@@ -584,9 +577,9 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv)
xga->ap_idx = val;
xga_log("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl,
val, val & 0x3f);
if ((xga->op_mode & 7) < 4) {
if ((xga->op_mode & 7) < 4)
xga->write_bank = xga->read_bank = 0;
} else {
else {
if (xga->base_addr_1mb) {
if (xga->aperture_cntl) {
xga->write_bank = (xga->ap_idx & 0x3f) << 16;
@@ -1007,6 +1000,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
uint32_t addr = base;
int bits;
uint32_t byte;
uint8_t mask;
uint8_t px;
int skip = 0;
@@ -1022,13 +1016,13 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
} else
byte = mem_readb_phys(addr);
xga_log("1. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->accel.pat_src);
if ((xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->access_mode & 0x08))
bits = (x & 7);
else
bits = 7 - (x & 7);
px = (byte >> bits) & 1;
xga_log("1bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, px=%x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, px, x, y, skip);
return px;
case 2: /*4-bit*/
addr += (y * (width >> 1));
@@ -1038,7 +1032,16 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
} else
byte = mem_readb_phys(addr);
xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip);
if ((xga->accel.px_map_format[map] & 0x08) && (xga->access_mode & 0x08))
mask = ((1 - (x & 1)) << 2);
else {
mask = ((x & 1) << 2);
mask ^= 0x04;
}
byte = (byte >> mask) & 0x0f;
xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d, mask=%02x.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip, mask);
return byte;
case 3: /*8-bit*/
addr += (y * width);
@@ -1091,11 +1094,11 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
} else
byte = mem_readb_phys(addr);
xga_log("2. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[map] & 0x0f), xga->accel.pat_src);
if (xga->access_mode & 0x08)
mask = 1 << (7 - (x & 7));
else {
if ((xga->accel.px_map_format[map] & 0x08) || (xga->accel.px_map_format[xga->accel.src_map] & 0x08)) {
xga_log("2. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[map] & 0x0f), xga->accel.pat_src);
mask = 1 << (x & 7);
} else
mask = 1 << (7 - (x & 7));
@@ -1123,10 +1126,16 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
} else
byte = mem_readb_phys(addr);
if (xga->accel.px_map_format[map] & 0x08)
mask = 0x0f << ((x & 1) << 2);
else
mask = 0x0f << ((1 - (x & 1)) << 2);
if ((xga->accel.px_map_format[map] & 0x08) && (xga->access_mode & 0x08))
mask = ((1 - (x & 1)) << 2);
else {
mask = ((x & 1) << 2);
mask ^= 0x04;
}
xga_log("4bpp Write: AccessMode=%02x.\n", xga->access_mode & 0x08);
pixel <<= mask;
mask = 0x0f << mask;
byte = (byte & ~mask) | (pixel & mask);
if (!skip) {
@@ -1606,6 +1615,7 @@ xga_bitblt(svga_t *svga)
xga->accel.sx += xdir;
dx += xdir;
xga->accel.x--;
if (xga->accel.x < 0) {
xga->accel.x = xga->accel.blt_width & 0xfff;
@@ -1781,6 +1791,7 @@ xga_bitblt(svga_t *svga)
}
xga->accel.sx += xdir;
if (xga->accel.pattern)
xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth);
else
@@ -2631,24 +2642,31 @@ xga_render_4bpp(svga_t *svga)
if (xga->firstline_draw == 2000)
xga->firstline_draw = xga->displine;
xga->lastline_draw = xga->displine;
for (int x = 0; x <= xga->h_disp; x += 8) {
for (int x = 0; x <= xga->h_disp; x += 16) {
dat = *(uint32_t *) (&xga->vram[xga->memaddr & xga->vram_mask]);
p[0] = xga->pallook[dat & 0x0f];
p[1] = xga->pallook[(dat >> 8) & 0x0f];
p[2] = xga->pallook[(dat >> 16) & 0x0f];
p[3] = xga->pallook[(dat >> 24) & 0x0f];
dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 2) & xga->vram_mask]);
p[4] = xga->pallook[dat & 0x0f];
p[5] = xga->pallook[(dat >> 8) & 0x0f];
p[6] = xga->pallook[(dat >> 16) & 0x0f];
p[1] = xga->pallook[dat & 0x0f];
p[0] = xga->pallook[(dat >> 4) & 0x0f];
p[3] = xga->pallook[(dat >> 8) & 0x0f];
p[2] = xga->pallook[(dat >> 12) & 0x0f];
p[5] = xga->pallook[(dat >> 16) & 0x0f];
p[4] = xga->pallook[(dat >> 20) & 0x0f];
p[7] = xga->pallook[(dat >> 24) & 0x0f];
p[6] = xga->pallook[(dat >> 28) & 0x0f];
dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 4) & xga->vram_mask]);
p[9] = xga->pallook[dat & 0x0f];
p[8] = xga->pallook[(dat >> 4) & 0x0f];
p[11] = xga->pallook[(dat >> 8) & 0x0f];
p[10] = xga->pallook[(dat >> 12) & 0x0f];
p[13] = xga->pallook[(dat >> 16) & 0x0f];
p[12] = xga->pallook[(dat >> 20) & 0x0f];
p[15] = xga->pallook[(dat >> 24) & 0x0f];
p[14] = xga->pallook[(dat >> 28) & 0x0f];
xga->memaddr += 8;
p += 8;
p += 16;
}
xga->memaddr &= xga->vram_mask;
}
@@ -2789,6 +2807,7 @@ xga_write(uint32_t addr, uint8_t val, void *priv)
addr &= xga->banked_mask;
addr += xga->write_bank;
xga_log("WriteBankedB addr=%08x, val=%02x, addrshift1=%08x.\n", addr, val, addr >> 1);
if (addr >= xga->vram_size)
return;
@@ -2806,6 +2825,7 @@ xga_writew(uint32_t addr, uint16_t val, void *priv)
addr &= xga->banked_mask;
addr += xga->write_bank;
xga_log("WriteBankedW addr=%08x, val=%04x, addrshift1=%08x.\n", addr, val, addr >> 1);
if (addr >= xga->vram_size)
return;
@@ -2824,6 +2844,7 @@ xga_writel(uint32_t addr, uint32_t val, void *priv)
addr &= xga->banked_mask;
addr += xga->write_bank;
xga_log("WriteBankedL addr=%08x, val=%08x, addrshift1=%08x.\n", addr, val, addr >> 1);
if (addr >= xga->vram_size)
return;
@@ -2971,7 +2992,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
return;
}
addr &= (xga->vram_size - 1);
addr &= xga->vram_mask;
if (addr >= xga->vram_size) {
xga_log("Write Linear Over!.\n");
@@ -3026,7 +3047,7 @@ xga_read_linear(uint32_t addr, void *priv)
if (!xga->on)
return svga_read_linear(addr, svga);
addr &= (xga->vram_size - 1);
addr &= xga->vram_mask;
if (addr >= xga->vram_size) {
xga_log("Read Linear Over ADDR=%x!.\n", addr);
@@ -3121,10 +3142,10 @@ xga_poll(void *priv)
svga->render_xga(svga);
svga->x_add = (overscan_x >> 1);
svga->x_add = svga->left_overscan;
xga_render_overscan_left(xga, svga);
xga_render_overscan_right(xga, svga);
svga->x_add = (overscan_x >> 1);
svga->x_add = svga->left_overscan;
if (xga->hwcursor_on) {
xga_hwcursor_draw(svga, xga->displine + svga->y_add);
@@ -3229,11 +3250,11 @@ xga_poll(void *priv)
}
if (xga->vc == xga->v_total) {
xga->vc = 0;
xga->scanline = 0;
xga->scanline = 0;
xga->dispon = 1;
xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0;
svga->x_add = (overscan_x >> 1);
svga->x_add = svga->left_overscan;
xga->hwcursor_on = 0;
xga->hwcursor_latch = xga->hwcursor;
@@ -3273,8 +3294,6 @@ xga_mca_write(int port, uint8_t val, void *priv)
/* Save the MCA register value. */
xga->pos_regs[port & 7] = val;
if (!(xga->pos_regs[4] & 1)) /*MCA 4MB addressing on systems with more than 16MB of memory*/
xga->pos_regs[4] |= 1;
if (xga->pos_regs[2] & 1) {
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
@@ -3361,7 +3380,6 @@ xga_pos_in(uint16_t addr, void *priv)
ret = xga->pos_regs[3];
ret |= (xga->dma_channel << 3);
}
xga_log("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret);
break;
case 0x0104:
@@ -3465,11 +3483,8 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv)
break;
case 0x0104:
xga_log("104Write=%02x.\n", val);
if ((xga->pos_idx & 3) == 0) {
if ((xga->pos_idx & 3) == 0)
xga->pos_regs[4] = val;
if (!(xga->pos_regs[4] & 0x01)) /*4MB addressing on systems with more than 15MB of memory*/
xga->pos_regs[4] |= 0x01;
}
break;
case 0x0105:
xga_log("105Write=%02x.\n", val);
@@ -3515,13 +3530,11 @@ xga_init(const device_t *info)
svga->xga = xga;
xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr");
xga->instance_isa = device_get_config_int("instance");
xga->type = device_get_config_int("type");
xga->dma_channel = device_get_config_int("dma");
xga->bus = info->flags;
xga->vram_size = (1024 << 10);
xga->vram_size = 1024 << 10;
xga->vram_mask = xga->vram_size - 1;
xga->vram = calloc(xga->vram_size, 1);
xga->changedvram = calloc((xga->vram_size >> 12) + 1, 1);
@@ -3548,25 +3561,6 @@ xga_init(const device_t *info)
mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl,
xga_memio_writeb, xga_memio_writew, xga_memio_writel,
xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga);
} else {
xga->pos_regs[2] = (xga->instance_isa << 1) | xga->ext_mem_addr;
xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000);
xga->instance = (xga->pos_regs[2] & 0x0e) >> 1;
xga->pos_regs[2] |= 0x01;
xga->pos_regs[4] |= 0x01;
if (mem_size >= 15360)
xga->pos_regs[5] = 0;
else {
xga->pos_regs[5] = ((mem_size * 64) >> 0x10) + 1;
if (xga->pos_regs[5] == 0x10)
xga->pos_regs[5] = 0x00;
}
xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20;
xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22);
rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, xga->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl,
xga_memio_writeb, xga_memio_writew, xga_memio_writel,
xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga);
}
}
@@ -3585,10 +3579,6 @@ xga_init(const device_t *info)
} else {
io_sethandler(0x0096, 0x0001, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga);
io_sethandler(0x0100, 0x0010, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga);
if (xga_standalone_enabled) {
io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga);
mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000);
}
}
return svga;
}
@@ -3678,89 +3668,6 @@ static const device_config_t xga_mca_configuration[] = {
// clang-format on
};
static const device_config_t xga_isa_configuration[] = {
// clang-format off
{
.name = "type",
.description = "XGA type",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "XGA-1", .value = 0 },
{ .description = "XGA-2", .value = 1 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "instance",
.description = "Instance",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 6,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "0 (2100h-210Fh)", .value = 0 },
{ .description = "1 (2110h-211Fh)", .value = 1 },
{ .description = "2 (2120h-212Fh)", .value = 2 },
{ .description = "3 (2130h-213Fh)", .value = 3 },
{ .description = "4 (2140h-214Fh)", .value = 4 },
{ .description = "5 (2150h-215Fh)", .value = 5 },
{ .description = "6 (2160h-216Fh)", .value = 6 },
{ .description = "7 (2170h-217Fh)", .value = 7 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "ext_mem_addr",
.description = "MMIO Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x00f0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "C800h", .value = 0x0040 },
{ .description = "CA00h", .value = 0x0050 },
{ .description = "CC00h", .value = 0x0060 },
{ .description = "CE00h", .value = 0x0070 },
{ .description = "D000h", .value = 0x0080 },
{ .description = "D200h", .value = 0x0090 },
{ .description = "D400h", .value = 0x00a0 },
{ .description = "D600h", .value = 0x00b0 },
{ .description = "D800h", .value = 0x00c0 },
{ .description = "DA00h", .value = 0x00d0 },
{ .description = "DC00h", .value = 0x00e0 },
{ .description = "DE00h", .value = 0x00f0 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "dma",
.description = "DMA",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 7,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "Disabled", .value = 0 },
{ .description = "DMA 6", .value = 6 },
{ .description = "DMA 7", .value = 7 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
static const device_config_t xga_inmos_isa_configuration[] = {
// clang-format off
{
@@ -3812,20 +3719,6 @@ const device_t xga_device = {
.config = xga_mca_configuration
};
const device_t xga_isa_device = {
.name = "XGA (ISA)",
.internal_name = "xga_isa",
.flags = DEVICE_ISA16,
.local = 0,
.init = xga_init,
.close = xga_close,
.reset = xga_reset,
.available = xga_available,
.speed_changed = xga_speed_changed,
.force_redraw = xga_force_redraw,
.config = xga_isa_configuration
};
const device_t inmos_isa_device = {
.name = "INMOS XGA (ISA)",
.internal_name = "inmos_xga_isa",
@@ -3848,6 +3741,4 @@ xga_device_add(void)
if (machine_has_bus(machine, MACHINE_BUS_MCA))
device_add(&xga_device);
else
device_add(&xga_isa_device);
}