DISPLAY: Latest version of display code from Phil Budne and Doug Gwyn including initial pdp1_dpy and pdp11_vt

This commit is contained in:
Mark Pizzolato 2013-10-16 01:02:12 -07:00
parent 026dd98d83
commit 1e3586ec91
42 changed files with 21636 additions and 8327 deletions

1
.gitattributes vendored
View file

@ -3,5 +3,6 @@
*.vcproj binary *.vcproj binary
*.exe binary *.exe binary
*.bin binary *.bin binary
*.rim binary
sim_rev.h export-subst sim_rev.h export-subst

View file

@ -25,13 +25,14 @@
cpu PDP-1 central processor cpu PDP-1 central processor
210Mar-12 RMS Fixed & vs && in Ea_ch (Michael Bloom) 21-Mar-12 RMS Fixed & vs && in Ea_ch (Michael Bloom)
30-May-07 RMS Fixed typo in SBS clear (Norm Lastovica) 30-May-07 RMS Fixed typo in SBS clear (Norm Lastovica)
28-Dec-06 RMS Added 16-channel SBS support, PDP-1D support 28-Dec-06 RMS Added 16-channel SBS support, PDP-1D support
28-Jun-06 RMS Fixed bugs in MUS and DIV 28-Jun-06 RMS Fixed bugs in MUS and DIV
22-Sep-05 RMS Fixed declarations (Sterling Garwood) 22-Sep-05 RMS Fixed declarations (Sterling Garwood)
16-Aug-05 RMS Fixed C++ declaration and cast problems 16-Aug-05 RMS Fixed C++ declaration and cast problems
09-Nov-04 RMS Added instruction history 09-Nov-04 RMS Added instruction history
08-Feb-04 PLB Added display device spacewar/test switches
07-Sep-03 RMS Added additional explanation on I/O simulation 07-Sep-03 RMS Added additional explanation on I/O simulation
01-Sep-03 RMS Added address switches for hardware readin 01-Sep-03 RMS Added address switches for hardware readin
23-Jul-03 RMS Revised to detect I/O wait hang 23-Jul-03 RMS Revised to detect I/O wait hang
@ -360,6 +361,10 @@ extern int32 dt (int32 inst, int32 dev, int32 dat);
extern int32 drm (int32 inst, int32 dev, int32 dat); extern int32 drm (int32 inst, int32 dev, int32 dat);
extern int32 clk (int32 inst, int32 dev, int32 dat); extern int32 clk (int32 inst, int32 dev, int32 dat);
extern int32 dcs (int32 inst, int32 dev, int32 dat); extern int32 dcs (int32 inst, int32 dev, int32 dat);
#ifdef USE_DISPLAY
extern int32 dpy (int32 inst, int32 dev, int32 dat, int32 dat2);
extern int32 spacewar (int32 inst, int32 dev, int32 dat);
#endif
const int32 sc_map[512] = { const int32 sc_map[512] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, /* 00000xxxx */ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, /* 00000xxxx */
@ -1203,6 +1208,11 @@ while (reason == 0) { /* loop until halted */
io_data = ptp (IR, dev, IO); io_data = ptp (IR, dev, IO);
break; break;
#ifdef USE_DISPLAY
case 007: /* display */
io_data = dpy (IR, dev, IO, AC);
break;
#endif
case 010: /* leave ring mode */ case 010: /* leave ring mode */
if (cpu_unit.flags & UNIT_1D) if (cpu_unit.flags & UNIT_1D)
PF = PF & ~PF_RNG; PF = PF & ~PF_RNG;
@ -1212,7 +1222,12 @@ while (reason == 0) { /* loop until halted */
case 011: /* enter ring mode */ case 011: /* enter ring mode */
if (cpu_unit.flags & UNIT_1D) if (cpu_unit.flags & UNIT_1D)
PF = PF | PF_RNG; PF = PF | PF_RNG;
else reason = stop_inst; else
#ifdef USE_DISPLAY
io_data = spacewar (IR, dev, IO);
#else
reason = stop_inst;
#endif
break; break;
case 022: /* data comm sys */ case 022: /* data comm sys */
@ -1685,3 +1700,19 @@ for (k = 0; k < lnt; k++) { /* print specified */
} /* end for */ } /* end for */
return SCPE_OK; return SCPE_OK;
} }
#ifdef USE_DISPLAY
/* set "test switches"; from display code */
void
cpu_set_switches(unsigned long bits)
{
/* just what we want; smaller CPUs might want to shift down? */
TW = bits;
}
unsigned long
cpu_get_switches(void)
{
return TW;
}
#endif

153
PDP1/pdp1_dpy.c Normal file
View file

@ -0,0 +1,153 @@
/* 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 */

View file

@ -58,7 +58,9 @@ extern DEVICE dt_dev;
extern DEVICE drm_dev; extern DEVICE drm_dev;
extern DEVICE drp_dev; extern DEVICE drp_dev;
extern DEVICE dcs_dev, dcsl_dev; extern DEVICE dcs_dev, dcsl_dev;
#if defined(USE_DISPLAY)
extern DEVICE dpy_dev; extern DEVICE dpy_dev;
#endif
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern REG cpu_reg[]; extern REG cpu_reg[];
extern int32 M[]; extern int32 M[];
@ -95,7 +97,9 @@ DEVICE *sim_devices[] = {
&drp_dev, &drp_dev,
&dcs_dev, &dcs_dev,
&dcsl_dev, &dcsl_dev,
/* &dpy_dev, */ #if defined(USE_DISPLAY)
&dpy_dev,
#endif
NULL NULL
}; };

64
PDP1/spacewar1/README Normal file
View file

@ -0,0 +1,64 @@
Preliminary PDP-1 Spacewar README
Phil Budne
February 9, 2004
Both spacewar.mac and macro1.c are available from Phil's CVS server.
see http://www.ultimate.com/phil/xy
cvs -d :pserver:anonymous@cvs.ultimate.com:/home/cvs login
Password: anonymous
cvs -d :pserver:anonymous@cvs.ultimate.com:/home/cvs co history/pdp1
README.MIT
readme from MIT
contains history, and instructions
spacewar.mac
spacewar 3.1 (24 sep 62) retyped at MIT from a listing,
originally assembled using a Perl macro-expander and assembler,
and run under a Java PDP-1 emulator.
This version modified by Phil Budne to assemble under his
version of "macro1" (see below)
Note that low memory (locations 6 thru 31) contains various
manifest constants which can be tweaked to alter the game's
behavior!
spacewar.rim
above assembled by Phil Budne's macro1
PDP-1 RIM of "loader" followed by loader blocks:
PDP-1 simulator V4.0
sim> set dpy enable
sim> attach ptr spacewar.rim
sim> boot ptr
controls compatible with MIT Java simulation, see README.LCS
or display/README from your SIMH distribution
munch.mac
"munching squares" display hack, reconstructed
from world.std.com/~dpbsmith/munch.html
munch.rim
binary of munching squares.
reads console switches:
Upto 18 simulated console switches, toggled by hitting keys:
123 456 789 qwe rty uio
space bar clears all switches.
assembled with '-r' option, so it can be "loaded" directly:
PDP-1 simulator V4.0
sim> set dpy enable
sim> load munch.rim
sim> run
macro1.c
Phil Budne's version of the MACRO cross-assembler

25
PDP1/spacewar1/README.MIT Normal file
View file

@ -0,0 +1,25 @@
Spacewar! was conceived in 1961 by Martin Graetz, Stephen Russell, and
Wayne Wiitanen. It was first realized on the PDP-1 in 1962 by Stephen
Russell, Peter Samson, Dan Edwards, and Martin Graetz, together with
Alan Kotok, Steve Piner, and Robert A Saunders. Spacewar! is in the
public domain, but this credit paragraph must accompany all
distributed versions of the program.
This is the original version! Martin Graetz provided us with a printed
version of the source. We typed in in again - it was about 40 pages
long - and re-assembled it with a PDP-1 assembler written in PERL. The
resulting binary runs on a PDP-1 emulator written as a Java applet.
The code is extremely faithful to the original. There are only two
changes. 1)The spaceships have been made bigger and 2) The overall
timing has been special cased to deal with varying machine speeds.
The sources are available in a subdirectory called "sources".
The "a", "s", "d", "f" keys control one of the spaceships. The "k",
"l", ";", "'" keys control the other. The controls are spin one way,
spin the other, thrust, and fire.
Barry Silverman
Brian Silverman
Vadim Gerasimov

3068
PDP1/spacewar1/macro1.c Normal file

File diff suppressed because it is too large Load diff

21
PDP1/spacewar1/munch.mac Normal file
View file

@ -0,0 +1,21 @@
munching squares
1000/
// from dpbsmith's web page:
// http://world.std.com/~dpbsmith/munch.html
// classic: 04000
// fun: 1, 4014, 4016, 100000
foo, lat
add \v
dac v
rcl 9s
xor v
dpy-4000
jmp foo
variables
start foo

BIN
PDP1/spacewar1/munch.rim Normal file

Binary file not shown.

1857
PDP1/spacewar1/spacewar.mac Normal file

File diff suppressed because it is too large Load diff

BIN
PDP1/spacewar1/spacewar.rim Normal file

Binary file not shown.

52
PDP11/lunar11/README.txt Normal file
View file

@ -0,0 +1,52 @@
VT11/GT40 Lunar Lander files
preliminary README phil
Phil Budne
February 9, 2004
Lunar lander startup can take forever (lander uses spin loop to count
down time for display of starting screen. This may be due to the fact
that SIMH only tracks cycles in terms of instructions, not execution
time). To speed up display of the startup screen, deposit a 1 in
location 32530 after loading the lander program, and before starting
it;
sim> ! Set CPU to a Unibus system type
sim> set cpu 11/70
sim> ! Enable DLI device so VT device autoconfigures
sim> ! with a starting vector of 320
sim> set dli enable
sim> set dli line=2
sim> ! Enable VT device
sim> set vt enable
sim> load lunar.lda
sim> dep 32530 1
sim> run
Lunar lander only needs a small screen area, and can run using a
simulated "VR14" display, which can fit on many computer screens
without scaling:
sim> set vt crt=vr14
sim> set vt scale=1
For more information on the VT11/GT40 see
http://www.brouhaha.com/~eric/retrocomputing/dec/gt40/
lunar.txt
Lunar lander instructions
(from ???)
lunar.lda
PDP-11 Paper Tape (LDA) format
http://www.brouhaha.com/~eric/retrocomputing/dec/gt40/software/moonlander/lunar.lda
lunar.dag
PDP-11 Paper Tape (LDA) format
above(?) as patched by Doug Gwyn to fix a spelling error?
load fails with bad checksum under 3.2-preview2?
gtlem.mac
Does not match above binaries??
http://www.brouhaha.com/~eric/retrocomputing/dec/gt40/software/moonlander/gtlem.mac

5102
PDP11/lunar11/gtlem.mac Normal file

File diff suppressed because it is too large Load diff

BIN
PDP11/lunar11/lunar.dag Normal file

Binary file not shown.

BIN
PDP11/lunar11/lunar.lda Normal file

Binary file not shown.

114
PDP11/lunar11/lunar.txt Normal file
View file

@ -0,0 +1,114 @@
PLAYING MOONLANDER (LEM)
The object of moonlander is to land a lunar module on the
surface of the moon. The program will run on any 8K GT40
with a light pen and a clock. If you are attached to a PDP-10
you may use the ROM bootstrap to bring over the assembled
binary. If you are not "talking" to a PDP-10, you may load
in the binary loader (absolute loader) and load in the paper
tape version of the program. Note: the program will destroy
the binary loader when it starts running.
When the program is loaded, it will automatically start and
display an "introductory message" on the screen. Future
restart of the program will not cause this message to be
displayed. Should any problems occur, the program may be
restarted at any time at location zero (000000). Power fail
protection is also provided. After starting (or restarting),
you then start playing the actual game. All numbers, speeds,
weights, etc., are actual numbers. They are for real. To
make the game more possible for an average person to play, I
have given him about 25 to 50% more fuel in the final stages
of landing than he would actually have.
What the user sees on the screen is a broad and extremely
mountainous view of the moon. On the right is a list of data
parameters which the user may examine. They are height,
altitude, angle, fuel left, thrust, weight, horizontal velocity,
vertical velocity, horizontal acceleration, vertical accelera-
tion, distance and seconds. At the top of the screen, any
four of the values may be displayed. To display an item, the
user points the light pen at the item he wishes to display.
The item will then start blinking, to indicate that this is the
item to be displayed. The user then points the light pen at
one of the previously displayed items at the top of the screen.
The old item disappears and is replaced by the new item.
Note that it is possible to display any item anywhere, and even
possible to display one item four times at the top. Anyway,
the parameters mean the following. Height is the height in
feet above the surface (terrain) of the moon. It is the "radar"
height. Altitude is the height above the "mean" height of the
moon ( I guess you would call it "mare" level). Thus altitude
is not affected by terrain. Angle is the angle of the ship in
relationship to the vertical. 10 degrees, -70 degrees, etc.
Fuel left is the amount of fuel left in pounds. Thrust is the
amount of thrust (pounds) currently being produced by the engine.
Weight is the current earth weight of the ship. As fuel is
burned off, the acceleration will increase due to a lessening of
weight. The horizontal velocity is the current horizontal speed
of the ship, in feet per second. It is necessary to land at
under 10 fps horizontal, or else the ship will tip over.
Vertical velocity is the downward speed of the ship. Try to
keep it under 30 for the first few landings, until you get
better. A perfect landing is under 8 fps. The horizontal
and vertical accelerations are just those, in f/sec/sec.
With no power, the vertical acceleration is about 5 fp/s/s
down (-5). Distance is the horizontal distance (X direction)
you are from the projected landing site. Try to stay within
500 feet of this distance, because there are not too many
spots suitable for landing on the moon. Seconds is just the
time since you started trying to land. Thus you now know how
to display information and what they mean.
To control the ship, two controls are provided. The first
controls the rolling or turning of the ship. This is accom-
plished by four arrows just above the display menu. Two point
left and two point right. The two pointing left mean rotate
left and the two pointing right mean rotate right. There is
a big and a little one in each direction. The big one means
to rotate "fast" and the small one means to rotate "slow".
Thus to rotate fast left, you point the light pen at
left arrow. To rotate slow right, you point the light pen at
the small arrow pointing to the right. The arrow will get
slightly brighter to indicate you have chosen it. Above the
arrow there is a bright, solid bar. This bar is your throttle
bar. To its left there is a number in percent (say 50%). This
number indicates the percentage of full thrust your rocket
engine is developing. The engine can develop anywhere from
10% to 100% thrust - full thrust is 10,500 pounds. The
engine thrust cannot fall below 10%. That is the way Grumman
built it (actually the subcontractor). To increase or decrease
your thrust, you merely slide the light pen up and down the bar.
The indicated percentage thrust will change accordingly.
Now we come to actually flying the beast. The module appears
in the upper left hand corner of the screen and is traveling
down and to the right. Your job is to land at the correct
spot (for the time being, we will say this is when the
distance and height both reach zero). The first picture you
see, with the module in the upper left hand corner, is not
drawn to scale (the module appears too big in relationship
to the mountains). Should you successfully get below around
400 feet altitude, the view will now change to a closeup
view of the landing site, and everything will be in scale.
Remember, it is not easy to land the first few times, but
don't be disappointed, you'll do it. Be careful, the game
is extremely addictive. It is also quite dynamic.
Incorporated in the game are just about everything the GT40
can do. Letters, italics, light pen letters, a light bar,
dynamic motion, various line types and intensities (the moon
is not all the same brightness you know). It also shows that
the GT40 can do a lot of calculations while maintaining a
reasonable display.
There are three possible landing sites on the Moon:
1. On the extreme left of the landscape
2. A small flat area to the right of the mountains
3. In the large "flat" area on the right
Good Luck!

View file

@ -620,6 +620,14 @@ typedef struct pdp_dib DIB;
#define INT_V_DLO 10 #define INT_V_DLO 10
#define INT_V_DCI 11 #define INT_V_DCI 11
#define INT_V_DCO 12 #define INT_V_DCO 12
/* VT simulation is sequential, so only
one interrupt is posted at a time. */
#define INT_V_VTLP 13 /* XXX - Manual says VTLP, VTST have opposite */
#define INT_V_VTST 14 /* XXX precedence, but that breaks LUNAR! */
/* XXX How this happens is an utter mystery. */
#define INT_V_VTCH 15
#define INT_V_VTNM 16
#define INT_V_LK 17
#define INT_V_PIR3 0 /* BR3 */ #define INT_V_PIR3 0 /* BR3 */
#define INT_V_PIR2 0 /* BR2 */ #define INT_V_PIR2 0 /* BR2 */
@ -667,6 +675,11 @@ typedef struct pdp_dib DIB;
#define INT_DLO (1u << INT_V_DLO) #define INT_DLO (1u << INT_V_DLO)
#define INT_DCI (1u << INT_V_DCI) #define INT_DCI (1u << INT_V_DCI)
#define INT_DCO (1u << INT_V_DCO) #define INT_DCO (1u << INT_V_DCO)
#define INT_VTLP (1u << INT_V_VTLP)
#define INT_VTST (1u << INT_V_VTST)
#define INT_VTCH (1u << INT_V_VTCH)
#define INT_VTNM (1u << INT_V_VTNM)
#define INT_LK (1u << INT_V_LK)
#define INT_PIR3 (1u << INT_V_PIR3) #define INT_PIR3 (1u << INT_V_PIR3)
#define INT_PIR2 (1u << INT_V_PIR2) #define INT_PIR2 (1u << INT_V_PIR2)
#define INT_PIR1 (1u << INT_V_PIR1) #define INT_PIR1 (1u << INT_V_PIR1)
@ -717,6 +730,11 @@ typedef struct pdp_dib DIB;
#define IPL_DLO 4 #define IPL_DLO 4
#define IPL_DCI 4 #define IPL_DCI 4
#define IPL_DCO 4 #define IPL_DCO 4
#define IPL_VTLP 4
#define IPL_VTST 4
#define IPL_VTCH 4
#define IPL_VTNM 4
#define IPL_LK 4 /* XXX just a guess */
#define IPL_PIR7 7 #define IPL_PIR7 7
#define IPL_PIR6 6 #define IPL_PIR6 6

View file

