Merge branch '86Box:master' into master

This commit is contained in:
starfrost
2025-01-11 00:11:51 +00:00
committed by GitHub
24 changed files with 1004 additions and 661 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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;

View File

@@ -13,10 +13,12 @@
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* 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 <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -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;
}

View File

@@ -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)
{

View File

@@ -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, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2016-2020 Miran Grca.
* Copyright 2008-2020 Sarah Walker.
* Copyright 2025 Jasmine Iwanek.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -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

View File

@@ -15,9 +15,11 @@
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2025 Jasmine Iwanek.
*/
#include <stdio.h>
#include <stdint.h>
@@ -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,

View File

@@ -160,6 +160,7 @@ SettingsPorts::on_pushButtonSerialPassThru4_clicked()
DeviceConfig::ConfigureDevice(&serial_passthrough_device, 4, qobject_cast<Settings *>(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::settings));
}
#endif
void
SettingsPorts::on_checkBoxSerialPassThru1_clicked(bool checked)
@@ -220,4 +222,4 @@ SettingsPorts::on_checkBoxSerialPassThru7_clicked(bool checked)
{
ui->pushButtonSerialPassThru7->setEnabled(checked);
}
#endif
#endif

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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:

View File

@@ -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);

View File

@@ -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"));

View File

@@ -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,

View File

@@ -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);

View File

@@ -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++;

View File

@@ -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;

View File

@@ -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++;