Game port overhaul
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* VARCem Virtual ARchaeological Computer EMulator.
|
||||
* An emulator of (mostly) x86-based PC systems and devices,
|
||||
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
|
||||
* spanning the era between 1981 and 1995.
|
||||
* 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 VARCem Project.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of a generic Game Port.
|
||||
*
|
||||
@@ -12,27 +12,11 @@
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the:
|
||||
*
|
||||
* Free Software Foundation, Inc.
|
||||
* 59 Temple Place - Suite 330
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
* Copyright 2021 RichardG.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -45,6 +29,7 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/isapnp.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/joystick_ch_flightstick_pro.h>
|
||||
#include <86box/joystick_standard.h>
|
||||
@@ -55,21 +40,25 @@
|
||||
typedef struct {
|
||||
pc_timer_t timer;
|
||||
int axis_nr;
|
||||
struct _gameport_ *gameport;
|
||||
struct _joystick_instance_ *joystick;
|
||||
} g_axis_t;
|
||||
|
||||
typedef struct _gameport_ {
|
||||
uint8_t state;
|
||||
uint16_t addr;
|
||||
|
||||
g_axis_t axis[4];
|
||||
|
||||
const joystick_if_t *joystick;
|
||||
void *joystick_dat;
|
||||
struct _joystick_instance_ *joystick;
|
||||
struct _gameport_ *next;
|
||||
} gameport_t;
|
||||
|
||||
typedef struct _joystick_instance_ {
|
||||
uint8_t state;
|
||||
g_axis_t axis[4];
|
||||
|
||||
int joystick_type = 0;
|
||||
const joystick_if_t *intf;
|
||||
void *dat;
|
||||
} joystick_instance_t;
|
||||
|
||||
|
||||
int joystick_type = 1;
|
||||
|
||||
|
||||
static const joystick_if_t joystick_none = {
|
||||
@@ -101,22 +90,54 @@ static const struct {
|
||||
{ "thrustmaster_fcs", &joystick_tm_fcs },
|
||||
{ "", NULL }
|
||||
};
|
||||
static gameport_t *gameport_global = NULL;
|
||||
static joystick_instance_t *joystick_instance = NULL;
|
||||
|
||||
|
||||
static uint8_t gameport_pnp_rom[] = {
|
||||
0x09, 0xf8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* BOX0002, dummy checksum (filled in by isapnp_add_card) */
|
||||
0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */
|
||||
0x82, 0x09, 0x00, 'G', 'a', 'm', 'e', ' ', 'P', 'o', 'r', 't', /* ANSI identifier */
|
||||
|
||||
0x15, 0x09, 0xf8, 0x00, 0x02, 0x01, /* logical device BOX0002, can participate in boot */
|
||||
0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */
|
||||
0x31, 0x00, /* start dependent functions, preferred */
|
||||
0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x08, 0x08, /* I/O 0x200, decodes 16-bit, 8-byte alignment, 8 addresses */
|
||||
0x30, /* start dependent functions, acceptable */
|
||||
0x47, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x08, /* I/O 0x208, decodes 16-bit, 8-byte alignment, 8 addresses */
|
||||
0x31, 0x02, /* start dependent functions, sub-optimal */
|
||||
0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */
|
||||
0x38, /* end dependent functions */
|
||||
|
||||
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
|
||||
};
|
||||
static const isapnp_device_config_t gameport_pnp_defaults[] = {
|
||||
{
|
||||
.activate = 1,
|
||||
.io = { { .base = 0x200 }, }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const device_t *standalone_gameport_type;
|
||||
static int gameport_instance_id = 0;
|
||||
/* Linked list of active game ports. Only the top port responds to reads
|
||||
or writes, and ports at the standard 200h location are prioritized. */
|
||||
static gameport_t *active_gameports = NULL;
|
||||
|
||||
|
||||
char *
|
||||
joystick_get_name(int js)
|
||||
{
|
||||
if (! joysticks[js].joystick)
|
||||
return(NULL);
|
||||
return((char *)joysticks[js].joystick->name);
|
||||
if (!joysticks[js].joystick)
|
||||
return NULL;
|
||||
return (char *) joysticks[js].joystick->name;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
joystick_get_internal_name(int js)
|
||||
{
|
||||
return((char *) joysticks[js].internal_name);
|
||||
return (char *) joysticks[js].internal_name;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,8 +146,7 @@ joystick_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (strlen((char *) joysticks[c].internal_name))
|
||||
{
|
||||
while (strlen((char *) joysticks[c].internal_name)) {
|
||||
if (!strcmp((char *) joysticks[c].internal_name, s))
|
||||
return c;
|
||||
c++;
|
||||
@@ -139,62 +159,63 @@ joystick_get_from_internal_name(char *s)
|
||||
int
|
||||
joystick_get_max_joysticks(int js)
|
||||
{
|
||||
return(joysticks[js].joystick->max_joysticks);
|
||||
return joysticks[js].joystick->max_joysticks;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
joystick_get_axis_count(int js)
|
||||
{
|
||||
return(joysticks[js].joystick->axis_count);
|
||||
return joysticks[js].joystick->axis_count;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
joystick_get_button_count(int js)
|
||||
{
|
||||
return(joysticks[js].joystick->button_count);
|
||||
return joysticks[js].joystick->button_count;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
joystick_get_pov_count(int js)
|
||||
{
|
||||
return(joysticks[js].joystick->pov_count);
|
||||
return joysticks[js].joystick->pov_count;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
joystick_get_axis_name(int js, int id)
|
||||
{
|
||||
return((char *)joysticks[js].joystick->axis_names[id]);
|
||||
return (char *) joysticks[js].joystick->axis_names[id];
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
joystick_get_button_name(int js, int id)
|
||||
{
|
||||
return((char *)joysticks[js].joystick->button_names[id]);
|
||||
return (char *) joysticks[js].joystick->button_names[id];
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
joystick_get_pov_name(int js, int id)
|
||||
{
|
||||
return (char *)joysticks[js].joystick->pov_names[id];
|
||||
return (char *) joysticks[js].joystick->pov_names[id];
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gameport_time(gameport_t *gameport, int nr, int axis)
|
||||
gameport_time(joystick_instance_t *joystick, int nr, int axis)
|
||||
{
|
||||
if (axis == AXIS_NOT_PRESENT)
|
||||
timer_disable(&gameport->axis[nr].timer);
|
||||
timer_disable(&joystick->axis[nr].timer);
|
||||
else {
|
||||
/* Convert axis value to 555 timing. */
|
||||
axis += 32768;
|
||||
axis = (axis * 100) / 65; /*Axis now in ohms*/
|
||||
axis = (axis * 100) / 65; /* axis now in ohms */
|
||||
axis = (axis * 11) / 1000;
|
||||
timer_set_delay_u64(&gameport->axis[nr].timer, TIMER_USEC * (axis + 24)); /*max = 11.115 ms*/
|
||||
timer_set_delay_u64(&joystick->axis[nr].timer, TIMER_USEC * (axis + 24)); /* max = 11.115 ms */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,16 +223,23 @@ gameport_time(gameport_t *gameport, int nr, int axis)
|
||||
static void
|
||||
gameport_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
gameport_t *p = (gameport_t *)priv;
|
||||
gameport_t *dev = (gameport_t *) priv;
|
||||
joystick_instance_t *joystick = dev->joystick;
|
||||
|
||||
p->state |= 0x0f;
|
||||
/* Respond only if a joystick is present and this port is at the top of the active ports list. */
|
||||
if (!joystick || (active_gameports != dev))
|
||||
return;
|
||||
|
||||
gameport_time(p, 0, p->joystick->read_axis(p->joystick_dat, 0));
|
||||
gameport_time(p, 1, p->joystick->read_axis(p->joystick_dat, 1));
|
||||
gameport_time(p, 2, p->joystick->read_axis(p->joystick_dat, 2));
|
||||
gameport_time(p, 3, p->joystick->read_axis(p->joystick_dat, 3));
|
||||
|
||||
p->joystick->write(p->joystick_dat);
|
||||
/* Read all axes. */
|
||||
joystick->state |= 0x0f;
|
||||
|
||||
gameport_time(joystick, 0, joystick->intf->read_axis(joystick->dat, 0));
|
||||
gameport_time(joystick, 1, joystick->intf->read_axis(joystick->dat, 1));
|
||||
gameport_time(joystick, 2, joystick->intf->read_axis(joystick->dat, 2));
|
||||
gameport_time(joystick, 3, joystick->intf->read_axis(joystick->dat, 3));
|
||||
|
||||
/* Notify the interface. */
|
||||
joystick->intf->write(joystick->dat);
|
||||
|
||||
cycles -= ISA_CYCLES(8);
|
||||
}
|
||||
@@ -220,114 +248,184 @@ gameport_write(uint16_t addr, uint8_t val, void *priv)
|
||||
static uint8_t
|
||||
gameport_read(uint16_t addr, void *priv)
|
||||
{
|
||||
gameport_t *p = (gameport_t *)priv;
|
||||
uint8_t ret;
|
||||
gameport_t *dev = (gameport_t *) priv;
|
||||
joystick_instance_t *joystick = dev->joystick;
|
||||
|
||||
ret = p->state | p->joystick->read(p->joystick_dat);
|
||||
/* Respond only if a joystick is present and this port is at the top of the active ports list. */
|
||||
if (!joystick || (active_gameports != dev))
|
||||
return 0xff;
|
||||
|
||||
/* Merge axis state with button state. */
|
||||
uint8_t ret = joystick->state | joystick->intf->read(joystick->dat);
|
||||
|
||||
cycles -= ISA_CYCLES(8);
|
||||
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
timer_over(void *priv)
|
||||
{
|
||||
g_axis_t *axis = (g_axis_t *)priv;
|
||||
gameport_t *p = axis->gameport;
|
||||
g_axis_t *axis = (g_axis_t *) priv;
|
||||
|
||||
p->state &= ~(1 << axis->axis_nr);
|
||||
axis->joystick->state &= ~(1 << axis->axis_nr);
|
||||
|
||||
if (axis == &p->axis[0])
|
||||
p->joystick->a0_over(p->joystick_dat);
|
||||
if (axis == &axis->joystick->axis[0])
|
||||
axis->joystick->intf->a0_over(axis->joystick->dat);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gameport_update_joystick_type(void)
|
||||
{
|
||||
gameport_t *p = gameport_global;
|
||||
/* Add a standalone game port if a joystick is enabled but no other game ports exist. */
|
||||
if (standalone_gameport_type)
|
||||
gameport_add(standalone_gameport_type);
|
||||
|
||||
if (p != NULL) {
|
||||
p->joystick->close(p->joystick_dat);
|
||||
p->joystick = joysticks[joystick_type].joystick;
|
||||
p->joystick_dat = p->joystick->init();
|
||||
/* Reset the joystick interface. */
|
||||
if (joystick_instance) {
|
||||
joystick_instance->intf->close(joystick_instance->dat);
|
||||
joystick_instance->intf = joysticks[joystick_type].joystick;
|
||||
joystick_instance->dat = joystick_instance->intf->init();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gameport_remap(uint16_t address)
|
||||
gameport_remap(void *priv, uint16_t address)
|
||||
{
|
||||
gameport_t *p = gameport_global;
|
||||
if (!p)
|
||||
gameport_t *dev = (gameport_t *) priv, *other_dev;
|
||||
|
||||
if (dev->addr) {
|
||||
/* Remove this port from the active ports list. */
|
||||
if (active_gameports == dev) {
|
||||
active_gameports = dev->next;
|
||||
dev->next = NULL;
|
||||
} else {
|
||||
other_dev = active_gameports;
|
||||
while (other_dev) {
|
||||
if (other_dev->next == dev) {
|
||||
other_dev->next = dev->next;
|
||||
dev->next = NULL;
|
||||
break;
|
||||
}
|
||||
other_dev = other_dev->next;
|
||||
}
|
||||
}
|
||||
|
||||
io_removehandler(dev->addr, (dev->addr & 1) ? 1 : 8,
|
||||
gameport_read, NULL, NULL, gameport_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
dev->addr = address;
|
||||
|
||||
if (dev->addr) {
|
||||
/* Add this port to the active ports list. */
|
||||
if ((dev->addr & 0xfff8) == 0x200) {
|
||||
/* Port within 200-207h: add to top. */
|
||||
dev->next = active_gameports;
|
||||
active_gameports = dev;
|
||||
} else {
|
||||
/* Port at other addresses: add to bottom. */
|
||||
other_dev = active_gameports;
|
||||
while (other_dev->next)
|
||||
other_dev = other_dev->next;
|
||||
other_dev->next = dev;
|
||||
}
|
||||
|
||||
io_sethandler(dev->addr, (dev->addr & 1) ? 1 : 8,
|
||||
gameport_read, NULL, NULL, gameport_write, NULL, NULL, dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gameport_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
||||
{
|
||||
if (ld > 0)
|
||||
return;
|
||||
|
||||
if (p->addr)
|
||||
io_removehandler(p->addr, (p->addr & 1) ? 1 : 8,
|
||||
gameport_read, NULL, NULL, gameport_write, NULL, NULL, p);
|
||||
gameport_t *dev = (gameport_t *) priv;
|
||||
|
||||
p->addr = address;
|
||||
/* Remap the game port to the specified address, or disable it. */
|
||||
gameport_remap(dev, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0);
|
||||
}
|
||||
|
||||
if (p->addr)
|
||||
io_sethandler(p->addr, (p->addr & 1) ? 1 : 8,
|
||||
gameport_read, NULL, NULL, gameport_write, NULL, NULL, p);
|
||||
|
||||
void *
|
||||
gameport_add(const device_t *gameport_type)
|
||||
{
|
||||
/* Prevent a standalone game port from being added later on. */
|
||||
standalone_gameport_type = NULL;
|
||||
|
||||
/* Add game port device. */
|
||||
return device_add_inst(gameport_type, gameport_instance_id++);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
gameport_init(const device_t *info)
|
||||
{
|
||||
gameport_t *p = NULL;
|
||||
gameport_t *dev = NULL;
|
||||
|
||||
if (!joystick_type) {
|
||||
gameport_global = p = NULL;
|
||||
return(p);
|
||||
dev = malloc(sizeof(gameport_t));
|
||||
memset(dev, 0x00, sizeof(gameport_t));
|
||||
|
||||
/* Allocate global instance. */
|
||||
if (!joystick_instance && joystick_type) {
|
||||
joystick_instance = malloc(sizeof(joystick_instance_t));
|
||||
memset(joystick_instance, 0x00, sizeof(joystick_instance_t));
|
||||
|
||||
joystick_instance->axis[0].joystick = joystick_instance;
|
||||
joystick_instance->axis[1].joystick = joystick_instance;
|
||||
joystick_instance->axis[2].joystick = joystick_instance;
|
||||
joystick_instance->axis[3].joystick = joystick_instance;
|
||||
|
||||
joystick_instance->axis[0].axis_nr = 0;
|
||||
joystick_instance->axis[1].axis_nr = 1;
|
||||
joystick_instance->axis[2].axis_nr = 2;
|
||||
joystick_instance->axis[3].axis_nr = 3;
|
||||
|
||||
timer_add(&joystick_instance->axis[0].timer, timer_over, &joystick_instance->axis[0], 0);
|
||||
timer_add(&joystick_instance->axis[1].timer, timer_over, &joystick_instance->axis[1], 0);
|
||||
timer_add(&joystick_instance->axis[2].timer, timer_over, &joystick_instance->axis[2], 0);
|
||||
timer_add(&joystick_instance->axis[3].timer, timer_over, &joystick_instance->axis[3], 0);
|
||||
|
||||
joystick_instance->intf = joysticks[joystick_type].joystick;
|
||||
joystick_instance->dat = joystick_instance->intf->init();
|
||||
}
|
||||
|
||||
p = malloc(sizeof(gameport_t));
|
||||
dev->joystick = joystick_instance;
|
||||
|
||||
memset(p, 0x00, sizeof(gameport_t));
|
||||
/* Map game port to the default address. Not applicable on PnP-only ports. */
|
||||
gameport_remap(dev, info->local);
|
||||
|
||||
p->axis[0].gameport = p;
|
||||
p->axis[1].gameport = p;
|
||||
p->axis[2].gameport = p;
|
||||
p->axis[3].gameport = p;
|
||||
/* Register ISAPnP if this is a standard game port card. */
|
||||
if (info->local == 0x200)
|
||||
isapnp_set_device_defaults(isapnp_add_card(gameport_pnp_rom, sizeof(gameport_pnp_rom), gameport_pnp_config_changed, NULL, NULL, NULL, dev), 0, gameport_pnp_defaults);
|
||||
|
||||
p->axis[0].axis_nr = 0;
|
||||
p->axis[1].axis_nr = 1;
|
||||
p->axis[2].axis_nr = 2;
|
||||
p->axis[3].axis_nr = 3;
|
||||
|
||||
timer_add(&p->axis[0].timer, timer_over, &p->axis[0], 0);
|
||||
timer_add(&p->axis[1].timer, timer_over, &p->axis[1], 0);
|
||||
timer_add(&p->axis[2].timer, timer_over, &p->axis[2], 0);
|
||||
timer_add(&p->axis[3].timer, timer_over, &p->axis[3], 0);
|
||||
|
||||
p->joystick = joysticks[joystick_type].joystick;
|
||||
p->joystick_dat = p->joystick->init();
|
||||
|
||||
gameport_global = p;
|
||||
|
||||
gameport_remap(info->local);
|
||||
|
||||
return(p);
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gameport_close(void *priv)
|
||||
{
|
||||
gameport_t *p = (gameport_t *)priv;
|
||||
gameport_t *dev = (gameport_t *) priv;
|
||||
|
||||
if (p == NULL) return;
|
||||
/* If this port was active, remove it from the active ports list. */
|
||||
gameport_remap(dev, 0);
|
||||
|
||||
p->joystick->close(p->joystick_dat);
|
||||
/* Free the global instance here, if it wasn't already freed. */
|
||||
if (joystick_instance) {
|
||||
joystick_instance->intf->close(joystick_instance->dat);
|
||||
|
||||
gameport_global = NULL;
|
||||
free(joystick_instance);
|
||||
joystick_instance = NULL;
|
||||
}
|
||||
|
||||
free(p);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -348,3 +446,12 @@ const device_t gameport_201_device = {
|
||||
NULL, { NULL }, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t gameport_pnp_device = {
|
||||
"Game port (Plug and Play only)",
|
||||
0, 0,
|
||||
gameport_init,
|
||||
gameport_close,
|
||||
NULL, { NULL }, NULL,
|
||||
NULL
|
||||
};
|
||||
|
@@ -1,40 +1,22 @@
|
||||
/*
|
||||
* VARCem Virtual ARchaeological Computer EMulator.
|
||||
* An emulator of (mostly) x86-based PC systems and devices,
|
||||
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
|
||||
* spanning the era between 1981 and 1995.
|
||||
* 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 VARCem Project.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Definitions for the generic game port handlers.
|
||||
*
|
||||
* NOTE: This module needs a good cleanup someday.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the:
|
||||
*
|
||||
* Free Software Foundation, Inc.
|
||||
* 59 Temple Place - Suite 330
|
||||
* Boston, MA 02111-1307
|
||||
* USA.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2021 RichardG.
|
||||
*/
|
||||
#ifndef EMU_GAMEPORT_H
|
||||
# define EMU_GAMEPORT_H
|
||||
@@ -125,8 +107,10 @@ extern "C" {
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern const device_t gameport_device;
|
||||
extern const device_t gameport_201_device;
|
||||
#endif
|
||||
extern const device_t gameport_pnp_device;
|
||||
|
||||
extern const device_t *standalone_gameport_type;
|
||||
#endif
|
||||
extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
|
||||
extern joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
extern int joysticks_present;
|
||||
@@ -150,7 +134,8 @@ extern char *joystick_get_button_name(int js, int id);
|
||||
extern char *joystick_get_pov_name(int js, int id);
|
||||
|
||||
extern void gameport_update_joystick_type(void);
|
||||
extern void gameport_remap(uint16_t address);
|
||||
extern void gameport_remap(void *priv, uint16_t address);
|
||||
extern void *gameport_add(const device_t *gameport_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -122,6 +122,7 @@ typedef struct sb_t
|
||||
};
|
||||
mpu_t *mpu;
|
||||
emu8k_t emu8k;
|
||||
void *gameport;
|
||||
|
||||
int pos;
|
||||
|
||||
|
@@ -2516,8 +2516,7 @@ machine_amstrad_init(const machine_t *model, int type)
|
||||
mouse_set_poll(ms_poll, ams);
|
||||
}
|
||||
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -74,8 +74,7 @@ machine_at_common_init_ex(const machine_t *model, int type)
|
||||
else if (type == 0)
|
||||
device_add(&at_nvr_device);
|
||||
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -516,8 +516,7 @@ ps1_common_init(const machine_t *model)
|
||||
device_add(&keyboard_ps2_ps1_device);
|
||||
|
||||
/* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */
|
||||
if (joystick_type)
|
||||
device_add(&gameport_201_device);
|
||||
standalone_gameport_type = &gameport_201_device;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1541,8 +1541,7 @@ machine_tandy1k_init(const machine_t *model, int type)
|
||||
break;
|
||||
}
|
||||
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
eep_data_out = 0x0000;
|
||||
}
|
||||
|
@@ -30,8 +30,7 @@ machine_xt_common_init(const machine_t *model)
|
||||
device_add(&fdc_xt_device);
|
||||
|
||||
nmi_init();
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -56,8 +56,7 @@ machine_xt_compaq_deskpro_init(const machine_t *model)
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_xt_device);
|
||||
nmi_init();
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
lpt1_remove();
|
||||
lpt1_init(0x03bc);
|
||||
|
@@ -174,8 +174,7 @@ machine_xt_lxt3_init(const machine_t *model)
|
||||
if (fdc_type == FDC_INTERNAL)
|
||||
device_add(&fdc_xt_device);
|
||||
nmi_init();
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
laserxt_init(1);
|
||||
|
||||
|
@@ -738,8 +738,7 @@ machine_xt_m24_init(const machine_t *model)
|
||||
/* FIXME: make sure this is correct?? */
|
||||
device_add(&at_nvr_device);
|
||||
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
nmi_init();
|
||||
|
||||
|
@@ -155,8 +155,7 @@ machine_xt_philips_common_init(const machine_t *model)
|
||||
|
||||
nmi_init();
|
||||
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
device_add(&keyboard_pc_device);
|
||||
|
||||
|
@@ -181,8 +181,7 @@ machine_xt_xi8088_init(const machine_t *model)
|
||||
nmi_init();
|
||||
device_add(&ibmat_nvr_device);
|
||||
pic2_init();
|
||||
if (joystick_type)
|
||||
device_add(&gameport_device);
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <86box/rom.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/serial.h>
|
||||
#include <86box/gameport.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/video.h>
|
||||
#include <86box/machine.h>
|
||||
@@ -74,6 +75,7 @@ machine_init_ex(int m)
|
||||
machine_log("Initializing as \"%s\"\n", machine_getname());
|
||||
|
||||
is_vpc = 0;
|
||||
standalone_gameport_type = NULL;
|
||||
|
||||
/* Set up the architecture flags. */
|
||||
AT = IS_AT(machine);
|
||||
|
@@ -117,14 +117,15 @@ um8669f_log(const char *fmt, ...)
|
||||
|
||||
typedef struct um8669f_t
|
||||
{
|
||||
int locked, cur_reg_108;
|
||||
void *pnp_card;
|
||||
int locked, cur_reg_108;
|
||||
void *pnp_card;
|
||||
isapnp_device_config_t *pnp_config[5];
|
||||
|
||||
uint8_t regs_108[256];
|
||||
uint8_t regs_108[256];
|
||||
|
||||
fdc_t *fdc;
|
||||
serial_t *uart[2];
|
||||
fdc_t *fdc;
|
||||
serial_t *uart[2];
|
||||
void *gameport;
|
||||
} um8669f_t;
|
||||
|
||||
|
||||
@@ -179,13 +180,13 @@ um8669f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri
|
||||
break;
|
||||
|
||||
case 5:
|
||||
gameport_remap(0);
|
||||
|
||||
if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) {
|
||||
um8669f_log("UM8669F: Game port enabled at port %04X\n", config->io[0].base);
|
||||
gameport_remap(config->io[0].base);
|
||||
} else
|
||||
gameport_remap(dev->gameport, config->io[0].base);
|
||||
} else {
|
||||
um8669f_log("UM8669F: Game port disabled\n");
|
||||
gameport_remap(dev->gameport, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,6 +287,8 @@ um8669f_init(const device_t *info)
|
||||
dev->uart[0] = device_add_inst(&ns16550_device, 1);
|
||||
dev->uart[1] = device_add_inst(&ns16550_device, 2);
|
||||
|
||||
dev->gameport = gameport_add(&gameport_pnp_device);
|
||||
|
||||
io_sethandler(0x0108, 0x0002,
|
||||
um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, dev);
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/mem.h>
|
||||
@@ -1352,13 +1353,16 @@ static void *es1371_init(const device_t *info)
|
||||
sound_add_handler(es1371_get_buffer, es1371);
|
||||
sound_set_cd_audio_filter(es1371_filter_cd_audio, es1371);
|
||||
|
||||
/* Add our own always-present game port to override the standalone ISAPnP one. */
|
||||
gameport_remap(gameport_add(&gameport_pnp_device), 0x200);
|
||||
|
||||
es1371->card = pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, es1371);
|
||||
|
||||
timer_add(&es1371->dac[1].timer, es1371_poll, es1371, 1);
|
||||
|
||||
generate_es1371_filter();
|
||||
|
||||
/* Return a CS4297A like VMWare does. */
|
||||
/* Return a CS4297A like VMware does. */
|
||||
es1371->codec_regs[0x7c] = 0x4352;
|
||||
es1371->codec_regs[0x7e] = 0x5910;
|
||||
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/sound.h>
|
||||
#include <86box/midi.h>
|
||||
@@ -71,6 +72,9 @@ static const uint16_t sb_mcv_addr[8] = {0x200, 0x210, 0x220, 0x230, 0x240, 0x250
|
||||
static const int sb_pro_mcv_irqs[4] = {7, 5, 3, 3};
|
||||
|
||||
|
||||
/* Each card in the SB16 family has a million variants, and it shows in the large variety of device IDs for the PnP models.
|
||||
These ROMs were reconstructed in a best-effort basis, around what Linux pnpdump configs and kernel logs could be found
|
||||
in mailing lists, forums and other places, as well as Linux's own SB PnP card tables for ALSA and OSS. */
|
||||
static uint8_t sb_16_pnp_rom[] = {
|
||||
0x0e, 0x8c, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL0028, dummy checksum (filled in by isapnp_add_card) */
|
||||
0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */
|
||||
@@ -87,14 +91,19 @@ static uint8_t sb_16_pnp_rom[] = {
|
||||
0x47, 0x01, 0x88, 0x03, 0x88, 0x03, 0x01, 0x04, /* I/O 0x388, decodes 16-bit, 1-byte alignment, 4 addresses */
|
||||
0x38, /* end dependent functions */
|
||||
|
||||
0x15, 0x0e, 0x8c, 0x70, 0x01, 0x00, /* logical device CTL7001 */
|
||||
0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */
|
||||
0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */
|
||||
0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */
|
||||
|
||||
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
|
||||
};
|
||||
static uint8_t sb_32_pnp_rom[] = {
|
||||
0x0e, 0x8c, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL009C, dummy checksum (filled in by isapnp_add_card) */
|
||||
0x0e, 0x8c, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL0048, dummy checksum (filled in by isapnp_add_card) */
|
||||
0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */
|
||||
0x82, 0x11, 0x00, 'C', 'r', 'e', 'a', 't', 'i', 'v', 'e', ' ', 'S', 'B', '3', '2', ' ', 'P', 'n', 'P', /* ANSI identifier */
|
||||
|
||||
0x16, 0x0e, 0x8c, 0x00, 0x41, 0x00, 0xa9, /* logical device CTL0041, supports vendor-specific registers 0x38/0x3A/0x3C/0x3F */
|
||||
0x16, 0x0e, 0x8c, 0x00, 0x31, 0x00, 0xa9, /* logical device CTL0031, supports vendor-specific registers 0x38/0x3A/0x3C/0x3F */
|
||||
0x82, 0x05, 0x00, 'A', 'u', 'd', 'i', 'o', /* ANSI identifier */
|
||||
0x31, 0x00, /* start dependent functions, preferred */
|
||||
0x22, 0x20, 0x00, /* IRQ 5 */
|
||||
@@ -153,14 +162,19 @@ static uint8_t sb_32_pnp_rom[] = {
|
||||
0x47, 0x01, 0x20, 0x06, 0x80, 0x06, 0x20, 0x04, /* I/O 0x620-0x680, decodes 16-bit, 32-byte alignment, 4 addresses */
|
||||
0x38, /* end dependent functions */
|
||||
|
||||
0x15, 0x0e, 0x8c, 0x70, 0x01, 0x00, /* logical device CTL7001 */
|
||||
0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */
|
||||
0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */
|
||||
0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */
|
||||
|
||||
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
|
||||
};
|
||||
static uint8_t sb_awe32_pnp_rom[] = {
|
||||
0x0e, 0x8c, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL009A, dummy checksum (filled in by isapnp_add_card) */
|
||||
0x0e, 0x8c, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, /* CTL0043, dummy checksum (filled in by isapnp_add_card) */
|
||||
0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */
|
||||
0x82, 0x15, 0x00, 'C', 'r', 'e', 'a', 't', 'i', 'v', 'e', ' ', 'S', 'B', ' ', 'A', 'W', 'E', '3', '2', ' ', 'P', 'n', 'P', /* ANSI identifier */
|
||||
|
||||
0x16, 0x0e, 0x8c, 0x00, 0x41, 0x00, 0xa9, /* logical device CTL0041, supports vendor-specific registers 0x38/0x3A/0x3C/0x3F */
|
||||
0x16, 0x0e, 0x8c, 0x00, 0x31, 0x00, 0xa9, /* logical device CTL0031, supports vendor-specific registers 0x38/0x3A/0x3C/0x3F */
|
||||
0x82, 0x05, 0x00, 'A', 'u', 'd', 'i', 'o', /* ANSI identifier */
|
||||
0x31, 0x00, /* start dependent functions, preferred */
|
||||
0x22, 0x20, 0x00, /* IRQ 5 */
|
||||
@@ -223,6 +237,11 @@ static uint8_t sb_awe32_pnp_rom[] = {
|
||||
0x47, 0x01, 0x20, 0x0e, 0x80, 0x0e, 0x20, 0x04, /* I/O 0xE20-0xE80, decodes 16-bit, 32-byte alignment, 4 addresses */
|
||||
0x38, /* end dependent functions */
|
||||
|
||||
0x15, 0x0e, 0x8c, 0x70, 0x01, 0x00, /* logical device CTL7001 */
|
||||
0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */
|
||||
0x82, 0x04, 0x00, 'G', 'a', 'm', 'e', /* ANSI identifier */
|
||||
0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x01, 0x08, /* I/O 0x200, decodes 16-bit, 1-byte alignment, 8 addresses */
|
||||
|
||||
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
|
||||
};
|
||||
|
||||
@@ -1188,69 +1207,75 @@ sb_pro_mcv_write(int port, uint8_t val, void *p)
|
||||
static void
|
||||
sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
||||
{
|
||||
if (ld != 0)
|
||||
return;
|
||||
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
uint16_t addr = sb->dsp.sb_addr;
|
||||
uint8_t val;
|
||||
|
||||
io_removehandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_removehandler(addr + 8, 0x0002, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_removehandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
|
||||
sb_ct1745_mixer_write, NULL, NULL, sb);
|
||||
switch (ld) {
|
||||
case 0: /* Audio */
|
||||
io_removehandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_removehandler(addr + 8, 0x0002, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_removehandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
|
||||
sb_ct1745_mixer_write, NULL, NULL, sb);
|
||||
|
||||
addr = sb->opl_pnp_addr;
|
||||
if (addr) {
|
||||
sb->opl_pnp_addr = 0;
|
||||
io_removehandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
}
|
||||
addr = sb->opl_pnp_addr;
|
||||
if (addr) {
|
||||
sb->opl_pnp_addr = 0;
|
||||
io_removehandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
}
|
||||
|
||||
sb_dsp_setaddr(&sb->dsp, 0);
|
||||
sb_dsp_setirq(&sb->dsp, 0);
|
||||
sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED);
|
||||
sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED);
|
||||
sb_dsp_setaddr(&sb->dsp, 0);
|
||||
sb_dsp_setirq(&sb->dsp, 0);
|
||||
sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED);
|
||||
sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED);
|
||||
|
||||
mpu401_change_addr(sb->mpu, 0);
|
||||
mpu401_change_addr(sb->mpu, 0);
|
||||
|
||||
if (config->activate) {
|
||||
addr = config->io[0].base;
|
||||
if (addr != ISAPNP_IO_DISABLED) {
|
||||
io_sethandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
|
||||
sb_ct1745_mixer_write, NULL, NULL, sb);
|
||||
if (config->activate) {
|
||||
addr = config->io[0].base;
|
||||
if (addr != ISAPNP_IO_DISABLED) {
|
||||
io_sethandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
|
||||
sb_ct1745_mixer_write, NULL, NULL, sb);
|
||||
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
}
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
}
|
||||
|
||||
addr = config->io[1].base;
|
||||
if (addr != ISAPNP_IO_DISABLED)
|
||||
mpu401_change_addr(sb->mpu, addr);
|
||||
addr = config->io[1].base;
|
||||
if (addr != ISAPNP_IO_DISABLED)
|
||||
mpu401_change_addr(sb->mpu, addr);
|
||||
|
||||
addr = config->io[2].base;
|
||||
if (addr != ISAPNP_IO_DISABLED) {
|
||||
sb->opl_pnp_addr = addr;
|
||||
io_sethandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
}
|
||||
addr = config->io[2].base;
|
||||
if (addr != ISAPNP_IO_DISABLED) {
|
||||
sb->opl_pnp_addr = addr;
|
||||
io_sethandler(addr, 0x0004, opl3_read, NULL, NULL,
|
||||
opl3_write, NULL, NULL, &sb->opl);
|
||||
}
|
||||
|
||||
val = config->irq[0].irq;
|
||||
if (val != ISAPNP_IRQ_DISABLED)
|
||||
sb_dsp_setirq(&sb->dsp, val);
|
||||
val = config->irq[0].irq;
|
||||
if (val != ISAPNP_IRQ_DISABLED)
|
||||
sb_dsp_setirq(&sb->dsp, val);
|
||||
|
||||
val = config->dma[0].dma;
|
||||
if (val != ISAPNP_DMA_DISABLED)
|
||||
sb_dsp_setdma8(&sb->dsp, val);
|
||||
val = config->dma[0].dma;
|
||||
if (val != ISAPNP_DMA_DISABLED)
|
||||
sb_dsp_setdma8(&sb->dsp, val);
|
||||
|
||||
val = config->dma[1].dma;
|
||||
if (val != ISAPNP_DMA_DISABLED)
|
||||
sb_dsp_setdma16(&sb->dsp, val);
|
||||
val = config->dma[1].dma;
|
||||
if (val != ISAPNP_DMA_DISABLED)
|
||||
sb_dsp_setdma16(&sb->dsp, val);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1: /* Game */
|
||||
gameport_remap(sb->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,21 +1284,18 @@ static void
|
||||
sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
|
||||
{
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
uint16_t addr;
|
||||
|
||||
switch (ld) {
|
||||
case 0:
|
||||
case 0: /* Audio */
|
||||
sb_16_pnp_config_changed(0, config, sb);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
emu8k_change_addr(&sb->emu8k, 0);
|
||||
case 1: /* WaveTable */
|
||||
emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0);
|
||||
break;
|
||||
|
||||
if (config->activate) {
|
||||
addr = config->io[0].base;
|
||||
if (addr != ISAPNP_IO_DISABLED)
|
||||
emu8k_change_addr(&sb->emu8k, addr);
|
||||
}
|
||||
case 2: /* Game */
|
||||
sb_16_pnp_config_changed(1, config, sb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1701,6 +1723,8 @@ sb_16_pnp_init(const device_t *info)
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
|
||||
sb->gameport = gameport_add(&gameport_pnp_device);
|
||||
|
||||
isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb);
|
||||
|
||||
return sb;
|
||||
@@ -1796,6 +1820,8 @@ sb_awe32_pnp_init(const device_t *info)
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
|
||||
sb->gameport = gameport_add(&gameport_pnp_device);
|
||||
|
||||
if (info->local == 1)
|
||||
isapnp_add_card(sb_32_pnp_rom, sizeof(sb_32_pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb);
|
||||
else
|
||||
|
Reference in New Issue
Block a user