@ -528,8 +528,8 @@ AUTO_CON auto_tab[] = {/*c #v am vm fxa fxv */
{ { NULL }, 1, 2, 0, 8, { 0 } }, /* DLV11J - fx CSRs */ { { NULL }, 1, 2, 0, 8, { 0 } }, /* DLV11J - fx CSRs */
{ { NULL }, 1, 2, 8, 8 }, /* DJ11 */ { { NULL }, 1, 2, 8, 8 }, /* DJ11 */
{ { NULL }, 1, 2, 16, 8 }, /* DH11 */ { { NULL }, 1, 2, 16, 8 }, /* DH11 */
{ { NULL }, 1, 4, 0, 8, { { "VT" }, 1, 4, 0, 8,
{012000, 012010, 012020, 012030} }, /* GT40 */ {012000, 012010, 012020, 012030} }, /* VT11/GT40 - fx CSRs */
{ { NULL }, 1, 2, 0, 8, { { NULL }, 1, 2, 0, 8,
{010400} }, /* LPS11 */ {010400} }, /* LPS11 */
{ { NULL }, 1, 2, 8, 8 }, /* DQ11 */ { { NULL }, 1, 2, 8, 8 }, /* DQ11 */

View file

@ -41,6 +41,7 @@
22-Jul-05 RMS Fixed missing , in initializer (Doug Gwyn) 22-Jul-05 RMS Fixed missing , in initializer (Doug Gwyn)
22-Dec-03 RMS Added second DEUNA/DELUA support 22-Dec-03 RMS Added second DEUNA/DELUA support
18-Oct-03 RMS Added DECtape off reel message 18-Oct-03 RMS Added DECtape off reel message
14-Sep-03 PLB Added VT11 support
06-May-03 RMS Added support for second DEQNA/DELQA 06-May-03 RMS Added support for second DEQNA/DELQA
09-Jan-03 RMS Added DELUA/DEUNA support 09-Jan-03 RMS Added DELUA/DEUNA support
17-Oct-02 RMS Fixed bugs in branch, SOB address parsing 17-Oct-02 RMS Fixed bugs in branch, SOB address parsing
@ -100,6 +101,9 @@ extern DEVICE tq_dev;
extern DEVICE ts_dev; extern DEVICE ts_dev;
extern DEVICE tu_dev; extern DEVICE tu_dev;
extern DEVICE ta_dev; extern DEVICE ta_dev;
#ifdef USE_DISPLAY
extern DEVICE vt_dev;
#endif
extern DEVICE xq_dev, xqb_dev; extern DEVICE xq_dev, xqb_dev;
extern DEVICE xu_dev, xub_dev; extern DEVICE xu_dev, xub_dev;
extern DEVICE ke_dev; extern DEVICE ke_dev;
@ -167,6 +171,9 @@ DEVICE *sim_devices[] = {
&tq_dev, &tq_dev,
&tu_dev, &tu_dev,
&ta_dev, &ta_dev,
#ifdef USE_DISPLAY
&vt_dev,
#endif
&xq_dev, &xq_dev,
&xqb_dev, &xqb_dev,
&xu_dev, &xu_dev,

433
PDP11/pdp11_vt.c Normal file
View file

@ -0,0 +1,433 @@
#ifdef USE_DISPLAY
/* pdp11_vt.c: PDP-11 VT11/VS60 Display Processor Simulation
Copyright (c) 2003-2004, Philip L. Budne, Douglas A. Gwyn
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.
vt VT11/VS60 Display Processor
05-Feb-04 DAG Improved VT11 emulation
Added VS60 support
14-Sep-03 PLB Start from pdp11_lp.c
*/
/*
* this file is just a thin layer of glue to the simulator-
* independent XY Display simulation
*/
#if defined (VM_VAX) /* VAX version */
#include "vax_defs.h"
#elif defined(VM_PDP11) /* PDP-11 version */
#include "pdp11_defs.h"
#else
#error "VT11/VS60 is supported only on the PDP-11 and VAX"
#endif
#include "display/display.h"
#include "display/vt11.h"
/*
* Timing parameters. Should allow some runtime adjustment,
* since several different configurations were shipped, including:
*
* GT40: PDP-11/05 with VT11 display processor
* GT44: PDP-11/40 with VT11 display processor
* GT46: PDP-11/34 with VT11 display processor
* GT62: PDP-11/34a with VS60 display system
*/
/*
* run a VT11/VS60 cycle every this many PDP-11 "cycle" times;
*
* Under the X Window System (X11), this includes polling
* for events (mouse movement)!
*/
#define VT11_DELAY 1
/*
* memory cycle time
*/
#define MEMORY_CYCLE 1 /* either .98 or 1.2 us? */
/*
* delay in microseconds between VT11/VS60 cycles:
* VT11/VS60 and PDP-11 CPU's share the same memory bus,
* and each VT11/VS60 instruction requires a memory reference;
* figure each PDP11 instruction requires two memory references
*/
#define CYCLE_US (MEMORY_CYCLE*(VT11_DELAY*2+1))
extern int32 int_req[IPL_HLVL];
extern int32 int_vec[IPL_HLVL][32];
DEVICE vt_dev;
t_stat vt_rd(int32 *data, int32 PA, int32 access);
t_stat vt_wr(int32 data, int32 PA, int32 access);
t_stat vt_svc(UNIT *uptr);
t_stat vt_reset(DEVICE *dptr);
t_stat vt_boot(int32 unit, DEVICE *dptr);
t_stat vt_set_crt(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat vt_show_crt(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat vt_set_scale(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat vt_show_scale(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat vt_set_hspace(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat vt_show_hspace(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat vt_set_vspace(UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat vt_show_vspace(FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat vt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
char *vt_description (DEVICE *dptr);
/* VT11/VS60 data structures
vt_dev VT11 device descriptor
vt_unit VT11 unit descriptor
vt_reg VT11 register list
vt_mod VT11 modifier list
*/
#define IOLN_VT11 010 /* VT11 */
#define IOLN_VS60 040 /* VS60 */
DIB vt_dib = { IOBA_AUTO, IOLN_VT11, &vt_rd, &vt_wr,
4, IVCL(VTST), VEC_AUTO, {NULL} };
/* (VT11 uses only the first 3 interrupt vectors) */
UNIT vt_unit = {
UDATA (&vt_svc, UNIT_SEQ, 0), VT11_DELAY};
REG vt_reg[] = {
{ GRDATA (DEVADDR, vt_dib.ba, DEV_RDX, 32, 0), REG_HRO },
{ GRDATA (DEVVEC, vt_dib.vec, DEV_RDX, 16, 0), REG_HRO },
{ NULL } };
MTAB vt_mod[] = {
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "CRT", "CRT={VR14|VR17|VR48}",
&vt_set_crt, &vt_show_crt, NULL, "CRT Type" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "SCALE", "SCALE={1|2|4|8}",
&vt_set_scale, &vt_show_scale, NULL, "Pixel Scale Factor" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "HSPACE", "HSPACE={NARROW|NORMAL}",
&vt_set_hspace, &vt_show_hspace, NULL, "Horizontal Spacing" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VSPACE", "VSPACE={TALL|NORMAL}",
&vt_set_vspace, &vt_show_vspace, NULL, "Vertical Spacing" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL, "Interrupt vector" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL, "Enable autoconfiguration of address & vector" },
{ 0 } };
DEVICE vt_dev = {
"VT", &vt_unit, vt_reg, vt_mod,
1, 8, 31, 1, DEV_RDX, 16,
NULL, NULL, &vt_reset,
&vt_boot, NULL, NULL,
&vt_dib, DEV_DIS | DEV_DISABLE | DEV_UBUS | DEV_Q18,
0, 0, NULL, NULL, NULL, NULL, NULL,
&vt_description
};
/* VT11/VS60 routines
vt_rd I/O page read
vt_wr I/O page write
vt_svc process event
vt_reset process reset
vt_boot bootstrap device
*/
t_stat
vt_rd(int32 *data, int32 PA, int32 access)
{
switch (PA & 036) {
case 000: *data = vt11_get_dpc(); return SCPE_OK;
case 002: *data = vt11_get_mpr(); return SCPE_OK;
case 004: *data = vt11_get_xpr(); return SCPE_OK;
case 006: *data = vt11_get_ypr(); return SCPE_OK;
case 010: if (!VS60) break; *data = vt11_get_rr(); return SCPE_OK;
case 012: if (!VS60) break; *data = vt11_get_spr(); return SCPE_OK;
case 014: if (!VS60) break; *data = vt11_get_xor(); return SCPE_OK;
case 016: if (!VS60) break; *data = vt11_get_yor(); return SCPE_OK;
case 020: if (!VS60) break; *data = vt11_get_anr(); return SCPE_OK;
case 022: if (!VS60) break; *data = vt11_get_scr(); return SCPE_OK;
case 024: if (!VS60) break; *data = vt11_get_nr(); return SCPE_OK;
case 026: if (!VS60) break; *data = vt11_get_sdr(); return SCPE_OK;
case 030: if (!VS60) break; *data = vt11_get_str(); return SCPE_OK;
case 032: if (!VS60) break; *data = vt11_get_sar(); return SCPE_OK;
case 034: if (!VS60) break; *data = vt11_get_zpr(); return SCPE_OK;
case 036: if (!VS60) break; *data = vt11_get_zor(); return SCPE_OK;
}
return SCPE_NXM;
}
t_stat
vt_wr(int32 data, int32 PA, int32 access)
{
uint16 d = data & 0177777; /* mask just in case */
switch (PA & 037) {
case 000: /* DPC */
/* set the simulator PC */
vt11_set_dpc(d);
/* clear interrupt request (only one will be simulated at a time) */
CLR_INT (VTST);
CLR_INT (VTLP);
CLR_INT (VTCH);
CLR_INT (VTNM);
/* start the display processor by running a cycle */
return vt_svc(&vt_unit);
case 002: vt11_set_mpr(d); return SCPE_OK;
case 004: vt11_set_xpr(d); return SCPE_OK;
case 006: vt11_set_ypr(d); return SCPE_OK;
case 010: if (!VS60) break; vt11_set_rr(d); return SCPE_OK;
case 012: if (!VS60) break; vt11_set_spr(d); return SCPE_OK;
case 014: if (!VS60) break; vt11_set_xor(d); return SCPE_OK;
case 016: if (!VS60) break; vt11_set_yor(d); return SCPE_OK;
case 020: if (!VS60) break; vt11_set_anr(d); return SCPE_OK;
case 022: if (!VS60) break; vt11_set_scr(d); return SCPE_OK;
case 024: if (!VS60) break; vt11_set_nr(d); return SCPE_OK;
case 026: if (!VS60) break; vt11_set_sdr(d); return SCPE_OK;
case 030: if (!VS60) break; vt11_set_str(d); return SCPE_OK;
case 032: if (!VS60) break; vt11_set_sar(d); return SCPE_OK;
case 034: if (!VS60) break; vt11_set_zpr(d); return SCPE_OK;
case 036: if (!VS60) break; vt11_set_zor(d); return SCPE_OK;
}
return SCPE_NXM;
}
/*
* here to run a display processor cycle, called as a SIMH
* "device service routine".
*
* Under X11 this includes polling for events, so it can't be
* call TOO infrequently...
*/
t_stat
vt_svc(UNIT *uptr)
{
if (vt11_cycle(CYCLE_US, 1))
sim_activate (&vt_unit, vt_unit.wait); /* running; reschedule */
return SCPE_OK;
}
t_stat
vt_reset(DEVICE *dptr)
{
if (!(dptr->flags & DEV_DIS))
vt11_reset();
CLR_INT (VTST);
CLR_INT (VTLP);
CLR_INT (VTCH);
CLR_INT (VTNM);
sim_cancel (&vt_unit); /* deactivate unit */
return auto_config ("VT", (dptr->flags & DEV_DIS) ? 0 : 1);
}
/*
* GT4x/GT62 bootstrap (acts as remote terminal)
*/
t_stat
vt_boot(int32 unit, DEVICE *dptr)
{
/* XXX should do something like vt11_set_dpc(&appropriate_ROM_image) */
return SCPE_NOFNC; /* not yet implemented */
}
/* SET/SHOW VT options: */
t_stat
vt_set_crt(UNIT *uptr, int32 val, char *cptr, void *desc)
{
char gbuf[CBUFSIZE];
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
get_glyph(cptr, gbuf, 0);
if (strcmp(gbuf, "VR14") == 0)
vt11_display = DIS_VR14;
else if (strcmp(gbuf, "VR17") == 0)
vt11_display = DIS_VR17;
else if (strcmp(gbuf, "VR48") == 0)
vt11_display = DIS_VR48;
else
return SCPE_ARG;
vt_dib.lnt = (VS60) ? IOLN_VS60 : IOLN_VT11;
return SCPE_OK;
}
t_stat
vt_show_crt(FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf(st, "crt=VR%d", (int)vt11_display);
return SCPE_OK;
}
t_stat
vt_set_scale(UNIT *uptr, int32 val, char *cptr, void *desc)
{
t_stat r;
t_value v;
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
v = get_uint(cptr, 10, 8, &r);
if (r != SCPE_OK)
return r;
if (v != 1 && v != 2 && v != 4 && v != 8)
return SCPE_ARG;
vt11_scale = v;
return SCPE_OK;
}
t_stat
vt_show_scale(FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf(st, "scale=%d", (int)vt11_scale);
return SCPE_OK;
}
t_stat
vt_set_hspace(UNIT *uptr, int32 val, char *cptr, void *desc)
{
char gbuf[CBUFSIZE];
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
get_glyph(cptr, gbuf, 0);
if (strcmp(gbuf, "NARROW") == 0)
vt11_csp_w = 12;
else if (strcmp(gbuf, "NORMAL") == 0)
vt11_csp_w = 14;
else
return SCPE_ARG;
return SCPE_OK;
}
t_stat
vt_show_hspace(FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf(st, "hspace=%s", vt11_csp_w==12 ? "narrow" : "normal");
return SCPE_OK;
}
t_stat
vt_set_vspace(UNIT *uptr, int32 val, char *cptr, void *desc)
{
char gbuf[CBUFSIZE];
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
get_glyph(cptr, gbuf, 0);
if (strcmp(gbuf, "TALL") == 0)
vt11_csp_h = 26;
else if (strcmp(gbuf, "NORMAL") == 0)
vt11_csp_h = 24;
else
return SCPE_ARG;
return SCPE_OK;
}
t_stat
vt_show_vspace(FILE *st, UNIT *uptr, int32 val, void *desc)
{
fprintf(st, "vspace=%s", vt11_csp_h==26 ? "tall" : "normal");
return SCPE_OK;
}
/* interface routines (called from display simulator) */
void
vt_stop_intr(void)
{
SET_INT (VTST);
}
void
vt_lpen_intr(void)
{
SET_INT (VTLP);
}
void
vt_char_intr(void)
{
SET_INT (VTCH);
}
void
vt_name_intr(void)
{
SET_INT (VTNM);
}
/* fetch memory */
int
vt_fetch(uint32 addr, vt11word *wp)
{
/* On PDP-11 Unibus 22-bit systems, the VT11/VS60 behaves as
an 18-bit Unibus peripheral and must go through the I/O map. */
/* apply Unibus map, when appropriate */
if (Map_ReadW(addr, 2, wp) == 0)
return 0; /* no problem */
/* else mapped address lies outside configured memory range */
*wp = 0164000; /* DNOP; just updates DPC if used */
/* which shouldn't happen */
return 1; /* used to set "time_out" flag */
}
char *vt_description (DEVICE *dptr)
{
return (VS60) ? "VS60 Display processor"
: "VT11 Display processor";
}
#ifdef VM_PDP11
/* PDP-11 simulation provides this */
extern int32 SR; /* switch register */
#else
int32 SR; /* switch register */
#endif
void
cpu_set_switches(unsigned long val)
{
SR = val;
}
unsigned long
cpu_get_switches(void)
{
return SR;
}
#else /* USE_DISPLAY not defined */
char pdp11_vt_unused; /* sometimes empty object modules cause problems */
#endif /* USE_DISPLAY not defined */

View file

@ -45,7 +45,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="./;../;../PDP1/" AdditionalIncludeDirectories="./;../;../PDP1/"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID" PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;USE_DISPLAY"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
@ -128,7 +128,7 @@
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
OmitFramePointers="true" OmitFramePointers="true"
AdditionalIncludeDirectories="./;../;../PDP1/" AdditionalIncludeDirectories="./;../;../PDP1/"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID" PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;USE_DISPLAY"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"
@ -189,6 +189,10 @@
Name="Source Files" Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
> >
<File
RelativePath="..\display\display.c"
>
</File>
<File <File
RelativePath="..\PDP1\pdp1_clk.c" RelativePath="..\PDP1\pdp1_clk.c"
> >
@ -201,6 +205,10 @@
RelativePath="..\PDP1\pdp1_dcs.c" RelativePath="..\PDP1\pdp1_dcs.c"
> >
</File> </File>
<File
RelativePath="..\PDP1\pdp1_dpy.c"
>
</File>
<File <File
RelativePath="..\PDP1\pdp1_drm.c" RelativePath="..\PDP1\pdp1_drm.c"
> >
@ -261,11 +269,19 @@
RelativePath="..\sim_tmxr.c" RelativePath="..\sim_tmxr.c"
> >
</File> </File>
<File
RelativePath="..\display\win32.c"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc" Filter="h;hpp;hxx;hm;inl;inc"
> >
<File
RelativePath="..\display\display.h"
>
</File>
<File <File
RelativePath="..\PDP1\pdp1_defs.h" RelativePath="..\PDP1\pdp1_defs.h"
> >
@ -318,6 +334,10 @@
RelativePath="..\sim_tmxr.h" RelativePath="..\sim_tmxr.h"
> >
</File> </File>
<File
RelativePath="..\display\ws.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" Name="Resource Files"

View file

@ -45,7 +45,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="./;../;../PDP11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;" AdditionalIncludeDirectories="./;../;../PDP11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_SHARED;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID" PreprocessorDefinitions="USE_SHARED;USE_DISPLAY;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
@ -129,7 +129,7 @@
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
OmitFramePointers="true" OmitFramePointers="true"
AdditionalIncludeDirectories="./;../;../PDP11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;" AdditionalIncludeDirectories="./;../;../PDP11/;&quot;../../windows-build/winpcap/Wpdpack/Include&quot;;&quot;../../windows-build/pthreads&quot;"
PreprocessorDefinitions="USE_SHARED;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID" PreprocessorDefinitions="USE_SHARED;USE_DISPLAY;VM_PDP11;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;SIM_ASYNCH_IO;USE_READER_THREAD;SIM_NEED_GIT_COMMIT_ID"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"
@ -191,6 +191,10 @@
Name="Source Files" Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm" Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
> >
<File
RelativePath="..\display\display.c"
>
</File>
<File <File
RelativePath="..\PDP11\pdp11_cis.c" RelativePath="..\PDP11\pdp11_cis.c"
> >
@ -339,6 +343,10 @@
RelativePath="..\PDP11\pdp11_vh.c" RelativePath="..\PDP11\pdp11_vh.c"
> >
</File> </File>
<File
RelativePath="..\PDP11\pdp11_vt.c"
>
</File>
<File <File
RelativePath="..\PDP11\pdp11_xq.c" RelativePath="..\PDP11\pdp11_xq.c"
> >
@ -407,11 +415,23 @@
RelativePath="..\sim_tmxr.c" RelativePath="..\sim_tmxr.c"
> >
</File> </File>
<File
RelativePath="..\display\vt11.c"
>
</File>
<File
RelativePath="..\display\win32.c"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc" Filter="h;hpp;hxx;hm;inl;inc"
> >
<File
RelativePath="..\display\display.h"
>
</File>
<File <File
RelativePath="..\PDP11\pdp11_cpumod.h" RelativePath="..\PDP11\pdp11_cpumod.h"
> >
@ -504,6 +524,14 @@
RelativePath="..\sim_tmxr.h" RelativePath="..\sim_tmxr.h"
> >
</File> </File>
<File
RelativePath="..\display\vt11.h"
>
</File>
<File
RelativePath="..\display\ws.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" Name="Resource Files"

View file

@ -483,7 +483,8 @@ PDP1_LIB = $(LIB_DIR)PDP1-$(ARCH).OLB
PDP1_SOURCE = $(PDP1_DIR)PDP1_LP.C,$(PDP1_DIR)PDP1_CPU.C,\ PDP1_SOURCE = $(PDP1_DIR)PDP1_LP.C,$(PDP1_DIR)PDP1_CPU.C,\
$(PDP1_DIR)PDP1_STDDEV.C,$(PDP1_DIR)PDP1_SYS.C,\ $(PDP1_DIR)PDP1_STDDEV.C,$(PDP1_DIR)PDP1_SYS.C,\
$(PDP1_DIR)PDP1_DT.C,$(PDP1_DIR)PDP1_DRM.C,\ $(PDP1_DIR)PDP1_DT.C,$(PDP1_DIR)PDP1_DRM.C,\
$(PDP1_DIR)PDP1_CLK.C,$(PDP1_DIR)PDP1_DCS.C $(PDP1_DIR)PDP1_CLK.C,$(PDP1_DIR)PDP1_DCS.C, \
$(PDP1_DIR)PDP1_DPY.C
PDP1_OPTIONS = /INCL=($(SIMH_DIR),$(PDP1_DIR))/DEF=($(CC_DEFS)) PDP1_OPTIONS = /INCL=($(SIMH_DIR),$(PDP1_DIR))/DEF=($(CC_DEFS))
# #
@ -535,7 +536,7 @@ PDP11_SOURCE1 = $(PDP11_DIR)PDP11_FP.C,$(PDP11_DIR)PDP11_CPU.C,\
$(PDP11_DIR)PDP11_CPUMOD.C,$(PDP11_DIR)PDP11_CR.C,\ $(PDP11_DIR)PDP11_CPUMOD.C,$(PDP11_DIR)PDP11_CR.C,\
$(PDP11_DIR)PDP11_TA.C,$(PDP11_DIR)PDP11_DMC.C,\ $(PDP11_DIR)PDP11_TA.C,$(PDP11_DIR)PDP11_DMC.C,\
$(PDP11_DIR)PDP11_DUP.C,$(PDP11_DIR)PDP11_RS.C,\ $(PDP11_DIR)PDP11_DUP.C,$(PDP11_DIR)PDP11_RS.C,\
$(PDP11_DIR)PDP11_IO_LIB.C $(PDP11_DIR)PDP11_VT.C,$(PDP11_DIR)PDP11_IO_LIB.C
PDP11_LIB2 = $(LIB_DIR)PDP11L2-$(ARCH).OLB PDP11_LIB2 = $(LIB_DIR)PDP11L2-$(ARCH).OLB
PDP11_SOURCE2 = $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\ PDP11_SOURCE2 = $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\
$(PDP11_DIR)PDP11_IO.C,$(PDP11_DIR)PDP11_RQ.C,\ $(PDP11_DIR)PDP11_IO.C,$(PDP11_DIR)PDP11_RQ.C,\

View file

@ -40,9 +40,9 @@ We're not GUI programmers, so the code is PRIMITIVE!!
Started from VC8E simulator by Douglas W. Jones Started from VC8E simulator by Douglas W. Jones
(distribution 5, of Feb 4, 1997); (distribution 5, of Feb 4, 1997);
This PDP8 Emulator was written by Douglas W. Jones at the This PDP8 Emulator was written by Douglas W. Jones at the
University of Iowa. It is distributed as freeware, of University of Iowa. It is distributed as freeware, of
uncertain function and uncertain utility. uncertain function and uncertain utility.
Original phosphor decay constants for Type 30 display from XMame 0.72.1 Original phosphor decay constants for Type 30 display from XMame 0.72.1
@ -71,30 +71,30 @@ makefile.
To compile test programs: To compile test programs:
======================== ========================
On Unix: On Unix:
# edit smakefile to match your environment # edit smakefile to match your environment
make -f smakefile make -f smakefile
or or
gmake -f gmakefile gmake -f gmakefile
On Win32 (using Cygwin); On Win32 (using Cygwin);
make -f gmakefile WIN32=1 make -f gmakefile WIN32=1
On Win32 (using MINGW): On Win32 (using MINGW):
# edit smakefile to match your environment # edit smakefile to match your environment
make -f smakefile make -f smakefile
or or
mingw32-make -f gmakefile WIN32=1 mingw32-make -f gmakefile WIN32=1
or or
execute build-mingw.bat in a DOS command window execute build-mingw.bat in a DOS command window
creates: creates:
munch: standalone simulation of PDP-1 munching squares; munch: standalone simulation of PDP-1 munching squares;
examines console "test switches" (see next section) examines console "test switches" (see next section)
vt11: sequences through VT11/VS60 simulator test displays; vt11: sequences through VT11/VS60 simulator test displays;
shows how the diplay-processor simulator can be used shows how the diplay-processor simulator can be used
from applications other than PDP-11 simulators from applications other than PDP-11 simulators
Console switches: Console switches:
================ ================
@ -110,13 +110,13 @@ Spacewar Switches:
Key presses for simulated Spacewar control box switches; Key presses for simulated Spacewar control box switches;
action player action player
1 2 1 2
rotate clockwise a k rotate clockwise a k
rotate counter clockwise s l rotate counter clockwise s l
fire engines d ; fire engines d ;
launch torpedo f ' launch torpedo f '
hyperspace (both at once) as kl hyperspace (both at once) as kl
Light pen: Light pen:
========= =========
@ -131,28 +131,28 @@ Too many compile time parameters:
Read the comments in display.c for more explanations!! Read the comments in display.c for more explanations!!
DISPLAY_TYPE default display type, one of: DISPLAY_TYPE default display type, one of:
DIS_VR14, DIS_VR17, DIS_VR20, DIS_VR48, DIS_TYPE30, DIS_TYPE340 DIS_VR14, DIS_VR17, DIS_VR20, DIS_VR48, DIS_TYPE30, DIS_TYPE340
selects screen characteristics (phosphor, dimensions). selects screen characteristics (phosphor, dimensions).
Only affects programs which do not make an expicit Only affects programs which do not make an expicit
display_init() call. display_init() call.
PIX_SCALE one of RES_FULL, RES_HALF, RES_QUARTER, RES_EIGHTH PIX_SCALE one of RES_FULL, RES_HALF, RES_QUARTER, RES_EIGHTH
selects default display scaling factor. selects default display scaling factor.
PEN_RADIUS default radius of light pen in (scaled) pixels PEN_RADIUS default radius of light pen in (scaled) pixels
MAXELAPSED Upper limit in real microseconds between polls/delays MAXELAPSED Upper limit in real microseconds between polls/delays
MINELAPSED Lower limit in real microseconds between polls/delays MINELAPSED Lower limit in real microseconds between polls/delays
MINDELAY Lower limit in real microseconds for attempted delay MINDELAY Lower limit in real microseconds for attempted delay
MAXDELAY Upper limit in real microseconds for attempted delay MAXDELAY Upper limit in real microseconds for attempted delay
GAINSHIFT delay_check increment/decrement gain factor GAINSHIFT delay_check increment/decrement gain factor
In display system support (x11.c, win32.c); In display system support (x11.c, win32.c);
PIX_SIZE selects displayed pixel size (default 1) PIX_SIZE selects displayed pixel size (default 1)
makes screen larger, useful when display scaled to small size makes screen larger, useful when display scaled to small size
Programming interface: Programming interface:
===================== =====================

328
display/carbon.c Normal file
View file

@ -0,0 +1,328 @@
/*
* $Id: carbon.c,v 1.2 2005/08/06 21:09:03 phil Exp $
* Mac OS X Carbon support for XY display simulator
* John Dundas <dundas@caltech.edu>
* December 2004
*
* This is a simplistic driver under Mac OS Carbon for the XY display
* simulator.
*
* A more interesting driver would use OpenGL directly.
*/
#include <Carbon/Carbon.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ws.h"
#include "xy.h"
#include <sys/types.h>
#include <sys/time.h>
#define ARRAYLEN(a) (sizeof (a) / sizeof (a[0]))
#ifndef PIX_SIZE
#define PIX_SIZE 1
#endif
/*
* light pen location
* see ws.h for full description
*/
int ws_lp_x = -1;
int ws_lp_y = -1;
static RGBColor blckColor = { 0x0000, 0x0000, 0x0000 };
static RGBColor whteColor = { 0xFFFF, 0xFFFF, 0xFFFF };
static WindowRef mainWind;
static RgnHandle rgn;
static MouseTrackingRef mouseRef;
static int xpixels, ypixels;
static int buttons = 0; /* tracks state of all buttons */
static EventTargetRef EventDispatchTarget;
void MyEventWait ( EventTimeout timeout ) /* double */
{
EventRef theEvent;
if (ReceiveNextEvent (0, NULL, timeout, true, &theEvent) == noErr) {
SendEventToEventTarget (theEvent, EventDispatchTarget);
ReleaseEvent (theEvent);
}
}
static pascal OSStatus doMouseEvent ( EventHandlerCallRef handlerRef,
EventRef event,
void *userData )
{
OSStatus err = eventNotHandledErr;
Point start;
GrafPtr prevPort;
/* make sure the display is the current grafport */
if (!QDSwapPort (GetWindowPort (mainWind), &prevPort))
prevPort = NULL;
switch (GetEventKind (event)) {
case kEventMouseEntered:
if (ActiveNonFloatingWindow () != mainWind)
break;
SetThemeCursor (kThemeCrossCursor);
break;
case kEventMouseExited:
if (ActiveNonFloatingWindow () != mainWind)
break;
SetThemeCursor (kThemeArrowCursor);
break;
case kEventMouseDown:
GetEventParameter (event, kEventParamMouseLocation,
typeQDPoint, NULL, sizeof (typeQDPoint), NULL, &start);
GlobalToLocal (&start);
ws_lp_x = start.h;
ws_lp_y = ypixels - start.v;
display_lp_sw = 1;
break;
case kEventMouseUp:
display_lp_sw = 0;
ws_lp_x = ws_lp_y = -1;
break;
default:
break;
}
if (prevPort)
SetPort (prevPort);
return (err);
}
static pascal OSStatus updateWindow ( EventHandlerCallRef handlerRef,
EventRef event,
void *userData )
{
OSStatus err = eventNotHandledErr;
switch (GetEventKind (event)) {
case kEventWindowActivated:
/* update menus */
break;
case kEventWindowClose: /* Override window close */
err = noErr;
break;
case kEventWindowDrawContent:
display_repaint ();
err = noErr;
default:
break;
}
return (err);
}
static pascal OSStatus doKbdEvent ( EventHandlerCallRef handlerRef,
EventRef event,
void *userData )
{
UInt32 c, m;
char key;
GetEventParameter (event, kEventParamKeyCode,
typeUInt32, NULL, sizeof (typeUInt32), NULL, &c);
GetEventParameter (event, kEventParamKeyMacCharCodes,
typeChar, NULL, sizeof (typeChar), NULL, &key);
GetEventParameter (event, kEventParamKeyModifiers,
typeUInt32, NULL, sizeof (typeUInt32), NULL, &m);
/* Keys with meta-modifiers are not allowed at this time. */
#define KEY_MODIFIERS (cmdKey | optionKey | kEventKeyModifierFnMask)
if (m & KEY_MODIFIERS)
return (eventNotHandledErr);
switch (GetEventKind (event)) {
case kEventRawKeyRepeat:
case kEventRawKeyDown:
display_keydown (key);
break;
case kEventRawKeyUp:
display_keyup (key);
break;
default:
break;
}
return (noErr);
}
int ws_init ( char *crtname, /* crt type name */
int xp, /* screen size in pixels */
int yp,
int colors ) /* colors to support (not used) */
{
WindowAttributes windowAttrs;
Rect r;
CFStringRef str;
static MouseTrackingRegionID mouseID = { 'AAPL', 0 };
static const EventTypeSpec moEvent[] = {
{ kEventClassMouse, kEventMouseEntered },
{ kEventClassMouse, kEventMouseExited },
{ kEventClassMouse, kEventMouseDown },
{ kEventClassMouse, kEventMouseUp },
};
static const EventTypeSpec wuEvent[] = {
{ kEventClassWindow, kEventWindowDrawContent },
{ kEventClassWindow, kEventWindowClose },
{ kEventClassWindow, kEventWindowActivated},
};
static const EventTypeSpec kdEvent[] = {
{ kEventClassKeyboard, kEventRawKeyDown },
{ kEventClassKeyboard, kEventRawKeyRepeat },
{ kEventClassKeyboard, kEventRawKeyUp},
};
xpixels = xp; /* save screen size */
ypixels = yp;
r.top = 100; r.left = 100; r.bottom = r.top + yp; r.right = r.left + xp;
/* should check this r against GetQDGlobalsScreenBits (&screen); */
windowAttrs = kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute;
if (CreateNewWindow (kDocumentWindowClass, windowAttrs, &r, &mainWind) != noErr)
return (0);
if (str = CFStringCreateWithCString (kCFAllocatorDefault, crtname,
kCFStringEncodingASCII)) {
SetWindowTitleWithCFString (mainWind, str);
CFRelease (str);
}
SetPortWindowPort (mainWind);
/*
* Setup to handle events
*/
EventDispatchTarget = GetEventDispatcherTarget ();
InstallEventHandler (GetWindowEventTarget (mainWind),
NewEventHandlerUPP (doMouseEvent), ARRAYLEN(moEvent),
(EventTypeSpec *) &moEvent, NULL, NULL);
InstallEventHandler (GetWindowEventTarget (mainWind),
NewEventHandlerUPP (updateWindow), ARRAYLEN(wuEvent),
(EventTypeSpec *) &wuEvent, NULL, NULL);
InstallEventHandler (GetWindowEventTarget (mainWind),
NewEventHandlerUPP (doKbdEvent), ARRAYLEN(kdEvent),
(EventTypeSpec *) &kdEvent, NULL, NULL);
/* create region to track cursor shape */
r.top = 0; r.left = 0; r.bottom = yp; r.right = xp;
rgn = NewRgn ();
RectRgn (rgn, &r);
CloseRgn (rgn);
CreateMouseTrackingRegion (mainWind, rgn, NULL,
kMouseTrackingOptionsLocalClip, mouseID, NULL, NULL, &mouseRef);
ShowWindow (mainWind);
RGBForeColor (&blckColor);
PaintRect (&r);
RGBBackColor (&blckColor);
return (1);
}
void *ws_color_black (void)
{
return (&blckColor);
}
void *ws_color_white (void)
{
return (&whteColor);
}
void *ws_color_rgb ( int r,
int g,
int b )
{
RGBColor *color;
if ((color = malloc (sizeof (RGBColor))) != NULL) {
color->red = r;
color->green = g;
color->blue = b;
}
return (color);
}
/* put a point on the screen */
void ws_display_point ( int x,
int y,
void *color )
{
#if PIX_SIZE != 1
Rect r;
#endif
if (x > xpixels || y > ypixels)
return;
y = ypixels - y /* - 1 */;
#if PIX_SIZE == 1
SetCPixel (x, y, (color == NULL) ? &blckColor : color);
#else
r.top = y * PIX_SIZE;
r.left = x * PIX_SIZE;
r.bottom = (y + 1) * PIX_SIZE;
r.right = (x + 1) * PIX_SIZE;
RGBForeColor ((color == NULL) ? &blckColor : color);
PaintRect (&r);
#endif
}
void ws_sync (void)
{
;
}
/*
* elapsed wall clock time since last call
* +INF on first call
*/
struct elapsed_state {
struct timeval tvs[2];
int new;
};
static unsigned long
elapsed(struct elapsed_state *ep)
{
unsigned long val;
gettimeofday(&ep->tvs[ep->new], NULL);
if (ep->tvs[!ep->new].tv_sec == 0)
val = ~0L;
else
val = ((ep->tvs[ep->new].tv_sec - ep->tvs[!ep->new].tv_sec) * 1000000 +
(ep->tvs[ep->new].tv_usec - ep->tvs[!ep->new].tv_usec));
ep->new = !ep->new;
return val;
}
/* called periodically */
int ws_poll ( int *valp,
int maxusec )
{
static struct elapsed_state es; /* static to avoid clearing! */
elapsed(&es); /* start clock */
do {
unsigned long e;
MyEventWait (maxusec * kEventDurationMicrosecond);
e = elapsed(&es);
maxusec -= e;
} while (maxusec > 10000); /* 10ms */
return (1);
}
void ws_beep (void)
{
SysBeep (3);
}
/* public version, used by delay code */
unsigned long os_elapsed (void)
{
static struct elapsed_state es;
return (elapsed (&es));
}

View file

@ -7,9 +7,9 @@
* with changes by Douglas A. Gwyn, 21 Jan. 2004 * with changes by Douglas A. Gwyn, 21 Jan. 2004
* *
* started from PDP-8/E simulator vc8e.c; * started from PDP-8/E simulator vc8e.c;
* This PDP8 Emulator was written by Douglas W. Jones at the * This PDP8 Emulator was written by Douglas W. Jones at the
* University of Iowa. It is distributed as freeware, of * University of Iowa. It is distributed as freeware, of
* uncertain function and uncertain utility. * uncertain function and uncertain utility.
*/ */
/* /*
@ -41,7 +41,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <limits.h> /* for USHRT_MAX */ #include <limits.h> /* for USHRT_MAX */
#include "ws.h" #include "ws.h"
#include "display.h" #include "display.h"
@ -86,14 +86,14 @@
struct phosphor { struct phosphor {
double red, green, blue; double red, green, blue;
double level; /* decay level (0.5 for half life) */ double level; /* decay level (0.5 for half life) */
double t_level; /* seconds to decay to level */ double t_level; /* seconds to decay to level */
}; };
struct color { struct color {
struct phosphor *phosphors; struct phosphor *phosphors;
int nphosphors; int nphosphors;
int half_life; /* for refresh calc */ int half_life; /* for refresh calc */
}; };
struct display { struct display {
@ -108,8 +108,8 @@ struct display {
* not even sure Type30 really used P17 (guess by Daniel P. B. Smith) * not even sure Type30 really used P17 (guess by Daniel P. B. Smith)
*/ */
static struct phosphor p17[] = { static struct phosphor p17[] = {
{0.11, 0.11, 1.0, 0.5, 0.05}, /* fast blue */ {0.11, 0.11, 1.0, 0.5, 0.05}, /* fast blue */
{1.0, 1.0, 0.11, 0.5, 0.20} /* slow yellow/green */ {1.0, 1.0, 0.11, 0.5, 0.20} /* slow yellow/green */
}; };
static struct color color_p17 = { p17, ELEMENTS(p17), 125000 }; static struct color color_p17 = { p17, ELEMENTS(p17), 125000 };
@ -146,7 +146,7 @@ static struct display displays[] = {
{ DIS_TX0, "MIT TX-0", &color_p17, NULL, 512, 512 }, { DIS_TX0, "MIT TX-0", &color_p17, NULL, 512, 512 },
/* /*
* Type 30 * Type 30
* PDP-1/4/5/8/9/10 "Precision CRT" display system * PDP-1/4/5/8/9/10 "Precision CRT" display system
* *
@ -171,8 +171,8 @@ static struct display displays[] = {
* brightness >= 30 fL * brightness >= 30 fL
* dot size .02" (20 mils) * dot size .02" (20 mils)
* settle time: * settle time:
* full screen 18us to +/-1 spot diameter * full screen 18us to +/-1 spot diameter
* .1" change 1us to +/-.5 spot diameter * .1" change 1us to +/-.5 spot diameter
* weight 75lb * weight 75lb
*/ */
{ DIS_VR14, "VR14", &color_p29, NULL, 1024, 768 }, { DIS_VR14, "VR14", &color_p29, NULL, 1024, 768 },
@ -252,9 +252,9 @@ static struct display displays[] = {
* *
* refresh_rate = ((1e6*LEVELS_PER_HALFLIFE)/PHOSPHOR_HALF_LIFE) * refresh_rate = ((1e6*LEVELS_PER_HALFLIFE)/PHOSPHOR_HALF_LIFE)
* refresh_interval = 1e6/DELAY_UNIT/refresh_rate * refresh_interval = 1e6/DELAY_UNIT/refresh_rate
* = PHOSPHOR_HALF_LIFE/LEVELS_PER_HALF_LIFE * = PHOSPHOR_HALF_LIFE/LEVELS_PER_HALF_LIFE
* intensities = (HALF_LIVES_TO_DISPLAY*PHOSPHOR_HALF_LIFE)/refresh_interval * intensities = (HALF_LIVES_TO_DISPLAY*PHOSPHOR_HALF_LIFE)/refresh_interval
* = HALF_LIVES_TO_DISPLAY*LEVELS_PER_HALFLIFE * = HALF_LIVES_TO_DISPLAY*LEVELS_PER_HALFLIFE
* *
* See also comments on display_age() * See also comments on display_age()
* *
@ -314,15 +314,15 @@ typedef unsigned short delay_t;
#define DELAY_T_MAX USHRT_MAX #define DELAY_T_MAX USHRT_MAX
struct point { struct point {
struct point *next; /* next entry in queue */ struct point *next; /* next entry in queue */
struct point *prev; /* prev entry in queue */ struct point *prev; /* prev entry in queue */
delay_t delay; /* delta T in DELAY_UNITs */ delay_t delay; /* delta T in DELAY_UNITs */
unsigned char ttl; /* zero means off, not linked in */ unsigned char ttl; /* zero means off, not linked in */
unsigned char level : 7; /* intensity level */ unsigned char level : 7; /* intensity level */
unsigned char color : 1; /* for VR20 (two colors) */ unsigned char color : 1; /* for VR20 (two colors) */
}; };
static struct point *points; /* allocated array of points */ static struct point *points; /* allocated array of points */
static struct point _head; static struct point _head;
#define head (&_head) #define head (&_head)
@ -404,12 +404,12 @@ queue_point(struct point *p)
#ifdef PARANOIA #ifdef PARANOIA
if (p->ttl == 0 || p->ttl > MAXTTL) if (p->ttl == 0 || p->ttl > MAXTTL)
printf("queuing %d,%d level %d!\n", X(p), Y(p), p->level); printf("queuing %d,%d level %d!\n", X(p), Y(p), p->level);
if (d > DELAY_T_MAX) if (d > DELAY_T_MAX)
printf("queuing %d,%d delay %d!\n", X(p), Y(p), d); printf("queuing %d,%d delay %d!\n", X(p), Y(p), d);
if (queue_interval > DELAY_T_MAX) if (queue_interval > DELAY_T_MAX)
printf("queue_interval (%d) > DELAY_T_MAX (%d)\n", printf("queue_interval (%d) > DELAY_T_MAX (%d)\n",
(int)queue_interval, DELAY_T_MAX); (int)queue_interval, DELAY_T_MAX);
#endif /* PARANOIA defined */ #endif /* PARANOIA defined */
p->next = head; p->next = head;
@ -436,14 +436,14 @@ queue_point(struct point *p)
* if more than MAXELAPSED microseconds elapsed while simulating * if more than MAXELAPSED microseconds elapsed while simulating
* delay_check simulated microseconds, decrease delay_check. * delay_check simulated microseconds, decrease delay_check.
*/ */
#define MAXELAPSED 100000 /* 10Hz */ #define MAXELAPSED 100000 /* 10Hz */
/* /*
* lower bound for elapsed time between elapsed time checks. * lower bound for elapsed time between elapsed time checks.
* if fewer than MINELAPSED microseconds elapsed while simulating * if fewer than MINELAPSED microseconds elapsed while simulating
* delay_check simulated microseconds, increase delay_check. * delay_check simulated microseconds, increase delay_check.
*/ */
#define MINELAPSED 50000 /* 20Hz */ #define MINELAPSED 50000 /* 20Hz */
/* /*
* upper bound for delay (sleep/poll). * upper bound for delay (sleep/poll).
@ -454,7 +454,7 @@ queue_point(struct point *p)
* should be <= MAXELAPSED * should be <= MAXELAPSED
*/ */
#ifndef MAXDELAY #ifndef MAXDELAY
#define MAXDELAY 100000 /* 100ms */ #define MAXDELAY 100000 /* 100ms */
#endif /* MAXDELAY not defined */ #endif /* MAXDELAY not defined */
/* /*
@ -466,7 +466,7 @@ queue_point(struct point *p)
* should be <= MINELAPSED * should be <= MINELAPSED
*/ */
#ifndef MINDELAY #ifndef MINDELAY
#define MINDELAY 50000 /* 50ms */ #define MINDELAY 50000 /* 50ms */
#endif /* MINDELAY not defined */ #endif /* MINDELAY not defined */
/* /*
@ -475,7 +475,7 @@ queue_point(struct point *p)
* Fast systems should ramp up quickly. * Fast systems should ramp up quickly.
*/ */
#ifndef INITIAL_DELAY_CHECK #ifndef INITIAL_DELAY_CHECK
#define INITIAL_DELAY_CHECK 1000 /* 1ms */ #define INITIAL_DELAY_CHECK 1000 /* 1ms */
#endif /* INITIAL_DELAY_CHECK */ #endif /* INITIAL_DELAY_CHECK */
/* /*
@ -483,7 +483,7 @@ queue_point(struct point *p)
* of delay_check * of delay_check
*/ */
#ifndef GAINSHIFT #ifndef GAINSHIFT
#define GAINSHIFT 3 /* gain=0.125 (12.5%) */ #define GAINSHIFT 3 /* gain=0.125 (12.5%) */
#endif /* GAINSHIFT not defined */ #endif /* GAINSHIFT not defined */
static void static void
@ -499,22 +499,22 @@ display_delay(int t, int slowdown)
sim_time += t; sim_time += t;
if (sim_time < delay_check) if (sim_time < delay_check)
return; return;
elapsed = os_elapsed(); /* read and reset elapsed timer */ elapsed = os_elapsed(); /* read and reset elapsed timer */
if (elapsed == ~0L) { /* first time thru? */ if (elapsed == ~0L) { /* first time thru? */
slowdown = 0; /* no adjustments */ slowdown = 0; /* no adjustments */
elapsed = sim_time; elapsed = sim_time;
} }
/* /*
* get delta between elapsed (real) time, and simulated time. * get delta between elapsed (real) time, and simulated time.
* if simulated time running faster, we need to slow things down (delay) * if simulated time running faster, we need to slow things down (delay)
*/ */
if (slowdown) if (slowdown)
delay = sim_time - elapsed; delay = sim_time - elapsed;
else else
delay = 0; /* just poll */ delay = 0; /* just poll */
#ifdef DEBUG_DELAY2 #ifdef DEBUG_DELAY2
printf("sim %d elapsed %d delay %d\r\n", sim_time, elapsed, delay); printf("sim %d elapsed %d delay %d\r\n", sim_time, elapsed, delay);
@ -537,32 +537,34 @@ display_delay(int t, int slowdown)
* to system load. * to system load.
*/ */
if (elapsed > MAXELAPSED || delay > MAXDELAY) { if (elapsed > MAXELAPSED || delay > MAXDELAY) {
/* too much elapsed time passed, or delay too large; shrink interval */ /* too much elapsed time passed, or delay too large; shrink interval */
if (delay_check > 1) { if (delay_check > 1) {
delay_check -= delay_check>>GAINSHIFT; delay_check -= delay_check>>GAINSHIFT;
#ifdef DEBUG_DELAY #ifdef DEBUG_DELAY
printf("reduced period to %d\r\n", delay_check); printf("reduced period to %d\r\n", delay_check);
#endif /* DEBUG_DELAY defined */ #endif /* DEBUG_DELAY defined */
} }
} }
else if ((elapsed < MINELAPSED) || (slowdown && (delay < MINDELAY))) { else
/* too little elapsed time passed, or delta very small */ if ((elapsed < MINELAPSED) || (slowdown && (delay < MINDELAY))) {
int gain = delay_check>>GAINSHIFT; /* too little elapsed time passed, or delta very small */
if (gain == 0) int gain = delay_check>>GAINSHIFT;
gain = 1; /* make sure some change made! */
delay_check += gain; if (gain == 0)
gain = 1; /* make sure some change made! */
delay_check += gain;
#ifdef DEBUG_DELAY #ifdef DEBUG_DELAY
printf("increased period to %d\r\n", delay_check); printf("increased period to %d\r\n", delay_check);
#endif /* DEBUG_DELAY defined */ #endif /* DEBUG_DELAY defined */
} }
if (delay < 0) if (delay < 0)
delay = 0; delay = 0;
/* else if delay < MINDELAY, clamp at MINDELAY??? */ /* else if delay < MINDELAY, clamp at MINDELAY??? */
/* poll for window system events and/or delay */ /* poll for window system events and/or delay */
ws_poll(NULL, delay); ws_poll(NULL, delay);
sim_time = 0; /* reset simulated time clock */ sim_time = 0; /* reset simulated time clock */
/* /*
* delay (poll/sleep) time included in next "elapsed" period * delay (poll/sleep) time included in next "elapsed" period
@ -582,15 +584,15 @@ display_delay(int t, int slowdown)
*/ */
int int
display_age(int t, /* simulated us since last call */ display_age(int t, /* simulated us since last call */
int slowdown) /* slowdown to simulated speed */ int slowdown) /* slowdown to simulated speed */
{ {
struct point *p; struct point *p;
static int elapsed = 0; static int elapsed = 0;
int changed; int changed;
if (!initialized && !display_init(DISPLAY_TYPE, PIX_SCALE)) if (!initialized && !display_init(DISPLAY_TYPE, PIX_SCALE))
return 0; return 0;
display_delay(t, slowdown); display_delay(t, slowdown);
@ -598,42 +600,42 @@ display_age(int t, /* simulated us since last call */
elapsed += t; elapsed += t;
if (elapsed < DELAY_UNIT) if (elapsed < DELAY_UNIT)
return 0; return 0;
t = elapsed / DELAY_UNIT; t = elapsed / DELAY_UNIT;
elapsed %= DELAY_UNIT; elapsed %= DELAY_UNIT;
while ((p = head->next) != head) { while ((p = head->next) != head) {
int x, y; int x, y;
/* look at oldest entry */ /* look at oldest entry */
if (p->delay > t) { /* further than our reach? */ if (p->delay > t) { /* further than our reach? */
p->delay -= t; /* update head */ p->delay -= t; /* update head */
queue_interval -= t; /* update span */ queue_interval -= t; /* update span */
break; /* quit */ break; /* quit */
} }
x = X(p); x = X(p);
y = Y(p); y = Y(p);
#ifdef PARANOIA #ifdef PARANOIA
if (p->ttl == 0) if (p->ttl == 0)
printf("BUG: age %d,%d ttl zero\n", x, y); printf("BUG: age %d,%d ttl zero\n", x, y);
#endif /* PARANOIA defined */ #endif /* PARANOIA defined */
/* dequeue point */ /* dequeue point */
p->prev->next = p->next; p->prev->next = p->next;
p->next->prev = p->prev; p->next->prev = p->prev;
t -= p->delay; /* lessen our reach */ t -= p->delay; /* lessen our reach */
queue_interval -= p->delay; /* update queue span */ queue_interval -= p->delay; /* update queue span */
ws_display_point(x, y, colors[p->color][p->level][--p->ttl]); ws_display_point(x, y, colors[p->color][p->level][--p->ttl]);
changed = 1; changed = 1;
/* queue it back up, unless we just turned it off! */ /* queue it back up, unless we just turned it off! */
if (p->ttl > 0) if (p->ttl > 0)
queue_point(p); queue_point(p);
} }
return changed; return changed;
} /* display_age */ } /* display_age */
@ -646,97 +648,99 @@ display_repaint(void) {
* bottom to top, left to right. * bottom to top, left to right.
*/ */
for (p = points, y = 0; y < ypixels; y++) for (p = points, y = 0; y < ypixels; y++)
for (x = 0; x < xpixels; p++, x++) for (x = 0; x < xpixels; p++, x++)
if (p->ttl) if (p->ttl)
ws_display_point(x, y, colors[p->color][p->level][p->ttl-1]); ws_display_point(x, y, colors[p->color][p->level][p->ttl-1]);
ws_sync(); ws_sync();
} }
/* (0,0) is lower left */ /* (0,0) is lower left */
static int static int
intensify(int x, /* 0..xpixels */ intensify(int x, /* 0..xpixels */
int y, /* 0..ypixels */ int y, /* 0..ypixels */
int level, /* 0..MAXLEVEL */ int level, /* 0..MAXLEVEL */
int color) /* for VR20! 0 or 1 */ int color) /* for VR20! 0 or 1 */
{ {
struct point *p; struct point *p;
int bleed; int bleed;
if (x < 0 || x >= xpixels || y < 0 || y >= ypixels) if (x < 0 || x >= xpixels || y < 0 || y >= ypixels)
return 0; /* limit to display */ return 0; /* limit to display */
p = P(x,y); p = P(x,y);
if (p->ttl) { /* currently lit? */ if (p->ttl) { /* currently lit? */
#ifdef LOUD #ifdef LOUD
printf("%d,%d old level %d ttl %d new %d\r\n", printf("%d,%d old level %d ttl %d new %d\r\n",
x, y, p->level, p->ttl, level); x, y, p->level, p->ttl, level);
#endif /* LOUD defined */ #endif /* LOUD defined */
/* unlink from delta queue */ /* unlink from delta queue */
p->prev->next = p->next; p->prev->next = p->next;
if (p->next == head) if (p->next == head)
queue_interval -= p->delay; queue_interval -= p->delay;
else else
p->next->delay += p->delay; p->next->delay += p->delay;
p->next->prev = p->prev; p->next->prev = p->prev;
} }
bleed = 0; /* no bleeding for now */ bleed = 0; /* no bleeding for now */
/* EXP: doesn't work... yet */ /* EXP: doesn't work... yet */
/* if "recently" drawn, same or brighter, same color, make even brighter */ /* if "recently" drawn, same or brighter, same color, make even brighter */
if (p->ttl >= MAXTTL*2/3 && level >= p->level && p->color == color && if (p->ttl >= MAXTTL*2/3 &&
level < MAXLEVEL) level >= p->level &&
level++; p->color == color &&
level < MAXLEVEL)
level++;
/* /*
* this allows a dim beam to suck light out of * this allows a dim beam to suck light out of
* a recently drawn bright spot!! * a recently drawn bright spot!!
*/ */
if (p->ttl != MAXTTL || p->level != level || p->color != color) { if (p->ttl != MAXTTL || p->level != level || p->color != color) {
p->ttl = MAXTTL; p->ttl = MAXTTL;
p->level = level; p->level = level;
p->color = color; /* save color even if monochrome */ p->color = color; /* save color even if monochrome */
ws_display_point(x, y, colors[p->color][p->level][p->ttl-1]); ws_display_point(x, y, colors[p->color][p->level][p->ttl-1]);
} }
queue_point(p); /* put at end of list */ queue_point(p); /* put at end of list */
return bleed; return bleed;
} }
int int
display_point(int x, /* 0..xpixels (unscaled) */ display_point(int x, /* 0..xpixels (unscaled) */
int y, /* 0..ypixels (unscaled) */ int y, /* 0..ypixels (unscaled) */
int level, /* DISPLAY_INT_xxx */ int level, /* DISPLAY_INT_xxx */
int color) /* for VR20! 0 or 1 */ int color) /* for VR20! 0 or 1 */
{ {
long lx, ly; long lx, ly;
if (!initialized && !display_init(DISPLAY_TYPE, PIX_SCALE)) if (!initialized && !display_init(DISPLAY_TYPE, PIX_SCALE))
return 0; return 0;
/* scale x and y to the displayed number of pixels */ /* scale x and y to the displayed number of pixels */
/* handle common cases quickly */ /* handle common cases quickly */
if (scale > 1) { if (scale > 1) {
if (scale == 2) { if (scale == 2) {
x >>= 1; x >>= 1;
y >>= 1; y >>= 1;
} }
else { else {
x /= scale; x /= scale;
y /= scale; y /= scale;
} }
} }
#if DISPLAY_INT_MIN > 0 #if DISPLAY_INT_MIN > 0
level -= DISPLAY_INT_MIN; /* make zero based */ level -= DISPLAY_INT_MIN; /* make zero based */
#endif #endif
intensify(x, y, level, color); intensify(x, y, level, color);
/* no bleeding for now (used to recurse for neighbor points) */ /* no bleeding for now (used to recurse for neighbor points) */
if (ws_lp_x == -1 || ws_lp_y == -1) if (ws_lp_x == -1 || ws_lp_y == -1)
return 0; return 0;
lx = x - ws_lp_x; lx = x - ws_lp_x;
ly = y - ws_lp_y; ly = y - ws_lp_y;
@ -754,59 +758,60 @@ phosphor_init(struct phosphor *phosphors, int nphosphors, int color)
/* for each display ttl level; newest to oldest */ /* for each display ttl level; newest to oldest */
for (ttl = NTTL-1; ttl > 0; ttl--) { for (ttl = NTTL-1; ttl > 0; ttl--) {
struct phosphor *pp; struct phosphor *pp;
double rr, rg, rb; /* real values */ double rr, rg, rb; /* real values */
/* fractional seconds */ /* fractional seconds */
double t = ((double)(NTTL-1-ttl))/refresh_rate; double t = ((double)(NTTL-1-ttl))/refresh_rate;
int ilevel; /* intensity levels */ int ilevel; /* intensity levels */
int p; int p;
/* sum over all phosphors in mixture */ /* sum over all phosphors in mixture */
rr = rg = rb = 0.0; rr = rg = rb = 0.0;
for (pp = phosphors, p = 0; p < nphosphors; pp++, p++) { for (pp = phosphors, p = 0; p < nphosphors; pp++, p++) {
double decay = pow(pp->level, t/pp->t_level); double decay = pow(pp->level, t/pp->t_level);
rr += decay * pp->red;
rg += decay * pp->green;
rb += decay * pp->blue;
}
/* scale for brightness for each intensity level */ rr += decay * pp->red;
for (ilevel = MAXLEVEL; ilevel >= 0; ilevel--) { rg += decay * pp->green;
int r, g, b; rb += decay * pp->blue;
void *cp; }
/* /* scale for brightness for each intensity level */
* convert to 16-bit integer; clamp at 16 bits. for (ilevel = MAXLEVEL; ilevel >= 0; ilevel--) {
* this allows the sum of brightness factors across phosphors int r, g, b;
* for each of R G and B to be greater than 1.0 void *cp;
*/
r = (int)(rr * level_scale[ilevel] * 0xffff); /*
if (r > 0xffff) r = 0xffff; * convert to 16-bit integer; clamp at 16 bits.
* this allows the sum of brightness factors across phosphors
* for each of R G and B to be greater than 1.0
*/
g = (int)(rg * level_scale[ilevel] * 0xffff); r = (int)(rr * level_scale[ilevel] * 0xffff);
if (g > 0xffff) g = 0xffff; if (r > 0xffff) r = 0xffff;
b = (int)(rb * level_scale[ilevel] * 0xffff); g = (int)(rg * level_scale[ilevel] * 0xffff);
if (b > 0xffff) b = 0xffff; if (g > 0xffff) g = 0xffff;
cp = ws_color_rgb(r, g, b); b = (int)(rb * level_scale[ilevel] * 0xffff);
if (!cp) { /* allocation failed? */ if (b > 0xffff) b = 0xffff;
if (ttl == MAXTTL-1) { /* brand new */
if (ilevel == MAXLEVEL) /* highest intensity? */ cp = ws_color_rgb(r, g, b);
cp = ws_color_white(); /* use white */ if (!cp) { /* allocation failed? */
else if (ttl == MAXTTL-1) { /* brand new */
cp = colors[color][ilevel+1][ttl]; /* use next lvl */ if (ilevel == MAXLEVEL) /* highest intensity? */
} /* brand new */ cp = ws_color_white(); /* use white */
else if (r + g + b >= 0xffff*3/3) /* light-ish? */ else
cp = colors[color][ilevel][ttl+1]; /* use previous TTL */ cp = colors[color][ilevel+1][ttl]; /* use next lvl */
else } /* brand new */
cp = ws_color_black(); else if (r + g + b >= 0xffff*3/3) /* light-ish? */
} cp = colors[color][ilevel][ttl+1]; /* use previous TTL */
colors[color][ilevel][ttl] = cp; else
} /* for each intensity level */ cp = ws_color_black();
}
colors[color][ilevel][ttl] = cp;
} /* for each intensity level */
} /* for each TTL */ } /* for each TTL */
} /* phosphor_init */ } /* phosphor_init */
@ -815,9 +820,10 @@ find_type(enum display_type type)
{ {
int i; int i;
struct display *dp; struct display *dp;
for (i = 0, dp = displays; i < ELEMENTS(displays); i++, dp++) for (i = 0, dp = displays; i < ELEMENTS(displays); i++, dp++)
if (dp->type == type) if (dp->type == type)
return dp; return dp;
return NULL; return NULL;
} }
@ -830,20 +836,20 @@ display_init(enum display_type type, int sf)
int i; int i;
if (initialized) { if (initialized) {
/* cannot change type once started */ /* cannot change type once started */
/* XXX say something???? */ /* XXX say something???? */
return type == display_type; return type == display_type;
} }
if (init_failed) if (init_failed)
return 0; /* avoid thrashing */ return 0; /* avoid thrashing */
init_failed = 1; /* assume the worst */ init_failed = 1; /* assume the worst */
dp = find_type(type); dp = find_type(type);
if (!dp) { if (!dp) {
fprintf(stderr, "Unknown display type %d\r\n", (int)type); fprintf(stderr, "Unknown display type %d\r\n", (int)type);
goto failed; goto failed;
} }
/* Initialize display list */ /* Initialize display list */
head->next = head->prev = head; head->next = head->prev = head;
@ -870,10 +876,10 @@ display_init(enum display_type type, int sf)
half_life = COLOR_HALF_LIFE(dp->color0); half_life = COLOR_HALF_LIFE(dp->color0);
if (dp->color1) { if (dp->color1) {
if (dp->color1->half_life > half_life) if (dp->color1->half_life > half_life)
half_life = COLOR_HALF_LIFE(dp->color1); half_life = COLOR_HALF_LIFE(dp->color1);
ncolors++; ncolors++;
} }
/* before phosphor_init; */ /* before phosphor_init; */
refresh_rate = (1000000*LEVELS_PER_HALFLIFE)/half_life; refresh_rate = (1000000*LEVELS_PER_HALFLIFE)/half_life;
@ -886,21 +892,21 @@ display_init(enum display_type type, int sf)
/* must be non-zero; interval of 1 means all pixels will age at once! */ /* must be non-zero; interval of 1 means all pixels will age at once! */
if (refresh_interval < 1) { if (refresh_interval < 1) {
/* decrease DELAY_UNIT? */ /* decrease DELAY_UNIT? */
fprintf(stderr, "NOTE! refresh_interval too small: %d\r\n", fprintf(stderr, "NOTE! refresh_interval too small: %d\r\n",
refresh_interval); refresh_interval);
/* dunno if this is a good idea, but might be better than dying */ /* dunno if this is a good idea, but might be better than dying */
refresh_interval = 1; refresh_interval = 1;
} }
/* point lifetime in DELAY_UNITs will not fit in p->delay field! */ /* point lifetime in DELAY_UNITs will not fit in p->delay field! */
if (refresh_interval > DELAY_T_MAX) { if (refresh_interval > DELAY_T_MAX) {
/* increase DELAY_UNIT? */ /* increase DELAY_UNIT? */
fprintf(stderr, "bad refresh_interval %d > DELAY_T_MAX %d\r\n", fprintf(stderr, "bad refresh_interval %d > DELAY_T_MAX %d\r\n",
refresh_interval, DELAY_T_MAX); refresh_interval, DELAY_T_MAX);
goto failed; goto failed;
} }
/* /*
* before phosphor_init; * before phosphor_init;
@ -911,23 +917,23 @@ display_init(enum display_type type, int sf)
*/ */
#define BOOST 5 #define BOOST 5
for (i = 0; i < NLEVELS; i++) for (i = 0; i < NLEVELS; i++)
level_scale[i] = ((float)i+1+BOOST)/(NLEVELS+BOOST); level_scale[i] = ((float)i+1+BOOST)/(NLEVELS+BOOST);
points = (struct point *)calloc((size_t)xpixels, points = (struct point *)calloc((size_t)xpixels,
ypixels * sizeof(struct point)); ypixels * sizeof(struct point));
if (!points) if (!points)
goto failed; goto failed;
if (!ws_init(dp->name, xpixels, ypixels, ncolors)) if (!ws_init(dp->name, xpixels, ypixels, ncolors))
goto failed; goto failed;
phosphor_init(dp->color0->phosphors, dp->color0->nphosphors, 0); phosphor_init(dp->color0->phosphors, dp->color0->nphosphors, 0);
if (dp->color1) if (dp->color1)
phosphor_init(dp->color1->phosphors, dp->color1->nphosphors, 1); phosphor_init(dp->color1->phosphors, dp->color1->nphosphors, 1);
initialized = 1; initialized = 1;
init_failed = 0; /* hey, we made it! */ init_failed = 0; /* hey, we made it! */
return 1; return 1;
failed: failed:
@ -997,7 +1003,7 @@ display_keydown(int k)
case 'a': case 'A': spacewar_switches |= 04; break; /* rotate R */ case 'a': case 'A': spacewar_switches |= 04; break; /* rotate R */
case 's': case 'S': spacewar_switches |= 010; break; /* rotate L */ case 's': case 'S': spacewar_switches |= 010; break; /* rotate L */
case '\'': case '"': spacewar_switches |= 040000; break; /* torpedos */ case '\'': case '"': spacewar_switches |= 040000; break; /* torpedos */
case ';': case ':': spacewar_switches |= 0100000; break; /* engines */ case ';': case ':': spacewar_switches |= 0100000; break; /* engines */
case 'k': case 'K': spacewar_switches |= 0200000; break; /* rotate R */ case 'k': case 'K': spacewar_switches |= 0200000; break; /* rotate R */
case 'l': case 'L': spacewar_switches |= 0400000; break; /* rotate L */ case 'l': case 'L': spacewar_switches |= 0400000; break; /* rotate L */
default: return; default: return;

View file

@ -41,7 +41,7 @@ enum display_type {
DIS_VR17 = 17, DIS_VR17 = 17,
DIS_VR20 = 20, DIS_VR20 = 20,
DIS_TYPE30 = 30, DIS_TYPE30 = 30,
DIS_TX0 = 33, DIS_TX0 = 33,
DIS_VR48 = 48, DIS_VR48 = 48,
DIS_TYPE340 = 340 DIS_TYPE340 = 340
}; };
@ -65,7 +65,7 @@ extern int display_xpoints(void);
extern int display_ypoints(void); extern int display_ypoints(void);
/* virtual points between display and menu sections */ /* virtual points between display and menu sections */
#define VR48_GUTTER 8 /* just a guess */ #define VR48_GUTTER 8 /* just a guess */
/* conversion factor from virtual points and displayed pixels */ /* conversion factor from virtual points and displayed pixels */
extern int display_scale(void); extern int display_scale(void);
@ -83,10 +83,10 @@ extern int display_age(int,int);
* always at least 8 (for VT11/VS60) -- may be mapped internally * always at least 8 (for VT11/VS60) -- may be mapped internally
*/ */
#define DISPLAY_INT_MAX 7 #define DISPLAY_INT_MAX 7
#define DISPLAY_INT_MIN 0 /* lowest "on" level */ #define DISPLAY_INT_MIN 0 /* lowest "on" level */
/* /*
* plot a point; argumen ts are x, y, intensity, color (0/1) * plot a point; argumen ts are x, y, intensity, color (0/1)
* returns true if light pen active (mouse button down) * returns true if light pen active (mouse button down)
* at (or very near) this location. * at (or very near) this location.
* *

View file

@ -1,22 +1,26 @@
# $Id: gmakefile,v 1.17 2004/01/24 08:31:56 phil Exp - revised by DAG # $Id: gmakefile,v 1.24 2005/11/05 02:06:14 phil Exp $
# (GNU) Makefile for test programs under Unix/X11 and Win32 # (GNU) Makefile for test programs under Unix/X11 and Win32
# #
# Unix: # Unix:
# edit Unix defs to fit your compiler/library environment, then # edit Unix defs to fit your compiler/library environment, then
# gmake -f gmakefile # gmake -f gmakefile
# or if GNU make is the default: # or if GNU make is the default:
# make -f gmakefile # make -f gmakefile
#
# OS X (Carbon)
# make -f gmakefile OSX=1
# #
# Win32 (Cygwin) # Win32 (Cygwin)
# make WIN32=1 # make -f gmakefile WIN32=1
# #
# Win32 (MINGW): # Win32 (MINGW):
# mingw32-make -f gmakefile WIN32=1 # mingw32-make -f gmakefile WIN32=1
DISP_DEFS=-DTEST_DIS=DIS_VR48 -DTEST_RES=RES_HALF # -DDEBUG_VT11 DISP_DEFS=-DTEST_DIS=DIS_VR48 -DTEST_RES=RES_HALF # -DDEBUG_VT11
ifeq ($(WIN32),) ifeq ($(WIN32),)
ifeq ($(OSX),)
#Unix environments #Unix environments
X11BASE=/usr/X11R6 X11BASE=/usr/X11R6
X11LIBDIR=$(X11BASE)/lib X11LIBDIR=$(X11BASE)/lib
@ -26,6 +30,10 @@ OSFLAGS=-I$(X11INCDIR)
DRIVER=x11.o DRIVER=x11.o
EXT= EXT=
else else
DRIVER=carbon.o
LIBS=-framework Carbon
endif
else
#Win32 environments #Win32 environments
LIBS=-lgdi32 LIBS=-lgdi32
OSFLAGS= OSFLAGS=
@ -39,39 +47,40 @@ CFLAGS=$(OPT) $(PROF) $(OSFLAGS) $(DISP_DEFS)
CC=gcc -Wunused CC=gcc -Wunused
LDFLAGS=$(PROF) LDFLAGS=$(PROF)
ALL= munch$(EXT) vt11$(EXT) ALL= munch$(EXT) vt11$(EXT)
ALL: $(ALL) ALL: $(ALL)
# munching squares; see README file for # munching squares; see README file for
# how to use console switches # how to use console switches
MUNCH=$(DRIVER) display.o test.o MUNCH=$(DRIVER) xy.o test.o
munch$(EXT): $(MUNCH) munch$(EXT): $(MUNCH)
$(CC) $(LDFLAGS) -o munch$(EXT) $(MUNCH) $(LIBS) $(CC) $(LDFLAGS) -o munch$(EXT) $(MUNCH) $(LIBS)
VT11=$(DRIVER) vt11.o vttest.o display.o VT11=$(DRIVER) vt11.o vttest.o xy.o
vt11$(EXT): $(VT11) vt11$(EXT): $(VT11)
$(CC) $(LDFLAGS) -o vt11$(EXT) $(VT11) $(LIBS) $(CC) $(LDFLAGS) -o vt11$(EXT) $(VT11) $(LIBS)
display.o: display.h ws.h xy.o: xy.h ws.h
vt11.o: display.h vt11.h vt11.o: xy.h vt11.h
x11.o: ws.h display.h x11.o: ws.h xy.h
carbon.o: ws.h
win32.o: ws.h win32.o: ws.h
test.o: display.h vt11.h test.o: xy.h vt11.h
vttest.o: display.h vt11.h vtmacs.h vttest.o: xy.h vt11.h vtmacs.h
clean: clean:
ifeq ($(WIN32),) ifeq ($(WIN32),)
rm -f *.o *~ .#* rm -f *.o *~ .#*
else else
if exist *.o del /q *.o if exist *.o del /q *.o
if exist *~ del /q *~ if exist *~ del /q *~
if exist .#* del /q .#* if exist .#* del /q .#*
endif endif
clobber: clean clobber: clean
ifeq ($(WIN32),) ifeq ($(WIN32),)
rm -f $(ALL) rm -f $(ALL)
else else
if exist *.exe del /q *.exe if exist *.exe del /q *.exe
endif endif

View file

@ -1,24 +1,29 @@
# $Id: smakefile,v 1.17 2004/01/24 08:31:56 phil Exp - revised by DAG # $Id: smakefile,v 1.6 2005/11/05 02:06:14 phil Exp $
# Makefile for test programs (standard Unix "make" version) # Makefile for test programs (standard Unix "make" version)
# Unix: # Unix:
# comment out Windows defs, uncomment Unix defs, # comment out OS X, Windows defs, uncomment Unix defs,
# edit Unix defs to fit your compiler/library environment, then # edit Unix defs to fit your compiler/library environment, then
# (g)make # make -f smakefile
#
# OS X (Carbon)
# comment out Unix, Windows defs, uncomment OS X defs
# make -f smakefile
# #
# Win32 (Cygwin) # Win32 (Cygwin)
# comment out Unix defs, uncomment Windows defs, then # comment out Unix defs, uncomment Windows defs, then
# make # make -f smakefile
# #
# Win32 (MINGW) # Win32 (MINGW)
# comment out Unix defs, uncomment Windows defs, then # comment out Unix defs, uncomment Windows defs, then
# mingw32-make # mingw32-make
DISP_DEFS=-DTEST_DIS=DIS_VR48 -DTEST_RES=RES_HALF # -DDEBUG_VT11 DISP_DEFS=-DTEST_DIS=DIS_VR48 -DTEST_RES=RES_HALF # -DDEBUG_VT11
#Unix environments #Unix environments
CC=cc # gcc -Wunused CC=cc
#CC=gcc -Wunused
#X11BASE=/usr/X11R6 #X11BASE=/usr/X11R6
#X11LIBDIR=$(X11BASE)/lib #X11LIBDIR=$(X11BASE)/lib
#X11INCDIR=$(X11BASE)/include #X11INCDIR=$(X11BASE)/include
@ -29,9 +34,19 @@ EXT=
PROF=-g # -pg PROF=-g # -pg
OPT=-O # -O2 OPT=-O # -O2
CFLAGS=$(OPT) $(PROF) $(OSFLAGS) $(DISP_DEFS) CFLAGS=$(OPT) $(PROF) $(OSFLAGS) $(DISP_DEFS)
CC=cc # gcc -Wunused
LDFLAGS=$(PROF) LDFLAGS=$(PROF)
##OS X
#CC=cc -Wunused
#LIBS=-framework Carbon
#OSFLAGS=
#DRIVER=carbon.o
#EXT=
#PROF=-g # -pg
#OPT=-O # -O2
#CFLAGS=$(OPT) $(PROF) $(OSFLAGS) $(DISP_DEFS)
#LDFLAGS=$(PROF)
##Win32 environments ##Win32 environments
#LIBS=-lgdi32 #LIBS=-lgdi32
#OSFLAGS= #OSFLAGS=
@ -43,33 +58,34 @@ LDFLAGS=$(PROF)
#CC=gcc -Wunused #CC=gcc -Wunused
LDFLAGS=$(PROF) LDFLAGS=$(PROF)
ALL= munch$(EXT) vt11$(EXT) ALL= munch$(EXT) vt11$(EXT)
ALL: $(ALL) ALL: $(ALL)
# munching squares; see README file for # munching squares; see README file for
# how to use console switches # how to use console switches
MUNCH=$(DRIVER) display.o test.o MUNCH=$(DRIVER) xy.o test.o
munch$(EXT): $(MUNCH) munch$(EXT): $(MUNCH)
$(CC) $(LDFLAGS) -o munch$(EXT) $(MUNCH) $(LIBS) $(CC) $(LDFLAGS) -o munch$(EXT) $(MUNCH) $(LIBS)
VT11=$(DRIVER) vt11.o vttest.o display.o VT11=$(DRIVER) vt11.o vttest.o xy.o
vt11$(EXT): $(VT11) vt11$(EXT): $(VT11)
$(CC) $(LDFLAGS) -o vt11$(EXT) $(VT11) $(LIBS) $(CC) $(LDFLAGS) -o vt11$(EXT) $(VT11) $(LIBS)
display.o: display.h ws.h xy.o: xy.h ws.h
vt11.o: display.h vt11.h vt11.o: xy.h vt11.h
x11.o: ws.h display.h x11.o: ws.h xy.h
carbon.o: ws.h
win32.o: ws.h win32.o: ws.h
test.o: display.h vt11.h test.o: xy.h vt11.h
vttest.o: display.h vt11.h vtmacs.h vttest.o: xy.h vt11.h vtmacs.h
clean: clean:
rm -f *.o *~ .#* # Unix rm -f *.o *~ .#* # Unix
# if exist *.o del /q *.o # Win32 # if exist *.o del /q *.o # Win32
# if exist *~ del /q *~ # Win32 # if exist *~ del /q *~ # Win32
# if exist .#* del /q .#* # Win32 # if exist .#* del /q .#* # Win32
clobber: clean clobber: clean
rm -f $(ALL) # Unix rm -f $(ALL) # Unix
# if exist *.exe del /q *.exe # Win32 # if exist *.exe del /q *.exe # Win32

View file

@ -1,5 +1,5 @@
/* /*
* $Id: test.c,v 1.23 2004/02/07 06:31:20 phil Exp $ * $Id: test.c,v 1.24 2005/01/14 18:58:00 phil Exp $
* XY Display simulator test program (PDP-1 Munching Squares) * XY Display simulator test program (PDP-1 Munching Squares)
* Phil Budne <phil@ultimate.com> * Phil Budne <phil@ultimate.com>
* September 2003 * September 2003
@ -52,7 +52,7 @@
#define EXIT_FAILURE 1 #define EXIT_FAILURE 1
#endif #endif
#include "display.h" #include "xy.h"
static unsigned long test_switches = 0; static unsigned long test_switches = 0;
@ -79,49 +79,49 @@ munch(void) {
int x, y; int x, y;
ac = test_switches; ac = test_switches;
ac += v; /* add v */ ac += v; /* add v */
if (ac & ~0777777) { if (ac & ~0777777) {
ac++; ac++;
ac &= 0777777; ac &= 0777777;
} }
v = ac; /* dac v */ v = ac; /* dac v */
ac <<= 9; /* rcl 9s */ ac <<= 9; /* rcl 9s */
io <<= 9; io <<= 9;
io |= ac>>18; io |= ac>>18;
ac &= 0777777; ac &= 0777777;
ac |= io>>18; ac |= io>>18;
io &= 0777777; io &= 0777777;
ac ^= v; /* xor v */ ac ^= v; /* xor v */
/* convert +/-512 one's complement to 0..1022, origin in lower left */ /* convert +/-512 one's complement to 0..1022, origin in lower left */
y = (io >> 8) & 01777; /* hi 10 */ y = (io >> 8) & 01777; /* hi 10 */
if (y & 01000) if (y & 01000)
y ^= 01000; y ^= 01000;
else else
y += 511; y += 511;
x = (ac >> 8) & 01777; /* hi 10 */ x = (ac >> 8) & 01777; /* hi 10 */
if (x & 01000) /* negative */ if (x & 01000) /* negative */
x ^= 01000; x ^= 01000;
else else
x += 511; x += 511;
if (display_point(x, y, DISPLAY_INT_MAX, 0)) if (display_point(x, y, DISPLAY_INT_MAX, 0))
printf("light pen hit at (%d,%d)\n", x, y); printf("light pen hit at (%d,%d)\n", x, y);
/*#define US 100000 /* 100ms (10/sec) */ /*#define US 100000 /* 100ms (10/sec) */
/*#define US 50000 /* 50ms (20/sec) */ /*#define US 50000 /* 50ms (20/sec) */
/*#define US 20000 /* 20ms (50/sec) */ /*#define US 20000 /* 20ms (50/sec) */
/*#define US 10000 /* 10ms (100/sec) */ /*#define US 10000 /* 10ms (100/sec) */
#define US 0 #define US 0
us += 50; /* 10 5us PDP-1 memory cycles */ us += 50; /* 10 5us PDP-1 memory cycles */
if (us >= US) { if (us >= US) {
display_age(us, 1); display_age(us, 1);
us = 0; us = 0;
} }
display_sync(); /* XXX push down */ display_sync(); /* XXX push down */
} }
#ifdef T2 #ifdef T2
@ -134,17 +134,17 @@ t2(void) {
display_init(TEST_DIS, TEST_RES); display_init(TEST_DIS, TEST_RES);
for (x = INTENSITIES-1; x >= 0; x--) { for (x = INTENSITIES-1; x >= 0; x--) {
for (y = 0; y < 20; y++) { for (y = 0; y < 20; y++) {
ws_display_point(x*4, y, x, 0); ws_display_point(x*4, y, x, 0);
ws_display_point(x*4+1, y, x, 0); ws_display_point(x*4+1, y, x, 0);
ws_display_point(x*4+2, y, x, 0); ws_display_point(x*4+2, y, x, 0);
ws_display_point(x*4+3, y, x, 0); ws_display_point(x*4+3, y, x, 0);
} }
display_sync(); display_sync();
} }
fflush(stdout); fflush(stdout);
for (;;) for (;;)
/* wait */ ; /* wait */ ;
} }
#endif #endif
@ -162,23 +162,23 @@ t3(void) {
display_init(TEST_DIS, TEST_RES); display_init(TEST_DIS, TEST_RES);
for (x = DISPLAY_INT_MAX; x >= 0; x--) { for (x = DISPLAY_INT_MAX; x >= 0; x--) {
for (y = 0; y < 20; y++) { for (y = 0; y < 20; y++) {
display_point(x*2, y*2, x, 0); display_point(x*2, y*2, x, 0);
} }
display_sync(); display_sync();
} }
fflush(stdout); fflush(stdout);
for (;;) for (;;)
/* wait */ ; /* wait */ ;
} }
#endif #endif
int int
main(void) { main(void) {
if (!display_init(TEST_DIS, TEST_RES)) if (!display_init(TEST_DIS, TEST_RES))
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
cpu_set_switches(04000UL); /* classic starting value */ cpu_set_switches(04000UL); /* classic starting value */
for (;;) { for (;;) {
#ifdef T2 #ifdef T2
t2(); t2();

View file

@ -1,5 +1,5 @@
/* /*
* $Id: type340.c,v 1.5 2004/01/24 20:52:16 phil Exp $ * $Id: type340.c,v 1.6 2005/01/14 18:58:00 phil Exp $
* Simulator Independent DEC Type 340 Graphic Display Processor Simulation * Simulator Independent DEC Type 340 Graphic Display Processor Simulation
* Phil Budne <phil@ultimate.com> * Phil Budne <phil@ultimate.com>
* September 20, 2003 * September 20, 2003
@ -35,7 +35,7 @@
* from the authors. * from the authors.
*/ */
#include "display.h" /* XY plot interface */ #include "xy.h" /* XY plot interface */
/* /*
* The Type 340 was used on the PDP-{4,6,7,9,10} * The Type 340 was used on the PDP-{4,6,7,9,10}
@ -62,23 +62,23 @@
typedef long ty340word; typedef long ty340word;
static ty340word DAC; /* Display Address Counter */ static ty340word DAC; /* Display Address Counter */
static unsigned char shift; /* 1 bit */ static unsigned char shift; /* 1 bit */
static enum mode mode; /* 3 bits */ static enum mode mode; /* 3 bits */
static int scale; /* 2 bits */ static int scale; /* 2 bits */
enum mode { PARAM=0, POINT, SLAVE, CHAR, VECTOR, VCONT, INCR, SUBR }; enum mode { PARAM=0, POINT, SLAVE, CHAR, VECTOR, VCONT, INCR, SUBR };
enum jump_type { DJP=2, DJS=3, DDS=1 }; enum jump_type { DJP=2, DJS=3, DDS=1 };
static ty340word ASR; /* Address Save Register */ static ty340word ASR; /* Address Save Register */
static unsigned char save_ff; /* "save" flip-flop */ static unsigned char save_ff; /* "save" flip-flop */
static unsigned char intensity; /* 3 bits */ static unsigned char intensity; /* 3 bits */
static unsigned char lp_ena; /* 1 bit */ static unsigned char lp_ena; /* 1 bit */
/* kept signed for raster violation checking */ /* kept signed for raster violation checking */
static short xpos, ypos; /* 10 bits, signed */ static short xpos, ypos; /* 10 bits, signed */
static unsigned char sequence; /* 2 bits */ static unsigned char sequence; /* 2 bits */
/* XXX make defines public for 340_cycle return */ /* XXX make defines public for 340_cycle return */
#define STOPPED 01 #define STOPPED 01
@ -101,7 +101,7 @@ ty340_set_dac(ty340word addr)
DAC = addr; DAC = addr;
mode = 0; mode = 0;
DEBUGF(("set DAC %06\r\n", DAC)); DEBUGF(("set DAC %06\r\n", DAC));
status = 0; /* XXX just clear stopped? */ status = 0; /* XXX just clear stopped? */
/* XXX clear other stuff? save_ff? */ /* XXX clear other stuff? save_ff? */
} }
@ -122,23 +122,23 @@ point(int x, int y, int seq)
i = DISPLAY_INT_MAX-7+intensity; i = DISPLAY_INT_MAX-7+intensity;
if (i <= 0) if (i <= 0)
i = 1; i = 1;
if (x < 0 || x > 1023) { if (x < 0 || x > 1023) {
status |= VEDGE; status |= VEDGE;
return 0; return 0;
} }
if (y < 0 || y > 1023) { if (y < 0 || y > 1023) {
status |= HEDGE; status |= HEDGE;
return 0; return 0;
} }
if (display_point(x, y, i, 0)) { if (display_point(x, y, i, 0)) {
if (lp_ena) { if (lp_ena) {
/* XXX save location? */ /* XXX save location? */
status |= LPHIT; status |= LPHIT;
sequence = seq; sequence = seq;
} }
} }
} }
@ -168,50 +168,50 @@ lineTwoStep(int x0, int y0, int x1, int y1)
if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
lpoint(x0,y0); lpoint(x0,y0);
if (dx == 0 && dy == 0) /* following algorithm won't work */ if (dx == 0 && dy == 0) /* following algorithm won't work */
return; /* just the one dot */ return; /* just the one dot */
lpoint(x1, y1); lpoint(x1, y1);
if (dx > dy) { if (dx > dy) {
int length = (dx - 1) >> 2; int length = (dx - 1) >> 2;
int extras = (dx - 1) & 3; int extras = (dx - 1) & 3;
int incr2 = (dy << 2) - (dx << 1); int incr2 = (dy << 2) - (dx << 1);
if (incr2 < 0) { if (incr2 < 0) {
int c = dy << 1; int c = dy << 1;
int incr1 = c << 1; int incr1 = c << 1;
int d = incr1 - dx; int d = incr1 - dx;
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
x0 += stepx; x0 += stepx;
x1 -= stepx; x1 -= stepx;
if (d < 0) { /* Pattern: */ if (d < 0) { /* Pattern: */
lpoint(x0, y0); lpoint(x0, y0);
lpoint(x0 += stepx, y0); /* x o o */ lpoint(x0 += stepx, y0); /* x o o */
lpoint(x1, y1); lpoint(x1, y1);
lpoint(x1 -= stepx, y1); lpoint(x1 -= stepx, y1);
d += incr1; d += incr1;
} }
else { else {
if (d < c) { /* Pattern: */ if (d < c) { /* Pattern: */
lpoint(x0, y0); /* o */ lpoint(x0, y0); /* o */
lpoint(x0 += stepx, y0 += stepy); /* x o */ lpoint(x0 += stepx, y0 += stepy); /* x o */
lpoint(x1, y1); lpoint(x1, y1);
lpoint(x1 -= stepx, y1 -= stepy); lpoint(x1 -= stepx, y1 -= stepy);
} else { } else {
lpoint(x0, y0 += stepy); /* Pattern: */ lpoint(x0, y0 += stepy); /* Pattern: */
lpoint(x0 += stepx, y0); /* o o */ lpoint(x0 += stepx, y0); /* o o */
lpoint(x1, y1 -= stepy); /* x */ lpoint(x1, y1 -= stepy); /* x */
lpoint(x1 -= stepx, y1); lpoint(x1 -= stepx, y1);
} }
d += incr2; d += incr2;
} }
} }
if (extras > 0) { if (extras > 0) {
if (d < 0) { if (d < 0) {
lpoint(x0 += stepx, y0); lpoint(x0 += stepx, y0);
if (extras > 1) lpoint(x0 += stepx, y0); if (extras > 1) lpoint(x0 += stepx, y0);
if (extras > 2) lpoint(x1 -= stepx, y1); if (extras > 2) lpoint(x1 -= stepx, y1);
} else } else
if (d < c) { if (d < c) {
lpoint(x0 += stepx, y0); lpoint(x0 += stepx, y0);
if (extras > 1) lpoint(x0 += stepx, y0 += stepy); if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
@ -221,96 +221,96 @@ lineTwoStep(int x0, int y0, int x1, int y1)
if (extras > 1) lpoint(x0 += stepx, y0); if (extras > 1) lpoint(x0 += stepx, y0);
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
} }
} }
} else { } else {
int c = (dy - dx) << 1; int c = (dy - dx) << 1;
int incr1 = c << 1; int incr1 = c << 1;
int d = incr1 + dx; int d = incr1 + dx;
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
x0 += stepx; x0 += stepx;
x1 -= stepx; x1 -= stepx;
if (d > 0) { if (d > 0) {
lpoint(x0, y0 += stepy); /* Pattern: */ lpoint(x0, y0 += stepy); /* Pattern: */
lpoint(x0 += stepx, y0 += stepy); /* o */ lpoint(x0 += stepx, y0 += stepy); /* o */
lpoint(x1, y1 -= stepy); /* o */ lpoint(x1, y1 -= stepy); /* o */
lpoint(x1 -= stepx, y1 -= stepy); /* x */ lpoint(x1 -= stepx, y1 -= stepy); /* x */
d += incr1; d += incr1;
} else { } else {
if (d < c) { if (d < c) {
lpoint(x0, y0); /* Pattern: */ lpoint(x0, y0); /* Pattern: */
lpoint(x0 += stepx, y0 += stepy); /* o */ lpoint(x0 += stepx, y0 += stepy); /* o */
lpoint(x1, y1); /* x o */ lpoint(x1, y1); /* x o */
lpoint(x1 -= stepx, y1 -= stepy); lpoint(x1 -= stepx, y1 -= stepy);
} else { } else {
lpoint(x0, y0 += stepy); /* Pattern: */ lpoint(x0, y0 += stepy); /* Pattern: */
lpoint(x0 += stepx, y0); /* o o */ lpoint(x0 += stepx, y0); /* o o */
lpoint(x1, y1 -= stepy); /* x */ lpoint(x1, y1 -= stepy); /* x */
lpoint(x1 -= stepx, y1); lpoint(x1 -= stepx, y1);
} }
d += incr2; d += incr2;
} }
} }
if (extras > 0) { if (extras > 0) {
if (d > 0) { if (d > 0) {
lpoint(x0 += stepx, y0 += stepy); lpoint(x0 += stepx, y0 += stepy);
if (extras > 1) lpoint(x0 += stepx, y0 += stepy); if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
} else if (d < c) { } else if (d < c) {
lpoint(x0 += stepx, y0); lpoint(x0 += stepx, y0);
if (extras > 1) lpoint(x0 += stepx, y0 += stepy); if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
if (extras > 2) lpoint(x1 -= stepx, y1); if (extras > 2) lpoint(x1 -= stepx, y1);
} else { } else {
lpoint(x0 += stepx, y0 += stepy); lpoint(x0 += stepx, y0 += stepy);
if (extras > 1) lpoint(x0 += stepx, y0); if (extras > 1) lpoint(x0 += stepx, y0);
if (extras > 2) { if (extras > 2) {
if (d > c) if (d > c)
lpoint(x1 -= stepx, y1 -= stepy); lpoint(x1 -= stepx, y1 -= stepy);
else else
lpoint(x1 -= stepx, y1); lpoint(x1 -= stepx, y1);
} }
} }
} }
} }
} else { } else {
int length = (dy - 1) >> 2; int length = (dy - 1) >> 2;
int extras = (dy - 1) & 3; int extras = (dy - 1) & 3;
int incr2 = (dx << 2) - (dy << 1); int incr2 = (dx << 2) - (dy << 1);
if (incr2 < 0) { if (incr2 < 0) {
int c = dx << 1; int c = dx << 1;
int incr1 = c << 1; int incr1 = c << 1;
int d = incr1 - dy; int d = incr1 - dy;
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
y0 += stepy; y0 += stepy;
y1 -= stepy; y1 -= stepy;
if (d < 0) { if (d < 0) {
lpoint(x0, y0); lpoint(x0, y0);
lpoint(x0, y0 += stepy); lpoint(x0, y0 += stepy);
lpoint(x1, y1); lpoint(x1, y1);
lpoint(x1, y1 -= stepy); lpoint(x1, y1 -= stepy);
d += incr1; d += incr1;
} else { } else {
if (d < c) { if (d < c) {
lpoint(x0, y0); lpoint(x0, y0);
lpoint(x0 += stepx, y0 += stepy); lpoint(x0 += stepx, y0 += stepy);
lpoint(x1, y1); lpoint(x1, y1);
lpoint(x1 -= stepx, y1 -= stepy); lpoint(x1 -= stepx, y1 -= stepy);
} else { } else {
lpoint(x0 += stepx, y0); lpoint(x0 += stepx, y0);
lpoint(x0, y0 += stepy); lpoint(x0, y0 += stepy);
lpoint(x1 -= stepx, y1); lpoint(x1 -= stepx, y1);
lpoint(x1, y1 -= stepy); lpoint(x1, y1 -= stepy);
} }
d += incr2; d += incr2;
} }
} }
if (extras > 0) { if (extras > 0) {
if (d < 0) { if (d < 0) {
lpoint(x0, y0 += stepy); lpoint(x0, y0 += stepy);
if (extras > 1) lpoint(x0, y0 += stepy); if (extras > 1) lpoint(x0, y0 += stepy);
if (extras > 2) lpoint(x1, y1 -= stepy); if (extras > 2) lpoint(x1, y1 -= stepy);
} else } else
if (d < c) { if (d < c) {
lpoint(x0, y0 += stepy); lpoint(x0, y0 += stepy);
if (extras > 1) lpoint(x0 += stepx, y0 += stepy); if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
@ -320,57 +320,57 @@ lineTwoStep(int x0, int y0, int x1, int y1)
if (extras > 1) lpoint(x0, y0 += stepy); if (extras > 1) lpoint(x0, y0 += stepy);
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
} }
} }
} else { } else {
int c = (dx - dy) << 1; int c = (dx - dy) << 1;
int incr1 = c << 1; int incr1 = c << 1;
int d = incr1 + dy; int d = incr1 + dy;
int i; int i;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
y0 += stepy; y0 += stepy;
y1 -= stepy; y1 -= stepy;
if (d > 0) { if (d > 0) {
lpoint(x0 += stepx, y0); lpoint(x0 += stepx, y0);
lpoint(x0 += stepx, y0 += stepy); lpoint(x0 += stepx, y0 += stepy);
lpoint(x1 -= stepy, y1); lpoint(x1 -= stepy, y1);
lpoint(x1 -= stepx, y1 -= stepy); lpoint(x1 -= stepx, y1 -= stepy);
d += incr1; d += incr1;
} else { } else {
if (d < c) { if (d < c) {
lpoint(x0, y0); lpoint(x0, y0);
lpoint(x0 += stepx, y0 += stepy); lpoint(x0 += stepx, y0 += stepy);
lpoint(x1, y1); lpoint(x1, y1);
lpoint(x1 -= stepx, y1 -= stepy); lpoint(x1 -= stepx, y1 -= stepy);
} else { } else {
lpoint(x0 += stepx, y0); lpoint(x0 += stepx, y0);
lpoint(x0, y0 += stepy); lpoint(x0, y0 += stepy);
lpoint(x1 -= stepx, y1); lpoint(x1 -= stepx, y1);
lpoint(x1, y1 -= stepy); lpoint(x1, y1 -= stepy);
} }
d += incr2; d += incr2;
} }
} }
if (extras > 0) { if (extras > 0) {
if (d > 0) { if (d > 0) {
lpoint(x0 += stepx, y0 += stepy); lpoint(x0 += stepx, y0 += stepy);
if (extras > 1) lpoint(x0 += stepx, y0 += stepy); if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy); if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
} else if (d < c) { } else if (d < c) {
lpoint(x0, y0 += stepy); lpoint(x0, y0 += stepy);
if (extras > 1) lpoint(x0 += stepx, y0 += stepy); if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
if (extras > 2) lpoint(x1, y1 -= stepy); if (extras > 2) lpoint(x1, y1 -= stepy);
} else { } else {
lpoint(x0 += stepx, y0 += stepy); lpoint(x0 += stepx, y0 += stepy);
if (extras > 1) lpoint(x0, y0 += stepy); if (extras > 1) lpoint(x0, y0 += stepy);
if (extras > 2) { if (extras > 2) {
if (d > c) if (d > c)
lpoint(x1 -= stepx, y1 -= stepy); lpoint(x1 -= stepx, y1 -= stepy);
else else
lpoint(x1, y1 -= stepy); lpoint(x1, y1 -= stepy);
} }
} }
} }
} }
} }
} /* lineTwoStep */ } /* lineTwoStep */
@ -383,30 +383,30 @@ vector(int i, int sx, int dx, int sy, int dy)
y0 = ypos; y0 = ypos;
if (sx) { if (sx) {
x1 = x0 - dx; x1 = x0 - dx;
if (x1 < 0) /* XXX TEMP? */ if (x1 < 0) /* XXX TEMP? */
x1 = 0; x1 = 0;
} }
else { else {
x1 = x0 + dx; x1 = x0 + dx;
if (x1 > 1023) /* XXX TEMP? */ if (x1 > 1023) /* XXX TEMP? */
x1 = 1023; x1 = 1023;
} }
if (sy) { if (sy) {
y1 = y0 - dy; y1 = y0 - dy;
if (y1 < 0) /* XXX TEMP? */ if (y1 < 0) /* XXX TEMP? */
y1 = 0; y1 = 0;
} }
else { else {
y1 = y0 + dy; /* XXX TEMP? */ y1 = y0 + dy; /* XXX TEMP? */
if (y1 > 1023) if (y1 > 1023)
y1 = 1023; y1 = 1023;
} }
DEBUGF(("vector i%d (%d,%d) to (%d,%d)\r\n", i, x0, y0, x1, y1)); DEBUGF(("vector i%d (%d,%d) to (%d,%d)\r\n", i, x0, y0, x1, y1));
if (i) if (i)
lineTwoStep(x0, y0, x1, y1); lineTwoStep(x0, y0, x1, y1);
xpos = x1; xpos = x1;
ypos = y1; ypos = y1;
@ -417,40 +417,40 @@ vector(int i, int sx, int dx, int sy, int dy)
int int
ipoint(int i, int n, unsigned char byte) ipoint(int i, int n, unsigned char byte)
{ {
if (byte & 010) { /* left/right */ if (byte & 010) { /* left/right */
if (byte & 04) { if (byte & 04) {
if (xpos == 0) { if (xpos == 0) {
status |= VEDGE; status |= VEDGE;
return 1; return 1;
} }
xpos--; xpos--;
} }
else { else {
if (xpos == 1023) { if (xpos == 1023) {
status |= VEDGE; status |= VEDGE;
return 1; return 1;
} }
xpos++; xpos++;
} }
} }
if (byte & 02) { /* up/down */ if (byte & 02) { /* up/down */
if (byte & 04) { if (byte & 04) {
if (ypos == 0) { if (ypos == 0) {
status |= HEDGE; status |= HEDGE;
return 1; return 1;
} }
ypos--; ypos--;
} }
else { else {
if (ypos == 1023) { if (ypos == 1023) {
status |= HEDGE; status |= HEDGE;
return 1; return 1;
} }
ypos++; ypos++;
} }
} }
if (i) if (i)
point(xpos, ypos, n); point(xpos, ypos, n);
return 0; return 0;
} }
@ -459,70 +459,70 @@ ipoint(int i, int n, unsigned char byte)
* 342 character generator - first 64 characters (from manual) * 342 character generator - first 64 characters (from manual)
*/ */
static const unsigned char chars[64][5] = { static const unsigned char chars[64][5] = {
{ 0070, 0124, 0154, 0124, 0070 }, /* 00 */ { 0070, 0124, 0154, 0124, 0070 }, /* 00 */
{ 0174, 0240, 0240, 0240, 0174 }, /* 01 A */ { 0174, 0240, 0240, 0240, 0174 }, /* 01 A */
{ 0376, 0222, 0222, 0222, 0154 }, /* 02 B */ { 0376, 0222, 0222, 0222, 0154 }, /* 02 B */
{ 0174, 0202, 0202, 0202, 0104 }, /* 03 C */ { 0174, 0202, 0202, 0202, 0104 }, /* 03 C */
{ 0376, 0202, 0202, 0202, 0174 }, /* 04 D */ { 0376, 0202, 0202, 0202, 0174 }, /* 04 D */
{ 0376, 0222, 0222, 0222, 0222 }, /* 05 E */ { 0376, 0222, 0222, 0222, 0222 }, /* 05 E */
{ 0376, 0220, 0220, 0220, 0220 }, /* 06 F */ { 0376, 0220, 0220, 0220, 0220 }, /* 06 F */
{ 0174, 0202, 0222, 0222, 0134 }, /* 07 G */ { 0174, 0202, 0222, 0222, 0134 }, /* 07 G */
{ 0376, 0020, 0020, 0020, 0376 }, /* 10 H */ { 0376, 0020, 0020, 0020, 0376 }, /* 10 H */
{ 0000, 0202, 0376, 0202, 0000 }, /* 11 I */ { 0000, 0202, 0376, 0202, 0000 }, /* 11 I */
{ 0004, 0002, 0002, 0002, 0374 }, /* 12 J */ { 0004, 0002, 0002, 0002, 0374 }, /* 12 J */
{ 0376, 0020, 0050, 0104, 0202 }, /* 13 K */ { 0376, 0020, 0050, 0104, 0202 }, /* 13 K */
{ 0376, 0002, 0002, 0002, 0002 }, /* 14 K */ { 0376, 0002, 0002, 0002, 0002 }, /* 14 K */
{ 0374, 0100, 0040, 0100, 0374 }, /* 15 M */ { 0374, 0100, 0040, 0100, 0374 }, /* 15 M */
{ 0376, 0100, 0040, 0020, 0376 }, /* 16 N */ { 0376, 0100, 0040, 0020, 0376 }, /* 16 N */
{ 0174, 0202, 0202, 0202, 0174 }, /* 17 O */ { 0174, 0202, 0202, 0202, 0174 }, /* 17 O */
{ 0376, 0220, 0220, 0220, 0140 }, /* 20 P */ { 0376, 0220, 0220, 0220, 0140 }, /* 20 P */
{ 0174, 0202, 0212, 0206, 0176 }, /* 21 Q */ { 0174, 0202, 0212, 0206, 0176 }, /* 21 Q */
{ 0376, 0220, 0230, 0224, 0142 }, /* 22 R */ { 0376, 0220, 0230, 0224, 0142 }, /* 22 R */
{ 0144, 0222, 0222, 0222, 0114 }, /* 23 S */ { 0144, 0222, 0222, 0222, 0114 }, /* 23 S */
{ 0200, 0200, 0376, 0200, 0200 }, /* 24 T */ { 0200, 0200, 0376, 0200, 0200 }, /* 24 T */
{ 0374, 0002, 0002, 0002, 0374 }, /* 25 U */ { 0374, 0002, 0002, 0002, 0374 }, /* 25 U */
{ 0370, 0004, 0002, 0004, 0370 }, /* 26 V */ { 0370, 0004, 0002, 0004, 0370 }, /* 26 V */
{ 0376, 0004, 0010, 0004, 0376 }, /* 27 W */ { 0376, 0004, 0010, 0004, 0376 }, /* 27 W */
{ 0202, 0104, 0070, 0104, 0202 }, /* 30 X */ { 0202, 0104, 0070, 0104, 0202 }, /* 30 X */
{ 0200, 0100, 0076, 0100, 0200 }, /* 31 Y */ { 0200, 0100, 0076, 0100, 0200 }, /* 31 Y */
{ 0226, 0232, 0222, 0262, 0322 }, /* 32 Z */ { 0226, 0232, 0222, 0262, 0322 }, /* 32 Z */
{ 0000, 0000, 0000, 0000, 0000 }, /* 33 LF */ { 0000, 0000, 0000, 0000, 0000 }, /* 33 LF */
{ 0000, 0000, 0000, 0000, 0000 }, /* 34 CR */ { 0000, 0000, 0000, 0000, 0000 }, /* 34 CR */
{ 0000, 0000, 0000, 0000, 0000 }, /* 35 HORIZ */ { 0000, 0000, 0000, 0000, 0000 }, /* 35 HORIZ */
{ 0000, 0000, 0000, 0000, 0000 }, /* 36 VERT */ { 0000, 0000, 0000, 0000, 0000 }, /* 36 VERT */
{ 0000, 0000, 0000, 0000, 0000 }, /* 37 ESC */ { 0000, 0000, 0000, 0000, 0000 }, /* 37 ESC */
{ 0000, 0000, 0000, 0000, 0000 }, /* 40 space */ { 0000, 0000, 0000, 0000, 0000 }, /* 40 space */
{ 0000, 0000, 0372, 0000, 0000 }, /* 41 ! */ { 0000, 0000, 0372, 0000, 0000 }, /* 41 ! */
{ 0000, 0340, 0000, 0340, 0000 }, /* 42 " */ { 0000, 0340, 0000, 0340, 0000 }, /* 42 " */
{ 0050, 0376, 0050, 0376, 0050 }, /* 43 # */ { 0050, 0376, 0050, 0376, 0050 }, /* 43 # */
{ 0144, 0222, 0376, 0222, 0114 }, /* 44 $ */ { 0144, 0222, 0376, 0222, 0114 }, /* 44 $ */
{ 0306, 0310, 0220, 0246, 0306 }, /* 45 % */ { 0306, 0310, 0220, 0246, 0306 }, /* 45 % */
{ 0154, 0222, 0156, 0004, 0012 }, /* 46 & */ { 0154, 0222, 0156, 0004, 0012 }, /* 46 & */
{ 0000, 0000, 0300, 0340, 0000 }, /* 47 ' */ { 0000, 0000, 0300, 0340, 0000 }, /* 47 ' */
{ 0070, 0104, 0202, 0000, 0000 }, /* 50 ( */ { 0070, 0104, 0202, 0000, 0000 }, /* 50 ( */
{ 0000, 0000, 0202, 0104, 0070 }, /* 51 ) */ { 0000, 0000, 0202, 0104, 0070 }, /* 51 ) */
{ 0124, 0070, 0174, 0070, 0124 }, /* 52 * */ { 0124, 0070, 0174, 0070, 0124 }, /* 52 * */
{ 0020, 0020, 0174, 0020, 0020 }, /* 53 + */ { 0020, 0020, 0174, 0020, 0020 }, /* 53 + */
{ 0000, 0014, 0016, 0000, 0000 }, /* 54 , */ { 0000, 0014, 0016, 0000, 0000 }, /* 54 , */
{ 0020, 0020, 0020, 0020, 0020 }, /* 55 - */ { 0020, 0020, 0020, 0020, 0020 }, /* 55 - */
{ 0000, 0006, 0006, 0000, 0000 }, /* 56 . */ { 0000, 0006, 0006, 0000, 0000 }, /* 56 . */
{ 0004, 0010, 0020, 0040, 0100 }, /* 57 / */ { 0004, 0010, 0020, 0040, 0100 }, /* 57 / */
{ 0174, 0212, 0222, 0242, 0174 }, /* 60 0 */ { 0174, 0212, 0222, 0242, 0174 }, /* 60 0 */
{ 0000, 0102, 0376, 0002, 0000 }, /* 61 1 */ { 0000, 0102, 0376, 0002, 0000 }, /* 61 1 */
{ 0116, 0222, 0222, 0222, 0142 }, /* 62 2 */ { 0116, 0222, 0222, 0222, 0142 }, /* 62 2 */
{ 0104, 0202, 0222, 0222, 0154 }, /* 63 3 */ { 0104, 0202, 0222, 0222, 0154 }, /* 63 3 */
{ 0020, 0060, 0120, 0376, 0020 }, /* 64 4 */ { 0020, 0060, 0120, 0376, 0020 }, /* 64 4 */
{ 0344, 0222, 0222, 0222, 0214 }, /* 65 5 */ { 0344, 0222, 0222, 0222, 0214 }, /* 65 5 */
{ 0174, 0222, 0222, 0222, 0114 }, /* 66 6 */ { 0174, 0222, 0222, 0222, 0114 }, /* 66 6 */
{ 0306, 0210, 0220, 0240, 0300 }, /* 67 7 */ { 0306, 0210, 0220, 0240, 0300 }, /* 67 7 */
{ 0154, 0222, 0222, 0222, 0154 }, /* 70 8 */ { 0154, 0222, 0222, 0222, 0154 }, /* 70 8 */
{ 0144, 0222, 0222, 0222, 0174 }, /* 71 9 */ { 0144, 0222, 0222, 0222, 0174 }, /* 71 9 */
{ 0000, 0066, 0066, 0000, 0000 }, /* 72 : */ { 0000, 0066, 0066, 0000, 0000 }, /* 72 : */
{ 0000, 0154, 0156, 0000, 0000 }, /* 73 ; */ { 0000, 0154, 0156, 0000, 0000 }, /* 73 ; */
{ 0020, 0050, 0104, 0202, 0000 }, /* 74 < */ { 0020, 0050, 0104, 0202, 0000 }, /* 74 < */
{ 0050, 0050, 0050, 0050, 0050 }, /* 75 = */ { 0050, 0050, 0050, 0050, 0050 }, /* 75 = */
{ 0000, 0202, 0104, 0050, 0020 }, /* 76 > */ { 0000, 0202, 0104, 0050, 0020 }, /* 76 > */
{ 0100, 0200, 0236, 0220, 0140 } /* 77 ? */ { 0100, 0200, 0236, 0220, 0140 } /* 77 ? */
}; };
/* /*
@ -535,43 +535,43 @@ character(int n, char c)
int x, y; int x, y;
switch (c) { switch (c) {
case 033: /* LF */ case 033: /* LF */
if (ypos < 12) { if (ypos < 12) {
status |= HEDGE; status |= HEDGE;
ypos = 0; ypos = 0;
} }
else else
ypos -= 12; /* XXX scale? */ ypos -= 12; /* XXX scale? */
return 0; return 0;
case 034: /* CR */ case 034: /* CR */
xpos = 0; xpos = 0;
return 0; return 0;
case 035: /* shift in */ case 035: /* shift in */
shift = 1; shift = 1;
return 0; return 0;
case 036: /* shift out */ case 036: /* shift out */
shift = 0; shift = 0;
return 0; return 0;
case 037: /* escape */ case 037: /* escape */
sequence = n; sequence = n;
return 1; return 1;
} }
/* XXX plot character from character set selected by "shift" /* XXX plot character from character set selected by "shift"
* (offset index by 64?) * (offset index by 64?)
*/ */
for (x = 0; x < 5; x++) { for (x = 0; x < 5; x++) {
for (y = 0; y < 7; y++) { for (y = 0; y < 7; y++) {
if (chars[c][x] & (1<<y)) { if (chars[c][x] & (1<<y)) {
/* XXX check for raster violation? */ /* XXX check for raster violation? */
point(xpos+x, ypos+y, n); /* XXX scale? */ point(xpos+x, ypos+y, n); /* XXX scale? */
} }
} }
} }
xpos += 7; /* XXX scale? */ xpos += 7; /* XXX scale? */
if (xpos > 1023) { if (xpos > 1023) {
xpos = 1023; xpos = 1023;
status |= VEDGE; status |= VEDGE;
} }
return 0; return 0;
} }
@ -583,7 +583,7 @@ ty340_cycle(int us, int slowdown)
int i, escape, stopped; int i, escape, stopped;
if (status & STOPPED) if (status & STOPPED)
return 0; /* XXX age display? */ return 0; /* XXX age display? */
inst = ty340_fetch(DAC); inst = ty340_fetch(DAC);
DEBUGF(("%06o: %06o\r\n", DAC, inst)); DEBUGF(("%06o: %06o\r\n", DAC, inst));
@ -592,115 +592,115 @@ ty340_cycle(int us, int slowdown)
escape = 0; escape = 0;
switch (mode) { switch (mode) {
case PARAM: case PARAM:
mode = GETFIELD(inst, 2, 4); mode = GETFIELD(inst, 2, 4);
if (TESTBIT(inst, 5)) { /* load l.p. enable */ if (TESTBIT(inst, 5)) { /* load l.p. enable */
lp_ena = TESTBIT(inst,6); lp_ena = TESTBIT(inst,6);
DEBUGF(("lp_ena %d\r\n", lp_ena)); DEBUGF(("lp_ena %d\r\n", lp_ena));
} }
if (TESTBIT(inst, 7)) { if (TESTBIT(inst, 7)) {
status |= STOPPED; status |= STOPPED;
if (TESTBIT(inst, 8)) if (TESTBIT(inst, 8))
ty340_stop_int(); /* set stop_int_end? */ ty340_stop_int(); /* set stop_int_end? */
} }
if (TESTBIT(inst, 11)) if (TESTBIT(inst, 11))
scale = GETFIELD(inst, 12, 13); scale = GETFIELD(inst, 12, 13);
if (TESTBIT(inst, 14)) if (TESTBIT(inst, 14))
intensity = GETFIELD(inst, 15, 17); intensity = GETFIELD(inst, 15, 17);
break; break;
case POINT: case POINT:
mode = GETFIELD(inst, 2, 4); mode = GETFIELD(inst, 2, 4);
if (TESTBIT(inst, 5)) /* load l.p. enable */ if (TESTBIT(inst, 5)) /* load l.p. enable */
lp_ena = TESTBIT(inst,6); lp_ena = TESTBIT(inst,6);
if (TESTBIT(inst, 1)) if (TESTBIT(inst, 1))
ypos = GETFIELD(inst, 8, 17); ypos = GETFIELD(inst, 8, 17);
else else
xpos = GETFIELD(inst, 8, 17); xpos = GETFIELD(inst, 8, 17);
if (TESTBIT(inst, 7)) if (TESTBIT(inst, 7))
point(xpos, ypos, 0); point(xpos, ypos, 0);
break; break;
case SLAVE: case SLAVE:
mode = GETFIELD(inst, 2, 4); mode = GETFIELD(inst, 2, 4);
break; break;
case CHAR: case CHAR:
escape = (character(0, GETFIELD(inst, 0, 5)) || escape = (character(0, GETFIELD(inst, 0, 5)) ||
character(1, GETFIELD(inst, 6, 11)) || character(1, GETFIELD(inst, 6, 11)) ||
character(2, GETFIELD(inst, 12, 17))); character(2, GETFIELD(inst, 12, 17)));
break; break;
case VECTOR: case VECTOR:
escape = TESTBIT(inst, 0); escape = TESTBIT(inst, 0);
if (vector(TESTBIT(inst, 1), if (vector(TESTBIT(inst, 1),
TESTBIT(inst, 2), GETFIELD(inst, 3, 9), TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) { TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) {
/* XXX interrupt? */ /* XXX interrupt? */
} }
break; break;
case VCONT: case VCONT:
escape = TESTBIT(inst, 0); escape = TESTBIT(inst, 0);
if (vector(TESTBIT(inst, 1), if (vector(TESTBIT(inst, 1),
TESTBIT(inst, 2), GETFIELD(inst, 3, 9), TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) { TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) {
/* XXX set escape? */ /* XXX set escape? */
mode = PARAM; /* raster violation */ mode = PARAM; /* raster violation */
} }
break; break;
case INCR: case INCR:
escape = TESTBIT(inst, 0); /* escape bit */ escape = TESTBIT(inst, 0); /* escape bit */
i = TESTBIT(inst, 1); i = TESTBIT(inst, 1);
if (ipoint(i, 0, GETFIELD(inst, 2, 5)) || if (ipoint(i, 0, GETFIELD(inst, 2, 5)) ||
ipoint(i, 1, GETFIELD(inst, 6, 9)) || ipoint(i, 1, GETFIELD(inst, 6, 9)) ||
ipoint(i, 2, GETFIELD(inst, 10, 13)) || ipoint(i, 2, GETFIELD(inst, 10, 13)) ||
ipoint(i, 3, GETFIELD(inst, 14, 17))) ipoint(i, 3, GETFIELD(inst, 14, 17)))
/* XXX set escape? */ /* XXX set escape? */
mode = PARAM; /* raster violation */ mode = PARAM; /* raster violation */
break; break;
case SUBR: case SUBR:
/* type 347 Display Subroutine Option? */ /* type 347 Display Subroutine Option? */
mode = GETFIELD(inst, 2, 4); mode = GETFIELD(inst, 2, 4);
/* XXX take high bits of current DAC? */ /* XXX take high bits of current DAC? */
addr = GETFIELD(inst, 5, 17); addr = GETFIELD(inst, 5, 17);
switch (GETFIELD(inst, 0, 1)) { switch (GETFIELD(inst, 0, 1)) {
case DJS: /* display jump and save */ case DJS: /* display jump and save */
ASR = DAC; ASR = DAC;
save_ff = 1; /* set "save" flip-flop */ save_ff = 1; /* set "save" flip-flop */
/* FALL */ /* FALL */
case DJP: /* display jump */ case DJP: /* display jump */
DAC = addr; DAC = addr;
break; break;
case DDS: /* display deposit save register */ case DDS: /* display deposit save register */
ty340_deposit(addr, (DJP<<16) | ASR); ty340_deposit(addr, (DJP<<16) | ASR);
save_ff = 0; /* ?? */ save_ff = 0; /* ?? */
break; break;
default: default:
/* XXX ??? */ /* XXX ??? */
break; break;
} }
break; break;
} }
if (escape) { if (escape) {
mode = PARAM; mode = PARAM;
if (save_ff) { if (save_ff) {
/* return from subroutine */ /* return from subroutine */
DAC = ASR; DAC = ASR;
save_ff = 0; save_ff = 0;
} }
} }
return status; return status;
} /* ty340_cycle */ } /* ty340_cycle */

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,11 @@
/* /*
* $Id: vt11.h,v 1.7 2004/01/25 17:20:51 phil Exp $ * $Id: vt11.h,v 1.8 2005/01/14 18:58:02 phil Exp $
* interface to VT11 simulator * interface to VT11 simulator
* Phil Budne <phil@ultimate.com> * Phil Budne <phil@ultimate.com>
* September 16, 2003 * September 16, 2003
* Substantially revised by Douglas A. Gwyn, 14 Jan. 2004 * Substantially revised by Douglas A. Gwyn, 14 Jan. 2004
* *
* prerequisite: display.h * prerequisite: xy.h
*/ */
/* /*
@ -46,17 +46,17 @@ typedef unsigned long uint32;
* spacing; to change the VT11 simulation from these default values, * spacing; to change the VT11 simulation from these default values,
* set vt11_csp_{w,h} before calling any function named vt11_*. * set vt11_csp_{w,h} before calling any function named vt11_*.
*/ */
extern unsigned char vt11_csp_w; /* horizontal character spacing */ extern unsigned char vt11_csp_w; /* horizontal character spacing */
#ifdef VT11_NARROW_OPT /* W3 or W6 installed */ #ifdef VT11_NARROW_OPT /* W3 or W6 installed */
#define VT11_CSP_W 12 #define VT11_CSP_W 12
#else /* VT11 normal; W4 or W5 installed */ #else /* VT11 normal; W4 or W5 installed */
#define VT11_CSP_W 14 #define VT11_CSP_W 14
#endif #endif
extern unsigned char vt11_csp_h; /* vertical character spacing */ extern unsigned char vt11_csp_h; /* vertical character spacing */
#ifdef VT11_TALL_OPT /* W3 or W4 installed */ #ifdef VT11_TALL_OPT /* W3 or W4 installed */
#define VT11_CSP_H 26 #define VT11_CSP_H 26
#else /* VT11 normal; W5 or W6 installed */ #else /* VT11 normal; W5 or W6 installed */
#define VT11_CSP_H 24 #define VT11_CSP_H 24
#endif #endif
/* /*
@ -65,73 +65,73 @@ extern unsigned char vt11_csp_h; /* vertical character spacing */
* before calling any function named vt11_* (other than vt11_reset()). * before calling any function named vt11_* (other than vt11_reset()).
*/ */
#ifndef DISPLAY_TYPE #ifndef DISPLAY_TYPE
#define DISPLAY_TYPE DIS_VR17 /* default display type */ #define DISPLAY_TYPE DIS_VR17 /* default display type */
#endif #endif
extern enum display_type vt11_display; /* DIS_VR{14,17,48} */ extern enum display_type vt11_display; /* DIS_VR{14,17,48} */
/* /*
* The PIX_SCALE #define establishes the initial default display scale * The PIX_SCALE #define establishes the initial default display scale
* factor; to change from the default scale factor, set vt11_scale * factor; to change from the default scale factor, set vt11_scale
* before calling any function named vt11_* (other than vt11_reset()). * before calling any function named vt11_* (other than vt11_reset()).
*/ */
#ifndef PIX_SCALE #ifndef PIX_SCALE
#define PIX_SCALE RES_HALF /* default display scale factor */ #define PIX_SCALE RES_HALF /* default display scale factor */
#endif #endif
extern int vt11_scale; /* RES_{FULL,HALF,QUARTER,EIGHTH} */ extern int vt11_scale; /* RES_{FULL,HALF,QUARTER,EIGHTH} */
/* /*
* When vt11_init (READONLY) is nonzero, it indicates that it is too late * When vt11_init (READONLY) is nonzero, it indicates that it is too late
* to change display parameters (type, scale, character spacing, etc.). * to change display parameters (type, scale, character spacing, etc.).
*/ */
extern unsigned char vt11_init; /* set after display_init() called */ extern unsigned char vt11_init; /* set after display_init() called */
/* vt11.c simulates either a VT11 or a VT48(VS60), according to display type: */ /* vt11.c simulates either a VT11 or a VT48(VS60), according to display type: */
#define VS60 (vt11_display == DIS_VR48) #define VS60 (vt11_display == DIS_VR48)
#define VT11 (!VS60) #define VT11 (!VS60)
/* The display file is an array of 16-bit words. */ /* The display file is an array of 16-bit words. */
typedef uint16 vt11word; typedef uint16 vt11word;
extern int32 vt11_get_dpc(void); /* read Display PC */ extern int32 vt11_get_dpc(void); /* read Display PC */
extern int32 vt11_get_mpr(void); /* read mode parameter register */ extern int32 vt11_get_mpr(void); /* read mode parameter register */
extern int32 vt11_get_xpr(void); /* read graphplot incr/X pos register */ extern int32 vt11_get_xpr(void); /* read graphplot incr/X pos register */
extern int32 vt11_get_ypr(void); /* read char code/Y pos register */ extern int32 vt11_get_ypr(void); /* read char code/Y pos register */
extern int32 vt11_get_rr(void); /* read relocate register */ extern int32 vt11_get_rr(void); /* read relocate register */
extern int32 vt11_get_spr(void); /* read status parameter register */ extern int32 vt11_get_spr(void); /* read status parameter register */
extern int32 vt11_get_xor(void); /* read X offset register */ extern int32 vt11_get_xor(void); /* read X offset register */
extern int32 vt11_get_yor(void); /* read Y offset register */ extern int32 vt11_get_yor(void); /* read Y offset register */
extern int32 vt11_get_anr(void); /* read associative name register */ extern int32 vt11_get_anr(void); /* read associative name register */
extern int32 vt11_get_scr(void); /* read slave console/color register */ extern int32 vt11_get_scr(void); /* read slave console/color register */
extern int32 vt11_get_nr(void); /* read name register */ extern int32 vt11_get_nr(void); /* read name register */
extern int32 vt11_get_sdr(void); /* read stack data register */ extern int32 vt11_get_sdr(void); /* read stack data register */
extern int32 vt11_get_str(void); /* read char string term register */ extern int32 vt11_get_str(void); /* read char string term register */
extern int32 vt11_get_sar(void); /* read stack address/maint register */ extern int32 vt11_get_sar(void); /* read stack address/maint register */
extern int32 vt11_get_zpr(void); /* read Z position register */ extern int32 vt11_get_zpr(void); /* read Z position register */
extern int32 vt11_get_zor(void); /* read Z offset register */ extern int32 vt11_get_zor(void); /* read Z offset register */
extern void vt11_set_dpc(uint16); /* write Display PC */ extern void vt11_set_dpc(uint16); /* write Display PC */
extern void vt11_set_mpr(uint16); /* write mode parameter register */ extern void vt11_set_mpr(uint16); /* write mode parameter register */
extern void vt11_set_xpr(uint16); /* write graphplot inc/X pos register */ extern void vt11_set_xpr(uint16); /* write graphplot inc/X pos register */
extern void vt11_set_ypr(uint16); /* write char code/Y pos register */ extern void vt11_set_ypr(uint16); /* write char code/Y pos register */
extern void vt11_set_rr(uint16); /* write relocate register */ extern void vt11_set_rr(uint16); /* write relocate register */
extern void vt11_set_spr(uint16); /* write status parameter register */ extern void vt11_set_spr(uint16); /* write status parameter register */
extern void vt11_set_xor(uint16); /* write X offset register */ extern void vt11_set_xor(uint16); /* write X offset register */
extern void vt11_set_yor(uint16); /* write Y offset register */ extern void vt11_set_yor(uint16); /* write Y offset register */
extern void vt11_set_anr(uint16); /* write associative name register */ extern void vt11_set_anr(uint16); /* write associative name register */
extern void vt11_set_scr(uint16); /* write slave console/color register */ extern void vt11_set_scr(uint16); /* write slave console/color register */
extern void vt11_set_nr(uint16); /* write name register */ extern void vt11_set_nr(uint16); /* write name register */
extern void vt11_set_sdr(uint16); /* write stack data register */ extern void vt11_set_sdr(uint16); /* write stack data register */
extern void vt11_set_str(uint16); /* write char string term register */ extern void vt11_set_str(uint16); /* write char string term register */
extern void vt11_set_sar(uint16); /* write stack address/maint register */ extern void vt11_set_sar(uint16); /* write stack address/maint register */
extern void vt11_set_zpr(uint16); /* write Z position register */ extern void vt11_set_zpr(uint16); /* write Z position register */
extern void vt11_set_zor(uint16); /* write Z offset register */ extern void vt11_set_zor(uint16); /* write Z offset register */
extern void vt11_reset(void); /* reset the display processor */ extern void vt11_reset(void); /* reset the display processor */
extern int vt11_cycle(int,int); /* perform a display processor cycle */ extern int vt11_cycle(int,int); /* perform a display processor cycle */
/* /*
* callbacks from VT11/VS60 simulator (to SIMH PDP-11 VT driver, for example) * callbacks from VT11/VS60 simulator (to SIMH PDP-11 VT driver, for example)
*/ */
extern int vt_fetch(uint32, vt11word *); /* get a display-file word */ extern int vt_fetch(uint32, vt11word *); /* get a display-file word */
extern void vt_stop_intr(void); /* post a display-stop interrupt */ extern void vt_stop_intr(void); /* post a display-stop interrupt */
extern void vt_lpen_intr(void); /* post a surface-related interrupt */ extern void vt_lpen_intr(void); /* post a surface-related interrupt */
extern void vt_char_intr(void); /* post a bad-char./timeout interrupt */ extern void vt_char_intr(void); /* post a bad-char./timeout interrupt */
extern void vt_name_intr(void); /* post a name-match interrupt */ extern void vt_name_intr(void); /* post a name-match interrupt */

View file

@ -1,291 +1,297 @@
/* /*
* $Id: vtmacs.h,v 1.4 2004/02/07 06:26:47 phil Exp $ * $Id: vtmacs.h,v 1.5 2005/01/12 18:10:13 phil Exp $
* macros for coding a VT11/VS60 display file (instructions and data) * macros for coding a VT11/VS60 display file (instructions and data)
* for standalone use of vt11.c (not embedded in PDP-11 simulator)
* Douglas A. Gwyn <gwyn@arl.army.mil> * Douglas A. Gwyn <gwyn@arl.army.mil>
* January 31, 2004 * September 03, 2004
* *
* XXX -- assumes ASCII host character set * XXX -- assumes ASCII host character set
*/ */
/* helper macros (not for use outside this header): */ /* helper macros (not for use outside this header): */
#define SGN_(x) ((x) < 0) #define SGN_(x) ((x) < 0)
#define MAG_(x) ((x) >= 0 ? (x) : -(x)) /* -0 not expressible directly in C */ #define MAG_(x) ((x) >= 0 ? (x) : -(x)) /* -0 not expressible directly in C */
#if 0 /* manual seems to say this; wrong! */
#define JDL_(x) ((SGN_(raddr) << 8) | MAG_(raddr))
#else /* sign extend, 9-bit twos complement */
#define JDL_(x) ((x) >= 0 ? (x) : ((~(unsigned)-(x))+1) & 0777)
#endif
/* control instructions: */ /* control instructions: */
/* load status register A: */ /* load status register A: */
#define LSRA(stop,stop_intr,lp_hit_chg,ital,refresh,menu) \ #define LSRA(stop,stop_intr,lp_hit_chg,ital,refresh,menu) \
0170000 | stop | stop_intr | lp_hit_chg | ital | refresh | menu 0170000 | stop | stop_intr | lp_hit_chg | ital | refresh | menu
/* display stop: */ /* display stop: */
#define ST_SAME 00000 /* don't stop display */ #define ST_SAME 00000 /* don't stop display */
#define ST_STOP 02000 /* stop display */ #define ST_STOP 02000 /* stop display */
/* stop interrupt: */ /* stop interrupt: */
#define SI_SAME 00000 /* no change */ #define SI_SAME 00000 /* no change */
#define SI_INHIBIT 01000 /* inhibit interrupt on stop */ #define SI_INHIBIT 01000 /* inhibit interrupt on stop */
#define SI_GENERATE 01400 /* generate interrupt on stop */ #define SI_GENERATE 01400 /* generate interrupt on stop */
/* light pen hit intensify (bright-down on VS60): */ /* light pen hit intensify (bright-down on VS60): */
#define LI_SAME 0000 /* no change */ #define LI_SAME 0000 /* no change */
#define LI_INTENSIFY 0200 /* enable intensify on hit (VT11) */ #define LI_INTENSIFY 0200 /* enable intensify on hit (VT11) */
#define LI_BRIGHTDOWN 0200 /* enable bright down on hit (VS60) */ #define LI_BRIGHTDOWN 0200 /* enable bright down on hit (VS60) */
#define LI_NOINTENSIFY 0300 /* inhibit intensify on hit (VT11) */ #define LI_NOINTENSIFY 0300 /* inhibit intensify on hit (VT11) */
#define LI_NOBRIGHTDOWN 0300 /* inhibit bright down on hit (VS60) */ #define LI_NOBRIGHTDOWN 0300 /* inhibit bright down on hit (VS60) */
/* italic font: */ /* italic font: */
#define IT_SAME 000 /* no change */ #define IT_SAME 000 /* no change */
#define IT_NORMAL 040 /* normal font */ #define IT_NORMAL 040 /* normal font */
#define IT_ITALIC 060 /* italic font */ #define IT_ITALIC 060 /* italic font */
/* refresh rate: */ /* refresh rate: */
#define RF_UNSYNC 000 /* unsynchronized */ #define RF_UNSYNC 000 /* unsynchronized */
#define RF_SAME 000 /* (happens to work like that) */ #define RF_SAME 000 /* (happens to work like that) */
#define RF_LINE 004 /* sync with line (VT11) */ #define RF_LINE 004 /* sync with line (VT11) */
#define RF_30 004 /* 30 frames/sec (VS60) */ #define RF_30 004 /* 30 frames/sec (VS60) */
#define RF_40 010 /* 40 frames/sec (VS60) */ #define RF_40 010 /* 40 frames/sec (VS60) */
#define RF_EXT 014 /* external sync (VS60) */ #define RF_EXT 014 /* external sync (VS60) */
/* menu/main area (VS60): */ /* menu/main area (VS60): */
#define MN_SAME 0 /* no change */ #define MN_SAME 0 /* no change */
#define MN_MAIN 2 /* major screen area */ #define MN_MAIN 2 /* major screen area */
#define MN_MENU 3 /* menu area */ #define MN_MENU 3 /* menu area */
/* load status register B: */ /* load status register B: */
#define LSRB(color,set_step,step) \ #define LSRB(color,set_step,step) \
0174000 | color | set_step | (step) 0174000 | color | set_step | (step)
/* color select (VS60): */ /* color select (VS60): */
#define CL_SAME 00000 /* no change */ #define CL_SAME 00000 /* no change */
#define CL_GREEN 01000 /* green */ #define CL_GREEN 01000 /* green */
#define CL_YELLOW 01200 /* yellow */ #define CL_YELLOW 01200 /* yellow */
#define CL_ORANGE 01400 /* orange */ #define CL_ORANGE 01400 /* orange */
#define CL_RED 01600 /* red */ #define CL_RED 01600 /* red */
/* graphplot increment register change enable: */ /* graphplot increment register change enable: */
#define SS_SAME 0000 /* no change (step value ignored) */ #define SS_SAME 0000 /* no change (step value ignored) */
#define SS_CHANGE 0100 /* write step value into register */ #define SS_CHANGE 0100 /* write step value into register */
/* load status register BB (VS60): */ /* load status register BB (VS60): */
#define LSRBB(z_data,edge_intr,depth_cue,char_esc) \ #define LSRBB(z_data,edge_intr,depth_cue,char_esc) \
0176000 | z_data | edge_intr | depth_cue | char_esc 0176000 | z_data | edge_intr | depth_cue | char_esc
/* file Z data: */ /* file Z data: */
#define ZD_SAME 000 /* no change */ #define ZD_SAME 000 /* no change */
#define ZD_NO 010 /* d.file does not contain Z coords. */ #define ZD_NO 010 /* d.file does not contain Z coords. */
#define ZD_YES 014 /* d.file contains Z coordinates */ #define ZD_YES 014 /* d.file contains Z coordinates */
/* edge interrupts enable: */ /* edge interrupts enable: */
#define ED_SAME 000 /* no change */ #define ED_SAME 000 /* no change */
#define ED_DIS 040 /* disable intr. on edge transition */ #define ED_DIS 040 /* disable intr. on edge transition */
#define ED_ENA 060 /* enable intr. on edge transition */ #define ED_ENA 060 /* enable intr. on edge transition */
/* depth cue processing: */ /* depth cue processing: */
#define DQ_SAME 0000 /* no change */ #define DQ_SAME 0000 /* no change */
#define DQ_OFF 0200 /* disable depth cueing (Z intensity) */ #define DQ_OFF 0200 /* disable depth cueing (Z intensity) */
#define DQ_ON 0300 /* enable depth cueing (Z intensity) */ #define DQ_ON 0300 /* enable depth cueing (Z intensity) */
/* escape on terminating character: */ /* escape on terminating character: */
#define ES_SAME 0 /* no change */ #define ES_SAME 0 /* no change */
#define ES_NO 2 /* disable POPR on terminating char. */ #define ES_NO 2 /* disable POPR on terminating char. */
#define ES_YES 3 /* enable POPR on terminating char. */ #define ES_YES 3 /* enable POPR on terminating char. */
/* load status register C (VS60): */ /* load status register C (VS60): */
#define LSRC(rotate,cs_change,cscale,vs_change,vscale) \ #define LSRC(rotate,cs_change,cscale,vs_change,vscale) \
0154000 | rotate | cs_change | ((cscale)<<5) | \ 0154000 | rotate | cs_change | ((cscale)<<5) | \
vs_change | (vscale) vs_change | (vscale)
/* character rotation: */ /* character rotation: */
#define RO_SAME 00000 /* no change */ #define RO_SAME 00000 /* no change */
#define RO_HORIZONTAL 01000 /* no text rotation */ #define RO_HORIZONTAL 01000 /* no text rotation */
#define RO_VERTICAL 01400 /* rotate text 90 degrees CCW */ #define RO_VERTICAL 01400 /* rotate text 90 degrees CCW */
/* character scale change enable: */ /* character scale change enable: */
#define CS_SAME 0000 /* no change (cscale value ignored) */ #define CS_SAME 0000 /* no change (cscale value ignored) */
#define CS_CHANGE 0200 /* set character scale */ #define CS_CHANGE 0200 /* set character scale */
/* vector scale change enable: */ /* vector scale change enable: */
#define VS_SAME 000 /* no change (vscale value ignored) */ #define VS_SAME 000 /* no change (vscale value ignored) */
#define VS_CHANGE 020 /* set vector scale */ #define VS_CHANGE 020 /* set vector scale */
/* load scope selection register (VS60): */ /* load scope selection register (VS60): */
#define LSSR(console,disp,lp_intr,sw_intr) \ #define LSSR(console,disp,lp_intr,sw_intr) \
0164000 | console | disp | lp_intr | sw_intr 0164000 | console | disp | lp_intr | sw_intr
/* console to which this instruction applies: */ /* console to which this instruction applies: */
#define CN_0 0000 /* console # 0 */ #define CN_0 0000 /* console # 0 */
#define CN_1 0400 /* console # 1 */ #define CN_1 0400 /* console # 1 */
/* display enable: */ /* display enable: */
#define DS_SAME 0000 /* no change */ #define DS_SAME 0000 /* no change */
#define DS_DIS 0200 /* disable display (blank CRT) */ #define DS_DIS 0200 /* disable display (blank CRT) */
#define DS_ENA 0300 /* enable display (use CRT) */ #define DS_ENA 0300 /* enable display (use CRT) */
/* light-pen hit interrupt enable: */ /* light-pen hit interrupt enable: */
#define LH_SAME 0000 /* no change */ #define LH_SAME 0000 /* no change */
#define LH_DIS 0040 /* light-pen hit interrupt disabled */ #define LH_DIS 0040 /* light-pen hit interrupt disabled */
#define LH_ENA 0060 /* light-pen hit interrupt enabled */ #define LH_ENA 0060 /* light-pen hit interrupt enabled */
/* tip-switch transition interrupt enable: */ /* tip-switch transition interrupt enable: */
#define SW_SAME 0000 /* no change */ #define SW_SAME 0000 /* no change */
#define SW_DIS 0010 /* tip-switch interrupt disabled */ #define SW_DIS 0010 /* tip-switch interrupt disabled */
#define SW_ENA 0014 /* tip-switch hit interrupt enabled */ #define SW_ENA 0014 /* tip-switch hit interrupt enabled */
/* load name register (VS60): */ /* load name register (VS60): */
#define LNR(name) \ #define LNR(name) \
0150000 | (name) 0150000 | (name)
/* set graphic mode: */ /* set graphic mode: */
#define SGM(mode,intens,lp_intr,blink,line_type) \ #define SGM(mode,intens,lp_intr,blink,line_type) \
0100000 | mode | intens | lp_intr | blink | line_type 0100000 | mode | intens | lp_intr | blink | line_type
/* graphic mode: */ /* graphic mode: */
#define GM_CHAR 000000 /* character */ #define GM_CHAR 000000 /* character */
#define GM_SVECT 004000 /* short vector */ #define GM_SVECT 004000 /* short vector */
#define GM_LVECT 010000 /* long vector */ #define GM_LVECT 010000 /* long vector */
#define GM_APOINT 014000 /* absolute point, or offset */ #define GM_APOINT 014000 /* absolute point, or offset */
#define GM_GRAPHX 020000 /* graphplot X, or basic long vector */ #define GM_GRAPHX 020000 /* graphplot X, or basic long vector */
#define GM_GRAPHY 024000 /* graphplot Y, or basic long vector */ #define GM_GRAPHY 024000 /* graphplot Y, or basic long vector */
#define GM_RPOINT 030000 /* relative point */ #define GM_RPOINT 030000 /* relative point */
#define GM_BSVECT 034000 /* basic short vector */ #define GM_BSVECT 034000 /* basic short vector */
#define GM_ARC 040000 /* circle/arc */ #define GM_ARC 040000 /* circle/arc */
#define GM_AVECT 044000 /* absolute vector */ #define GM_AVECT 044000 /* absolute vector */
/* intensity: */ /* intensity: */
#define IN_SAME 00000 /* no change */ #define IN_SAME 00000 /* no change */
#define IN_0 02000 /* intensity level 0 (dimmest) */ #define IN_0 02000 /* intensity level 0 (dimmest) */
#define IN_1 02200 /* intensity level 1 */ #define IN_1 02200 /* intensity level 1 */
#define IN_2 02400 /* intensity level 2 */ #define IN_2 02400 /* intensity level 2 */
#define IN_3 02600 /* intensity level 3 */ #define IN_3 02600 /* intensity level 3 */
#define IN_4 03000 /* intensity level 4 */ #define IN_4 03000 /* intensity level 4 */
#define IN_5 03200 /* intensity level 5 */ #define IN_5 03200 /* intensity level 5 */
#define IN_6 03400 /* intensity level 6 */ #define IN_6 03400 /* intensity level 6 */
#define IN_7 03600 /* intensity level 7 (brightest) */ #define IN_7 03600 /* intensity level 7 (brightest) */
/* light pen interrupt: */ /* light pen interrupt: */
#define LP_SAME 0000 /* no change */ #define LP_SAME 0000 /* no change */
#define LP_DIS 0100 /* light-pen hit interrupt disabled */ #define LP_DIS 0100 /* light-pen hit interrupt disabled */
#define LP_ENA 0140 /* light-pen hit interrupt enabled */ #define LP_ENA 0140 /* light-pen hit interrupt enabled */
/* blink: */ /* blink: */
#define BL_SAME 000 /* no change */ #define BL_SAME 000 /* no change */
#define BL_OFF 020 /* blink off */ #define BL_OFF 020 /* blink off */
#define BL_ON 030 /* blink on */ #define BL_ON 030 /* blink on */
/* line type: */ /* line type: */
#define LT_SAME 00 /* no change */ #define LT_SAME 00 /* no change */
#define LT_SOLID 04 /* solid */ #define LT_SOLID 04 /* solid */
#define LT_LDASH 05 /* long dash */ #define LT_LDASH 05 /* long dash */
#define LT_SDASH 06 /* short dash */ #define LT_SDASH 06 /* short dash */
#define LT_DDASH 07 /* dot dash */ #define LT_DDASH 07 /* dot dash */
/* display jump absolute: */ /* display jump absolute: */
#define DJMP_ABS(addr) \ #define DJMP_ABS(addr) \
0160000, \ 0160000, \
(addr) & ~1 (addr) & ~1
/* display jump relative (VS60): */ /* display jump relative (VS60) [raddr in words]: */
#define DJMP_REL(raddr) \ #define DJMP_REL(raddr) \
0161000 | (SGN_(raddr) << 8) | MAG_(raddr) 0161000 | JDL_(raddr)
/* display jump to subroutine absolute (VS60): */ /* display jump to subroutine absolute (VS60): */
#define DJSR_ABS(addr) \ #define DJSR_ABS(addr) \
0162000, \ 0162000, \
(addr) & ~1 (addr) & ~1
/* display jump to subroutine relative (VS60): */ /* display jump to subroutine relative (VS60) [raddr in words]: */
#define DJSR_REL(raddr) \ #define DJSR_REL(raddr) \
0163000 | (SGN_(raddr) << 8) | MAG_(raddr) 0163000 | JDL_(raddr)
/* display no-op: */ /* display no-op: */
#define DNOP \ #define DNOP \
0164000 0164000
/* display pop, no restore (VS60): */ /* display pop, no restore (VS60): */
#define DPOP_NR \ #define DPOP_NR \
0165000 0165000
/* display pop, restore (VS60): */ /* display pop, restore (VS60): */
#define DPOP_R \ #define DPOP_R \
0165000 0165000
/* display stop: */ /* display stop: */
#define DSTOP LSRA(ST_STOP,SI_SAME,LI_SAME,IT_SAME,RF_UNSYNC,MN_SAME) #define DSTOP LSRA(ST_STOP,SI_SAME,LI_SAME,IT_SAME,RF_UNSYNC,MN_SAME)
/* graphic data: */ /* graphic data: */
/* intensify enable (common to all modes exept CHAR and OFFSET): */ /* intensify enable (common to all modes exept CHAR and OFFSET): */
#define I_OFF 000000 /* beam off */ #define I_OFF 000000 /* beam off */
#define I_ON 040000 /* beam on */ #define I_ON 040000 /* beam on */
/* Note: when VS60 "file Z data" is enabled, /* Note: when VS60 "file Z data" is enabled,
use the *3() macros instead of the corresponding normal ones. */ use the *3() macros instead of the corresponding normal ones. */
/* character data: */ /* character data: */
#define CHAR(c1,c2) \ #define CHAR(c1,c2) \
((c2) << 8) | (c1) /* 7-bit ASCII assumed */ ((c2) << 8) | (c1) /* 7-bit ASCII assumed */
/* short vector data: */ /* short vector data: */
#define SVECT(i,dx,dy) \ #define SVECT(i,dx,dy) \
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy) i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy)
#define SVECT3(i,dx,dy,dz) \ #define SVECT3(i,dx,dy,dz) \
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy), \ i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy), \
(SGN_(dz) << 13) | (MAG_(dz) << 2) (SGN_(dz) << 13) | (MAG_(dz) << 2)
/* long vector data: */ /* long vector data: */
#define LVECT(i,dx,dy) \ #define LVECT(i,dx,dy) \
i | (SGN_(dx) << 13) | MAG_(dx), \ i | (SGN_(dx) << 13) | MAG_(dx), \
(SGN_(dy) << 13) | MAG_(dy) (SGN_(dy) << 13) | MAG_(dy)
#define LVECT3(i,dx,dy,dz) \ #define LVECT3(i,dx,dy,dz) \
i | (SGN_(dx) << 13) | MAG_(dx), \ i | (SGN_(dx) << 13) | MAG_(dx), \
(SGN_(dy) << 13) | MAG_(dy), \ (SGN_(dy) << 13) | MAG_(dy), \
(SGN_(dz) << 13) | (MAG_(dz) << 2) (SGN_(dz) << 13) | (MAG_(dz) << 2)
/* rotation data (VS60, probably unimplemented): */ /* rotation data (VS60, probably unimplemented): */
#define ROTATE(i,a,b) \ #define ROTATE(i,a,b) \
i | (SGN_(a) << 13) | 010000 | MAG_(a), \ i | (SGN_(a) << 13) | 010000 | MAG_(a), \
(SGN_(b) << 13) | MAG_(b) (SGN_(b) << 13) | MAG_(b)
#define ROTATE3(i,a,b,c) \ #define ROTATE3(i,a,b,c) \
i | (SGN_(a) << 13) | 010000 | MAG_(a), \ i | (SGN_(a) << 13) | 010000 | MAG_(a), \
(SGN_(b) << 13) | MAG_(b), \ (SGN_(b) << 13) | MAG_(b), \
(SGN_(c) << 13) | (MAG_(c) << 2) (SGN_(c) << 13) | (MAG_(c) << 2)
/* absolute point data: */ /* absolute point data: */
#define APOINT(i,x,y) \ #define APOINT(i,x,y) \
i | (SGN_(x) << 13) | MAG_(x), \ i | (SGN_(x) << 13) | MAG_(x), \
(SGN_(y) << 13) | MAG_(y) (SGN_(y) << 13) | MAG_(y)
#define APOINT3(i,x,y,z) \ #define APOINT3(i,x,y,z) \
i | (SGN_(x) << 13) | MAG_(x), \ i | (SGN_(x) << 13) | MAG_(x), \
(SGN_(y) << 13) | MAG_(y), \ (SGN_(y) << 13) | MAG_(y), \
(SGN_(z) << 13) | (MAG_(z) << 2) (SGN_(z) << 13) | (MAG_(z) << 2)
/* offset data (VS60): */ /* offset data (VS60): */
#define OFFSET(x,y) \ #define OFFSET(x,y) \
(SGN_(x) << 13) | 010000 | MAG_(x), \ (SGN_(x) << 13) | 010000 | MAG_(x), \
(SGN_(y) << 13) | 010000 | MAG_(y) (SGN_(y) << 13) | 010000 | MAG_(y)
#define OFFSET3(x,y,z) \ #define OFFSET3(x,y,z) \
(SGN_(x) << 13) | 010000 | MAG_(x), \ (SGN_(x) << 13) | 010000 | MAG_(x), \
(SGN_(y) << 13) | 010000 | MAG_(y), \ (SGN_(y) << 13) | 010000 | MAG_(y), \
(SGN_(z) << 13) | 010000 | (MAG_(z) << 2) (SGN_(z) << 13) | 010000 | (MAG_(z) << 2)
/* graphplot X data: */ /* graphplot X data: */
#define GRAPHX(i,x) \ #define GRAPHX(i,x) \
i | (x) i | (x)
/* graphplot Y data: */ /* graphplot Y data: */
#define GRAPHY(i,y) \ #define GRAPHY(i,y) \
i | (y) i | (y)
/* basic long vector data (VS60): */ /* basic long vector data (VS60): */
#define BLVECT(i,dir,len) \ #define BLVECT(i,dir,len) \
i | ((dir) << 11) | 02000 | (len) i | ((dir) << 11) | 02000 | (len)
/* relative point data: */ /* relative point data: */
#define RPOINT(i,dx,dy) \ #define RPOINT(i,dx,dy) \
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy) i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy)
#define RPOINT3(i,dx,dy,dz) \ #define RPOINT3(i,dx,dy,dz) \
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy), \ i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy), \
(SGN_(dz) << 13) | (MAG_(dz) << 2) (SGN_(dz) << 13) | (MAG_(dz) << 2)
/* basic short vector data (VS60): */ /* basic short vector data (VS60): */
#define BSVECT(i,dir1,len1,dir2,len2) \ #define BSVECT(i,dir1,len1,dir2,len2) \
i | ((dir2) << 11) | ((len2) << 7) | ((dir1) << 4) | (len1) i | ((dir2) << 11) | ((len2) << 7) | ((dir1) << 4) | (len1)
/* circle/arc data (VS60, option): */ /* circle/arc data (VS60, option): */
#define ARC(i,dcx,dcy,dex,dey) \ #define ARC(i,dcx,dcy,dex,dey) \
i | (SGN_(dcx) << 13) | MAG_(dcx), \ i | (SGN_(dcx) << 13) | MAG_(dcx), \
(SGN_(dcy) << 13) | MAG_(dcy), \ (SGN_(dcy) << 13) | MAG_(dcy), \
(SGN_(dex) << 13) | MAG_(dex), \ (SGN_(dex) << 13) | MAG_(dex), \
(SGN_(dey) << 13) | MAG_(dey) (SGN_(dey) << 13) | MAG_(dey)
#define ARC3(i,dcx,dcy,cz,dex,dey,ez) \ #define ARC3(i,dcx,dcy,cz,dex,dey,ez) \
i | (SGN_(dcx) << 13) | MAG_(dcx), \ i | (SGN_(dcx) << 13) | MAG_(dcx), \
(SGN_(dcy) << 13) | MAG_(dcy), \ (SGN_(dcy) << 13) | MAG_(dcy), \
(SGN_(cz) << 13) | (MAG_(cz) << 2), \ (SGN_(cz) << 13) | (MAG_(cz) << 2), \
(SGN_(dex) << 13) | MAG_(dex), \ (SGN_(dex) << 13) | MAG_(dex), \
(SGN_(dey) << 13) | MAG_(dey), \ (SGN_(dey) << 13) | MAG_(dey), \
(SGN_(ez) << 13) | (MAG_(ez) << 2) (SGN_(ez) << 13) | (MAG_(ez) << 2)
/* absolute vector data (VS60): */ /* absolute vector data (VS60): */
#define AVECT(i,x,y) \ #define AVECT(i,x,y) \
i | (SGN_(x) << 13) | MAG_(x), \ i | (SGN_(x) << 13) | MAG_(x), \
(SGN_(y) << 13) | MAG_(y) (SGN_(y) << 13) | MAG_(y)
#define AVECT3(i,x,y,z) \ #define AVECT3(i,x,y,z) \
i | (SGN_(x) << 13) | MAG_(x), \ i | (SGN_(x) << 13) | MAG_(x), \
(SGN_(y) << 13) | MAG_(y), \ (SGN_(y) << 13) | MAG_(y), \
(SGN_(z) << 13) | (MAG_(z) << 2) (SGN_(z) << 13) | (MAG_(z) << 2)

