diff --git a/PDP10/kx10_defs.h b/PDP10/kx10_defs.h index 730a0fe..04a6c5d 100644 --- a/PDP10/kx10_defs.h +++ b/PDP10/kx10_defs.h @@ -454,6 +454,7 @@ extern DEVICE dkb_dev; extern DEVICE auxcpu_dev; extern DEVICE dpk_dev; extern DEVICE wcnsls_dev; /* MIT Spacewar Consoles */ +extern DEVICE ocnsls_dev; /* Old MIT Spacewar Consoles */ extern DEVICE ai_dev; extern DEVICE dct_dev; /* PDP6 devices. */ extern DEVICE dtc_dev; @@ -580,6 +581,7 @@ int auxcpu_write (t_addr addr, t_uint64); #endif #define NUM_DEVS_DPY USE_DISPLAY #define NUM_DEVS_WCNSLS USE_DISPLAY +#define NUM_DEVS_OCNSLS USE_DISPLAY #if PDP6_DEV #define NUM_DEVS_DTC 1 #define NUM_DEVS_DCT 2 diff --git a/PDP10/kx10_dpy.c b/PDP10/kx10_dpy.c index 54e2fd6..3efebae 100644 --- a/PDP10/kx10_dpy.c +++ b/PDP10/kx10_dpy.c @@ -85,6 +85,7 @@ */ #include "kx10_defs.h" +#include "sim_video.h" #include #ifndef NUM_DEVS_DPY @@ -296,13 +297,38 @@ t_stat dpy_svc (UNIT *uptr) return SCPE_OK; } +#define JOY_MAX_UNITS 4 +#define JOY_MAX_AXES 4 +#define JOY_MAX_BUTTONS 4 + +static int joy_axes[JOY_MAX_UNITS * JOY_MAX_AXES]; +static int joy_buttons[JOY_MAX_UNITS * JOY_MAX_BUTTONS]; + +static void dpy_joy_motion(int which, int axis, int value) +{ + if (which < JOY_MAX_UNITS && axis < JOY_MAX_AXES) { + joy_axes[which * JOY_MAX_AXES + axis] = value; + } +} + +static void dpy_joy_button(int which, int button, int state) +{ + if (which < JOY_MAX_UNITS && button < JOY_MAX_BUTTONS) { + joy_buttons[which * JOY_MAX_UNITS + button] = state; + } +} + /* Reset routine */ t_stat dpy_reset (DEVICE *dptr) { - if (!(dptr->flags & DEV_DIS)) { + if (dptr->flags & DEV_DIS) { + display_close(dptr); + } else { display_reset(); ty340_reset(dptr); + vid_register_gamepad_motion_callback (dpy_joy_motion); + vid_register_gamepad_button_callback (dpy_joy_button); } sim_cancel (&dpy_unit[0]); /* deactivate unit */ return SCPE_OK; @@ -367,17 +393,25 @@ cpu_set_switches(unsigned long w1, unsigned long w2) { #if NUM_DEVS_WCNSLS > 0 #define WCNSLS_DEVNUM 0420 +#define UNIT_JOY (1 << DEV_V_UF) + t_stat wcnsls_devio(uint32 dev, uint64 *data); const char *wcnsls_description (DEVICE *dptr); DIB wcnsls_dib[] = { { WCNSLS_DEVNUM, 1, &wcnsls_devio, NULL }}; +MTAB wcnsls_mod[] = { + { UNIT_JOY, UNIT_JOY, "JOYSTICK", "JOYSTICK", NULL, NULL, NULL, + "Use USB joysticks"}, + { 0 } + }; + UNIT wcnsls_unit[] = { { UDATA (NULL, UNIT_IDLE, 0) }}; DEVICE wcnsls_dev = { - "WCNSLS", wcnsls_unit, NULL, NULL, + "WCNSLS", wcnsls_unit, NULL, wcnsls_mod, NUM_DEVS_WCNSLS, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, @@ -390,17 +424,6 @@ const char *wcnsls_description (DEVICE *dptr) return "MIT Spacewar Consoles"; } -t_stat wcnsls_devio(uint32 dev, uint64 *data) { - uint64 switches; - - switch (dev & 3) { - case CONO: - /* CONO WCNSLS,40 ;enable spacewar consoles */ - break; - - case DATAI: - switches = 0777777777777LL; /* 1 is off */ - /* * map 32-bit "spacewar_switches" value to what PDP-6/10 game expects * (four 9-bit bytes) @@ -418,6 +441,71 @@ t_stat wcnsls_devio(uint32 dev, uint64 *data) { #define LL 18 /* lower left: thin ship "third plug" */ #define UL 27 /* upper left: fat ship "bottom plug" */ +#define JOY_TRIG 5000 +#define JOY0 (JOY_MAX_AXES*0) +#define JOY1 (JOY_MAX_AXES*1) +#define JOY2 (JOY_MAX_AXES*2) +#define JOY3 (JOY_MAX_AXES*3) +#define BUT0 (JOY_MAX_BUTTONS*0) +#define BUT1 (JOY_MAX_BUTTONS*1) +#define BUT2 (JOY_MAX_BUTTONS*2) +#define BUT3 (JOY_MAX_BUTTONS*3) + +static uint64 joystick_switches (void) +{ + uint64 switches = 0777777777777LL; + + if (joy_axes[JOY0] > JOY_TRIG) + switches &= ~(CCW << UR); + else if (joy_axes[JOY0] < -JOY_TRIG) + switches &= ~(CW << UR); + if (joy_axes[JOY0+1] < -JOY_TRIG) + switches &= ~(THRUST << UR); + if (joy_buttons[BUT0]) + switches &= ~(FIRE << UR); + if (joy_buttons[BUT0+1]) + switches &= ~(HYPER << UR); + + if (joy_axes[JOY1] > JOY_TRIG) + switches &= ~(CCW << LR); + else if (joy_axes[JOY1] < -JOY_TRIG) + switches &= ~(CW << LR); + if (joy_axes[JOY1+1] < -JOY_TRIG) + switches &= ~(THRUST << LR); + if (joy_buttons[BUT1]) + switches &= ~(FIRE << LR); + if (joy_buttons[BUT1+1]) + switches &= ~(HYPER << LR); + + if (joy_axes[JOY2] > JOY_TRIG) + switches &= ~(CCW << LL); + else if (joy_axes[JOY2] < -JOY_TRIG) + switches &= ~(CW << LL); + if (joy_axes[JOY2+1] < -JOY_TRIG) + switches &= ~(THRUST << LL); + if (joy_buttons[BUT2]) + switches &= ~(FIRE << LL); + if (joy_buttons[BUT2+1]) + switches &= ~(HYPER << LL); + + if (joy_axes[JOY3] > JOY_TRIG) + switches &= ~((uint64)CCW << UL); + else if (joy_axes[JOY3] < -JOY_TRIG) + switches &= ~((uint64)CW << UL); + if (joy_axes[JOY3+1] < -JOY_TRIG) + switches &= ~((uint64)THRUST << UL); + if (joy_buttons[BUT3]) + switches &= ~((uint64)FIRE << UL); + if (joy_buttons[BUT3+1]) + switches &= ~(HYPER << UL); + + return switches; +} + +static uint64 keyboard_switches (void) +{ + uint64 switches = 0777777777777LL; /* 1 is off */ + #if 1 #define DEBUGSW(X) (void)0 #else @@ -433,15 +521,118 @@ t_stat wcnsls_devio(uint32 dev, uint64 *data) { SPACEWAR_SWITCHES; #undef SWSW - if (spacewar_switches) - DEBUGSW(("in %#lo out %#llo\r\n", spacewar_switches, switches)); + if (spacewar_switches) + DEBUGSW(("in %#lo out %#llo\r\n", spacewar_switches, switches)); + + + return switches; +} + +t_stat wcnsls_devio(uint32 dev, uint64 *data) { + switch (dev & 3) { + case CONO: + /* CONO WCNSLS,40 ;enable spacewar consoles */ + break; + + case DATAI: + if (wcnsls_unit->flags & UNIT_JOY) { + *data = joystick_switches (); + } else { + *data = keyboard_switches (); + } - *data = switches; sim_debug(DEBUG_DATAIO, &wcnsls_dev, "WCNSLS %03o DATI %012llo PC=%06o\n", - dev, switches, PC); + dev, *data, PC); + break; + } + return SCPE_OK; +} + +/* + * Old MIT Spacewar console switches + */ +#if NUM_DEVS_OCNSLS > 0 +#define OCNSLS_DEVNUM 0724 + +t_stat ocnsls_devio(uint32 dev, uint64 *data); +const char *ocnsls_description (DEVICE *dptr); + +DIB ocnsls_dib[] = { + { OCNSLS_DEVNUM, 1, &ocnsls_devio, NULL }}; + +UNIT ocnsls_unit[] = { + { UDATA (NULL, UNIT_IDLE, 0) }}; + +DEVICE ocnsls_dev = { + "OCNSLS", ocnsls_unit, NULL, NULL, + NUM_DEVS_OCNSLS, 0, 0, 0, 0, 0, + NULL, NULL, NULL, + NULL, NULL, NULL, + &ocnsls_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, NULL, + NULL, NULL, NULL, NULL, NULL, &ocnsls_description + }; + +const char *ocnsls_description (DEVICE *dptr) +{ + return "Old MIT Spacewar Consoles"; +} + +#define OHYPER 0004LL /* Hyperspace. */ +#define OFIRE 0010LL /* Fire torpedo. */ +#define OCW 0020LL /* Turn clockwise. */ +#define OCCW 0040LL /* Turn counter clockwise. */ +#define SLOW 0100LL /* Weak thrust. */ +#define FAST 0200LL /* Strong thrust. */ +#define BEACON 020000LL /* Aiming beacon. */ + +static uint64 old_switches (void) +{ + uint64 switches = 0; + + if (joy_axes[JOY0] > JOY_TRIG) + switches |= OCCW; + else if (joy_axes[JOY0] < -JOY_TRIG) + switches |= OCW; + if (joy_axes[JOY0+1] < -JOY_TRIG) + switches |= FAST; + if (joy_axes[JOY0+1] > JOY_TRIG) + switches |= SLOW; + if (joy_buttons[BUT0]) + switches |= OFIRE; + if (joy_buttons[BUT0+1]) + switches |= OHYPER; + if (joy_buttons[BUT0+2]) + switches |= BEACON; + + if (joy_axes[JOY1] > JOY_TRIG) + switches |= OCCW << 18; + else if (joy_axes[JOY1] < -JOY_TRIG) + switches |= OCW << 18; + if (joy_axes[JOY1+1] < -JOY_TRIG) + switches |= FAST << 18; + if (joy_axes[JOY1+1] > JOY_TRIG) + switches |= SLOW << 18; + if (joy_buttons[BUT1]) + switches |= OFIRE << 18; + if (joy_buttons[BUT1+1]) + switches |= OHYPER << 18; + if (joy_buttons[BUT1+2]) + switches |= BEACON << 18; + + return switches; +} + +t_stat ocnsls_devio(uint32 dev, uint64 *data) { + switch (dev & 3) { + case DATAI: + *data = old_switches (); + break; + case CONI: + *data = 0; break; } return SCPE_OK; } #endif #endif +#endif diff --git a/PDP10/kx10_sys.c b/PDP10/kx10_sys.c index 10bf9f3..ae11caa 100644 --- a/PDP10/kx10_sys.c +++ b/PDP10/kx10_sys.c @@ -161,6 +161,9 @@ DEVICE *sim_devices[] = { #if (NUM_DEVS_WCNSLS > 0) &wcnsls_dev, #endif +#if (NUM_DEVS_OCNSLS > 0) + &ocnsls_dev, +#endif #endif #if (NUM_DEVS_III > 0) &iii_dev,