DISPLAY: Update display code to support DEC Type 340, and 36 switches
Only interface code to Type 340 is for Richard Cornwell's KA10 (but could be used on PDP-1/4/7/9 as well)
This commit is contained in:
parent
c05190780b
commit
b11fbf6cd4
12 changed files with 1260 additions and 260 deletions
|
@ -1704,15 +1704,16 @@ return SCPE_OK;
|
||||||
|
|
||||||
#ifdef USE_DISPLAY
|
#ifdef USE_DISPLAY
|
||||||
/* set "test switches"; from display code */
|
/* set "test switches"; from display code */
|
||||||
|
#include "display/display.h" /* prototypes */
|
||||||
|
|
||||||
void cpu_set_switches(unsigned long bits)
|
void cpu_set_switches(unsigned long v1, unsigned long v2)
|
||||||
{
|
{
|
||||||
/* just what we want; smaller CPUs might want to shift down? */
|
TW = v1 ^ v2;
|
||||||
TW = bits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long cpu_get_switches(void)
|
void cpu_get_switches(unsigned long *p1, unsigned long *p2)
|
||||||
{
|
{
|
||||||
return TW;
|
*p1 = TW;
|
||||||
|
*p2 = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -545,15 +545,16 @@ int32 SR; /* switch register */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
cpu_set_switches(unsigned long val)
|
cpu_set_switches(unsigned long v1, unsigned long v2)
|
||||||
{
|
{
|
||||||
SR = val;
|
SR = v1 ^ v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
void
|
||||||
cpu_get_switches(void)
|
cpu_get_switches(unsigned long *p1, unsigned long *p2)
|
||||||
{
|
{
|
||||||
return SR;
|
*p1 = SR;
|
||||||
|
*p2 = 0;
|
||||||
}
|
}
|
||||||
#else /* USE_DISPLAY not defined */
|
#else /* USE_DISPLAY not defined */
|
||||||
char pdp11_vt_unused; /* sometimes empty object modules cause problems */
|
char pdp11_vt_unused; /* sometimes empty object modules cause problems */
|
||||||
|
|
|
@ -1193,18 +1193,22 @@ for (k = 0; k < lnt; k++) { /* print specified */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_DISPLAY
|
||||||
|
#include "display/display.h" /* prototypes */
|
||||||
|
|
||||||
/* set "test switches"; from display code */
|
/* set "test switches"; from display code */
|
||||||
void
|
void
|
||||||
cpu_set_switches(unsigned long bits)
|
cpu_set_switches(unsigned long v1, unsigned long v2)
|
||||||
{
|
{
|
||||||
/* just what we want; smaller CPUs might want to shift down? */
|
/* just what we want; smaller CPUs might want to shift down? */
|
||||||
TAC = bits;
|
TAC = v1 ^ v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long
|
void
|
||||||
cpu_get_switches(void)
|
cpu_get_switches(unsigned long *p1, unsigned long *p2)
|
||||||
{
|
{
|
||||||
return TAC;
|
*p1 = TAC;
|
||||||
|
*p2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) {
|
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) {
|
||||||
|
|
13
display/Makefile.340
Normal file
13
display/Makefile.340
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# Makefile for type340 test/debug
|
||||||
|
|
||||||
|
ALL=tdbg tx
|
||||||
|
all: $(ALL)
|
||||||
|
|
||||||
|
tdbg: tst340.c type340.c Makefile.340 type340.h type340cmd.h
|
||||||
|
cc -g -o tdbg tst340.c type340.c -DTY340_NODISPLAY -DDEBUG_TY340 -DDUMP
|
||||||
|
|
||||||
|
tx: tst340.c type340.c display.c x11.c Makefile.340 ws.h type340.h type340cmd.h display.h
|
||||||
|
cc -g -o tx tst340.c type340.c display.c x11.c -lm -lX11 -lXt -DDUMP
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(ALL)
|
|
@ -13,7 +13,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2004, Philip L. Budne
|
* Copyright (c) 2003-2018 Philip L. Budne
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -132,7 +132,6 @@ static struct display displays[] = {
|
||||||
/*
|
/*
|
||||||
* TX-0
|
* TX-0
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* Unknown manufacturer
|
* Unknown manufacturer
|
||||||
*
|
*
|
||||||
* 12" tube,
|
* 12" tube,
|
||||||
|
@ -140,8 +139,6 @@ static struct display displays[] = {
|
||||||
* 50us point plot time (20,000 points/sec)
|
* 50us point plot time (20,000 points/sec)
|
||||||
* P17 Phosphor??? Two phosphor layers:
|
* P17 Phosphor??? Two phosphor layers:
|
||||||
* fast blue (.05s half life), and slow green (.2s half life)
|
* fast blue (.05s half life), and slow green (.2s half life)
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
{ DIS_TX0, "MIT TX-0", &color_p17, NULL, 512, 512 },
|
{ DIS_TX0, "MIT TX-0", &color_p17, NULL, 512, 512 },
|
||||||
|
|
||||||
|
@ -216,8 +213,9 @@ static struct display displays[] = {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Type 340 Display system
|
* Type 340 Display system
|
||||||
* on PDP-4/6/7/9/10
|
* on PDP-1/4/6/7/9/10
|
||||||
*
|
*
|
||||||
|
* Raytheon 16ADP7A CRT, same as Type 30
|
||||||
* 1024x1024
|
* 1024x1024
|
||||||
* 9 3/8" raster (.01" dot pitch)
|
* 9 3/8" raster (.01" dot pitch)
|
||||||
* 0,0 at lower left
|
* 0,0 at lower left
|
||||||
|
@ -989,15 +987,12 @@ display_scale(void)
|
||||||
/*
|
/*
|
||||||
* handle keyboard events
|
* handle keyboard events
|
||||||
*
|
*
|
||||||
* data switches; 18 -- enough for PDP-1/4/7/9/15 (for munching squares!)
|
* data switches: bit toggled on key up, all cleared on space
|
||||||
|
* enough for PDP-1/4/7/9/15 (for munching squares!):
|
||||||
* 123 456 789 qwe rty uio
|
* 123 456 789 qwe rty uio
|
||||||
* bit toggled on key up
|
|
||||||
* all cleared on space
|
|
||||||
*
|
*
|
||||||
* spacewar switches; bit high as long as key down
|
* second set of 18 for PDP-6/10, IBM7xxx (shifted versions of above):
|
||||||
* asdf kl;'
|
* !@# $%^ &*( QWE RTY UIO
|
||||||
* just where PDP-1 spacewar expects them!
|
|
||||||
* key mappings same as MIT Media Lab Java PDP-1 simulator
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
unsigned long spacewar_switches = 0;
|
unsigned long spacewar_switches = 0;
|
||||||
|
@ -1006,15 +1001,13 @@ unsigned long spacewar_switches = 0;
|
||||||
void
|
void
|
||||||
display_keydown(int k)
|
display_keydown(int k)
|
||||||
{
|
{
|
||||||
|
/*printf("down '%c'\r\n", k); /**/
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case 'f': case 'F': spacewar_switches |= 01; break; /* torpedos */
|
/* handle spacewar switches: see display.h for copious commentary */
|
||||||
case 'd': case 'D': spacewar_switches |= 02; break; /* engines */
|
#define SWSW(LC,UC,BIT,POS36,FUNC36) \
|
||||||
case 'a': case 'A': spacewar_switches |= 04; break; /* rotate R */
|
case LC: case UC: spacewar_switches |= BIT; return;
|
||||||
case 's': case 'S': spacewar_switches |= 010; break; /* rotate L */
|
SPACEWAR_SWITCHES
|
||||||
case '\'': case '"': spacewar_switches |= 040000; break; /* torpedos */
|
#undef SWSW
|
||||||
case ';': case ':': spacewar_switches |= 0100000; break; /* engines */
|
|
||||||
case 'k': case 'K': spacewar_switches |= 0200000; break; /* rotate R */
|
|
||||||
case 'l': case 'L': spacewar_switches |= 0400000; break; /* rotate L */
|
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1023,19 +1016,16 @@ display_keydown(int k)
|
||||||
void
|
void
|
||||||
display_keyup(int k)
|
display_keyup(int k)
|
||||||
{
|
{
|
||||||
unsigned long test_switches = cpu_get_switches();
|
unsigned long test_switches, test_switches2;
|
||||||
|
|
||||||
/* fetch console switches from simulator? */
|
cpu_get_switches(&test_switches, &test_switches2);
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case 'f': case 'F': spacewar_switches &= ~01; return;
|
/* handle spacewar switches: see display.h for copious commentary */
|
||||||
case 'd': case 'D': spacewar_switches &= ~02; return;
|
#define SWSW(LC,UC,BIT,POS36,NAME36) \
|
||||||
case 'a': case 'A': spacewar_switches &= ~04; return;
|
case LC: case UC: spacewar_switches &= ~BIT; return;
|
||||||
case 's': case 'S': spacewar_switches &= ~010; return;
|
|
||||||
|
|
||||||
case '\'': case '"': spacewar_switches &= ~040000; return;
|
SPACEWAR_SWITCHES
|
||||||
case ';': case ':': spacewar_switches &= ~0100000; return;
|
#undef SWSW
|
||||||
case 'k': case 'K': spacewar_switches &= ~0200000; return;
|
|
||||||
case 'l': case 'L': spacewar_switches &= ~0400000; return;
|
|
||||||
|
|
||||||
case '1': test_switches ^= 1<<17; break;
|
case '1': test_switches ^= 1<<17; break;
|
||||||
case '2': test_switches ^= 1<<16; break;
|
case '2': test_switches ^= 1<<16; break;
|
||||||
|
@ -1049,20 +1039,45 @@ display_keyup(int k)
|
||||||
case '8': test_switches ^= 1<<10; break;
|
case '8': test_switches ^= 1<<10; break;
|
||||||
case '9': test_switches ^= 1<<9; break;
|
case '9': test_switches ^= 1<<9; break;
|
||||||
|
|
||||||
case 'q': case 'Q': test_switches ^= 1<<8; break;
|
case 'q': test_switches ^= 1<<8; break;
|
||||||
case 'w': case 'W': test_switches ^= 1<<7; break;
|
case 'w': test_switches ^= 1<<7; break;
|
||||||
case 'e': case 'E': test_switches ^= 1<<6; break;
|
case 'e': test_switches ^= 1<<6; break;
|
||||||
|
|
||||||
case 'r': case 'R': test_switches ^= 1<<5; break;
|
case 'r': test_switches ^= 1<<5; break;
|
||||||
case 't': case 'T': test_switches ^= 1<<4; break;
|
case 't': test_switches ^= 1<<4; break;
|
||||||
case 'y': case 'Y': test_switches ^= 1<<3; break;
|
case 'y': test_switches ^= 1<<3; break;
|
||||||
|
|
||||||
case 'u': case 'U': test_switches ^= 1<<2; break;
|
case 'u': test_switches ^= 1<<2; break;
|
||||||
case 'i': case 'I': test_switches ^= 1<<1; break;
|
case 'i': test_switches ^= 1<<1; break;
|
||||||
case 'o': case 'O': test_switches ^= 1; break;
|
case 'o': test_switches ^= 1; break;
|
||||||
|
|
||||||
case ' ': test_switches = 0; break;
|
/* second set of 18 switches */
|
||||||
|
case '!': test_switches2 ^= 1<<17; break;
|
||||||
|
case '@': test_switches2 ^= 1<<16; break;
|
||||||
|
case '#': test_switches2 ^= 1<<15; break;
|
||||||
|
|
||||||
|
case '$': test_switches2 ^= 1<<14; break;
|
||||||
|
case '%': test_switches2 ^= 1<<13; break;
|
||||||
|
case '^': test_switches2 ^= 1<<12; break;
|
||||||
|
|
||||||
|
case '&': test_switches2 ^= 1<<11; break;
|
||||||
|
case '*': test_switches2 ^= 1<<10; break;
|
||||||
|
case '(': test_switches2 ^= 1<<9; break;
|
||||||
|
|
||||||
|
case 'Q': test_switches2 ^= 1<<8; break;
|
||||||
|
case 'W': test_switches2 ^= 1<<7; break;
|
||||||
|
case 'E': test_switches2 ^= 1<<6; break;
|
||||||
|
|
||||||
|
case 'R': test_switches2 ^= 1<<5; break;
|
||||||
|
case 'T': test_switches2 ^= 1<<4; break;
|
||||||
|
case 'Y': test_switches2 ^= 1<<3; break;
|
||||||
|
|
||||||
|
case 'U': test_switches2 ^= 1<<2; break;
|
||||||
|
case 'I': test_switches2 ^= 1<<1; break;
|
||||||
|
case 'O': test_switches2 ^= 1; break;
|
||||||
|
|
||||||
|
case ' ': test_switches = test_switches2 = 0; break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
cpu_set_switches(test_switches);
|
cpu_set_switches(test_switches, test_switches2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2004, Philip L. Budne
|
* Copyright (c) 2003-2018, Philip L. Budne
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -37,11 +37,15 @@
|
||||||
* known display types
|
* known display types
|
||||||
*/
|
*/
|
||||||
enum display_type {
|
enum display_type {
|
||||||
|
/*
|
||||||
|
* Give TX-0 the rightful spot as the progenitor
|
||||||
|
* of the PDP-1, and thus all DEC machines.
|
||||||
|
*/
|
||||||
|
DIS_TX0 = 0,
|
||||||
DIS_VR14 = 14,
|
DIS_VR14 = 14,
|
||||||
DIS_VR17 = 17,
|
DIS_VR17 = 17,
|
||||||
DIS_VR20 = 20,
|
DIS_VR20 = 20,
|
||||||
DIS_TYPE30 = 30,
|
DIS_TYPE30 = 30,
|
||||||
DIS_TX0 = 33,
|
|
||||||
DIS_VR48 = 48,
|
DIS_VR48 = 48,
|
||||||
DIS_TYPE340 = 340
|
DIS_TYPE340 = 340
|
||||||
};
|
};
|
||||||
|
@ -86,7 +90,7 @@ extern int display_age(int,int);
|
||||||
#define DISPLAY_INT_MIN 0 /* lowest "on" level */
|
#define DISPLAY_INT_MIN 0 /* lowest "on" level */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* plot a point; argumen ts are x, y, intensity, color (0/1)
|
* plot a point; arguments are x, y, intensity, color (0/1)
|
||||||
* returns true if light pen active (mouse button down)
|
* returns true if light pen active (mouse button down)
|
||||||
* at (or very near) this location.
|
* at (or very near) this location.
|
||||||
*
|
*
|
||||||
|
@ -119,10 +123,78 @@ extern void display_lp_radius(int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set by simulated spacewar switch box switches
|
* set by simulated spacewar switch box switches
|
||||||
* 18 bits (only high 4 and low 4 used)
|
* bits high as long as key down
|
||||||
|
*
|
||||||
|
* asdf kl;'
|
||||||
|
* bits just where PDP-1 spacewar expects them!
|
||||||
|
* key mappings same as MIT Media Lab Java PDP-1 simulator
|
||||||
|
*
|
||||||
|
* PDP-6/10 SPCWAR adds hyperspace button, two more players.
|
||||||
|
* All additional bits above PDP-1 18-bit word.
|
||||||
*/
|
*/
|
||||||
extern unsigned long spacewar_switches;
|
extern unsigned long spacewar_switches;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* spacewar_switches fruit salad:
|
||||||
|
*
|
||||||
|
* the low 18 bits spacewar_swiches (a 32-bit int)
|
||||||
|
* are the switches for PDP-1 spacewar (four at either end)
|
||||||
|
* where the game expects them.
|
||||||
|
*
|
||||||
|
* Additional bits for the PDP-6/10 game are in the upper 14 bits:
|
||||||
|
* existing (top player) hyperspace buttons in the top two bits,
|
||||||
|
* and bottom players in two 6-bit bytes
|
||||||
|
*
|
||||||
|
* Too much mess to have in three places (display.c key up/down and
|
||||||
|
* the PDP-10 interface code), so I'm using a common idiom from the PDP-10
|
||||||
|
* world: define a macro that expands to multiple macro invocations
|
||||||
|
* and redefine the inner macro as needed before expanding the outer macro.
|
||||||
|
*
|
||||||
|
* I have little/no expectation that this is actually playable, but
|
||||||
|
* you could rig up an AVR (or other USB MCU) with switch boxes to
|
||||||
|
* look like a USB HID keyboard. For full historical accuracy, please
|
||||||
|
* use wooden controllers!
|
||||||
|
*
|
||||||
|
* Phil Budne Feb 2018
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* SWSW (SpaceWar SWitch) macro args:
|
||||||
|
* LC: lower case key
|
||||||
|
* UC: upper case key
|
||||||
|
* BIT: bit in spacewar_switches (1 means switch on)
|
||||||
|
* yes, 32-bit int bits expressed in octal
|
||||||
|
* (which is just like decimal, if you're missing two fingers)
|
||||||
|
* POS: user in PDP-6/10 parlance Upper/Lower Left/Right
|
||||||
|
* FUNC: function name in PDP-6/10 parlance (FIRE means beam or torpedo)
|
||||||
|
* comment is meaning in PDP-1 parlance
|
||||||
|
*
|
||||||
|
* entries in order of PDP-1 function bit order
|
||||||
|
*/
|
||||||
|
#define SPACEWAR_SWITCHES \
|
||||||
|
SWSW('f', 'F', 01, UL, FIRE) /* torpedos */ \
|
||||||
|
SWSW('d', 'D', 02, UL, THRUST) /* engines */ \
|
||||||
|
SWSW('a', 'A', 04, UL, CW) /* rotate R */ \
|
||||||
|
SWSW('s', 'S', 010, UL, CCW) /* rotate L */ \
|
||||||
|
SWSW('g', 'G', 010000000000, UL, HYPER) /* PDP-6/10 hyperspace */ \
|
||||||
|
\
|
||||||
|
SWSW('\'', '"', 040000, UR, FIRE) /* torpedos */ \
|
||||||
|
SWSW(';', ':', 0100000, UR, THRUST) /* engines */ \
|
||||||
|
SWSW('k', 'K', 0200000, UR, CW) /* rotate R */ \
|
||||||
|
SWSW('l', 'L', 0400000, UR, CCW) /* rotate L */ \
|
||||||
|
SWSW('\r','\n',020000000000, UR, HYPER) /* PDP-6/10 hyperspace */ \
|
||||||
|
\
|
||||||
|
SWSW('v', 'V', 01000000, LL, FIRE) /* torpedos */ \
|
||||||
|
SWSW('c', 'C', 02000000, LL, THRUST) /* engines */ \
|
||||||
|
SWSW('z', 'Z', 04000000, LL, CW) /* rotate R */ \
|
||||||
|
SWSW('x', 'X', 010000000, LL, CCW) /* rotate L */ \
|
||||||
|
SWSW('b', 'B', 020000000, LL, HYPER) /* hyperspace */ \
|
||||||
|
\
|
||||||
|
SWSW('.', '>', 0100000000, LR, FIRE) /* torpedos */ \
|
||||||
|
SWSW(',', '<', 0200000000, LR, THRUST) /* engines */ \
|
||||||
|
SWSW('n', 'N', 0400000000, LR, CW) /* rotate R */ \
|
||||||
|
SWSW('m', 'M', 01000000000, LR, CCW) /* rotate L */ \
|
||||||
|
SWSW('/', '?', 02000000000, LR, HYPER) /* hyperspace */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* light pen "tip switch" activated (for VS60 emulation etc.)
|
* light pen "tip switch" activated (for VS60 emulation etc.)
|
||||||
* should only be set from "driver" (window system layer)
|
* should only be set from "driver" (window system layer)
|
||||||
|
@ -138,7 +210,7 @@ extern unsigned char display_tablet;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* users of this library are expected to provide these calls.
|
* users of this library are expected to provide these calls.
|
||||||
* simulator will set 18 simulated switches.
|
* simulator will set up to 36 simulated switches.
|
||||||
*/
|
*/
|
||||||
extern unsigned long cpu_get_switches(void); /* get current switch state */
|
extern void cpu_get_switches(unsigned long *p1, unsigned long *p2);
|
||||||
extern void cpu_set_switches(unsigned long); /* set switches */
|
extern void cpu_set_switches(unsigned long, unsigned long);
|
||||||
|
|
368
display/tst340.c
Normal file
368
display/tst340.c
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
/*
|
||||||
|
* debug output, no display:
|
||||||
|
* cc -g -o tst340 tst340.c type340.c -DTY340_NODISPLAY -DDEBUG_TY340
|
||||||
|
*
|
||||||
|
* w/ display:
|
||||||
|
* cc -g -o tst340 tst340.c type340.c display.c x11.c -lm -lX11 -lXt
|
||||||
|
*/
|
||||||
|
|
||||||
|
// possible source of test code
|
||||||
|
// light pen diag:
|
||||||
|
// http://bitsavers.informatik.uni-stuttgart.de/pdf/dec/pdp7/DIGITAL-7-78-M_370LightPenDiag_Apr64.pdf
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "display.h"
|
||||||
|
#include "type340.h"
|
||||||
|
#include "type340cmd.h"
|
||||||
|
|
||||||
|
void dump(int *ip);
|
||||||
|
|
||||||
|
int words[] = {
|
||||||
|
#if 0
|
||||||
|
// 11sim!
|
||||||
|
020154,
|
||||||
|
0221000,
|
||||||
|
0120000,
|
||||||
|
0600001,
|
||||||
|
020000,
|
||||||
|
0220000,
|
||||||
|
0121000,
|
||||||
|
0600400,
|
||||||
|
03000
|
||||||
|
#elif 1
|
||||||
|
// p budne: character test
|
||||||
|
MPT, /* param: point mode */
|
||||||
|
MPT|H|0, /* point: h=0; point mode */
|
||||||
|
MPAR|V|512, /* point: v=64; par mode */
|
||||||
|
MCHR|S3|IN7, /* param: chr mode, size 3, intensity 7 */
|
||||||
|
CHAR('H'-'@', 'E'-'@', 'L'-'@'),
|
||||||
|
CHAR('L'-'@', 'O'-'@', ' '),
|
||||||
|
CHAR('W'-'@', 'O'-'@', 'R'-'@'),
|
||||||
|
CHAR('L'-'@', 'D'-'@', '!'),
|
||||||
|
CHAR(' ', 0, 037),
|
||||||
|
MCHR|S2|IN7, /* param: chr mode, size 2, intensity 7 */
|
||||||
|
CHAR(CHRCR, CHRLF, 'H'-'@'),
|
||||||
|
CHAR('E'-'@', 'L'-'@', 'L'-'@'),
|
||||||
|
CHAR('O'-'@', ' ', 'W'-'@'),
|
||||||
|
CHAR('O'-'@', 'R'-'@', 'L'-'@'),
|
||||||
|
CHAR('D'-'@', '!', CHRESC),
|
||||||
|
MCHR|S1|IN7, /* param: chr mode, size 1, intensity 7 */
|
||||||
|
CHAR(CHRCR, CHRLF, 'H'-'@'),
|
||||||
|
CHAR('E'-'@', 'L'-'@', 'L'-'@'),
|
||||||
|
CHAR('O'-'@', ' ', 'W'-'@'),
|
||||||
|
CHAR('O'-'@', 'R'-'@', 'L'-'@'),
|
||||||
|
CHAR('D'-'@', '!', CHRESC),
|
||||||
|
|
||||||
|
MCHR|S0|IN2, /* param: chr mode, size 0, intensity 2 */
|
||||||
|
CHAR(CHRUC, CHRCR, CHRLF),
|
||||||
|
CHAR(000, 001, 002), CHAR(003, 004, 005), CHAR(006, 007, ' '),
|
||||||
|
CHAR(010, 011, 012), CHAR(013, 014, 015), CHAR(016, 017, ' '),
|
||||||
|
CHAR(020, 021, 022), CHAR(023, 024, 025), CHAR(026, 027, ' '),
|
||||||
|
CHAR(030, 031, 032), /* 33-37 are control codes */
|
||||||
|
CHAR(040, 041, 042), CHAR(043, 044, 045), CHAR(046, 047, ' '),
|
||||||
|
CHAR(050, 051, 052), CHAR(053, 054, 055), CHAR(056, 057, ' '),
|
||||||
|
CHAR(060, 061, 062), CHAR(063, 064, 065), CHAR(066, 067, ' '),
|
||||||
|
CHAR(070, 071, 072), CHAR(073, 074, 075), CHAR(076, 077, ' '),
|
||||||
|
|
||||||
|
CHAR(CHRLC, CHRCR, CHRLF),
|
||||||
|
CHAR(000, 001, 002), CHAR(003, 004, 005), CHAR(006, 007, ' '),
|
||||||
|
CHAR(010, 011, 012), CHAR(013, 014, 015), CHAR(016, 017, ' '),
|
||||||
|
CHAR(020, 021, 022), CHAR(023, 024, 025), CHAR(026, 027, ' '),
|
||||||
|
CHAR(030, 031, 032), /* 33-37 are control codes */
|
||||||
|
CHAR(040, 041, 042), CHAR(043, 044, 045), CHAR(046, 047, ' '),
|
||||||
|
CHAR(050, 051, 052), CHAR(053, 054, 055), CHAR(056, 057, ' '),
|
||||||
|
CHAR(060, 061, 062), CHAR(063, 064, 065), CHAR(066, 067, ' '),
|
||||||
|
CHAR(070, 071, 072), CHAR(073, 074, 075), CHAR(076, 077, ' '),
|
||||||
|
CHAR(CHRESC, 0, 0),
|
||||||
|
STP
|
||||||
|
#elif 1
|
||||||
|
/*
|
||||||
|
030153: PT LPOFF S2 IN3
|
||||||
|
221000: PT V 512.
|
||||||
|
103000: VCT IP H 512.
|
||||||
|
703100: ESCP INSFY DN YP4 YP2 RT XP64
|
||||||
|
140000: INCR
|
||||||
|
304210: INSFY INCRPT( PR, PR, PR, PR)
|
||||||
|
325063: INSFY INCRPT( PUR, PUR, PD, PD)
|
||||||
|
631777: ESCP INSFY INCRPT( PD, PD, PDL, PDL)
|
||||||
|
100000: VCT
|
||||||
|
600210: ESCP INSFY LT XP8
|
||||||
|
140000: INCR
|
||||||
|
237463: INSFY INCRPT( PD, PDL, PD, PD)
|
||||||
|
231673: INSFY INCRPT( PD, PD, PDR, PDR)
|
||||||
|
704210: ESCP INSFY INCRPT( PR, PR, PR, PR)
|
||||||
|
100000: VCT
|
||||||
|
203400: INSFY UP YP4 YP2 YP1
|
||||||
|
600203: ESCP INSFY LT XP2 XP1
|
||||||
|
140000: INCR
|
||||||
|
377463: INSFY INCRPT( PDL, PDL, PD, PD)
|
||||||
|
631273: ESCP INSFY INCRPT( PD, PU, PDR, PDR)
|
||||||
|
002000: PAR STOP
|
||||||
|
*/
|
||||||
|
// H-340_Type_340_Precision_Incremental_CRT_System_Nov64.pdf
|
||||||
|
MPT|LPON|S2|IN3, // 0030133, /* set params */
|
||||||
|
MPT|V|512, // 0220000, /* y axis */
|
||||||
|
MVCT|H|IP|512, // 0103760, /* x axis, draw line */
|
||||||
|
ESCP|INSFY|DN|YP4|YP2|XP64, // 0703100, /* draw curve */
|
||||||
|
MINCR, // 0140000, /* set mode */
|
||||||
|
INSFY|INCRPT(PR,PR,PR,PR), // 0304210, /* draw curve */
|
||||||
|
INSFY|INCRPT(PUR,PUR,PD,PD), // 0325063, /* draw curve */
|
||||||
|
ESCP|INSFY|INCRPT(PD,PD,PDL,PDL), // 0631777,
|
||||||
|
MVCT, // 0100000, /* set mode */
|
||||||
|
ESCP|INSFY|LT|XP8, // 0600210, /* draw line */
|
||||||
|
MINCR, // 0140000, /* set mode */
|
||||||
|
0237463, /* draw curve */
|
||||||
|
0231673, /* draw curve */
|
||||||
|
0704210, /* draw curve */
|
||||||
|
0100000, /* set mode */
|
||||||
|
0203400, /* draw line */
|
||||||
|
0600203, /* draw line */
|
||||||
|
0140000, /* set mode */
|
||||||
|
0377463, /* draw curve */
|
||||||
|
0631273, /* draw curve */
|
||||||
|
#if 0
|
||||||
|
#endif
|
||||||
|
0002000, /* stop, set done, send data interrupt */
|
||||||
|
#else
|
||||||
|
// ITS SYSTEM;DDT > @ RECYC
|
||||||
|
0020157,
|
||||||
|
0261777
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main() {
|
||||||
|
#ifdef DUMP
|
||||||
|
dump(words);
|
||||||
|
#endif
|
||||||
|
for (;;) {
|
||||||
|
ty340_reset();
|
||||||
|
for (unsigned i = 0; i < sizeof(words)/sizeof(words[0]); i++) {
|
||||||
|
#ifdef TY340_NODISPLAY
|
||||||
|
putchar('\n');
|
||||||
|
#endif
|
||||||
|
int s = ty340_instruction(words[i]);
|
||||||
|
#ifdef TY340_NODISPLAY
|
||||||
|
printf(" status %#o\n", s);
|
||||||
|
#endif
|
||||||
|
if (s & ST340_STOPPED)
|
||||||
|
break;
|
||||||
|
/* XXX check for LPHIT? fetch coordinates */
|
||||||
|
}
|
||||||
|
#ifdef TY340_NODISPLAY
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
display_age(1000, 1);
|
||||||
|
display_sync();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ty340word
|
||||||
|
ty340_fetch(ty340word addr) {
|
||||||
|
printf("ty340_fetch %#o\n", addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ty340_store(ty340word addr, ty340word value) {
|
||||||
|
printf("ty340_store %#o %#o\n", addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ty340_cond_int(ty340word status) {
|
||||||
|
/*printf("ty340_stop_int\n");*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ty340_lp_int(ty340word x, ty340word y) {
|
||||||
|
printf("ty340_lp_int %d. %d.\n", x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ty340_rfd(void) { /* request for data */
|
||||||
|
#ifdef TY340_NODISPLAY
|
||||||
|
puts("ty340_rfd");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cpu_get_switches(unsigned long *p1, unsigned long *p2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cpu_set_switches(unsigned long sw1, unsigned long sw2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* dump display list using symbols from type340cmd.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DUMP
|
||||||
|
// Vector & incremental modes
|
||||||
|
static int
|
||||||
|
escpinsfy(int word)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (word & ESCP) {
|
||||||
|
printf(" ESCP");
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
if (word & INSFY)
|
||||||
|
printf(" INSFY");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
incr(int pt)
|
||||||
|
{
|
||||||
|
pt &= 017;
|
||||||
|
//printf(" %#o", pt);
|
||||||
|
switch (pt) {
|
||||||
|
#define P(X) case X: printf(" " #X); return
|
||||||
|
P(PR);
|
||||||
|
P(PL);
|
||||||
|
P(PU);
|
||||||
|
P(PD);
|
||||||
|
P(PUL);
|
||||||
|
P(PUR);
|
||||||
|
P(PDL);
|
||||||
|
P(PDR);
|
||||||
|
}
|
||||||
|
printf(" ???");
|
||||||
|
}
|
||||||
|
|
||||||
|
// PAR, SLV, POINT
|
||||||
|
static int
|
||||||
|
xmode(int word)
|
||||||
|
{
|
||||||
|
int m = word & MODEMASK;
|
||||||
|
switch (m) {
|
||||||
|
#define M(MODE) case MODE: printf(#MODE); break
|
||||||
|
M(MPAR);
|
||||||
|
M(MPT);
|
||||||
|
M(MSLV);
|
||||||
|
M(MCHR);
|
||||||
|
M(MVCT);
|
||||||
|
M(MVCTC);
|
||||||
|
M(MINCR);
|
||||||
|
M(MSUBR);
|
||||||
|
default: printf("M??"); break; /* SNH */
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns 1 if not stopped */
|
||||||
|
int
|
||||||
|
dump1(int *mp, int word)
|
||||||
|
{
|
||||||
|
int run = 1;
|
||||||
|
printf("%06o: ", word);
|
||||||
|
switch (*mp) {
|
||||||
|
case MPAR:
|
||||||
|
*mp = xmode(word);
|
||||||
|
// XXX look at reserved bits: 0300600??
|
||||||
|
if (word & LPOFF) {
|
||||||
|
if ((word & LPON) == LPON)
|
||||||
|
printf(" LPON");
|
||||||
|
else
|
||||||
|
printf(" LPOFF");
|
||||||
|
}
|
||||||
|
if (word & STP) {
|
||||||
|
if ((word & STP) == STP)
|
||||||
|
printf(" STP");
|
||||||
|
else
|
||||||
|
printf(" STOP");
|
||||||
|
run = 0;
|
||||||
|
}
|
||||||
|
switch (word & S3) {
|
||||||
|
case S0: printf(" S0"); break;
|
||||||
|
case S1: printf(" S1"); break;
|
||||||
|
case S2: printf(" S2"); break;
|
||||||
|
case S3: printf(" S3"); break;
|
||||||
|
}
|
||||||
|
switch (word & IN7) {
|
||||||
|
case IN0: printf(" IN0"); break;
|
||||||
|
case IN1: printf(" IN1"); break;
|
||||||
|
case IN2: printf(" IN2"); break;
|
||||||
|
case IN3: printf(" IN3"); break;
|
||||||
|
case IN4: printf(" IN4"); break;
|
||||||
|
case IN5: printf(" IN5"); break;
|
||||||
|
case IN6: printf(" IN6"); break;
|
||||||
|
case IN7: printf(" IN7"); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MPT:
|
||||||
|
// 0400000 reserved
|
||||||
|
*mp = xmode(word);
|
||||||
|
if (word & IP) printf(" IP");
|
||||||
|
if (word & V) printf(" V");
|
||||||
|
else printf(" H");
|
||||||
|
printf(" %d.", word & 01777);
|
||||||
|
break;
|
||||||
|
case MSLV:
|
||||||
|
*mp = xmode(word);
|
||||||
|
// reserved: 010000
|
||||||
|
printf(" XXX SLAVE");
|
||||||
|
break;
|
||||||
|
case MCHR:
|
||||||
|
printf(" XXX CHR");
|
||||||
|
if ((word>>12)&077 == 037 ||
|
||||||
|
(word>>6)&077 == 037 ||
|
||||||
|
(word&077) == 037)
|
||||||
|
*mp = 0;
|
||||||
|
case MVCT:
|
||||||
|
case MVCTC:
|
||||||
|
if (escpinsfy(word)) *mp = 0;
|
||||||
|
if (word & 077400) {
|
||||||
|
if (word & DN) printf(" DN");
|
||||||
|
else printf(" UP");
|
||||||
|
if (word & YP64) printf(" YP64");
|
||||||
|
if (word & YP32) printf(" YP32");
|
||||||
|
if (word & YP16) printf(" YP16");
|
||||||
|
if (word & YP8) printf(" YP8");
|
||||||
|
if (word & YP4) printf(" YP4");
|
||||||
|
if (word & YP2) printf(" YP2");
|
||||||
|
if (word & YP1) printf(" YP1");
|
||||||
|
}
|
||||||
|
if (word & 0377) {
|
||||||
|
if (word & LT) printf(" LT");
|
||||||
|
else printf(" RT");
|
||||||
|
if (word & XP64) printf(" XP64");
|
||||||
|
if (word & XP32) printf(" XP32");
|
||||||
|
if (word & XP16) printf(" XP16");
|
||||||
|
if (word & XP8) printf(" XP8");
|
||||||
|
if (word & XP4) printf(" XP4");
|
||||||
|
if (word & XP2) printf(" XP2");
|
||||||
|
if (word & XP1) printf(" XP1");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MINCR:
|
||||||
|
if (escpinsfy(word)) *mp = 0;
|
||||||
|
printf(" INCRPT(");
|
||||||
|
incr(word >> 12); putchar(',');
|
||||||
|
incr(word >> 8); putchar(',');
|
||||||
|
incr(word >> 4); putchar(',');
|
||||||
|
incr(word); putchar(')');
|
||||||
|
break;
|
||||||
|
case MSUBR:
|
||||||
|
puts("XXX SUBR: quitting");
|
||||||
|
run = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
return run;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dump(int *ip)
|
||||||
|
{
|
||||||
|
int mode = 0;
|
||||||
|
puts(" === DUMP ===");
|
||||||
|
while (dump1(&mode, *ip++))
|
||||||
|
;
|
||||||
|
puts("=== END DUMP ===");
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -1,3 +1,8 @@
|
||||||
|
/*
|
||||||
|
* wrap, or clip?
|
||||||
|
* finish lc bitmaps
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Id: type340.c,v 1.6 2005/01/14 18:58:00 phil Exp $
|
* $Id: type340.c,v 1.6 2005/01/14 18:58:00 phil Exp $
|
||||||
* Simulator Independent DEC Type 340 Graphic Display Processor Simulation
|
* Simulator Independent DEC Type 340 Graphic Display Processor Simulation
|
||||||
|
@ -5,12 +10,33 @@
|
||||||
* September 20, 2003
|
* September 20, 2003
|
||||||
* from vt11.c
|
* from vt11.c
|
||||||
*
|
*
|
||||||
* Information from DECUS 7-13
|
* First displayed PDP-6/10 SPCWAR Feb 2018!
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
*
|
||||||
|
* This file simulates ONLY the 340 proper
|
||||||
|
* and not CPU specific interfacing details
|
||||||
|
*
|
||||||
|
* see:
|
||||||
|
* http://www.bitsavers.org/pdf/dec/graphics/H-340_Type_340_Precision_Incremental_CRT_System_Nov64.pdf
|
||||||
|
*
|
||||||
|
* Initial information from DECUS 7-13:
|
||||||
|
* http://www.bitsavers.org/pdf/dec/graphics/7-13_340_Display_Programming_Manual.pdf
|
||||||
|
* pre-bitsavers location(!!):
|
||||||
* http://www.spies.com/~aek/pdf/dec/pdp7/7-13_340displayProgMan.pdf
|
* http://www.spies.com/~aek/pdf/dec/pdp7/7-13_340displayProgMan.pdf
|
||||||
|
*
|
||||||
|
* NOTE!!! The 340 is an async processor, with multiple control signals
|
||||||
|
* running in parallel. No attempt has been made to simulate this.
|
||||||
|
* And while it might be fun to try to implement it as a bit vector
|
||||||
|
* of signals, and run code triggered by those signals in the next
|
||||||
|
* service interval, BUT unless/until this is proven necessary, I'm
|
||||||
|
* resisting that impulse (pun not intended).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2004, Philip L. Budne
|
* Copyright (c) 2003-2018, Philip L. Budne
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -36,13 +62,21 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "display.h" /* XY plot interface */
|
#include "display.h" /* XY plot interface */
|
||||||
|
#include "type340.h" /* interface definitions */
|
||||||
|
#include "type340cmd.h" /* 340 command definitions */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Type 340 was used on the PDP-{4,6,7,9,10}
|
* sub-options, under "#if"
|
||||||
* and used 18-bit words, with bits numbered 0 thru 17
|
* (make runtime selectable????!)
|
||||||
* (most significant to least)
|
* TYPE342 character generator
|
||||||
|
* TYPE343 slave display control
|
||||||
|
* TYPE347 subroutine facility
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef TYPE342
|
||||||
|
#define TYPE342 1 /* default to character generation */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BITMASK(N) (1<<(17-(N)))
|
#define BITMASK(N) (1<<(17-(N)))
|
||||||
|
|
||||||
/* mask for a field */
|
/* mask for a field */
|
||||||
|
@ -55,91 +89,126 @@
|
||||||
#define TESTBIT(W,B) (((W) & BITMASK(B)) != 0)
|
#define TESTBIT(W,B) (((W) & BITMASK(B)) != 0)
|
||||||
|
|
||||||
#ifdef DEBUG_TY340
|
#ifdef DEBUG_TY340
|
||||||
|
#include <stdio.h>
|
||||||
#define DEBUGF(X) printf X
|
#define DEBUGF(X) printf X
|
||||||
#else
|
#else
|
||||||
#define DEBUGF(X)
|
#define DEBUGF(X)
|
||||||
#endif
|
#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 mode { PARAM=0, POINT, SLAVE, CHAR, VECTOR, VCONT, INCR, SUBR };
|
||||||
|
|
||||||
enum jump_type { DJP=2, DJS=3, DDS=1 };
|
#define TY340_UNITS 1
|
||||||
static ty340word ASR; /* Address Save Register */
|
|
||||||
static unsigned char save_ff; /* "save" flip-flop */
|
|
||||||
|
|
||||||
static unsigned char intensity; /* 3 bits */
|
enum jump_type { DJP=2, DJS=3, DDS=1 }; /* type 347 */
|
||||||
static unsigned char lp_ena; /* 1 bit */
|
|
||||||
|
|
||||||
/* kept signed for raster violation checking */
|
/* put all the state in a struct "just in case" */
|
||||||
static short xpos, ypos; /* 10 bits, signed */
|
static struct type340 {
|
||||||
static unsigned char sequence; /* 2 bits */
|
/* ty340word DAC; /* Display Address Counter */
|
||||||
|
ty340word status; /* see ST340_XXX in type340.h */
|
||||||
|
signed short xpos, ypos; /* 10 bits, signed (for OOB checks) */
|
||||||
|
char initialized; /* 0 before display_init */
|
||||||
|
/* only using (evil) bitfield syntax to limit enum size */
|
||||||
|
enum mode mode : 8; /* 3 bits */
|
||||||
|
unsigned char lp_ena; /* 1 bit */
|
||||||
|
unsigned char scale; /* multiplier: 1,2,4,8 */
|
||||||
|
unsigned char intensity; /* 3 bits */
|
||||||
|
#if TYPE342
|
||||||
|
unsigned char shift; /* 1 bit */
|
||||||
|
#endif
|
||||||
|
#if TYPE347
|
||||||
|
ty340word ASR; /* Address Save Register */
|
||||||
|
unsigned char SAVE_FF; /* "save" flip-flop */
|
||||||
|
#endif
|
||||||
|
} u340[TY340_UNITS];
|
||||||
|
|
||||||
/* XXX make defines public for 340_cycle return */
|
#if TY340_UNITS == 1
|
||||||
#define STOPPED 01
|
#define UNIT(N) u340
|
||||||
#define LPHIT 02
|
#else
|
||||||
#define VEDGE 04
|
#define UNIT(N) (u340+(N))
|
||||||
#define HEDGE 010
|
#endif
|
||||||
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);
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* NOT USED WITH PDP-6 Type 344 Interface!! */
|
||||||
void
|
void
|
||||||
ty340_set_dac(ty340word addr)
|
ty340_set_dac(ty340word addr)
|
||||||
{
|
{
|
||||||
DAC = addr;
|
struct type340 *u = UNIT(0);
|
||||||
mode = 0;
|
u->DAC = addr;
|
||||||
DEBUGF(("set DAC %06\r\n", DAC));
|
DEBUGF(("set DAC %06o\r\n", u->DAC));
|
||||||
status = 0; /* XXX just clear stopped? */
|
|
||||||
/* XXX clear other stuff? save_ff? */
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
/* XXX only when reset? */
|
||||||
|
u->mode = 0;
|
||||||
|
u->status = 0; /* XXX just clear stopped? */
|
||||||
|
ty340_rfd(); /* ready for data */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ty340word
|
||||||
ty340_reset(void)
|
ty340_reset(void)
|
||||||
{
|
{
|
||||||
/* XXX call display layer? destroy window? */
|
struct type340 *u = UNIT(0);
|
||||||
xpos = ypos = 0;
|
#ifndef TY340_NODISPLAY
|
||||||
status = STOPPED;
|
if (!u->initialized) {
|
||||||
|
display_init(DIS_TYPE340, 1, u); /* XXX check return? */
|
||||||
|
u->initialized = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
u->xpos = u->ypos = 0;
|
||||||
|
u->mode = 0;
|
||||||
|
u->status = 0; /* set ST340_DONE? */
|
||||||
|
u->scale = 1;
|
||||||
|
#if TYPE347
|
||||||
|
u->SAVE_FF = 0;
|
||||||
|
#endif
|
||||||
|
ty340_rfd(); /* ready for data */
|
||||||
|
return u->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
point(int x, int y, int seq)
|
point(int x, int y, int seq)
|
||||||
{
|
{
|
||||||
|
struct type340 *u = UNIT(0);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* XXX apply scale? */
|
#ifdef TYPE340_POINT
|
||||||
|
DEBUGF(("type340 point %d %d %d\r\n", x, y, seq));
|
||||||
|
#endif
|
||||||
|
|
||||||
i = DISPLAY_INT_MAX-7+intensity;
|
i = DISPLAY_INT_MAX-7+u->intensity;
|
||||||
if (i <= 0)
|
if (i <= 0)
|
||||||
i = 1;
|
i = 1;
|
||||||
|
|
||||||
if (x < 0 || x > 1023) {
|
if (x < 0 || x > 1023) {
|
||||||
status |= VEDGE;
|
/* XXX clip? wrap?? */
|
||||||
|
u->status |= ST340_VEDGE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (y < 0 || y > 1023) {
|
if (y < 0 || y > 1023) {
|
||||||
status |= HEDGE;
|
/* XXX clip? wrap?? */
|
||||||
|
u->status |= ST340_HEDGE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TY340_NODISPLAY
|
||||||
if (display_point(x, y, i, 0)) {
|
if (display_point(x, y, i, 0)) {
|
||||||
if (lp_ena) {
|
/*
|
||||||
/* XXX save location? */
|
* in real life: type340 pauses
|
||||||
status |= LPHIT;
|
* until CPU reads coordinates
|
||||||
sequence = seq;
|
*/
|
||||||
}
|
u->status |= ST340_LPHIT;
|
||||||
|
if (u->lp_ena)
|
||||||
|
ty340_lp_int(x, y);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lpoint(int x, int y)
|
||||||
|
{
|
||||||
|
#ifdef TYPE340_LPOINT
|
||||||
|
DEBUGF(("type340 lpoint %d %d\r\n", x, y));
|
||||||
|
#endif
|
||||||
|
point(x, y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -374,92 +443,125 @@ lineTwoStep(int x0, int y0, int x1, int y1)
|
||||||
}
|
}
|
||||||
} /* lineTwoStep */
|
} /* lineTwoStep */
|
||||||
|
|
||||||
static int
|
/* here in VECTOR & VCONT modes */
|
||||||
vector(int i, int sx, int dx, int sy, int dy)
|
int
|
||||||
|
vector(int i, int sy, int dy, int sx, int dx)
|
||||||
{
|
{
|
||||||
|
struct type340 *u = UNIT(0);
|
||||||
int x0, y0, x1, y1;
|
int x0, y0, x1, y1;
|
||||||
|
int flags;
|
||||||
|
|
||||||
x0 = xpos;
|
DEBUGF(("v i%d y%c%d x%c%d\r\n", i,
|
||||||
y0 = ypos;
|
(sy ? '-' : '+'), dy,
|
||||||
|
(sx ? '-' : '+'), dx));
|
||||||
|
x0 = u->xpos;
|
||||||
|
y0 = u->ypos;
|
||||||
|
|
||||||
if (sx) {
|
if (sx) {
|
||||||
x1 = x0 - dx;
|
x1 = x0 - dx * u->scale;
|
||||||
if (x1 < 0) /* XXX TEMP? */
|
if (x1 < 0) {
|
||||||
x1 = 0;
|
x1 = 0;
|
||||||
|
flags = ST340_HEDGE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x1 = x0 + dx;
|
x1 = x0 + dx * u->scale;
|
||||||
if (x1 > 1023) /* XXX TEMP? */
|
if (x1 > 1023) {
|
||||||
x1 = 1023;
|
x1 = 1023;
|
||||||
|
flags = ST340_HEDGE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sy) {
|
if (sy) {
|
||||||
y1 = y0 - dy;
|
y1 = y0 - dy * u->scale;
|
||||||
if (y1 < 0) /* XXX TEMP? */
|
if (y1 < 0) {
|
||||||
y1 = 0;
|
y1 = 0;
|
||||||
|
flags |= ST340_VEDGE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
y1 = y0 + dy; /* XXX TEMP? */
|
y1 = y0 + dy * u->scale;
|
||||||
if (y1 > 1023)
|
if (y1 > 1023) {
|
||||||
y1 = 1023;
|
y1 = 1023;
|
||||||
|
flags |= ST340_VEDGE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGF(("vector i%d (%d,%d) to (%d,%d)\r\n", i, x0, y0, x1, y1));
|
DEBUGF(("vector i%d (%d,%d) to (%d,%d)\r\n", i, x0, y0, x1, y1));
|
||||||
if (i)
|
if (i) /* XXX need OLD value??? */
|
||||||
lineTwoStep(x0, y0, x1, y1);
|
lineTwoStep(x0, y0, x1, y1);
|
||||||
|
|
||||||
xpos = x1;
|
u->xpos = x1;
|
||||||
ypos = y1;
|
u->ypos = y1;
|
||||||
return 0;
|
u->status |= flags; /* ?? */
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return true on raster violation */
|
/*
|
||||||
|
* incremental vector
|
||||||
|
* return true on raster violation
|
||||||
|
*
|
||||||
|
* i is intensify
|
||||||
|
* n is subvector number
|
||||||
|
* byte is 4 bits
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
ipoint(int i, int n, unsigned char byte)
|
ipoint(int i, int n, unsigned char byte)
|
||||||
{
|
{
|
||||||
|
struct type340 *u = UNIT(0);
|
||||||
|
DEBUGF(("type340 ipoint i%d n%d %#o\r\n", i, n, byte));
|
||||||
if (byte & 010) { /* left/right */
|
if (byte & 010) { /* left/right */
|
||||||
if (byte & 04) {
|
if (byte & 04) { /* left */
|
||||||
if (xpos == 0) {
|
u->xpos -= u->scale;
|
||||||
status |= VEDGE;
|
if (u->xpos < 0) {
|
||||||
return 1;
|
u->xpos = 0; /* XXX wrap? */
|
||||||
|
u->status |= ST340_VEDGE; /* save flags & continue?? */
|
||||||
|
return 1; /* escape */
|
||||||
}
|
}
|
||||||
xpos--;
|
|
||||||
}
|
}
|
||||||
else {
|
else { /* right */
|
||||||
if (xpos == 1023) {
|
u->xpos += u->scale;
|
||||||
status |= VEDGE;
|
if (u->xpos > 1023) {
|
||||||
|
u->xpos = 1023; /* XXX wrap? */
|
||||||
|
u->status |= ST340_VEDGE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
xpos++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (byte & 02) { /* up/down */
|
if (byte & 02) { /* up/down */
|
||||||
if (byte & 04) {
|
if (byte & 01) { /* down */
|
||||||
if (ypos == 0) {
|
u->ypos -= u->scale;
|
||||||
status |= HEDGE;
|
if (u->ypos < 0) {
|
||||||
|
u->ypos = 0; /* XXX wrap? */
|
||||||
|
u->status |= ST340_HEDGE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ypos--;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ypos == 1023) {
|
u->ypos += u->scale;
|
||||||
status |= HEDGE;
|
if (u->ypos > 1023) {
|
||||||
|
u->ypos = 1023; /* XXX wrap? */
|
||||||
|
u->status |= ST340_HEDGE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ypos++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i)
|
if (i)
|
||||||
point(xpos, ypos, n);
|
point(u->xpos, u->ypos, n);
|
||||||
|
|
||||||
return 0;
|
return 0; /* no escape */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TYPE342
|
||||||
/*
|
/*
|
||||||
* 342 character generator - first 64 characters (from manual)
|
* 342 character generator - first 64 characters
|
||||||
|
* 7-13_340_Display_Programming_Manual.pdf p.24
|
||||||
|
* each char contains a vertical stripe of the matrix.
|
||||||
|
* lowest bit is bottom
|
||||||
|
* first char is leftmost
|
||||||
*/
|
*/
|
||||||
static const unsigned char chars[64][5] = {
|
static const unsigned char chars[128][5] = {
|
||||||
{ 0070, 0124, 0154, 0124, 0070 }, /* 00 */
|
{ 0070, 0124, 0154, 0124, 0070 }, /* 00 blob */
|
||||||
{ 0174, 0240, 0240, 0240, 0174 }, /* 01 A */
|
{ 0174, 0240, 0240, 0240, 0174 }, /* 01 A */
|
||||||
{ 0376, 0222, 0222, 0222, 0154 }, /* 02 B */
|
{ 0376, 0222, 0222, 0222, 0154 }, /* 02 B */
|
||||||
{ 0174, 0202, 0202, 0202, 0104 }, /* 03 C */
|
{ 0174, 0202, 0202, 0202, 0104 }, /* 03 C */
|
||||||
|
@ -522,6 +624,76 @@ static const unsigned char chars[64][5] = {
|
||||||
{ 0020, 0050, 0104, 0202, 0000 }, /* 74 < */
|
{ 0020, 0050, 0104, 0202, 0000 }, /* 74 < */
|
||||||
{ 0050, 0050, 0050, 0050, 0050 }, /* 75 = */
|
{ 0050, 0050, 0050, 0050, 0050 }, /* 75 = */
|
||||||
{ 0000, 0202, 0104, 0050, 0020 }, /* 76 > */
|
{ 0000, 0202, 0104, 0050, 0020 }, /* 76 > */
|
||||||
|
{ 0100, 0200, 0236, 0220, 0140 }, /* 77 ? */
|
||||||
|
/*
|
||||||
|
* NOT YET COMPLETE!!!
|
||||||
|
* original letterforms not available, using
|
||||||
|
* https://fontstruct.com/fontstructions/show/357807/5x7_monospaced_pixel_font
|
||||||
|
* PLB: I wonder if VT52 was 5x7????
|
||||||
|
*/
|
||||||
|
{ 0070, 0124, 0154, 0124, 0070 }, /* 00 blob */
|
||||||
|
{ 0070, 0204, 0204, 0050, 0274 }, /* 01 a needs fixing! */
|
||||||
|
{ 0377, 0050, 0204, 0204, 0070 }, /* 02 b needs fixing! */
|
||||||
|
{ 0070, 0204, 0204, 0204, 0050 }, /* 03 c needs fixing! */
|
||||||
|
{ 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 */
|
||||||
|
{ 0376, 0100, 0040, 0100, 0376 }, /* 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 ? */
|
{ 0100, 0200, 0236, 0220, 0140 } /* 77 ? */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -529,178 +701,233 @@ static const unsigned char chars[64][5] = {
|
||||||
* type 342 Character/Symbol generator for type 340 display
|
* type 342 Character/Symbol generator for type 340 display
|
||||||
* return true if ESCaped
|
* return true if ESCaped
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
character(int n, char c)
|
character(int n, unsigned char c)
|
||||||
{
|
{
|
||||||
|
struct type340 *u = UNIT(0);
|
||||||
int x, y;
|
int x, y;
|
||||||
|
unsigned char s = u->scale;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 033: /* LF */
|
case CHRLF: /* LF */
|
||||||
if (ypos < 12) {
|
u->ypos -= 12*s;
|
||||||
status |= HEDGE;
|
if (u->ypos < 0) {
|
||||||
ypos = 0;
|
u->status |= ST340_HEDGE;
|
||||||
|
u->ypos = 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
ypos -= 12; /* XXX scale? */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
case 034: /* CR */
|
case CHRCR: /* CR */
|
||||||
xpos = 0;
|
u->xpos = 0;
|
||||||
return 0;
|
return 0;
|
||||||
case 035: /* shift in */
|
case CHRUC: /* "SHIFT IN (HORIZ)" */
|
||||||
shift = 1;
|
u->shift = 0; /* upper case in spcwac.163 */
|
||||||
return 0;
|
return 0;
|
||||||
case 036: /* shift out */
|
case CHRLC: /* "SHIFT OUT (VERT)" */
|
||||||
shift = 0;
|
u->shift = 0100; /* lower case in spcwar.163 */
|
||||||
return 0;
|
return 0;
|
||||||
case 037: /* escape */
|
case CHRESC: /* escape */
|
||||||
sequence = n;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* XXX plot character from character set selected by "shift"
|
/* plot character from character set selected by "shift" */
|
||||||
* (offset index by 64?)
|
|
||||||
*/
|
|
||||||
for (x = 0; x < 5; x++) {
|
for (x = 0; x < 5; x++) {
|
||||||
for (y = 0; y < 7; y++) {
|
for (y = 0; y < 8; y++) {
|
||||||
if (chars[c][x] & (1<<y)) {
|
if (chars[c|u->shift][x] & (1<<y)) {
|
||||||
/* XXX check for raster violation? */
|
/* XXX check for raster violation? */
|
||||||
point(xpos+x, ypos+y, n); /* XXX scale? */
|
point(u->xpos+x*s, u->ypos+y*s, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xpos += 7; /* XXX scale? */
|
u->xpos += 7*s;
|
||||||
if (xpos > 1023) {
|
if (u->xpos > 1023) {
|
||||||
xpos = 1023;
|
u->xpos = 1023;
|
||||||
status |= VEDGE;
|
u->status |= ST340_VEDGE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
/*
|
||||||
ty340_cycle(int us, int slowdown)
|
* execute one type340 instruction
|
||||||
|
* returns status word
|
||||||
|
* (could return number of microseconds)
|
||||||
|
*/
|
||||||
|
ty340word
|
||||||
|
ty340_instruction(ty340word inst)
|
||||||
{
|
{
|
||||||
ty340word inst, addr;
|
struct type340 *u = UNIT(0);
|
||||||
int i, escape, stopped;
|
int i, escape;
|
||||||
|
#ifdef TYPE347
|
||||||
|
ty340word addr;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (status & STOPPED)
|
/* cleared by RFD */
|
||||||
return 0; /* XXX age display? */
|
u->status &= ~(ST340_HEDGE|ST340_VEDGE);
|
||||||
|
|
||||||
inst = ty340_fetch(DAC);
|
DEBUGF(("type340 mode %#o status %#o\r\n", u->mode, u->status));
|
||||||
DEBUGF(("%06o: %06o\r\n", DAC, inst));
|
if (u->status & ST340_STOPPED) /* XXX LPINT as well??? */
|
||||||
DAC++;
|
return u->status;
|
||||||
|
|
||||||
escape = 0;
|
escape = 0;
|
||||||
switch (mode) {
|
switch (u->mode) {
|
||||||
case PARAM:
|
case PARAM:
|
||||||
mode = GETFIELD(inst, 2, 4);
|
if (inst & 0600600) { /* curious to see if MIT hacked theirs */
|
||||||
|
DEBUGF(("type340 reserved param bits set %#o\r\n", inst));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* READ TO MODE: */
|
||||||
|
u->mode = GETFIELD(inst, 2, 4);
|
||||||
if (TESTBIT(inst, 5)) { /* load l.p. enable */
|
if (TESTBIT(inst, 5)) { /* load l.p. enable */
|
||||||
lp_ena = TESTBIT(inst,6);
|
u->lp_ena = TESTBIT(inst,6);
|
||||||
DEBUGF(("lp_ena %d\r\n", lp_ena));
|
DEBUGF(("type340 lp_ena %d\r\n", u->lp_ena));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PM PULSE: */
|
||||||
|
if (TESTBIT(inst, 14)) {
|
||||||
|
/* STORE INTENSITY: */
|
||||||
|
u->intensity = GETFIELD(inst, 15, 17);
|
||||||
|
DEBUGF(("type340 set intensity %d\r\n", u->intensity));
|
||||||
|
}
|
||||||
|
if (TESTBIT(inst, 11)) {
|
||||||
|
/* STORE SCALE: */
|
||||||
|
u->scale = 1<<GETFIELD(inst, 12, 13); /* save as multiplier */
|
||||||
|
DEBUGF(("type340 set scale %d\r\n", u->scale));
|
||||||
|
}
|
||||||
if (TESTBIT(inst, 7)) {
|
if (TESTBIT(inst, 7)) {
|
||||||
status |= STOPPED;
|
u->status |= ST340_STOPPED;
|
||||||
if (TESTBIT(inst, 8))
|
DEBUGF(("type340 stop\r\n"));
|
||||||
ty340_stop_int(); /* set stop_int_end? */
|
if (TESTBIT(inst, 8)) {
|
||||||
|
DEBUGF(("type340 stop int\r\n"));
|
||||||
|
u->status |= ST340_STOP_INT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TESTBIT(inst, 11))
|
|
||||||
scale = GETFIELD(inst, 12, 13);
|
|
||||||
|
|
||||||
if (TESTBIT(inst, 14))
|
|
||||||
intensity = GETFIELD(inst, 15, 17);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POINT:
|
case POINT:
|
||||||
mode = GETFIELD(inst, 2, 4);
|
u->mode = GETFIELD(inst, 2, 4);
|
||||||
|
|
||||||
if (TESTBIT(inst, 5)) /* load l.p. enable */
|
if (TESTBIT(inst, 5)) { /* load l.p. enable */
|
||||||
lp_ena = TESTBIT(inst,6);
|
u->lp_ena = TESTBIT(inst,6);
|
||||||
|
DEBUGF(("type340 lp_ena %d\r\n", u->lp_ena));
|
||||||
|
}
|
||||||
|
|
||||||
if (TESTBIT(inst, 1))
|
if (TESTBIT(inst, 1)) {
|
||||||
ypos = GETFIELD(inst, 8, 17);
|
u->ypos = GETFIELD(inst, 8, 17);
|
||||||
else
|
DEBUGF(("type340 set u->ypos %d\r\n", u->ypos));
|
||||||
xpos = GETFIELD(inst, 8, 17);
|
}
|
||||||
|
else {
|
||||||
if (TESTBIT(inst, 7))
|
u->xpos = GETFIELD(inst, 8, 17);
|
||||||
point(xpos, ypos, 0);
|
DEBUGF(("type340 set xpos %d\r\n", u->xpos));
|
||||||
|
}
|
||||||
|
if (TESTBIT(inst, 7)) { /* intensify */
|
||||||
|
DEBUGF(("type340 point (%d,%d)\r\n", u->ypos, u->xpos));
|
||||||
|
point(u->xpos, u->ypos, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SLAVE:
|
case SLAVE:
|
||||||
mode = GETFIELD(inst, 2, 4);
|
DEBUGF(("type340 slave %06o\r\n", inst));
|
||||||
|
u->mode = GETFIELD(inst, 2, 4);
|
||||||
|
#if TYPE343
|
||||||
|
/* control multiple windows???? */
|
||||||
|
#else
|
||||||
|
/* ..set the mode register and halt without requesting a new data word */
|
||||||
|
u->status |= ST340_STOPPED;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHAR:
|
case CHAR:
|
||||||
|
DEBUGF(("type340 char %06o\r\n", inst));
|
||||||
|
#if TYPE342
|
||||||
escape = (character(0, GETFIELD(inst, 0, 5)) ||
|
escape = (character(0, GETFIELD(inst, 0, 5)) ||
|
||||||
character(1, GETFIELD(inst, 6, 11)) ||
|
character(1, GETFIELD(inst, 6, 11)) ||
|
||||||
character(2, GETFIELD(inst, 12, 17)));
|
character(2, GETFIELD(inst, 12, 17)));
|
||||||
|
#else
|
||||||
|
/* what other missing options do: */
|
||||||
|
u->status |= ST340_STOPPED;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VECTOR:
|
case VECTOR:
|
||||||
|
DEBUGF(("type340 vector %06o\r\n", inst));
|
||||||
escape = TESTBIT(inst, 0);
|
escape = TESTBIT(inst, 0);
|
||||||
if (vector(TESTBIT(inst, 1),
|
if (vector(TESTBIT(inst, 1),
|
||||||
TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
|
TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
|
||||||
TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) {
|
TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) {
|
||||||
/* XXX interrupt? */
|
/* XXX interrupt? */
|
||||||
|
escape = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VCONT:
|
case VCONT:
|
||||||
escape = TESTBIT(inst, 0);
|
DEBUGF(("type340 vcont %06o\r\n", inst));
|
||||||
if (vector(TESTBIT(inst, 1),
|
while (!vector(TESTBIT(inst, 1),
|
||||||
TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
|
TESTBIT(inst, 2), GETFIELD(inst, 3, 9),
|
||||||
TESTBIT(inst, 10), GETFIELD(inst, 11, 17))) {
|
TESTBIT(inst, 10), GETFIELD(inst, 11, 17)))
|
||||||
/* XXX set escape? */
|
;
|
||||||
mode = PARAM; /* raster violation */
|
escape = 1; /* XXX always???? */
|
||||||
}
|
/* NOTE: NO INTERRUPT!! Clear conditions???? */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INCR:
|
case INCR:
|
||||||
escape = TESTBIT(inst, 0); /* escape bit */
|
DEBUGF(("type340 incr %06o\r\n", inst));
|
||||||
i = TESTBIT(inst, 1);
|
i = TESTBIT(inst, 1); /* intensify bit */
|
||||||
|
|
||||||
if (ipoint(i, 0, GETFIELD(inst, 2, 5)) ||
|
if (ipoint(i, 0, GETFIELD(inst, 2, 5)) ||
|
||||||
ipoint(i, 1, GETFIELD(inst, 6, 9)) ||
|
ipoint(i, 1, GETFIELD(inst, 6, 9)) ||
|
||||||
ipoint(i, 2, GETFIELD(inst, 10, 13)) ||
|
ipoint(i, 2, GETFIELD(inst, 10, 13)) ||
|
||||||
ipoint(i, 3, GETFIELD(inst, 14, 17)))
|
ipoint(i, 3, GETFIELD(inst, 14, 17)))
|
||||||
/* XXX set escape? */
|
escape = 1;
|
||||||
mode = PARAM; /* raster violation */
|
else if (TESTBIT(inst, 0)) /* escape bit */
|
||||||
|
escape = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBR:
|
case SUBR:
|
||||||
|
DEBUGF(("type340 subr %06o\r\n", inst));
|
||||||
|
#if TYPE347
|
||||||
/* type 347 Display Subroutine Option? */
|
/* type 347 Display Subroutine Option? */
|
||||||
|
|
||||||
mode = GETFIELD(inst, 2, 4);
|
u->mode = GETFIELD(inst, 2, 4);
|
||||||
/* XXX take high bits of current DAC? */
|
|
||||||
addr = GETFIELD(inst, 5, 17);
|
addr = GETFIELD(inst, 5, 17);
|
||||||
|
|
||||||
switch (GETFIELD(inst, 0, 1)) {
|
switch (GETFIELD(inst, 0, 1)) {
|
||||||
case DJS: /* display jump and save */
|
case DJS: /* display jump and save */
|
||||||
ASR = DAC;
|
u->ASR = u->DAC;
|
||||||
save_ff = 1; /* set "save" flip-flop */
|
u->SAVE_FF = 1; /* set "save" flip-flop */
|
||||||
/* FALL */
|
/* FALL */
|
||||||
case DJP: /* display jump */
|
case DJP: /* display jump */
|
||||||
DAC = addr;
|
u->DAC = addr;
|
||||||
break;
|
break;
|
||||||
case DDS: /* display deposit save register */
|
case DDS: /* display deposit save register */
|
||||||
ty340_deposit(addr, (DJP<<16) | ASR);
|
ty340_store(addr, (DJP<<16) | u->ASR);
|
||||||
save_ff = 0; /* ?? */
|
/* clear SAVE_FF? */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* XXX ??? */
|
/* XXX ??? */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#else /* no 347 */
|
||||||
|
/* "halts without generating request for data or interrupt" */
|
||||||
|
u->status |= ST340_STOPPED;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (escape) {
|
if (escape) {
|
||||||
mode = PARAM;
|
u->mode = PARAM;
|
||||||
if (save_ff) {
|
#if TYPE347
|
||||||
|
if (u->SAVE_FF) {
|
||||||
/* return from subroutine */
|
/* return from subroutine */
|
||||||
DAC = ASR;
|
u->DAC = u->ASR;
|
||||||
save_ff = 0;
|
u->SAVE_FF = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return status;
|
if (!(u->status & ST340_STOPPED)) /* XXX LPINT as well??? */
|
||||||
} /* ty340_cycle */
|
ty340_rfd(); /* ready for data */
|
||||||
|
return u->status;
|
||||||
|
} /* ty340_instruction */
|
||||||
|
|
||||||
|
ty340word
|
||||||
|
ty340_status(void)
|
||||||
|
{
|
||||||
|
struct type340 *u = UNIT(0);
|
||||||
|
return u->status;
|
||||||
|
}
|
||||||
|
|
60
display/type340.h
Normal file
60
display/type340.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* external interface for type340.c
|
||||||
|
* Simulator Independent DEC Type 340 Graphic Display Processor Simulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef unsigned int ty340word;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type340 status bits
|
||||||
|
* MUST BE EXACT SAME VALUES AS USED IN PDP-10 CONI!!!
|
||||||
|
*/
|
||||||
|
#define ST340_VEDGE 04000
|
||||||
|
#define ST340_LPHIT 02000
|
||||||
|
#define ST340_HEDGE 01000
|
||||||
|
#define ST340_STOP_INT 00400
|
||||||
|
|
||||||
|
/* NOT same as PDP-10 CONI */
|
||||||
|
#define ST340_STOPPED 0400000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calls from host into type340.c
|
||||||
|
*/
|
||||||
|
ty340word ty340_reset(void);
|
||||||
|
ty340word ty340_status(void);
|
||||||
|
ty340word ty340_instruction(ty340word inst);
|
||||||
|
void ty340_set_dac(ty340word addr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calls from type340.c into host simulator
|
||||||
|
*/
|
||||||
|
extern ty340word ty340_fetch(ty340word);
|
||||||
|
extern void ty340_store(ty340word, ty340word);
|
||||||
|
extern void ty340_lp_int(ty340word x, ty340word y);
|
||||||
|
extern void ty340_rfd(void);
|
177
display/type340cmd.h
Normal file
177
display/type340cmd.h
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* constants for type 340 words
|
||||||
|
* (use for writing test programs)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define CHAR(C1,C2,C3) \
|
||||||
|
(((C1)<<12)|((C2)<<6)|(C3))
|
||||||
|
|
||||||
|
#define INCRPT(P1,P2,P3,P4) (((P1)<<12)|((P2)<<8)|((P3)<<4)|(P4))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adapted from
|
||||||
|
* 7-13_340_Display_Programming_Manual.pdf
|
||||||
|
* Appendix 1: Mnemonics
|
||||||
|
*
|
||||||
|
* tst340.c dump() routine uses/prints these
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* modes: */
|
||||||
|
#define MPAR 0000000 /* parameter */
|
||||||
|
#define MPT 0020000 /* point */
|
||||||
|
#define MSLV 0040000 /* slave */
|
||||||
|
#define MCHR 0060000 /* character */
|
||||||
|
#define MVCT 0100000 /* Vector */
|
||||||
|
#define MVCTC 0120000 /* Vector continue */
|
||||||
|
#define MINCR 0140000 /* Increment */
|
||||||
|
#define MSUBR 0160000 /* Subroutine */
|
||||||
|
|
||||||
|
#define MODEMASK 0160000
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Parameter Mode Words
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LPON 014000
|
||||||
|
#define LPOFF 010000
|
||||||
|
|
||||||
|
#define STP 0003000 /* stop & interrupt */
|
||||||
|
#define STOP 0001000 /* just stop: not in display manual */
|
||||||
|
|
||||||
|
/* scale settings */
|
||||||
|
#define S0 0000100
|
||||||
|
#define S1 0000120
|
||||||
|
#define S2 0000140
|
||||||
|
#define S3 0000160
|
||||||
|
|
||||||
|
/* intensity settings */
|
||||||
|
#define IN0 0000010
|
||||||
|
#define IN1 0000011
|
||||||
|
#define IN2 0000012
|
||||||
|
#define IN3 0000013
|
||||||
|
#define IN4 0000014
|
||||||
|
#define IN5 0000015
|
||||||
|
#define IN6 0000016
|
||||||
|
#define IN7 0000017
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Point Mode Words
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define V 0200000 /* Vertical word */
|
||||||
|
#define H 0000000 /* Horizontal word */
|
||||||
|
#define IP 0002000 /* Intensify point */
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Slave Mode Words
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define S1ON 05000
|
||||||
|
#define S1OFF 04000
|
||||||
|
#define LP1ON 02000
|
||||||
|
|
||||||
|
#define S2ON 0500
|
||||||
|
#define S2OFF 0400
|
||||||
|
#define LP2ON 0200
|
||||||
|
|
||||||
|
#define S3ON 050
|
||||||
|
#define S3OFF 040
|
||||||
|
#define LP3ON 020
|
||||||
|
|
||||||
|
#define S4ON 05
|
||||||
|
#define S4OFF 04
|
||||||
|
#define LP4ON 02
|
||||||
|
|
||||||
|
// for use in XXX macro:
|
||||||
|
#define SXON 05
|
||||||
|
#define SXOFF 04
|
||||||
|
#define LPXON 02
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Character mode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* defines from ITS: 340def 4 */
|
||||||
|
#define CHRESC 037 /* escape from character mode */
|
||||||
|
#define CHRUC 035 /* shift to upper-case */
|
||||||
|
#define CHRLC 036 /* " " lower-case */
|
||||||
|
#define CHRLF 033 /* line-feed */
|
||||||
|
#define CHRCR 034 /* carriage-return */
|
||||||
|
#define CHRSP 040 /* space (identity!) */
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Vector and Vector Continue Words
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ESCP 0400000 /* Escape */
|
||||||
|
#define INSFY 0200000 /* Intensify */
|
||||||
|
|
||||||
|
/** y position */
|
||||||
|
|
||||||
|
#define DN 0100000 /* Down */
|
||||||
|
#define UP 0000000 /* Up */
|
||||||
|
|
||||||
|
/* number of points moved */
|
||||||
|
#define YP64 0040000
|
||||||
|
#define YP32 0020000
|
||||||
|
#define YP16 0010000
|
||||||
|
#define YP8 0004000
|
||||||
|
#define YP4 0002000
|
||||||
|
#define YP2 0001000
|
||||||
|
#define YP1 0000400
|
||||||
|
|
||||||
|
/** x position */
|
||||||
|
#define LT 0000200 /* Left */
|
||||||
|
#define RT 0000000 /* Right */
|
||||||
|
|
||||||
|
#define XP64 0000100
|
||||||
|
#define XP32 0000040
|
||||||
|
#define XP16 0000020
|
||||||
|
#define XP8 0000010
|
||||||
|
#define XP4 0000004
|
||||||
|
#define XP2 0000002
|
||||||
|
#define XP1 0000001
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* increment
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PR 010
|
||||||
|
#define PL 014
|
||||||
|
#define PU 002
|
||||||
|
#define PD 003
|
||||||
|
|
||||||
|
#define PUL (PU|PL)
|
||||||
|
#define PUR (PU|PR)
|
||||||
|
|
||||||
|
#define PDL (PD|PL)
|
||||||
|
#define PDR (PD|PR)
|
||||||
|
|
||||||
|
/* INSFY and ESCP from vector modes */
|
|
@ -1295,7 +1295,7 @@ main(void) {
|
||||||
|
|
||||||
puts("initial tests work for both VT11 and VS60");
|
puts("initial tests work for both VT11 and VS60");
|
||||||
for (df = VT, start = 0, more = 1; more; ) {
|
for (df = VT, start = 0, more = 1; more; ) {
|
||||||
vt11_reset(); /* reset everything */
|
vt11_reset(NULL, 0); /* reset everything */
|
||||||
vt11_set_dpc(start); /* start section */
|
vt11_set_dpc(start); /* start section */
|
||||||
c = 0;
|
c = 0;
|
||||||
while (vt11_cycle(USEC, 1)) {
|
while (vt11_cycle(USEC, 1)) {
|
||||||
|
@ -1315,7 +1315,7 @@ main(void) {
|
||||||
puts("move the light pen through the tracking object");
|
puts("move the light pen through the tracking object");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
for (df = LP, start = 0, more = 1; more; ) {
|
for (df = LP, start = 0, more = 1; more; ) {
|
||||||
vt11_reset(); /* reset everything */
|
vt11_reset(NULL, 0); /* reset everything */
|
||||||
vt11_set_dpc(start); /* start section */
|
vt11_set_dpc(start); /* start section */
|
||||||
c = 0;
|
c = 0;
|
||||||
while (vt11_cycle(USEC, 1)) {
|
while (vt11_cycle(USEC, 1)) {
|
||||||
|
@ -1335,7 +1335,7 @@ main(void) {
|
||||||
ws_beep();
|
ws_beep();
|
||||||
puts("following tests require VS60");
|
puts("following tests require VS60");
|
||||||
for (df = VS, start = 0, more = 1; more; ) {
|
for (df = VS, start = 0, more = 1; more; ) {
|
||||||
vt11_reset(); /* reset everything */
|
vt11_reset(NULL, 0); /* reset everything */
|
||||||
vt11_set_str((uint16)(0200 | '~')); /* set terminating char. */
|
vt11_set_str((uint16)(0200 | '~')); /* set terminating char. */
|
||||||
vt11_set_anr((uint16)(040000 | (2<<12) | 04000 | 01234));
|
vt11_set_anr((uint16)(040000 | (2<<12) | 04000 | 01234));
|
||||||
/* set associative name 0123x */
|
/* set associative name 0123x */
|
||||||
|
@ -1358,7 +1358,7 @@ main(void) {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
wf_update(1); /* do first-time init */
|
wf_update(1); /* do first-time init */
|
||||||
for (df = WF, start = 0, more = 1; more; ) {
|
for (df = WF, start = 0, more = 1; more; ) {
|
||||||
vt11_reset(); /* reset everything */
|
vt11_reset(NULL, 0); /* reset everything */
|
||||||
vt11_set_dpc(start); /* start section */
|
vt11_set_dpc(start); /* start section */
|
||||||
c = 0;
|
c = 0;
|
||||||
while (vt11_cycle(USEC, 1)) {
|
while (vt11_cycle(USEC, 1)) {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2004, Philip L. Budne
|
* Copyright (c) 2003-2018, Philip L. Budne
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -38,6 +38,10 @@
|
||||||
* from the authors.
|
* from the authors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef USE_XKB
|
||||||
|
#define USE_XKB 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -51,6 +55,9 @@
|
||||||
#include <X11/Core.h>
|
#include <X11/Core.h>
|
||||||
#include <X11/Shell.h>
|
#include <X11/Shell.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
|
#ifdef USE_XKB
|
||||||
|
#include <X11/XKBlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -155,6 +162,55 @@ handle_button_release(w, d, e, b)
|
||||||
*b = TRUE;
|
*b = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* map keyboard XEvent to 8 bit char or -1
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
mapkey(e)
|
||||||
|
XEvent *e;
|
||||||
|
{
|
||||||
|
int shift = (ShiftMask & e->xkey.state) != 0;
|
||||||
|
KeySym key;
|
||||||
|
|
||||||
|
#ifdef USE_XKB
|
||||||
|
/*
|
||||||
|
* X Keyboard Extension
|
||||||
|
* described in
|
||||||
|
* https://www.x.org/releases/X11R7.7/doc/libX11/XKB/xkblib.html#Xkb_Keyboard_Extension_Support_for_Keyboards
|
||||||
|
* copyright 1995, 1996
|
||||||
|
*
|
||||||
|
* use XkbLibraryVersion and/or XkbQueryExtension
|
||||||
|
* to determine if available???
|
||||||
|
*/
|
||||||
|
key = XkbKeycodeToKeysym(dpy, e->xkey.keycode, 0, shift);
|
||||||
|
#elif 1
|
||||||
|
/*
|
||||||
|
* documented in
|
||||||
|
* Xlib: C Language X Interface (X Version 11, Release 4)
|
||||||
|
* copyright 1989
|
||||||
|
*/
|
||||||
|
int keysyms_per_keycode_return;
|
||||||
|
KeySym *keysyms = XGetKeyboardMapping(dpy,
|
||||||
|
e->xkey.keycode,
|
||||||
|
1,
|
||||||
|
&keysyms_per_keycode_return);
|
||||||
|
key = keysyms[0];
|
||||||
|
XFree(keysyms);
|
||||||
|
#else /* just in case... */
|
||||||
|
/* XKeycodeToKeysym deprecated */
|
||||||
|
key = XKeycodeToKeysym(dpy, e->xkey.keycode, shift);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((key & 0xff00) == 0)
|
||||||
|
return key & 0xff;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case XK_Return: return '\r';
|
||||||
|
}
|
||||||
|
/* printf("ignoring keycode %#x\r\n", key); /**/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_key_press(w, d, e, b)
|
handle_key_press(w, d, e, b)
|
||||||
Widget w;
|
Widget w;
|
||||||
|
@ -162,12 +218,9 @@ handle_key_press(w, d, e, b)
|
||||||
XEvent *e;
|
XEvent *e;
|
||||||
Boolean *b;
|
Boolean *b;
|
||||||
{
|
{
|
||||||
int shift = (ShiftMask & e->xkey.state) != 0;
|
int k = mapkey(e);
|
||||||
KeySym key = XKeycodeToKeysym( dpy, e->xkey.keycode, shift );
|
if (k >= 0)
|
||||||
|
display_keydown(k);
|
||||||
/*printf("key %d down\n", key); fflush(stdout);*/
|
|
||||||
if ((key & 0xff00) == 0)
|
|
||||||
display_keydown(key);
|
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
*b = TRUE;
|
*b = TRUE;
|
||||||
|
@ -180,12 +233,9 @@ handle_key_release(w, d, e, b)
|
||||||
XEvent *e;
|
XEvent *e;
|
||||||
Boolean *b;
|
Boolean *b;
|
||||||
{
|
{
|
||||||
int shift = (ShiftMask & e->xkey.state) != 0;
|
int k = mapkey(e);
|
||||||
KeySym key = XKeycodeToKeysym( dpy, e->xkey.keycode, shift );
|
if (k >= 0)
|
||||||
|
display_keyup(k);
|
||||||
/*printf("key %d up\n", key); fflush(stdout);*/
|
|
||||||
if ((key & 0xff00) == 0)
|
|
||||||
display_keyup(key);
|
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
*b = TRUE;
|
*b = TRUE;
|
||||||
|
@ -216,7 +266,9 @@ ws_init(const char *crtname, /* crt type name */
|
||||||
int argc;
|
int argc;
|
||||||
char *argv[1];
|
char *argv[1];
|
||||||
int height, width;
|
int height, width;
|
||||||
|
#ifdef USE_XKB
|
||||||
|
Bool supported;
|
||||||
|
#endif
|
||||||
xpixels = xp; /* save screen size */
|
xpixels = xp; /* save screen size */
|
||||||
ypixels = yp;
|
ypixels = yp;
|
||||||
|
|
||||||
|
@ -227,6 +279,16 @@ ws_init(const char *crtname, /* crt type name */
|
||||||
dpy = XtOpenDisplay( app_context, NULL, NULL, crtname, NULL, 0,
|
dpy = XtOpenDisplay( app_context, NULL, NULL, crtname, NULL, 0,
|
||||||
&argc, argv);
|
&argc, argv);
|
||||||
|
|
||||||
|
#ifdef USE_XKB
|
||||||
|
/*
|
||||||
|
* suppress synthetic key up events from autorepeat
|
||||||
|
* (will still see repeated down events)
|
||||||
|
* see keymap function for XKb history
|
||||||
|
*/
|
||||||
|
supported = False;
|
||||||
|
(void) XkbSetDetectableAutoRepeat(dpy, True, &supported);
|
||||||
|
#endif
|
||||||
|
|
||||||
scr = DefaultScreen(dpy);
|
scr = DefaultScreen(dpy);
|
||||||
|
|
||||||
crtshell = XtAppCreateShell( crtname, /* app name */
|
crtshell = XtAppCreateShell( crtname, /* app name */
|
||||||
|
|
Loading…
Add table
Reference in a new issue