View file

@ -1,11 +1,11 @@
/* /*
* $Id: vttest.c,v 1.10 2004/02/07 06:31:21 phil Exp $ * $Id: vttest.c,v 1.15 2005/08/06 21:09:05 phil Exp $
* VT11 test * VT11 test
* Phil Budne <phil@ultimate.com> * Phil Budne <phil@ultimate.com>
* September 13, 2003 * September 13, 2003
* Substantially revised by Douglas A. Gwyn, 27 Jan. 2004 * Substantially revised by Douglas A. Gwyn, 05 Aug 2005
* *
* XXX -- assumes ASCII host character set * XXX -- assumes ASCII host character set
* *
* In addition to providing some display tests, this program serves as an * In addition to providing some display tests, this program serves as an
* example of how the VT11/VS60 display processor simulator can be used * example of how the VT11/VS60 display processor simulator can be used
@ -22,7 +22,7 @@
* safely modify the display without stopping the display processor, which * safely modify the display without stopping the display processor, which
* is asynchronously interpreting the display file. * is asynchronously interpreting the display file.
*/ */
#undef FRAME1STOP /* define to pause after first frame of a section */ #undef FRAME1STOP /* define to pause after first frame of a section */
#ifndef TEST_DIS #ifndef TEST_DIS
#define TEST_DIS DIS_VR48 #define TEST_DIS DIS_VR48
@ -32,39 +32,40 @@
#define TEST_RES RES_HALF #define TEST_RES RES_HALF
#endif #endif
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "ws.h" /* for ws_beep() */ #include "ws.h" /* for ws_beep() */
#include "display.h" #include "xy.h"
#include "vt11.h" #include "vt11.h"
#include "vtmacs.h" #include "vtmacs.h"
#define USEC 3 /* simulated microseconds per cycle; #define USEC 3 /* simulated microseconds per cycle;
making this large causes flicker! */ making this large causes flicker! */
#define JMPA 0160000 /* first word of DJMP_ABS */ #define JMPA 0160000 /* first word of DJMP_ABS */
#define SUPSCR 021 /* SUPERSCRIPT char */ #define SUPSCR 021 /* SUPERSCRIPT char */
#define SUBSCR 022 /* SUBSCRIPT char */ #define SUBSCR 022 /* SUBSCRIPT char */
#define ENDSUP 023 /* END SUPERSCRIPT char */ #define ENDSUP 023 /* END SUPERSCRIPT char */
#define ENDSUB 024 /* END SUBSCRIPT char */ #define ENDSUB 024 /* END SUBSCRIPT char */
/* The following display file (whose words might be larger than 16 bits) is /* The following display file (whose words might be larger than 16 bits) is
divided into sections, each ended by a display-stop-with-interrupt divided into sections, each ended by a display-stop-with-interrupt
instruction followed by an extra word. The display-stop interrupt handler instruction followed by an extra word. The display-stop interrupt handler
replaces these two words with a jump to the start of the section, causing replaces these two words with a jump to the start of the section, causing
an endless refresh loop. To advance to the next section, activate the an endless refresh loop. To advance to the next section, activate the
"tip switch" (mouse button 1); this works even if simulating a VT11. */ "tip switch" (mouse button 1); this works even if simulating a VT11. */
#define ENDSECT LSRA(ST_STOP,SI_GENERATE,LI_SAME,IT_SAME,RF_UNSYNC,MN_SAME), 0, #define ENDSECT LSRA(ST_STOP,SI_GENERATE,LI_SAME,IT_SAME,RF_UNSYNC,MN_SAME), 0,
#define ENDFILE LSRA(ST_STOP,SI_GENERATE,LI_SAME,IT_SAME,RF_UNSYNC,MN_SAME), 1, #define ENDFILE LSRA(ST_STOP,SI_GENERATE,LI_SAME,IT_SAME,RF_UNSYNC,MN_SAME), 1,
/* FILE VT. Static displays that work for both VT11 and VS60. */ /* FILE VT. Static displays that work for both VT11 and VS60. */
unsigned short VT[] = { unsigned short VT[] = {
/* SECTION 1. Box just inside VR14 area using all four line types. /* SECTION 1. Box just inside VR14 area using all four line types.
Suitable for VT11 and VS60. */ Suitable for VT11 and VS60. */
LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME), LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME),
@ -86,7 +87,7 @@ unsigned short VT[] = {
ENDSECT ENDSECT
/* SECTION 2. All text characters (both normal and italic). /* SECTION 2. All text characters (both normal and italic).
Suitable for VT11 and VS60. */ Suitable for VT11 and VS60. */
LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME), LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME),
@ -138,7 +139,7 @@ unsigned short VT[] = {
ENDSECT ENDSECT
/* SECTION 3. Fancy display involving all VT11 graphic modes. /* SECTION 3. Fancy display involving all VT11 graphic modes.
Suitable for VT11 and VS60. */ Suitable for VT11 and VS60. */
LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME), LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME),
@ -810,7 +811,7 @@ unsigned short VT[] = {
ENDSECT ENDSECT
/* SECTION 4. Clipping tests. /* SECTION 4. Clipping tests.
Suitable for VT11 and VS60. */ Suitable for VT11 and VS60. */
LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME), LSRA(ST_SAME, SI_SAME, LI_INTENSIFY, IT_NORMAL, RF_UNSYNC, MN_SAME),
@ -843,32 +844,33 @@ unsigned short LP[] = {
/* SECTION 1. "rubber-band" dot-dash vector to tracking object. */ /* SECTION 1. "rubber-band" dot-dash vector to tracking object. */
SGM(GM_APOINT, IN_SAME, LP_SAME, BL_SAME, LT_SAME), SGM(GM_APOINT, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
APOINT(I_OFF, 01000, 01000), /* screen center */ APOINT(I_OFF, 01000, 01000), /* screen center */
SGM(GM_LVECT, IN_4, LP_DIS, BL_SAME, LT_DDASH), SGM(GM_LVECT, IN_4, LP_DIS, BL_SAME, LT_DDASH),
/* following coordinates are updated by LP hit intr. handler: */ /* following coordinates are updated by LP hit intr. handler: */
LVECT(I_ON, 0, 0), /* tracking object center */ LVECT(I_ON, 0, 0), /* tracking object center */
SGM(GM_SVECT, IN_7, LP_ENA, BL_SAME, LT_SOLID), SGM(GM_SVECT, IN_7, LP_ENA, BL_SAME, LT_SOLID),
SVECT(I_OFF, 1, -31), SVECT(I_OFF, 0, 30),
SVECT(I_ON, -2, 0), SVECT(I_ON, 0, -60),
SVECT(I_OFF, 2, 0), SVECT(I_OFF, 30, 30),
SVECT(I_ON, 0, 62), SVECT(I_ON, -60, 0),
SVECT(I_ON, -2, 0),
SVECT(I_OFF, 2, 0),
SVECT(I_ON, 30, -30),
SVECT(I_OFF, 0, -2),
SVECT(I_ON, 0, 2),
SVECT(I_ON, -62, 0),
SVECT(I_OFF, 0, -2),
SVECT(I_ON, 0, 2),
SVECT(I_ON, 30, 30), SVECT(I_ON, 30, 30),
SVECT(I_ON, 0, -62), SVECT(I_ON, 30, -30),
SVECT(I_ON, -30, 30),
SVECT(I_ON, 62, 0),
SVECT(I_ON, -30, -30), SVECT(I_ON, -30, -30),
#if 0 /* not needed for this app */ SVECT(I_ON, -30, 30),
SVECT(I_OFF, -1, 31), /* "flyback" vector */ SVECT(I_OFF, 10, 0),
SVECT(I_ON, 20, 20),
SVECT(I_ON, 20, -20),
SVECT(I_ON, -20, -20),
SVECT(I_ON, -20, 20),
SVECT(I_OFF, 10, 0),
SVECT(I_ON, 10, 10),
SVECT(I_ON, 10, -10),
SVECT(I_ON, -10, -10),
SVECT(I_ON, -10, 10),
#if 0 /* not needed for this app */
SVECT(I_OFF, 0, -10), /* "flyback" vector */
#endif #endif
ENDSECT ENDSECT
@ -890,10 +892,10 @@ unsigned short VS[] = {
SGM(GM_CHAR, IN_SAME, LP_SAME, BL_OFF, LT_SAME), SGM(GM_CHAR, IN_SAME, LP_SAME, BL_OFF, LT_SAME),
CHAR('F','o'), CHAR('l','l'), CHAR('o','w'), CHAR('i','n'), CHAR('g',' '), CHAR('F','o'), CHAR('l','l'), CHAR('o','w'), CHAR('i','n'), CHAR('g',' '),
CHAR('t','e'), CHAR('s','t'), CHAR('s',' '), CHAR('d','o'), CHAR('t','e'), CHAR('s','t'), CHAR('s',' '), CHAR('d','o'),
CHAR(' ','n'), CHAR('o','t'), CHAR(' ','w'), CHAR('o','r'), CHAR(' ','n'), CHAR('o','t'), CHAR(' ','w'), CHAR('o','r'),
CHAR('k',' '), CHAR('f','o'), CHAR('r',' '), CHAR('V','T'), CHAR('k',' '), CHAR('f','o'), CHAR('r',' '), CHAR('V','T'),
CHAR('1','1'), CHAR(';',0), CHAR('1','1'), CHAR(';',0),
/* italic text */ /* italic text */
LSRA(ST_SAME, SI_SAME, LI_SAME, IT_ITALIC, RF_UNSYNC, MN_SAME), LSRA(ST_SAME, SI_SAME, LI_SAME, IT_ITALIC, RF_UNSYNC, MN_SAME),
@ -920,20 +922,20 @@ unsigned short VS[] = {
SGM(GM_CHAR, IN_SAME, LP_SAME, BL_SAME, LT_SAME), SGM(GM_CHAR, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
LSRC(RO_SAME, CS_CHANGE, 0, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 0, VS_SAME, 0),
CHAR(' ',' '), CHAR('S','m'), CHAR('a','l'), CHAR('l',':'), CHAR(' ','1'), CHAR(' ',' '), CHAR('S','m'), CHAR('a','l'), CHAR('l',':'), CHAR(' ','1'),
CHAR('/','2'), CHAR('/','2'),
LSRC(RO_SAME, CS_CHANGE, 1, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 1, VS_SAME, 0),
CHAR(' ',' '), CHAR('N','o'), CHAR('r','m'), CHAR('a','l'), CHAR(':',' '), CHAR(' ',' '), CHAR('N','o'), CHAR('r','m'), CHAR('a','l'), CHAR(':',' '),
CHAR('1',0), CHAR('1',0),
LSRC(RO_SAME, CS_CHANGE, 2, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 2, VS_SAME, 0),
CHAR(' ',' '), CHAR('B','i'), CHAR('g',':'), CHAR(' ','1'), CHAR('-','1'), CHAR(' ',' '), CHAR('B','i'), CHAR('g',':'), CHAR(' ','1'), CHAR('-','1'),
CHAR('/','2'), CHAR('/','2'),
LSRC(RO_SAME, CS_CHANGE, 3, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 3, VS_SAME, 0),
CHAR(' ',' '), CHAR('L','a'), CHAR('r','g'), CHAR('e',':'), CHAR(' ','2'), CHAR(' ',' '), CHAR('L','a'), CHAR('r','g'), CHAR('e',':'), CHAR(' ','2'),
CHAR('\r','\n'), CHAR('\r','\n'), CHAR('\r','\n'),
CHAR(' ',' '), CHAR('A',SUBSCR), CHAR('B',SUBSCR), CHAR('C',SUBSCR), CHAR(' ',' '), CHAR('A',SUBSCR), CHAR('B',SUBSCR), CHAR('C',SUBSCR),
CHAR('D',ENDSUB), CHAR(ENDSUB,ENDSUB), CHAR('W',SUPSCR), CHAR('D',ENDSUB), CHAR(ENDSUB,ENDSUB), CHAR('W',SUPSCR),
CHAR('X',SUPSCR), CHAR('Y',SUPSCR), CHAR('Z',ENDSUP), CHAR('X',SUPSCR), CHAR('Y',SUPSCR), CHAR('Z',ENDSUP),
CHAR(ENDSUP,ENDSUP), CHAR('!','!'), CHAR(ENDSUP,ENDSUP), CHAR('!','!'),
/* vertical text, 4 sizes */ /* vertical text, 4 sizes */
SGM(GM_APOINT, IN_SAME, LP_SAME, BL_SAME, LT_SAME), SGM(GM_APOINT, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
@ -942,20 +944,20 @@ unsigned short VS[] = {
SGM(GM_CHAR, IN_SAME, LP_SAME, BL_SAME, LT_SAME), SGM(GM_CHAR, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
LSRC(RO_VERTICAL, CS_CHANGE, 0, VS_SAME, 0), LSRC(RO_VERTICAL, CS_CHANGE, 0, VS_SAME, 0),
CHAR(' ',' '), CHAR('S','m'), CHAR('a','l'), CHAR('l',':'), CHAR(' ','1'), CHAR(' ',' '), CHAR('S','m'), CHAR('a','l'), CHAR('l',':'), CHAR(' ','1'),
CHAR('/','2'), CHAR('/','2'),
LSRC(RO_SAME, CS_CHANGE, 1, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 1, VS_SAME, 0),
CHAR(' ',' '), CHAR('N','o'), CHAR('r','m'), CHAR('a','l'), CHAR(':',' '), CHAR(' ',' '), CHAR('N','o'), CHAR('r','m'), CHAR('a','l'), CHAR(':',' '),
CHAR('1',0), CHAR('1',0),
LSRC(RO_SAME, CS_CHANGE, 2, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 2, VS_SAME, 0),
CHAR(' ',' '), CHAR('B','i'), CHAR('g',':'), CHAR(' ','1'), CHAR('-','1'), CHAR(' ',' '), CHAR('B','i'), CHAR('g',':'), CHAR(' ','1'), CHAR('-','1'),
CHAR('/','2'), CHAR('/','2'),
LSRC(RO_SAME, CS_CHANGE, 3, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 3, VS_SAME, 0),
CHAR(' ',' '), CHAR('L','a'), CHAR('r','g'), CHAR('e',':'), CHAR(' ','2'), CHAR(' ',' '), CHAR('L','a'), CHAR('r','g'), CHAR('e',':'), CHAR(' ','2'),
CHAR('\r','\n'), CHAR('\r','\n'), CHAR('\r','\n'),
CHAR(' ',' '), CHAR('A',SUBSCR), CHAR('B',SUBSCR), CHAR('C',SUBSCR), CHAR(' ',' '), CHAR('A',SUBSCR), CHAR('B',SUBSCR), CHAR('C',SUBSCR),
CHAR('D',ENDSUB), CHAR(ENDSUB,ENDSUB), CHAR('W',SUPSCR), CHAR('D',ENDSUB), CHAR(ENDSUB,ENDSUB), CHAR('W',SUPSCR),
CHAR('X',SUPSCR), CHAR('Y',SUPSCR), CHAR('Z',ENDSUP), CHAR('X',SUPSCR), CHAR('Y',SUPSCR), CHAR('Z',ENDSUP),
CHAR(ENDSUP,ENDSUP), CHAR('!','!'), CHAR(ENDSUP,ENDSUP), CHAR('!','!'),
/* horizontal text, sub/superscript examples from DECgraphic-11 manual */ /* horizontal text, sub/superscript examples from DECgraphic-11 manual */
SGM(GM_APOINT, IN_SAME, LP_SAME, BL_SAME, LT_SAME), SGM(GM_APOINT, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
@ -964,11 +966,11 @@ unsigned short VS[] = {
LSRC(RO_HORIZONTAL, CS_CHANGE, 2, VS_SAME, 0), LSRC(RO_HORIZONTAL, CS_CHANGE, 2, VS_SAME, 0),
SGM(GM_CHAR, IN_SAME, LP_SAME, BL_SAME, LT_SAME), SGM(GM_CHAR, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
CHAR('C',SUBSCR), CHAR('2',ENDSUB), CHAR('H',SUBSCR), CHAR('5',ENDSUB), CHAR('C',SUBSCR), CHAR('2',ENDSUB), CHAR('H',SUBSCR), CHAR('5',ENDSUB),
CHAR('O','H'), CHAR(' ',' '), CHAR('O','H'), CHAR(' ',' '),
CHAR(016,000), CHAR(017,'='), CHAR(016,003), CHAR(017,'('), CHAR(016,000), CHAR(017,'='), CHAR(016,003), CHAR(017,'('),
CHAR('x',SUBSCR), CHAR('i',ENDSUB), CHAR('-','q'), CHAR(SUBSCR,'i'), CHAR('x',SUBSCR), CHAR('i',ENDSUB), CHAR('-','q'), CHAR(SUBSCR,'i'),
CHAR(ENDSUB,')'), CHAR(SUPSCR,'2'), CHAR(ENDSUP,'e'), CHAR(SUPSCR,'-'), CHAR(ENDSUB,')'), CHAR(SUPSCR,'2'), CHAR(ENDSUP,'e'), CHAR(SUPSCR,'-'),
CHAR('i',SUPSCR), CHAR('2',ENDSUP), CHAR(ENDSUP,0), CHAR('i',SUPSCR), CHAR('2',ENDSUP), CHAR(ENDSUP,0),
LSRC(RO_SAME, CS_CHANGE, 1, VS_SAME, 0), LSRC(RO_SAME, CS_CHANGE, 1, VS_SAME, 0),
LSRA(ST_SAME, SI_SAME, LI_SAME, IT_SAME, RF_SAME, MN_MENU), LSRA(ST_SAME, SI_SAME, LI_SAME, IT_SAME, RF_SAME, MN_MENU),
@ -1018,7 +1020,7 @@ unsigned short VS[] = {
/* SECTION 3. 3D data, but depth cueing disabled. */ /* SECTION 3. 3D data, but depth cueing disabled. */
LSRBB(ZD_YES, ED_ENA, DQ_OFF, ES_YES), /* but term char not used */ LSRBB(ZD_YES, ED_ENA, DQ_OFF, ES_YES), /* but term char not used */
LSRA(ST_SAME, SI_SAME, LI_BRIGHTDOWN, IT_SAME, RF_30, MN_MAIN), LSRA(ST_SAME, SI_SAME, LI_BRIGHTDOWN, IT_SAME, RF_30, MN_MAIN),
SGM(GM_APOINT, IN_4, LP_ENA, BL_OFF, LT_LDASH), SGM(GM_APOINT, IN_4, LP_ENA, BL_OFF, LT_LDASH),
@ -1053,7 +1055,7 @@ unsigned short VS[] = {
/* SECTION 4. 3D data, with depth cueing enabled. */ /* SECTION 4. 3D data, with depth cueing enabled. */
LSRBB(ZD_YES, ED_ENA, DQ_ON, ES_YES), /* but term char not used */ LSRBB(ZD_YES, ED_ENA, DQ_ON, ES_YES), /* but term char not used */
LSRA(ST_SAME, SI_SAME, LI_BRIGHTDOWN, IT_SAME, RF_EXT, MN_MAIN), LSRA(ST_SAME, SI_SAME, LI_BRIGHTDOWN, IT_SAME, RF_EXT, MN_MAIN),
SGM(GM_APOINT, IN_4, LP_ENA, BL_OFF, LT_DDASH), SGM(GM_APOINT, IN_4, LP_ENA, BL_OFF, LT_DDASH),
@ -1137,16 +1139,150 @@ unsigned short VS[] = {
/* SECTION 7. Offset, vector scale, and clipping. */ /* SECTION 7. Offset, vector scale, and clipping. */
/* XXX need test for offset, vector scale, and clipping */ LSRA(ST_SAME, SI_SAME, LI_BRIGHTDOWN, IT_NORMAL, RF_UNSYNC, MN_MAIN),
LSRC(RO_HORIZONTAL, CS_CHANGE, 1, VS_CHANGE, 4),
SGM(GM_APOINT, IN_3, LP_ENA, BL_OFF, LT_SOLID),
OFFSET(0, 0),
APOINT(I_ON, 01040, 01040),
APOINT(I_ON, 01040, 0740),
APOINT(I_ON, 0740, 01040),
APOINT(I_ON, 0740, 0740),
SGM(GM_APOINT, IN_5, LP_SAME, BL_ON, LT_SAME),
OFFSET(06, 010),
APOINT(I_ON, 01040, 01040),
APOINT(I_ON, 01040, 0740),
APOINT(I_ON, 0740, 01040),
APOINT(I_ON, 0740, 0740),
OFFSET(014, 020),
LSRC(RO_HORIZONTAL, CS_SAME, 0, VS_CHANGE, 8),
SGM(GM_APOINT, IN_7, LP_ENA, BL_SAME, LT_SAME),
APOINT(I_ON, 0420, 0420),
SGM(GM_RPOINT, IN_7, LP_SAME, BL_SAME, LT_SAME),
RPOINT(I_ON, 0, -040),
RPOINT(I_ON, -040, 040),
RPOINT(I_ON, 0, -040),
/* XXX need test for clipping */
ENDSECT
/* END OF TEST SECTIONS. */ /* END OF TEST SECTIONS. */
ENDFILE ENDFILE
}; };
static unsigned short *df; /* -> start of current display file */ /* FILE WF. Rotating wire-frame display that works only for VS60. */
static uint16 start; /* initial DPC for section of d.file */
static int more; /* set until end of d.file seen */ unsigned short WF[] = {
/* SECTION 1. 3D data, with depth cueing enabled. */
LSRBB(ZD_YES, ED_ENA, DQ_ON, ES_NO),
LSRA(ST_SAME, SI_SAME, LI_BRIGHTDOWN, IT_SAME, RF_40, MN_MAIN),
SGM(GM_APOINT, IN_4, LP_ENA, BL_OFF, LT_DDASH),
APOINT3(I_OFF, 0, 0, 0), /* cube coords filled in by wf_update() */
SGM(GM_AVECT, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_OFF, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
SGM(GM_AVECT, IN_SAME, LP_SAME, BL_SAME, LT_SOLID),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_OFF, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_OFF, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
AVECT3(I_OFF, 0, 0, 0),
AVECT3(I_ON, 0, 0, 0),
LSRA(ST_SAME, SI_SAME, LI_SAME, IT_SAME, RF_SAME, MN_MENU),
SGM(GM_APOINT, IN_7, LP_ENA, BL_OFF, LT_SAME),
APOINT3(I_OFF, 0, 1000, 0200),
SGM(GM_CHAR, IN_SAME, LP_SAME, BL_SAME, LT_SAME),
CHAR('4','0'), CHAR('H','z'), CHAR(' ','S'), CHAR('y','n'), CHAR('c',0),
ENDSECT
/* END OF TEST SECTIONS. */
ENDFILE
};
static unsigned short *df; /* -> start of current display file */
static uint16 start; /* initial DPC for section of d.file */
static int more; /* set until end of d.file seen */
static void
wf_update(int first_time) {
double c, s; /* cosine, sine of rotation angle */
int x, y, z; /* rotated coordinates */
static int xc = 01000, yc = 01000, zc = 0; /* cube center coords */
static int vp = 010000; /* distance to vanishing point */
static struct {
int offset; /* WF[] offset (words) of vector data */
int i; /* I_ON or I_OFF */
int x, y, z; /* coords of cube corner point */
} *dp, data[] = {
3, I_OFF, 00400, 00400, 0400,
7, I_ON, 01400, 00400, 0400,
10, I_ON, 01400, 01400, 0400,
13, I_ON, 00400, 01400, 0400,
16, I_ON, 00400, 00400, 0400,
19, I_OFF, 00400, 00400, -0400,
22, I_ON, 01400, 00400, -0400,
25, I_ON, 01400, 01400, -0400,
28, I_ON, 00400, 01400, -0400,
31, I_ON, 00400, 00400, -0400,
35, I_ON, 00400, 00400, 0400,
38, I_OFF, 01400, 00400, 0400,
41, I_ON, 01400, 00400, -0400,
44, I_OFF, 01400, 01400, -0400,
47, I_ON, 01400, 01400, 0400,
50, I_OFF, 00400, 01400, 0400,
53, I_ON, 00400, 01400, -0400,
-1 /* end-of-data marker */
};
static double rot = 0.0; /* total amount of rotation, degrees */
if (first_time) {
/* tilt cube toward viewer */
c = cos(30.0 * 3.14159/180.0);
s = sin(30.0 * 3.14159/180.0);
for (dp = data; dp->offset >= 0; ++dp) {
z = zc + ((dp->z - zc) * c + (dp->y - yc) * s);
y = yc + ((dp->y - yc) * c - (dp->z - zc) * s);
WF[dp->offset ] = dp->i | (SGN_(dp->x) << 13) | MAG_(dp->x);
WF[dp->offset + 1] = (SGN_(y) << 13) | MAG_(y);
WF[dp->offset + 2] = (SGN_(z) << 13) | (MAG_(z) << 2);
/* X coord. unchanged because rotation is parallel to X axis */
dp->y = y;
dp->z = z;
}
} else
if ((rot += 1.0) >= 360.0) /* rotation increment */
rot -= 360.0;
c = cos(rot * 3.14159/180.0);
s = sin(rot * 3.14159/180.0);
for (dp = data; dp->offset >= 0; ++dp) {
x = xc + ((dp->x - xc) * c + (dp->z - zc) * s);
z = zc + ((dp->z - zc) * c - (dp->x - xc) * s);
/* apply (approximate) perspective */
x = x * (1.0 + (double)z / vp );
y = dp->y * (1.0 + (double)z / vp );
WF[dp->offset ] = dp->i | (SGN_(x) << 13) | MAG_(x);
WF[dp->offset + 1] = (SGN_(y) << 13) | MAG_(y);
WF[dp->offset + 2] = (SGN_(z) << 13) | (MAG_(z) << 2);
}
}
int int
main(void) { main(void) {
@ -1159,17 +1295,17 @@ main(void) {
puts("initial tests work for both VT11 and VS60"); puts("initial tests work for both VT11 and VS60");
for (df = VT, start = 0, more = 1; more; ) { for (df = VT, start = 0, more = 1; more; ) {
vt11_reset(); /* reset everything */ vt11_reset(); /* reset everything */
vt11_set_dpc(start); /* start section */ vt11_set_dpc(start); /* start section */
c = 0; c = 0;
while (vt11_cycle(USEC, 1)) { while (vt11_cycle(USEC, 1)) {
display_sync(); /* XXX push down? */ display_sync(); /* XXX push down? */
if (display_lp_sw) /* tip switch activated */ if (display_lp_sw) /* tip switch activated */
c = 1; /* flag: break requested */ c = 1; /* flag: break requested */
if (c && !display_lp_sw) /* wait for switch release */ if (c && !display_lp_sw) /* wait for switch release */
break; break;
} }
/* end of section */ /* end of section */
} }
/* end of display file */ /* end of display file */
@ -1179,40 +1315,60 @@ main(void) {
puts("move the light pen through the tracking object"); puts("move the light pen through the tracking object");
fflush(stdout); fflush(stdout);
for (df = LP, start = 0, more = 1; more; ) { for (df = LP, start = 0, more = 1; more; ) {
vt11_reset(); /* reset everything */ vt11_reset(); /* reset everything */
vt11_set_dpc(start); /* start section */ vt11_set_dpc(start); /* start section */
c = 0; c = 0;
while (vt11_cycle(USEC, 1)) { while (vt11_cycle(USEC, 1)) {
display_sync(); /* XXX push down? */ display_sync(); /* XXX push down? */
if (display_lp_sw) /* tip switch activated */ if (display_lp_sw) /* tip switch activated */
c = 1; /* flag: break requested */ c = 1; /* flag: break requested */
if (c && !display_lp_sw) /* wait for switch release */ if (c && !display_lp_sw) /* wait for switch release */
break; break;
/* [dynamic modifications to the display file can be done here] */ /* [dynamic modifications to the display file can be done here] */
} }
/* end of section */ /* end of section */
} }
/* end of display file */ /* end of display file */
/* VS60 tests */ /* VS60 tests */
ws_beep(); ws_beep();
puts("following tests require VS60"); puts("following tests require VS60");
for (df = VS, start = 0, more = 1; more; ) { for (df = VS, start = 0, more = 1; more; ) {
vt11_reset(); /* reset everything */ vt11_reset(); /* reset everything */
vt11_set_str((uint16)(0200 | '~')); /* set terminating char. */ vt11_set_str((uint16)(0200 | '~')); /* set terminating char. */
vt11_set_anr((uint16)(040000 | (2<<12) | 04000 | 01234)); vt11_set_anr((uint16)(040000 | (2<<12) | 04000 | 01234));
/* set associative name 0123x */ /* set associative name 0123x */
vt11_set_dpc(start); /* start section */ vt11_set_dpc(start); /* start section */
c = 0; c = 0;
while (vt11_cycle(USEC, 1)) { while (vt11_cycle(USEC, 1)) {
display_sync(); /* XXX push down? */ display_sync(); /* XXX push down? */
if (display_lp_sw) /* tip switch activated */ if (display_lp_sw) /* tip switch activated */
c = 1; /* flag: break requested */ c = 1; /* flag: break requested */
if (c && !display_lp_sw) /* wait for switch release */ if (c && !display_lp_sw) /* wait for switch release */
break; break;
} }
/* end of section */ /* end of section */
}
/* end of display file */
/* VS60 rotating wire-frame display */
puts("press and release tip switch (button 1) for next display");
fflush(stdout);
wf_update(1); /* do first-time init */
for (df = WF, start = 0, more = 1; more; ) {
vt11_reset(); /* reset everything */
vt11_set_dpc(start); /* start section */
c = 0;
while (vt11_cycle(USEC, 1)) {
display_sync(); /* XXX push down? */
if (display_lp_sw) /* tip switch activated */
c = 1; /* flag: break requested */
if (c && !display_lp_sw) /* wait for switch release */
break;
}
/* end of section */
} }
/* end of display file */ /* end of display file */
@ -1245,57 +1401,65 @@ vt_fetch(uint32 addr, vt11word *w) {
void void
vt_stop_intr(void) { vt_stop_intr(void) {
uint16 dpc = vt11_get_dpc(); /* -> just after DSTOP instruction */ uint16 dpc = vt11_get_dpc(); /* -> just after DSTOP instruction */
if (df[dpc/2] == 0) { /* ENDSECT */ if (df[dpc/2] == 0) { /* ENDSECT */
#ifdef FRAME1STOP #ifdef FRAME1STOP
int c; int c;
puts("end of first pass through this test pattern; display frozen"); puts("end of pass through this test pattern; display frozen");
puts("enter newline to refresh this section or EOF to quit"); puts("enter newline to refresh this section or EOF to quit");
fflush(stdout); fflush(stdout);
while ((c = getchar()) != '\n') while ((c = getchar()) != '\n')
if (c == EOF) if (c == EOF)
exit(0); /* user aborted test */ exit(0); /* user aborted test */
#endif #endif
df[dpc/2 - 1] = JMPA; if (df == WF) {
df[dpc/2] = start; wf_update(0);
start = dpc + 2; /* save start of next section */ vt11_set_dpc(0); /* restart modified display */
vt11_set_dpc(dpc - 2); /* reset; then JMPA to old start */ start = dpc + 2; /* save start of next section */
puts("press and release tip switch (mouse button 1) for next display"); } else {
fflush(stdout); df[dpc/2 - 1] = JMPA;
} else /* ENDFILE */ df[dpc/2] = start;
more = 0; start = dpc + 2; /* save start of next section */
vt11_set_dpc(dpc - 2); /* reset; then JMPA to old start */
puts("press and release tip switch (button 1) for next display");
fflush(stdout);
}
} else /* ENDFILE */
more = 0;
} }
void void
vt_lpen_intr(void) { vt_lpen_intr(void) {
if (df == LP) { if (df == LP) {
int dx = (int)(vt11_get_xpr() & 01777) - 01000; int dx = (int)(vt11_get_xpr() & 01777) - 01000;
int dy = (int)(vt11_get_ypr() & 01777) - 01000; int dy = (int)(vt11_get_ypr() & 01777) - 01000;
if (dx < 0) if (dx < 0)
dx = (-dx) | 020000; /* negative */ dx = (-dx) | 020000; /* negative */
if (dy < 0) if (dy < 0)
dy = (-dy) | 020000; /* negative */ dy = (-dy) | 020000; /* negative */
df[4] = dx | I_ON; /* visible */ df[4] = dx | I_ON; /* visible */
df[5] = dy; df[5] = dy;
} else { } else {
printf("VT11 lightpen interrupt (%d,%d)\n", printf("VT11 lightpen interrupt (0%o,0%o)\n",
(int)vt11_get_xpr() & 01777, (int)vt11_get_ypr() & 01777); (unsigned)vt11_get_xpr() & 01777,
fflush(stdout); (unsigned)vt11_get_ypr() & 01777);
fflush(stdout);
} }
vt11_set_dpc((uint16)1); /* resume */ vt11_set_dpc((uint16)1); /* resume */
} }
void void
vt_char_intr(void) { vt_char_intr(void) {
puts("VT11 illegal character/timeout interrupt"); puts("VT11 illegal character/timeout interrupt");
fflush(stdout); fflush(stdout);
vt11_set_dpc((uint16)1); /* resume */ vt11_set_dpc((uint16)1); /* resume */
} }
void void
vt_name_intr(void) { vt_name_intr(void) {
puts("VS60 name-match interrupt"); puts("VS60 name-match interrupt");
fflush(stdout); fflush(stdout);
vt11_set_dpc((uint16)1); /* resume */ vt11_set_dpc((uint16)1); /* resume */
} }

View file

@ -1,5 +1,5 @@
/* /*
* $Id: win32.c,v 1.38 2004/02/07 06:32:01 phil Exp $ * $Id: win32.c,v 1.39 2005/01/14 18:58:03 phil Exp $
* Win32 support for XY display simulator * Win32 support for XY display simulator
* Phil Budne <phil@ultimate.com> * Phil Budne <phil@ultimate.com>
* September 2003 * September 2003
@ -47,14 +47,14 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "ws.h" #include "ws.h"
#include "display.h" #include "xy.h"
#ifndef PIX_SIZE #ifndef PIX_SIZE
#define PIX_SIZE 1 #define PIX_SIZE 1
#endif #endif
#define APP_CLASS "XYAppClass" #define APP_CLASS "XYAppClass"
#define APP_MENU "XYAppMenu" /* ?? */ #define APP_MENU "XYAppMenu" /* ?? */
/* /*
* light pen location * light pen location
@ -77,8 +77,8 @@ static __inline int
map_key(int k) map_key(int k)
{ {
switch (k) { switch (k) {
case 186: return ';'; /* VK_OEM_1? */ case 186: return ';'; /* VK_OEM_1? */
case 222: return '\''; /* VK_OEM_7? */ case 222: return '\''; /* VK_OEM_7? */
} }
return k; return k;
} }
@ -115,9 +115,9 @@ mousepos(DWORD lp)
/* if window has been stretched, can get out of range bits!! */ /* if window has been stretched, can get out of range bits!! */
if (x >= 0 && x < xpixels && y >= 0 && y < ypixels) { if (x >= 0 && x < xpixels && y >= 0 && y < ypixels) {
/* checked by display_add_point() */ /* checked by display_add_point() */
ws_lp_x = x; ws_lp_x = x;
ws_lp_y = y; ws_lp_y = y;
} }
} }
@ -128,56 +128,56 @@ patsy(HWND wh, UINT msg, WPARAM wp, LPARAM lp) /* "WndProc" */
/* printf("msg %d\n", msg); */ /* printf("msg %d\n", msg); */
switch (msg) { switch (msg) {
case WM_DESTROY: case WM_DESTROY:
PostQuitMessage(0); PostQuitMessage(0);
return 0; return 0;
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
if (wp & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) { if (wp & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) {
#ifdef SWITCH_CURSORS #ifdef SWITCH_CURSORS
if (ws_lp_x == -1 && !display_tablet) if (ws_lp_x == -1 && !display_tablet)
SetCursor(cross); SetCursor(cross);
#endif #endif
mousepos(lp); mousepos(lp);
} }
#ifdef SWITCH_CURSORS #ifdef SWITCH_CURSORS
else if (ws_lp_x != -1 && !display_tablet) else if (ws_lp_x != -1 && !display_tablet)
SetCursor(arrow); SetCursor(arrow);
#endif #endif
break; /* return?? */ break; /* return?? */
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
display_lp_sw = 1; display_lp_sw = 1;
case WM_MBUTTONDOWN: case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN: case WM_RBUTTONDOWN:
#ifdef SWITCH_CURSORS #ifdef SWITCH_CURSORS
if (!display_tablet) if (!display_tablet)
SetCursor(cross); SetCursor(cross);
#endif #endif
mousepos(lp); mousepos(lp);
break; /* return?? */ break; /* return?? */
case WM_LBUTTONUP: case WM_LBUTTONUP:
display_lp_sw = 0; display_lp_sw = 0;
case WM_MBUTTONUP: case WM_MBUTTONUP:
case WM_RBUTTONUP: case WM_RBUTTONUP:
#ifdef SWITCH_CURSORS #ifdef SWITCH_CURSORS
if (!display_tablet) if (!display_tablet)
SetCursor(arrow); SetCursor(arrow);
#endif #endif
ws_lp_x = ws_lp_y = -1; ws_lp_x = ws_lp_y = -1;
break; /* return?? */ break; /* return?? */
case WM_KEYDOWN: case WM_KEYDOWN:
keydown(wp); keydown(wp);
break; break;
case WM_KEYUP: case WM_KEYUP:
keyup(wp); keyup(wp);
break; break;
case WM_PAINT: case WM_PAINT:
display_repaint(); display_repaint();
break; /* return?? */ break; /* return?? */
} }
return DefWindowProc(wh, msg, wp, lp); return DefWindowProc(wh, msg, wp, lp);
} }
@ -188,18 +188,18 @@ ws_poll(int *valp, int maxus)
#ifdef THREADS #ifdef THREADS
/* msgthread handles window events; just delay simulator */ /* msgthread handles window events; just delay simulator */
if (maxus > 0) if (maxus > 0)
Sleep((maxus+999)/1000); Sleep((maxus+999)/1000);
#else #else
MSG msg; MSG msg;
DWORD start; DWORD start;
int maxms = (maxus + 999) / 1000; int maxms = (maxus + 999) / 1000;
for (start = GetTickCount(); GetTickCount() - start < maxms; Sleep(1)) { for (start = GetTickCount(); GetTickCount() - start < maxms; Sleep(1)) {
/* empty message queue without blocking */ /* empty message queue without blocking */
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
} }
#endif #endif
return 1; return 1;
@ -211,7 +211,7 @@ ws_loop(void (*func)(void *), void *arg)
{ {
int val; int val;
while (ws_poll(&val, 0)) while (ws_poll(&val, 0))
(*func)(arg); (*func)(arg);
return val; return val;
} }
@ -223,37 +223,37 @@ ws_init2(void) {
#ifdef SWITCH_CURSORS #ifdef SWITCH_CURSORS
if (!display_tablet) { if (!display_tablet) {
arrow = LoadCursor(NULL, IDC_ARROW); arrow = LoadCursor(NULL, IDC_ARROW);
cross = LoadCursor(NULL, IDC_CROSS); cross = LoadCursor(NULL, IDC_CROSS);
} }
#endif #endif
black_brush = GetStockObject(BLACK_BRUSH); black_brush = GetStockObject(BLACK_BRUSH);
white_brush = GetStockObject(WHITE_BRUSH); white_brush = GetStockObject(WHITE_BRUSH);
wc.lpszClassName = APP_CLASS; wc.lpszClassName = APP_CLASS;
wc.lpfnWndProc = patsy; wc.lpfnWndProc = patsy;
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
/* also CS_NOCLOSE? CS_SAVEBITS? */ /* also CS_NOCLOSE? CS_SAVEBITS? */
wc.hInstance = static_inst = GetModuleHandleA(0); wc.hInstance = static_inst = GetModuleHandleA(0);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
#ifdef SWITCH_CURSORS #ifdef SWITCH_CURSORS
wc.hCursor = NULL; wc.hCursor = NULL;
#else #else
wc.hCursor = display_tablet ? NULL : LoadCursor(NULL, IDC_CROSS); wc.hCursor = display_tablet ? NULL : LoadCursor(NULL, IDC_CROSS);
#endif #endif
wc.hbrBackground = black_brush; wc.hbrBackground = black_brush;
wc.lpszMenuName = APP_MENU; wc.lpszMenuName = APP_MENU;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
wc.cbWndExtra = 0; wc.cbWndExtra = 0;
/* WNDCLASSEX/RegisterClassEx include hIconSm (small icon) */ /* WNDCLASSEX/RegisterClassEx include hIconSm (small icon) */
RegisterClass(&wc); RegisterClass(&wc);
/* /*
* WS_OVERLAPPEDWINDOW=> * WS_OVERLAPPEDWINDOW=>
* WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, * WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME,
* WS_MINIMIZEBOX, WS_MAXIMIZEBOX * WS_MINIMIZEBOX, WS_MAXIMIZEBOX
* *
* WS_CHILD (no menu bar), WS_POPUP (mutually exclusive) * WS_CHILD (no menu bar), WS_POPUP (mutually exclusive)
*/ */
@ -263,15 +263,15 @@ ws_init2(void) {
h = (ypixels*PIX_SIZE)+32; h = (ypixels*PIX_SIZE)+32;
/* XXX -- above values work with XP; Phil had +10,+30 */ /* XXX -- above values work with XP; Phil had +10,+30 */
static_wh = CreateWindow(APP_CLASS, /* registered class name */ static_wh = CreateWindow(APP_CLASS, /* registered class name */
window_name, /* window name */ window_name, /* window name */
WS_OVERLAPPED, /* style */ WS_OVERLAPPED, /* style */
CW_USEDEFAULT, CW_USEDEFAULT, /* X,Y */ CW_USEDEFAULT, CW_USEDEFAULT, /* X,Y */
w, h, w, h,
NULL, /* HWND hWndParent */ NULL, /* HWND hWndParent */
NULL, /* HMENU hMenu */ NULL, /* HMENU hMenu */
static_inst, /* application instance */ static_inst, /* application instance */
NULL); /* lpParam */ NULL); /* lpParam */
ShowWindow(static_wh, SW_SHOW); ShowWindow(static_wh, SW_SHOW);
UpdateWindow(static_wh); UpdateWindow(static_wh);
@ -292,8 +292,8 @@ msgthread(LPVOID arg)
init_done = 1; init_done = 1;
while (GetMessage(&msg, NULL, 0, 0) > 0) { while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
return msg.wParam; return msg.wParam;
} }
@ -301,17 +301,17 @@ msgthread(LPVOID arg)
static void static void
ws_thread_init(void) ws_thread_init(void)
{ {
HANDLE th = CreateThread(NULL, /* sec. attr. */ HANDLE th = CreateThread(NULL, /* sec. attr. */
0, /* stack size */ 0, /* stack size */
msgthread, msgthread,
NULL, /* param */ NULL, /* param */
0, /* flags */ 0, /* flags */
&msgthread_id); &msgthread_id);
CloseHandle(th); CloseHandle(th);
/* XXX use a mutex; don't wait forever!! */ /* XXX use a mutex; don't wait forever!! */
while (!init_done) while (!init_done)
; Sleep(200);
} }
#endif /* THREADS */ #endif /* THREADS */
@ -328,7 +328,7 @@ ws_init(char *name, int xp, int yp, int colors)
#else #else
ws_init2(); ws_init2();
#endif #endif
return 1; /* XXX return errors!! */ return 1; /* XXX return errors!! */
} }
void * void *
@ -358,9 +358,9 @@ ws_display_point(int x, int y, void *color)
HBRUSH brush = color; HBRUSH brush = color;
if (x > xpixels || y > ypixels) if (x > xpixels || y > ypixels)
return; return;
y = ypixels - 1 - y; /* invert y, top left origin */ y = ypixels - 1 - y; /* invert y, top left origin */
/* top left corner */ /* top left corner */
r.left = x*PIX_SIZE; r.left = x*PIX_SIZE;
@ -371,7 +371,7 @@ ws_display_point(int x, int y, void *color)
r.bottom = (y+1)*PIX_SIZE; r.bottom = (y+1)*PIX_SIZE;
if (brush == NULL) if (brush == NULL)
brush = black_brush; brush = black_brush;
dc = GetDC(static_wh); dc = GetDC(static_wh);
FillRect(dc, &r, brush); FillRect(dc, &r, brush);
@ -390,7 +390,7 @@ ws_beep(void) {
MessageBeep(MB_OK); MessageBeep(MB_OK);
#else #else
/* works over terminal service? Plays default sound/beep on Win9x/ME */ /* works over terminal service? Plays default sound/beep on Win9x/ME */
Beep(440, 500); /* Hz, ms. */ Beep(440, 500); /* Hz, ms. */
#endif #endif
} }
@ -410,9 +410,9 @@ os_elapsed(void)
*/ */
t[new] = GetTickCount(); t[new] = GetTickCount();
if (t[!new] == 0) if (t[!new] == 0)
ret = ~0L; /* +INF */ ret = ~0L; /* +INF */
else else
ret = (t[new] - t[!new]) * 1000; ret = (t[new] - t[!new]) * 1000;
new = !new; /* Ecclesiastes III */ new = !new; /* Ecclesiastes III */
return ret; return ret;
} }

View file

@ -32,7 +32,6 @@
/* unless you're writing a new driver, you shouldn't be looking here! */ /* unless you're writing a new driver, you shouldn't be looking here! */
extern int ws_init(char *, int, int, int); extern int ws_init(char *, int, int, int);
extern void ws_close(void); // 2006-07-19 SAI
extern void *ws_color_rgb(int, int, int); extern void *ws_color_rgb(int, int, int);
extern void *ws_color_black(void); extern void *ws_color_black(void);
extern void *ws_color_white(void); extern void *ws_color_white(void);

View file

@ -1,5 +1,5 @@
/* /*
* $Id: x11.c,v 1.29 2004/02/03 21:23:51 phil Exp $ * $Id: x11.c,v 1.32 2005/01/14 18:58:03 phil Exp $
* X11 support for XY display simulator * X11 support for XY display simulator
* Phil Budne <phil@ultimate.com> * Phil Budne <phil@ultimate.com>
* September 2003 * September 2003
@ -7,9 +7,9 @@
* Changes from Douglas A. Gwyn, Jan 8, 2004 * Changes from Douglas A. Gwyn, Jan 8, 2004
* *
* started from PDP-8/E simulator (vc8e.c & kc8e.c); * started from PDP-8/E simulator (vc8e.c & kc8e.c);
* This PDP8 Emulator was written by Douglas W. Jones at the * This PDP8 Emulator was written by Douglas W. Jones at the
* University of Iowa. It is distributed as freeware, of * University of Iowa. It is distributed as freeware, of
* uncertain function and uncertain utility. * uncertain function and uncertain utility.
*/ */
/* /*
@ -42,7 +42,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "ws.h" #include "ws.h"
#include "display.h" #include "xy.h"
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -59,10 +59,6 @@
#define PIX_SIZE 1 #define PIX_SIZE 1
#endif #endif
//#define FULL_SCREEN 1
#define NO_CURSOR 1
#define NO_BORDER 1
/* /*
* light pen location * light pen location
* see ws.h for full description * see ws.h for full description
@ -84,9 +80,9 @@ static int xoffset, yoffset;
static GC whiteGC; /* gc with white foreground */ static GC whiteGC; /* gc with white foreground */
static GC blackGC; /* gc with black foreground */ static GC blackGC; /* gc with black foreground */
static int buttons = 0; /* tracks state of all buttons */ static int buttons = 0; /* tracks state of all buttons */
static int os_pollfd(int, int); /* forward */ static int os_pollfd(int, int); /* forward */
/* here on any mouse button down, AND movement when any button down */ /* here on any mouse button down, AND movement when any button down */
static void static void
@ -101,6 +97,7 @@ handle_button_press(w, d, e, b)
x = e->xbutton.x; x = e->xbutton.x;
y = e->xbutton.y; y = e->xbutton.y;
#ifdef FULL_SCREEN #ifdef FULL_SCREEN
/* untested! */
x -= xoffset; x -= xoffset;
y -= yoffset; y -= yoffset;
#endif #endif
@ -109,12 +106,10 @@ handle_button_press(w, d, e, b)
y *= PIX_SIZE; y *= PIX_SIZE;
#endif #endif
#ifndef NO_CURSUR
if (!display_tablet) if (!display_tablet)
/* crosshair cursor to indicate tip of active pen */ /* crosshair cursor to indicate tip of active pen */
XDefineCursor(dpy, XtWindow(crt), XDefineCursor(dpy, XtWindow(crt),
(Cursor) XCreateFontCursor(dpy, XC_crosshair)); (Cursor) XCreateFontCursor(dpy, XC_crosshair));
#endif
y = ypixels - y - 1; y = ypixels - y - 1;
/*printf("lightpen at %d,%d\n", x, y); fflush(stdout);*/ /*printf("lightpen at %d,%d\n", x, y); fflush(stdout);*/
@ -122,16 +117,16 @@ handle_button_press(w, d, e, b)
ws_lp_y = y; ws_lp_y = y;
if (e->type == ButtonPress) { if (e->type == ButtonPress) {
buttons |= e->xbutton.button; buttons |= e->xbutton.button;
if (e->xbutton.button == 1) { if (e->xbutton.button == 1) {
display_lp_sw = 1; display_lp_sw = 1;
/*printf("tip switch activated\n"); fflush(stdout);*/ /*printf("tip switch activated\n"); fflush(stdout);*/
} }
} }
if (b) if (b)
*b = TRUE; *b = TRUE;
} }
static void static void
@ -141,25 +136,23 @@ handle_button_release(w, d, e, b)
XEvent *e; XEvent *e;
Boolean *b; Boolean *b;
{ {
if ((buttons &= ~e->xbutton.button) == 0) { /* all buttons released */ if ((buttons &= ~e->xbutton.button) == 0) { /* all buttons released */
#ifndef NO_CURSOR if (!display_tablet)
if (!display_tablet) /* pencil cursor (close to a pen!) to indicate inactive pen posn */
/* pencil cursor (close to a pen!) to indicate inactive pen posn */ XDefineCursor(dpy, XtWindow(crt),
XDefineCursor(dpy, XtWindow(crt), (Cursor) XCreateFontCursor(dpy, XC_pencil));
(Cursor) XCreateFontCursor(dpy, XC_pencil));
#endif
/* XXX change cursor back?? */ /* XXX change cursor back?? */
ws_lp_x = ws_lp_y = -1; ws_lp_x = ws_lp_y = -1;
} }
if (e->xbutton.button == 1) { if (e->xbutton.button == 1) {
display_lp_sw = 0; display_lp_sw = 0;
/*printf("tip switch deactivated\n"); fflush(stdout);*/ /*printf("tip switch deactivated\n"); fflush(stdout);*/
} }
if (b) if (b)
*b = TRUE; *b = TRUE;
} }
static void static void
@ -174,10 +167,10 @@ handle_key_press(w, d, e, b)
/*printf("key %d down\n", key); fflush(stdout);*/ /*printf("key %d down\n", key); fflush(stdout);*/
if ((key & 0xff00) == 0) if ((key & 0xff00) == 0)
display_keydown(key); display_keydown(key);
if (b) if (b)
*b = TRUE; *b = TRUE;
} }
static void static void
@ -192,10 +185,10 @@ handle_key_release(w, d, e, b)
/*printf("key %d up\n", key); fflush(stdout);*/ /*printf("key %d up\n", key); fflush(stdout);*/
if ((key & 0xff00) == 0) if ((key & 0xff00) == 0)
display_keyup(key); display_keyup(key);
if (b) if (b)
*b = TRUE; *b = TRUE;
} }
static void static void
@ -208,13 +201,13 @@ handle_exposure(w, d, e, b)
display_repaint(); display_repaint();
if (b) if (b)
*b = TRUE; *b = TRUE;
} }
int int
ws_init(char *crtname, /* crt type name */ ws_init(char *crtname, /* crt type name */
int xp, int yp, /* screen size in pixels */ int xp, int yp, /* screen size in pixels */
int colors) /* colors to support (not used) */ int colors) /* colors to support (not used) */
{ {
Arg arg[25]; Arg arg[25];
XGCValues gcvalues; XGCValues gcvalues;
@ -223,7 +216,7 @@ ws_init(char *crtname, /* crt type name */
char *argv[1]; char *argv[1];
int height, width; int height, width;
xpixels = xp; /* save screen size */ xpixels = xp; /* save screen size */
ypixels = yp; ypixels = yp;
XtToolkitInitialize(); XtToolkitInitialize();
@ -231,20 +224,16 @@ ws_init(char *crtname, /* crt type name */
argc = 0; argc = 0;
argv[0] = NULL; argv[0] = NULL;
dpy = XtOpenDisplay( app_context, NULL, NULL, crtname, NULL, 0, dpy = XtOpenDisplay( app_context, NULL, NULL, crtname, NULL, 0,
&argc, argv); &argc, argv);
scr = DefaultScreen(dpy); scr = DefaultScreen(dpy);
crtshell = XtAppCreateShell( crtname, /* app name */ crtshell = XtAppCreateShell( crtname, /* app name */
crtname, /* app class */ crtname, /* app class */
#ifdef NO_BORDER applicationShellWidgetClass, /* wclass */
overrideShellWidgetClass, dpy, /* display */
#else NULL, /* arglist */
applicationShellWidgetClass, /* wclass */ 0); /* nargs */
#endif
dpy, /* display */
NULL, /* arglist */
0); /* nargs */
cmap = DefaultColormap(dpy, scr); cmap = DefaultColormap(dpy, scr);
@ -264,13 +253,14 @@ ws_init(char *crtname, /* crt type name */
width = xpixels*PIX_SIZE; width = xpixels*PIX_SIZE;
height = ypixels*PIX_SIZE; height = ypixels*PIX_SIZE;
#endif #endif
XtSetArg(arg[n], XtNwidth, width); n++; XtSetArg(arg[n], XtNwidth, width); n++;
XtSetArg(arg[n], XtNheight, height); n++; XtSetArg(arg[n], XtNheight, height); n++;
XtSetArg(arg[n], XtNbackground, BlackPixel( dpy, scr )); n++; XtSetArg(arg[n], XtNbackground, BlackPixel( dpy, scr )); n++;
crt = XtCreateWidget( crtname, widgetClass, crtshell, arg, n); crt = XtCreateWidget( crtname, widgetClass, crtshell, arg, n);
XtManageChild(crt); XtManageChild(crt);
XtPopup(crtshell, XtGrabNonexclusive); XtPopup(crtshell, XtGrabNonexclusive);
XtSetKeyboardFocus(crtshell, crt); /* experimental? */
/* /*
* Create black and white Graphics Contexts * Create black and white Graphics Contexts
@ -279,48 +269,35 @@ ws_init(char *crtname, /* crt type name */
gcvalues.foreground = BlackPixel( dpy, scr ); gcvalues.foreground = BlackPixel( dpy, scr );
gcvalues.background = BlackPixel( dpy, scr ); gcvalues.background = BlackPixel( dpy, scr );
blackGC = XCreateGC(dpy, XtWindow(crt), blackGC = XCreateGC(dpy, XtWindow(crt),
GCForeground | GCBackground, &gcvalues); GCForeground | GCBackground, &gcvalues);
gcvalues.foreground = WhitePixel( dpy, scr ); gcvalues.foreground = WhitePixel( dpy, scr );
whiteGC = XCreateGC(dpy, XtWindow(crt), whiteGC = XCreateGC(dpy, XtWindow(crt),
GCForeground | GCBackground, &gcvalues); GCForeground | GCBackground, &gcvalues);
#ifndef NO_CURSOR
if (!display_tablet) { if (!display_tablet) {
/* pencil cursor */ /* pencil cursor */
XDefineCursor(dpy, XtWindow(crt), XDefineCursor(dpy, XtWindow(crt),
(Cursor) XCreateFontCursor(dpy, XC_pencil)); (Cursor) XCreateFontCursor(dpy, XC_pencil));
} }
#endif
/* /*
* Setup to handle events * Setup to handle events
*/ */
XtAddEventHandler(crt, ButtonPressMask|ButtonMotionMask, FALSE, XtAddEventHandler(crt, ButtonPressMask|ButtonMotionMask, FALSE,
handle_button_press, NULL); handle_button_press, NULL);
XtAddEventHandler(crt, ButtonReleaseMask, FALSE, XtAddEventHandler(crt, ButtonReleaseMask, FALSE,
handle_button_release, NULL); handle_button_release, NULL);
XtAddEventHandler(crt, KeyPressMask, FALSE, XtAddEventHandler(crt, KeyPressMask, FALSE,
handle_key_press, NULL); handle_key_press, NULL);
XtAddEventHandler(crt, KeyReleaseMask, FALSE, XtAddEventHandler(crt, KeyReleaseMask, FALSE,
handle_key_release, NULL); handle_key_release, NULL);
XtAddEventHandler(crt, ExposureMask, FALSE, XtAddEventHandler(crt, ExposureMask, FALSE,
handle_exposure, NULL); handle_exposure, NULL);
return 1; return 1;
} /* ws_init */ } /* ws_init */
/* Added 2006-07-19 SAI */
void ws_close(void)
{
XtCloseDisplay(dpy);
}
void * void *
ws_color_black(void) ws_color_black(void)
{ {
@ -344,12 +321,12 @@ ws_color_rgb(int r, int g, int b)
/* ignores flags */ /* ignores flags */
if (XAllocColor(dpy, cmap, &color)) { if (XAllocColor(dpy, cmap, &color)) {
XGCValues gcvalues; XGCValues gcvalues;
memset(&gcvalues, 0, sizeof(gcvalues)); memset(&gcvalues, 0, sizeof(gcvalues));
gcvalues.foreground = gcvalues.background = color.pixel; gcvalues.foreground = gcvalues.background = color.pixel;
return XCreateGC(dpy, XtWindow(crt), return XCreateGC(dpy, XtWindow(crt),
GCForeground | GCBackground, GCForeground | GCBackground,
&gcvalues); &gcvalues);
} }
/* allocation failed */ /* allocation failed */
return NULL; return NULL;
@ -362,21 +339,21 @@ ws_display_point(int x, int y, void *color)
GC gc = (GC) color; GC gc = (GC) color;
if (x > xpixels || y > ypixels) if (x > xpixels || y > ypixels)
return; return;
y = ypixels - y - 1; /* X11 coordinate system */ y = ypixels - y - 1; /* X11 coordinate system */
#ifdef FULL_SCREEN #ifdef FULL_SCREEN
x += xoffset; x += xoffset;
y += yoffset; y += yoffset;
#endif #endif
if (gc == NULL) if (gc == NULL)
gc = blackGC; /* default to off */ gc = blackGC; /* default to off */
#if PIX_SIZE == 1 #if PIX_SIZE == 1
XDrawPoint(dpy, XtWindow(crt), gc, x, y); XDrawPoint(dpy, XtWindow(crt), gc, x, y);
#else #else
XFillRectangle(dpy, XtWindow(crt), gc, XFillRectangle(dpy, XtWindow(crt), gc,
x*PIX_SIZE, y*PIX_SIZE, PIX_SIZE, PIX_SIZE); x*PIX_SIZE, y*PIX_SIZE, PIX_SIZE, PIX_SIZE);
#endif #endif
} }
@ -403,10 +380,10 @@ elapsed(struct elapsed_state *ep)
gettimeofday(&ep->tvs[ep->new], NULL); gettimeofday(&ep->tvs[ep->new], NULL);
if (ep->tvs[!ep->new].tv_sec == 0) if (ep->tvs[!ep->new].tv_sec == 0)
val = ~0L; val = ~0L;
else else
val = ((ep->tvs[ep->new].tv_sec - ep->tvs[!ep->new].tv_sec) * 1000000 + val = ((ep->tvs[ep->new].tv_sec - ep->tvs[!ep->new].tv_sec) * 1000000 +
(ep->tvs[ep->new].tv_usec - ep->tvs[!ep->new].tv_usec)); (ep->tvs[ep->new].tv_usec - ep->tvs[!ep->new].tv_usec));
ep->new = !ep->new; ep->new = !ep->new;
return val; return val;
} }
@ -415,33 +392,33 @@ elapsed(struct elapsed_state *ep)
int int
ws_poll(int *valp, int maxusec) ws_poll(int *valp, int maxusec)
{ {
static struct elapsed_state es; /* static to avoid clearing! */ static struct elapsed_state es; /* static to avoid clearing! */
#ifdef WS_POLL_DEBUG #ifdef WS_POLL_DEBUG
printf("ws_poll %d\n", maxusec); printf("ws_poll %d\n", maxusec);
fflush(stdout); fflush(stdout);
#endif #endif
elapsed(&es); /* start clock */ elapsed(&es); /* start clock */
do { do {
unsigned long e; unsigned long e;
/* tried checking return, but lost on TCP connections? */ /* tried checking return, but lost on TCP connections? */
os_pollfd(ConnectionNumber(dpy), maxusec); os_pollfd(ConnectionNumber(dpy), maxusec);
while (XtAppPending(app_context)) { while (XtAppPending(app_context)) {
XEvent event; XEvent event;
/* XXX check for connection loss; set *valp? return 0 */ /* XXX check for connection loss; set *valp? return 0 */
XtAppNextEvent(app_context, &event ); XtAppNextEvent(app_context, &event );
XtDispatchEvent( &event ); XtDispatchEvent( &event );
} }
e = elapsed(&es); e = elapsed(&es);
#ifdef WS_POLL_DEBUG #ifdef WS_POLL_DEBUG
printf(" maxusec %d e %d\r\n", maxusec, e); printf(" maxusec %d e %d\r\n", maxusec, e);
fflush(stdout); fflush(stdout);
#endif #endif
maxusec -= e; maxusec -= e;
} while (maxusec > 10000); /* 10ms */ } while (maxusec > 10000); /* 10ms */
return 1; return 1;
} }
@ -455,14 +432,14 @@ ws_loop(void (*func)(void *), void *arg)
/* XXX use XtAppAddWorkProc & XtAppMainLoop? */ /* XXX use XtAppAddWorkProc & XtAppMainLoop? */
while (ws_poll(&val,0)) while (ws_poll(&val,0))
(*func)(arg); (*func)(arg);
return val; return val;
} }
void void
ws_beep(void) ws_beep(void)
{ {
XBell(dpy, 0); /* ring at base volume */ XBell(dpy, 0); /* ring at base volume */
XFlush(dpy); XFlush(dpy);
} }
@ -498,13 +475,13 @@ os_pollfd(int fd, int maxus)
fd_set rfds; fd_set rfds;
struct timeval tv; struct timeval tv;
if (maxus >= 1000000) { /* not bloody likely, avoid divide */ if (maxus >= 1000000) { /* not bloody likely, avoid divide */
tv.tv_sec = maxus / 1000000; tv.tv_sec = maxus / 1000000;
tv.tv_usec = maxus % 1000000; tv.tv_usec = maxus % 1000000;
} }
else { else {
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = maxus; tv.tv_usec = maxus;
} }
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(fd, &rfds); FD_SET(fd, &rfds);

