simh-testsetgenerator/PDP11/pdp11_vt.c
2019-02-07 08:16:31 +01:00

1134 lines
70 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifdef USE_DISPLAY
/* pdp11_vt.c: PDP-11 VT11/VS60 Display Processor Simulation
Copyright (c) 2003-2004, Philip L. Budne, Douglas A. Gwyn
Copyright (c) 1993-2003, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of the authors shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the authors.
vt VT11/VS60 Display Processor
05-Feb-04 DAG Improved VT11 emulation
Added VS60 support
14-Sep-03 PLB Start from pdp11_lp.c
*/
/*
* this file is just a thin layer of glue to the simulator-
* independent XY Display simulation
*/
#if defined (VM_VAX) /* VAX version */
#include "vax_defs.h"
#elif defined(VM_PDP11) /* PDP-11 version */
#include "pdp11_defs.h"
#else
#error "VT11/VS60 is supported only on the PDP-11 and VAX"
#endif
#include "display/display.h"
#include "display/vt11.h"
#include "sim_video.h"
/*
* Timing parameters. Should allow some runtime adjustment,
* since several different configurations were shipped, including:
*
* GT40: PDP-11/05 with VT11 display processor
* GT44: PDP-11/40 with VT11 display processor
* GT46: PDP-11/34 with VT11 display processor
* GT62: PDP-11/34a with VS60 display system
*/
/*
* run a VT11/VS60 cycle every this many PDP-11 "cycle" times;
*
* this includes phosphor aging and polling for events (mouse movement)
* every refresh_interval (determined internally while processing the
* VT11/VS60 cycle).
*/
#define VT11_DELAY 1
/*
* memory cycle time
*/
#define MEMORY_CYCLE 1 /* either .98 or 1.2 us? */
/*
* delay in microseconds between VT11/VS60 cycles:
* VT11/VS60 and PDP-11 CPU's share the same memory bus,
* and each VT11/VS60 instruction requires a memory reference;
* figure each PDP11 instruction requires two memory references
*/
#define CYCLE_US (MEMORY_CYCLE*(VT11_DELAY*2+1))
extern int32 int_vec[IPL_HLVL][32];
t_stat vt_rd(int32 *data, int32 PA, int32 access);
t_stat vt_wr(int32 data, int32 PA, int32 access);
t_stat vt_svc(UNIT *uptr);
t_stat vt_reset(DEVICE *dptr);
t_stat vt_boot(int32 unit, DEVICE *dptr);
t_stat vt_set_crt(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat vt_show_crt(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat vt_set_scale(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat vt_show_scale(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat vt_set_hspace(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat vt_show_hspace(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat vt_set_vspace(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat vt_show_vspace(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat vt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *vt_description (DEVICE *dptr);
/* VT11/VS60 data structures
vt_dev VT11 device descriptor
vt_unit VT11 unit descriptor
vt_reg VT11 register list
vt_mod VT11 modifier list
*/
#define IOLN_VT11 010 /* VT11 */
#define IOLN_VS60 040 /* VS60 */
DIB vt_dib = { IOBA_AUTO, IOLN_VT11, &vt_rd, &vt_wr,
4, IVCL(VTST), VEC_AUTO, {NULL}, IOLN_VT11 };
/* (VT11 uses only the first 3 interrupt vectors) */
UNIT vt_unit = {
UDATA (&vt_svc, 0, 0), VT11_DELAY};
REG vt_reg[] = {
{ DRDATAD (CYCLE, vt_unit.wait, 24, "VT11/VS60 cycle"), REG_NZ + PV_LEFT },
{ GRDATA (DEVADDR, vt_dib.ba, DEV_RDX, 32, 0), REG_HRO },
{ GRDATA (DEVVEC, vt_dib.vec, DEV_RDX, 16, 0), REG_HRO },
{ NULL } };
MTAB vt_mod[] = {
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "CRT", "CRT={VR14|VR17|VR48}",
&vt_set_crt, &vt_show_crt, NULL, "CRT Type" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "SCALE", "SCALE={1|2|4|8}",
&vt_set_scale, &vt_show_scale, NULL, "Pixel Scale Factor" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "HSPACE", "HSPACE={NARROW|NORMAL}",
&vt_set_hspace, &vt_show_hspace, NULL, "Horizontal Spacing" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VSPACE", "VSPACE={TALL|NORMAL}",
&vt_set_vspace, &vt_show_vspace, NULL, "Vertical Spacing" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL, "Interrupt vector" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE",
&set_addr_flt, NULL, NULL, "Enable autoconfiguration of address & vector" },
{ 0 } };
static t_bool vt_stop_flag = FALSE;
static void vt_quit_callback (void)
{
vt_stop_flag = TRUE;
}
/* Debug detail levels */
#define DEB_OPS 0001 /* transactions */
#define DEB_RRD 0002 /* reg reads */
#define DEB_RWR 0004 /* reg writes */
#define DEB_TRC 0010 /* trace */
#define DEB_STINT 0020 /* STOP interrupts */
#define DEB_LPINT 0040 /* Light Pen interrupts */
#define DEB_CHINT 0100 /* CHAR interrupts */
#define DEB_NMINT 0200 /* NAME interrupts */
#define DEB_INT 0360 /* All Interrupts */
#define DEB_VT11 0400 /* VT11 activities */
#define DEB_VMOU SIM_VID_DBG_MOUSE /* Video mouse */
#define DEB_VKEY SIM_VID_DBG_KEY /* Video key */
#define DEB_VCUR SIM_VID_DBG_CURSOR /* Video cursor */
#define DEB_VVID SIM_VID_DBG_VIDEO /* Video */
DEBTAB vt_deb[] = {
{ "OPS", DEB_OPS, "transactions" },
{ "RRD", DEB_RRD, "register reads" },
{ "RWR", DEB_RWR, "register writes" },
{ "INT", DEB_INT, "All Interrupts" },
{ "STOP", DEB_STINT, "STOP interrupts" },
{ "LPEN", DEB_LPINT, "Light Pen interrupts" },
{ "CHAR", DEB_CHINT, "CHAR interrupts" },
{ "NAME", DEB_NMINT, "NAME interrupts" },
{ "VT11", DEB_VT11, "VT11 activities" },
{ "TRACE", DEB_TRC, "trace" },
{ "VMOU", DEB_VMOU, "Video Mouse" },
{ "VKEY", DEB_VKEY, "Video Key" },
{ "VCUR", DEB_VCUR, "Video Cursor" },
{ "VVID", DEB_VVID, "Video Video" },
{ NULL, 0 }
};
DEVICE vt_dev = {
"VT", &vt_unit, vt_reg, vt_mod,
1, 8, 31, 1, DEV_RDX, 16,
NULL, NULL, &vt_reset,
&vt_boot, NULL, NULL,
&vt_dib, DEV_DIS | DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG,
0, vt_deb, NULL, NULL, NULL, &vt_help, NULL,
&vt_description
};
const char *vt_regnam[] = {
"DPC",
"MPR",
"XPR",
"YPR",
"RR",
"SPR",
"XOR",
"YOR",
"ANR",
"SCR",
"NR",
"SDR",
"STR",
"SAR",
"ZPR",
"ZOR",
};
/* VT11/VS60 routines
vt_rd I/O page read
vt_wr I/O page write
vt_svc process event
vt_reset process reset
vt_boot bootstrap device
*/
t_stat
vt_rd(int32 *data, int32 PA, int32 access)
{
t_stat stat = SCPE_OK;
switch (PA & 036) {
case 000: *data = vt11_get_dpc(); break;
case 002: *data = vt11_get_mpr(); break;
case 004: *data = vt11_get_xpr(); break;
case 006: *data = vt11_get_ypr(); break;
case 010: if (VS60) *data = vt11_get_rr(); else stat = SCPE_NXM; break;
case 012: if (VS60) *data = vt11_get_spr(); else stat = SCPE_NXM; break;
case 014: if (VS60) *data = vt11_get_xor(); else stat = SCPE_NXM; break;
case 016: if (VS60) *data = vt11_get_yor(); else stat = SCPE_NXM; break;
case 020: if (VS60) *data = vt11_get_anr(); else stat = SCPE_NXM; break;
case 022: if (VS60) *data = vt11_get_scr(); else stat = SCPE_NXM; break;
case 024: if (VS60) *data = vt11_get_nr(); else stat = SCPE_NXM; break;
case 026: if (VS60) *data = vt11_get_sdr(); else stat = SCPE_NXM; break;
case 030: if (VS60) *data = vt11_get_str(); else stat = SCPE_NXM; break;
case 032: if (VS60) *data = vt11_get_sar(); else stat = SCPE_NXM; break;
case 034: if (VS60) *data = vt11_get_zpr(); else stat = SCPE_NXM; break;
case 036: if (VS60) *data = vt11_get_zor(); else stat = SCPE_NXM; break;
default: stat = SCPE_NXM;
}
sim_debug (DEB_RRD, &vt_dev, "vt_rd(%s-PA=0%o,data=0x%X(0%o),access=%d)\n", vt_regnam[(PA & 036)>>1], (int)PA, (int)*data, (int)*data, (int)access);
return stat;
}
t_stat
vt_wr(int32 data, int32 PA, int32 access)
{
uint16 d = data & 0177777; /* mask just in case */
sim_debug (DEB_RWR, &vt_dev, "vt_wr(%s-PA=0%o,data=0x%X(0%o),access=%d)\n", vt_regnam[(PA & 036)>>1], (int)PA, (int)data, (int)data, (int)access);
switch (PA & 037) {
case 000: /* DPC */
/* set the simulator PC */
vt11_set_dpc(d);
/* Interrupt requests are cleared as each vector is dispatched,
so in general, no need to clear interrupt requests here.
However, if software is running at high IPL (diagnostics maybe)
clearing them here does no harm */
if (INT_IS_SET(VTST)) {
sim_debug (DEB_STINT, &vt_dev, "CLR_INT(all)\n");
CLR_INT (VTST);
}
if (INT_IS_SET(VTLP)) {
sim_debug (DEB_LPINT, &vt_dev, "CLR_INT(all)\n");
CLR_INT (VTLP);
}
if (INT_IS_SET(VTCH)) {
sim_debug (DEB_CHINT, &vt_dev, "CLR_INT(all)\n");
CLR_INT (VTCH);
}
if (INT_IS_SET(VTNM)) {
sim_debug (DEB_NMINT, &vt_dev, "CLR_INT(all)\n");
CLR_INT (VTNM);
}
/* start the display processor by running a cycle */
vt_svc (&vt_unit);
return SCPE_OK;
case 002: vt11_set_mpr(d); return SCPE_OK;
case 004: vt11_set_xpr(d); return SCPE_OK;
case 006: vt11_set_ypr(d); return SCPE_OK;
case 010: if (!VS60) break; vt11_set_rr(d); return SCPE_OK;
case 012: if (!VS60) break; vt11_set_spr(d); return SCPE_OK;
case 014: if (!VS60) break; vt11_set_xor(d); return SCPE_OK;
case 016: if (!VS60) break; vt11_set_yor(d); return SCPE_OK;
case 020: if (!VS60) break; vt11_set_anr(d); return SCPE_OK;
case 022: if (!VS60) break; vt11_set_scr(d); return SCPE_OK;
case 024: if (!VS60) break; vt11_set_nr(d); return SCPE_OK;
case 026: if (!VS60) break; vt11_set_sdr(d); return SCPE_OK;
case 030: if (!VS60) break; vt11_set_str(d); return SCPE_OK;
case 032: if (!VS60) break; vt11_set_sar(d); return SCPE_OK;
case 034: if (!VS60) break; vt11_set_zpr(d); return SCPE_OK;
case 036: if (!VS60) break; vt11_set_zor(d); return SCPE_OK;
}
return SCPE_NXM;
}
/*
* here to run a display processor cycle, called as a SIMH
* "device service routine".
*/
t_stat
vt_svc(UNIT *uptr)
{
sim_debug (DEB_TRC, &vt_dev, "vt_svc(wait=%d,DPC=0%o)\n", uptr->wait, vt11_get_dpc());
if (vt11_cycle(uptr->wait, 0))
sim_activate_after (uptr, uptr->wait); /* running; reschedule */
if (vt_stop_flag) {
vt_stop_flag = FALSE; /* reset flag after we notice it */
return SCPE_STOP;
}
return SCPE_OK;
}
t_stat
vt_reset(DEVICE *dptr)
{
DEVICE *ng_dptr;
ng_dptr = find_dev ("NG");
if (!(dptr->flags & DEV_DIS) &&
(ng_dptr != NULL) && !(ng_dptr->flags & DEV_DIS)) {
dptr->flags |= DEV_DIS;
return sim_messagef (SCPE_NOFNC, "VT and NG device can't both be enabled\n");
}
if (!(dptr->flags & DEV_DIS))
vt11_reset(dptr, DEB_VT11);
vid_register_quit_callback (&vt_quit_callback);
sim_debug (DEB_INT, &vt_dev, "CLR_INT(all)\n");
CLR_INT (VTST);
CLR_INT (VTLP);
CLR_INT (VTCH);
CLR_INT (VTNM);
sim_cancel (dptr->units); /* deactivate unit */
return auto_config ("VT", (dptr->flags & DEV_DIS) ? 0 : 1);
}
#include "pdp11_vt_lunar_rom.h" /* Lunar Lander image */
/*
* GT4x/GT62 bootstrap (acts as remote terminal)
*
*/
t_addr vt_rom_base = 017766000;
uint16 vt_boot_rom[] = {
// ; .ASECT
//
// ;BOOTVT.S09 5/2/72
//
//
// ; VT-40 BOOTSTRAP LOADER, VERSION S09, RELEASE R01, 5/2/72
//
// ; COPYRIGHT 1972, DIGITAL EQUIPMENT CORPORATION
// ; 146 MAIN STREET
// ; MAYNARD, MASSACHUSSETTS
// ; 01754
//
//
// ; WRITTEN BY JACK BURNESS, SENIOR SYSTEMS ARCHITECT!
//
//
//
//
// ; THIS ROUTINE IS INTENDED TO BE LOADED IN THE ROM PORTION OF THE VT-40.
//
//
// ; REGISTER DEFINITIONS:
//
// 000000 R0=%0
// 000001 R1=%1
// 000002 R2=%2
// 000003 R3=%3
// 000004 R4=%4
// 000005 R5=%5
// 000006 R6=%6
// 000007 R7=%7
//
// 000006 SP=R6
// 000007 PC=R7
//
// 000000 RET1=R0 ;RETURN OF VALUE REGISTER.
// 000001 INP1=R1 ;ARGUMENT FOR CALLED FUNCTION
// 000002 INP2=R2 ;SECOND ARGUMENT.
// 000003 WORK1=R3 ;FIRST WORK REGISTER.
// 000004 WORK2=R4 ;SECOND WORKING REGISTER.
// 000005 SCR1=R5 ;SCRATCH REGISTER.
//
// 000003 L.CKSM=WORK1 ;OVERLAPPING DEFINITIONS FOR LOADER PORTION.
// 000000 L.BYT=RET1
// 000005 L.BC=SCR1
// 000001 L.ADR=INP1
//
//
//
//
// 016000 COREND=16000 ;FIRST LOCATION OF NON-CORE.
//
// ; ROMORG=037000 ;WHERE THE ROM PROGRAM SHOULD GO.
// 166000 ROMORG=166000 ;WHERE THE ROM PROGRAM SHOULD GO.
// 000000 STARTX=0 ;WHERE TO START DISPLAYING THE X POSITIONS.
// 001360 STARTY=1360 ;WHERE TO START DISPLAYING THE Y.
//
// 172000 VT40PC=172000 ;VT40 PROGRAM COUNTER.
// 177560 KBDIS=177560 ;TTY INPUT STATUS.
// 175614 P10OS=175614 ;PDP-10 OUTPUT STATUS.
// 175610 P10IS=175610 ;PDP-10 INPUT STATUS.
//
// 177562 KBDIB=KBDIS+2 ;TTY INPUT BUFFER.
// 175612 P10IB=P10IS+2 ;PDP-10 INPUT CHARACTER.
// 175616 P10OB=P10OS+2 ;PDP-10 OUTPUT BUFFER.
//
//
// 015776 P10OC=COREND-2 ;CHARACTER TO BE SENT TO THE PDP-10
// 015772 P10IC=P10OC-4 ;INPUT CHARACTER FROM 10 PLUS ONE SAVE CHARACTER
// 015770 STKSRT=P10IC-2 ;FIRST LOCATION OF STACK.
//
//
// 160000 JMPDIS=160000 ;THE VT-40 DISPLAY JUMP INSTRUCTION.
//
//
// 000024 PWRFAL=24 ;POWER FAIL RESTART LOCATION.
//
//
// 166000 .=ROMORG ;SET THE ORIGIN NOW!!!!
//
//
0012705, 0000026, // 166000 012705 000026 START: MOV #PWRFAL+2,SCR1 ;PICK UP POINTER TO P.F. STATUS.
0005015, // 166004 005015 CLR @SCR1 ;CLEAR IT OUT TO BE SURE.
0010745, // 166006 010745 MOV PC,-(SCR1) ;SET UP THE RESTART LOCATION.
//
0000005, // 166010 000005 RESET ;RESET THE BUS.
//
0012767, 0000007, 0007570, // 166012 012767 000007 007570 MOV #7,P10IS ;INITIALIZE PDP-10 INPUT
0012767, 0000001, 0011532, // 166020 012767 000001 011532 MOV #1,KBDIS ;INITIALIZE TTY INPUT.
0012767, 0000201, 0007560, // 166026 012767 000201 007560 MOV #201,P10OS ;INITIALIZE PDP-10 OUTPUT.
//
//
//
0012706, 0015770, // 166034 012706 015770 RESTRT: MOV #STKSRT,SP ;SET UP THE STACK NOW!
0005001, // 166040 005001 CLR L.ADR ;CLEAR ADDRESS POINTER.
0012702, 0160000, // 166042 012702 160000 MOV #JMPDIS,INP2 ;PLACE A DISPLAY JUMP INSTRUCTION IN A REGISTER.
//
//
0010221, // 166046 010221 MOV INP2,(L.ADR)+ ;MOVE IT TO LOCATION 0.
0012711, 0166756, // 166050 012711 166756 MOV #DISPRG,(L.ADR) ;MOVE ADDRESS POINTER INTO 2.
0012701, 0000030, // 166054 012701 000030 MOV #PWRFAL+4,L.ADR ;SET UP WHERE WE WILL STORE CHARACTERS.
0005000, // 166060 005000 CLR RET1 ;PREPARE TO INSERT A ZERO CHARACTER.
0004767, 0000022, // 166062 004767 000022 JSR PC,DOCHAR ;INSERT IT NOW.
0005067, 0003706, // 166066 005067 003706 CLR VT40PC ;CLEAR THE DISPLAY PROGRAM COUNTER AND START.
//
0004767, 0000210, // 166072 004767 000210 MAJOR: JSR PC,GETCHR ;GET A CHARACTER NOW.
0000240, // 166076 000240 NOP
0000240, // 166100 000240 NOP
0000240, // 166102 000240 NOP
0012746, 0166072, // 166104 012746 166072 MOV #MAJOR,-(SP) ;INSERT IN DISPLAY BUFFER NOW.
//
0010105, // 166110 010105 DOCHAR: MOV L.ADR,SCR1 ;GET CURRENT BUFFER POSITION NOW.
0022525, // 166112 022525 CMP (SCR1)+,(SCR1)+ ;BYPASS CURRENT DISPLAY JUMP.
0005025, // 166114 005025 CLR (SCR1)+ ;CLEAR FUTURE ADDRESS FOR JUMP.
0010225, // 166116 010225 MOV INP2,(SCR1)+ ;STICK IN TEMPORARY JUMP WHILE WE REPLACE CURREN
0005015, // 166120 005015 CLR (SCR1) ;A DISPLAY JUMP TO ZERO.
0005011, // 166122 005011 CLR (L.ADR) ;NOW REPLACE CURRENT DISPLAY JUMP BY THE CHARACT
0050021, // 166124 050021 BIS RET1,(L.ADR)+ ;IT'S DONE THIS WAY TO WASTE 2 CYCLES.
0010211, // 166126 010211 MOV INP2,(L.ADR) ;TO AVOID TIMING PROBLEMS WITH THE VT40.
0000207, // 166130 000207 RTS PC ;AND FINALLY RETURN.
//
//
0004767, 0000124, // 166132 004767 000124 GET8: JSR PC,GETSIX ;GET SIX BITS NOW.
0010046, // 166136 010046 MOV RET1,-(SP) ;SAVE THE CHARACTER NOW.
0000401, // 166140 000401 BR GETP84 ;BYPASS THE 8'ER
0005002, // 166142 005002 GET84: CLR INP2 ;RESET THE MAGIC REGISTER NOW.
0005722, // 166144 005722 GETP84: TST (INP2)+ ;INCREMENT WHERE TO GO.
0066207, 0166250, // 166146 066207 166250 ADD GET8TB(INP2),PC ;UPDATE PC NOW.
//
// 166152 GET8P=.
//
0004767, 0000104, // 166152 004767 000104 GET81: JSR PC,GETSIX ;GET A CHARACTER NOW.
0010004, // 166156 010004 MOV RET1,WORK2 ;SAVE FOR A SECOND.
0006300, // 166160 006300 ASL RET1
0006300, // 166162 006300 ASL RET1 ;SHIFT TO LEFT OF BYTE
0106300, // 166164 106300 ASLB RET1
0106116, // 166166 106116 ROLB @SP ;PACK THEM IN.
0106300, // 166170 106300 ASLB RET1
//
//
0106116, // 166172 106116 ROLB @SP ;A GOOD 8 BIT THING.
0012600, // 166174 012600 MOV (SP)+,RET1 ;POP AND RETURN NOW.
0000207, // 166176 000207 RTS PC
//
0006300, // 166200 006300 GET82: ASL RET1 ;WORST CASE, SHIFT 4
0006300, // 166202 006300 ASL RET1
0106300, // 166204 106300 ASLB RET1
0106104, // 166206 106104 ROLB WORK2
0106300, // 166210 106300 ASLB RET1
0106104, // 166212 106104 ROLB WORK2
0106300, // 166214 106300 ASLB RET1
0106104, // 166216 106104 ROLB WORK2
0106300, // 166220 106300 ASLB RET1
0106104, // 166222 106104 ROLB WORK2
0010400, // 166224 010400 MOV WORK2,RET1
0012604, // 166226 012604 MOV (SP)+,WORK2
0000207, // 166230 000207 RTS PC
//
0006100, // 166232 006100 GET83: ROL RET1
0006100, // 166234 006100 ROL RET1
0006004, // 166236 006004 ROR WORK2
0106000, // 166240 106000 RORB RET1
0006004, // 166242 006004 ROR WORK2
0106000, // 166244 106000 RORB RET1 ;FINAL CHARACTER ASSEMBLED.
0005726, // 166246 005726 TST (SP)+ ;FUDGE STACK.
0000207, // 166250 000207 RTS PC ;AND RETURN NOW.
//
// 166250 GET8TB = .-2 ;PUSH ZERO CONDITION BACK INTO NEVER-NEVER LAND.
//
0000000, // 166252 000000 .WORD GET81-GET8P
0000026, // 166254 000026 .WORD GET82-GET8P
0000060, // 166256 000060 .WORD GET83-GET8P
0177770, // 166260 177770 .WORD GET84-GET8P
//
//
0004767, 0000020, // 166262 004767 000020 GETSIX: JSR PC,GETCHR
0020027, 0000040, // 166266 020027 000040 CMP RET1,#40
0002546, // 166272 002546 BLT L.BAD
0020027, 0000137, // 166274 020027 000137 CMP RET1,#137
0003143, // 166300 003143 BGT L.BAD
0000207, // 166302 000207 RTS PC
//
//
//
0005726, // 166304 005726 GETCHP: TST (SP)+ ;UPDATE THE STACK.
//
0012700, 0015772, // 166306 012700 015772 GETCHR: MOV #P10IC,RET1 ;SET UP POINTER TO THE INPUT CHARACTER.
0004767, 0000064, // 166312 004767 000064 GETCHL: JSR PC,CHECK
0005710, // 166316 005710 TST @RET1 ;ANY CHARACTER THERE?
0001774, // 166320 001774 BEQ GETCHL
0011046, // 166322 011046 MOV @RET1,-(SP) ;PUSH THE CHAR ON THE STACK.
0005020, // 166324 005020 CLR (RET1)+ ;CLEAR THE CHAR GOT FLAG NOW.
0042716, 0177600, // 166326 042716 177600 BIC #-200,(SP) ;CLEAR AWAY PARITY NOW.
0001764, // 166332 001764 BEQ GETCHP ;IF ZERO, GET ANOTHER
//
//
0022716, 0000177, // 166334 022716 000177 CMP #177,(SP)
0001761, // 166340 001761 BEQ GETCHP ;ALSO IGNORE RUBOUTS.
0022710, 0000175, // 166342 022710 000175 CMP #175,@RET1 ;WAS IT A "175"
0001007, // 166346 001007 BNE GETNP ;NOPE.
0011610, // 166350 011610 MOV (SP),@RET1 ;YEP. RESET IN CASE OF ABORT.
0021027, 0000122, // 166352 021027 000122 CMP @RET1,#122 ;IS IT AN R
0001626, // 166356 001626 BEQ RESTRT ;YEP. RESTART
0021027, 0000114, // 166360 021027 000114 CMP @RET1,#114 ;IS IT AN L
0001455, // 166364 001455 BEQ LOAD ;YEP. LOAD.
//
0011610, // 166366 011610 GETNP: MOV (SP),@RET1 ;NOW DO THE FUDGING.
0012600, // 166370 012600 MOV (SP)+,RET1
0020027, 0000175, // 166372 020027 000175 CMP RET1,#175
0001743, // 166376 001743 BEQ GETCHR ;IF ALTMODE, LOOP
0000207, // 166400 000207 RTS PC
//
//
0005767, 0027370, // 166402 005767 027370 CHECK: TST P10OC ;DO WE WANT TO OUTPUT?
0001410, // 166406 001410 BEQ CHECK1 ;NO.
0105767, 0007200, // 166410 105767 007200 TSTB P10OS ;WE DO. IS THE 10 READY?
0100005, // 166414 100005 BPL CHECK1 ;NOT QUITE.
0016767, 0027354, 0007172, // 166416 016767 027354 007172 MOV P10OC,P10OB ;IT'S READY. SEND THE CHARACTER.
0005067, 0027346, // 166424 005067 027346 CLR P10OC ;AND THE SAVED CHARACTER.
//
0105767, 0011124, // 166430 105767 011124 CHECK1: TSTB KBDIS ;HEY, IS THE KEYBOARD READY?
0100014, // 166434 100014 BPL CHECK3 ;NOPE. NO LUCK.
0116746, 0011120, // 166436 116746 011120 MOVB KBDIB,-(SP) ;YEP. SAVE THE CHARACTER NOW.
0012767, 0000001, 0011110, // 166442 012767 000001 011110 MOV #1,KBDIS ;AND REENABLE THE COMMUNICATIONS DEVICE.
//
0004767, 0177726, // 166450 004767 177726 CHECK2: JSR PC,CHECK ;IS THE OUTPUT READY?
0005767, 0027316, // 166454 005767 027316 TST P10OC
0001373, // 166460 001373 BNE CHECK2 ;IF NOT, WAIT TILL DONE.
0012667, 0007130, // 166462 012667 007130 MOV (SP)+,P10OB ;AND THEN SEND OUT THE CHARACTER.
//
//
0105767, 0007116, // 166466 105767 007116 CHECK3: TSTB P10IS ;IS THE 10 TALKING TO ME.
0100011, // 166472 100011 BPL CHECK4 ;NOPE. EXIT.
0116767, 0007112, 0027270, // 166474 116767 007112 027270 MOVB P10IB,P10IC ;GET THE CHARACTER NOW.
0052767, 0177400, 0027262, // 166502 052767 177400 027262 BIS #-400,P10IC ;MAKE SURE IT'S NONE ZERO.
0012767, 0000007, 0007072, // 166510 012767 000007 007072 MOV #7,P10IS ;REINITIALIZE COMMUNICATION LINE.
//
0000207, // 166516 000207 CHECK4: RTS PC ;AND RETURN.
//
//
// ; THE L O A D E R
//
0005002, // 166520 005002 LOAD: CLR INP2 ;RESET TO FIRST 8 BIT CHARACTER.
0012712, 0172000, // 166522 012712 172000 MOV #172000,(INP2) ;AND ALSO CLEVERLY STOP THE VT40.
0012706, 0015770, // 166526 012706 015770 MOV #STKSRT,SP ;RESET STACK POINTER NOW.
//
0005003, // 166532 005003 L.LD2: CLR L.CKSM ;CLEAR THE CHECKSUM
0004767, 0000070, // 166534 004767 000070 JSR PC,L.PTR ;GET A BYTE NOW.
0105300, // 166540 105300 DECB L.BYT ;IS IT ONE?
0001373, // 166542 001373 BNE L.LD2 ;NOPE. WAIT AWHILE
0004767, 0000060, // 166544 004767 000060 JSR PC,L.PTR ;YEP. GET NEXT CHARACTER.
//
0004767, 0000072, // 166550 004767 000072 JSR PC,L.GWRD ;GET A WORD.
0010005, // 166554 010005 MOV L.BYT,L.BC ;GET THE COUNTER NOW.
0162705, 0000004, // 166556 162705 000004 SUB #4,L.BC ;CHOP OFF EXTRA STUFF.
0022705, 0000002, // 166562 022705 000002 CMP #2,L.BC ;NULL?
0001437, // 166566 001437 BEQ L.JMP ;YEP. MUST BE END.
0004767, 0000052, // 166570 004767 000052 JSR PC,L.GWRD ;NOPE. GET THE ADDRESS.
0010001, // 166574 010001 MOV L.BYT,L.ADR ;AND REMEMBER FOR OLD TIMES SAKE.
//
0004767, 0000026, // 166576 004767 000026 L.LD3: JSR PC,L.PTR ;GET A BYTE (DATA)
0002010, // 166602 002010 BGE L.LD4 ;ALL DONE WITH THE COUNTER?
0105703, // 166604 105703 TSTB L.CKSM ;YEP. GOOD CHECK SUM?
0001751, // 166606 001751 BEQ L.LD2 ;NOPE. LOAD ERROR.
//
0012700, // 166610 012700 L.BAD: MOV (PC)+,RET1 ;SEND OUT SOME CHARACTERS NOW.
0041175, // 166612 175
// 166613 102 .BYTE 175,102 ;"CTRL BAD"
0004767, 0000110, // 166614 004767 000110 JSR PC,SENDIT
0000167, 0177210, // 166620 000167 177210 JMP RESTRT
//
0110021, // 166624 110021 L.LD4: MOVB L.BYT,(L.ADR)+ ;PLACE THE BYTE IN CORE.
0000763, // 166626 000763 BR L.LD3 ;GET ANOTHER ONE.
//
0004767, 0177276, // 166630 004767 177276 L.PTR: JSR PC,GET8 ;GET 8 BITS NOW.
0060003, // 166634 060003 ADD L.BYT,L.CKSM ;UPDATE CHECKSUM
0042700, 0177400, // 166636 042700 177400 BIC #177400,L.BYT ;CLEAN UP THE BYTE NOW.
0005305, // 166642 005305 DEC L.BC ;UPDATE THE COUNTER.
0000207, // 166644 000207 RTS PC ;RETURN NOW.
//
0004767, 0177756, // 166646 004767 177756 L.GWRD: JSR PC,L.PTR ;GET A CHARACTER.
0010046, // 166652 010046 MOV L.BYT,-(SP) ;SAVE FOR A SECOND.
0004767, 0177750, // 166654 004767 177750 JSR PC,L.PTR ;GET ANOTHER CHARACTER.
0000300, // 166660 000300 SWAB L.BYT ;NOW ASSEMBLE THE WORD.
0052600, // 166662 052600 BIS (SP)+,L.BYT ;AND RETURN WITH A 16 BITER.
//
//
0000207, // 166664 000207 RTS PC
//
0004767, 0177754, // 166666 004767 177754 L.JMP: JSR PC,L.GWRD ;GET A WORD
0010046, // 166672 010046 MOV L.BYT,-(SP) ;SAVE ON THE STACK.
0004767, 0177730, // 166674 004767 177730 JSR PC,L.PTR ;GET A CHARACTER.
0105703, // 166700 105703 TSTB L.CKSM ;IS IT ZERO?
0001342, // 166702 001342 BNE L.BAD ;YEP. WHAT CRAP.
0032716, 0000001, // 166704 032716 000001 BIT #1,(SP) ;IS IT ODD?
0001406, // 166710 001406 BEQ L.JMP1 ;YEP. START PROGRAM GOING NOW.
0012700, // 166712 012700 MOV (PC)+,RET1 ;TELL PDP-10 WE'VE LOADED OK.
0043575, // 166714 175
// 166715 107 .BYTE 175,107
0004767, 0000006, // 166716 004767 000006 JSR PC,SENDIT
0000000, // 166722 000000 HALT
0000776, // 166724 000776 BR .-2
//
0000136, // 166726 000136 L.JMP1: JMP @(SP)+ ;AND AWAY WE GO.
//
//
0004767, 0177446, // 166730 004767 177446 SENDIT: JSR PC,CHECK ;POLL THE OUTPUT DEVICE NOW.
0005767, 0027036, // 166734 005767 027036 TST P10OC ;OUTPUT CLEAR?
0001373, // 166740 001373 BNE SENDIT ;NOPE. LOOP AWHILE LONGER.
0010067, 0006650, // 166742 010067 006650 MOV RET1,P10OB ;SEND OUT THE CHARACTER.
0105000, // 166746 105000 CLRB RET1 ;CLEAR THE BYTE.
0000300, // 166750 000300 SWAB RET1 ;AND SWAP THEM NOW.
0001366, // 166752 001366 BNE SENDIT ;IF NOT EQUAL, REPEAT.
0000207, // 166754 000207 RTS PC
0000000, // 166756 000000 //
0000000, // 166760 000000 //
0000000, // 166762 000000 //
0000000, // 166764 000000 //
0000000, // 166766 000000 //
0000000, // 166770 000000 //
0000000, // 166772 000000 //
0000000, // 166774 000000 //
0000000, // 166776 000000 //
//
// ; THIS IS THE INITIALIZING VT40 PROGRAM WHICH WILL
// ; JUMP TO THE PROGRAM AFTER THE POWER FAIL LOCATIONS
// ; WHICH WILL JUMP TO ZERO WHICH WILL JUMP BACK TO HERE.
//
//
//
0170256, // 166756 170256 DISPRG: .WORD 170256 ;LOAD STATUS REGISTER FOR NORMAL OPERATION.
0115124, // 166760 115124 .WORD 115124 ;SET POINT MODE. "NORMAL".
0000000, // 166762 000000 .WORD STARTX ;X COORDINATE
0001360, // 166764 001360 .WORD STARTY ;Y COORDINATE
0100000, // 166766 100000 .WORD 100000 ;SET CHARACTER MODE.
0160000, // 166770 160000 .WORD JMPDIS ;THEN JUMP TO THE POWERFAIL LOCATION.
0000030, // 166772 000030 .WORD PWRFAL+4 ;TO DISPLAY USERS CHARACTERS.
//
//
// 000001 .END
};
t_stat
vt_rom_rd(int32 *data, int32 PA, int32 access)
{
*data = (int32)vt_boot_rom[(((PA - vt_rom_base) & 0xFFFF) >> 1)];
return SCPE_OK;
}
DIB vt_rom_dib;
t_stat
vt_boot(int32 unit, DEVICE *dptr)
{
t_stat r;
char stability[32];
extern int32 saved_PC;
if (sim_switch_number == 40) { /* GT40 Boot? */
set_cmd (0, "CPU 11/05");
set_cmd (0, "CPU 16k");
set_cmd (0, "DLI ENABLE");
set_cmd (0, "DLI LINES=1");
set_cmd (0, "DLI ADDRESS=17775610");
set_cmd (0, "VT CRT=VR14");
set_cmd (0, "VT SCALE=1");
set_cmd (0, "VT ADDRESS=17772000");
vt_dib.next = &vt_rom_dib;
vt_rom_dib.ba = vt_rom_base;
vt_rom_dib.lnt = sizeof (vt_boot_rom);
vt_rom_dib.rd = &vt_rom_rd;
r = build_ubus_tab (&vt_dev, &vt_rom_dib);
if (r != SCPE_OK)
return r;
cpu_set_boot (vt_rom_base);
return r;
}
/* XXX should do something like vt11_set_dpc(&appropriate_ROM_image) */
/* Instead, since that won't be too useful.... */
/* Load and start Lunar Lander which has the potential to be fun! */
sim_set_memory_load_file (BOOT_CODE_ARRAY, BOOT_CODE_SIZE);
r = load_cmd (0, BOOT_CODE_FILENAME);
sim_set_memory_load_file (NULL, 0);
/* Lunar Lander presumes a VT device vector base of 320 */
if (0320 != vt_dib.vec) { /* If that is not the case, then copy the 320 vectors to the right place */
WrMemW (vt_dib.vec + 000, RdMemW (0320 + 0));
WrMemW (vt_dib.vec + 002, RdMemW (0320 + 2));
WrMemW (vt_dib.vec + 004, RdMemW (0324 + 0));
WrMemW (vt_dib.vec + 006, RdMemW (0324 + 2));
WrMemW (vt_dib.vec + 010, RdMemW (0330 + 0));
WrMemW (vt_dib.vec + 012, RdMemW (0330 + 2));
WrMemW (vt_dib.vec + 014, RdMemW (0334 + 0));
WrMemW (vt_dib.vec + 016, RdMemW (0334 + 2));
}
cpu_set_boot (saved_PC);
set_cmd (0, "VT SCALE=1");
set_cmd (0, "VT CRT=VR14");
sprintf (stability, "%d", SIM_IDLE_STMIN);
sim_set_idle (NULL, 0, stability, NULL); /* force minimum calibration stability */
sim_clr_idle (NULL, 0, stability, NULL);
return r;
}
/* SET/SHOW VT options: */
t_stat
vt_set_crt(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
char gbuf[CBUFSIZE];
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
get_glyph(cptr, gbuf, 0);
if (strcmp(gbuf, "VR14") == 0)
vt11_display = DIS_VR14;
else if (strcmp(gbuf, "VR17") == 0)
vt11_display = DIS_VR17;
else if (strcmp(gbuf, "VR48") == 0)
vt11_display = DIS_VR48;
else
return SCPE_ARG;
vt_dib.lnt = (VS60) ? IOLN_VS60 : IOLN_VT11;
deassign_device (&vt_dev);
if (VS60)
assign_device (&vt_dev, "VS60");
return SCPE_OK;
}
t_stat
vt_show_crt(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "crt=VR%d", (int)vt11_display);
return SCPE_OK;
}
t_stat
vt_set_scale(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
t_stat r;
t_value v;
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
v = get_uint(cptr, 10, 8, &r);
if (r != SCPE_OK)
return r;
if (v != 1 && v != 2 && v != 4 && v != 8)
return SCPE_ARG;
vt11_scale = v;
return SCPE_OK;
}
t_stat
vt_show_scale(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "scale=%d", (int)vt11_scale);
return SCPE_OK;
}
t_stat
vt_set_hspace(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
char gbuf[CBUFSIZE];
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
get_glyph(cptr, gbuf, 0);
if (strcmp(gbuf, "NARROW") == 0)
vt11_csp_w = 12;
else if (strcmp(gbuf, "NORMAL") == 0)
vt11_csp_w = 14;
else
return SCPE_ARG;
return SCPE_OK;
}
t_stat
vt_show_hspace(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "hspace=%s", vt11_csp_w==12 ? "narrow" : "normal");
return SCPE_OK;
}
t_stat
vt_set_vspace(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
char gbuf[CBUFSIZE];
if (vt11_init)
return SCPE_ALATT; /* should be "changes locked out" */
if (cptr == NULL)
return SCPE_ARG;
get_glyph(cptr, gbuf, 0);
if (strcmp(gbuf, "TALL") == 0)
vt11_csp_h = 26;
else if (strcmp(gbuf, "NORMAL") == 0)
vt11_csp_h = 24;
else
return SCPE_ARG;
return SCPE_OK;
}
t_stat
vt_show_vspace(FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
fprintf(st, "vspace=%s", vt11_csp_h==26 ? "tall" : "normal");
return SCPE_OK;
}
/* interface routines (called from display simulator) */
void
vt_stop_intr(void)
{
sim_debug (DEB_STINT, &vt_dev, "SET_INT (VTST)\n");
SET_INT (VTST);
}
void
vt_lpen_intr(void)
{
sim_debug (DEB_LPINT, &vt_dev, "SET_INT (VTLP)\n");
SET_INT (VTLP);
}
void
vt_char_intr(void)
{
sim_debug (DEB_CHINT, &vt_dev, "SET_INT (CHAR)\n");
SET_INT (VTCH);
}
void
vt_name_intr(void)
{
sim_debug (DEB_NMINT, &vt_dev, "SET_INT (VTNM)\n");
SET_INT (VTNM);
}
/* fetch memory */
int
vt_fetch(uint32 addr, vt11word *wp)
{
/* On PDP-11 Unibus 22-bit systems, the VT11/VS60 behaves as
an 18-bit Unibus peripheral and must go through the I/O map. */
/* apply Unibus map, when appropriate */
/*
* The Graphics processor only has a 16 bit program counter
* (i.e. address register). If this address happens to be >= 56Kb
* then it is a reference to a graphics program running from
* ROM and in order for that to be found on an 18 bit Unibus
* we need to sign extend the the address so it resides in
* the I/O page.
*/
if (addr >= (uint32)(IOPAGEBASE & DMASK)) {
sim_debug (DEB_VT11, &vt_dev, "vt_fetch(addr=0%o) Adjusting ROM address to 0%o\n", (int)addr, (int)(addr | IOPAGEBASE));
addr |= IOPAGEBASE;
}
if (Map_ReadW(addr, 2, wp) == 0) {
sim_debug (DEB_VT11, &vt_dev, "vt_fetch(addr=0%o) - 0%o\n", (int)addr, (int)*wp);
return 0; /* no problem */
}
sim_debug (DEB_VT11, &vt_dev, "vt_fetch(addr=0%o) - failed\n", (int)addr);
/* else mapped address lies outside configured memory range */
*wp = 0164000; /* DNOP; just updates DPC if used */
/* which shouldn't happen */
return 1; /* used to set "time_out" flag */
}
const char *vt_description (DEVICE *dptr)
{
return (VS60) ? "VS60 Display processor"
: "VT11 Display processor";
}
#ifdef VM_PDP11
/* PDP-11 simulation provides this */
extern int32 SR; /* switch register */
#else
int32 SR; /* switch register */
#endif
void
cpu_set_switches(unsigned long v1, unsigned long v2)
{
SR = v1 ^ v2;
}
void
cpu_get_switches(unsigned long *p1, unsigned long *p2)
{
*p1 = SR;
*p2 = 0;
}
t_stat vt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
const char helpString[] =
/* The '*'s in the next line represent the standard text width of a help line */
/****************************************************************************/
" The VT11 is a calligraphic display-file device used in the GT4x series\n"
" of workstations (PDP-11/04,34,40 based).\n\n"
" The VS60 is an improved, extended, upward-compatible version of the\n"
" VT11, used in the GT62 workstation (PDP-11/34 based). It supports\n"
" dual consoles (CRTs with light pens), multiple phosphor colors, 3D\n"
" depth cueing, and circle/arc generator as options. We do not know\n"
" whether any of these options were ever implemented or delivered.\n"
" Apparently a later option substituted a digitizing-tablet correlator\n"
" for the light pen. The VS60 has a 4-level silo (graphic data pipeline)\n"
" which for reasons of simplicity is not implemented in this simulation;\n"
" the only visible effect is that DZVSC diagnostic tests 110 & 111 will\n"
" report failure.\n\n"
" The VSV11/VS11 is a color raster display-file device (with joystick\n"
" instead of light pen) with instructions similar to the VT11's but\n"
" different enough that a separate emulation should be created by\n"
" editing a copy of this source file rather than trying to hack it into\n"
" this one. Very likely, the display (phosphor decay) simulation will\n"
" also require revision to handle multiple colors.\n\n"
" There were further models in this series, but they appear to have\n"
" little if any compatibility with the VT11.\n\n"
" Much later, DEC produced a display system it called the VS60S, but\n"
" that doesn't seem to bear any relationship to the original VS60.\n\n"
" A PDP-11 system has at most one display controller attached.\n\n"
"1 Booting\n"
" There are two booting options for the GT40.\n"
"2 Demo Mode - Lunar Lander\n"
" The most famous software for the GT40 was the MOONLANDER\n"
" game by Jack Burness, also known as LUNAR LANDER. This was\n"
" undoubtedly the inspiration for Atari's coin-operated video\n"
" game of that name. To play the demo and play the game:\n\n"
"++sim> set vt enable\n"
"++sim> boot vt\n\n"
"3 Playing Lunar Lander\n"
" The object of moonlander is to land a lunar module on the\n"
" surface of the moon.\n\n"
" When the program is loaded, it will automatically start and\n"
" display an \"introductory message\" on the screen. Future\n"
" restart of the program will not cause this message to be\n"
" displayed. All numbers, speeds, weights, etc., are actual\n"
" numbers. They are for real. To make the game more possible\n"
" for an average person to play, I have given him about 25 to\n"
" 50%% more fuel in the final stages of landing than he would\n"
" actually have.\n\n"
" What the user sees on the screen is a broad and extremely\n"
" mountainous view of the moon. On the right is a list of data\n"
" parameters which the user may examine. They are height,\n"
" altitude, angle, fuel left, thrust, weight, horizontal\n"
" velocity, vertical velocity, horizontal acceleration, vertical\n"
" acceleration, distance and seconds. At the top of the screen,\n"
" any four of the values may be displayed. To display an item,\n"
" the user points the mouse at the item he wishes to display.\n"
" The item will then start blinking, to indicate that this is\n"
" the item to be displayed. The user then points the mouse at\n"
" one of the previously displayed items at the top of the screen.\n"
" The old item disappears and is replaced by the new item.\n"
" Note that it is possible to display any item anywhere, and even\n"
" possible to display one item four times at the top. Anyway,\n"
" the parameters mean the following. Height is the height in\n"
" feet above the surface (terrain) of the moon. It is the \"radar\"\n"
" height. Altitude is the height above the \"mean\" height of the\n"
" moon ( I guess you would call it \"mare\" level). Thus altitude\n"
" is not affected by terrain. Angle is the angle of the ship in\n"
" relationship to the vertical. 10 degrees, -70 degrees, etc.\n"
" Fuel left is the amount of fuel left in pounds. Thrust is the\n"
" amount of thrust (pounds) currently being produced by the engine.\n"
" Weight is the current earth weight of the ship. As fuel is\n"
" burned off, the acceleration will increase due to a lessening of\n"
" weight. The horizontal velocity is the current horizontal speed\n"
" of the ship, in feet per second. It is necessary to land at\n"
" under 10 fps horizontal, or else the ship will tip over.\n"
" Vertical velocity is the downward speed of the ship. Try to\n"
" keep it under 30 for the first few landings, until you get\n"
" better. A perfect landing is under 8 fps. The horizontal\n"
" and vertical accelerations are just those, in f/sec/sec.\n"
" With no power, the vertical acceleration is about 5 fp/s/s\n"
" down (-5). Distance is the horizontal distance (X direction)\n"
" you are from the projected landing site. Try to stay within\n"
" 500 feet of this distance, because there are not too many\n"
" spots suitable for landing on the moon. Seconds is just the\n"
" time since you started trying to land. Thus you now know how\n"
" to display information and what they mean.\n\n"
" To control the ship, two controls are provided. The first\n"
" controls the rolling or turning of the ship. This is accom-\n"
" plished by four arrows just above the display menu. Two point\n"
" left and two point right. The two pointing left mean rotate\n"
" left and the two pointing right mean rotate right. There is\n"
" a big and a little one in each direction. The big one means\n"
" to rotate \"fast\" and the small one means to rotate \"slow\".\n"
" Thus to rotate fast left, you point the mouse at left arrow.\n"
" To rotate slow right, you point the mouse at the small arrow\n"
" pointing to the right. The arrow will get slightly brighter\n"
" to indicate you have chosen it. Above the arrow there is a\n"
" bright, solid bar. This bar is your throttle bar. To its\n"
" left there is a number in percent (say 50%%). This number\n"
" indicates the percentage of full thrust your rocket engine\n"
" is developing. The engine can develop anywhere from\n"
" 10%% to 100%% thrust - full thrust is 10,500 pounds. The\n"
" engine thrust cannot fall below 10%%. That is the way Grumman\n"
" built it (actually the subcontractor). To increase or decrease\n"
" your thrust, you merely slide the mouse up and down the bar.\n"
" The indicated percentage thrust will change accordingly.\n\n"
" Now we come to actually flying the beast. The module appears\n"
" in the upper left hand corner of the screen and is traveling\n"
" down and to the right. Your job is to land at the correct\n"
" spot (for the time being, we will say this is when the\n"
" distance and height both reach zero). The first picture you\n"
" see, with the module in the upper left hand corner, is not\n"
" drawn to scale (the module appears too big in relationship\n"
" to the mountains). Should you successfully get below around\n"
" 400 feet altitude, the view will now change to a closeup\n"
" view of the landing site, and everything will be in scale.\n"
" Remember, it is not easy to land the first few times, but\n"
" don't be disappointed, you'll do it. Be careful, the game\n"
" is extremely addictive. It is also quite dynamic.\n\n"
" Incorporated in the game are just about everything the GT40\n"
" can do. Letters, italics, light pen letters, a light bar,\n"
" dynamic motion, various line types and intensities (the moon\n"
" is not all the same brightness you know). It also shows that\n"
" the GT40 can do a lot of calculations while maintaining a\n"
" reasonable display.\n\n"
" There are three possible landing sites on the Moon:\n\n"
"+1. On the extreme left of the landscape\n\n"
"+2. A small flat area to the right of the mountains\n\n"
"+3. In the large \"flat\" area on the right\n\n"
" Good Luck!\n\n"
"2 Terminal Mode\n"
" The GT40 LSI 11/05 configuration had a boot ROM which allowed the\n"
" VR14 to be used as a very minimal dumb terminal in order to allow\n"
" the user to login to the host computer. It watches for the host\n"
" computer to send a special character sequence to initiate download\n"
" mode. In download mode it loads a series of memory areas supplied\n"
" by the host. The data sent in download mode is encoded with six bits\n"
" per character.\n\n"
" GT40 Terminal Mode is initiated by:\n\n"
"++sim> set dli enable\n"
"++sim> attach dli Line=0,Connect=ipaddr:port\n"
"++sim> set vt enable\n"
"++sim> boot -40 vt\n\n"
"1 Implementation Status\n"
" Clipping is not implemented properly for arcs.\n\n"
" This simulation passes all four MAINDEC VS60 diagnostics and the\n"
" DEC/X11 VS60 system exerciser, with the following exceptions:\n\n"
" MD-11-DZVSA-A, VS60 instruction test part I, test 161:\n"
" Failure to time-out an access to a \"nonexistent\" bus address, when the\n"
" system is configured with so much memory that the probed address\n"
" actually responds; this is a deficiency in the diagnostic itself.\n\n"
" MD-11-DZVSB-A, VS60 instruction test part II:\n"
" No exceptions.\n\n"
" MD-11-DZVSC-B, VS60 instruction test part III, tests 107,110,111:\n"
" Memory address test fails under SIMH, due to SIMH not implementing\n"
" KT11 \"maintenance mode\", in which the final destination address (only)\n"
" is relocated. When SIMH is patched to fix this, the test still fails\n"
" due to a bug in the diagnostic itself, namely a call to DPCONV1 which\n"
" tests a condition code that is supposed to pertain to R0 but which\n"
" hasn't been set up. Swapping the two instructions before the call to\n"
" DPCONV1 corrects this, and then this test passes.\n"
" Graphic silo content tests fail, since the silo pipeline is not\n"
" simulated; there are no plans to fix this, since it serves no other\n"
" purpose in this simulation and would adversely affect performance.\n\n"
" MD-11-DZVSD-B, VS60 visual display test, frame 13:\n"
" \"O\" character sizes are slightly off, due to optimization for raster\n"
" display rather than true stroking; there are no plans to change this.\n\n"
" MD-11-DZVSE-A0, XXDP VS60 visual display exerciser:\n"
" No visible exceptions. Light-pen interrupts might not be handled\n"
" right, since they're reported as errors and cause display restart.\n"
" (XXX Need to obtain source listing to check this.)\n\n"
;
return scp_help (st, dptr, uptr, flag, helpString, cptr);
}
#else /* USE_DISPLAY not defined */
char pdp11_vt_unused; /* sometimes empty object modules cause problems */
#endif /* USE_DISPLAY not defined */