mirror of
https://github.com/simh/simh.git
synced 2026-01-25 11:46:37 +00:00
Initial public version of TX-0 for SIMH
Integrate TX-0 simulation into SIMH.
This commit is contained in:
166
display/README
Normal file
166
display/README
Normal file
@@ -0,0 +1,166 @@
|
||||
$Id: README,v 1.15 2004/02/09 07:20:18 phil Exp $
|
||||
|
||||
XY Display Simulation
|
||||
Simulates XY plotting displays used on DEC PDP systems.
|
||||
|
||||
Copyright (c) 2003-2004, Philip L. Budne and Douglas A. Gwyn
|
||||
|
||||
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.
|
||||
|
||||
Phil Budne <phil@ultimate.com>
|
||||
Douglas A Gwyn <gwyn@arl.army.mil>
|
||||
February 5, 2004
|
||||
|
||||
Designed for use with Bob Supnik's SIMH, but the code should be easily
|
||||
portable, and usable standalone (see vttest.c for an example).
|
||||
|
||||
Display code is provided for X11 (Unix/VMS) and Win32.
|
||||
We're not GUI programmers, so the code is PRIMITIVE!!
|
||||
|
||||
Started from VC8E simulator by Douglas W. Jones
|
||||
(distribution 5, of Feb 4, 1997);
|
||||
|
||||
This PDP8 Emulator was written by Douglas W. Jones at the
|
||||
University of Iowa. It is distributed as freeware, of
|
||||
uncertain function and uncertain utility.
|
||||
|
||||
Original phosphor decay constants for Type 30 display from XMame 0.72.1
|
||||
|
||||
VT11 support GREATLY enhanced (and VT48 support added) and
|
||||
other general improvements from Douglas A Gwyn.
|
||||
|
||||
In the interest of fair play we have supplied two makefiles (neither
|
||||
of which is named Makefile nor makefile), one which works under all
|
||||
flavors of "make" (after necessary editing, in the traditional manner),
|
||||
and one which functions only under the GNU version of make (sometimes
|
||||
installed as "gmake", but the default "make" on many systems). We have
|
||||
not added a third flavor which uses BSD make enhancements, because our
|
||||
deeply held roots (over 40 combined years of Unix experience by the
|
||||
authors) demand that things should work on all platforms. Both the
|
||||
Linux and Windows worlds violate this simple credo (everything works so
|
||||
long as you use OUR preferred software), and many current users may not
|
||||
even realize that editing Makefiles used to be de rigeur. Since the
|
||||
GNU environment is widely available and "gmake" has features that
|
||||
support automatic configuration for multiple platforms, we have
|
||||
supplied thr GNU-specific variant with the expectation that many users
|
||||
will find it more convenient. You can copy or link whichever flavor of
|
||||
makefile suits your taste to whichever spelling of "makefile" suits
|
||||
your fancy, or invoke "make" with the -f flag specifying the desired
|
||||
makefile.
|
||||
|
||||
To compile test programs:
|
||||
========================
|
||||
On Unix:
|
||||
# edit smakefile to match your environment
|
||||
make -f smakefile
|
||||
or
|
||||
gmake -f gmakefile
|
||||
|
||||
On Win32 (using Cygwin);
|
||||
make -f gmakefile WIN32=1
|
||||
|
||||
On Win32 (using MINGW):
|
||||
# edit smakefile to match your environment
|
||||
make -f smakefile
|
||||
or
|
||||
mingw32-make -f gmakefile WIN32=1
|
||||
or
|
||||
execute build-mingw.bat in a DOS command window
|
||||
|
||||
creates:
|
||||
|
||||
munch: standalone simulation of PDP-1 munching squares;
|
||||
examines console "test switches" (see next section)
|
||||
|
||||
vt11: sequences through VT11/VS60 simulator test displays;
|
||||
shows how the diplay-processor simulator can be used
|
||||
from applications other than PDP-11 simulators
|
||||
|
||||
Console switches:
|
||||
================
|
||||
|
||||
Upto 18 simulated console switches, toggled by hitting keys:
|
||||
|
||||
123 456 789 qwe rty uio
|
||||
|
||||
space bar clears all switches.
|
||||
|
||||
Spacewar Switches:
|
||||
=================
|
||||
|
||||
Key presses for simulated Spacewar control box switches;
|
||||
|
||||
action player
|
||||
1 2
|
||||
rotate clockwise a k
|
||||
rotate counter clockwise s l
|
||||
fire engines d ;
|
||||
launch torpedo f '
|
||||
hyperspace (both at once) as kl
|
||||
|
||||
Light pen:
|
||||
=========
|
||||
|
||||
The light pen is active when any mouse button is held down.
|
||||
|
||||
Mouse button 1 acts as a "tip switch" for models so equipped (VS60).
|
||||
The light pen may be dragged while active.
|
||||
|
||||
Too many compile time parameters:
|
||||
================================
|
||||
|
||||
Read the comments in display.c for more explanations!!
|
||||
|
||||
DISPLAY_TYPE default display type, one of:
|
||||
DIS_VR14, DIS_VR17, DIS_VR20, DIS_VR48, DIS_TYPE30, DIS_TYPE340
|
||||
selects screen characteristics (phosphor, dimensions).
|
||||
|
||||
Only affects programs which do not make an expicit
|
||||
display_init() call.
|
||||
|
||||
PIX_SCALE one of RES_FULL, RES_HALF, RES_QUARTER, RES_EIGHTH
|
||||
selects default display scaling factor.
|
||||
|
||||
PEN_RADIUS default radius of light pen in (scaled) pixels
|
||||
|
||||
MAXELAPSED Upper 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
|
||||
MAXDELAY Upper limit in real microseconds for attempted delay
|
||||
GAINSHIFT delay_check increment/decrement gain factor
|
||||
|
||||
In display system support (x11.c, win32.c);
|
||||
|
||||
PIX_SIZE selects displayed pixel size (default 1)
|
||||
makes screen larger, useful when display scaled to small size
|
||||
|
||||
Programming interface:
|
||||
=====================
|
||||
|
||||
see display.h
|
||||
|
||||
Source repository:
|
||||
=================
|
||||
|
||||
Up-to-date Sources are available by anonymous CVS.
|
||||
See http://www.ultimate.com/phil/xy/
|
||||
12
display/build_mingw.bat
Normal file
12
display/build_mingw.bat
Normal file
@@ -0,0 +1,12 @@
|
||||
@echo off
|
||||
rem $Id: build_mingw.bat,v 1.1 2004/01/25 17:48:03 phil Exp $
|
||||
rem Compile all test programs using MINGW make and gcc environment
|
||||
rem
|
||||
rem If needed, define the path for the MINGW bin directory.
|
||||
rem (this should already be set if MINGW was installed correctly)
|
||||
rem
|
||||
gcc -v 1>NUL 2>NUL
|
||||
if ERRORLEVEL 1 path C:\MinGW\bin;D:\MinGW\bin;E:\MinGW\bin;%path%
|
||||
gcc -v 1>NUL 2>NUL
|
||||
if ERRORLEVEL 1 echo "MinGW Environment Unavailable"
|
||||
mingw32-make WIN32=1 -f gmakefile %1 %2 %3 %4
|
||||
1053
display/display.c
Normal file
1053
display/display.c
Normal file
File diff suppressed because it is too large
Load Diff
143
display/display.h
Normal file
143
display/display.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* $Id: display.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_TX0 = 33,
|
||||
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; argumen ts 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 */
|
||||
77
display/gmakefile
Normal file
77
display/gmakefile
Normal file
@@ -0,0 +1,77 @@
|
||||
# $Id: gmakefile,v 1.17 2004/01/24 08:31:56 phil Exp - revised by DAG
|
||||
|
||||
# (GNU) Makefile for test programs under Unix/X11 and Win32
|
||||
#
|
||||
# Unix:
|
||||
# edit Unix defs to fit your compiler/library environment, then
|
||||
# gmake -f gmakefile
|
||||
# or if GNU make is the default:
|
||||
# make -f gmakefile
|
||||
#
|
||||
# Win32 (Cygwin)
|
||||
# make WIN32=1
|
||||
#
|
||||
# Win32 (MINGW):
|
||||
# mingw32-make -f gmakefile WIN32=1
|
||||
|
||||
DISP_DEFS=-DTEST_DIS=DIS_VR48 -DTEST_RES=RES_HALF # -DDEBUG_VT11
|
||||
|
||||
ifeq ($(WIN32),)
|
||||
#Unix environments
|
||||
X11BASE=/usr/X11R6
|
||||
X11LIBDIR=$(X11BASE)/lib
|
||||
X11INCDIR=$(X11BASE)/include
|
||||
LIBS=-L$(X11LIBDIR) -lXt -lX11 -lm
|
||||
OSFLAGS=-I$(X11INCDIR)
|
||||
DRIVER=x11.o
|
||||
EXT=
|
||||
else
|
||||
#Win32 environments
|
||||
LIBS=-lgdi32
|
||||
OSFLAGS=
|
||||
DRIVER=win32.o
|
||||
EXT=.exe
|
||||
endif
|
||||
|
||||
#PROF=-g # -pg
|
||||
OPT=-O2
|
||||
CFLAGS=$(OPT) $(PROF) $(OSFLAGS) $(DISP_DEFS)
|
||||
CC=gcc -Wunused
|
||||
LDFLAGS=$(PROF)
|
||||
|
||||
ALL= munch$(EXT) vt11$(EXT)
|
||||
ALL: $(ALL)
|
||||
|
||||
# munching squares; see README file for
|
||||
# how to use console switches
|
||||
|
||||
MUNCH=$(DRIVER) display.o test.o
|
||||
munch$(EXT): $(MUNCH)
|
||||
$(CC) $(LDFLAGS) -o munch$(EXT) $(MUNCH) $(LIBS)
|
||||
|
||||
VT11=$(DRIVER) vt11.o vttest.o display.o
|
||||
vt11$(EXT): $(VT11)
|
||||
$(CC) $(LDFLAGS) -o vt11$(EXT) $(VT11) $(LIBS)
|
||||
|
||||
display.o: display.h ws.h
|
||||
vt11.o: display.h vt11.h
|
||||
x11.o: ws.h display.h
|
||||
win32.o: ws.h
|
||||
test.o: display.h vt11.h
|
||||
vttest.o: display.h vt11.h vtmacs.h
|
||||
|
||||
clean:
|
||||
ifeq ($(WIN32),)
|
||||
rm -f *.o *~ .#*
|
||||
else
|
||||
if exist *.o del /q *.o
|
||||
if exist *~ del /q *~
|
||||
if exist .#* del /q .#*
|
||||
endif
|
||||
|
||||
clobber: clean
|
||||
ifeq ($(WIN32),)
|
||||
rm -f $(ALL)
|
||||
else
|
||||
if exist *.exe del /q *.exe
|
||||
endif
|
||||
75
display/smakefile
Normal file
75
display/smakefile
Normal file
@@ -0,0 +1,75 @@
|
||||
# $Id: smakefile,v 1.17 2004/01/24 08:31:56 phil Exp - revised by DAG
|
||||
|
||||
# Makefile for test programs (standard Unix "make" version)
|
||||
|
||||
# Unix:
|
||||
# comment out Windows defs, uncomment Unix defs,
|
||||
# edit Unix defs to fit your compiler/library environment, then
|
||||
# (g)make
|
||||
#
|
||||
# Win32 (Cygwin)
|
||||
# comment out Unix defs, uncomment Windows defs, then
|
||||
# make
|
||||
#
|
||||
# Win32 (MINGW)
|
||||
# comment out Unix defs, uncomment Windows defs, then
|
||||
# mingw32-make
|
||||
|
||||
DISP_DEFS=-DTEST_DIS=DIS_VR48 -DTEST_RES=RES_HALF # -DDEBUG_VT11
|
||||
|
||||
#Unix environments
|
||||
CC=cc # gcc -Wunused
|
||||
#X11BASE=/usr/X11R6
|
||||
#X11LIBDIR=$(X11BASE)/lib
|
||||
#X11INCDIR=$(X11BASE)/include
|
||||
LIBS=-lXt -lX11 -lm # -L$(X11LIBDIR)
|
||||
OSFLAGS=-I$(X11INCDIR)
|
||||
DRIVER=x11.o
|
||||
EXT=
|
||||
PROF=-g # -pg
|
||||
OPT=-O # -O2
|
||||
CFLAGS=$(OPT) $(PROF) $(OSFLAGS) $(DISP_DEFS)
|
||||
CC=cc # gcc -Wunused
|
||||
LDFLAGS=$(PROF)
|
||||
|
||||
##Win32 environments
|
||||
#LIBS=-lgdi32
|
||||
#OSFLAGS=
|
||||
#DRIVER=win32.o
|
||||
#EXT=.exe
|
||||
#PROF=-g # -pg
|
||||
#OPT=-O2
|
||||
#CFLAGS=$(OPT) $(PROF) $(OSFLAGS) $(DISP_DEFS)
|
||||
#CC=gcc -Wunused
|
||||
LDFLAGS=$(PROF)
|
||||
|
||||
ALL= munch$(EXT) vt11$(EXT)
|
||||
ALL: $(ALL)
|
||||
|
||||
# munching squares; see README file for
|
||||
# how to use console switches
|
||||
|
||||
MUNCH=$(DRIVER) display.o test.o
|
||||
munch$(EXT): $(MUNCH)
|
||||
$(CC) $(LDFLAGS) -o munch$(EXT) $(MUNCH) $(LIBS)
|
||||
|
||||
VT11=$(DRIVER) vt11.o vttest.o display.o
|
||||
vt11$(EXT): $(VT11)
|
||||
$(CC) $(LDFLAGS) -o vt11$(EXT) $(VT11) $(LIBS)
|
||||
|
||||
display.o: display.h ws.h
|
||||
vt11.o: display.h vt11.h
|
||||
x11.o: ws.h display.h
|
||||
win32.o: ws.h
|
||||
test.o: display.h vt11.h
|
||||
vttest.o: display.h vt11.h vtmacs.h
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ .#* # Unix
|
||||
# if exist *.o del /q *.o # Win32
|
||||
# if exist *~ del /q *~ # Win32
|
||||
# if exist .#* del /q .#* # Win32
|
||||
|
||||
clobber: clean
|
||||
rm -f $(ALL) # Unix
|
||||
# if exist *.exe del /q *.exe # Win32
|
||||
192
display/test.c
Normal file
192
display/test.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* $Id: test.c,v 1.23 2004/02/07 06:31:20 phil Exp $
|
||||
* XY Display simulator test program (PDP-1 Munching Squares)
|
||||
* Phil Budne <phil@ultimate.com>
|
||||
* September 2003
|
||||
*
|
||||
* Updates from Douglas A. Gwyn, 12 Jan. 2004
|
||||
*
|
||||
* With thanks to Daniel Smith for his web page:
|
||||
* http://world.std.com/~dpbsmith/munch.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef TEST_DIS
|
||||
#define TEST_DIS DIS_TYPE30
|
||||
#endif
|
||||
|
||||
#ifndef TEST_RES
|
||||
#define TEST_RES RES_HALF
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
/* SunOS4 <stdlib.h> doesn't define this */
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
#include "display.h"
|
||||
|
||||
static unsigned long test_switches = 0;
|
||||
|
||||
/* called from display code: */
|
||||
unsigned long
|
||||
cpu_get_switches(void) {
|
||||
return test_switches;
|
||||
}
|
||||
|
||||
/* called from display code: */
|
||||
void
|
||||
cpu_set_switches(bits)
|
||||
unsigned long bits;
|
||||
{
|
||||
printf("switches: %06lo\n", bits);
|
||||
test_switches = bits;
|
||||
}
|
||||
|
||||
void
|
||||
munch(void) {
|
||||
static long us = 0;
|
||||
static long io = 0, v = 0;
|
||||
long ac;
|
||||
int x, y;
|
||||
|
||||
ac = test_switches;
|
||||
ac += v; /* add v */
|
||||
if (ac & ~0777777) {
|
||||
ac++;
|
||||
ac &= 0777777;
|
||||
}
|
||||
v = ac; /* dac v */
|
||||
|
||||
ac <<= 9; /* rcl 9s */
|
||||
io <<= 9;
|
||||
io |= ac>>18;
|
||||
ac &= 0777777;
|
||||
ac |= io>>18;
|
||||
io &= 0777777;
|
||||
|
||||
ac ^= v; /* xor v */
|
||||
|
||||
/* convert +/-512 one's complement to 0..1022, origin in lower left */
|
||||
y = (io >> 8) & 01777; /* hi 10 */
|
||||
if (y & 01000)
|
||||
y ^= 01000;
|
||||
else
|
||||
y += 511;
|
||||
|
||||
x = (ac >> 8) & 01777; /* hi 10 */
|
||||
if (x & 01000) /* negative */
|
||||
x ^= 01000;
|
||||
else
|
||||
x += 511;
|
||||
|
||||
if (display_point(x, y, DISPLAY_INT_MAX, 0))
|
||||
printf("light pen hit at (%d,%d)\n", x, y);
|
||||
|
||||
/*#define US 100000 /* 100ms (10/sec) */
|
||||
/*#define US 50000 /* 50ms (20/sec) */
|
||||
/*#define US 20000 /* 20ms (50/sec) */
|
||||
/*#define US 10000 /* 10ms (100/sec) */
|
||||
#define US 0
|
||||
us += 50; /* 10 5us PDP-1 memory cycles */
|
||||
if (us >= US) {
|
||||
display_age(us, 1);
|
||||
us = 0;
|
||||
}
|
||||
display_sync(); /* XXX push down */
|
||||
}
|
||||
|
||||
#ifdef T2
|
||||
/* display all window system level intensities;
|
||||
* must be compiled with -DINTENSITIES=<n> -DT2
|
||||
*/
|
||||
void
|
||||
t2(void) {
|
||||
int x, y;
|
||||
|
||||
display_init(TEST_DIS, TEST_RES);
|
||||
for (x = INTENSITIES-1; x >= 0; x--) {
|
||||
for (y = 0; y < 20; y++) {
|
||||
ws_display_point(x*4, 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+3, y, x, 0);
|
||||
}
|
||||
display_sync();
|
||||
}
|
||||
fflush(stdout);
|
||||
for (;;)
|
||||
/* wait */ ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef T3
|
||||
/* display all "user" level intensities;
|
||||
* must be compiled with -DINTENSITIES=<n> -DT3
|
||||
*
|
||||
* skip every other virtual point on both axes
|
||||
* default scaling maps adjacent pixels and
|
||||
* causes re-intensification!
|
||||
*/
|
||||
void
|
||||
t3(void) {
|
||||
int x, y;
|
||||
|
||||
display_init(TEST_DIS, TEST_RES);
|
||||
for (x = DISPLAY_INT_MAX; x >= 0; x--) {
|
||||
for (y = 0; y < 20; y++) {
|
||||
display_point(x*2, y*2, x, 0);
|
||||
}
|
||||
display_sync();
|
||||
}
|
||||
fflush(stdout);
|
||||
for (;;)
|
||||
/* wait */ ;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main(void) {
|
||||
if (!display_init(TEST_DIS, TEST_RES))
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
cpu_set_switches(04000UL); /* classic starting value */
|
||||
for (;;) {
|
||||
#ifdef T2
|
||||
t2();
|
||||
#endif
|
||||
#ifdef T3
|
||||
t3();
|
||||
#endif
|
||||
munch();
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
706
display/type340.c
Normal file
706
display/type340.c
Normal file
@@ -0,0 +1,706 @@
|
||||
/*
|
||||
* $Id: type340.c,v 1.5 2004/01/24 20:52:16 phil Exp $
|
||||
* Simulator Independent DEC Type 340 Graphic Display Processor Simulation
|
||||
* Phil Budne <phil@ultimate.com>
|
||||
* September 20, 2003
|
||||
* from vt11.c
|
||||
*
|
||||
* Information from DECUS 7-13
|
||||
* http://www.spies.com/~aek/pdf/dec/pdp7/7-13_340displayProgMan.pdf
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 name of the author 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.
|
||||
*/
|
||||
|
||||
#include "display.h" /* XY plot interface */
|
||||
|
||||
/*
|
||||
* The Type 340 was used on the PDP-{4,6,7,9,10}
|
||||
* and used 18-bit words, with bits numbered 0 thru 17
|
||||
* (most significant to least)
|
||||
*/
|
||||
|
||||
#define BITMASK(N) (1<<(17-(N)))
|
||||
|
||||
/* mask for a field */
|
||||
#define FIELDMASK(START,END) ((1<<((END)-(START)+1))-1)
|
||||
|
||||
/* extract a field */
|
||||
#define GETFIELD(W,START,END) (((W)>>(17-(END)))&FIELDMASK(START,END))
|
||||
|
||||
/* extract a 1-bit field */
|
||||
#define TESTBIT(W,B) (((W) & BITMASK(B)) != 0)
|
||||
|
||||
#ifdef DEBUG_TY340
|
||||
#define DEBUGF(X) printf X
|
||||
#else
|
||||
#define DEBUGF(X)
|
||||
#endif
|
||||
|
||||
typedef long ty340word;
|
||||
|
||||
static ty340word DAC; /* Display Address Counter */
|
||||
static unsigned char shift; /* 1 bit */
|
||||
static enum mode mode; /* 3 bits */
|
||||
static int scale; /* 2 bits */
|
||||
|
||||
enum mode { PARAM=0, POINT, SLAVE, CHAR, VECTOR, VCONT, INCR, SUBR };
|
||||
|
||||
enum jump_type { DJP=2, DJS=3, DDS=1 };
|
||||
static ty340word ASR; /* Address Save Register */
|
||||
static unsigned char save_ff; /* "save" flip-flop */
|
||||
|
||||
static unsigned char intensity; /* 3 bits */
|
||||
static unsigned char lp_ena; /* 1 bit */
|
||||
|
||||
/* kept signed for raster violation checking */
|
||||
static short xpos, ypos; /* 10 bits, signed */
|
||||
static unsigned char sequence; /* 2 bits */
|
||||
|
||||
/* XXX make defines public for 340_cycle return */
|
||||
#define STOPPED 01
|
||||
#define LPHIT 02
|
||||
#define VEDGE 04
|
||||
#define HEDGE 010
|
||||
static unsigned char status = STOPPED;
|
||||
|
||||
/*
|
||||
* callbacks into PDP-6/10 simulator
|
||||
*/
|
||||
extern ty340word ty340_fetch(ty340word);
|
||||
extern void ty340_store(ty340word, ty340word);
|
||||
extern void ty340_stop_int(void);
|
||||
extern void ty340_lp_int(void);
|
||||
|
||||
void
|
||||
ty340_set_dac(ty340word addr)
|
||||
{
|
||||
DAC = addr;
|
||||
mode = 0;
|
||||
DEBUGF(("set DAC %06\r\n", DAC));
|
||||
status = 0; /* XXX just clear stopped? */
|
||||
/* XXX clear other stuff? save_ff? */
|
||||
}
|
||||
|
||||
void
|
||||
ty340_reset(void)
|
||||
{
|
||||
/* XXX call display layer? destroy window? */
|
||||
xpos = ypos = 0;
|
||||
status = STOPPED;
|
||||
}
|
||||
|
||||
static int
|
||||
point(int x, int y, int seq)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* XXX apply scale? */
|
||||
|
||||
i = DISPLAY_INT_MAX-7+intensity;
|
||||
if (i <= 0)
|
||||
i = 1;
|
||||
|
||||
if (x < 0 || x > 1023) {
|
||||
status |= VEDGE;
|
||||
return 0;
|
||||
}
|
||||
if (y < 0 || y > 1023) {
|
||||
status |= HEDGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (display_point(x, y, i, 0)) {
|
||||
if (lp_ena) {
|
||||
/* XXX save location? */
|
||||
status |= LPHIT;
|
||||
sequence = seq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* two-step algorithm, developed by Xiaolin Wu
|
||||
* from http://graphics.lcs.mit.edu/~mcmillan/comp136/Lecture6/Lines.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* The two-step algorithm takes the interesting approach of treating
|
||||
* line drawing as a automaton, or finite state machine. If one looks
|
||||
* at the possible configurations for the next two pixels of a line,
|
||||
* it is easy to see that only a finite set of possibilities exist.
|
||||
* The two-step algorithm shown here also exploits the symmetry of
|
||||
* line-drawing by simultaneously drawn from both ends towards the
|
||||
* midpoint.
|
||||
*/
|
||||
|
||||
static void
|
||||
lineTwoStep(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
int dy = y1 - y0;
|
||||
int dx = x1 - x0;
|
||||
int stepx, stepy;
|
||||
|
||||
if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
|
||||
if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
|
||||
|
||||
lpoint(x0,y0);
|
||||
if (dx == 0 && dy == 0) /* following algorithm won't work */
|
||||
return; /* just the one dot */
|
||||
lpoint(x1, y1);
|
||||
if (dx > dy) {
|
||||
int length = (dx - 1) >> 2;
|
||||
int extras = (dx - 1) & 3;
|
||||
int incr2 = (dy << 2) - (dx << 1);
|
||||
if (incr2 < 0) {
|
||||
int c = dy << 1;
|
||||
int incr1 = c << 1;
|
||||
int d = incr1 - dx;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
x0 += stepx;
|
||||
x1 -= stepx;
|
||||
if (d < 0) { /* Pattern: */
|
||||
lpoint(x0, y0);
|
||||
lpoint(x0 += stepx, y0); /* x o o */
|
||||
lpoint(x1, y1);
|
||||
lpoint(x1 -= stepx, y1);
|
||||
d += incr1;
|
||||
}
|
||||
else {
|
||||
if (d < c) { /* Pattern: */
|
||||
lpoint(x0, y0); /* o */
|
||||
lpoint(x0 += stepx, y0 += stepy); /* x o */
|
||||
lpoint(x1, y1);
|
||||
lpoint(x1 -= stepx, y1 -= stepy);
|
||||
} else {
|
||||
lpoint(x0, y0 += stepy); /* Pattern: */
|
||||
lpoint(x0 += stepx, y0); /* o o */
|
||||
lpoint(x1, y1 -= stepy); /* x */
|
||||
lpoint(x1 -= stepx, y1);
|
||||
}
|
||||
d += incr2;
|
||||
}
|
||||
}
|
||||
if (extras > 0) {
|
||||
if (d < 0) {
|
||||
lpoint(x0 += stepx, y0);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0);
|
||||
if (extras > 2) lpoint(x1 -= stepx, y1);
|
||||
} else
|
||||
if (d < c) {
|
||||
lpoint(x0 += stepx, y0);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1 -= stepx, y1);
|
||||
} else {
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0);
|
||||
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int c = (dy - dx) << 1;
|
||||
int incr1 = c << 1;
|
||||
int d = incr1 + dx;
|
||||
int i;
|
||||
for (i = 0; i < length; i++) {
|
||||
x0 += stepx;
|
||||
x1 -= stepx;
|
||||
if (d > 0) {
|
||||
lpoint(x0, y0 += stepy); /* Pattern: */
|
||||
lpoint(x0 += stepx, y0 += stepy); /* o */
|
||||
lpoint(x1, y1 -= stepy); /* o */
|
||||
lpoint(x1 -= stepx, y1 -= stepy); /* x */
|
||||
d += incr1;
|
||||
} else {
|
||||
if (d < c) {
|
||||
lpoint(x0, y0); /* Pattern: */
|
||||
lpoint(x0 += stepx, y0 += stepy); /* o */
|
||||
lpoint(x1, y1); /* x o */
|
||||
lpoint(x1 -= stepx, y1 -= stepy);
|
||||
} else {
|
||||
lpoint(x0, y0 += stepy); /* Pattern: */
|
||||
lpoint(x0 += stepx, y0); /* o o */
|
||||
lpoint(x1, y1 -= stepy); /* x */
|
||||
lpoint(x1 -= stepx, y1);
|
||||
}
|
||||
d += incr2;
|
||||
}
|
||||
}
|
||||
if (extras > 0) {
|
||||
if (d > 0) {
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
|
||||
} else if (d < c) {
|
||||
lpoint(x0 += stepx, y0);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1 -= stepx, y1);
|
||||
} else {
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0);
|
||||
if (extras > 2) {
|
||||
if (d > c)
|
||||
lpoint(x1 -= stepx, y1 -= stepy);
|
||||
else
|
||||
lpoint(x1 -= stepx, y1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int length = (dy - 1) >> 2;
|
||||
int extras = (dy - 1) & 3;
|
||||
int incr2 = (dx << 2) - (dy << 1);
|
||||
if (incr2 < 0) {
|
||||
int c = dx << 1;
|
||||
int incr1 = c << 1;
|
||||
int d = incr1 - dy;
|
||||
int i;
|
||||
for (i = 0; i < length; i++) {
|
||||
y0 += stepy;
|
||||
y1 -= stepy;
|
||||
if (d < 0) {
|
||||
lpoint(x0, y0);
|
||||
lpoint(x0, y0 += stepy);
|
||||
lpoint(x1, y1);
|
||||
lpoint(x1, y1 -= stepy);
|
||||
d += incr1;
|
||||
} else {
|
||||
if (d < c) {
|
||||
lpoint(x0, y0);
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
lpoint(x1, y1);
|
||||
lpoint(x1 -= stepx, y1 -= stepy);
|
||||
} else {
|
||||
lpoint(x0 += stepx, y0);
|
||||
lpoint(x0, y0 += stepy);
|
||||
lpoint(x1 -= stepx, y1);
|
||||
lpoint(x1, y1 -= stepy);
|
||||
}
|
||||
d += incr2;
|
||||
}
|
||||
}
|
||||
if (extras > 0) {
|
||||
if (d < 0) {
|
||||
lpoint(x0, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1, y1 -= stepy);
|
||||
} else
|
||||
if (d < c) {
|
||||
lpoint(x0, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1, y1 -= stepy);
|
||||
} else {
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int c = (dx - dy) << 1;
|
||||
int incr1 = c << 1;
|
||||
int d = incr1 + dy;
|
||||
int i;
|
||||
for (i = 0; i < length; i++) {
|
||||
y0 += stepy;
|
||||
y1 -= stepy;
|
||||
if (d > 0) {
|
||||
lpoint(x0 += stepx, y0);
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
lpoint(x1 -= stepy, y1);
|
||||
lpoint(x1 -= stepx, y1 -= stepy);
|
||||
d += incr1;
|
||||
} else {
|
||||
if (d < c) {
|
||||
lpoint(x0, y0);
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
lpoint(x1, y1);
|
||||
lpoint(x1 -= stepx, y1 -= stepy);
|
||||
} else {
|
||||
lpoint(x0 += stepx, y0);
|
||||
lpoint(x0, y0 += stepy);
|
||||
lpoint(x1 -= stepx, y1);
|
||||
lpoint(x1, y1 -= stepy);
|
||||
}
|
||||
d += incr2;
|
||||
}
|
||||
}
|
||||
if (extras > 0) {
|
||||
if (d > 0) {
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1 -= stepx, y1 -= stepy);
|
||||
} else if (d < c) {
|
||||
lpoint(x0, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 2) lpoint(x1, y1 -= stepy);
|
||||
} else {
|
||||
lpoint(x0 += stepx, y0 += stepy);
|
||||
if (extras > 1) lpoint(x0, y0 += stepy);
|
||||
if (extras > 2) {
|
||||
if (d > c)
|
||||
lpoint(x1 -= stepx, y1 -= stepy);
|
||||
else
|
||||
lpoint(x1, y1 -= stepy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* lineTwoStep */
|
||||
|
||||
static int
|
||||
vector(int i, int sx, int dx, int sy, int dy)
|
||||
{
|
||||
int x0, y0, x1, y1;
|
||||
|
||||
x0 = xpos;
|
||||
y0 = ypos;
|
||||
|
||||
if (sx) {
|
||||
x1 = x0 - dx;
|
||||
if (x1 < 0) /* XXX TEMP? */
|
||||
x1 = 0;
|
||||
}
|
||||
else {
|
||||
x1 = x0 + dx;
|
||||
if (x1 > 1023) /* XXX TEMP? */
|
||||
x1 = 1023;
|
||||
}
|
||||
|
||||
if (sy) {
|
||||
y1 = y0 - dy;
|
||||
if (y1 < 0) /* XXX TEMP? */
|
||||
y1 = 0;
|
||||
}
|
||||
else {
|
||||
y1 = y0 + dy; /* XXX TEMP? */
|
||||
if (y1 > 1023)
|
||||
y1 = 1023;
|
||||
}
|
||||
|
||||
DEBUGF(("vector i%d (%d,%d) to (%d,%d)\r\n", i, x0, y0, x1, y1));
|
||||
if (i)
|
||||
lineTwoStep(x0, y0, x1, y1);
|
||||
|
||||
xpos = x1;
|
||||
ypos = y1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return true on raster violation */
|
||||
int
|
||||
ipoint(int i, int n, unsigned char byte)
|
||||
{
|
||||
if (byte & 010) { /* left/right */
|
||||
if (byte & 04) {
|
||||
if (xpos == 0) {
|
||||
status |= VEDGE;
|
||||
return 1;
|
||||
}
|
||||
xpos--;
|
||||
}
|
||||
else {
|
||||
if (xpos == 1023) {
|
||||
status |= VEDGE;
|
||||
return 1;
|
||||
}
|
||||
xpos++;
|
||||
}
|
||||
}
|
||||
if (byte & 02) { /* up/down */
|
||||
if (byte & 04) {
|
||||
if (ypos == 0) {
|
||||
status |= HEDGE;
|
||||
return 1;
|
||||
}
|
||||
ypos--;
|
||||
}
|
||||
else {
|
||||
if (ypos == 1023) {
|
||||
status |= HEDGE;
|
||||
return 1;
|
||||
}
|
||||
ypos++;
|
||||
}
|
||||
}
|
||||
if (i)
|
||||
point(xpos, ypos, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 342 character generator - first 64 characters (from manual)
|
||||
*/
|
||||
static const unsigned char chars[64][5] = {
|
||||
{ 0070, 0124, 0154, 0124, 0070 }, /* 00 */
|
||||
{ 0174, 0240, 0240, 0240, 0174 }, /* 01 A */
|
||||
{ 0376, 0222, 0222, 0222, 0154 }, /* 02 B */
|
||||
{ 0174, 0202, 0202, 0202, 0104 }, /* 03 C */
|
||||
{ 0376, 0202, 0202, 0202, 0174 }, /* 04 D */
|
||||
{ 0376, 0222, 0222, 0222, 0222 }, /* 05 E */
|
||||
{ 0376, 0220, 0220, 0220, 0220 }, /* 06 F */
|
||||
{ 0174, 0202, 0222, 0222, 0134 }, /* 07 G */
|
||||
{ 0376, 0020, 0020, 0020, 0376 }, /* 10 H */
|
||||
{ 0000, 0202, 0376, 0202, 0000 }, /* 11 I */
|
||||
{ 0004, 0002, 0002, 0002, 0374 }, /* 12 J */
|
||||
{ 0376, 0020, 0050, 0104, 0202 }, /* 13 K */
|
||||
{ 0376, 0002, 0002, 0002, 0002 }, /* 14 K */
|
||||
{ 0374, 0100, 0040, 0100, 0374 }, /* 15 M */
|
||||
{ 0376, 0100, 0040, 0020, 0376 }, /* 16 N */
|
||||
{ 0174, 0202, 0202, 0202, 0174 }, /* 17 O */
|
||||
{ 0376, 0220, 0220, 0220, 0140 }, /* 20 P */
|
||||
{ 0174, 0202, 0212, 0206, 0176 }, /* 21 Q */
|
||||
{ 0376, 0220, 0230, 0224, 0142 }, /* 22 R */
|
||||
{ 0144, 0222, 0222, 0222, 0114 }, /* 23 S */
|
||||
{ 0200, 0200, 0376, 0200, 0200 }, /* 24 T */
|
||||
{ 0374, 0002, 0002, 0002, 0374 }, /* 25 U */
|
||||
{ 0370, 0004, 0002, 0004, 0370 }, /* 26 V */
|
||||
{ 0376, 0004, 0010, 0004, 0376 }, /* 27 W */
|
||||
{ 0202, 0104, 0070, 0104, 0202 }, /* 30 X */
|
||||
{ 0200, 0100, 0076, 0100, 0200 }, /* 31 Y */
|
||||
{ 0226, 0232, 0222, 0262, 0322 }, /* 32 Z */
|
||||
{ 0000, 0000, 0000, 0000, 0000 }, /* 33 LF */
|
||||
{ 0000, 0000, 0000, 0000, 0000 }, /* 34 CR */
|
||||
{ 0000, 0000, 0000, 0000, 0000 }, /* 35 HORIZ */
|
||||
{ 0000, 0000, 0000, 0000, 0000 }, /* 36 VERT */
|
||||
{ 0000, 0000, 0000, 0000, 0000 }, /* 37 ESC */
|
||||
{ 0000, 0000, 0000, 0000, 0000 }, /* 40 space */
|
||||
{ 0000, 0000, 0372, 0000, 0000 }, /* 41 ! */
|
||||
{ 0000, 0340, 0000, 0340, 0000 }, /* 42 " */
|
||||
{ 0050, 0376, 0050, 0376, 0050 }, /* 43 # */
|
||||
{ 0144, 0222, 0376, 0222, 0114 }, /* 44 $ */
|
||||
{ 0306, 0310, 0220, 0246, 0306 }, /* 45 % */
|
||||
{ 0154, 0222, 0156, 0004, 0012 }, /* 46 & */
|
||||
{ 0000, 0000, 0300, 0340, 0000 }, /* 47 ' */
|
||||
{ 0070, 0104, 0202, 0000, 0000 }, /* 50 ( */
|
||||
{ 0000, 0000, 0202, 0104, 0070 }, /* 51 ) */
|
||||
{ 0124, 0070, 0174, 0070, 0124 }, /* 52 * */
|
||||
{ 0020, 0020, 0174, 0020, 0020 }, /* 53 + */
|
||||
{ 0000, 0014, 0016, 0000, 0000 }, /* 54 , */
|
||||
{ 0020, 0020, 0020, 0020, 0020 }, /* 55 - */
|
||||
{ 0000, 0006, 0006, 0000, 0000 }, /* 56 . */
|
||||
{ 0004, 0010, 0020, 0040, 0100 }, /* 57 / */
|
||||
{ 0174, 0212, 0222, 0242, 0174 }, /* 60 0 */
|
||||
{ 0000, 0102, 0376, 0002, 0000 }, /* 61 1 */
|
||||
{ 0116, 0222, 0222, 0222, 0142 }, /* 62 2 */
|
||||
{ 0104, 0202, 0222, 0222, 0154 }, /* 63 3 */
|
||||
{ 0020, 0060, 0120, 0376, 0020 }, /* 64 4 */
|
||||
{ 0344, 0222, 0222, 0222, 0214 }, /* 65 5 */
|
||||
{ 0174, 0222, 0222, 0222, 0114 }, /* 66 6 */
|
||||
{ 0306, 0210, 0220, 0240, 0300 }, /* 67 7 */
|
||||
{ 0154, 0222, 0222, 0222, 0154 }, /* 70 8 */
|
||||
{ 0144, 0222, 0222, 0222, 0174 }, /* 71 9 */
|
||||
{ 0000, 0066, 0066, 0000, 0000 }, /* 72 : */
|
||||
{ 0000, 0154, 0156, 0000, 0000 }, /* 73 ; */
|
||||
{ 0020, 0050, 0104, 0202, 0000 }, /* 74 < */
|
||||
{ 0050, 0050, 0050, 0050, 0050 }, /* 75 = */
|
||||
{ 0000, 0202, 0104, 0050, 0020 }, /* 76 > */
|
||||
{ 0100, 0200, 0236, 0220, 0140 } /* 77 ? */
|
||||
};
|
||||
|
||||
/*
|
||||
* type 342 Character/Symbol generator for type 340 display
|
||||
* return true if ESCaped
|
||||
*/
|
||||
static int
|
||||
character(int n, char c)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
switch (c) {
|
||||
case 033: /* LF */
|
||||
if (ypos < 12) {
|
||||
status |= HEDGE;
|
||||
ypos = 0;
|
||||
}
|
||||
else
|
||||
ypos -= 12; /* XXX scale? */
|
||||
|
||||
return 0;
|
||||
case 034: /* CR */
|
||||
xpos = 0;
|
||||
return 0;
|
||||
case 035: /* shift in */
|
||||
shift = 1;
|
||||
return 0;
|
||||
case 036: /* shift out */
|
||||
shift = 0;
|
||||
return 0;
|
||||
case 037: /* escape */
|
||||
sequence = n;
|
||||
return 1;
|
||||
}
|
||||
/* XXX plot character from character set selected by "shift"
|
||||
* (offset index by 64?)
|
||||
*/
|
||||
for (x = 0; x < 5; x++) {
|
||||
for (y = 0; y < 7; y++) {
|
||||
if (chars[c][x] & (1<<y)) {
|
||||
/* XXX check for raster violation? */
|
||||
point(xpos+x, ypos+y, n); /* XXX scale? */
|
||||
}
|
||||
}
|
||||
}
|
||||
xpos += 7; /* XXX scale? */
|
||||
if (xpos > 1023) {
|
||||
xpos = 1023;
|
||||
status |= VEDGE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ty340_cycle(int us, int slowdown)
|
||||
{
|
||||
ty340word inst, addr;
|
||||
int i, escape, stopped;
|
||||
|
||||
if (status & STOPPED)
|
||||
return 0; /* XXX age display? */
|
||||
|
||||
inst = ty340_fetch(DAC);
|
||||
DEBUGF(("%06o: %06o\r\n", DAC, inst));
|
||||
DAC++;
|
||||
|
||||
escape = 0;
|
||||
switch (mode) {
|
||||
case PARAM:
|
||||
mode = GETFIELD(inst, 2, 4);
|
||||
|
||||
if (TESTBIT(inst, 5)) { /* load l.p. enable */
|
||||
lp_ena = TESTBIT(inst,6);
|
||||
DEBUGF(("lp_ena %d\r\n", lp_ena));
|
||||
}
|
||||
|
||||
if (TESTBIT(inst, 7)) {
|
||||
status |= STOPPED;
|
||||
if (TESTBIT(inst, 8))
|
||||
ty340_stop_int(); /* set stop_int_end? */
|
||||
}
|
||||
|
||||
if (TESTBIT(inst, 11))
|
||||
scale = GETFIELD(inst, 12, 13);
|
||||
|
||||
if (TESTBIT(inst, 14))
|
||||
intensity = GETFIELD(inst, 15, 17);
|
||||
|
||||
break;
|
||||
|
||||
case POINT:
|
||||
mode = GETFIELD(inst, 2, 4);
|
||||
|
||||
if (TESTBIT(inst, 5)) /* load l.p. enable */
|
||||
lp_ena = TESTBIT(inst,6);
|
||||
|
||||
if (TESTBIT(inst, 1))
|
||||
ypos = GETFIELD(inst, 8, 17);
|
||||
else
|
||||
xpos = GETFIELD(inst, 8, 17);
|
||||
|
||||
if (TESTBIT(inst, 7))
|
||||
point(xpos, ypos, 0);
|
||||
break;
|
||||
|
||||
case SLAVE:
|
||||
mode = GETFIELD(inst, 2, 4);
|
||||
break;
|
||||
|
||||
case CHAR:
|
||||
escape = (character(0, GETFIELD(inst, 0, 5)) ||
|
||||
character(1, GETFIELD(inst, 6, 11)) ||
|
||||
character(2, GETFIELD(inst, 12, 17)));
|
||||
break;
|
||||
|
||||
case VECTOR:
|
||||
escape = TESTBIT(inst, 0);
|
||||
if (vector(TESTBIT(inst, 1),
|
||||
TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
|
||||
TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) {
|
||||
/* XXX interrupt? */
|
||||
}
|
||||
break;
|
||||
case VCONT:
|
||||
escape = TESTBIT(inst, 0);
|
||||
if (vector(TESTBIT(inst, 1),
|
||||
TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
|
||||
TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) {
|
||||
/* XXX set escape? */
|
||||
mode = PARAM; /* raster violation */
|
||||
}
|
||||
break;
|
||||
|
||||
case INCR:
|
||||
escape = TESTBIT(inst, 0); /* escape bit */
|
||||
i = TESTBIT(inst, 1);
|
||||
|
||||
if (ipoint(i, 0, GETFIELD(inst, 2, 5)) ||
|
||||
ipoint(i, 1, GETFIELD(inst, 6, 9)) ||
|
||||
ipoint(i, 2, GETFIELD(inst, 10, 13)) ||
|
||||
ipoint(i, 3, GETFIELD(inst, 14, 17)))
|
||||
/* XXX set escape? */
|
||||
mode = PARAM; /* raster violation */
|
||||
break;
|
||||
|
||||
case SUBR:
|
||||
/* type 347 Display Subroutine Option? */
|
||||
|
||||
mode = GETFIELD(inst, 2, 4);
|
||||
/* XXX take high bits of current DAC? */
|
||||
addr = GETFIELD(inst, 5, 17);
|
||||
|
||||
switch (GETFIELD(inst, 0, 1)) {
|
||||
case DJS: /* display jump and save */
|
||||
ASR = DAC;
|
||||
save_ff = 1; /* set "save" flip-flop */
|
||||
/* FALL */
|
||||
case DJP: /* display jump */
|
||||
DAC = addr;
|
||||
break;
|
||||
case DDS: /* display deposit save register */
|
||||
ty340_deposit(addr, (DJP<<16) | ASR);
|
||||
save_ff = 0; /* ?? */
|
||||
break;
|
||||
default:
|
||||
/* XXX ??? */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (escape) {
|
||||
mode = PARAM;
|
||||
if (save_ff) {
|
||||
/* return from subroutine */
|
||||
DAC = ASR;
|
||||
save_ff = 0;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
} /* ty340_cycle */
|
||||
3148
display/vt11.c
Normal file
3148
display/vt11.c
Normal file
File diff suppressed because it is too large
Load Diff
137
display/vt11.h
Normal file
137
display/vt11.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* $Id: vt11.h,v 1.7 2004/01/25 17:20:51 phil Exp $
|
||||
* interface to VT11 simulator
|
||||
* Phil Budne <phil@ultimate.com>
|
||||
* September 16, 2003
|
||||
* Substantially revised by Douglas A. Gwyn, 14 Jan. 2004
|
||||
*
|
||||
* prerequisite: display.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2004, Philip L. Budne and Douglas A. Gwyn
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SIM_DEFS_H_
|
||||
typedef unsigned short uint16;
|
||||
typedef long int32;
|
||||
typedef unsigned long uint32;
|
||||
#endif /* _SIM_DEFS_H_ */
|
||||
|
||||
/*
|
||||
* VT11 jumpers control character spacing; VS60 always uses VT11 normal.
|
||||
* The VT11_CSP_{W,H} #defines establish the initial default character
|
||||
* spacing; to change the VT11 simulation from these default values,
|
||||
* set vt11_csp_{w,h} before calling any function named vt11_*.
|
||||
*/
|
||||
extern unsigned char vt11_csp_w; /* horizontal character spacing */
|
||||
#ifdef VT11_NARROW_OPT /* W3 or W6 installed */
|
||||
#define VT11_CSP_W 12
|
||||
#else /* VT11 normal; W4 or W5 installed */
|
||||
#define VT11_CSP_W 14
|
||||
#endif
|
||||
extern unsigned char vt11_csp_h; /* vertical character spacing */
|
||||
#ifdef VT11_TALL_OPT /* W3 or W4 installed */
|
||||
#define VT11_CSP_H 26
|
||||
#else /* VT11 normal; W5 or W6 installed */
|
||||
#define VT11_CSP_H 24
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The DISPLAY_TYPE #define establishes the initial default display
|
||||
* type; to change from the default display type, set vt11_display
|
||||
* before calling any function named vt11_* (other than vt11_reset()).
|
||||
*/
|
||||
#ifndef DISPLAY_TYPE
|
||||
#define DISPLAY_TYPE DIS_VR17 /* default display type */
|
||||
#endif
|
||||
extern enum display_type vt11_display; /* DIS_VR{14,17,48} */
|
||||
/*
|
||||
* The PIX_SCALE #define establishes the initial default display scale
|
||||
* factor; to change from the default scale factor, set vt11_scale
|
||||
* before calling any function named vt11_* (other than vt11_reset()).
|
||||
*/
|
||||
#ifndef PIX_SCALE
|
||||
#define PIX_SCALE RES_HALF /* default display scale factor */
|
||||
#endif
|
||||
extern int vt11_scale; /* RES_{FULL,HALF,QUARTER,EIGHTH} */
|
||||
/*
|
||||
* When vt11_init (READONLY) is nonzero, it indicates that it is too late
|
||||
* to change display parameters (type, scale, character spacing, etc.).
|
||||
*/
|
||||
extern unsigned char vt11_init; /* set after display_init() called */
|
||||
|
||||
/* vt11.c simulates either a VT11 or a VT48(VS60), according to display type: */
|
||||
#define VS60 (vt11_display == DIS_VR48)
|
||||
#define VT11 (!VS60)
|
||||
|
||||
/* The display file is an array of 16-bit words. */
|
||||
typedef uint16 vt11word;
|
||||
|
||||
extern int32 vt11_get_dpc(void); /* read Display PC */
|
||||
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_ypr(void); /* read char code/Y pos register */
|
||||
extern int32 vt11_get_rr(void); /* read relocate 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_yor(void); /* read Y offset 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_nr(void); /* read name 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_sar(void); /* read stack address/maint register */
|
||||
extern int32 vt11_get_zpr(void); /* read Z position register */
|
||||
extern int32 vt11_get_zor(void); /* read Z offset register */
|
||||
|
||||
extern void vt11_set_dpc(uint16); /* write Display PC */
|
||||
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_ypr(uint16); /* write char code/Y pos register */
|
||||
extern void vt11_set_rr(uint16); /* write relocate 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_yor(uint16); /* write Y offset 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_nr(uint16); /* write name 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_sar(uint16); /* write stack address/maint register */
|
||||
extern void vt11_set_zpr(uint16); /* write Z position register */
|
||||
extern void vt11_set_zor(uint16); /* write Z offset register */
|
||||
|
||||
extern void vt11_reset(void); /* reset the display processor */
|
||||
extern int vt11_cycle(int,int); /* perform a display processor cycle */
|
||||
|
||||
/*
|
||||
* 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 void vt_stop_intr(void); /* post a display-stop 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_name_intr(void); /* post a name-match interrupt */
|
||||
291
display/vtmacs.h
Normal file
291
display/vtmacs.h
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* $Id: vtmacs.h,v 1.4 2004/02/07 06:26:47 phil Exp $
|
||||
* macros for coding a VT11/VS60 display file (instructions and data)
|
||||
* Douglas A. Gwyn <gwyn@arl.army.mil>
|
||||
* January 31, 2004
|
||||
*
|
||||
* XXX -- assumes ASCII host character set
|
||||
*/
|
||||
|
||||
/* helper macros (not for use outside this header): */
|
||||
#define SGN_(x) ((x) < 0)
|
||||
#define MAG_(x) ((x) >= 0 ? (x) : -(x)) /* -0 not expressible directly in C */
|
||||
|
||||
/* control instructions: */
|
||||
|
||||
/* load status register A: */
|
||||
#define LSRA(stop,stop_intr,lp_hit_chg,ital,refresh,menu) \
|
||||
0170000 | stop | stop_intr | lp_hit_chg | ital | refresh | menu
|
||||
/* display stop: */
|
||||
#define ST_SAME 00000 /* don't stop display */
|
||||
#define ST_STOP 02000 /* stop display */
|
||||
/* stop interrupt: */
|
||||
#define SI_SAME 00000 /* no change */
|
||||
#define SI_INHIBIT 01000 /* inhibit interrupt on stop */
|
||||
#define SI_GENERATE 01400 /* generate interrupt on stop */
|
||||
/* light pen hit intensify (bright-down on VS60): */
|
||||
#define LI_SAME 0000 /* no change */
|
||||
#define LI_INTENSIFY 0200 /* enable intensify on hit (VT11) */
|
||||
#define LI_BRIGHTDOWN 0200 /* enable bright down on hit (VS60) */
|
||||
#define LI_NOINTENSIFY 0300 /* inhibit intensify on hit (VT11) */
|
||||
#define LI_NOBRIGHTDOWN 0300 /* inhibit bright down on hit (VS60) */
|
||||
/* italic font: */
|
||||
#define IT_SAME 000 /* no change */
|
||||
#define IT_NORMAL 040 /* normal font */
|
||||
#define IT_ITALIC 060 /* italic font */
|
||||
/* refresh rate: */
|
||||
#define RF_UNSYNC 000 /* unsynchronized */
|
||||
#define RF_SAME 000 /* (happens to work like that) */
|
||||
#define RF_LINE 004 /* sync with line (VT11) */
|
||||
#define RF_30 004 /* 30 frames/sec (VS60) */
|
||||
#define RF_40 010 /* 40 frames/sec (VS60) */
|
||||
#define RF_EXT 014 /* external sync (VS60) */
|
||||
/* menu/main area (VS60): */
|
||||
#define MN_SAME 0 /* no change */
|
||||
#define MN_MAIN 2 /* major screen area */
|
||||
#define MN_MENU 3 /* menu area */
|
||||
|
||||
/* load status register B: */
|
||||
#define LSRB(color,set_step,step) \
|
||||
0174000 | color | set_step | (step)
|
||||
/* color select (VS60): */
|
||||
#define CL_SAME 00000 /* no change */
|
||||
#define CL_GREEN 01000 /* green */
|
||||
#define CL_YELLOW 01200 /* yellow */
|
||||
#define CL_ORANGE 01400 /* orange */
|
||||
#define CL_RED 01600 /* red */
|
||||
/* graphplot increment register change enable: */
|
||||
#define SS_SAME 0000 /* no change (step value ignored) */
|
||||
#define SS_CHANGE 0100 /* write step value into register */
|
||||
|
||||
/* load status register BB (VS60): */
|
||||
#define LSRBB(z_data,edge_intr,depth_cue,char_esc) \
|
||||
0176000 | z_data | edge_intr | depth_cue | char_esc
|
||||
/* file Z data: */
|
||||
#define ZD_SAME 000 /* no change */
|
||||
#define ZD_NO 010 /* d.file does not contain Z coords. */
|
||||
#define ZD_YES 014 /* d.file contains Z coordinates */
|
||||
/* edge interrupts enable: */
|
||||
#define ED_SAME 000 /* no change */
|
||||
#define ED_DIS 040 /* disable intr. on edge transition */
|
||||
#define ED_ENA 060 /* enable intr. on edge transition */
|
||||
/* depth cue processing: */
|
||||
#define DQ_SAME 0000 /* no change */
|
||||
#define DQ_OFF 0200 /* disable depth cueing (Z intensity) */
|
||||
#define DQ_ON 0300 /* enable depth cueing (Z intensity) */
|
||||
/* escape on terminating character: */
|
||||
#define ES_SAME 0 /* no change */
|
||||
#define ES_NO 2 /* disable POPR on terminating char. */
|
||||
#define ES_YES 3 /* enable POPR on terminating char. */
|
||||
|
||||
/* load status register C (VS60): */
|
||||
#define LSRC(rotate,cs_change,cscale,vs_change,vscale) \
|
||||
0154000 | rotate | cs_change | ((cscale)<<5) | \
|
||||
vs_change | (vscale)
|
||||
/* character rotation: */
|
||||
#define RO_SAME 00000 /* no change */
|
||||
#define RO_HORIZONTAL 01000 /* no text rotation */
|
||||
#define RO_VERTICAL 01400 /* rotate text 90 degrees CCW */
|
||||
/* character scale change enable: */
|
||||
#define CS_SAME 0000 /* no change (cscale value ignored) */
|
||||
#define CS_CHANGE 0200 /* set character scale */
|
||||
/* vector scale change enable: */
|
||||
#define VS_SAME 000 /* no change (vscale value ignored) */
|
||||
#define VS_CHANGE 020 /* set vector scale */
|
||||
|
||||
/* load scope selection register (VS60): */
|
||||
#define LSSR(console,disp,lp_intr,sw_intr) \
|
||||
0164000 | console | disp | lp_intr | sw_intr
|
||||
/* console to which this instruction applies: */
|
||||
#define CN_0 0000 /* console # 0 */
|
||||
#define CN_1 0400 /* console # 1 */
|
||||
/* display enable: */
|
||||
#define DS_SAME 0000 /* no change */
|
||||
#define DS_DIS 0200 /* disable display (blank CRT) */
|
||||
#define DS_ENA 0300 /* enable display (use CRT) */
|
||||
/* light-pen hit interrupt enable: */
|
||||
#define LH_SAME 0000 /* no change */
|
||||
#define LH_DIS 0040 /* light-pen hit interrupt disabled */
|
||||
#define LH_ENA 0060 /* light-pen hit interrupt enabled */
|
||||
/* tip-switch transition interrupt enable: */
|
||||
#define SW_SAME 0000 /* no change */
|
||||
#define SW_DIS 0010 /* tip-switch interrupt disabled */
|
||||
#define SW_ENA 0014 /* tip-switch hit interrupt enabled */
|
||||
|
||||
/* load name register (VS60): */
|
||||
#define LNR(name) \
|
||||
0150000 | (name)
|
||||
|
||||
/* set graphic mode: */
|
||||
#define SGM(mode,intens,lp_intr,blink,line_type) \
|
||||
0100000 | mode | intens | lp_intr | blink | line_type
|
||||
/* graphic mode: */
|
||||
#define GM_CHAR 000000 /* character */
|
||||
#define GM_SVECT 004000 /* short vector */
|
||||
#define GM_LVECT 010000 /* long vector */
|
||||
#define GM_APOINT 014000 /* absolute point, or offset */
|
||||
#define GM_GRAPHX 020000 /* graphplot X, or basic long vector */
|
||||
#define GM_GRAPHY 024000 /* graphplot Y, or basic long vector */
|
||||
#define GM_RPOINT 030000 /* relative point */
|
||||
#define GM_BSVECT 034000 /* basic short vector */
|
||||
#define GM_ARC 040000 /* circle/arc */
|
||||
#define GM_AVECT 044000 /* absolute vector */
|
||||
/* intensity: */
|
||||
#define IN_SAME 00000 /* no change */
|
||||
#define IN_0 02000 /* intensity level 0 (dimmest) */
|
||||
#define IN_1 02200 /* intensity level 1 */
|
||||
#define IN_2 02400 /* intensity level 2 */
|
||||
#define IN_3 02600 /* intensity level 3 */
|
||||
#define IN_4 03000 /* intensity level 4 */
|
||||
#define IN_5 03200 /* intensity level 5 */
|
||||
#define IN_6 03400 /* intensity level 6 */
|
||||
#define IN_7 03600 /* intensity level 7 (brightest) */
|
||||
/* light pen interrupt: */
|
||||
#define LP_SAME 0000 /* no change */
|
||||
#define LP_DIS 0100 /* light-pen hit interrupt disabled */
|
||||
#define LP_ENA 0140 /* light-pen hit interrupt enabled */
|
||||
/* blink: */
|
||||
#define BL_SAME 000 /* no change */
|
||||
#define BL_OFF 020 /* blink off */
|
||||
#define BL_ON 030 /* blink on */
|
||||
/* line type: */
|
||||
#define LT_SAME 00 /* no change */
|
||||
#define LT_SOLID 04 /* solid */
|
||||
#define LT_LDASH 05 /* long dash */
|
||||
#define LT_SDASH 06 /* short dash */
|
||||
#define LT_DDASH 07 /* dot dash */
|
||||
|
||||
/* display jump absolute: */
|
||||
#define DJMP_ABS(addr) \
|
||||
0160000, \
|
||||
(addr) & ~1
|
||||
|
||||
/* display jump relative (VS60): */
|
||||
#define DJMP_REL(raddr) \
|
||||
0161000 | (SGN_(raddr) << 8) | MAG_(raddr)
|
||||
|
||||
/* display jump to subroutine absolute (VS60): */
|
||||
#define DJSR_ABS(addr) \
|
||||
0162000, \
|
||||
(addr) & ~1
|
||||
|
||||
/* display jump to subroutine relative (VS60): */
|
||||
#define DJSR_REL(raddr) \
|
||||
0163000 | (SGN_(raddr) << 8) | MAG_(raddr)
|
||||
|
||||
/* display no-op: */
|
||||
#define DNOP \
|
||||
0164000
|
||||
|
||||
/* display pop, no restore (VS60): */
|
||||
#define DPOP_NR \
|
||||
0165000
|
||||
|
||||
/* display pop, restore (VS60): */
|
||||
#define DPOP_R \
|
||||
0165000
|
||||
|
||||
/* display stop: */
|
||||
#define DSTOP LSRA(ST_STOP,SI_SAME,LI_SAME,IT_SAME,RF_UNSYNC,MN_SAME)
|
||||
|
||||
/* graphic data: */
|
||||
|
||||
/* intensify enable (common to all modes exept CHAR and OFFSET): */
|
||||
#define I_OFF 000000 /* beam off */
|
||||
#define I_ON 040000 /* beam on */
|
||||
|
||||
/* Note: when VS60 "file Z data" is enabled,
|
||||
use the *3() macros instead of the corresponding normal ones. */
|
||||
|
||||
/* character data: */
|
||||
#define CHAR(c1,c2) \
|
||||
((c2) << 8) | (c1) /* 7-bit ASCII assumed */
|
||||
|
||||
/* short vector data: */
|
||||
#define SVECT(i,dx,dy) \
|
||||
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy)
|
||||
#define SVECT3(i,dx,dy,dz) \
|
||||
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy), \
|
||||
(SGN_(dz) << 13) | (MAG_(dz) << 2)
|
||||
|
||||
/* long vector data: */
|
||||
#define LVECT(i,dx,dy) \
|
||||
i | (SGN_(dx) << 13) | MAG_(dx), \
|
||||
(SGN_(dy) << 13) | MAG_(dy)
|
||||
#define LVECT3(i,dx,dy,dz) \
|
||||
i | (SGN_(dx) << 13) | MAG_(dx), \
|
||||
(SGN_(dy) << 13) | MAG_(dy), \
|
||||
(SGN_(dz) << 13) | (MAG_(dz) << 2)
|
||||
|
||||
/* rotation data (VS60, probably unimplemented): */
|
||||
#define ROTATE(i,a,b) \
|
||||
i | (SGN_(a) << 13) | 010000 | MAG_(a), \
|
||||
(SGN_(b) << 13) | MAG_(b)
|
||||
#define ROTATE3(i,a,b,c) \
|
||||
i | (SGN_(a) << 13) | 010000 | MAG_(a), \
|
||||
(SGN_(b) << 13) | MAG_(b), \
|
||||
(SGN_(c) << 13) | (MAG_(c) << 2)
|
||||
|
||||
/* absolute point data: */
|
||||
#define APOINT(i,x,y) \
|
||||
i | (SGN_(x) << 13) | MAG_(x), \
|
||||
(SGN_(y) << 13) | MAG_(y)
|
||||
#define APOINT3(i,x,y,z) \
|
||||
i | (SGN_(x) << 13) | MAG_(x), \
|
||||
(SGN_(y) << 13) | MAG_(y), \
|
||||
(SGN_(z) << 13) | (MAG_(z) << 2)
|
||||
|
||||
/* offset data (VS60): */
|
||||
#define OFFSET(x,y) \
|
||||
(SGN_(x) << 13) | 010000 | MAG_(x), \
|
||||
(SGN_(y) << 13) | 010000 | MAG_(y)
|
||||
#define OFFSET3(x,y,z) \
|
||||
(SGN_(x) << 13) | 010000 | MAG_(x), \
|
||||
(SGN_(y) << 13) | 010000 | MAG_(y), \
|
||||
(SGN_(z) << 13) | 010000 | (MAG_(z) << 2)
|
||||
|
||||
/* graphplot X data: */
|
||||
#define GRAPHX(i,x) \
|
||||
i | (x)
|
||||
|
||||
/* graphplot Y data: */
|
||||
#define GRAPHY(i,y) \
|
||||
i | (y)
|
||||
|
||||
/* basic long vector data (VS60): */
|
||||
#define BLVECT(i,dir,len) \
|
||||
i | ((dir) << 11) | 02000 | (len)
|
||||
|
||||
/* relative point data: */
|
||||
#define RPOINT(i,dx,dy) \
|
||||
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy)
|
||||
#define RPOINT3(i,dx,dy,dz) \
|
||||
i | (SGN_(dx) << 13) | (MAG_(dx) << 7) | (SGN_(dy) << 6) | MAG_(dy), \
|
||||
(SGN_(dz) << 13) | (MAG_(dz) << 2)
|
||||
|
||||
/* basic short vector data (VS60): */
|
||||
#define BSVECT(i,dir1,len1,dir2,len2) \
|
||||
i | ((dir2) << 11) | ((len2) << 7) | ((dir1) << 4) | (len1)
|
||||
|
||||
/* circle/arc data (VS60, option): */
|
||||
#define ARC(i,dcx,dcy,dex,dey) \
|
||||
i | (SGN_(dcx) << 13) | MAG_(dcx), \
|
||||
(SGN_(dcy) << 13) | MAG_(dcy), \
|
||||
(SGN_(dex) << 13) | MAG_(dex), \
|
||||
(SGN_(dey) << 13) | MAG_(dey)
|
||||
#define ARC3(i,dcx,dcy,cz,dex,dey,ez) \
|
||||
i | (SGN_(dcx) << 13) | MAG_(dcx), \
|
||||
(SGN_(dcy) << 13) | MAG_(dcy), \
|
||||
(SGN_(cz) << 13) | (MAG_(cz) << 2), \
|
||||
(SGN_(dex) << 13) | MAG_(dex), \
|
||||
(SGN_(dey) << 13) | MAG_(dey), \
|
||||
(SGN_(ez) << 13) | (MAG_(ez) << 2)
|
||||
|
||||
/* absolute vector data (VS60): */
|
||||
#define AVECT(i,x,y) \
|
||||
i | (SGN_(x) << 13) | MAG_(x), \
|
||||
(SGN_(y) << 13) | MAG_(y)
|
||||
#define AVECT3(i,x,y,z) \
|
||||
i | (SGN_(x) << 13) | MAG_(x), \
|
||||
(SGN_(y) << 13) | MAG_(y), \
|
||||
(SGN_(z) << 13) | (MAG_(z) << 2)
|
||||
1301
display/vttest.c
Normal file
1301
display/vttest.c
Normal file
File diff suppressed because it is too large
Load Diff
418
display/win32.c
Normal file
418
display/win32.c
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* $Id: win32.c,v 1.38 2004/02/07 06:32:01 phil Exp $
|
||||
* Win32 support for XY display simulator
|
||||
* Phil Budne <phil@ultimate.com>
|
||||
* September 2003
|
||||
* Revised by Douglas A. Gwyn, 05 Feb. 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.
|
||||
*/
|
||||
|
||||
/* use a thread to handle windows messages; */
|
||||
#define THREADS
|
||||
|
||||
/*
|
||||
* BUGS:
|
||||
* Does not allow you to close display window;
|
||||
* would need to tear down both system, and system independent data.
|
||||
*
|
||||
* now tries to handle PAINT message, as yet untested!!
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "ws.h"
|
||||
#include "display.h"
|
||||
|
||||
#ifndef PIX_SIZE
|
||||
#define PIX_SIZE 1
|
||||
#endif
|
||||
|
||||
#define APP_CLASS "XYAppClass"
|
||||
#define APP_MENU "XYAppMenu" /* ?? */
|
||||
|
||||
/*
|
||||
* light pen location
|
||||
* see ws.h for full description
|
||||
*/
|
||||
int ws_lp_x = -1;
|
||||
int ws_lp_y = -1;
|
||||
|
||||
static HWND static_wh;
|
||||
static HINSTANCE static_inst;
|
||||
static int xpixels, ypixels;
|
||||
static char *window_name;
|
||||
static HBRUSH white_brush;
|
||||
static HBRUSH black_brush;
|
||||
#ifdef SWITCH_CURSORS
|
||||
static HCURSOR cross, arrow;
|
||||
#endif
|
||||
|
||||
static __inline int
|
||||
map_key(int k)
|
||||
{
|
||||
switch (k) {
|
||||
case 186: return ';'; /* VK_OEM_1? */
|
||||
case 222: return '\''; /* VK_OEM_7? */
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
static void
|
||||
keydown(int k)
|
||||
{
|
||||
display_keydown(map_key(k));
|
||||
}
|
||||
|
||||
static void
|
||||
keyup(int k)
|
||||
{
|
||||
display_keyup(map_key(k));
|
||||
}
|
||||
|
||||
/*
|
||||
* here on any button click, or if mouse dragged while a button down
|
||||
*/
|
||||
static void
|
||||
mousepos(DWORD lp)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = LOWORD(lp);
|
||||
y = HIWORD(lp);
|
||||
|
||||
/* convert to display coordinates */
|
||||
#if PIX_SIZE > 1
|
||||
x /= PIX_SIZE;
|
||||
y /= PIX_SIZE;
|
||||
#endif
|
||||
y = ypixels - 1 - y;
|
||||
|
||||
/* if window has been stretched, can get out of range bits!! */
|
||||
if (x >= 0 && x < xpixels && y >= 0 && y < ypixels) {
|
||||
/* checked by display_add_point() */
|
||||
ws_lp_x = x;
|
||||
ws_lp_y = y;
|
||||
}
|
||||
}
|
||||
|
||||
/* thoingggg!! "message for you sir!!!" */
|
||||
static LRESULT CALLBACK
|
||||
patsy(HWND wh, UINT msg, WPARAM wp, LPARAM lp) /* "WndProc" */
|
||||
{
|
||||
/* printf("msg %d\n", msg); */
|
||||
switch (msg) {
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if (wp & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) {
|
||||
#ifdef SWITCH_CURSORS
|
||||
if (ws_lp_x == -1 && !display_tablet)
|
||||
SetCursor(cross);
|
||||
#endif
|
||||
mousepos(lp);
|
||||
}
|
||||
#ifdef SWITCH_CURSORS
|
||||
else if (ws_lp_x != -1 && !display_tablet)
|
||||
SetCursor(arrow);
|
||||
#endif
|
||||
break; /* return?? */
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
display_lp_sw = 1;
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
#ifdef SWITCH_CURSORS
|
||||
if (!display_tablet)
|
||||
SetCursor(cross);
|
||||
#endif
|
||||
mousepos(lp);
|
||||
break; /* return?? */
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
display_lp_sw = 0;
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
#ifdef SWITCH_CURSORS
|
||||
if (!display_tablet)
|
||||
SetCursor(arrow);
|
||||
#endif
|
||||
ws_lp_x = ws_lp_y = -1;
|
||||
break; /* return?? */
|
||||
|
||||
case WM_KEYDOWN:
|
||||
keydown(wp);
|
||||
break;
|
||||
|
||||
case WM_KEYUP:
|
||||
keyup(wp);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
display_repaint();
|
||||
break; /* return?? */
|
||||
}
|
||||
return DefWindowProc(wh, msg, wp, lp);
|
||||
}
|
||||
|
||||
int
|
||||
ws_poll(int *valp, int maxus)
|
||||
{
|
||||
#ifdef THREADS
|
||||
/* msgthread handles window events; just delay simulator */
|
||||
if (maxus > 0)
|
||||
Sleep((maxus+999)/1000);
|
||||
#else
|
||||
MSG msg;
|
||||
DWORD start;
|
||||
int maxms = (maxus + 999) / 1000;
|
||||
|
||||
for (start = GetTickCount(); GetTickCount() - start < maxms; Sleep(1)) {
|
||||
/* empty message queue without blocking */
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* called from non-threaded main program */
|
||||
int
|
||||
ws_loop(void (*func)(void *), void *arg)
|
||||
{
|
||||
int val;
|
||||
while (ws_poll(&val, 0))
|
||||
(*func)(arg);
|
||||
return val;
|
||||
}
|
||||
|
||||
/* worker for display init */
|
||||
static void
|
||||
ws_init2(void) {
|
||||
WNDCLASS wc;
|
||||
int h, w;
|
||||
|
||||
#ifdef SWITCH_CURSORS
|
||||
if (!display_tablet) {
|
||||
arrow = LoadCursor(NULL, IDC_ARROW);
|
||||
cross = LoadCursor(NULL, IDC_CROSS);
|
||||
}
|
||||
#endif
|
||||
|
||||
black_brush = GetStockObject(BLACK_BRUSH);
|
||||
white_brush = GetStockObject(WHITE_BRUSH);
|
||||
|
||||
wc.lpszClassName = APP_CLASS;
|
||||
wc.lpfnWndProc = patsy;
|
||||
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
|
||||
/* also CS_NOCLOSE? CS_SAVEBITS? */
|
||||
|
||||
wc.hInstance = static_inst = GetModuleHandleA(0);
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
#ifdef SWITCH_CURSORS
|
||||
wc.hCursor = NULL;
|
||||
#else
|
||||
wc.hCursor = display_tablet ? NULL : LoadCursor(NULL, IDC_CROSS);
|
||||
#endif
|
||||
wc.hbrBackground = black_brush;
|
||||
wc.lpszMenuName = APP_MENU;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
/* WNDCLASSEX/RegisterClassEx include hIconSm (small icon) */
|
||||
RegisterClass(&wc);
|
||||
|
||||
/*
|
||||
* WS_OVERLAPPEDWINDOW=>
|
||||
* WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME,
|
||||
* WS_MINIMIZEBOX, WS_MAXIMIZEBOX
|
||||
*
|
||||
* WS_CHILD (no menu bar), WS_POPUP (mutually exclusive)
|
||||
*/
|
||||
|
||||
/* empirical crocks to get entire screen; */
|
||||
w = (xpixels*PIX_SIZE)+6;
|
||||
h = (ypixels*PIX_SIZE)+32;
|
||||
/* XXX -- above values work with XP; Phil had +10,+30 */
|
||||
|
||||
static_wh = CreateWindow(APP_CLASS, /* registered class name */
|
||||
window_name, /* window name */
|
||||
WS_OVERLAPPED, /* style */
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, /* X,Y */
|
||||
w, h,
|
||||
NULL, /* HWND hWndParent */
|
||||
NULL, /* HMENU hMenu */
|
||||
static_inst, /* application instance */
|
||||
NULL); /* lpParam */
|
||||
|
||||
ShowWindow(static_wh, SW_SHOW);
|
||||
UpdateWindow(static_wh);
|
||||
}
|
||||
|
||||
#ifdef THREADS
|
||||
static volatile init_done;
|
||||
static DWORD msgthread_id;
|
||||
|
||||
static DWORD WINAPI
|
||||
msgthread(LPVOID arg)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
ws_init2();
|
||||
|
||||
/* XXX use a mutex? */
|
||||
init_done = 1;
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0) > 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
static void
|
||||
ws_thread_init(void)
|
||||
{
|
||||
HANDLE th = CreateThread(NULL, /* sec. attr. */
|
||||
0, /* stack size */
|
||||
msgthread,
|
||||
NULL, /* param */
|
||||
0, /* flags */
|
||||
&msgthread_id);
|
||||
CloseHandle(th);
|
||||
|
||||
/* XXX use a mutex; don't wait forever!! */
|
||||
while (!init_done)
|
||||
;
|
||||
}
|
||||
#endif /* THREADS */
|
||||
|
||||
/* called from display layer on first display op */
|
||||
int
|
||||
ws_init(char *name, int xp, int yp, int colors)
|
||||
{
|
||||
xpixels = xp;
|
||||
ypixels = yp;
|
||||
window_name = name;
|
||||
|
||||
#ifdef THREADS
|
||||
ws_thread_init();
|
||||
#else
|
||||
ws_init2();
|
||||
#endif
|
||||
return 1; /* XXX return errors!! */
|
||||
}
|
||||
|
||||
void *
|
||||
ws_color_rgb(int r, int g, int b)
|
||||
{
|
||||
/* XXX check for failure??? try GetNearestColor??? */
|
||||
return CreateSolidBrush(RGB(r/256, g/256, b/256));
|
||||
}
|
||||
|
||||
void *
|
||||
ws_color_black(void)
|
||||
{
|
||||
return black_brush;
|
||||
}
|
||||
|
||||
void *
|
||||
ws_color_white(void)
|
||||
{
|
||||
return white_brush;
|
||||
}
|
||||
|
||||
void
|
||||
ws_display_point(int x, int y, void *color)
|
||||
{
|
||||
HDC dc;
|
||||
RECT r;
|
||||
HBRUSH brush = color;
|
||||
|
||||
if (x > xpixels || y > ypixels)
|
||||
return;
|
||||
|
||||
y = ypixels - 1 - y; /* invert y, top left origin */
|
||||
|
||||
/* top left corner */
|
||||
r.left = x*PIX_SIZE;
|
||||
r.top = y*PIX_SIZE;
|
||||
|
||||
/* bottom right corner, non-inclusive */
|
||||
r.right = (x+1)*PIX_SIZE;
|
||||
r.bottom = (y+1)*PIX_SIZE;
|
||||
|
||||
if (brush == NULL)
|
||||
brush = black_brush;
|
||||
|
||||
dc = GetDC(static_wh);
|
||||
FillRect(dc, &r, brush);
|
||||
ReleaseDC(static_wh, dc);
|
||||
}
|
||||
|
||||
void
|
||||
ws_sync(void) {
|
||||
/* noop */
|
||||
}
|
||||
|
||||
void
|
||||
ws_beep(void) {
|
||||
#if 0
|
||||
/* play SystemDefault sound; does not work over terminal service */
|
||||
MessageBeep(MB_OK);
|
||||
#else
|
||||
/* works over terminal service? Plays default sound/beep on Win9x/ME */
|
||||
Beep(440, 500); /* Hz, ms. */
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long
|
||||
os_elapsed(void)
|
||||
{
|
||||
static int new;
|
||||
unsigned long ret;
|
||||
static DWORD t[2];
|
||||
|
||||
/*
|
||||
* only returns milliseconds, but Sleep()
|
||||
* only takes milliseconds.
|
||||
*
|
||||
* wraps after 49.7 days of uptime.
|
||||
* DWORD is an unsigned long, so this should be OK
|
||||
*/
|
||||
t[new] = GetTickCount();
|
||||
if (t[!new] == 0)
|
||||
ret = ~0L; /* +INF */
|
||||
else
|
||||
ret = (t[new] - t[!new]) * 1000;
|
||||
new = !new; /* Ecclesiastes III */
|
||||
return ret;
|
||||
}
|
||||
66
display/ws.h
Normal file
66
display/ws.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* $Id: ws.h,v 1.17 2004/02/03 21:23:51 phil Exp $
|
||||
* Interfaces to window-system specific code for XY display simulation
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* unless you're writing a new driver, you shouldn't be looking here! */
|
||||
|
||||
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_black(void);
|
||||
extern void *ws_color_white(void);
|
||||
extern void ws_display_point(int, int, void *);
|
||||
extern void ws_sync(void);
|
||||
extern int ws_loop(void (*)(void *), void *);
|
||||
extern int ws_poll(int *, int);
|
||||
extern void ws_beep(void);
|
||||
|
||||
/* entries into display.c from below: */
|
||||
extern void display_keyup(int);
|
||||
extern void display_keydown(int);
|
||||
extern void display_repaint(void);
|
||||
|
||||
/*
|
||||
* Globals set by O/S display level to SCALED location in display
|
||||
* coordinate system in order to save an upcall on every mouse
|
||||
* movement.
|
||||
*
|
||||
* *NOT* for consumption by clients of display.c; although display
|
||||
* clients can now get the scaling factor, real displays only give you
|
||||
* a light pen "hit" when the beam passes under the light pen.
|
||||
*/
|
||||
|
||||
extern int ws_lp_x, ws_lp_y;
|
||||
|
||||
/*
|
||||
* O/S services in theory independent of window system,
|
||||
* but in (current) practice not!
|
||||
*/
|
||||
extern unsigned long os_elapsed(void);
|
||||
512
display/x11.c
Normal file
512
display/x11.c
Normal file
@@ -0,0 +1,512 @@
|
||||
/*
|
||||
* $Id: x11.c,v 1.29 2004/02/03 21:23:51 phil Exp $
|
||||
* X11 support for XY display simulator
|
||||
* Phil Budne <phil@ultimate.com>
|
||||
* September 2003
|
||||
*
|
||||
* Changes from Douglas A. Gwyn, Jan 8, 2004
|
||||
*
|
||||
* started from PDP-8/E simulator (vc8e.c & kc8e.c);
|
||||
* This PDP8 Emulator was written by Douglas W. Jones at the
|
||||
* University of Iowa. It is distributed as freeware, of
|
||||
* uncertain function and uncertain utility.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ws.h"
|
||||
#include "display.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/StringDefs.h>
|
||||
#include <X11/Core.h>
|
||||
#include <X11/Shell.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef PIX_SIZE
|
||||
#define PIX_SIZE 1
|
||||
#endif
|
||||
|
||||
//#define FULL_SCREEN 1
|
||||
#define NO_CURSOR 1
|
||||
#define NO_BORDER 1
|
||||
|
||||
/*
|
||||
* light pen location
|
||||
* see ws.h for full description
|
||||
*/
|
||||
int ws_lp_x = -1;
|
||||
int ws_lp_y = -1;
|
||||
|
||||
static XtAppContext app_context; /* the topmost context for everything */
|
||||
static Display* dpy; /* its display */
|
||||
static int scr; /* its screen */
|
||||
static Colormap cmap; /* its colormap */
|
||||
static Widget crtshell; /* the X window shell */
|
||||
static Widget crt; /* the X window in which output will plot */
|
||||
static int xpixels, ypixels;
|
||||
#ifdef FULL_SCREEN
|
||||
/* occupy entire screen for vintage computer fan Sellam Ismail */
|
||||
static int xoffset, yoffset;
|
||||
#endif
|
||||
|
||||
static GC whiteGC; /* gc with white foreground */
|
||||
static GC blackGC; /* gc with black foreground */
|
||||
static int buttons = 0; /* tracks state of all buttons */
|
||||
|
||||
static int os_pollfd(int, int); /* forward */
|
||||
|
||||
/* here on any mouse button down, AND movement when any button down */
|
||||
static void
|
||||
handle_button_press(w, d, e, b)
|
||||
Widget w;
|
||||
XtPointer d;
|
||||
XEvent *e;
|
||||
Boolean *b;
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = e->xbutton.x;
|
||||
y = e->xbutton.y;
|
||||
#ifdef FULL_SCREEN
|
||||
x -= xoffset;
|
||||
y -= yoffset;
|
||||
#endif
|
||||
#if PIX_SIZE > 1
|
||||
x *= PIX_SIZE;
|
||||
y *= PIX_SIZE;
|
||||
#endif
|
||||
|
||||
#ifndef NO_CURSUR
|
||||
if (!display_tablet)
|
||||
/* crosshair cursor to indicate tip of active pen */
|
||||
XDefineCursor(dpy, XtWindow(crt),
|
||||
(Cursor) XCreateFontCursor(dpy, XC_crosshair));
|
||||
#endif
|
||||
|
||||
y = ypixels - y - 1;
|
||||
/*printf("lightpen at %d,%d\n", x, y); fflush(stdout);*/
|
||||
ws_lp_x = x;
|
||||
ws_lp_y = y;
|
||||
|
||||
if (e->type == ButtonPress) {
|
||||
buttons |= e->xbutton.button;
|
||||
|
||||
if (e->xbutton.button == 1) {
|
||||
display_lp_sw = 1;
|
||||
/*printf("tip switch activated\n"); fflush(stdout);*/
|
||||
}
|
||||
}
|
||||
|
||||
if (b)
|
||||
*b = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_button_release(w, d, e, b)
|
||||
Widget w;
|
||||
XtPointer d;
|
||||
XEvent *e;
|
||||
Boolean *b;
|
||||
{
|
||||
if ((buttons &= ~e->xbutton.button) == 0) { /* all buttons released */
|
||||
#ifndef NO_CURSOR
|
||||
if (!display_tablet)
|
||||
/* pencil cursor (close to a pen!) to indicate inactive pen posn */
|
||||
XDefineCursor(dpy, XtWindow(crt),
|
||||
(Cursor) XCreateFontCursor(dpy, XC_pencil));
|
||||
#endif
|
||||
|
||||
/* XXX change cursor back?? */
|
||||
ws_lp_x = ws_lp_y = -1;
|
||||
}
|
||||
|
||||
if (e->xbutton.button == 1) {
|
||||
display_lp_sw = 0;
|
||||
/*printf("tip switch deactivated\n"); fflush(stdout);*/
|
||||
}
|
||||
|
||||
if (b)
|
||||
*b = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_key_press(w, d, e, b)
|
||||
Widget w;
|
||||
XtPointer d;
|
||||
XEvent *e;
|
||||
Boolean *b;
|
||||
{
|
||||
int shift = (ShiftMask & e->xkey.state) != 0;
|
||||
KeySym key = XKeycodeToKeysym( dpy, e->xkey.keycode, shift );
|
||||
|
||||
/*printf("key %d down\n", key); fflush(stdout);*/
|
||||
if ((key & 0xff00) == 0)
|
||||
display_keydown(key);
|
||||
|
||||
if (b)
|
||||
*b = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_key_release(w, d, e, b)
|
||||
Widget w;
|
||||
XtPointer d;
|
||||
XEvent *e;
|
||||
Boolean *b;
|
||||
{
|
||||
int shift = (ShiftMask & e->xkey.state) != 0;
|
||||
KeySym key = XKeycodeToKeysym( dpy, e->xkey.keycode, shift );
|
||||
|
||||
/*printf("key %d up\n", key); fflush(stdout);*/
|
||||
if ((key & 0xff00) == 0)
|
||||
display_keyup(key);
|
||||
|
||||
if (b)
|
||||
*b = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_exposure(w, d, e, b)
|
||||
Widget w;
|
||||
XtPointer d;
|
||||
XEvent *e;
|
||||
Boolean *b;
|
||||
{
|
||||
display_repaint();
|
||||
|
||||
if (b)
|
||||
*b = TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
ws_init(char *crtname, /* crt type name */
|
||||
int xp, int yp, /* screen size in pixels */
|
||||
int colors) /* colors to support (not used) */
|
||||
{
|
||||
Arg arg[25];
|
||||
XGCValues gcvalues;
|
||||
unsigned int n;
|
||||
int argc;
|
||||
char *argv[1];
|
||||
int height, width;
|
||||
|
||||
xpixels = xp; /* save screen size */
|
||||
ypixels = yp;
|
||||
|
||||
XtToolkitInitialize();
|
||||
app_context = XtCreateApplicationContext();
|
||||
argc = 0;
|
||||
argv[0] = NULL;
|
||||
dpy = XtOpenDisplay( app_context, NULL, NULL, crtname, NULL, 0,
|
||||
&argc, argv);
|
||||
|
||||
scr = DefaultScreen(dpy);
|
||||
|
||||
crtshell = XtAppCreateShell( crtname, /* app name */
|
||||
crtname, /* app class */
|
||||
#ifdef NO_BORDER
|
||||
overrideShellWidgetClass,
|
||||
#else
|
||||
applicationShellWidgetClass, /* wclass */
|
||||
#endif
|
||||
dpy, /* display */
|
||||
NULL, /* arglist */
|
||||
0); /* nargs */
|
||||
|
||||
cmap = DefaultColormap(dpy, scr);
|
||||
|
||||
/*
|
||||
* Create a drawing area
|
||||
*/
|
||||
|
||||
n = 0;
|
||||
#ifdef FULL_SCREEN
|
||||
/* center raster in full-screen black window */
|
||||
width = DisplayWidth(dpy,scr);
|
||||
height = DisplayHeight(dpy,scr);
|
||||
|
||||
xoffset = (width - xpixels*PIX_SIZE)/2;
|
||||
yoffset = (height - ypixels*PIX_SIZE)/2;
|
||||
#else
|
||||
width = xpixels*PIX_SIZE;
|
||||
height = ypixels*PIX_SIZE;
|
||||
#endif
|
||||
XtSetArg(arg[n], XtNwidth, width); n++;
|
||||
XtSetArg(arg[n], XtNheight, height); n++;
|
||||
XtSetArg(arg[n], XtNbackground, BlackPixel( dpy, scr )); n++;
|
||||
|
||||
crt = XtCreateWidget( crtname, widgetClass, crtshell, arg, n);
|
||||
XtManageChild(crt);
|
||||
XtPopup(crtshell, XtGrabNonexclusive);
|
||||
|
||||
/*
|
||||
* Create black and white Graphics Contexts
|
||||
*/
|
||||
|
||||
gcvalues.foreground = BlackPixel( dpy, scr );
|
||||
gcvalues.background = BlackPixel( dpy, scr );
|
||||
blackGC = XCreateGC(dpy, XtWindow(crt),
|
||||
GCForeground | GCBackground, &gcvalues);
|
||||
|
||||
gcvalues.foreground = WhitePixel( dpy, scr );
|
||||
whiteGC = XCreateGC(dpy, XtWindow(crt),
|
||||
GCForeground | GCBackground, &gcvalues);
|
||||
|
||||
#ifndef NO_CURSOR
|
||||
if (!display_tablet) {
|
||||
/* pencil cursor */
|
||||
XDefineCursor(dpy, XtWindow(crt),
|
||||
(Cursor) XCreateFontCursor(dpy, XC_pencil));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup to handle events
|
||||
*/
|
||||
|
||||
XtAddEventHandler(crt, ButtonPressMask|ButtonMotionMask, FALSE,
|
||||
handle_button_press, NULL);
|
||||
XtAddEventHandler(crt, ButtonReleaseMask, FALSE,
|
||||
handle_button_release, NULL);
|
||||
XtAddEventHandler(crt, KeyPressMask, FALSE,
|
||||
handle_key_press, NULL);
|
||||
XtAddEventHandler(crt, KeyReleaseMask, FALSE,
|
||||
handle_key_release, NULL);
|
||||
XtAddEventHandler(crt, ExposureMask, FALSE,
|
||||
handle_exposure, NULL);
|
||||
return 1;
|
||||
} /* ws_init */
|
||||
|
||||
|
||||
/* Added 2006-07-19 SAI */
|
||||
|
||||
void ws_close(void)
|
||||
{
|
||||
|
||||
XtCloseDisplay(dpy);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ws_color_black(void)
|
||||
{
|
||||
return blackGC;
|
||||
}
|
||||
|
||||
void *
|
||||
ws_color_white(void)
|
||||
{
|
||||
return whiteGC;
|
||||
}
|
||||
|
||||
void *
|
||||
ws_color_rgb(int r, int g, int b)
|
||||
{
|
||||
XColor color;
|
||||
|
||||
color.red = r;
|
||||
color.green = g;
|
||||
color.blue = b;
|
||||
/* ignores flags */
|
||||
|
||||
if (XAllocColor(dpy, cmap, &color)) {
|
||||
XGCValues gcvalues;
|
||||
memset(&gcvalues, 0, sizeof(gcvalues));
|
||||
gcvalues.foreground = gcvalues.background = color.pixel;
|
||||
return XCreateGC(dpy, XtWindow(crt),
|
||||
GCForeground | GCBackground,
|
||||
&gcvalues);
|
||||
}
|
||||
/* allocation failed */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* put a point on the screen */
|
||||
void
|
||||
ws_display_point(int x, int y, void *color)
|
||||
{
|
||||
GC gc = (GC) color;
|
||||
|
||||
if (x > xpixels || y > ypixels)
|
||||
return;
|
||||
|
||||
y = ypixels - y - 1; /* X11 coordinate system */
|
||||
|
||||
#ifdef FULL_SCREEN
|
||||
x += xoffset;
|
||||
y += yoffset;
|
||||
#endif
|
||||
if (gc == NULL)
|
||||
gc = blackGC; /* default to off */
|
||||
#if PIX_SIZE == 1
|
||||
XDrawPoint(dpy, XtWindow(crt), gc, x, y);
|
||||
#else
|
||||
XFillRectangle(dpy, XtWindow(crt), gc,
|
||||
x*PIX_SIZE, y*PIX_SIZE, PIX_SIZE, PIX_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ws_sync(void)
|
||||
{
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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! */
|
||||
|
||||
#ifdef WS_POLL_DEBUG
|
||||
printf("ws_poll %d\n", maxusec);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
elapsed(&es); /* start clock */
|
||||
do {
|
||||
unsigned long e;
|
||||
|
||||
/* tried checking return, but lost on TCP connections? */
|
||||
os_pollfd(ConnectionNumber(dpy), maxusec);
|
||||
|
||||
while (XtAppPending(app_context)) {
|
||||
XEvent event;
|
||||
|
||||
/* XXX check for connection loss; set *valp? return 0 */
|
||||
XtAppNextEvent(app_context, &event );
|
||||
XtDispatchEvent( &event );
|
||||
}
|
||||
e = elapsed(&es);
|
||||
#ifdef WS_POLL_DEBUG
|
||||
printf(" maxusec %d e %d\r\n", maxusec, e);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
maxusec -= e;
|
||||
} while (maxusec > 10000); /* 10ms */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* utility: can be called from main program
|
||||
* which is willing to cede control
|
||||
*/
|
||||
int
|
||||
ws_loop(void (*func)(void *), void *arg)
|
||||
{
|
||||
int val;
|
||||
|
||||
/* XXX use XtAppAddWorkProc & XtAppMainLoop? */
|
||||
while (ws_poll(&val,0))
|
||||
(*func)(arg);
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
ws_beep(void)
|
||||
{
|
||||
XBell(dpy, 0); /* ring at base volume */
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
/****************
|
||||
* could move these to unix.c, if VMS versions needed
|
||||
* (or just (GASP!) ifdef)
|
||||
*/
|
||||
|
||||
/* public version, used by delay code */
|
||||
unsigned long
|
||||
os_elapsed(void)
|
||||
{
|
||||
static struct elapsed_state es;
|
||||
return elapsed(&es);
|
||||
}
|
||||
|
||||
/*
|
||||
* select/DisplayNumber works on VMS 7.0+?
|
||||
* could move to "unix.c"
|
||||
* (I have some nasty VMS code that's supposed to to the job
|
||||
* for older systems)
|
||||
*/
|
||||
|
||||
/*
|
||||
* sleep for maxus microseconds, returning TRUE sooner if fd is readable
|
||||
* used by X11 driver
|
||||
*/
|
||||
static int
|
||||
os_pollfd(int fd, int maxus)
|
||||
{
|
||||
|
||||
/* use trusty old select (most portable) */
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
|
||||
if (maxus >= 1000000) { /* not bloody likely, avoid divide */
|
||||
tv.tv_sec = maxus / 1000000;
|
||||
tv.tv_usec = maxus % 1000000;
|
||||
}
|
||||
else {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = maxus;
|
||||
}
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
return select(fd+1, &rfds, NULL, NULL, &tv) > 0;
|
||||
}
|
||||
Reference in New Issue
Block a user