1036
display/xy.c Normal file

File diff suppressed because it is too large Load diff

142
display/xy.h Normal file
View file

@ -0,0 +1,142 @@
/*
* $Id: xy.h,v 1.13 2004/01/24 08:34:33 phil Exp $
* interface to O/S independent layer of XY display simulator
* Phil Budne <phil@ultimate.com>
* September 2003
*
* Changes from Douglas A. Gwyn, Jan 12, 2004
*/
/*
* Copyright (c) 2003-2004, Philip L. Budne
*
* 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.
*/
/*
* known display types
*/
enum display_type {
DIS_VR14 = 14,
DIS_VR17 = 17,
DIS_VR20 = 20,
DIS_TYPE30 = 30,
DIS_VR48 = 48,
DIS_TYPE340 = 340
};
/*
* display scale factors
*/
#define RES_FULL 1
#define RES_HALF 2
#define RES_QUARTER 4
#define RES_EIGHTH 8
/*
* must be called before first call to display_age()
* (but called implicitly by display_point())
*/
extern int display_init(enum display_type, int scale);
/* return size of virtual display */
extern int display_xpoints(void);
extern int display_ypoints(void);
/* virtual points between display and menu sections */
#define VR48_GUTTER 8 /* just a guess */
/* conversion factor from virtual points and displayed pixels */
extern int display_scale(void);
/*
* simulate passage of time; first argument is simulated microseconds elapsed,
* second argument is flag to slow down simulated speed
* see comments in display.c for why you should call it often!!
* Under X11 polls for window events!!
*/
extern int display_age(int,int);
/*
* display intensity levels.
* always at least 8 (for VT11/VS60) -- may be mapped internally
*/
#define DISPLAY_INT_MAX 7
#define DISPLAY_INT_MIN 0 /* lowest "on" level */
/*
* plot a point; arguments are x, y, intensity, color (0/1)
* returns true if light pen active (mouse button down)
* at (or very near) this location.
*
* Display initialized on first call.
*/
extern int display_point(int,int,int,int);
/*
* force window system to output bits to screen;
* call after adding points, or aging the screen
*/
extern void display_sync(void);
/*
* currently a noop
*/
extern void display_reset(void);
/*
* ring the bell
*/
extern void display_beep(void);
/*
* Set light-pen radius; maximum radius in display coordinates
* from a "lit" location that the light pen will see.
*/
extern void display_lp_radius(int);
/*
* set by simulated spacewar switch box switches
* 18 bits (only high 4 and low 4 used)
*/
extern unsigned long spacewar_switches;
/*
* light pen "tip switch" activated (for VS60 emulation etc.)
* should only be set from "driver" (window system layer)
*/
extern unsigned char display_lp_sw;
/*
* deactivates light pen
* (SIMH DR11-C simulation when initialized sets this and
* then reports mouse coordinates as Talos digitizer data)
*/
extern unsigned char display_tablet;
/*
* users of this library are expected to provide these calls.
* simulator will set 18 simulated switches.
*/
extern unsigned long cpu_get_switches(void); /* get current switch state */
extern void cpu_set_switches(unsigned long); /* set switches */

