From d8c7a58d61a1658779fdfb072af932e928fff2a7 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Sat, 27 Mar 2021 15:22:00 +0100 Subject: [PATCH] KA10: Stanford TV device with Spacewar buttons. Only the buttons are included at this point. --- PDP10/ka10_tv.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++ PDP10/kx10_defs.h | 2 + PDP10/kx10_dpy.c | 2 +- PDP10/kx10_sys.c | 3 ++ makefile | 3 +- 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 PDP10/ka10_tv.c diff --git a/PDP10/ka10_tv.c b/PDP10/ka10_tv.c new file mode 100644 index 0000000..719d55a --- /dev/null +++ b/PDP10/ka10_tv.c @@ -0,0 +1,130 @@ +/* ka10_tv.c: Stanford TV camera and Spacewar buttons. + + Copyright (c) 2021, Lars Brinkhoff + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + LARS BRINKHOFF BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +#include "kx10_defs.h" +#include "sim_video.h" + +#if NUM_DEVS_TV > 0 + +#define TV_DEVNUM 0404 + +#define JOY_MAX_UNITS 5 +#define JOY_MAX_AXES 4 +#define JOY_MAX_BUTTONS 4 + +#define JOY_TRIG 5000 + +#define ROTATE_AXIS 0 +#define THRUSTER_AXIS 1 +#define TORPEDO_BUTTON 0 +#define HYPER_BUTTON 1 + +/* CONI bits. */ +#define TPBIT 001LL /* Fire torpedo. */ +#define THRUBT 002LL /* Thruster. */ +#define ROTRBT 004LL /* Rotate right. */ +#define ROTLBT 010LL /* Rotate left. */ +#define HYPRBT 014LL /* Hyperspace = right + left. */ + +static t_stat tv_devio(uint32 dev, uint64 *data); +static t_stat tv_reset (DEVICE *dptr); +static const char *tv_description (DEVICE *dptr); + +static int joy_axes[JOY_MAX_UNITS][JOY_MAX_AXES]; +static int joy_buttons[JOY_MAX_UNITS][JOY_MAX_BUTTONS]; + +DIB tv_dib = { TV_DEVNUM, 1, &tv_devio, NULL }; + +DEVICE tv_dev = { + "TV", NULL, NULL, NULL, + 0, 8, 0, 1, 8, 36, + NULL, NULL, &tv_reset, NULL, NULL, NULL, + &tv_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, dev_debug, + NULL, NULL, NULL, NULL, NULL, &tv_description +}; + +static void tv_joy_motion(int which, int axis, int value) +{ + if (which < JOY_MAX_UNITS && axis < JOY_MAX_AXES) { + joy_axes[which][axis] = value; + sim_debug (DEBUG_DETAIL, &tv_dev, "Joystick %d axid %d: value %d\n", + which, axis, value); + } +} + +static void tv_joy_button(int which, int button, int state) +{ + if (which < JOY_MAX_UNITS && button < JOY_MAX_BUTTONS) { + joy_buttons[which][button] = state; + sim_debug (DEBUG_DETAIL, &tv_dev, "Joystick %d button %d: state %d\n", + which, button, state); + } +} + +static uint64 tv_buttons (void) +{ + uint64 buttons = 2; /* Needed for unknown reason! */ + int i; + + for (i = 0; i < JOY_MAX_UNITS; i++) { + if (joy_axes[i][ROTATE_AXIS] > JOY_TRIG) + buttons ^= ROTRBT << (4 * i); + else if (joy_axes[i][ROTATE_AXIS] < -JOY_TRIG) + buttons ^= ROTLBT << (4 * i); + if (joy_axes[i][THRUSTER_AXIS] < -JOY_TRIG) + buttons ^= THRUBT << (4 * i); + if (joy_buttons[i][TORPEDO_BUTTON]) + buttons ^= TPBIT << (4 * i); + if (joy_buttons[i][HYPER_BUTTON]) + buttons ^= HYPRBT << (4 * i); + } + + return buttons; +} + +t_stat tv_devio(uint32 dev, uint64 *data) +{ + switch(dev & 07) { + case CONI|4: + *data = tv_buttons (); + sim_debug (DEBUG_CONI, &tv_dev, "%07llo\n", *data); + break; + } + + return SCPE_OK; +} + +static t_stat tv_reset (DEVICE *dptr) +{ + memset (joy_axes, 0, sizeof joy_axes); + memset (joy_buttons, 0, sizeof joy_buttons); + vid_register_gamepad_motion_callback (tv_joy_motion); + vid_register_gamepad_button_callback (tv_joy_button); + return SCPE_OK; +} + +const char *tv_description (DEVICE *dptr) +{ + return "Stanford TV camera and Spacewar buttons"; +} +#endif diff --git a/PDP10/kx10_defs.h b/PDP10/kx10_defs.h index 2b29e9b..032e3f0 100644 --- a/PDP10/kx10_defs.h +++ b/PDP10/kx10_defs.h @@ -507,6 +507,7 @@ extern DEVICE dkb_dev; extern DEVICE auxcpu_dev; extern DEVICE slave_dev; extern DEVICE dpk_dev; +extern DEVICE tv_dev; extern DEVICE wcnsls_dev; /* MIT Spacewar Consoles */ extern DEVICE ocnsls_dev; /* Old MIT Spacewar Consoles */ extern DEVICE ai_dev; @@ -720,6 +721,7 @@ extern void ka10_lights_clear_aux (int); #define NUM_DEVS_PMP WAITS #define NUM_DEVS_DKB (WAITS * USE_DISPLAY) #define NUM_DEVS_III (WAITS * USE_DISPLAY) +#define NUM_DEVS_TV (WAITS * USE_DISPLAY) #define NUM_DEVS_PD ITS #define NUM_DEVS_PCLK WAITS #define NUM_DEVS_IMX ITS diff --git a/PDP10/kx10_dpy.c b/PDP10/kx10_dpy.c index 1db3ae9..be0eb9e 100644 --- a/PDP10/kx10_dpy.c +++ b/PDP10/kx10_dpy.c @@ -357,7 +357,7 @@ static void dpy_joy_motion(int which, int axis, int 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; + joy_buttons[which * JOY_MAX_BUTTONS + button] = state; } } diff --git a/PDP10/kx10_sys.c b/PDP10/kx10_sys.c index 71ad9a2..f2d900e 100644 --- a/PDP10/kx10_sys.c +++ b/PDP10/kx10_sys.c @@ -174,6 +174,9 @@ DEVICE *sim_devices[] = { #if (NUM_DEVS_III > 0) &iii_dev, #endif +#if (NUM_DEVS_TV > 0) + &tv_dev, +#endif #if NUM_DEVS_IMP > 0 &imp_dev, #endif diff --git a/makefile b/makefile index 11fe530..ba91549 100644 --- a/makefile +++ b/makefile @@ -2103,7 +2103,8 @@ KA10 = ${KA10D}/kx10_cpu.c ${KA10D}/kx10_sys.c ${KA10D}/kx10_df.c \ ${KA10D}/pdp6_dtc.c ${KA10D}/pdp6_mtc.c ${KA10D}/pdp6_dsk.c \ ${KA10D}/pdp6_dcs.c ${KA10D}/ka10_dpk.c ${KA10D}/kx10_dpy.c \ ${PDP10D}/ka10_ai.c ${KA10D}/ka10_iii.c ${KA10D}/kx10_disk.c \ - ${PDP10D}/ka10_pclk.c ${DISPLAYL} ${DISPLAY340} ${DISPLAYIII} + ${PDP10D}/ka10_pclk.c ${PDP10D}/ka10_tv.c \ + ${DISPLAYL} ${DISPLAY340} ${DISPLAYIII} KA10_OPT = -DKA=1 -DUSE_INT64 -I ${KA10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KA10_DISPLAY_OPT} ifneq (${PANDA_LIGHTS},) # ONLY for Panda display.