diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index 9eb75f7cd..06d0a0a60 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -225,12 +225,8 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) ali1531_shadow_recalc(val, dev); break; - case 0x50: - case 0x51: - case 0x52: - case 0x54: - case 0x55: - case 0x56: + case 0x50 ... 0x52: + case 0x54 ... 0x56: dev->pci_conf[addr] = val; break; @@ -247,8 +243,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0x86; break; - case 0x59: - case 0x5a: + case 0x59 ... 0x5a: case 0x5c: dev->pci_conf[addr] = val; break; @@ -270,8 +265,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1); break; - case 0x70: - case 0x71: + case 0x70 ... 0x71: dev->pci_conf[addr] = val; break; @@ -283,8 +277,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0x2b; break; - case 0x76: - case 0x77: + case 0x76 ... 0x77: dev->pci_conf[addr] = val; break; diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c index ef9a6746d..4205db161 100644 --- a/src/chipset/sis_5513_p2i.c +++ b/src/chipset/sis_5513_p2i.c @@ -106,7 +106,7 @@ sis_5513_apc_reset(sis_5513_pci_to_isa_t *dev) { memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs)); - if (dev->rev == 0b0) { + if (dev->rev == 0xb0) { dev->apc_regs[0x03] = 0x80; dev->apc_regs[0x04] = 0x38; dev->apc_regs[0x07] = 0x01; diff --git a/src/device.c b/src/device.c index 9a904f550..5b733df46 100644 --- a/src/device.c +++ b/src/device.c @@ -19,7 +19,7 @@ * Copyright 2016-2019 Miran Grca. * Copyright 2008-2019 Sarah Walker. * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -89,38 +89,38 @@ device_init(void) } void -device_set_context(device_context_t *c, const device_t *dev, int inst) +device_set_context(device_context_t *ctx, const device_t *dev, int inst) { - memset(c, 0, sizeof(device_context_t)); - c->dev = dev; - c->instance = inst; + memset(ctx, 0, sizeof(device_context_t)); + ctx->dev = dev; + ctx->instance = inst; if (inst) { - sprintf(c->name, "%s #%i", dev->name, inst); + sprintf(ctx->name, "%s #%i", dev->name, inst); /* If a numbered section is not present, but a non-numbered of the same name is, rename the non-numbered section to numbered. */ - const void *sec = config_find_section(c->name); + const void *sec = config_find_section(ctx->name); void * single_sec = config_find_section((char *) dev->name); if ((sec == NULL) && (single_sec != NULL)) - config_rename_section(single_sec, c->name); + config_rename_section(single_sec, ctx->name); } else if (!strcmp(dev->name, "PS/2 Mouse")) { - sprintf(c->name, "%s", dev->name); + sprintf(ctx->name, "%s", dev->name); /* Migrate the old "Standard PS/2 Mouse" section */ - const void *sec = config_find_section(c->name); + const void *sec = config_find_section(ctx->name); void * old_sec = config_find_section("Standard PS/2 Mouse"); if ((sec == NULL) && (old_sec != NULL)) - config_rename_section(old_sec, c->name); + config_rename_section(old_sec, ctx->name); } else if (!strcmp(dev->name, "Microsoft RAMCard")) { - sprintf(c->name, "%s", dev->name); + sprintf(ctx->name, "%s", dev->name); - /* Migrate the old "Standard PS/2 Mouse" section */ - const void *sec = config_find_section(c->name); + /* Migrate the old "Microsoft RAMCard for IBM PC" section */ + const void *sec = config_find_section(ctx->name); void * old_sec = config_find_section("Microsoft RAMCard for IBM PC"); if ((sec == NULL) && (old_sec != NULL)) - config_rename_section(old_sec, c->name); + config_rename_section(old_sec, ctx->name); } else - sprintf(c->name, "%s", dev->name); + sprintf(ctx->name, "%s", dev->name); } static void @@ -153,7 +153,7 @@ device_add_common(const device_t *dev, void *p, void *params, int inst) { device_t *init_dev = NULL; void *priv = NULL; - int c; + int16_t c; if (params != NULL) { init_dev = calloc(1, sizeof(device_t)); @@ -162,7 +162,7 @@ device_add_common(const device_t *dev, void *p, void *params, int inst) } else init_dev = (device_t *) dev; - for (c = 0; c < 256; c++) { + for (c = 0; c < DEVICE_MAX; c++) { if (!inst && (devices[c] == dev)) { device_log("DEVICE: device already exists!\n"); return (NULL); @@ -244,6 +244,7 @@ void * device_add_linked(const device_t *dev, void *priv) { void *ret; + device_common_priv = priv; ret = device_add_common(dev, NULL, NULL, 0); device_common_priv = NULL; @@ -311,7 +312,8 @@ device_close_all(void) #endif if (devices[c]->close != NULL) devices[c]->close(device_priv[c]); - devices[c] = device_priv[c] = NULL; + devices[c] = NULL; + device_priv[c] = NULL; } } } @@ -372,7 +374,7 @@ device_available(const device_t *dev) if (dev != NULL) { config = dev->config; if (config != NULL) { - while (config->type != -1) { + while (config->type != CONFIG_END) { if (config->type == CONFIG_BIOS) { int roms_present = 0; @@ -414,7 +416,7 @@ device_get_bios_file(const device_t *dev, const char *internal_name, int file_no if (dev != NULL) { config = dev->config; if (config != NULL) { - while (config->type != -1) { + while (config->type != CONFIG_END) { if (config->type == CONFIG_BIOS) { bios = config->bios; @@ -452,7 +454,7 @@ device_has_config(const device_t *dev) config = dev->config; - while (config->type != -1) { + while (config->type != CONFIG_END) { c++; config++; } @@ -543,8 +545,7 @@ device_get_name(const device_t *dev, int bus, char *name) strcat(pbus, ")"); /* Allocate the temporary device name string and set it to all zeroes. */ - tname = (char *) malloc(strlen(dev->name) + 1); - memset(tname, 0x00, strlen(dev->name) + 1); + tname = (char *) calloc(1, strlen(dev->name) + 1); /* First strip the bus string with parentheses. */ fbus = strstr(dev->name, pbus); @@ -612,256 +613,256 @@ device_get_instance(void) } const char * -device_get_config_string(const char *s) +device_get_config_string(const char *str) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_string((char *) device_current.name, (char *) s, (char *) c->default_string)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_string((char *) device_current.name, (char *) str, (char *) cfg->default_string)); - c++; + cfg++; } return (NULL); } int -device_get_config_int(const char *s) +device_get_config_int(const char *str) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_int((char *) device_current.name, (char *) s, c->default_int)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_int((char *) device_current.name, (char *) str, cfg->default_int)); - c++; + cfg++; } return 0; } int -device_get_config_int_ex(const char *s, int def) +device_get_config_int_ex(const char *str, int def) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_int((char *) device_current.name, (char *) s, def)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_int((char *) device_current.name, (char *) str, def)); - c++; + cfg++; } return def; } int -device_get_config_hex16(const char *s) +device_get_config_hex16(const char *str) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_hex16((char *) device_current.name, (char *) s, c->default_int)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_hex16((char *) device_current.name, (char *) str, cfg->default_int)); - c++; + cfg++; } return 0; } int -device_get_config_hex20(const char *s) +device_get_config_hex20(const char *str) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_hex20((char *) device_current.name, (char *) s, c->default_int)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_hex20((char *) device_current.name, (char *) str, cfg->default_int)); - c++; + cfg++; } return 0; } int -device_get_config_mac(const char *s, int def) +device_get_config_mac(const char *str, int def) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_mac((char *) device_current.name, (char *) s, def)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_mac((char *) device_current.name, (char *) str, def)); - c++; + cfg++; } return def; } void -device_set_config_int(const char *s, int val) +device_set_config_int(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_int((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_int((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } void -device_set_config_hex16(const char *s, int val) +device_set_config_hex16(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_hex16((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_hex16((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } void -device_set_config_hex20(const char *s, int val) +device_set_config_hex20(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_hex20((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_hex20((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } void -device_set_config_mac(const char *s, int val) +device_set_config_mac(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_mac((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_mac((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } int -device_is_valid(const device_t *device, int m) +device_is_valid(const device_t *device, int mch) { if (device == NULL) return 1; - if ((device->flags & DEVICE_PCJR) && !machine_has_bus(m, MACHINE_BUS_PCJR)) + if ((device->flags & DEVICE_PCJR) && !machine_has_bus(mch, MACHINE_BUS_PCJR)) return 0; - if ((device->flags & DEVICE_XTKBC) && machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC)) + if ((device->flags & DEVICE_XTKBC) && machine_has_bus(mch, MACHINE_BUS_ISA16) && !machine_has_bus(mch, MACHINE_BUS_DM_KBC)) return 0; - if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16)) + if ((device->flags & DEVICE_AT) && !machine_has_bus(mch, MACHINE_BUS_ISA16)) return 0; - if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC)) + if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(mch, MACHINE_BUS_ISA16) && !machine_has_bus(mch, MACHINE_BUS_DM_KBC)) return 0; - if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS)) + if ((device->flags & DEVICE_PS2) && !machine_has_bus(mch, MACHINE_BUS_PS2_PORTS)) return 0; - if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA)) + if ((device->flags & DEVICE_ISA) && !machine_has_bus(mch, MACHINE_BUS_ISA)) return 0; - if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS)) + if ((device->flags & DEVICE_CBUS) && !machine_has_bus(mch, MACHINE_BUS_CBUS)) return 0; - if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_ISA)) + if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(mch, MACHINE_BUS_PCMCIA) && !machine_has_bus(mch, MACHINE_BUS_ISA)) return 0; - if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA)) + if ((device->flags & DEVICE_MCA) && !machine_has_bus(mch, MACHINE_BUS_MCA)) return 0; - if ((device->flags & DEVICE_HIL) && !machine_has_bus(m, MACHINE_BUS_HIL)) + if ((device->flags & DEVICE_HIL) && !machine_has_bus(mch, MACHINE_BUS_HIL)) return 0; - if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA)) + if ((device->flags & DEVICE_EISA) && !machine_has_bus(mch, MACHINE_BUS_EISA)) return 0; - if ((device->flags & DEVICE_AT32) && !machine_has_bus(m, MACHINE_BUS_AT32)) + if ((device->flags & DEVICE_AT32) && !machine_has_bus(mch, MACHINE_BUS_AT32)) return 0; - if ((device->flags & DEVICE_OLB) && !machine_has_bus(m, MACHINE_BUS_OLB)) + if ((device->flags & DEVICE_OLB) && !machine_has_bus(mch, MACHINE_BUS_OLB)) return 0; - if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB)) + if ((device->flags & DEVICE_VLB) && !machine_has_bus(mch, MACHINE_BUS_VLB)) return 0; - if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI)) + if ((device->flags & DEVICE_PCI) && !machine_has_bus(mch, MACHINE_BUS_PCI)) return 0; - if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_PCI)) + if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(mch, MACHINE_BUS_CARDBUS) && !machine_has_bus(mch, MACHINE_BUS_PCI)) return 0; - if ((device->flags & DEVICE_USB) && !machine_has_bus(m, MACHINE_BUS_USB)) + if ((device->flags & DEVICE_USB) && !machine_has_bus(mch, MACHINE_BUS_USB)) return 0; - if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP)) + if ((device->flags & DEVICE_AGP) && !machine_has_bus(mch, MACHINE_BUS_AGP)) return 0; - if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97)) + if ((device->flags & DEVICE_AC97) && !machine_has_bus(mch, MACHINE_BUS_AC97)) return 0; return 1; } int -machine_get_config_int(char *s) +machine_get_config_int(char *str) { - const device_t *d = machine_get_device(machine); - const device_config_t *c; + const device_t *dev = machine_get_device(machine); + const device_config_t *cfg; - if (d == NULL) + if (dev == NULL) return 0; - c = d->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_int((char *) d->name, s, c->default_int)); + cfg = dev->config; + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_int((char *) dev->name, str, cfg->default_int)); - c++; + cfg++; } return 0; } char * -machine_get_config_string(char *s) +machine_get_config_string(char *str) { - const device_t *d = machine_get_device(machine); - const device_config_t *c; + const device_t *dev = machine_get_device(machine); + const device_config_t *cfg; - if (d == NULL) + if (dev == NULL) return 0; - c = d->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_string((char *) d->name, s, (char *) c->default_string)); + cfg = dev->config; + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_string((char *) dev->name, str, (char *) cfg->default_string)); - c++; + cfg++; } return NULL; @@ -881,7 +882,7 @@ const device_t device_none = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -895,7 +896,7 @@ const device_t device_internal = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 882174e4e..af3d5d5fc 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1961,18 +1961,24 @@ keyboard_at_write(void *priv) } } else { if (dev->flags & FLAG_CTRLDAT) { - /* Special case - another command during another command that wants input - proceed + /* + Special case - another command during another command that wants input - proceed as normal but do not cancel the command (so keep waiting for input), unless the - command in progress is ED (Set/reset LEDs). */ - if (val == 0xed) { - keyboard_scan = 1; + command in progress is ED (Set/reset LEDs). + + It appears to also apply to command EE (Echo), F4 (Enable), F5 (Diable and Set + Default), and F6 (SetDefault). + */ + if ((val == 0xed) || (val == 0xee) || (val == 0xf4) || (val == 0xf5) || (val == 0xf6)) dev->flags &= ~FLAG_CTRLDAT; - } else + else dev->state = DEV_STATE_MAIN_WANT_IN; } switch (val) { case 0xed: /* set/reset LEDs */ + if ((dev->flags & FLAG_CTRLDAT) && (dev->command == 0xed)) + keyboard_scan = 1; dev->command = val; keyboard_at_log("%s: set/reset LEDs\n", dev->name); dev->flags |= FLAG_CTRLDAT; diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 67a30b1c8..1c2ec5203 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -18,7 +18,7 @@ * Copyright 2016-2019 Miran Grca. * Copyright 2008-2019 Sarah Walker. * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -197,12 +197,12 @@ extern "C" { #endif extern void device_init(void); -extern void device_set_context(device_context_t *c, const device_t *dev, int inst); +extern void device_set_context(device_context_t *ctx, const device_t *dev, int inst); extern void device_context(const device_t *dev); extern void device_context_inst(const device_t *dev, int inst); extern void device_context_restore(void); -extern void *device_add(const device_t *d); -extern void *device_add_linked(const device_t *d, void *priv); +extern void *device_add(const device_t *dev); +extern void *device_add_linked(const device_t *dev, void *priv); extern void *device_add_params(const device_t *dev, void *params); extern void device_add_ex(const device_t *dev, void *priv); extern void device_add_ex_params(const device_t *dev, void *priv, void *params); @@ -223,27 +223,27 @@ extern void device_get_name(const device_t *dev, int bus, char *name); extern int device_has_config(const device_t *dev); extern const char *device_get_bios_file(const device_t *dev, const char *internal_name, int file_no); -extern int device_is_valid(const device_t *, int m); +extern int device_is_valid(const device_t *, int mch); extern const device_t* device_context_get_device(void); extern int device_get_config_int(const char *name); -extern int device_get_config_int_ex(const char *s, int dflt_int); +extern int device_get_config_int_ex(const char *str, int def); extern int device_get_config_hex16(const char *name); extern int device_get_config_hex20(const char *name); -extern int device_get_config_mac(const char *name, int dflt_int); -extern void device_set_config_int(const char *s, int val); -extern void device_set_config_hex16(const char *s, int val); -extern void device_set_config_hex20(const char *s, int val); -extern void device_set_config_mac(const char *s, int val); +extern int device_get_config_mac(const char *name, int def); +extern void device_set_config_int(const char *str, int val); +extern void device_set_config_hex16(const char *str, int val); +extern void device_set_config_hex20(const char *str, int val); +extern void device_set_config_mac(const char *str, int val); extern const char *device_get_config_string(const char *name); extern int device_get_instance(void); #define device_get_config_bios device_get_config_string extern const char *device_get_internal_name(const device_t *dev); -extern int machine_get_config_int(char *s); -extern char *machine_get_config_string(char *s); +extern int machine_get_config_int(char *str); +extern char *machine_get_config_string(char *str); extern const device_t device_none; extern const device_t device_internal; diff --git a/src/include/86box/snd_sb.h b/src/include/86box/snd_sb.h index a85f1515c..06fbbfa3b 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -29,15 +29,19 @@ enum { SADLIB = 1, /* No DSP */ - SB1, /* DSP v1.05 */ - SB15, /* DSP v2.00 */ - SB2, /* DSP v2.01 - needed for high-speed DMA */ - SBPRO, /* DSP v3.00 */ - SBPRO2, /* DSP v3.02 + OPL3 */ - SB16, /* DSP v4.05 + OPL3 */ - SBAWE32, /* DSP v4.12 + OPL3 */ - SBAWE32PNP, /* DSP v4.13 + OPL3 */ - SBAWE64 /* DSP v4.16 + OPL3 */ + SB_DSP_105, /* DSP v1.05, Original CT1320 (Also known as CT1310) */ + SB_DSP_200, /* DSP v2.00 */ + SB_DSP_201, /* DSP v2.01 - needed for high-speed DMA, Seen on CT1350B with CT1336 */ + SB_DSP_202, /* DSP v2.02 - Seen on CT1350B with CT1336A */ + SBPRO_DSP_300, /* DSP v3.00 */ + SBPRO2_DSP_302, /* DSP v3.02 + OPL3 */ + SB16_DSP_404, /* DSP v4.05 + OPL3 */ + SB16_DSP_405, /* DSP v4.05 + OPL3 */ + SB16_DSP_406, /* DSP v4.06 + OPL3 */ + SB16_DSP_411, /* DSP v4.11 + OPL3 */ + SBAWE32_DSP_412, /* DSP v4.12 + OPL3 */ + SBAWE32_DSP_413, /* DSP v4.13 + OPL3 */ + SBAWE64_DSP_416 /* DSP v4.16 + OPL3 */ }; /* SB 2.0 CD version */ diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index 0e6e0965a..57e98cc44 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -138,6 +138,7 @@ typedef struct ibm8514_t { int output2; int ssv_len; + int ssv_len_back; uint8_t ssv_dir; uint8_t ssv_draw; int odd_in; diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 122c5cdef..fea87c8f6 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -13,10 +13,12 @@ * Authors: Fred N. van Kempen, * Miran Grca, * Sarah Walker, + * Jasmine Iwanek, * * Copyright 2017-2020 Fred N. van Kempen. * Copyright 2016-2020 Miran Grca. * Copyright 2008-2020 Sarah Walker. + * Copyright 2025 Jasmine Iwanek. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,7 +38,6 @@ * Boston, MA 02111-1307 * USA. */ - #include #include #include @@ -53,6 +54,7 @@ #include <86box/fdc_ext.h> #include <86box/nvr.h> #include <86box/gameport.h> +#include <86box/ibm_5161.h> #include <86box/keyboard.h> #include <86box/lpt.h> #include <86box/rom.h> @@ -149,10 +151,41 @@ machine_at_ps2_ide_init(const machine_t *model) device_add(&ide_isa_device); } +static const device_config_t ibmat_config[] = { + // clang-format off + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmat_device = { + .name = " IBM AT Devices", + .internal_name = "ibmat_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmat_config +}; + int machine_at_ibm_init(const machine_t *model) { - int ret; + int ret; + uint8_t enable_5161; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + device_context_restore(); ret = bios_load_interleaved("roms/machines/ibmat/62x0820.u27", "roms/machines/ibmat/62x0821.u47", @@ -163,6 +196,9 @@ machine_at_ibm_init(const machine_t *model) machine_at_ibm_common_init(model); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } @@ -218,10 +254,41 @@ machine_at_ibmatpx_init(const machine_t *model) return ret; } +static const device_config_t ibmxt286_config[] = { + // clang-format off + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmxt286_device = { + .name = "IBM XT Model 286 Devices", + .internal_name = "ibmxt286_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt286_config +}; + int machine_at_ibmxt286_init(const machine_t *model) { - int ret; + int ret; + uint8_t enable_5161; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + device_context_restore(); ret = bios_load_interleaved("roms/machines/ibmxt286/bios_5162_21apr86_u34_78x7460_27256.bin", "roms/machines/ibmxt286/bios_5162_21apr86_u35_78x7461_27256.bin", @@ -232,6 +299,9 @@ machine_at_ibmxt286_init(const machine_t *model) machine_at_ibm_common_init(model); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 9c1eb817b..ead31c21c 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -214,7 +214,7 @@ machine_at_neat_ami_init(const machine_t *model) // TODO // Onboard Paradise PVGA1A-JK VGA Graphics -// Data Technology Corporation DTC7187 RLL Controller +// Data Technology Corporation DTC7187 RLL Controller (Optional) int machine_at_ataripc4_init(const machine_t *model) { diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 62466bf91..7b59686d6 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -1,3 +1,25 @@ +/* + * 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. + * + * Standard PC/AT implementation. + * + * + * + * Authors: Fred N. van Kempen, + * Miran Grca, + * Sarah Walker, + * Jasmine Iwanek, + * + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2025 Jasmine Iwanek. + */ #include #include #include @@ -37,22 +59,94 @@ machine_xt_common_init(const machine_t *model, int fixed_floppy) standalone_gameport_type = &gameport_device; } +static const device_config_t ibmpc_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ibm5150_5700671", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "5700671 (10/19/81)", .internal_name = "ibm5150_5700671", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc/BIOS_IBM5150_19OCT81_5700671_U33.BIN", "" } }, + { .name = "5700051 (04/24/81)", .internal_name = "ibm5150_5700051", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc/BIOS_IBM5150_24APR81_5700051_U33.BIN", "" } }, + // The following are Diagnostic ROMs. + { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, + { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, + { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, + { .files_no = 0 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "enable_basic", + .description = "IBM Cassette Basic", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmpc_device = { + .name = "IBM PC (1981) Device", + .internal_name = "ibmpc_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmpc_config +}; + int machine_pc_init(const machine_t *model) { - int ret; + int ret = 0; + int ret2; + uint8_t enable_5161; + uint8_t enable_basic; + const char *fn; - ret = bios_load_linear("roms/machines/ibmpc/BIOS_5150_24APR81_U33.BIN", - 0x000fe000, 40960, 0); - if (ret) { - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U29 - 5700019.bin", - 0x000f6000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U30 - 5700027.bin", - 0x000f8000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U31 - 5700035.bin", - 0x000fa000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U32 - 5700043.bin", - 0x000fc000, 8192, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + enable_basic = machine_get_config_int("enable_basic"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 40960, 0); + device_context_restore(); + + if (enable_basic && ret) { + ret2 = bios_load_aux_linear("roms/machines/ibmpc/ibm-basic-1.00.rom", + 0x000f6000, 32768, 0); + if (!ret2) { + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U29 - 5700019.bin", + 0x000f6000, 8192, 0); + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U30 - 5700027.bin", + 0x000f8000, 8192, 0); + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U31 - 5700035.bin", + 0x000fa000, 8192, 0); + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U32 - 5700043.bin", + 0x000fc000, 8192, 0); + } } if (bios_only || !ret) @@ -62,28 +156,98 @@ machine_pc_init(const machine_t *model) machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } +static const device_config_t ibmpc82_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ibm5150_1501476", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "1501476 (10/27/82)", .internal_name = "ibm5150_1501476", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_27OCT82_1501476_U33.BIN", "" } }, + { .name = "5000024 (08/16/82)", .internal_name = "ibm5150_5000024", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_16AUG82_5000024_U33.BIN", "" } }, + // The following are Diagnostic ROMs. + { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, + { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, + { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, + { .files_no = 0 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "enable_basic", + .description = "IBM Cassette Basic", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmpc82_device = { + .name = "IBM PC (1982) Devices", + .internal_name = "ibmpc82_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmpc82_config +}; + int machine_pc82_init(const machine_t *model) { - int ret; - int ret2; + int ret = 0; + int ret2; + uint8_t enable_5161; + uint8_t enable_basic; + const char *fn; - ret = bios_load_linear("roms/machines/ibmpc82/pc102782.bin", - 0x000fe000, 40960, 0); - if (ret) { + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + enable_basic = machine_get_config_int("enable_basic"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 40960, 0); + device_context_restore(); + + if (enable_basic && ret) { ret2 = bios_load_aux_linear("roms/machines/ibmpc82/ibm-basic-1.10.rom", 0x000f6000, 32768, 0); if (!ret2) { - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.f6", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U29 - 5000019.bin", 0x000f6000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.f8", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U30 - 5000021.bin", 0x000f8000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.fa", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U31 - 5000022.bin", 0x000fa000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.fc", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U32 - 5000023.bin", 0x000fc000, 8192, 0); } } @@ -92,40 +256,110 @@ machine_pc82_init(const machine_t *model) return ret; device_add(&keyboard_pc82_device); - device_add(&ibm_5161_device); machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } +static const device_config_t ibmxt_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ibm5160_1501512_5000027", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "1501512 (11/08/82)", .internal_name = "ibm5160_1501512_5000027", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } }, + { .name = "1501512 (11/08/82) (Alt)", .internal_name = "ibm5160_1501512_6359116", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_6359116.BIN", "" } }, + { .name = "5000026 (08/16/82)", .internal_name = "ibm5160_5000026_5000027", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_16AUG82_U18_5000026.BIN", "roms/machines/ibmxt/BIOS_5160_16AUG82_U19_5000027.BIN", "" } }, +#if 0 + // The following are Diagnostic ROMs. + { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, + { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, + { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, +#endif + { .files_no = 0 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "enable_basic", + .description = "IBM Cassette Basic", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmxt_device = { + .name = "IBM XT (1982) Device", + .internal_name = "ibmxt_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt_config +}; + int machine_xt_init(const machine_t *model) { - int ret; + int ret = 0; + uint8_t enable_5161; + uint8_t enable_basic; + const char *fn; - ret = bios_load_linear("roms/machines/ibmxt/xt.rom", - 0x000f0000, 65536, 0); - if (!ret) { - ret = bios_load_linear("roms/machines/ibmxt/1501512.u18", - 0x000fe000, 65536, 0x6000); - if (ret) { - bios_load_aux_linear("roms/machines/ibmxt/1501512.u18", - 0x000f8000, 24576, 0); - bios_load_aux_linear("roms/machines/ibmxt/5000027.u19", - 0x000f0000, 32768, 0); - } + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + enable_basic = machine_get_config_int("enable_basic"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000); + + if (enable_basic && ret) { + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + (void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1); + (void) bios_load_aux_linear(fn, 0x000f0000, 32768, 0); } + device_context_restore(); if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); - device_add(&ibm_5161_device); machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } @@ -147,28 +381,93 @@ machine_genxt_init(const machine_t *model) return ret; } +static const device_config_t ibmxt86_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ibm5160_050986", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "1501512 (05/09/86)", .internal_name = "ibm5160_050986", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } }, + { .name = "5000026 (01/10/86)", .internal_name = "ibm5160_011086", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0851_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0854_27256_F000.BIN", "" } }, + { .name = "1501512 (01/10/86) (Alt)", .internal_name = "ibm5160_011086_alt", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0852_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0853_27256_F000.BIN", "" } }, +#if 0 + // The following are Diagnostic ROMs. + { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, + { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, + { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, +#endif + { .files_no = 0 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmxt86_device = { + .name = "IBM XT (1986) Device", + .internal_name = "ibmxt86_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt86_config +}; + int machine_xt86_init(const machine_t *model) { - int ret; + int ret = 0; + uint8_t enable_5161; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000); - ret = bios_load_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", - 0x000fe000, 65536, 0x6000); if (ret) { - (void) bios_load_aux_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", - 0x000f8000, 24576, 0); - (void) bios_load_aux_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", - 0x000f0000, 32768, 0); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + (void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1); + (void) bios_load_aux_linear(fn, 0x000f0000, 32768, 0); } + device_context_restore(); if (bios_only || !ret) return ret; device_add(&keyboard_xt86_device); - device_add(&ibm_5161_device); machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } @@ -214,6 +513,7 @@ machine_xt_amixt_init(const machine_t *model) // TODO // Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions) +// RTC // Adaptec ACB-2072 RLL Controller Card (Optional) // Atari PCM1 Mouse Support int diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b60d35fd7..3fc3bcc8a 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -15,9 +15,11 @@ * * Authors: Miran Grca, * Fred N. van Kempen, + * Jasmine Iwanek, * * Copyright 2016-2020 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2025 Jasmine Iwanek. */ #include #include @@ -55,6 +57,12 @@ extern const device_t vid_device_sl; extern const device_t t1200_video_device; extern const device_t compaq_plasma_device; extern const device_t ps1_2011_device; +extern const device_t ibmpc_device; +extern const device_t ibmpc82_device; +extern const device_t ibmxt_device; +extern const device_t ibmxt86_device; +extern const device_t ibmat_device; +extern const device_t ibmxt286_device; const machine_filter_t machine_types[] = { { "None", MACHINE_TYPE_NONE }, @@ -243,7 +251,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmpc_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -282,7 +290,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmpc82_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -360,7 +368,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmxt_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -399,7 +407,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmxt86_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -2673,7 +2681,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmat_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -2793,7 +2801,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmxt286_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index 01d7d3f9f..9679c9e21 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -160,6 +160,7 @@ SettingsPorts::on_pushButtonSerialPassThru4_clicked() DeviceConfig::ConfigureDevice(&serial_passthrough_device, 4, qobject_cast(Settings::settings)); } +#if 0 void SettingsPorts::on_pushButtonSerialPassThru5_clicked() { @@ -177,6 +178,7 @@ SettingsPorts::on_pushButtonSerialPassThru7_clicked() { DeviceConfig::ConfigureDevice(&serial_passthrough_device, 7, qobject_cast(Settings::settings)); } +#endif void SettingsPorts::on_checkBoxSerialPassThru1_clicked(bool checked) @@ -220,4 +222,4 @@ SettingsPorts::on_checkBoxSerialPassThru7_clicked(bool checked) { ui->pushButtonSerialPassThru7->setEnabled(checked); } -#endif \ No newline at end of file +#endif diff --git a/src/qt/qt_settingsports.hpp b/src/qt/qt_settingsports.hpp index 1ecb051af..fb9cdb343 100644 --- a/src/qt/qt_settingsports.hpp +++ b/src/qt/qt_settingsports.hpp @@ -19,45 +19,23 @@ public: #if 0 private slots: void on_checkBoxSerialPassThru7_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru6_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru5_clicked(bool checked); #endif - -private slots: void on_checkBoxSerialPassThru4_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru3_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru2_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru1_clicked(bool checked); private slots: +#if 0 void on_pushButtonSerialPassThru7_clicked(); - -private slots: void on_pushButtonSerialPassThru6_clicked(); - -private slots: void on_pushButtonSerialPassThru5_clicked(); - -private slots: +#endif void on_pushButtonSerialPassThru4_clicked(); - -private slots: void on_pushButtonSerialPassThru3_clicked(); - -private slots: void on_pushButtonSerialPassThru2_clicked(); - -private slots: void on_pushButtonSerialPassThru1_clicked(); private slots: diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 9aa5f391f..c2e5c9168 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -630,6 +630,7 @@ esp_hard_reset(esp_t *dev) fifo8_reset(&dev->fifo); fifo8_reset(&dev->cmdfifo); dev->dma = 0; + dev->tchi_written = 0; dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7; esp_log("ESP Reset\n"); @@ -1346,7 +1347,7 @@ esp_reg_read(esp_t *dev, uint32_t saddr) if (dev->mca) { ret = dev->rregs[ESP_TCHI]; } else { - if (dev->rregs[ESP_CFG2] & 0x40) + if (!dev->tchi_written) ret = TCHI_AM53C974; else ret = dev->rregs[ESP_TCHI]; @@ -1369,6 +1370,8 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_log("Write reg %02x = %02x\n", saddr, val); switch (saddr) { case ESP_TCHI: + dev->tchi_written = 1; + fallthrough; case ESP_TCLO: case ESP_TCMID: esp_log("ESP TCW reg%02x = %02x.\n", saddr, val); diff --git a/src/sound/midi.c b/src/sound/midi.c index 78794ef24..e9b4a82b6 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -71,7 +71,7 @@ typedef struct const device_t *device; } MIDI_OUT_DEVICE, MIDI_IN_DEVICE; -static const MIDI_OUT_DEVICE devices[] = { +static const MIDI_OUT_DEVICE midi_out_devices[] = { // clang-format off { &device_none }, #ifdef USE_FLUIDSYNTH @@ -106,8 +106,8 @@ static const MIDI_IN_DEVICE midi_in_devices[] = { int midi_out_device_available(int card) { - if (devices[card].device) - return device_available(devices[card].device); + if (midi_out_devices[card].device) + return device_available(midi_out_devices[card].device); return 1; } @@ -115,21 +115,21 @@ midi_out_device_available(int card) const device_t * midi_out_device_getdevice(int card) { - return devices[card].device; + return midi_out_devices[card].device; } int midi_out_device_has_config(int card) { - if (!devices[card].device) + if (!midi_out_devices[card].device) return 0; - return devices[card].device->config ? 1 : 0; + return midi_out_devices[card].device->config ? 1 : 0; } const char * midi_out_device_get_internal_name(int card) { - return device_get_internal_name(devices[card].device); + return device_get_internal_name(midi_out_devices[card].device); } int @@ -137,8 +137,8 @@ midi_out_device_get_from_internal_name(char *s) { int c = 0; - while (devices[c].device != NULL) { - if (!strcmp(devices[c].device->internal_name, s)) + while (midi_out_devices[c].device != NULL) { + if (!strcmp(midi_out_devices[c].device->internal_name, s)) return c; c++; } @@ -149,8 +149,8 @@ midi_out_device_get_from_internal_name(char *s) void midi_out_device_init(void) { - if ((midi_output_device_current > 0) && devices[midi_output_device_current].device) - device_add(devices[midi_output_device_current].device); + if ((midi_output_device_current > 0) && midi_out_devices[midi_output_device_current].device) + device_add(midi_out_devices[midi_output_device_current].device); midi_output_device_last = midi_output_device_current; } diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index a3a763244..cf05203f3 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -1238,7 +1238,7 @@ azt_init(const device_t *info) fm_driver_get(FM_YMF262, &azt2316a->sb->opl); sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1); - sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); + sb_dsp_init(&azt2316a->sb->dsp, SBPRO2_DSP_302, azt2316a->type, azt2316a); sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index 8ba344ec9..833124bb2 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -497,7 +497,7 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv) /* Set TDMA channels if auto-detection is enabled. */ if ((dev->io_regs[0x27] & 0x01) && (mixer->index == 0x81)) { dev->tdma_8 = dev->sb->dsp.sb_8_dmanum; - if (dev->sb->dsp.sb_type >= SB16) + if (dev->sb->dsp.sb_type >= SB16_DSP_404) dev->tdma_16 = dev->sb->dsp.sb_16_dmanum; } } else { @@ -879,7 +879,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) dev->sb->dsp.sbleftright_default = !!(val & 0x02); /* Enable or disable SB16 mode. */ - dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2 : SB16; + dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2_DSP_302 : SB16_DSP_405; break; case 0x22: diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index 9c8b0b460..d69986d98 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -394,7 +394,7 @@ optimc_init(const device_t *info) optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B); - sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc); + sb_dsp_init(&optimc->sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, optimc); sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma); diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index f9bab8d87..fab2a6a75 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -2314,7 +2314,7 @@ pas16_init(const device_t *info) pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f); fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); - sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); + sb_dsp_init(&pas16->dsp, SB_DSP_201, SB_SUBTYPE_DEFAULT, pas16); pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); memset(pas16->mpu, 0, sizeof(mpu_t)); mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 3213e3cf0..016e50c40 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -43,6 +43,10 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> +#define SB_1 0 +#define SB_15 1 +#define SB_2 2 + #define SB_16_PNP_NOIDE 0 #define SB_16_PNP_IDE 1 @@ -288,7 +292,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) if (!sb->opl_enabled) return; - if (sb->dsp.sb_type == SBPRO) { + if (sb->dsp.sb_type == SBPRO_DSP_300) { opl_buf = sb->opl.update(sb->opl.priv); opl2_buf = sb->opl2.update(sb->opl2.priv); } else @@ -300,7 +304,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->dsp.sb_type == SBPRO) { + if (sb->dsp.sb_type == SBPRO_DSP_300) { /* Two chips for LEFT and RIGHT channels. Each chip stores data into the LEFT channel only (no sample alternating.) */ out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; @@ -322,7 +326,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) } sb->opl.reset_buffer(sb->opl.priv); - if (sb->dsp.sb_type == SBPRO) + if (sb->dsp.sb_type == SBPRO_DSP_300) sb->opl2.reset_buffer(sb->opl2.priv); } @@ -415,7 +419,7 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; const int dsp_rec_pos = sb->dsp.record_pos_write; double bass_treble; - const int32_t *opl_buf = NULL; + const int32_t *opl_buf = NULL; if (sb->opl_enabled) opl_buf = sb->opl.update(sb->opl.priv); @@ -1157,7 +1161,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0xff: - if ((sb->dsp.sb_type > SBAWE32) && !sb->dsp.sb_16_dma_supported) { + if ((sb->dsp.sb_type > SBAWE32_DSP_412) && !sb->dsp.sb_16_dma_supported) { /* Bit 5: High DMA channel enabled (0 = yes, 1 = no); Bit 2: ????; @@ -1341,7 +1345,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ const uint8_t temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | ((sb->dsp.sb_irq401) ? 4 : 0); - if (sb->dsp.sb_type >= SBAWE32) + if (sb->dsp.sb_type >= SBAWE32_DSP_412) ret = temp | 0x80; else ret = temp | 0x40; @@ -1386,7 +1390,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) - Register FF = FF: Volume playback normal. - Register FF = Not FF: Volume playback low unless bit 6 of 82h is set. */ - if (sb->dsp.sb_type > SBAWE32) + if (sb->dsp.sb_type > SBAWE32_DSP_412) ret = mixer->regs[mixer->index]; break; @@ -1808,8 +1812,8 @@ sb_mcv_read(int port, void *priv) void sb_mcv_write(int port, uint8_t val, void *priv) { - uint16_t addr; - sb_t *sb = (sb_t *) priv; + uint16_t addr = 0; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -1872,8 +1876,8 @@ sb_pro_mcv_read(int port, void *priv) static void sb_pro_mcv_write(int port, uint8_t val, void *priv) { - uint16_t addr; - sb_t *sb = (sb_t *) priv; + uint16_t addr = 0; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -1943,8 +1947,8 @@ sb_16_reply_mca_read(int port, void *priv) static void sb_16_reply_mca_write(const int port, const uint8_t val, void *priv) { - uint16_t addr; - sb_t *sb = (sb_t *) priv; + uint16_t addr = 0; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -2219,7 +2223,7 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void break; case 2: /* Reserved (16) / WaveTable (32+) */ - if (sb->dsp.sb_type > SB16) + if (sb->dsp.sb_type >= SBAWE32_DSP_412) emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); break; @@ -2812,182 +2816,62 @@ ess_chipchat_mca_write(int port, uint8_t val, void *priv) } void * -sb_1_init(UNUSED(const device_t *info)) +sb_init(UNUSED(const device_t *info)) { - /* SB1/2 port mappings, 210h to 260h in 10h steps - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - const uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - fm_driver_get(FM_YM3812, &sb->opl); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB1, 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")); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr + 8, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - io_sethandler(0x0388, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - } - - sb->cms_enabled = 1; - memset(&sb->cms, 0, sizeof(cms_t)); - io_sethandler(addr, 0x0004, - cms_read, NULL, NULL, - cms_write, NULL, NULL, - &sb->cms); - - sb->mixer_enabled = 0; - sound_add_handler(sb_get_buffer_sb2, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb2, sb); - sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - - return sb; -} - -void * -sb_15_init(UNUSED(const device_t *info)) -{ - /* SB1/2 port mappings, 210h to 260h in 10h steps - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - const uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - fm_driver_get(FM_YM3812, &sb->opl); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB15, 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")); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr + 8, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - io_sethandler(0x0388, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - } - - sb->cms_enabled = device_get_config_int("cms"); - if (sb->cms_enabled) { - memset(&sb->cms, 0, sizeof(cms_t)); - io_sethandler(addr, 0x0004, - cms_read, NULL, NULL, - cms_write, NULL, NULL, - &sb->cms); - } - - sb->mixer_enabled = 0; - sound_add_handler(sb_get_buffer_sb2, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb2, sb); - sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - - return sb; -} - -void * -sb_mcv_init(UNUSED(const device_t *info)) -{ - /* SB1/2 port mappings, 210h to 260h in 10h steps - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - fm_driver_get(FM_YM3812, &sb->opl); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); - sb_dsp_setaddr(&sb->dsp, 0); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - - sb->mixer_enabled = 0; - sound_add_handler(sb_get_buffer_sb2, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb2, sb); - sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); - - /* I/O handlers activated in sb_mcv_write */ - mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb); - sb->pos_regs[0] = 0x84; - sb->pos_regs[1] = 0x50; - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - - return sb; -} - -void * -sb_2_init(UNUSED(const device_t *info)) -{ - /* SB2 port mappings, 220h or 240h. - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip - "CD version" also uses 250h or 260h for - 2x0 to 2x3 -> CDROM interface - 2x4 to 2x5 -> Mixer interface */ + /* SB1.x port mappings, 210h to 260h in 10h steps: + (SB2 port mappings are 220h or 240h) + 2x0 to 2x3 -> CMS chip + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip + SB2 "CD version" also uses 250h or 260h: + 2x0 to 2x3 -> CDROM interface + 2x4 to 2x5 -> Mixer interface */ /* My SB 2.0 mirrors the OPL2 at ports 2x0/2x1. Presumably this mirror is disabled when the CMS chips are present. This mirror may also exist on SB 1.5 & MCV, however I am unable to test this. It shouldn't exist on SB 1.0 as the CMS chips are always present there. Syndicate requires this mirror - for music to play.*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - uint16_t mixer_addr = device_get_config_int("mixaddr"); + for music to play. */ + sb_t *sb = calloc(1, sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); + uint16_t mixer_addr = 0x0000; + uint8_t model = 0; - memset(sb, 0, sizeof(sb_t)); + switch (info->local) { + default: + case SB_1: + model = SB_DSP_105; + sb->cms_enabled = 1; + break; + + case SB_15: + model = SB_DSP_200; + sb->cms_enabled = device_get_config_int("cms"); + break; + + case SB_2: + model = SB_DSP_201; + sb->cms_enabled = device_get_config_int("cms"); + mixer_addr = device_get_config_int("mixaddr"); + break; + } sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); + 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")); - if (mixer_addr > 0x000) + + if (mixer_addr > 0x0000) sb_ct1335_mixer_reset(sb); - sb->cms_enabled = device_get_config_int("cms"); /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { - if (!sb->cms_enabled) { + // TODO: See if this applies to the SB1.5 as well + if ((!sb->cms_enabled) && ((model == SB_DSP_201) || (model == SB_DSP_202))) { io_sethandler(addr, 0x0002, sb->opl.read, NULL, NULL, sb->opl.write, NULL, NULL, @@ -3019,6 +2903,7 @@ sb_2_init(UNUSED(const device_t *info)) sb); } else sb->mixer_enabled = 0; + sound_add_handler(sb_get_buffer_sb2, sb); if (sb->opl_enabled) music_add_handler(sb_get_music_buffer_sb2, sb); @@ -3030,6 +2915,41 @@ sb_2_init(UNUSED(const device_t *info)) return sb; } +void * +sb_mcv_init(UNUSED(const device_t *info)) +{ + /* SB1/2 port mappings, 210h to 260h in 10h steps + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip */ + sb_t *sb = calloc(1, sizeof(sb_t)); + + sb->opl_enabled = device_get_config_int("opl"); + if (sb->opl_enabled) + fm_driver_get(FM_YM3812, &sb->opl); + + sb_dsp_set_real_opl(&sb->dsp, 1); + sb_dsp_init(&sb->dsp, SB_DSP_105, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); + + sb->mixer_enabled = 0; + sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); + sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); + + /* I/O handlers activated in sb_mcv_write */ + mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb); + sb->pos_regs[0] = 0x84; + sb->pos_regs[1] = 0x50; + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + + return sb; +} + static uint8_t sb_pro_v1_opl_read(uint16_t port, void *priv) { @@ -3059,9 +2979,8 @@ sb_pro_v1_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) { @@ -3072,7 +2991,7 @@ sb_pro_v1_init(UNUSED(const device_t *info)) } sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO_DSP_300, 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")); @@ -3122,16 +3041,15 @@ sb_pro_v2_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, 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")); @@ -3176,14 +3094,13 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) 2x4 to 2x5 -> Mixer interface 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) */ - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; @@ -3205,13 +3122,12 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) static void * sb_pro_compat_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; @@ -3219,8 +3135,7 @@ sb_pro_compat_init(UNUSED(const device_t *info)) if (sb->opl_enabled) music_add_handler(sb_get_music_buffer_sbpro, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, 1); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3230,18 +3145,16 @@ sb_pro_compat_init(UNUSED(const device_t *info)) static void * sb_16_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); const uint16_t addr = device_get_config_hex16("base"); const uint16_t mpu_addr = device_get_config_hex16("base401"); - memset(sb, 0x00, sizeof(sb_t)); - sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get((int) (intptr_t) info->local, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32_DSP_413 : SB16_DSP_405, 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")); @@ -3277,8 +3190,7 @@ sb_16_init(UNUSED(const device_t *info)) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART, device_get_config_int("receive_input401")); } else @@ -3298,14 +3210,13 @@ sb_16_init(UNUSED(const device_t *info)) static void * sb_16_reply_mca_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0x00, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); @@ -3318,8 +3229,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3353,15 +3263,14 @@ sb_16_pnp_ide_available(void) static void * sb_16_pnp_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0x00, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); sb->pnp = 1; sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); @@ -3373,8 +3282,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3457,8 +3365,7 @@ sb_vibra16xv_available(void) static void * sb_vibra16_pnp_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0x00, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); sb->pnp = 1; @@ -3466,7 +3373,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, (info->local == SB_VIBRA16XV) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, (info->local == SB_VIBRA16XV) ? SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb); /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ sb_dsp_setdma16_supported(&sb->dsp, info->local != SB_VIBRA16XV); sb_ct1745_mixer_reset(sb); @@ -3479,8 +3386,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3558,13 +3464,12 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) static void * sb_16_compat_init(const device_t *info) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); @@ -3574,7 +3479,7 @@ sb_16_compat_init(const device_t *info) sound_add_handler(sb_get_buffer_sb16_awe32, sb); music_add_handler(sb_get_music_buffer_sb16_awe32, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + 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); @@ -3637,7 +3542,7 @@ sb_awe64_gold_available(void) static void * sb_awe32_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); uint16_t mpu_addr = device_get_config_hex16("base401"); uint16_t emu_addr = device_get_config_hex16("emu_base"); @@ -3650,7 +3555,7 @@ sb_awe32_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBAWE32_DSP_412, 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")); @@ -3687,7 +3592,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + 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")); @@ -3710,11 +3615,9 @@ sb_awe32_init(UNUSED(const device_t *info)) static void * sb_goldfinch_init(const device_t *info) { - goldfinch_t *goldfinch = malloc(sizeof(goldfinch_t)); + goldfinch_t *goldfinch = calloc(1, sizeof(goldfinch_t)); int onboard_ram = device_get_config_int("onboard_ram"); - memset(goldfinch, 0x00, sizeof(goldfinch_t)); - wavetable_add_handler(sb_get_wavetable_buffer_goldfinch, goldfinch); emu8k_init(&goldfinch->emu8k, 0, onboard_ram); @@ -3758,18 +3661,16 @@ sb_goldfinch_init(const device_t *info) static void * sb_awe32_pnp_init(const device_t *info) { - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); int onboard_ram = device_get_config_int("onboard_ram"); - memset(sb, 0x00, sizeof(sb_t)); - sb->pnp = 1; sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_init(&sb->dsp, (info->local >= SB_AWE64_VALUE) ? - SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); @@ -3783,8 +3684,7 @@ sb_awe32_pnp_init(const device_t *info) if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3903,7 +3803,7 @@ ess_x688_init(UNUSED(const device_t *info)) fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setaddr(&ess->dsp, addr); sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); @@ -4014,7 +3914,7 @@ ess_x688_pnp_init(UNUSED(const device_t *info)) fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); @@ -4100,7 +4000,7 @@ ess_x688_mca_init(UNUSED(const device_t *info)) fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); @@ -4211,7 +4111,8 @@ static const device_config_t sb_config[] = { }, { .description = "0x260", - .value = 0x260 }, + .value = 0x260 + }, { .description = "" } } }, @@ -4260,7 +4161,7 @@ static const device_config_t sb_config[] = { .description = "DMA 3", .value = 3 }, - { "" } + { .description = "" } } }, { @@ -4314,8 +4215,7 @@ static const device_config_t sb15_config[] = { .description = "0x260", .value = 0x260 }, - { - .description = "" } + { .description = "" } } }, { @@ -4408,10 +4308,6 @@ static const device_config_t sb2_config[] = { .description = "0x240", .value = 0x240 }, - { - .description = "0x260", - .value = 0x260 - }, { .description = "" } } }, @@ -4428,14 +4324,6 @@ static const device_config_t sb2_config[] = { .description = "Disabled", .value = 0 }, - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, { .description = "0x250", .value = 0x250 @@ -5769,8 +5657,8 @@ const device_t sb_1_device = { .name = "Sound Blaster v1.0", .internal_name = "sb", .flags = DEVICE_ISA, - .local = 0, - .init = sb_1_init, + .local = SB_1, + .init = sb_init, .close = sb_close, .reset = NULL, .available = NULL, @@ -5783,8 +5671,8 @@ const device_t sb_15_device = { .name = "Sound Blaster v1.5", .internal_name = "sb1.5", .flags = DEVICE_ISA, - .local = 0, - .init = sb_15_init, + .local = SB_15, + .init = sb_init, .close = sb_close, .reset = NULL, .available = NULL, @@ -5811,8 +5699,8 @@ const device_t sb_2_device = { .name = "Sound Blaster v2.0", .internal_name = "sb2.0", .flags = DEVICE_ISA, - .local = 0, - .init = sb_2_init, + .local = SB_2, + .init = sb_init, .close = sb_close, .reset = NULL, .available = NULL, diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 2cabde8cc..9ce0b9fb7 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -77,13 +77,33 @@ static int sb_commands[256] = { -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 }; +#if 0 +// Currently unused, here for reference if ever needed +char sb202_copyright[] = "COPYRIGHT(C) CREATIVE TECHNOLOGY PTE. LTD. (1991) " +#endif char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; -uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40c, 0x40d, 0x410 }; +uint16_t sb_dsp_versions[] = { + 0, /* Pad */ + 0, /* SADLIB - No DSP */ + 0x105, /* SB_DSP_105 - SB1/1.5, DSP v1.05 */ + 0x200, /* SB_DSP_200 - SB1.5/2, DSP v2.00 */ + 0x201, /* SB_DSP_201 - SB1.5/2, DSP v2.01 - needed for high-speed DMA */ + 0x202, /* SB_DSP_202 - SB2, DSP v2.02 */ + 0x300, /* SB_PRO_DSP_300 - SB Pro, DSP v3.00 */ + 0x302, /* SBPRO2_DSP_302 - SB Pro 2, DSP v3.02 + OPL3 */ + 0x404, /* SB16_DSP_404 - DSP v4.04 + OPL3 */ + 0x405, /* SB16_405 - DSP v4.05 + OPL3 */ + 0x406, /* SB16_406 - DSP v4.06 + OPL3 */ + 0x40b, /* SB16_411 - DSP v4.11 + OPL3 */ + 0x40c, /* SBAWE32 - DSP v4.12 + OPL3 */ + 0x40d, /* SBAWE32PNP - DSP v4.13 + OPL3 */ + 0x410 /* SBAWE64 - DSP v4.16 + OPL3 */ +}; /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 }; @@ -525,7 +545,7 @@ sb_doreset(sb_dsp_t *dsp) sb_commands[8] = 1; sb_commands[9] = 1; } else { - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) sb_commands[8] = 1; else sb_commands[8] = -1; @@ -1206,7 +1226,7 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the current DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_8051_ram[0x20] = dsp->sb_command; } @@ -1232,15 +1252,15 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_command) { case 0x01: /* ???? */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; break; case 0x03: /* ASP status */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) sb_add_data(dsp, 0); break; case 0x04: /* ASP set mode register */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_asp_mode = dsp->sb_data[0]; if (dsp->sb_asp_mode & 4) dsp->sb_asp_ram_index = 0; @@ -1248,7 +1268,7 @@ sb_exec_command(sb_dsp_t *dsp) } /* else DSP Status (Obsolete) */ break; case 0x05: /* ASP set codec parameter */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); } break; @@ -1278,9 +1298,9 @@ sb_exec_command(sb_dsp_t *dsp) sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ break; } - if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ + if (dsp->sb_type == SBAWE64_DSP_416) /* AWE64 has no ASP or a socket for it */ sb_add_data(dsp, 0xFF); - else if (dsp->sb_type >= SB16) + else if (dsp->sb_type >= SB16_DSP_404) sb_add_data(dsp, 0x18); break; case 0x09: /* AZTECH mode set */ @@ -1296,7 +1316,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x0E: /* ASP set register */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ @@ -1315,7 +1335,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x0F: /* ASP get register */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ if (dsp->sb_asp_mode & 8) dsp->sb_asp_ram_index = 0; @@ -1359,11 +1379,11 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x1C: /* 8-bit autoinit DMA output */ - if (dsp->sb_type >= SB15) + if (dsp->sb_type >= SB_DSP_200) sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x1F: /* 2-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { + if (dsp->sb_type >= SB_DSP_200) { sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; @@ -1388,7 +1408,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x28: /* Direct ADC, 8-bit (Burst) */ break; case 0x2C: /* 8-bit autoinit DMA input */ - if (dsp->sb_type >= SB15) + if (dsp->sb_type >= SB_DSP_200) sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); break; case 0x30: /* MIDI Polling mode input */ @@ -1405,7 +1425,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x33: /* MIDI Read Timestamp Interrupt */ break; case 0x34: /* MIDI In poll */ - if (dsp->sb_type < SB2) + if (dsp->sb_type < SB_DSP_200) break; sb_dsp_log("MIDI poll in\n"); dsp->midi_in_poll = 1; @@ -1413,7 +1433,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->uart_irq = 0; break; case 0x35: /* MIDI In irq */ - if (dsp->sb_type < SB2) + if (dsp->sb_type < SB_DSP_200) break; sb_dsp_log("MIDI irq in\n"); dsp->midi_in_poll = 0; @@ -1432,7 +1452,7 @@ sb_exec_command(sb_dsp_t *dsp) temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); - if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) + if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16_DSP_404)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; if (IS_ESS(dsp)) { @@ -1441,7 +1461,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x41: /* Set output sampling rate */ case 0x42: /* Set input sampling rate */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; @@ -1459,7 +1479,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x47: /* Continue Auto-Initialize DMA, 16-bit */ break; case 0x48: /* Set DSP block transfer size */ - dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); + if (dsp->sb_type >= SB_DSP_200) + dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); break; case 0x65: /* 4-bit ESPCM output with reference */ case 0x64: /* 4-bit ESPCM output */ @@ -1534,7 +1555,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x7D: /* 4-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { + if (dsp->sb_type >= SB_DSP_200) { sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; @@ -1542,7 +1563,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x7F: /* 2.6-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { + if (dsp->sb_type >= SB_DSP_200) { sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; @@ -1555,24 +1576,24 @@ sb_exec_command(sb_dsp_t *dsp) timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho)); break; case 0x90: /* High speed 8-bit autoinit DMA output */ - if (dsp->sb_type >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x91: /* High speed 8-bit single cycle DMA output */ - if (dsp->sb_type >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0x98: /* High speed 8-bit autoinit DMA input */ - if (dsp->sb_type >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x99: /* High speed 8-bit single cycle DMA input */ - if (dsp->sb_type >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0xA0: /* Set input mode to mono */ case 0xA8: /* Set input mode to stereo */ - if ((dsp->sb_type < SB2) || (dsp->sb_type > SBPRO2)) + if ((dsp->sb_type < SBPRO_DSP_300) || (dsp->sb_type > SBPRO2_DSP_302)) break; /* TODO: Implement. 3.xx-only command. */ break; @@ -1584,7 +1605,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xB5: case 0xB6: case 0xB7: /* 16-bit DMA output */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1598,7 +1619,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xBD: case 0xBE: case 0xBF: /* 16-bit DMA input */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1612,7 +1633,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xC5: case 0xC6: case 0xC7: /* 8-bit DMA output */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1626,7 +1647,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xCD: case 0xCE: case 0xCF: /* 8-bit DMA input */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1638,20 +1659,20 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xD1: /* Speaker on */ if (IS_NOT_ESS(dsp)) { - if (dsp->sb_type < SB15) { + if (dsp->sb_type < SB_DSP_200) { dsp->sb_8_pause = 1; sb_stop_dma(dsp); - } else if (dsp->sb_type < SB16) + } else if (dsp->sb_type < SB16_DSP_404) dsp->muted = 0; } dsp->sb_speaker = 1; break; case 0xD3: /* Speaker off */ if (IS_NOT_ESS(dsp)) { - if (dsp->sb_type < SB15) { + if (dsp->sb_type < SB_DSP_201) { dsp->sb_8_pause = 1; sb_stop_dma(dsp); - } else if (dsp->sb_type < SB16) + } else if (dsp->sb_type < SB16_DSP_404) dsp->muted = 1; } dsp->sb_speaker = 0; @@ -1661,26 +1682,28 @@ sb_exec_command(sb_dsp_t *dsp) sb_resume_dma(dsp, 1); break; case 0xD5: /* Pause 16-bit DMA */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_16_pause = 1; sb_stop_dma(dsp); } break; case 0xD6: /* Continue 16-bit DMA */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_16_pause = 0; sb_resume_dma(dsp, 1); } break; case 0xD8: /* Get speaker status */ - sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); + if (dsp->sb_type >= SB_DSP_200) + sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); break; case 0xD9: /* Exit 16-bit auto-init mode */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->sb_16_autoinit = 0; break; case 0xDA: /* Exit 8-bit auto-init mode */ - dsp->sb_8_autoinit = 0; + if (dsp->sb_type >= SB_DSP_200) + dsp->sb_8_autoinit = 0; break; case 0xE0: /* DSP identification */ sb_add_data(dsp, ~dsp->sb_data[0]); @@ -1721,7 +1744,7 @@ sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, dsp->sbe2); break; case 0xE3: /* DSP copyright */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { c = 0; while (sb16_copyright[c]) sb_add_data(dsp, sb16_copyright[c++]); @@ -1782,15 +1805,15 @@ sb_exec_command(sb_dsp_t *dsp) timer_set_delay_u64(&dsp->irq16_timer, (10ULL * TIMER_USEC)); break; case 0xF8: - if (dsp->sb_type < SB16) + if (dsp->sb_type < SB16_DSP_404) sb_add_data(dsp, 0); break; case 0xF9: /* SB16 8051 RAM read */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); break; case 0xFA: /* SB16 8051 RAM write */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; break; case 0xFF: /* No, that's not how you program auto-init DMA */ @@ -1800,11 +1823,24 @@ sb_exec_command(sb_dsp_t *dsp) * http://the.earth.li/~tfm/oldpage/sb_dsp.html * http://www.synchrondata.com/pheaven/www/area19.htm * http://www.dcee.net/Files/Programm/Sound/ - * 0E3h DSP Copyright SBPro2??? - * 0F0h Sine Generator SB - * 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 - * 0F2h IRQ Request, 8-bit SB + * https://github.com/schlae/sb-firmware/blob/master/sbv202.asm + * 008h Halt (Infinate Loop) SB2??? + * 018h DMA playback with auto init DMA. SB2??? + * 028h Auto-init direct ADC SB2??? + * 036h (Timestamp) SB??? + * 037h (Timestamp) SB??? + * 050h Stops playback of SRAM samples SB??? + * 051h Plays back samples stored in SRAM. SB??? + * 058h Load data into SRAM SB??? + * 059h Fetches the samples and then immediately plays them back. SB??? + * 078h Auto-init DMA ADPCM SB2??? + * 07Ah 2.6-bit ADPCM SB??? + * 0E3h DSP Copyright SBPro2??? (SBPRO2_DSP_302) + * 0F0h Sine Generator SB (SB_DSP_105, DSP20x) + * 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 (DSP20x, SBPRO2_DSP_302) + * 0F2h IRQ Request, 8-bit SB (SB_DSP_105, DSP20x) * 0F3h IRQ Request, 16-bit SB16 + * 0F4h Perform ROM checksum SB (SB_DSP_105, DSP20x) * 0FBh DSP Status SB16 * 0FCh DSP Auxiliary Status SB16 * 0FDh DSP Command Status SB16 @@ -1817,7 +1853,7 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the last DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->sb_8051_ram[0x30] = dsp->sb_command; } @@ -1836,31 +1872,31 @@ sb_do_reset(sb_dsp_t *dsp, const uint8_t v) } void -sb_write(uint16_t a, uint8_t v, void *priv) +sb_write(uint16_t addr, uint8_t val, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; - sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, a, v); + sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xE))) - a &= 0xfffe; + if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xE))) + addr &= 0xfffe; - switch (a & 0xF) { + switch (addr & 0xF) { case 6: /* Reset */ - sb_do_reset(dsp, v); + sb_do_reset(dsp, val); - if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) { + if (!(val & 2) && (dsp->espcm_fifo_reset & 2)) { fifo_reset(dsp->espcm_fifo); } - dsp->espcm_fifo_reset = v; + dsp->espcm_fifo_reset = val; dsp->uart_midi = 0; dsp->uart_irq = 0; dsp->onebyte_midi = 0; return; case 0xC: /* Command/data write */ if (dsp->uart_midi || dsp->onebyte_midi) { - midi_raw_out_byte(v); + midi_raw_out_byte(val); dsp->onebyte_midi = 0; return; } @@ -1873,8 +1909,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) return; } if (dsp->sb_data_stat == -1) { - dsp->sb_command = v; - if (v == 0x01) + dsp->sb_command = val; + if (val == 0x01) sb_add_data(dsp, 0); dsp->sb_data_stat++; if (IS_AZTECH(dsp)) { @@ -1901,7 +1937,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) } } } else { - dsp->sb_data[dsp->sb_data_stat++] = v; + dsp->sb_data[dsp->sb_data_stat++] = val; } if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { sb_exec_command(dsp); @@ -1920,17 +1956,17 @@ sb_write(uint16_t a, uint8_t v, void *priv) } uint8_t -sb_read(uint16_t a, void *priv) +sb_read(uint16_t addr, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xF))) + if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xF))) /* Exception: ESS AudioDrive does not alias port base+0xf */ - a &= 0xfffe; + addr &= 0xfffe; - switch (a & 0xf) { + switch (addr & 0xf) { case 0x6: if (IS_ESS(dsp)) { ret = (dsp->espcm_fifo_reset & 0x03) | 0x08 | (dsp->activity & 0xe0); @@ -1968,7 +2004,7 @@ sb_read(uint16_t a, void *priv) if (dsp->state == DSP_S_RESET_WAIT) dsp->state = DSP_S_NORMAL; if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) { - if (dsp->sb_8_enable || dsp->sb_type >= SB16) + if (dsp->sb_8_enable || dsp->sb_type >= SB16_DSP_404) dsp->busy_count = (dsp->busy_count + 1) & 3; else dsp->busy_count = 0; @@ -1993,7 +2029,7 @@ sb_read(uint16_t a, void *priv) ret = 0x80; } else { sb_dsp_log("SB Write Data Creative read 0xff\n"); - if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp)) ret = 0xaa; else ret = 0xff; @@ -2003,7 +2039,7 @@ sb_read(uint16_t a, void *priv) ret = 0x00; } else { sb_dsp_log("SB Write Data Creative read 0x7f\n"); - if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp)) ret = 0x2a; else ret = 0x7f; @@ -2027,7 +2063,7 @@ sb_read(uint16_t a, void *priv) ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; } else { sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff); - if ((dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + if ((dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp)) ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa; else ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; @@ -2138,11 +2174,11 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) /* Default values. Use sb_dsp_setxxx() methods to change. */ dsp->sb_irqnum = 7; dsp->sb_8_dmanum = 1; - if (type >= SB16) + if (type >= SB16_DSP_404) dsp->sb_16_dmanum = 5; else dsp->sb_16_dmanum = 0xff; - if ((type >= SB16) || IS_ESS(dsp)) + if ((type >= SB16_DSP_404) || IS_ESS(dsp)) dsp->sb_16_8_dmanum = 0x1; dsp->mpu = NULL; @@ -2174,7 +2210,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) a set frequency command is sent. */ recalc_sb16_filter(0, 3200 * 2); } - if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) { + if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2_DSP_302)) { /* OPL3 or dual OPL2 is stereo. */ if (dsp->sb_has_real_opl) recalc_opl_filter(FREQ_49716 * 2); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 810d403ab..0e51feae4 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -43,6 +43,11 @@ #include <86box/vid_ati_mach8.h> #include "cpu.h" +#ifdef CLAMP +# undef CLAMP +#endif + + #define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140_4k.BIN" static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv); @@ -68,6 +73,17 @@ ibm8514_log(const char *fmt, ...) # define ibm8514_log(fmt, ...) #endif +static int16_t +CLAMP(int16_t in, int16_t min, int16_t max) +{ + if (in < min) + return min; + if (in > max) + return max; + + return in; +} + #define WRITE8(addr, var, val) \ switch ((addr) & 1) { \ case 0: \ @@ -416,14 +432,6 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (len == 2) { dev->accel.short_stroke = val; - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cur_x >= 0x600) - dev->accel.cx |= ~0x5ff; - - dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_y >= 0x600) - dev->accel.cy |= ~0x5ff; - if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); @@ -969,6 +977,7 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t dev->accel.ssv_len = ssv & 0x0f; dev->accel.ssv_dir = ssv & 0xe0; dev->accel.ssv_draw = ssv & 0x10; + dev->accel.ssv_len_back = dev->accel.ssv_len; if (ibm8514_cpu_src(svga)) { dev->data_available = 0; @@ -1006,6 +1015,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint16_t bkgd_color = dev->accel.bkgd_color; uint32_t old_mix_dat; int and3 = dev->accel.cur_x & 3; + int poly_src; if (!dev->bpp) { compare &= 0xff; @@ -1121,13 +1131,24 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat old_mix_dat = mix_dat; + if (cmd == 5 || cmd == 1 || (cmd == 2 && (dev->accel.multifunc[0x0a] & 0x06))) + ibm8514_log("CMD=%d, full=%04x, pixcntl=%d, filling=%02x.\n", cmd, dev->accel.cmd, pixcntl, dev->accel.multifunc[0x0a] & 0x06); + /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ - if (dev->accel.ssv_state == 0) + if (dev->accel.ssv_state == 0) { + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + + dev->accel.cy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; break; + } if (dev->accel.cmd & 0x08) { while (count-- && dev->accel.ssv_len >= 0) { @@ -1289,7 +1310,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.ssv_len_back) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -1303,7 +1324,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cx--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.ssv_len_back) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -1454,6 +1475,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!dev->accel.sy) { dev->accel.cmd_back = 1; + if (!cpu_input) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } break; } @@ -1505,8 +1530,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy--; } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; dev->accel.x_count = 0; dev->accel.output = 0; } else { /*Bresenham Line*/ @@ -1580,7 +1603,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -1594,7 +1617,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cx--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -1673,6 +1696,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!dev->accel.sy) { dev->accel.cmd_back = 1; + if (!cpu_input) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } break; } @@ -1682,7 +1709,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -1696,7 +1723,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cx--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -1709,8 +1736,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy--; } } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; } break; @@ -2283,35 +2308,62 @@ skip_nibble_rect_write: } } } else if ((dev->accel.multifunc[0x0a] & 0x06) == 0x04) { /*Polygon Draw Type A*/ + ibm8514_log("Polygon Draw Type A: Clipping: L=%d, R=%d, T=%d, B=%d, C(%d,%d), sx=%d, sy=%d.\n", clip_l, clip_r, clip_t, clip_b, dev->accel.cx, dev->accel.cy, dev->accel.sx, dev->accel.sy); while (count-- && (dev->accel.sy >= 0)) { if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { - READ(dev->accel.dest + dev->accel.cx, mix_dat); - if ((mix_dat & rd_mask_polygon) == rd_mask_polygon) + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + case 3: + src_dat = 0; + break; + + default: + break; + } + + READ(dev->accel.dest + dev->accel.cx, poly_src); + if ((poly_src & rd_mask_polygon) == rd_mask_polygon) dev->accel.fill_state ^= 1; READ(dev->accel.dest + dev->accel.cx, dest_dat); + old_dest_dat = dest_dat; if (dev->accel.fill_state) { - if (!(rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) { - MIX(mix_dat ^ rd_mask_polygon, dest_dat, mix_dat); - ibm8514_log("Filling c(%d,%d) without bit 0 of rdmask=%02x, wrtmask=%02x, mixdat=%02x, dest=%02x, old=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, old_dest_dat); - dest_dat &= ~rd_mask_polygon; - } else if ((rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) { - ibm8514_log("Filling c(%d,%d) with bit 0 of rdmask=%02x, wrtmask=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask); - dest_dat &= ~(rd_mask_polygon & wrt_mask); + if (rd_mask_polygon & 0x01) { + if (wrt_mask & 0x01) { + dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State On, Write Mask 1, Read Mask 1.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } else { + if (wrt_mask & 0x01) { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat &= ~rd_mask_polygon; /*Fill State On, Write Mask 1, Read Mask 0.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } } } else { - if (!(rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) - dest_dat &= ~rd_mask_polygon; - else if ((rd_mask_polygon & 0x01) && (wrt_mask & 0x01)) - dest_dat &= ~(rd_mask_polygon & wrt_mask); + if (rd_mask_polygon & 0x01) { + if (wrt_mask & 0x01) { + dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State Off, Write Mask 1, Read Mask 1.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } else { + if (wrt_mask & 0x01) { + dest_dat &= ~rd_mask_polygon; /*Fill State Off, Write Mask 1, Read Mask 0.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } } - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || @@ -2322,7 +2374,11 @@ skip_nibble_rect_write: ibm8514_log("Results c(%d,%d):rdmask=%02x, wrtmask=%02x, mix=%02x, destdat=%02x, nowrite=%d.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, dev->accel.cx_back); WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } - } + } else + ibm8514_log("Out of bounds DrawA C(%d,%d).\n", dev->accel.cx, dev->accel.cy); + + mix_dat <<= 1; + mix_dat |= 1; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2356,6 +2412,8 @@ skip_nibble_rect_write: if (dev->accel.sy < 0) { ibm8514_log(".\n"); dev->accel.cmd_back = 1; + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; return; } } @@ -2468,7 +2526,7 @@ skip_nibble_rect_write: else dev->accel.oldcy = dev->accel.cy - 1; - ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.multifunc[2], dev->accel.multifunc[4], dev->accel.clip_top, clip_b, dev->accel.multifunc[0x0a]); + ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, clip_l, clip_r, clip_t, clip_b, dev->accel.multifunc[0x0a]); if (ibm8514_cpu_src(svga)) { dev->data_available = 0; @@ -2483,8 +2541,7 @@ skip_nibble_rect_write: if (dev->accel.cmd & 0x08) { /*Vectored Boundary Line*/ while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx < clip_l) - dev->accel.cx = clip_l; + dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r); if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && @@ -2591,11 +2648,10 @@ skip_nibble_rect_write: } } else { /*Vectored Bresenham*/ while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx < clip_l) - dev->accel.cx = clip_l; + dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r); if ((dev->accel.cx >= clip_l) && - (dev->accel.cx <= clip_r) && + (dev->accel.cx < clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -2658,7 +2714,7 @@ skip_nibble_rect_write: else dev->accel.cy--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2673,7 +2729,7 @@ skip_nibble_rect_write: dev->accel.cx--; dev->accel.oldcy = dev->accel.cy; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x80) dev->accel.cy++; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 4e7d1ac09..bc54d0d7c 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1361,7 +1361,7 @@ gd54xx_in(uint16_t addr, void *priv) 32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width for 2M of memory */ - ret |= (gd54xx_is_5434(svga)) ? 0x98 : 0x18; + ret |= 0x18; break; case 4096: ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/ @@ -2281,6 +2281,9 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + val = (val >> 8) | (val << 8); + gd54xx_write(addr, val, gd54xx); gd54xx_write(addr + 1, val >> 8, gd54xx); return; @@ -2308,6 +2311,9 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + gd54xx_write(addr, val, gd54xx); gd54xx_write(addr + 1, val >> 8, gd54xx); gd54xx_write(addr + 2, val >> 16, gd54xx); @@ -3661,9 +3667,6 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) mask_shift = 31 - byte_pos; if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) cpu_dat >>= byte_pos; - else if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) - cpu_dat = ((cpu_dat & 0xff000000) >> 24) | ((cpu_dat & 0x00ff0000) >> 8) | - ((cpu_dat & 0x0000ff00) << 8) | ((cpu_dat & 0x000000ff) << 24); } else mask_shift = 7; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index abb2d70aa..bb5c283ad 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -273,6 +273,7 @@ typedef struct s3_t { int dat_count; int b2e8_pix, temp_cnt; int ssv_len; + int ssv_len_back; uint8_t ssv_dir; uint8_t ssv_draw; uint8_t dat_buf_16bit; @@ -511,7 +512,7 @@ s3_update_irqs(s3_t *s3) } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv); -void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv); +void s3_short_stroke_start(s3_t *s3, uint8_t ssv); static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); #define WRITE8(addr, var, val) \ @@ -922,15 +923,12 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cmd & 0x1000) { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); } else { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); } break; @@ -1787,15 +1785,12 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) s3->accel.short_stroke = val; s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cmd & 0x1000) { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); } else { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); } } } @@ -7823,19 +7818,16 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) } void -s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) +s3_short_stroke_start(s3_t *s3, uint8_t ssv) { - if (!cpu_input) { - s3->accel.ssv_len = ssv & 0x0f; - s3->accel.ssv_dir = ssv & 0xe0; - s3->accel.ssv_draw = ssv & 0x10; + s3->accel.ssv_len = ssv & 0x0f; + s3->accel.ssv_dir = ssv & 0xe0; + s3->accel.ssv_draw = !!(ssv & 0x10); - if (s3_cpu_src(s3)) { - return; /*Wait for data from CPU*/ - } - } + if (s3_cpu_src(s3)) + return; /*Wait for data from CPU*/ - s3->accel_start(count, cpu_input, mix_dat, cpu_dat, s3); + s3->accel_start(-1, 0, -1, 0, s3); } void @@ -7978,11 +7970,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ - if (s3->accel.ssv_state == 0) + if (s3->accel.ssv_state == 0) { + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; break; + } - if (s3->accel.cmd & 0x08) /*Radial*/ - { + if (s3->accel.cmd & 0x08) { /*Radial*/ while (count-- && s3->accel.ssv_len >= 0) { if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -8036,8 +8030,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi else cpu_dat >>= 16; - if (!s3->accel.ssv_len) + if (!s3->accel.ssv_len) { + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; break; + } switch (s3->accel.ssv_dir & 0xe0) { case 0x00: @@ -8077,9 +8074,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; } - - s3->accel.cur_x = s3->accel.cx & 0xfff; - s3->accel.cur_y = s3->accel.cy & 0xfff; } break; @@ -8270,7 +8264,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi else s3->accel.cy--; - if (s3->accel.err_term >= 0) { + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { s3->accel.err_term += s3->accel.destx_distp; if (s3->accel.cmd & 0x20) s3->accel.cx++; @@ -8284,7 +8278,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi else s3->accel.cx--; - if (s3->accel.err_term >= 0) { + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { s3->accel.err_term += s3->accel.destx_distp; if (s3->accel.cmd & 0x80) s3->accel.cy++;