View file

@ -677,6 +677,22 @@ SIM = scp.c sim_console.c sim_fio.c sim_timer.c sim_sock.c \
sim_tmxr.c sim_ether.c sim_tape.c sim_disk.c sim_serial.c \ sim_tmxr.c sim_ether.c sim_tape.c sim_disk.c sim_serial.c \
sim_video.c sim_video.c
DISPLAYD = display
ifeq ($(WIN32),)
ifeq (x11,$(shell if $(TEST) -e /usr/include/X11/Intrinsic.h ; then echo x11; fi))
DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/x11.c
DISPLAYVT = ${DISPLAYD}/vt11.c
DISPLAY_OPT = -DUSE_DISPLAY -I/usr/X11/include -lXt -lX11 -lm
else
DISPLAYL =
DISPLAYVT =
DISPLAY_OPT =
endif
else
DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/win32.c
DISPLAYVT = ${DISPLAYD}/vt11.c
DISPLAY_OPT = -DUSE_DISPLAY -lgdi32
endif
# #
# Emulator source files and compile time options # Emulator source files and compile time options
@ -684,8 +700,8 @@ SIM = scp.c sim_console.c sim_fio.c sim_timer.c sim_sock.c \
PDP1D = PDP1 PDP1D = PDP1
PDP1 = ${PDP1D}/pdp1_lp.c ${PDP1D}/pdp1_cpu.c ${PDP1D}/pdp1_stddev.c \ PDP1 = ${PDP1D}/pdp1_lp.c ${PDP1D}/pdp1_cpu.c ${PDP1D}/pdp1_stddev.c \
${PDP1D}/pdp1_sys.c ${PDP1D}/pdp1_dt.c ${PDP1D}/pdp1_drm.c \ ${PDP1D}/pdp1_sys.c ${PDP1D}/pdp1_dt.c ${PDP1D}/pdp1_drm.c \
${PDP1D}/pdp1_clk.c ${PDP1D}/pdp1_dcs.c ${PDP1D}/pdp1_clk.c ${PDP1D}/pdp1_dcs.c ${PDP1D}/pdp1_dpy.c ${DISPLAYL}
PDP1_OPT = -I ${PDP1D} PDP1_OPT = -I ${PDP1D} $(DISPLAY_OPT)
NOVAD = NOVA NOVAD = NOVA
@ -727,8 +743,9 @@ PDP11 = ${PDP11D}/pdp11_fp.c ${PDP11D}/pdp11_cpu.c ${PDP11D}/pdp11_dz.c \
${PDP11D}/pdp11_cr.c ${PDP11D}/pdp11_rf.c ${PDP11D}/pdp11_dl.c \ ${PDP11D}/pdp11_cr.c ${PDP11D}/pdp11_rf.c ${PDP11D}/pdp11_dl.c \
${PDP11D}/pdp11_ta.c ${PDP11D}/pdp11_rc.c ${PDP11D}/pdp11_kg.c \ ${PDP11D}/pdp11_ta.c ${PDP11D}/pdp11_rc.c ${PDP11D}/pdp11_kg.c \
${PDP11D}/pdp11_ke.c ${PDP11D}/pdp11_dc.c ${PDP11D}/pdp11_dmc.c \ ${PDP11D}/pdp11_ke.c ${PDP11D}/pdp11_dc.c ${PDP11D}/pdp11_dmc.c \
${PDP11D}/pdp11_dup.c ${PDP11D}/pdp11_rs.c ${PDP11D}/pdp11_io_lib.c ${PDP11D}/pdp11_dup.c ${PDP11D}/pdp11_rs.c ${PDP11D}/pdp11_vt.c \
PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT} ${PDP11D}/pdp11_io_lib.c $(DISPLAYL) $(DISPLAYVT)
PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT} $(DISPLAY_OPT)
VAXD = VAX VAXD = VAX
@ -978,20 +995,6 @@ SWTP6800MP-A2 = ${SWTP6800C}/mp-a2.c ${SWTP6800C}/m6800.c ${SWTP6800C}/m6810.c \
${SWTP6800C}/mp-b2.c ${SWTP6800C}/mp-8m.c ${SWTP6800C}/i2716.c ${SWTP6800C}/mp-b2.c ${SWTP6800C}/mp-8m.c ${SWTP6800C}/i2716.c
SWTP6800_OPT = -I ${SWTP6800D} SWTP6800_OPT = -I ${SWTP6800D}
DISPLAYD = display
ifeq ($(WIN32),)
ifeq (x11,$(shell if $(TEST) -e /usr/include/X11/Intrinsic.h ; then echo x11; fi))
DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/x11.c
DISPLAY_OPT = -DUSE_DISPLAY -I/usr/X11/include -lXt -lX11 -lm
else
DISPLAYL =
DISPLAY_OPT =
endif
else
DISPLAYL = ${DISPLAYD}/display.c $(DISPLAYD)/win32.c
DISPLAY_OPT = -DUSE_DISPLAY
endif
TX0D = TX-0 TX0D = TX-0
TX0 = ${TX0D}/tx0_cpu.c ${TX0D}/tx0_dpy.c ${TX0D}/tx0_stddev.c \ TX0 = ${TX0D}/tx0_cpu.c ${TX0D}/tx0_dpy.c ${TX0D}/tx0_stddev.c \
${TX0D}/tx0_sys.c ${TX0D}/tx0_sys_orig.c ${DISPLAYL} ${TX0D}/tx0_sys.c ${TX0D}/tx0_sys_orig.c ${DISPLAYL}