153 lines
5.1 KiB
C
153 lines
5.1 KiB
C
/* pdp1_dpy.c: PDP-1 display simulator
|
||
|
||
Copyright (c) 2004, Philip L. Budne
|
||
Copyright (c) 1993-2003, Robert M. Supnik
|
||
|
||
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
|
||
THE AUTHORS 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.
|
||
|
||
Except as contained in this notice, the names of the authors shall not be
|
||
used in advertising or otherwise to promote the sale, use or other dealings
|
||
in this Software without prior written authorization from the authors.
|
||
|
||
dpy Type 30 Display for the PDP-1
|
||
02-Feb-04 PLB Revamp intensity levels
|
||
02-Jan-04 DAG Provide dummy global when display not supported
|
||
16-Sep-03 PLB Update for SIMH 3.0-2
|
||
12-Sep-03 PLB Add spacewar switch support
|
||
04-Sep-03 PLB Start from pdp1_lp.c
|
||
*/
|
||
|
||
#ifdef USE_DISPLAY
|
||
#include "pdp1_defs.h"
|
||
#include "display/display.h"
|
||
|
||
extern int32 ios, cpls, iosta, PF;
|
||
extern int32 stop_inst;
|
||
|
||
t_stat dpy_svc (UNIT *uptr);
|
||
t_stat dpy_reset (DEVICE *dptr);
|
||
|
||
/* DPY data structures
|
||
|
||
dpy_dev DPY device descriptor
|
||
dpy_unit DPY unit
|
||
dpy_reg DPY register list
|
||
*/
|
||
|
||
#define CYCLE_TIME 5 /* 5us memory cycle */
|
||
#define DPY_WAIT (50/CYCLE_TIME) /* 50us */
|
||
|
||
UNIT dpy_unit = {
|
||
UDATA (&dpy_svc, UNIT_ATTABLE, 0), DPY_WAIT };
|
||
|
||
DEVICE dpy_dev = {
|
||
"DPY", &dpy_unit, NULL, NULL,
|
||
1, 10, 31, 1, 8, 8,
|
||
NULL, NULL, &dpy_reset,
|
||
NULL, NULL, NULL,
|
||
NULL, DEV_DIS | DEV_DISABLE };
|
||
|
||
/* Display IOT routine */
|
||
|
||
int32 dpy (int32 inst, int32 dev, int32 io, int32 ac)
|
||
{
|
||
int32 x, y;
|
||
int level;
|
||
|
||
if (dpy_dev.flags & DEV_DIS) /* disabled? */
|
||
return (stop_inst << IOT_V_REASON) | io; /* stop if requested */
|
||
if (GEN_CPLS (inst)) { /* comp pulse? */
|
||
ios = 0; /* clear flop */
|
||
cpls = cpls | CPLS_DPY; } /* request completion */
|
||
else cpls = cpls & ~CPLS_DPY;
|
||
|
||
x = (ac >> 8) & 01777; /* high ten bits of ac */
|
||
y = (io >> 8) & 01777; /* high ten bits of io */
|
||
/*
|
||
* convert one's complement -511..+511 center origin
|
||
* to 0..1022 (lower left origin)
|
||
*/
|
||
if (x & 01000)
|
||
x ^= 01000;
|
||
else
|
||
x += 511;
|
||
if (y & 01000)
|
||
y ^= 01000;
|
||
else
|
||
y += 511;
|
||
|
||
/* intensity, from values seen in spacewar (40,00,01,02,03) */
|
||
switch ((inst >> 6) & 077) {
|
||
case 01: level = DISPLAY_INT_MAX-5; break;
|
||
case 02: level = DISPLAY_INT_MAX-4; break;
|
||
case 03: level = DISPLAY_INT_MAX-2; break;
|
||
case 040: /* super bright? */
|
||
default: level = DISPLAY_INT_MAX; break;
|
||
}
|
||
|
||
if (display_point(x,y,level,0)) {
|
||
/* here with light pen hit */
|
||
PF = PF | 010; /* set prog flag 3 */
|
||
iosta |= IOS_TTI; /* set io status flag */
|
||
}
|
||
else
|
||
iosta &= ~IOS_TTI; /* clear io status flag */
|
||
sim_activate (&dpy_unit, dpy_unit.wait); /* activate */
|
||
|
||
return io;
|
||
}
|
||
|
||
/*
|
||
* Unit service routine
|
||
*
|
||
* Under X11 this includes polling for events, so it can't be
|
||
* call TOO infrequently...
|
||
*/
|
||
t_stat dpy_svc (UNIT *uptr)
|
||
{
|
||
if (cpls & CPLS_DPY) { /* completion pulse? */
|
||
ios = 1; /* restart */
|
||
cpls = cpls & ~CPLS_DPY; } /* clr pulse pending */
|
||
|
||
display_age(dpy_unit.wait*CYCLE_TIME, 1);
|
||
sim_activate (&dpy_unit, dpy_unit.wait); /* requeue! */
|
||
return SCPE_OK;
|
||
}
|
||
|
||
/* Reset routine */
|
||
|
||
t_stat dpy_reset (DEVICE *dptr)
|
||
{
|
||
if (!(dptr->flags & DEV_DIS)) {
|
||
display_reset();
|
||
cpls = cpls & ~CPLS_DPY;
|
||
iosta = iosta & ~(IOS_PNT | IOS_SPC); /* clear flags */
|
||
}
|
||
sim_cancel (&dpy_unit); /* deactivate unit */
|
||
return SCPE_OK;
|
||
}
|
||
|
||
int32 spacewar (int32 inst, int32 dev, int32 io)
|
||
{
|
||
if (dpy_dev.flags & DEV_DIS) /* disabled? */
|
||
return (stop_inst << IOT_V_REASON) | io; /* stop if requested */
|
||
return spacewar_switches;
|
||
}
|
||
#else /* USE_DISPLAY not defined */
|
||
char pdp1_dpy_unused; /* sometimes empty object modules cause problems */
|
||
#endif /* USE_DISPLAY not defined */
|