GUS gameport work

Classic: gameport toggleable by jumper/config option (pre-rev 3.4), disabled by default
MAX: gameport toggleable by software register (post-rev 3.4), enabled by default
Disable access to rev 3.4+ registers on Classic
This commit is contained in:
Alexander Babikov
2025-08-03 17:36:07 +05:00
parent 0c89274233
commit 91413a8457

View File

@@ -13,6 +13,7 @@
#include <86box/io.h> #include <86box/io.h>
#include <86box/midi.h> #include <86box/midi.h>
#include <86box/nmi.h> #include <86box/nmi.h>
#include <86box/gameport.h>
#include <86box/pic.h> #include <86box/pic.h>
#include <86box/sound.h> #include <86box/sound.h>
#include "cpu.h" #include "cpu.h"
@@ -120,7 +121,9 @@ typedef struct gus_t {
uint8_t sb_ctrl; uint8_t sb_ctrl;
int sb_nmi; int sb_nmi;
uint8_t joy_trim;
uint8_t reg_ctrl; uint8_t reg_ctrl;
uint8_t jumper;
uint8_t ad_status; uint8_t ad_status;
uint8_t ad_data; uint8_t ad_data;
@@ -143,6 +146,8 @@ typedef struct gus_t {
uint8_t usrr; uint8_t usrr;
void *gameport;
uint8_t max_ctrl; uint8_t max_ctrl;
ad1848_t ad1848; ad1848_t ad1848;
@@ -159,6 +164,9 @@ int gusfreqs[] = {
double vol16bit[4096]; double vol16bit[4096];
void gus_write(uint16_t addr, uint8_t val, void *priv);
uint8_t gus_read(uint16_t addr, void *priv);
void void
gus_update_int_status(gus_t *gus) gus_update_int_status(gus_t *gus)
{ {
@@ -537,6 +545,10 @@ gus_write(uint16_t addr, uint8_t val, void *priv)
gus->t2on = 1; gus->t2on = 1;
break; break;
case 0x4B: /*Joystick trim DAC*/
gus->joy_trim = val;
break;
case 0x4c: /*Reset*/ case 0x4c: /*Reset*/
gus->reset = val; gus->reset = val;
break; break;
@@ -634,9 +646,23 @@ gus_write(uint16_t addr, uint8_t val, void *priv)
gus->gp2_addr = val; gus->gp2_addr = val;
break; break;
case 5: case 5:
gus->usrr = 0; if (gus->type > GUS_CLASSIC)
gus->usrr = 0;
break; break;
case 6: case 6:
if (gus->type > GUS_CLASSIC) {
if (!(val & 0x2) && (gus->jumper & 0x2))
io_removehandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
else if ((val & 0x2) && !(gus->jumper & 0x2))
io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
if (!(val & 0x4) && (gus->jumper & 0x4))
gameport_remap(gus->gameport, 0x0);
else if ((val & 0x4) && !(gus->jumper & 0x4))
gameport_remap(gus->gameport, 0x201);
gus->jumper = val;
}
break; break;
default: default:
@@ -672,7 +698,8 @@ gus_write(uint16_t addr, uint8_t val, void *priv)
gus->sb_2xe = val; gus->sb_2xe = val;
break; break;
case 0x20f: case 0x20f:
gus->reg_ctrl = val; if (gus->type > GUS_CLASSIC)
gus->reg_ctrl = val;
break; break;
case 0x306: case 0x306:
case 0x706: case 0x706:
@@ -746,10 +773,10 @@ gus_read(uint16_t addr, void *priv)
return val; return val;
case 0x20F: case 0x20F:
if (gus->type == GUS_MAX) if (gus->type > GUS_CLASSIC)
val = 0x02; val = gus->jumper;
else else
val = 0x00; val = 0xff;
break; break;
case 0x302: case 0x302:
@@ -842,6 +869,9 @@ gus_read(uint16_t addr, void *priv)
case 0x49: /*Sampling control*/ case 0x49: /*Sampling control*/
return 0; return 0;
case 0x4B: /*Joystick trim DAC*/
return gus->joy_trim;
case 0x00: case 0x00:
case 0x01: case 0x01:
case 0x02: case 0x02:
@@ -884,22 +914,24 @@ gus_read(uint16_t addr, void *priv)
return 0; return 0;
case 0x20b: case 0x20b:
switch (gus->reg_ctrl & 0x07) { if (gus->type > GUS_CLASSIC) {
case 1: switch (gus->reg_ctrl & 0x07) {
val = gus->gp1; case 1:
break; val = gus->gp1;
case 2: break;
val = gus->gp2; case 2:
break; val = gus->gp2;
case 3: break;
val = gus->gp1_addr; case 3:
break; val = gus->gp1_addr;
case 4: break;
val = gus->gp2_addr; case 4:
break; val = gus->gp2_addr;
break;
default: default:
break; break;
}
} }
break; break;
@@ -1292,6 +1324,7 @@ gus_reset(void *priv)
gus->sb_ctrl = 0; gus->sb_ctrl = 0;
gus->sb_nmi = 0; gus->sb_nmi = 0;
gus->joy_trim = 29;
gus->reg_ctrl = 0; gus->reg_ctrl = 0;
gus->ad_status = 0; gus->ad_status = 0;
@@ -1355,12 +1388,21 @@ gus_init(UNUSED(const device_t *info))
gus->type = info->local; gus->type = info->local;
gus->jumper = 0x06;
gus->base = device_get_config_hex16("base"); gus->base = device_get_config_hex16("base");
io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
io_sethandler(0x0100 + gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
io_sethandler(0x0102 + gus->base, 0x000e, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
io_sethandler(0x0506 + gus->base, 0x0001, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0506 + gus->base, 0x0001, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
io_sethandler(0x0388, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0388, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus);
if (gus->type == GUS_CLASSIC && device_get_config_int("gameport"))
gus->gameport = gameport_add(&gameport_201_device);
else {
gus->gameport = gameport_add(&gameport_pnp_1io_device);
gameport_remap(gus->gameport, 0x201);
}
if (gus->type == GUS_MAX) { if (gus->type == GUS_MAX) {
ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231);
@@ -1442,6 +1484,17 @@ static const device_config_t gus_config[] = {
}, },
.bios = { { 0 } } .bios = { { 0 } }
}, },
{
.name = "gameport",
.description = "Enable Game port",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ {
.name = "receive_input", .name = "receive_input",
.description = "Receive MIDI input", .description = "Receive MIDI input",