diff --git a/PDP10/kx10_dpy.c b/PDP10/kx10_dpy.c index 58f0beb..1db3ae9 100644 --- a/PDP10/kx10_dpy.c +++ b/PDP10/kx10_dpy.c @@ -454,37 +454,63 @@ 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) +#define UNIT_JOY (1 << DEV_V_UF) /* Use USB gaming devices. */ +#define UNIT_CSCOPE (1 << (DEV_V_UF+1)) /* Enable color scope. */ t_stat wcnsls_devio(uint32 dev, uint64 *data); +t_stat wcnsls_svc (UNIT *uptr); +t_stat wcnsls_reset (DEVICE *dptr); const char *wcnsls_description (DEVICE *dptr); +static uint64 dev420_cono = 0; +static uint8 cscope_r = 0; +static uint8 cscope_g = 0; +static uint8 cscope_b = 0; +static VID_DISPLAY *cscope_display = NULL; +static uint32 fade[512 * 512]; +static uint32 dot[7 * 7]; + DIB wcnsls_dib[] = { { WCNSLS_DEVNUM, 1, &wcnsls_devio, NULL }}; MTAB wcnsls_mod[] = { { UNIT_JOY, UNIT_JOY, "JOYSTICK", "JOYSTICK", NULL, NULL, NULL, "Use USB joysticks"}, + { UNIT_CSCOPE, UNIT_CSCOPE, "CSCOPE", "CSCOPE", NULL, NULL, NULL, + "Enable color scope"}, { 0 } }; UNIT wcnsls_unit[] = { - { UDATA (NULL, UNIT_IDLE, 0) }}; + { UDATA (wcnsls_svc, UNIT_IDLE, 0) }}; + +REG wcnsls_reg[] = { + {ORDATA(CONO, dev420_cono, 18)}, + {0} +}; DEVICE wcnsls_dev = { - "WCNSLS", wcnsls_unit, NULL, wcnsls_mod, + "WCNSLS", wcnsls_unit, wcnsls_reg, wcnsls_mod, NUM_DEVS_WCNSLS, 0, 0, 0, 0, 0, + NULL, NULL, wcnsls_reset, NULL, NULL, NULL, - NULL, NULL, NULL, - &wcnsls_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, NULL, + &wcnsls_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, dev_debug, NULL, NULL, NULL, NULL, NULL, &wcnsls_description }; const char *wcnsls_description (DEVICE *dptr) { - return "MIT Spacewar Consoles"; + return "MIT Spacewar Consoles, and DEC color scope"; } +/* Device 420 CONO bits. */ +#define CONO_BLUE 0000020 /* Color scope blue enable */ +#define CONO_SPCWAR 0000040 /* Spacewar consoles */ +#define CONO_GREEN 0002000 /* Color scope green enable */ +#define CONO_RANDOM 0004000 /* Random switches */ +#define CONO_RED 0200000 /* Color scope red enable */ +#define CONO_KNIGHT 0400000 /* Switches in TK's office */ + /* * map 32-bit "spacewar_switches" value to what PDP-6/10 game expects * (four 9-bit bytes) @@ -512,55 +538,86 @@ const char *wcnsls_description (DEVICE *dptr) #define BUT2 (JOY_MAX_BUTTONS*2) #define BUT3 (JOY_MAX_BUTTONS*3) +static void +cscope_init (void) +{ + int i; + fade[0] = vid_map_rgba_window (cscope_display, 0, 0, 0, 240); + for (i = 1; i < 512 * 512; i++) + fade[i] = fade[0]; +} + +static void +cscope_plot(int x, int y) +{ + int i, j; + for (i = 0; i < 7; i++) { + for (j = 0; j < 7; j++) { + int dx = i - 3, dy = j - 3; + int r2 = dx*dx + dy*dy; + double focus = 0.2; + double intensity = 0xFF/15.0; + double alpha = 0xFF*exp(-focus*r2); + dot[i + 7*j] = vid_map_rgba_window (cscope_display, + (uint8)(intensity*(cscope_r << 4)), + (uint8)(intensity*(cscope_g << 4)), + (uint8)(intensity*(cscope_b << 4)), + (uint8)alpha); + } + } + + vid_draw_window (cscope_display, x - 3, 511 - y - 3, 7, 7, dot); +} + static uint64 joystick_switches (void) { - uint64 switches = 0777777777777LL; + 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[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[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[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); + 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; + return switches; } static uint64 keyboard_switches (void) @@ -589,17 +646,66 @@ static uint64 keyboard_switches (void) return switches; } +t_stat wcnsls_svc (UNIT *uptr) +{ + vid_refresh_window (cscope_display); + vid_draw_window (cscope_display, 0, 0, 512, 512, fade); + sim_activate_after (uptr, 33333); + return SCPE_OK; +} + +t_stat +wcnsls_reset (DEVICE *dptr) +{ + t_stat r; + if (sim_switches & SWMASK('P') || dptr->flags & DEV_DIS || + (wcnsls_unit->flags & UNIT_CSCOPE) == 0) { + sim_cancel (wcnsls_unit); + if (cscope_display != NULL) + vid_close_window (cscope_display); + cscope_display = NULL; + } else if (cscope_display == NULL) { + r = vid_open_window (&cscope_display, dptr, "Color scope", 512, 512, 0); + if (r != SCPE_OK) + return r; + /* Allow time for window to open and data structures to settle. */ + sim_os_sleep (1); + r = vid_set_alpha_mode (cscope_display, SIM_ALPHA_BLEND); + if (r != SCPE_OK) + return r; + sim_activate_abs (wcnsls_unit, 0); + cscope_init (); + } + return SCPE_OK; +} + t_stat wcnsls_devio(uint32 dev, uint64 *data) { switch (dev & 3) { case CONO: /* CONO WCNSLS,40 ;enable spacewar consoles */ + sim_debug (DEBUG_CONO, &wcnsls_dev, "%06llo\n", *data); + dev420_cono = *data; + if (dev420_cono & CONO_RED) + cscope_r = (dev420_cono >> 12) & 017; + if (dev420_cono & CONO_GREEN) + cscope_g = (dev420_cono >> 6) & 017; + if (dev420_cono & CONO_BLUE) + cscope_b = dev420_cono & 017; + break; + + case DATAO: + sim_debug (DEBUG_DATAIO, &wcnsls_dev, "DATAO %012llo\n", *data); + if (wcnsls_unit->flags & UNIT_CSCOPE) + cscope_plot((*data >> 9) & 0777, *data & 0777); break; case DATAI: - if (wcnsls_unit->flags & UNIT_JOY) { - *data = joystick_switches (); - } else { - *data = keyboard_switches (); + if (dev420_cono & CONO_SPCWAR) { + if (wcnsls_unit->flags & UNIT_JOY) { + *data = joystick_switches (); + } else { + *data = keyboard_switches (); + } } sim_debug(DEBUG_DATAIO, &wcnsls_dev, "WCNSLS %03o DATI %012llo PC=%06o\n", @@ -648,39 +754,39 @@ const char *ocnsls_description (DEVICE *dptr) static uint64 old_switches (void) { - uint64 switches = 0; + 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[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; + 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; + return switches; } t_stat ocnsls_devio(uint32 dev, uint64 *data) {