Initial public version of TX-0 for SIMH
Integrate TX-0 simulation into SIMH.
This commit is contained in:
parent
be1e1326b3
commit
35ef1c8d24
25 changed files with 11346 additions and 0 deletions
20
TX-0/resource.h
Normal file
20
TX-0/resource.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by tx0.rc
|
||||||
|
//
|
||||||
|
#define HTC_VERS_MIN 0
|
||||||
|
#define HTC_VERS_REV 0
|
||||||
|
#define HTC_VERS_MAJ 1
|
||||||
|
#define IDI_ICON1 106
|
||||||
|
#define HTC_VERS_BUILD 1746
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 108
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
BIN
TX-0/tx0.ico
Normal file
BIN
TX-0/tx0.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
110
TX-0/tx0.rc
Normal file
110
TX-0/tx0.rc
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// Microsoft Visual C++ generated resource script.
|
||||||
|
//
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 2 resource.
|
||||||
|
//
|
||||||
|
#include "afxres.h"
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// English (U.S.) resources
|
||||||
|
|
||||||
|
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||||
|
#ifdef _WIN32
|
||||||
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
#pragma code_page(1252)
|
||||||
|
#endif //_WIN32
|
||||||
|
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// TEXTINCLUDE
|
||||||
|
//
|
||||||
|
|
||||||
|
1 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"resource.h\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
2 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"#include ""afxres.h""\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
3 TEXTINCLUDE
|
||||||
|
BEGIN
|
||||||
|
"\r\n"
|
||||||
|
"\0"
|
||||||
|
END
|
||||||
|
|
||||||
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Version
|
||||||
|
//
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION 1,0,0,1746
|
||||||
|
PRODUCTVERSION 1,0,0,1746
|
||||||
|
FILEFLAGSMASK 0x17L
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x1L
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x4L
|
||||||
|
FILETYPE 0x1L
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "FileDescription", "SIMH TX-0 Simulator"
|
||||||
|
VALUE "FileVersion", "1.0.0.1746"
|
||||||
|
VALUE "InternalName", "TX-0"
|
||||||
|
VALUE "LegalCopyright", "Copyright (c) 2009-2012, Howard M. Harte"
|
||||||
|
VALUE "OriginalFilename", "TX0.exe"
|
||||||
|
VALUE "ProductName", " TX-0 Application"
|
||||||
|
VALUE "ProductVersion", "1.0.0.1746"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Icon
|
||||||
|
//
|
||||||
|
|
||||||
|
// Icon with lowest ID value placed first to ensure application icon
|
||||||
|
// remains consistent on all systems.
|
||||||
|
IDI_ICON1 ICON "tx0.ico"
|
||||||
|
#endif // English (U.S.) resources
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef APSTUDIO_INVOKED
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Generated from the TEXTINCLUDE 3 resource.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
#endif // not APSTUDIO_INVOKED
|
||||||
|
|
1476
TX-0/tx0_cpu.c
Normal file
1476
TX-0/tx0_cpu.c
Normal file
File diff suppressed because it is too large
Load diff
93
TX-0/tx0_defs.h
Normal file
93
TX-0/tx0_defs.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* *
|
||||||
|
* $Id: tx0_defs.h 2059 2009-02-23 05:59:14Z hharte $ *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2009 Howard M. Harte. *
|
||||||
|
* Based on pdp1_defs.h, Copyright (c) 1993-2006, Robert M. Supnik *
|
||||||
|
* *
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||||
|
* a copy of this software and associated documentation files (the *
|
||||||
|
* "Software"), to deal in the Software without restriction, including *
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to *
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to *
|
||||||
|
* the following conditions: *
|
||||||
|
* *
|
||||||
|
* The above copyright notice and this permission notice shall be *
|
||||||
|
* included in all copies or substantial portions of the Software. *
|
||||||
|
* *
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL HOWARD M. HARTE 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 Howard M. Harte shall *
|
||||||
|
* not be used in advertising or otherwise to promote the sale, use or *
|
||||||
|
* other dealings in this Software without prior written authorization *
|
||||||
|
* of Howard M. Harte. *
|
||||||
|
* *
|
||||||
|
* Module Description: *
|
||||||
|
* cpu TX-0 Central Processor *
|
||||||
|
* *
|
||||||
|
* Environment: *
|
||||||
|
* User mode only *
|
||||||
|
* *
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _PDP1_DEFS_H_
|
||||||
|
#define _PDP1_DEFS_H_ 0
|
||||||
|
|
||||||
|
#include "sim_defs.h"
|
||||||
|
|
||||||
|
/* Simulator stop codes */
|
||||||
|
#define STOP_RSRV 1 /* must be 1 */
|
||||||
|
#define STOP_HALT 2 /* HALT */
|
||||||
|
#define STOP_IBKPT 3 /* breakpoint */
|
||||||
|
|
||||||
|
/* Memory */
|
||||||
|
#define ASIZE 16 /* address bits */
|
||||||
|
#define MAXMEMSIZE (1u << ASIZE) /* max mem size */
|
||||||
|
#define AMASK (MAXMEMSIZE - 1) /* address mask */
|
||||||
|
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||||
|
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||||
|
|
||||||
|
/* Architectural constants */
|
||||||
|
#define SIGN 0400000 /* sign */
|
||||||
|
#define DMASK 0777777 /* data mask */
|
||||||
|
#define YMASK 0017777 /* "Y" Mask for address calculation (13 bits) */
|
||||||
|
|
||||||
|
/* I/O status flags */
|
||||||
|
#define IOS_V_LPN 17 /* light pen */
|
||||||
|
#define IOS_V_PETR 16 /* paper tape reader */
|
||||||
|
#define IOS_V_TTO 15 /* typewriter out */
|
||||||
|
#define IOS_V_TTI 14 /* typewriter in */
|
||||||
|
#define IOS_V_PTP 13 /* paper tape punch */
|
||||||
|
#define IOS_V_DRM 12 /* drum */
|
||||||
|
#define IOS_V_SQB 11 /* sequence break */
|
||||||
|
#define IOS_V_PNT 3 /* print done */
|
||||||
|
#define IOS_V_SPC 2 /* space done */
|
||||||
|
#define IOS_V_DCS 1 /* data comm sys */
|
||||||
|
#define IOS_V_DRP 0 /* parallel drum busy */
|
||||||
|
|
||||||
|
#define IOS_LPN (1 << IOS_V_LPN)
|
||||||
|
#define IOS_PETR (1 << IOS_V_PETR)
|
||||||
|
#define IOS_TTO (1 << IOS_V_TTO)
|
||||||
|
#define IOS_TTI (1 << IOS_V_TTI)
|
||||||
|
#define IOS_PTP (1 << IOS_V_PTP)
|
||||||
|
#define IOS_DRM (1 << IOS_V_DRM)
|
||||||
|
#define IOS_SQB (1 << IOS_V_SQB)
|
||||||
|
#define IOS_PNT (1 << IOS_V_PNT)
|
||||||
|
#define IOS_SPC (1 << IOS_V_SPC)
|
||||||
|
#define IOS_DCS (1 << IOS_V_DCS)
|
||||||
|
#define IOS_DRP (1 << IOS_V_DRP)
|
||||||
|
|
||||||
|
#define UNIT_V_MODE (UNIT_V_UF + 0)
|
||||||
|
#define UNIT_MODE (3 << UNIT_V_MODE)
|
||||||
|
#define UNIT_MODE_READIN (3 << UNIT_V_MODE)
|
||||||
|
#define UNIT_MODE_TEST (1 << UNIT_V_MODE)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
16
TX-0/tx0_diag.txt
Normal file
16
TX-0/tx0_diag.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
Programs that are known to work well:
|
||||||
|
|
||||||
|
bin_tic-tac-toe_new_code_12-16-61.bin, seems to fully work:
|
||||||
|
sim> boot petr
|
||||||
|
sim> g (will halt with 205200 in LR)
|
||||||
|
sim> e lr
|
||||||
|
LR: 205200
|
||||||
|
sim> g (again to start game.)
|
||||||
|
bin_tstDisplay.bin, makes a diagonal line on the DPY
|
||||||
|
bin_lightGunTst.bin, can draw on screen with light pen.
|
||||||
|
|
||||||
|
|
||||||
|
bin_newMouse_3-22-66.bin - These kind of work, but mouse gives up easy
|
||||||
|
bin_newMouse_8-14-61.bin - and can crash on complex mazes. Sim bug
|
||||||
|
somewhere.
|
139
TX-0/tx0_dpy.c
Normal file
139
TX-0/tx0_dpy.c
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* *
|
||||||
|
* $Id: tx0_dpy.c 2060 2009-02-24 06:49:07Z hharte $ *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2009-2012, Howard M. Harte *
|
||||||
|
* Copyright (c) 2004, Philip L. Budne *
|
||||||
|
* Copyright (c) 1993-2003, Robert M. Supnik *
|
||||||
|
* *
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||||
|
* a copy of this software and associated documentation files (the *
|
||||||
|
* "Software"), to deal in the Software without restriction, including *
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to *
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to *
|
||||||
|
* the following conditions: *
|
||||||
|
* *
|
||||||
|
* The above copyright notice and this permission notice shall be *
|
||||||
|
* included in all copies or substantial portions of the Software. *
|
||||||
|
* *
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL HOWARD M. HARTE 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 Howard M. Harte shall *
|
||||||
|
* not be used in advertising or otherwise to promote the sale, use or *
|
||||||
|
* other dealings in this Software without prior written authorization *
|
||||||
|
* of Howard M. Harte. *
|
||||||
|
* *
|
||||||
|
* Module Description: *
|
||||||
|
* TX-0 display simulator *
|
||||||
|
* *
|
||||||
|
* Environment: *
|
||||||
|
* User mode only *
|
||||||
|
* *
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#ifdef USE_DISPLAY
|
||||||
|
#include "tx0_defs.h"
|
||||||
|
#include "display/display.h"
|
||||||
|
|
||||||
|
extern int32 ios, iosta, PF;
|
||||||
|
extern int32 stop_inst;
|
||||||
|
extern int32 PEN_HIT;
|
||||||
|
|
||||||
|
t_stat dpy_svc (UNIT *uptr);
|
||||||
|
t_stat dpy_reset (DEVICE *dptr);
|
||||||
|
|
||||||
|
/* DPY data structures
|
||||||
|
dpy_dev DPY device descriptor
|
||||||
|
dpy_unit DPY unit
|
||||||
|
dpy_reg DPY register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CYCLE_TIME 5 /* 5us memory cycle */
|
||||||
|
#define DPY_WAIT (50/CYCLE_TIME) /* 50us */
|
||||||
|
|
||||||
|
UNIT dpy_unit = {
|
||||||
|
UDATA (&dpy_svc, UNIT_ATTABLE, 0), DPY_WAIT };
|
||||||
|
|
||||||
|
DEVICE dpy_dev = {
|
||||||
|
"DPY", &dpy_unit, NULL, NULL,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &dpy_reset,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, DEV_DISABLE };
|
||||||
|
|
||||||
|
/* Display Routine */
|
||||||
|
int32 dpy (int32 ac)
|
||||||
|
{
|
||||||
|
int32 pen_hit;
|
||||||
|
int32 x, y;
|
||||||
|
int level;
|
||||||
|
|
||||||
|
if (dpy_dev.flags & DEV_DIS) /* disabled? */
|
||||||
|
return SCPE_UDIS;
|
||||||
|
|
||||||
|
x = (ac >> 9) & 0777; /* X = high nine bits of AC */
|
||||||
|
y = (ac & 0777); /* Y = low nine bits of AC */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert one's complement -255..+255 center origin
|
||||||
|
* to 0..511 (lower left origin)
|
||||||
|
*/
|
||||||
|
if (x & 0400)
|
||||||
|
x ^= 0400;
|
||||||
|
else
|
||||||
|
x += 255;
|
||||||
|
if (y & 0400)
|
||||||
|
y ^= 0400;
|
||||||
|
else
|
||||||
|
y += 255;
|
||||||
|
|
||||||
|
level = DISPLAY_INT_MAX; /* Maximum intensity */
|
||||||
|
|
||||||
|
if (display_point(x,y,level,0)) {
|
||||||
|
/* here with light pen hit */
|
||||||
|
PF = PF | 010; /* set prog flag 3 */
|
||||||
|
pen_hit = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pen_hit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_activate (&dpy_unit, dpy_unit.wait); /* activate */
|
||||||
|
|
||||||
|
return pen_hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit service routine
|
||||||
|
*
|
||||||
|
* Under X11 this includes polling for events, so it can't be
|
||||||
|
* call TOO infrequently...
|
||||||
|
*/
|
||||||
|
t_stat dpy_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
display_age(dpy_unit.wait*CYCLE_TIME, 1);
|
||||||
|
sim_activate (&dpy_unit, dpy_unit.wait); /* requeue! */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat dpy_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
display_init(DIS_TX0, RES_FULL);
|
||||||
|
display_reset();
|
||||||
|
iosta = iosta & ~(IOS_PNT | IOS_SPC); /* clear flags */
|
||||||
|
sim_cancel (&dpy_unit); /* deactivate unit */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* USE_DISPLAY not defined */
|
||||||
|
char tx0_dpy_unused; /* sometimes empty object modules cause problems */
|
||||||
|
#endif /* USE_DISPLAY not defined */
|
623
TX-0/tx0_stddev.c
Normal file
623
TX-0/tx0_stddev.c
Normal file
|
@ -0,0 +1,623 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* *
|
||||||
|
* $Id: tx0_stddev.c 2063 2009-02-25 07:37:57Z hharte $ *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2009-2012 Howard M. Harte. *
|
||||||
|
* Based on pdp1_stddev.c, Copyright (c) 1993-2006, Robert M. Supnik *
|
||||||
|
* *
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||||
|
* a copy of this software and associated documentation files (the *
|
||||||
|
* "Software"), to deal in the Software without restriction, including *
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to *
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to *
|
||||||
|
* the following conditions: *
|
||||||
|
* *
|
||||||
|
* The above copyright notice and this permission notice shall be *
|
||||||
|
* included in all copies or substantial portions of the Software. *
|
||||||
|
* *
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL HOWARD M. HARTE 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 Howard M. Harte shall *
|
||||||
|
* not be used in advertising or otherwise to promote the sale, use or *
|
||||||
|
* other dealings in this Software without prior written authorization *
|
||||||
|
* of Howard M. Harte. *
|
||||||
|
* *
|
||||||
|
* Module Description: *
|
||||||
|
* TX-0 Standard Devices *
|
||||||
|
* *
|
||||||
|
* Environment: *
|
||||||
|
* User mode only *
|
||||||
|
* *
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
petr paper tape reader
|
||||||
|
ptp paper tape punch
|
||||||
|
tti keyboard
|
||||||
|
tto teleprinter
|
||||||
|
|
||||||
|
Note: PTP timeout must be >10X faster than TTY output timeout for Macro
|
||||||
|
to work correctly!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tx0_defs.h"
|
||||||
|
|
||||||
|
#define FLEXO_STOP 061 /* stop code */
|
||||||
|
#define FLEXO_UC 071
|
||||||
|
#define FLEXO_LC 075
|
||||||
|
#define UC_V 6 /* upper case */
|
||||||
|
#define UC (1 << UC_V)
|
||||||
|
#define BOTH (1 << (UC_V + 1)) /* both cases */
|
||||||
|
#define CW (1 << (UC_V + 2)) /* char waiting */
|
||||||
|
#define TT_WIDTH 077
|
||||||
|
#define UNIT_V_ASCII (UNIT_V_UF + 0) /* ASCII/binary mode */
|
||||||
|
#define UNIT_ASCII (1 << UNIT_V_ASCII)
|
||||||
|
#define PETR_LEADER 20 /* ASCII leader chars */
|
||||||
|
|
||||||
|
#define TRACE_PRINT(dev, level, args) if(dev.dctrl & level) { \
|
||||||
|
printf args; \
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 petr_state = 0;
|
||||||
|
int32 petr_wait = 0;
|
||||||
|
int32 petr_stopioe = 0;
|
||||||
|
int32 petr_uc = 0; /* upper/lower case */
|
||||||
|
int32 petr_hold = 0; /* holding buffer */
|
||||||
|
int32 petr_leader = PETR_LEADER; /* leader count */
|
||||||
|
int32 ptp_stopioe = 0;
|
||||||
|
int32 tti_hold = 0; /* tti hold buf */
|
||||||
|
int32 tty_buf = 0; /* tty buffer */
|
||||||
|
int32 tty_uc = 0; /* tty uc/lc */
|
||||||
|
int32 tto_sbs = 0;
|
||||||
|
|
||||||
|
extern int32 ios, iosta;
|
||||||
|
extern int32 PF, IR, PC, TA;
|
||||||
|
extern int32 M[];
|
||||||
|
|
||||||
|
t_stat petr_svc (UNIT *uptr);
|
||||||
|
t_stat ptp_svc (UNIT *uptr);
|
||||||
|
t_stat tti_svc (UNIT *uptr);
|
||||||
|
t_stat tto_svc (UNIT *uptr);
|
||||||
|
t_stat petr_reset (DEVICE *dptr);
|
||||||
|
t_stat ptp_reset (DEVICE *dptr);
|
||||||
|
t_stat tty_reset (DEVICE *dptr);
|
||||||
|
t_stat petr_boot (int32 unitno, DEVICE *dptr);
|
||||||
|
t_stat petr_attach (UNIT *uptr, char *cptr);
|
||||||
|
|
||||||
|
/* Character translation tables */
|
||||||
|
|
||||||
|
int32 flexo_to_ascii[128] = {
|
||||||
|
/*00*/ 0, 0, 'e', '8', 0, '|', 'a', '3', /* lower case */
|
||||||
|
/*10*/ ' ', '=', 's', '4', 'i', '+', 'u', '2',
|
||||||
|
/*20*/ 0, '.', 'd', '5', 'r', '1', 'j', '7',
|
||||||
|
/*30*/ 'n', ',', 'f', '6', 'c', '-', 'k', 0,
|
||||||
|
/*40*/ 't', 0, 'z', '\b','l', '\t','w', 0,
|
||||||
|
/*50*/ 'h', '\r','y', 0, 'p', 0, 'q', 0,
|
||||||
|
/*60*/ 'o', '*', 'b', 0, 'g', 0, '9', 0,
|
||||||
|
/*70*/ 'm', 0, 'x', 0, 'v', 0, '0', 0,
|
||||||
|
/*00*/ 0, 0, 'E', '8', 0, '_', 'A', '3', /* upper case */
|
||||||
|
/*10*/ ' ', ':', 'S', '4', 'I', '/', 'U', '2',
|
||||||
|
/*20*/ 0, ')', 'D', '5', 'R', '1', 'J', '7',
|
||||||
|
/*30*/ 'N', '(', 'F', '6', 'C', '-', 'K', 0,
|
||||||
|
/*40*/ 'T', 0, 'Z', '\b','L', '\t','W', 0,
|
||||||
|
/*50*/ 'H', '\r','Y', 0, 'P', 0, 'Q', 0,
|
||||||
|
/*60*/ 'O', '*', 'B', 0, 'G', 0, '9', 0,
|
||||||
|
/*70*/ 'M', 0, 'X', 0, 'V', 0, '0', 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
int32 ascii_to_flexo[128] = {
|
||||||
|
/*00*/ 0, 0, 0, BOTH+061, 0, 0, 0, 0, /* STOP mapped to ^C */
|
||||||
|
/*10*/ BOTH+043, BOTH+045, 0, 0, 0, BOTH+051, 0, 0,
|
||||||
|
/*20*/ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
/*30*/ 0, 0, 0, BOTH+020, 0, 0, 0, 0, /* Color Shift mapped to ESC */
|
||||||
|
/*40*/ BOTH+010, 0, 0, 0, 0, 0, 0, 0, /* " ", */
|
||||||
|
/*50*/ UC+021, UC+031, 021, 015, 031, UC+035, UC+011, UC+015, /* ()*+,-./ */
|
||||||
|
/*60*/ 076, 025, 017, 007, 013, 023, 033, 027, /* 0-7 */
|
||||||
|
/*70*/ 003, 066, 0, 0, 0, 011, 0, 0, /* 89:;<=>? */
|
||||||
|
/*00*/ 040, UC+006, UC+062, UC+034, UC+022, UC+002, UC+032, UC+064, /* A-G */
|
||||||
|
/*10*/ UC+050, UC+014, UC+026, UC+036, UC+044, UC+070, UC+030, UC+060, /* H-O */
|
||||||
|
/*20*/ UC+054, UC+056, UC+024, UC+012, 040, 016, 074, 046, /* P-W */
|
||||||
|
/*30*/ UC+072, UC+052, UC+042, 0, 0, 0, 0, UC+005, /* X-Z, */
|
||||||
|
/*40*/ 00, 006, 062, 034, 022, 002, 032, 064, /* a-g */
|
||||||
|
/*50*/ 050, 014, 026, 036, 044, 070, 030, 060, /* h-o */
|
||||||
|
/*60*/ 054, 056, 024, 012, 040, 016, 074, 046, /* p-w */
|
||||||
|
/*70*/ 072, 052, 042, 0, 005, 0, UC+035, BOTH+077 /* x-z, */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PETR data structures
|
||||||
|
|
||||||
|
petr_dev PETR device descriptor
|
||||||
|
petr_unit PETR unit
|
||||||
|
petr_reg PETR register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT petr_unit = {
|
||||||
|
UDATA (&petr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
|
||||||
|
SERIAL_IN_WAIT
|
||||||
|
};
|
||||||
|
|
||||||
|
REG petr_reg[] = {
|
||||||
|
{ ORDATA (BUF, petr_unit.buf, 18) },
|
||||||
|
{ FLDATA (UC, petr_uc, UC_V) },
|
||||||
|
{ FLDATA (DONE, iosta, IOS_V_PETR) },
|
||||||
|
{ ORDATA (HOLD, petr_hold, 9), REG_HRO },
|
||||||
|
{ ORDATA (STATE, petr_state, 5), REG_HRO },
|
||||||
|
{ FLDATA (WAIT, petr_wait, 0), REG_HRO },
|
||||||
|
{ DRDATA (POS, petr_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, petr_unit.wait, 24), PV_LEFT },
|
||||||
|
{ DRDATA (LEADER, petr_leader, 6), REG_HRO },
|
||||||
|
{ FLDATA (STOP_IOE, petr_stopioe, 0) },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
MTAB petr_mod[] = {
|
||||||
|
{ UNIT_ASCII, UNIT_ASCII, "ASCII", "ASCII", NULL },
|
||||||
|
{ UNIT_ASCII, 0, "FLEXO", "FLEXO", NULL },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Debug flags */
|
||||||
|
#define ERROR_MSG (1 << 0)
|
||||||
|
#define TRACE_MSG (1 << 1)
|
||||||
|
#define VERBOSE_MSG (1 << 2)
|
||||||
|
|
||||||
|
/* Debug Flags */
|
||||||
|
static DEBTAB petr_dt[] = {
|
||||||
|
{ "ERROR", ERROR_MSG },
|
||||||
|
{ "TRACE", TRACE_MSG },
|
||||||
|
{ "VERBOSE",VERBOSE_MSG },
|
||||||
|
{ NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE petr_dev = {
|
||||||
|
"PETR", &petr_unit, petr_reg, petr_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &petr_reset,
|
||||||
|
&petr_boot, &petr_attach, NULL,
|
||||||
|
NULL, DEV_DEBUG, (ERROR_MSG),
|
||||||
|
petr_dt, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PTP data structures
|
||||||
|
|
||||||
|
ptp_dev PTP device descriptor
|
||||||
|
ptp_unit PTP unit
|
||||||
|
ptp_reg PTP register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT ptp_unit = {
|
||||||
|
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
|
||||||
|
};
|
||||||
|
|
||||||
|
REG ptp_reg[] = {
|
||||||
|
{ ORDATA (BUF, ptp_unit.buf, 8) },
|
||||||
|
{ FLDATA (DONE, iosta, IOS_V_PTP) },
|
||||||
|
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
|
||||||
|
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
MTAB ptp_mod[] = {
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE ptp_dev = {
|
||||||
|
"PTP", &ptp_unit, ptp_reg, ptp_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &ptp_reset,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, DEV_DEBUG, (ERROR_MSG|TRACE_MSG),
|
||||||
|
petr_dt, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TTI data structures
|
||||||
|
|
||||||
|
tti_dev TTI device descriptor
|
||||||
|
tti_unit TTI unit
|
||||||
|
tti_reg TTI register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||||
|
|
||||||
|
REG tti_reg[] = {
|
||||||
|
{ ORDATA (BUF, tty_buf, 6) },
|
||||||
|
{ FLDATA (UC, tty_uc, UC_V) },
|
||||||
|
{ ORDATA (HOLD, tti_hold, 9), REG_HRO },
|
||||||
|
{ FLDATA (DONE, iosta, IOS_V_TTI) },
|
||||||
|
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
MTAB tti_mod[] = {
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE tti_dev = {
|
||||||
|
"TTI", &tti_unit, tti_reg, tti_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &tty_reset,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, DEV_DEBUG, (ERROR_MSG|TRACE_MSG),
|
||||||
|
petr_dt, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TTO data structures
|
||||||
|
|
||||||
|
tto_dev TTO device descriptor
|
||||||
|
tto_unit TTO unit
|
||||||
|
tto_reg TTO register list
|
||||||
|
*/
|
||||||
|
|
||||||
|
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT * 10 };
|
||||||
|
|
||||||
|
REG tto_reg[] = {
|
||||||
|
{ ORDATA (BUF, tty_buf, 6) },
|
||||||
|
{ FLDATA (UC, tty_uc, UC_V) },
|
||||||
|
{ FLDATA (DONE, iosta, IOS_V_TTO) },
|
||||||
|
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
|
||||||
|
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
MTAB tto_mod[] = {
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE tto_dev = {
|
||||||
|
"TTO", &tto_unit, tto_reg, tto_mod,
|
||||||
|
1, 10, 31, 1, 8, 8,
|
||||||
|
NULL, NULL, &tty_reset,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, DEV_DEBUG, (ERROR_MSG|TRACE_MSG),
|
||||||
|
petr_dt, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Paper tape reader: IOT routine. Points to note:
|
||||||
|
|
||||||
|
- RPA (but not RPB) complements the reader clutch control. Thus,
|
||||||
|
if the reader is running, RPA will stop it.
|
||||||
|
- The status bit indicates data in the reader buffer that has not
|
||||||
|
been transfered to IR. It is cleared by any RB->IR operation,
|
||||||
|
including RRB and the completion pulse.
|
||||||
|
- A reader error on a wait mode operation could hang the simulator.
|
||||||
|
IOH is set; any retry (without RESET) will be NOP'd. Accordingly,
|
||||||
|
the PETR service routine clears IOH on any error during a rpa/rpb i.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32 petr (int32 inst, int32 dev, int32 dat)
|
||||||
|
{
|
||||||
|
int32 tmpAC = 0;
|
||||||
|
int i = 0;
|
||||||
|
t_stat result;
|
||||||
|
ios = 1;
|
||||||
|
|
||||||
|
for (i=0;i<inst;i++) {
|
||||||
|
do {
|
||||||
|
result = petr_svc(&petr_unit);
|
||||||
|
if (result != SCPE_OK) {
|
||||||
|
printf("PETR: Read error\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ((petr_unit.buf & 0100) == 0); /* NOTE: Lines without seventh hole are ignored by PETR. */
|
||||||
|
petr_unit.buf &= 077; /* Mask to 6 bits. */
|
||||||
|
tmpAC |= ((petr_unit.buf & 001) >> 0) << 17; /* bit 0 */
|
||||||
|
tmpAC |= ((petr_unit.buf & 002) >> 1) << 14; /* bit 3 */
|
||||||
|
tmpAC |= ((petr_unit.buf & 004) >> 2) << 11; /* bit 6 */
|
||||||
|
tmpAC |= ((petr_unit.buf & 010) >> 3) << 8; /* bit 9 */
|
||||||
|
tmpAC |= ((petr_unit.buf & 020) >> 4) << 5; /* bit 12 */
|
||||||
|
tmpAC |= ((petr_unit.buf & 040) >> 5) << 2; /* bit 15 */
|
||||||
|
|
||||||
|
if (i < (inst-1)) {
|
||||||
|
uint32 bit0 = (tmpAC & 1) << 17;
|
||||||
|
TRACE_PRINT(petr_dev, TRACE_MSG, ("PETR read [%04x=0x%02x] %03o\n", petr_unit.pos-1, petr_unit.buf, petr_unit.buf));
|
||||||
|
tmpAC >>= 1;
|
||||||
|
tmpAC |= bit0;
|
||||||
|
} else {
|
||||||
|
TRACE_PRINT(petr_dev, TRACE_MSG, ("PETR read [%04x=0x%02x] %03o, tmpAC=%06o\n", petr_unit.pos-1, petr_unit.buf, petr_unit.buf, tmpAC));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmpAC;
|
||||||
|
|
||||||
|
/* sim_activate (&petr_unit, petr_unit.wait); */ /* start reader */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unit service */
|
||||||
|
|
||||||
|
t_stat petr_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 temp;
|
||||||
|
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) { /* attached? */
|
||||||
|
ios = 0;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((temp = getc (uptr->fileref)) != EOF) { /* no, get raw char */
|
||||||
|
uptr->pos = uptr->pos + 1; /* if not eof, count */
|
||||||
|
}
|
||||||
|
if (temp == EOF) { /* end of file? */
|
||||||
|
if (feof (uptr->fileref)) {
|
||||||
|
ios = 0;
|
||||||
|
return SCPE_IOERR;
|
||||||
|
}
|
||||||
|
else perror ("PETR I/O error");
|
||||||
|
clearerr (uptr->fileref);
|
||||||
|
ios = 0;
|
||||||
|
return SCPE_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
uptr->buf = temp;
|
||||||
|
|
||||||
|
ios = 0;
|
||||||
|
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat petr_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
petr_state = 0; /* clear state */
|
||||||
|
petr_wait = 0;
|
||||||
|
petr_hold = 0;
|
||||||
|
petr_uc = 0;
|
||||||
|
petr_unit.buf = 0;
|
||||||
|
iosta = iosta & ~IOS_PETR; /* clear flag */
|
||||||
|
sim_cancel (&petr_unit); /* deactivate unit */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attach routine */
|
||||||
|
|
||||||
|
t_stat petr_attach (UNIT *uptr, char *cptr)
|
||||||
|
{
|
||||||
|
petr_leader = PETR_LEADER; /* set up leader */
|
||||||
|
return attach_unit (uptr, cptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bootstrap routine */
|
||||||
|
extern t_stat cpu_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||||
|
extern UNIT cpu_unit;
|
||||||
|
|
||||||
|
//#define SANITY_CHECK_TAPE
|
||||||
|
|
||||||
|
/* Switches the CPU to READIN mode and starts execution. */
|
||||||
|
t_stat petr_boot (int32 unitno, DEVICE *dptr)
|
||||||
|
{
|
||||||
|
t_stat reason = SCPE_OK;
|
||||||
|
|
||||||
|
#ifdef SANITY_CHECK_TAPE
|
||||||
|
int32 AC, MBR, MAR, IR = 0;
|
||||||
|
int32 blkcnt, chksum = 0, fa, la;
|
||||||
|
int32 addr, tdata;
|
||||||
|
#endif /* SANITY_CHECK_TAPE */
|
||||||
|
|
||||||
|
/* Switch to READIN mode. */
|
||||||
|
cpu_set_mode(&cpu_unit, UNIT_MODE_READIN, NULL, NULL);
|
||||||
|
#ifdef SANITY_CHECK_TAPE
|
||||||
|
for(;(IR != 2) && (IR != 1);) {
|
||||||
|
AC = petr(3,0,0); /* Read three chars from tape into AC */
|
||||||
|
MAR = AC & AMASK; /* Set memory address */
|
||||||
|
IR = AC >> 16;
|
||||||
|
|
||||||
|
if (!MEM_ADDR_OK(MAR)) {
|
||||||
|
TRACE_PRINT(petr_dev, ERROR_MSG, ("READIN: Tape address out of range.\n"));
|
||||||
|
reason = SCPE_FMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (IR) {
|
||||||
|
case 00: /* Storage (sto x) */
|
||||||
|
case 03: /* Storage (opr x) */
|
||||||
|
MBR = petr(3,0,0); /* Read three characters from tape. */
|
||||||
|
TRACE_PRINT(petr_dev, ERROR_MSG, ("READIN: sto @%06o = %06o\n", MAR, MBR));
|
||||||
|
printf("[%06o] = %06o\n", MAR, MBR);
|
||||||
|
break;
|
||||||
|
case 02: /* Transfer Control (trn x) Start Execution */
|
||||||
|
PC = MAR;
|
||||||
|
reason = SCPE_OK; /* let SIMH start execution. */
|
||||||
|
TRACE_PRINT(petr_dev, ERROR_MSG, ("READIN: trn %06o (Start Execution)\n", PC));
|
||||||
|
reason = cpu_set_mode(&cpu_unit, 0, NULL, NULL);
|
||||||
|
break;
|
||||||
|
case 01: /* Transfer (add x) - Halt */
|
||||||
|
PC = MAR;
|
||||||
|
reason = SCPE_STOP; /* let SIMH halt. */
|
||||||
|
TRACE_PRINT(petr_dev, ERROR_MSG, ("READIN: add %06o (Halt)\n", PC));
|
||||||
|
reason = cpu_set_mode(&cpu_unit, 0, NULL, NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reason = SCPE_IERR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blkcnt = 0;
|
||||||
|
while (1) {
|
||||||
|
chksum = 0;
|
||||||
|
|
||||||
|
fa = petr(3,0,0); /* Read three characters from tape. */
|
||||||
|
|
||||||
|
if ((fa & 0400000) || (fa & 0200000)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
chksum += fa;
|
||||||
|
if (chksum > 0777777) {
|
||||||
|
chksum +=1;
|
||||||
|
}
|
||||||
|
chksum &= 0777777;
|
||||||
|
|
||||||
|
la = petr(3,0,0); /* Read three characters from tape. */
|
||||||
|
|
||||||
|
chksum += la;
|
||||||
|
if (chksum > 0777777) {
|
||||||
|
chksum +=1;
|
||||||
|
}
|
||||||
|
chksum &= 0777777;
|
||||||
|
|
||||||
|
la = (~la) & 0177777;
|
||||||
|
|
||||||
|
printf("First Address=%06o, Last Address=%06o\n", fa, la);
|
||||||
|
|
||||||
|
for(addr = fa; addr <= la; addr++) {
|
||||||
|
tdata = petr(3,0,0); /* Read three characters from tape. */
|
||||||
|
chksum += tdata;
|
||||||
|
if (chksum > 0777777) {
|
||||||
|
chksum +=1;
|
||||||
|
}
|
||||||
|
chksum &= 0777777;
|
||||||
|
}
|
||||||
|
|
||||||
|
chksum = (~chksum) & 0777777;
|
||||||
|
|
||||||
|
tdata = petr(3,0,0);
|
||||||
|
|
||||||
|
if (chksum != tdata) {
|
||||||
|
reason = SCPE_FMT;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Block %d: Calculated checksum=%06o, real checksum=%06o, %s\n", blkcnt, chksum, tdata, chksum == tdata ? "OK" : "BAD Checksum!");
|
||||||
|
blkcnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek (petr_dev.units[0].fileref, 0, SEEK_SET);
|
||||||
|
#endif /* SANITY_CHECK_TAPE */
|
||||||
|
|
||||||
|
/* Start Execution */
|
||||||
|
return (reason);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Paper tape punch: IOT routine */
|
||||||
|
|
||||||
|
int32 ptp (int32 inst, int32 dev, int32 dat)
|
||||||
|
{
|
||||||
|
iosta = iosta & ~IOS_PTP; /* clear flag */
|
||||||
|
ptp_unit.buf = dat & 0177;
|
||||||
|
ptp_svc (&ptp_unit);
|
||||||
|
/* sim_activate (&ptp_unit, ptp_unit.wait); */ /* start unit */
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unit service */
|
||||||
|
|
||||||
|
t_stat ptp_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
ios = 1; /* restart */
|
||||||
|
iosta = iosta | IOS_PTP; /* set flag */
|
||||||
|
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||||
|
return SCPE_UNATT;
|
||||||
|
if (putc (uptr->buf, uptr->fileref) == EOF) { /* I/O error? */
|
||||||
|
perror ("PTP I/O error");
|
||||||
|
clearerr (uptr->fileref);
|
||||||
|
return SCPE_IOERR;
|
||||||
|
}
|
||||||
|
uptr->pos = uptr->pos + 1;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat ptp_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
ptp_unit.buf = 0; /* clear state */
|
||||||
|
iosta = iosta & ~IOS_PTP; /* clear flag */
|
||||||
|
sim_cancel (&ptp_unit); /* deactivate unit */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Typewriter IOT routines */
|
||||||
|
|
||||||
|
int32 tti (int32 inst, int32 dev, int32 dat)
|
||||||
|
{
|
||||||
|
iosta = iosta & ~IOS_TTI; /* clear flag */
|
||||||
|
return tty_buf & 077;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 tto (int32 inst, int32 dev, int32 dat)
|
||||||
|
{
|
||||||
|
tty_buf = dat & TT_WIDTH; /* load buffer */
|
||||||
|
ios = 0;
|
||||||
|
tto_svc(&tto_unit);
|
||||||
|
/* sim_activate (&tto_unit, tto_unit.wait); */ /* activate unit */
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unit service routines */
|
||||||
|
|
||||||
|
t_stat tti_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 in = 0, temp = 0;
|
||||||
|
|
||||||
|
sim_activate (uptr, uptr->wait); /* continue poll */
|
||||||
|
if (tti_hold & CW) { /* char waiting? */
|
||||||
|
tty_buf = tti_hold & TT_WIDTH; /* return char */
|
||||||
|
tti_hold = 0; /* not waiting */
|
||||||
|
} else {
|
||||||
|
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp;
|
||||||
|
if (temp & SCPE_BREAK) return SCPE_OK; /* ignore break */
|
||||||
|
temp = temp & 0177;
|
||||||
|
if (temp == 0177) temp = '\b'; /* rubout? bs */
|
||||||
|
sim_putchar (temp); /* echo */
|
||||||
|
if (temp == '\r') sim_putchar ('\n'); /* cr? add nl */
|
||||||
|
in = ascii_to_flexo[temp]; /* translate char */
|
||||||
|
|
||||||
|
if (in == 0) return SCPE_OK; /* no xlation? */
|
||||||
|
if ((in & BOTH) || ((in & UC) == (tty_uc & UC))) {
|
||||||
|
tty_buf = in & TT_WIDTH;
|
||||||
|
} else { /* must shift */
|
||||||
|
tty_uc = in & UC; /* new case */
|
||||||
|
tty_buf = tty_uc? FLEXO_UC: FLEXO_LC;
|
||||||
|
tti_hold = in | CW; /* set 2nd waiting */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iosta = iosta | IOS_TTI; /* set flag */
|
||||||
|
TRACE_PRINT(tti_dev, TRACE_MSG, ("TTI read ASCII: %02x / FLEXO=%03o\n", temp, tty_buf));
|
||||||
|
uptr->pos = uptr->pos + 1;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat tto_svc (UNIT *uptr)
|
||||||
|
{
|
||||||
|
int32 c = 0;
|
||||||
|
t_stat r;
|
||||||
|
|
||||||
|
if (tty_buf == FLEXO_UC) tty_uc = UC; /* upper case? */
|
||||||
|
else if (tty_buf == FLEXO_LC) tty_uc = 0; /* lower case? */
|
||||||
|
else {
|
||||||
|
c = flexo_to_ascii[tty_buf | tty_uc]; /* translate */
|
||||||
|
if (c && ((r = sim_putchar_s (c)) != SCPE_OK)) { /* output; error? */
|
||||||
|
sim_activate (uptr, uptr->wait); /* retry */
|
||||||
|
return ((r == SCPE_STALL)? SCPE_OK: r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iosta = iosta | IOS_TTO; /* set flag */
|
||||||
|
uptr->pos = uptr->pos + 1;
|
||||||
|
if (c == '\r') { /* cr? add lf */
|
||||||
|
sim_putchar ('\n');
|
||||||
|
uptr->pos = uptr->pos + 1;
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset routine */
|
||||||
|
|
||||||
|
t_stat tty_reset (DEVICE *dptr)
|
||||||
|
{
|
||||||
|
tty_buf = 0; /* clear buffer */
|
||||||
|
tty_uc = 0; /* clear case */
|
||||||
|
tti_hold = 0; /* clear hold buf */
|
||||||
|
iosta = (iosta & ~IOS_TTI) | IOS_TTO; /* clear flag */
|
||||||
|
sim_activate (&tti_unit, tti_unit.wait); /* activate keyboard */
|
||||||
|
sim_cancel (&tto_unit); /* stop printer */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
439
TX-0/tx0_sys.c
Normal file
439
TX-0/tx0_sys.c
Normal file
|
@ -0,0 +1,439 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* *
|
||||||
|
* $Id: tx0_sys.c 2061 2009-02-24 07:05:58Z hharte $ *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2009-2012 Howard M. Harte. *
|
||||||
|
* Based on pdp1_sys.c, Copyright (c) 1993-2007, Robert M. Supnik *
|
||||||
|
* *
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||||
|
* a copy of this software and associated documentation files (the *
|
||||||
|
* "Software"), to deal in the Software without restriction, including *
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish, *
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to *
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to *
|
||||||
|
* the following conditions: *
|
||||||
|
* *
|
||||||
|
* The above copyright notice and this permission notice shall be *
|
||||||
|
* included in all copies or substantial portions of the Software. *
|
||||||
|
* *
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL HOWARD M. HARTE 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 Howard M. Harte shall *
|
||||||
|
* not be used in advertising or otherwise to promote the sale, use or *
|
||||||
|
* other dealings in this Software without prior written authorization *
|
||||||
|
* of Howard M. Harte. *
|
||||||
|
* *
|
||||||
|
* Module Description: *
|
||||||
|
* TX-0 simulator interface *
|
||||||
|
* *
|
||||||
|
* Environment: *
|
||||||
|
* User mode only *
|
||||||
|
* *
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#include "tx0_defs.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
extern DEVICE cpu_dev;
|
||||||
|
extern DEVICE petr_dev;
|
||||||
|
extern DEVICE tto_dev;
|
||||||
|
extern DEVICE tti_dev;
|
||||||
|
extern DEVICE ptp_dev;
|
||||||
|
#ifdef USE_DISPLAY
|
||||||
|
extern DEVICE dpy_dev;
|
||||||
|
#endif /* USE_DISPLAY */
|
||||||
|
|
||||||
|
#ifdef USE_FPC
|
||||||
|
extern DEVICE fpc_dev;
|
||||||
|
#endif /* USE_FPC */
|
||||||
|
extern UNIT cpu_unit;
|
||||||
|
extern REG cpu_reg[];
|
||||||
|
extern int32 M[];
|
||||||
|
extern int32 PC;
|
||||||
|
extern int32 ascii_to_flexo[], flexo_to_ascii[];
|
||||||
|
extern int32 sc_map[];
|
||||||
|
extern int32 sim_switches;
|
||||||
|
|
||||||
|
/* SCP data structures and interface routines
|
||||||
|
|
||||||
|
sim_name simulator name string
|
||||||
|
sim_PC pointer to saved PC register descriptor
|
||||||
|
sim_emax number of words for examine
|
||||||
|
sim_devices array of pointers to simulated devices
|
||||||
|
sim_stop_messages array of pointers to stop messages
|
||||||
|
sim_load binary loader
|
||||||
|
*/
|
||||||
|
|
||||||
|
char sim_name[] = "TX-0";
|
||||||
|
|
||||||
|
REG *sim_PC = &cpu_reg[0];
|
||||||
|
|
||||||
|
int32 sim_emax = 1;
|
||||||
|
|
||||||
|
DEVICE *sim_devices[] = {
|
||||||
|
&cpu_dev,
|
||||||
|
&petr_dev,
|
||||||
|
&tti_dev,
|
||||||
|
&tto_dev,
|
||||||
|
&ptp_dev,
|
||||||
|
#ifdef USE_DISPLAY
|
||||||
|
&dpy_dev,
|
||||||
|
#endif/* USE_DISPLAY */
|
||||||
|
#ifdef USE_FPC
|
||||||
|
&fpc_dev,
|
||||||
|
#endif /* USE_FPC */
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *sim_stop_messages[] = {
|
||||||
|
"Unknown error",
|
||||||
|
"Undefined instruction",
|
||||||
|
"HALT instruction",
|
||||||
|
"Breakpoint",
|
||||||
|
"Nested XCT's",
|
||||||
|
"Nested indirect addresses",
|
||||||
|
"Infinite I/O wait state",
|
||||||
|
"DECtape off reel"
|
||||||
|
};
|
||||||
|
|
||||||
|
int32 tx0_getw (FILE *inf)
|
||||||
|
{
|
||||||
|
int32 i, tmp, word;
|
||||||
|
|
||||||
|
word = 0;
|
||||||
|
for (i = 0; i < 3;) {
|
||||||
|
if ((tmp = getc (inf)) == EOF) return -1;
|
||||||
|
if (tmp & 0200) {
|
||||||
|
word = (word << 6) | (tmp & 077);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Symbol tables */
|
||||||
|
typedef struct {
|
||||||
|
int32 opr;
|
||||||
|
char *mnemonic;
|
||||||
|
char *desc;
|
||||||
|
} OPMAP;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *mnemonic;
|
||||||
|
char *desc;
|
||||||
|
} INSTMAP;
|
||||||
|
|
||||||
|
const INSTMAP instmap[] = {
|
||||||
|
/* Store Class */
|
||||||
|
{ "sto", "Store AC" },
|
||||||
|
{ "stx", "Store AC, Indexed" },
|
||||||
|
{ "sxa", "Store XR in Address" },
|
||||||
|
{ "ado", "Add One" },
|
||||||
|
{ "slr", "Store LR" },
|
||||||
|
{ "slx", "Store LR, Indexed" },
|
||||||
|
{ "stz", "Store Zero" },
|
||||||
|
{ "[!sto-nop]", "NOP" },
|
||||||
|
|
||||||
|
/* Add Class */
|
||||||
|
{ "add", "Add" },
|
||||||
|
{ "adx", "Add, Indexed" },
|
||||||
|
{ "ldx", "Load XR" },
|
||||||
|
{ "aux", "Augment XR" },
|
||||||
|
{ "llr", "Load LR" },
|
||||||
|
{ "llx", "Load LR, Indexed" },
|
||||||
|
{ "lda", "Load AC" },
|
||||||
|
{ "lax", "Load AC, Indexed" },
|
||||||
|
|
||||||
|
/* Transfer Class */
|
||||||
|
{ "trn", "Transfer Negative" },
|
||||||
|
{ "trz", "Transfer +/- Zero" },
|
||||||
|
{ "tsx", "Transfer and set Index" },
|
||||||
|
{ "tix", "Transfer and Index" },
|
||||||
|
{ "tra", "Transfer" },
|
||||||
|
{ "trx", "Transfer Indexed" },
|
||||||
|
{ "tlv", "Transfer on external Level" },
|
||||||
|
{ "[!tra-nop]", "NOP" }
|
||||||
|
};
|
||||||
|
|
||||||
|
const OPMAP opmap [] = {
|
||||||
|
{ 0600000, "opr", "No operation" },
|
||||||
|
{ 0600001, "xro", "Clear XR to +0" },
|
||||||
|
{ 0600003, "lxr", "Place LR in XR" },
|
||||||
|
{ 0600012, "cry", "Carry the contents of AC according to bits of LR" },
|
||||||
|
{ 0600022, "lpd", "Logical exclusive or of AC is placed in AC (partial add)" },
|
||||||
|
{ 0600032, "lad", "Add LR to AC" },
|
||||||
|
{ 0600040, "com", "Compliment the AC" },
|
||||||
|
{ 0600072, "lcd", "Contents of LR minus those of AC are placed in AC" },
|
||||||
|
{ 0600130, "xad", "Add index register to accumulator" },
|
||||||
|
{ 0600170, "xcd", "Contents of XR minus those of AC are placed in AC" },
|
||||||
|
{ 0600200, "lro", "Clear LR to +0" },
|
||||||
|
{ 0600300, "xlr", "Place XR in LR" },
|
||||||
|
{ 0600303, "ixl", "Interchange XR and LR" },
|
||||||
|
{ 0600400, "shr", "Shift accumulator right one place, bit 0 remains unchanged" },
|
||||||
|
{ 0600600, "cyr", "Cycle AC right one place" },
|
||||||
|
{ 0603000, "pen", "Contents of light pen and light cannon flip-flops replace contents of AC bits 0 and 1. The flip-flops are cleared." },
|
||||||
|
{ 0604000, "bsr", "Backspace tape unit by one record" },
|
||||||
|
{ 0604004, "rtb", "Read tape binary (odd parity)" },
|
||||||
|
{ 0604004, "rds", "Select tape unit for reading a record" },
|
||||||
|
{ 0604010, "rew", "Rewind tape unit" },
|
||||||
|
{ 0604014, "wtb", "Write tape binary (odd parity)" },
|
||||||
|
{ 0604014, "wrs", "Select tape unit for writing a record" },
|
||||||
|
{ 0604024, "rtd", "Read tape decimal (even parity)" },
|
||||||
|
{ 0604034, "wtd", "Write tape decimal (even parity)" },
|
||||||
|
{ 0607000, "cpf", "The program flag is cleared" },
|
||||||
|
{ 0620000, "cpy", "Transmit information between the live register and selected input-output unit" },
|
||||||
|
{ 0622000, "dis", "Display point on CRT corresponding to contents of AC" },
|
||||||
|
{ 0624000, "prt", "Print one on-line flexo character from bits 2, 5, etc." },
|
||||||
|
{ 0624600, "pnt", "PRT, then cycle AC right once to set up another character" },
|
||||||
|
{ 0625000, "typ", "Read one character from on-line flexowriter into LR bits 12-17" },
|
||||||
|
{ 0626600, "p6h", "Punch one line of paper tape; 6 holes from bits 2, 5, etc. of AC then cycle right once." },
|
||||||
|
{ 0627600, "p7h", "Same as p6h, but punch 7th hole" },
|
||||||
|
{ 0630000, "hlt", "Stops computer" },
|
||||||
|
{ 0631000, "cll", "Clear left half of AC to zero" },
|
||||||
|
{ 0632000, "clr", "Clear right half of AC" },
|
||||||
|
{ 0632022, "---", "CLR+PAD+LMB" },
|
||||||
|
{ 0640001, "axr", "Place AC contents in XR" },
|
||||||
|
{ 0640021, "axo", "AXR, then set AC to +0" },
|
||||||
|
{ 0640030, "cyl", "Cycle AC left one place" },
|
||||||
|
{ 0640031, "alx", "AXR, then cycle AC left once" },
|
||||||
|
{ 0640040, "amz", "Add minus zero to AC" },
|
||||||
|
{ 0640061, "axc", "AXR, then set AC to -0" },
|
||||||
|
{ 0640200, "alr", "Place accumulator contents in live register" },
|
||||||
|
{ 0640201, "---", "ALR+MBX, Place accumulator contents in live register, Transfer MBR to XR." },
|
||||||
|
{ 0640203, "rax", "Place LR in XR, then place AC in LR" },
|
||||||
|
{ 0640205, "orl", "Logical or of AC and LR is placed in LR" },
|
||||||
|
{ 0640207, "anl", "Logical and of AC and LR is placed in LR" },
|
||||||
|
{ 0640220, "alo", "ALR, then set AC to +0" },
|
||||||
|
{ 0640230, "all", "ALR, then cycle left once" },
|
||||||
|
{ 0640231, "---", "AMB+MBL+PAD+CRY+MBX" },
|
||||||
|
{ 0640232, "iad", "Interchange and add AC contents are placed in the LR and the previous contents of the LR ar added to AC" },
|
||||||
|
{ 0640260, "alc", "ALR, then set AC to -0" },
|
||||||
|
{ 0640601, "arx", "AXR, then cycle AC right once" },
|
||||||
|
{ 0647000, "spf", "Place AC in program flag register" },
|
||||||
|
{ 0662020, "dso", "DIS, then clear AC" },
|
||||||
|
{ 0664020, "pno", "PRT, then clear AC" },
|
||||||
|
{ 0664060, "pnc", "PRT, then clear AC to -0" },
|
||||||
|
{ 0666020, "p6o", "p6h then clear AC" },
|
||||||
|
{ 0667020, "p7o", "p7h then clear AC" },
|
||||||
|
{ 0700000, "cla", "Clear entire AC to +0" },
|
||||||
|
{ 0700001, "cax", "Clear AC and XR to +0" },
|
||||||
|
{ 0700012, "lal", "Place LR in AC cycled left once" },
|
||||||
|
{ 0700022, "lac", "Place LR in AC" },
|
||||||
|
{ 0700040, "clc", "Clear and complement: set AC to -0" },
|
||||||
|
{ 0700062, "lcc", "Place complement of LR in AC" },
|
||||||
|
{ 0700072, "laz", "Add LR to minus zero in AC" },
|
||||||
|
{ 0700110, "xal", "XAC, then cycle AC left once" },
|
||||||
|
{ 0700120, "xac", "Place index register in accumulator" },
|
||||||
|
{ 0700160, "xcc", "Place complement of XR in accumulator" },
|
||||||
|
{ 0700200, "cal", "Clear AC and LR to +0" },
|
||||||
|
{ 0700322, "rxe", "Place LR in AC, then place XR in LR" },
|
||||||
|
{ 0700622, "lar", "Place LR in AC cycled right once" },
|
||||||
|
{ 0701000, "tac", "Contents of test accumulator are placed in AC" },
|
||||||
|
{ 0702020, "tbr", "Contents of test buffer register are placed in AC" },
|
||||||
|
{ 0703000, "---", "Clear AC and read light pen" },
|
||||||
|
{ 0706020, "rpf", "The program flag register is placed in AC" },
|
||||||
|
{ 0721000, "rlc", "Read one line paper tape into AC bits 0, 3, etc." },
|
||||||
|
{ 0721600, "rlr", "rlc, then cycle AC right once" },
|
||||||
|
{ 0723000, "r3c", "Read three lines of paper tape" },
|
||||||
|
{ 0723032, "---", "R3C+LMB+PAD+CRY" },
|
||||||
|
{ 0726000, "p6a", "Clear AC and punch a line of blank tape" },
|
||||||
|
{ 0740025, "ora", "Logical or of AC and LR is placed in AC" },
|
||||||
|
{ 0740027, "ana", "Logical and of AC and LR is placed in AC" },
|
||||||
|
{ 0740207, "anc", "ANL, then clear AC" },
|
||||||
|
{ 0740205, "oro", "ORL, then clear AC" },
|
||||||
|
{ 0740222, "ial", "Interchange AC and LR" },
|
||||||
|
{ 0763232, "---", "AMB+CLA+R3L+MBL+LMB+PAD+CRY" },
|
||||||
|
{ 0766020, "p6b", "Punch a line of blank tape, but save AC" },
|
||||||
|
{ 0000000, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Symbolic decode
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*of = output stream
|
||||||
|
addr = current PC
|
||||||
|
*val = pointer to values
|
||||||
|
*uptr = pointer to unit
|
||||||
|
sw = switches
|
||||||
|
Outputs:
|
||||||
|
return = status code
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FMTASC(x) ((x) < 040)? "<%03o>": "%c", (x)
|
||||||
|
#define SIXTOASC(x) flexo_to_ascii[x]
|
||||||
|
#define ASCTOSIX(x) (ascii_to_flexo[x] & 077)
|
||||||
|
|
||||||
|
extern int32 cpu_get_mode (void);
|
||||||
|
extern t_stat fprint_sym_orig (FILE *of, t_addr addr, t_value *val,
|
||||||
|
UNIT *uptr, int32 sw);
|
||||||
|
|
||||||
|
|
||||||
|
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
|
||||||
|
UNIT *uptr, int32 sw)
|
||||||
|
{
|
||||||
|
int32 cflag, i, inst, op;
|
||||||
|
|
||||||
|
if(!cpu_get_mode()) {
|
||||||
|
return fprint_sym_orig (of, addr, val, uptr, sw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inst = val[0];
|
||||||
|
cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
||||||
|
if (sw & SWMASK ('A')) { /* ASCII? */
|
||||||
|
if (inst > 0377) return SCPE_ARG;
|
||||||
|
fprintf (of, FMTASC (inst & 0177));
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
if (sw & SWMASK ('F')) {
|
||||||
|
fputc (flexo_to_ascii[inst & 077], of);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
if (sw & SWMASK ('C')) { /* character? */
|
||||||
|
fprintf (of, "%c", SIXTOASC ((inst >> 12) & 077));
|
||||||
|
fprintf (of, "%c", SIXTOASC ((inst >> 6) & 077));
|
||||||
|
fprintf (of, "%c", SIXTOASC (inst & 077));
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
|
||||||
|
|
||||||
|
/* Instruction decode */
|
||||||
|
|
||||||
|
op = (inst >> 13) & 037;
|
||||||
|
|
||||||
|
if ((op & 030) != 030) /* sto, add, trn (not an opr) */
|
||||||
|
{
|
||||||
|
fprintf (of, "%s %05o (%s)", instmap[op].mnemonic, inst & 017777, instmap[op].desc);
|
||||||
|
} else { /* opr */
|
||||||
|
for(i=0;opmap[i].opr != 0;i++) {
|
||||||
|
if(inst == opmap[i].opr) {
|
||||||
|
fprintf (of, "opr %s (%s)", opmap[i].mnemonic, opmap[i].desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get 18b signed number
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*cptr = pointer to input string
|
||||||
|
*sign = pointer to sign
|
||||||
|
*status = pointer to error status
|
||||||
|
Outputs:
|
||||||
|
val = output value
|
||||||
|
*/
|
||||||
|
|
||||||
|
t_value get_sint (char *cptr, int32 *sign, t_stat *status)
|
||||||
|
{
|
||||||
|
*sign = 1;
|
||||||
|
if (*cptr == '+') {
|
||||||
|
*sign = 0;
|
||||||
|
cptr++;
|
||||||
|
}
|
||||||
|
else if (*cptr == '-') {
|
||||||
|
*sign = -1;
|
||||||
|
cptr++;
|
||||||
|
}
|
||||||
|
return get_uint (cptr, 8, DMASK, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Symbolic input
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
*cptr = pointer to input string
|
||||||
|
addr = current PC
|
||||||
|
uptr = pointer to unit
|
||||||
|
*val = pointer to output values
|
||||||
|
sw = switches
|
||||||
|
Outputs:
|
||||||
|
status = error status
|
||||||
|
*/
|
||||||
|
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int32 cflag, d, i, j, k, sign;
|
||||||
|
t_stat r;
|
||||||
|
static int32 sc_enc[10] = { 0, 01, 03, 07, 017, 037, 077, 0177, 0377, 0777 };
|
||||||
|
char gbuf[CBUFSIZE];
|
||||||
|
|
||||||
|
cflag = (uptr == NULL) || (uptr == &cpu_unit);
|
||||||
|
while (isspace (*cptr)) cptr++;
|
||||||
|
for (i = 1; (i < 3) && (cptr[i] != 0); i++)
|
||||||
|
if (cptr[i] == 0) for (j = i + 1; j <= 3; j++) cptr[j] = 0;
|
||||||
|
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||||
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
|
val[0] = (t_value) cptr[0];
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
|
||||||
|
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
|
||||||
|
val[0] = ((ASCTOSIX (cptr[0]) & 077) << 12) |
|
||||||
|
((ASCTOSIX (cptr[1]) & 077) << 6) |
|
||||||
|
(ASCTOSIX (cptr[2]) & 077);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
|
||||||
|
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
|
||||||
|
if (opcode[i] == NULL) return SCPE_ARG;
|
||||||
|
val[0] = opc_val[i] & DMASK; /* get value */
|
||||||
|
j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */
|
||||||
|
|
||||||
|
switch (j) { /* case on class */
|
||||||
|
|
||||||
|
case I_V_LAW: /* LAW */
|
||||||
|
cflag = 0; /* fall through */
|
||||||
|
case I_V_MRF: case I_V_MRI: /* mem ref */
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0); /* get next field */
|
||||||
|
if ((j != I_V_MRI) && strcmp (gbuf, "I") == 0) { /* indirect? */
|
||||||
|
val[0] = val[0] | IA;
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0);
|
||||||
|
}
|
||||||
|
d = get_uint (gbuf, 8, AMASK, &r);
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
if (d <= DAMASK) val[0] = val[0] | d;
|
||||||
|
else if (cflag && (((addr ^ d) & EPCMASK) == 0))
|
||||||
|
val[0] = val[0] | (d & DAMASK);
|
||||||
|
else return SCPE_ARG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case I_V_SHF: /* shift */
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0);
|
||||||
|
d = get_uint (gbuf, 10, 9, &r);
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
val[0] = val[0] | sc_enc[d];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case I_V_NPN: case I_V_IOT:
|
||||||
|
case I_V_OPR: case I_V_SKP: case I_V_SPC:
|
||||||
|
for (cptr = get_glyph (cptr, gbuf, 0); gbuf[0] != 0;
|
||||||
|
cptr = get_glyph (cptr, gbuf, 0)) {
|
||||||
|
for (i = 0; (opcode[i] != NULL) &&
|
||||||
|
(strcmp (opcode[i], gbuf) != 0); i++) ;
|
||||||
|
if (opcode[i] != NULL) {
|
||||||
|
k = opc_val[i] & DMASK;
|
||||||
|
if ((k != IA) && (((k ^ val[0]) & 0760000) != 0))
|
||||||
|
return SCPE_ARG;
|
||||||
|
val[0] = val[0] | k;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d = get_sint (gbuf, &sign, &r);
|
||||||
|
if (r != SCPE_OK) return SCPE_ARG;
|
||||||
|
if (sign == 0) val[0] = val[0] + d;
|
||||||
|
else if (sign < 0) val[0] = val[0] - d;
|
||||||
|
else val[0] = val[0] | d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} /* end case */
|
||||||
|
if (*cptr != 0) return SCPE_ARG; /* junk at end? */
|
||||||
|
#endif
|
||||||
|
return SCPE_ARG;
|
||||||
|
}
|
133
TX-0/tx0_sys_orig.c
Normal file
133
TX-0/tx0_sys_orig.c
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* *
|
||||||
|
* $Id: tx0_sys_orig.c 2065 2009-02-25 15:05:00Z hharte $ *
|
||||||
|
* *
|
||||||
|
* Copyright (c) 2009-2012 Howard M. Harte. *
|
||||||
|
* *
|
||||||
|
* 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 HOWARD M. HARTE 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 Howard M. Harte shall *
|
||||||
|
* not be used in advertising or otherwise to promote the sale, use or *
|
||||||
|
* other dealings in this Software without prior written authorization *
|
||||||
|
* of Howard M. Harte. *
|
||||||
|
* *
|
||||||
|
* Module Description: *
|
||||||
|
* TX-0 simulator interface *
|
||||||
|
* *
|
||||||
|
* Environment: *
|
||||||
|
* User mode only *
|
||||||
|
* *
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#include "tx0_defs.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32 opr;
|
||||||
|
char *mnemonic;
|
||||||
|
char *desc;
|
||||||
|
} OPMAP;
|
||||||
|
|
||||||
|
const OPMAP opmap_orig [] = {
|
||||||
|
{ 0700000, "cll", "Clear the left nine digital positions of the AC" },
|
||||||
|
{ 0640000, "clr", "Clear the right nine digital positions of the AC" },
|
||||||
|
{ 0620000, "ios", "In-Out Stop" },
|
||||||
|
{ 0630000, "hlt", "Halt the computer" },
|
||||||
|
{ 0607000, "p7h", "Punch holes 1-6 in flexo tape Also punch a 7th hole on tape" },
|
||||||
|
{ 0606000, "p6h", "Punch holes 1-6 in flexo tape" },
|
||||||
|
{ 0604000, "pnt", "Print one flexowrite charater" },
|
||||||
|
{ 0601000, "r1c", "Read one line of flexo tape" },
|
||||||
|
{ 0603000, "r3c", "Read three lines of flexo tape" },
|
||||||
|
{ 0602000, "dis", "Intesnsify a point on the scope from x,y in AC" },
|
||||||
|
{ 0600400, "shr", "Shift the AC right one place" },
|
||||||
|
{ 0600600, "cyr", "Cycle the AC right one digital position (AC17 -> AC0)" },
|
||||||
|
{ 0600200, "mlr", "Store the contents of the MBR in the LR" },
|
||||||
|
{ 0600100, "pen", "Read the light pen flip flops 1 and 2 into AC0 and AC1" },
|
||||||
|
{ 0600004, "tac", "Insert a one in each digital position of the AC whereever there is a one in the corresponding digital position of the TAC" },
|
||||||
|
{ 0600040, "com", "Complement every digit in the accumulator" },
|
||||||
|
{ 0600020, "pad", "Partial add AC to MBR" },
|
||||||
|
{ 0600010, "cry", "Partial add the 18 digits of the AC to the corresponding 18 digits of the carry" },
|
||||||
|
{ 0600001, "amb", "Store the contents of the AC in the MBR" },
|
||||||
|
{ 0600003, "tbr", "Store the contents of the TBR in the MBR" },
|
||||||
|
{ 0600002, "lmb", "Store the contents of the LR in the MBR" },
|
||||||
|
/* Combined Operate Class Commands */
|
||||||
|
{ 0740000, "cla", "Clear the AC" },
|
||||||
|
{ 0600031, "cyl", "Cycle the AC left one digital position" },
|
||||||
|
{ 0740040, "clc", "Clear and complement AC" },
|
||||||
|
{ 0622000, "dis", "Display (note IOS must be included for in-out cmds)" },
|
||||||
|
{ 0760000, "ios+cll+clr", "In out stop with AC cleared" },
|
||||||
|
{ 0627600, "ios+p7h+cyr", "Punch 7 holes and cycle AC right" },
|
||||||
|
{ 0626600, "ios+p6h+cyr", "Punch 6 holes and cycle AC right" },
|
||||||
|
{ 0766000, "ios+cll+clr+p6h", "Clear the AC and punch a blank space on tape" },
|
||||||
|
{ 0624600, "ios+pnt+cyr", "Print and cycle AC right" },
|
||||||
|
{ 0627021, "ios+p7h+amb+pad", "Punch 7 holes and leave AC cleared" },
|
||||||
|
{ 0626021, "ios+p6h+amb+pad", "Punch 6 holes and leave AC cleared" },
|
||||||
|
{ 0624021, "ios+pnt+amb+pad", "Print and leave AC cleared" },
|
||||||
|
{ 0741000, "cll+clr+ric", "Clear AC and start PETR running (note computer hasn't stopped to wait for information" },
|
||||||
|
{ 0601031, "ric+amb+pad+cry", "Start PETR running and cycle AC left" },
|
||||||
|
{ 0601600, "ric+cyr", "Start PETR running and cycle right" },
|
||||||
|
{ 0763000, "cll+clr+ios+r3c", "Clear AC and read 3 lines of tape" },
|
||||||
|
{ 0761000, "cll+clr+ios+ric", "Clear AC and read one line of tape" },
|
||||||
|
{ 0761031, "cll+clr+ios+ric+pad+cry", "Read 1 line of tape and cycle AC left" },
|
||||||
|
{ 0761600, "cll+clr+ios+ric+cyr", "Read 1 line of tape and cycle right" },
|
||||||
|
{ 0740004, "cll+clr+tac", "Put contents of TAC in AC" },
|
||||||
|
{ 0600030, "pad+cry", "Full-add the MBR and AC and leave sum in AC" },
|
||||||
|
{ 0740022, "cll+clr+lmb+pad", "Clear the AC - store LR contents in memory buffer register add memory buffer to AC - i.e., store live reg. contents in AC (LAC)" },
|
||||||
|
{ 0600201, "amb+mlr", "Store contents of AC in MBR, store contents of MBR in LR i.e., store contents of AC in LR. (ALR)" },
|
||||||
|
{ 0600022, "lmb+pad", "Store the contents of LR in MBR, partial add AC and MBR i.e., partial add LR to AC. (LPD)" },
|
||||||
|
/* { 0600200, "mlr", "Since MLR alone will ahve a clear MBR, this is really clear LR (LRO)" }, */
|
||||||
|
{ 0600032, "lmb+pad+cry", "Full-add the LR to the AC (LAD)" },
|
||||||
|
{ 0740023, "cll+clr+tbr+pad", "Store contents of TBR in AC" },
|
||||||
|
{ 0000000, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
t_stat fprint_sym_orig (FILE *of, t_addr addr, t_value *val,
|
||||||
|
UNIT *uptr, int32 sw)
|
||||||
|
{
|
||||||
|
int32 i, inst, op;
|
||||||
|
|
||||||
|
inst = val[0];
|
||||||
|
|
||||||
|
/* Instruction decode */
|
||||||
|
|
||||||
|
op = (inst >> 16) & 3;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case 0:
|
||||||
|
fprintf (of, "sto %06o", inst & 0177777); /* opcode */
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fprintf (of, "add %06o", inst & 0177777); /* opcode */
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fprintf (of, "trn %06o", inst & 0177777); /* opcode */
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
for(i=0;opmap_orig[i].opr != 0;i++) {
|
||||||
|
if(inst == opmap_orig[i].opr) {
|
||||||
|
fprintf (of, "opr %s (%s)", opmap_orig[i].mnemonic, opmap_orig[i].desc); /* opcode */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
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;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue