Files
86Box/src/game/gameport.c

798 lines
23 KiB
C
Raw Normal View History

/*
* 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.
*
* Implementation of a generic Game Port.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
2023-01-06 15:36:29 -05:00
* Sarah Walker, <https://pcem-emulator.co.uk/>
* RichardG, <richardg867@gmail.com>
2024-11-30 15:33:29 -05:00
* Jasmine Iwanek, <jriwanek@gmail.com>
*
2024-11-30 15:33:29 -05:00
* Copyright 2016-2022 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2021 RichardG.
2024-11-30 15:26:06 -05:00
* Copyright 2021-2025 Jasmine Iwanek.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <86box/86box.h>
#include <86box/machine.h>
2020-02-29 19:12:23 +01:00
#include "cpu.h"
#include <86box/device.h>
#include <86box/io.h>
#include <86box/timer.h>
2021-05-20 22:51:55 -03:00
#include <86box/isapnp.h>
#include <86box/gameport.h>
2023-06-26 12:47:04 -04:00
#include <86box/plat_unused.h>
2024-11-30 15:26:06 -05:00
device_t game_ports[GAMEPORT_MAX];
typedef struct {
const device_t *device;
} GAMEPORT;
2023-06-28 13:46:28 -04:00
typedef struct g_axis_t {
2022-09-18 17:14:24 -04:00
pc_timer_t timer;
int axis_nr;
2021-05-20 22:51:55 -03:00
struct _joystick_instance_ *joystick;
} g_axis_t;
typedef struct _gameport_ {
2022-09-18 17:14:24 -04:00
uint16_t addr;
uint8_t len;
2021-05-20 22:51:55 -03:00
struct _joystick_instance_ *joystick;
2022-09-18 17:14:24 -04:00
struct _gameport_ *next;
2021-05-20 22:51:55 -03:00
} gameport_t;
2025-01-26 03:01:19 -05:00
typedef struct _tmacm_ {
struct gameport_t *port1;
struct gameport_t *port2;
} tmacm_t;
2021-05-20 22:51:55 -03:00
typedef struct _joystick_instance_ {
2022-09-18 17:14:24 -04:00
uint8_t state;
g_axis_t axis[4];
2021-05-20 22:51:55 -03:00
const joystick_if_t *intf;
2022-09-18 17:14:24 -04:00
void *dat;
2021-05-20 22:51:55 -03:00
} joystick_instance_t;
2023-08-14 17:20:48 -04:00
int joystick_type = JS_TYPE_NONE;
static const joystick_if_t joystick_none = {
2022-09-18 17:14:24 -04:00
.name = "None",
2022-03-13 09:40:04 -04:00
.internal_name = "none",
2022-09-18 17:14:24 -04:00
.init = NULL,
.close = NULL,
.read = NULL,
.write = NULL,
.read_axis = NULL,
.a0_over = NULL,
.axis_count = 0,
.button_count = 0,
.pov_count = 0,
2022-03-13 09:40:04 -04:00
.max_joysticks = 0,
2022-09-18 17:14:24 -04:00
.axis_names = { NULL },
.button_names = { NULL },
.pov_names = { NULL }
2016-09-16 02:32:25 +02:00
};
2020-12-04 21:45:09 +05:00
static const struct {
2022-09-18 17:14:24 -04:00
const joystick_if_t *joystick;
2020-12-04 21:45:09 +05:00
} joysticks[] = {
2025-02-03 20:00:58 -05:00
{ &joystick_none },
{ &joystick_2axis_2button },
{ &joystick_2axis_4button },
{ &joystick_2axis_6button },
{ &joystick_2axis_8button },
{ &joystick_3axis_2button },
{ &joystick_3axis_4button },
{ &joystick_4axis_4button },
2022-03-13 09:00:26 -04:00
{ &joystick_ch_flightstick_pro },
2025-02-03 20:00:58 -05:00
{ &joystick_sw_pad },
{ &joystick_tm_fcs },
{ NULL }
};
2021-05-20 22:51:55 -03:00
static joystick_instance_t *joystick_instance[GAMEPORT_MAX] = { NULL, NULL };
2021-05-20 22:51:55 -03:00
static uint8_t gameport_pnp_rom[] = {
2022-09-18 17:14:24 -04:00
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 */
2021-05-20 22:51:55 -03:00
0x82, 0x09, 0x00, 'G', 'a', 'm', 'e', ' ', 'P', 'o', 'r', 't', /* ANSI identifier */
2022-09-18 17:14:24 -04:00
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 */
2021-05-20 22:51:55 -03:00
0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */
};
static const isapnp_device_config_t gameport_pnp_defaults[] = {
2022-09-18 17:14:24 -04:00
{.activate = 1,
2023-06-28 13:46:28 -04:00
.io = {
{ .base = 0x200 },
}
}
2021-05-20 22:51:55 -03:00
};
2022-09-18 17:14:24 -04:00
const device_t *standalone_gameport_type;
int gameport_instance_id = 0;
2021-05-20 22:51:55 -03:00
/* Linked list of active game ports. Only the top port responds to reads
or writes, and ports at the standard 200h location are prioritized. */
2022-09-18 17:14:24 -04:00
static gameport_t *active_gameports = NULL;
2023-08-14 17:20:48 -04:00
const char *
joystick_get_name(int js)
{
2021-05-20 22:51:55 -03:00
if (!joysticks[js].joystick)
2022-09-18 17:14:24 -04:00
return NULL;
2023-08-14 17:20:48 -04:00
return joysticks[js].joystick->name;
2020-12-04 21:45:09 +05:00
}
2023-08-14 17:20:48 -04:00
const char *
2020-12-04 21:45:09 +05:00
joystick_get_internal_name(int js)
{
if (joysticks[js].joystick == NULL)
2022-09-18 17:14:24 -04:00
return "";
2023-08-14 17:20:48 -04:00
return joysticks[js].joystick->internal_name;
2020-12-04 21:45:09 +05:00
}
int
joystick_get_from_internal_name(char *s)
{
int c = 0;
while (joysticks[c].joystick != NULL) {
2023-08-14 17:20:48 -04:00
if (!strcmp(joysticks[c].joystick->internal_name, s))
2022-09-18 17:14:24 -04:00
return c;
c++;
2020-12-04 21:45:09 +05:00
}
return 0;
}
int
joystick_get_max_joysticks(int js)
{
2021-05-20 22:51:55 -03:00
return joysticks[js].joystick->max_joysticks;
}
int
joystick_get_axis_count(int js)
{
2021-05-20 22:51:55 -03:00
return joysticks[js].joystick->axis_count;
}
int
joystick_get_button_count(int js)
{
2021-05-20 22:51:55 -03:00
return joysticks[js].joystick->button_count;
}
int
joystick_get_pov_count(int js)
{
2021-05-20 22:51:55 -03:00
return joysticks[js].joystick->pov_count;
}
2023-08-14 17:20:48 -04:00
const char *
joystick_get_axis_name(int js, int id)
{
2023-08-14 17:20:48 -04:00
return joysticks[js].joystick->axis_names[id];
}
2023-08-14 17:20:48 -04:00
const char *
joystick_get_button_name(int js, int id)
{
2023-08-14 17:20:48 -04:00
return joysticks[js].joystick->button_names[id];
}
2023-08-14 17:20:48 -04:00
const char *
joystick_get_pov_name(int js, int id)
{
2023-08-14 17:20:48 -04:00
return joysticks[js].joystick->pov_names[id];
}
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
static void
2021-05-20 22:51:55 -03:00
gameport_time(joystick_instance_t *joystick, int nr, int axis)
{
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
if (axis == AXIS_NOT_PRESENT)
2022-09-18 17:14:24 -04:00
timer_disable(&joystick->axis[nr].timer);
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
else {
2022-09-18 17:14:24 -04:00
/* Convert axis value to 555 timing. */
axis += 32768;
axis = (axis * 100) / 65; /* axis now in ohms */
axis = (axis * 11) / 1000;
timer_set_delay_u64(&joystick->axis[nr].timer, TIMER_USEC * (axis + 24)); /* max = 11.115 ms */
Added the IBM 5161 ISA expansion for PC and XT; Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
}
}
static void
2023-06-26 12:47:04 -04:00
gameport_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), void *priv)
{
2022-09-18 17:14:24 -04:00
gameport_t *dev = (gameport_t *) priv;
2021-05-20 22:51:55 -03:00
joystick_instance_t *joystick = dev->joystick;
/* Respond only if a joystick is present and this port is at the top of the active ports list. */
if (!joystick || (active_gameports != dev))
2022-09-18 17:14:24 -04:00
return;
2021-05-20 22:51:55 -03:00
/* Read all axes. */
joystick->state |= 0x0f;
2021-05-20 22:51:55 -03:00
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);
}
static uint8_t
2023-06-26 12:47:04 -04:00
gameport_read(UNUSED(uint16_t addr), void *priv)
{
2022-09-18 17:14:24 -04:00
gameport_t *dev = (gameport_t *) priv;
2021-05-20 22:51:55 -03:00
joystick_instance_t *joystick = dev->joystick;
/* Respond only if a joystick is present and this port is at the top of the active ports list. */
if (!joystick || (active_gameports != dev))
2022-09-18 17:14:24 -04:00
return 0xff;
2021-05-20 22:51:55 -03:00
/* Merge axis state with button state. */
uint8_t ret = joystick->state | joystick->intf->read(joystick->dat);
cycles -= ISA_CYCLES(8);
2021-05-20 22:51:55 -03:00
return ret;
}
static void
timer_over(void *priv)
{
2021-05-20 22:51:55 -03:00
g_axis_t *axis = (g_axis_t *) priv;
2021-05-20 22:51:55 -03:00
axis->joystick->state &= ~(1 << axis->axis_nr);
2021-06-03 16:02:15 -03:00
/* Notify the joystick when the first axis' period is finished. */
2021-05-20 22:51:55 -03:00
if (axis == &axis->joystick->axis[0])
2022-09-18 17:14:24 -04:00
axis->joystick->intf->a0_over(axis->joystick->dat);
}
void
gameport_update_joystick_type(void)
{
2021-05-20 22:51:55 -03:00
/* Add a standalone game port if a joystick is enabled but no other game ports exist. */
if (standalone_gameport_type)
2022-09-18 17:14:24 -04:00
gameport_add(standalone_gameport_type);
2021-05-20 22:51:55 -03:00
/* Reset the joystick interface. */
if (joystick_instance[0]) {
joystick_instance[0]->intf->close(joystick_instance[0]->dat);
joystick_instance[0]->intf = joysticks[joystick_type].joystick;
joystick_instance[0]->dat = joystick_instance[0]->intf->init();
}
}
2021-04-02 23:44:24 -03:00
void
2021-05-20 22:51:55 -03:00
gameport_remap(void *priv, uint16_t address)
2021-04-02 23:44:24 -03:00
{
2023-05-11 03:02:36 -04:00
gameport_t *dev = (gameport_t *) priv;
gameport_t *other_dev;
2021-05-20 22:51:55 -03:00
if (dev->addr) {
2022-09-18 17:14:24 -04:00
/* 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->len,
gameport_read, NULL, NULL, gameport_write, NULL, NULL, dev);
2021-05-20 22:51:55 -03:00
}
dev->addr = address;
if (dev->addr) {
2022-09-18 17:14:24 -04:00
/* Add this port to the active ports list. */
if (!active_gameports || ((dev->addr & 0xfff8) == 0x200)) {
/* No ports have been added yet, or 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->len,
gameport_read, NULL, NULL, gameport_write, NULL, NULL, dev);
2021-05-20 22:51:55 -03:00
}
}
static void
gameport_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv)
{
if (ld > 0)
2022-09-18 17:14:24 -04:00
return;
2021-04-02 23:44:24 -03:00
2021-05-20 22:51:55 -03:00
gameport_t *dev = (gameport_t *) priv;
/* 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);
}
void *
gameport_add(const device_t *gameport_type)
{
/* Prevent a standalone game port from being added later on, unless this
is an unused Super I/O game port (no MACHINE_GAMEPORT machine flag). */
if (!(gameport_type->local & GAMEPORT_SIO) || machine_has_flags(machine, MACHINE_GAMEPORT))
2022-09-18 17:14:24 -04:00
standalone_gameport_type = NULL;
2021-04-02 23:44:24 -03:00
2021-05-20 22:51:55 -03:00
/* Add game port device. */
return device_add_inst(gameport_type, gameport_instance_id++);
2021-04-02 23:44:24 -03:00
}
static void *
gameport_init(const device_t *info)
{
2025-01-07 00:42:06 -05:00
gameport_t *dev = calloc(1, sizeof(gameport_t));
2016-09-16 02:32:25 +02:00
2021-05-20 22:51:55 -03:00
/* Allocate global instance. */
if (!joystick_instance[0] && joystick_type) {
2025-01-07 00:42:06 -05:00
joystick_instance[0] = calloc(1, sizeof(joystick_instance_t));
joystick_instance[0]->axis[0].joystick = joystick_instance[0];
joystick_instance[0]->axis[1].joystick = joystick_instance[0];
joystick_instance[0]->axis[2].joystick = joystick_instance[0];
joystick_instance[0]->axis[3].joystick = joystick_instance[0];
joystick_instance[0]->axis[0].axis_nr = 0;
joystick_instance[0]->axis[1].axis_nr = 1;
joystick_instance[0]->axis[2].axis_nr = 2;
joystick_instance[0]->axis[3].axis_nr = 3;
timer_add(&joystick_instance[0]->axis[0].timer, timer_over, &joystick_instance[0]->axis[0], 0);
timer_add(&joystick_instance[0]->axis[1].timer, timer_over, &joystick_instance[0]->axis[1], 0);
timer_add(&joystick_instance[0]->axis[2].timer, timer_over, &joystick_instance[0]->axis[2], 0);
timer_add(&joystick_instance[0]->axis[3].timer, timer_over, &joystick_instance[0]->axis[3], 0);
joystick_instance[0]->intf = joysticks[joystick_type].joystick;
joystick_instance[0]->dat = joystick_instance[0]->intf->init();
2021-05-20 22:51:55 -03:00
}
2016-09-16 02:32:25 +02:00
dev->joystick = joystick_instance[0];
2016-09-16 02:32:25 +02:00
2021-05-20 22:51:55 -03:00
/* Map game port to the default address. Not applicable on PnP-only ports. */
dev->len = (info->local >> 16) & 0xff;
gameport_remap(dev, info->local & 0xffff);
2021-05-20 22:51:55 -03:00
/* Register ISAPnP if this is a standard game port card. */
2021-06-18 09:02:39 +05:00
if ((info->local & 0xffff) == 0x200)
2022-09-18 17:14:24 -04:00
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);
2021-05-20 22:51:55 -03:00
return dev;
}
2022-03-12 18:47:12 -05:00
static void *
2023-06-26 12:47:04 -04:00
tmacm_init(UNUSED(const device_t *info))
2022-03-12 18:47:12 -05:00
{
2025-01-26 03:01:19 -05:00
uint16_t port = 0x0000;
tmacm_t *dev = NULL;
2022-03-13 17:15:54 -04:00
2025-01-26 03:01:19 -05:00
dev = calloc(1, sizeof(tmacm_t));
2022-03-12 18:47:12 -05:00
2023-08-14 17:20:48 -04:00
port = (uint16_t) device_get_config_hex16("port1_addr");
2022-09-18 17:14:24 -04:00
switch (port) {
2022-03-12 18:47:12 -05:00
case 0x201:
2025-01-26 03:01:19 -05:00
dev->port1 = gameport_add(&gameport_201_device);
2022-03-12 18:47:12 -05:00
break;
case 0x203:
2025-01-26 03:01:19 -05:00
dev->port1 = gameport_add(&gameport_203_device);
2022-03-12 18:47:12 -05:00
break;
case 0x205:
2025-01-26 03:01:19 -05:00
dev->port1 = gameport_add(&gameport_205_device);
2022-03-12 18:47:12 -05:00
break;
case 0x207:
2025-01-26 03:01:19 -05:00
dev->port1 = gameport_add(&gameport_207_device);
2022-03-12 18:47:12 -05:00
break;
default:
break;
}
2023-08-14 17:20:48 -04:00
port = (uint16_t) device_get_config_hex16("port2_addr");
2022-09-18 17:14:24 -04:00
switch (port) {
2023-04-01 22:48:02 -04:00
case 0x209:
2025-01-26 03:01:19 -05:00
dev->port2 = gameport_add(&gameport_209_device);
2022-03-12 18:47:12 -05:00
break;
2023-04-01 22:48:02 -04:00
case 0x20b:
2025-01-26 03:01:19 -05:00
dev->port2 = gameport_add(&gameport_20b_device);
2022-03-12 18:47:12 -05:00
break;
2023-04-01 22:48:02 -04:00
case 0x20d:
2025-01-26 03:01:19 -05:00
dev->port2 = gameport_add(&gameport_20d_device);
2022-03-12 18:47:12 -05:00
break;
2023-04-01 22:48:02 -04:00
case 0x20f:
2025-01-26 03:01:19 -05:00
dev->port2 = gameport_add(&gameport_20f_device);
2022-03-12 18:47:12 -05:00
break;
default:
break;
}
2022-03-13 17:37:11 -04:00
return dev;
2022-03-12 18:47:12 -05:00
}
static void
gameport_close(void *priv)
{
2021-05-20 22:51:55 -03:00
gameport_t *dev = (gameport_t *) priv;
2021-05-20 22:51:55 -03:00
/* If this port was active, remove it from the active ports list. */
gameport_remap(dev, 0);
2016-09-16 02:32:25 +02:00
2021-05-20 22:51:55 -03:00
/* Free the global instance here, if it wasn't already freed. */
if (joystick_instance[0]) {
joystick_instance[0]->intf->close(joystick_instance[0]->dat);
free(joystick_instance[0]);
joystick_instance[0] = NULL;
2021-05-20 22:51:55 -03:00
}
2021-05-20 22:51:55 -03:00
free(dev);
}
const device_t gameport_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_8ADDR | 0x0200,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
};
const device_t gameport_201_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 201h only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_201",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x0201,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-03-12 18:47:12 -05:00
};
const device_t gameport_203_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 203h only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_203",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x0203,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-03-12 18:47:12 -05:00
};
const device_t gameport_205_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 205h only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_205",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x0205,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-03-12 18:47:12 -05:00
};
const device_t gameport_207_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 207h only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_207",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x0207,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
};
2021-05-20 22:51:55 -03:00
2021-12-19 18:18:20 -05:00
const device_t gameport_208_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 208h-20fh)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_208",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_8ADDR | 0x0208,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2021-12-19 18:18:20 -05:00
};
const device_t gameport_209_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 209h only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_209",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x0209,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-03-12 18:47:12 -05:00
};
const device_t gameport_20b_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 20Bh only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_20b",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x020B,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-03-12 18:47:12 -05:00
};
const device_t gameport_20d_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 20Dh only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_20d",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x020D,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-03-12 18:47:12 -05:00
};
const device_t gameport_20f_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Port 20Fh only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_20f",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_1ADDR | 0x020F,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-03-12 18:47:12 -05:00
};
static const device_config_t tmacm_config[] = {
2022-09-18 17:14:24 -04:00
// clang-format off
2022-03-12 18:47:12 -05:00
{
2025-02-03 20:00:58 -05:00
.name = "port1_addr",
.description = "Port 1 Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x0201,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
2022-03-12 18:47:12 -05:00
{ .description = "201h", .value = 0x0201 },
{ .description = "203h", .value = 0x0203 },
{ .description = "205h", .value = 0x0205 },
{ .description = "207h", .value = 0x0207 },
{ .description = "Disabled", .value = 0x0000 },
2025-02-03 20:00:58 -05:00
{ .description = "" }
},
.bios = { { 0 } }
2022-03-12 18:47:12 -05:00
},
{
2025-02-03 20:00:58 -05:00
.name = "port2_addr",
.description = "Port 2 Address",
.type = CONFIG_HEX16,
.default_string = NULL,
.default_int = 0x0209,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
2022-03-12 18:47:12 -05:00
{ .description = "209h", .value = 0x0209 },
{ .description = "20Bh", .value = 0x020B },
{ .description = "20Dh", .value = 0x020D },
{ .description = "20Fh", .value = 0x020F },
{ .description = "Disabled", .value = 0x0000 },
2025-02-03 20:00:58 -05:00
{ .description = "" }
},
.bios = { { 0 } }
2022-03-12 18:47:12 -05:00
},
2025-01-26 15:15:53 -05:00
{ .name = "", .description = "", .type = CONFIG_END }
2022-11-19 08:49:04 -05:00
// clang-format on
2022-03-12 18:47:12 -05:00
};
const device_t gameport_tm_acm_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (ThrustMaster ACM)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_tmacm",
2022-09-18 17:14:24 -04:00
.flags = DEVICE_ISA,
.local = 0,
.init = tmacm_init,
.close = NULL,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = tmacm_config
};
2021-05-20 22:51:55 -03:00
const device_t gameport_pnp_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Plug and Play only)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_pnp",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_8ADDR,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
};
2024-12-30 13:47:54 -05:00
const device_t gameport_pnp_1io_device = {
.name = "Game port (Plug and Play only, 1 I/O port)",
.internal_name = "gameport_pnp_1io",
.flags = 0,
.local = GAMEPORT_1ADDR,
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2024-12-30 13:47:54 -05:00
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t gameport_pnp_6io_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Plug and Play only, 6 I/O ports)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_pnp_6io",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_6ADDR,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2021-05-20 22:51:55 -03:00
};
const device_t gameport_sio_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Super I/O)",
2022-03-12 18:47:12 -05:00
.internal_name = "gameport_sio",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_SIO | GAMEPORT_8ADDR,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-03-12 18:47:12 -05:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
};
2022-07-18 23:45:25 +02:00
const device_t gameport_sio_1io_device = {
2022-09-18 17:14:24 -04:00
.name = "Game port (Super I/O, 1 I/O port)",
2022-07-18 23:45:25 +02:00
.internal_name = "gameport_sio",
2022-09-18 17:14:24 -04:00
.flags = 0,
.local = GAMEPORT_SIO | GAMEPORT_1ADDR,
2022-09-18 17:14:24 -04:00
.init = gameport_init,
.close = gameport_close,
.reset = NULL,
2025-01-07 01:12:42 -05:00
.available = NULL,
2022-07-18 23:45:25 +02:00
.speed_changed = NULL,
2022-09-18 17:14:24 -04:00
.force_redraw = NULL,
.config = NULL
2022-07-18 23:45:25 +02:00
};
2024-11-30 15:26:06 -05:00
static const GAMEPORT gameports[] = {
{ &device_none },
{ &device_internal },
{ &gameport_device },
{ &gameport_208_device },
{ &gameport_pnp_device },
{ &gameport_tm_acm_device },
{ NULL }
// clang-format on
};
/* UI */
int
gameport_available(int port)
{
if (gameports[port].device)
return (device_available(gameports[port].device));
return 1;
}
/* UI */
const device_t *
gameports_getdevice(int port)
{
return (gameports[port].device);
}
/* UI */
int
gameport_has_config(int port)
{
if (!gameports[port].device)
return 0;
return (device_has_config(gameports[port].device) ? 1 : 0);
}
/* UI */
const char *
gameport_get_internal_name(int port)
{
return device_get_internal_name(gameports[port].device);
}
/* UI */
int
gameport_get_from_internal_name(const char *str)
{
int c = 0;
while (gameports[c].device != NULL) {
if (!strcmp(gameports[c].device->internal_name, str))
return c;
c++;
}
return 0;
}