1
0
mirror of https://github.com/PDP-10/its.git synced 2026-02-24 00:02:14 +00:00

LIVE - Phil Budne's PALX Game of Life.

Runs in 11SIM and SIMH 11/45 mode.  Uses VT52 escape codes, so use a
VT52 capable terminal emulator, or use the CRTSTY option SIMULATE VT52.
This commit is contained in:
Lars Brinkhoff
2018-06-01 20:26:38 +02:00
parent 1d56271a43
commit 0c9864e7e5
4 changed files with 611 additions and 1 deletions

605
src/budd/live.palx Executable file
View File

@@ -0,0 +1,605 @@
.TITLE LIVE -- A LIFE PROGRAM FOR VT52'S
.SBTTL PHIL BUDNE@DEC, DECEMBER 1982
; ************* STAND ALONE DEFINITIONS
TKS==177560
TKB==TKS+2
TPS==TKS+4
TPB==TKS+6
R0=%0
R1=%1
R2=%2
R3=%3
R4=%4
R5=%5
SP=%6
PC=%7
.=1000
; ************ END STAND ALONE DEFS
STAR='*
SPACE=<' >
; CELL STATE BITS
DEAD=0 ;* DEAD, STABLE (MUST BE ZERO)
ALIVE=1 ;* LIVE, STABLE
CHANGE=2
BIRTH=DEAD+CHANGE ;* DEAD -> LIVE SOON
DEATH=ALIVE+CHANGE ;* LIVE -> DEAD SOON
SCRWID=70. ;DISPLAY WIDTH 1..SCRWID
SCRLEN=24. ;DISPLAY LENGTH 1..SCRLEN
SCRPAD=10. ;AMOUNT TO PAD SCREEN BY ON EACH SIDE
SCRPDW=SCRPAD ;WIDTH PADDING
SCRPDL=SCRPAD*2 ;LENGTH PADDING
FLDWID=SCRWID+<2*SCRPDW> ;ACTUAL CELL FIELD WIDTH
FLDLEN=SCRLEN+<2*SCRPDL> ;ACTUAL CELL FIELD LENGTH
WIDTH=FLDWID+2 ;WIDTH W/ BUFFER CELLS
LENGTH=FLDLEN+2 ;LENGTH W/ BUFFER ROWS
TOP=WIDTH+1 ;FIRST ACTIVE CELL
BOT=<LENGTH-1>*WIDTH-2 ;LAST ACTIVE CELL
VTOP=TOP+<WIDTH*SCRPDL>+SCRPDW ;FIRST DISPLAYED CELL
XTOP=1 ;X CURSOR POS FOR VTOP
YTOP=1 ;Y CURSOR POS FOR VTOP
; 000000000000000000
; 0xXXXXXXXXXXXXXXX0
; 0XXXXXXXXXXXXXXXX0
; 0XX,...........XX0
; 0XX............XX0
; 0XX............XX0
; 0XX............XX0
; 0XX............XX0
; 0XXXXXXXXXXXXXXXX0
; 0XXXXXXXXXXXXXXXX0
; 000000000000000000
;
; . CELLS IN BOARD, FLD, SCR ,=VTOP
; X CELLS IN BOARD, FLD x=TOP
; 0 CELLS IN BOARD
UP=-WIDTH ;OFFSET TO GO UP 1 ROW
DOWN=WIDTH ;DOWN 1 RON
RIGHT=1 ;RIGHT 1 CELL
LEFT=-1 ;LEFT 1 CELL
; LEFT RIGHT
; -------------------------
; UP ! . ! . ! . !
; ! . ! . ! . !
; DOWN ! . ! . ! . !
; -------------------------
; SUML SUMC SUMR
SUML: .BLKW 1 ;SUM OF CELLS IN LEFT COLM
SUMC: .BLKW 1 ;SUM OF CELLS IN CENTER COLM
SUMR: .BLKW 1 ;SUM OF CELLS IN RIGHT COLM
STATES: .BLKW 4 ;SUM OF CELLS IN EACH STATE
XPOS: .BLKW 1 ;EDITING X POSN
YPOS: .BLKW 1 ;EDITING Y POSN
CELPOS: .BLKW 1 ;EDITING POINTER INTO CELLS
XTEMP: .BLKW 1
YTEMP: .BLKW 1
BRDSIZ=WIDTH*LENGTH
BOARD: .BLKB BRDSIZ
.EVEN
.SBTTL PROGRAM STARTS HERE
START: MOV #1000, SP ;GIVE US A STACK *** STAND ALONE ***
BEGIN: JSR PC, CM.CLR ;CLEAR SCREEN
TOPLVL: JSR PC, GETC
; HERE WITH CMD CHAR IN R0
1$: MOV #COMTBL, R1
2$: CMP (R1)+, R0 ;THIS IT?
BEQ 3$ ;YEP!
TST (R1)+ ;NO, DISCARD ADDR
BNE 2$ ;END?
MOV #'G-100, R0 ;FLEEP
JSR PC, PUTC
BR TOPLVL
3$: JSR PC, @(R1) ;GO!!, RETURN WITH CARRY SET IF ERROR
BR TOPLVL ;GET ANOTHER CMD
COMTBL: .WORD SPACE, CM.SPA ;SPACE - ERASE + EAST
.WORD STAR, CM.NEW ;STAR - NEW CELL + EAST
.WORD '., CM.NEW ;DOT - NEW CELL + EAST
.WORD '?, CM.HLP ;? - BE HELPFUL
.WORD 'S, CM.TOG ;S - TOGGLE
.WORD 'W, CM.N ;W - NORTH
.WORD 'X, CM.S ;X - SOUTH
.WORD 'D, CM.E ;D - EAST
.WORD 'A, CM.W ;A - WEST
.WORD 'E, CM.NE ;E - NORTH EAST
.WORD 'Q, CM.NW ;Q - NORTH WEST
.WORD 'C, CM.SE ;C - SOUTH EAST
.WORD 'Z, CM.SW ;Z - SOUTH WEST
.WORD '5, CM.TOG ;5 - TOGGLE
.WORD '8, CM.N ;8 - NORTH
.WORD '2, CM.S ;2 - SOUTH
.WORD '6, CM.E ;6 - EAST
.WORD '4, CM.W ;4 - WEST
.WORD '9, CM.NE ;9 - NORTH EAST
.WORD '7, CM.NW ;7 - NORTH WEST
.WORD '3, CM.SE ;3 - SOUTH EAST
.WORD '1, CM.SW ;1 - SOUTH WEST
.WORD '0, CM.SPA ;0 - CLEAR, ADVANCE
.WORD 'G, CM.RUN ;G - GO!
.WORD 'K, CM.CLR ;K - CLEAR SCREEN
.WORD 'H, CM.HLP ;H - HELP!!
.WORD 'R, CM.REF ;R - REFRESH
.WORD 33, CM.ESC ;ESC - DO ESCAPE PROCESSING
.WORD 'B-100, CM.W ;^B - WEST (ALA EMACS)
.WORD 'D-100, CM.KILL ;^D - ERASE
.WORD 'F-100, CM.E ;^F - EAST (ALA EMACS)
.WORD 'H-100, CM.W ;^H - WEST
.WORD 'J-100, CM.S ;^J - SOUTH
.WORD 'L-100, CM.REF ;^L - REFRESH
.WORD 'N-100, CM.S ;^N - SOUTH (ALA EMACS)
.WORD 'P-100, CM.N ;^P - NORTH (ALA EMACS)
.WORD 'Z-100, CM.QUIT ;^Z - QUIT
.WORD 177, CM.DEL ;DEL - RUBOUT
.WORD -1, 0
CM.HLP: JSR PC, CLRSCR ;CLEAR THE SCREEN
MOV #HLPMES, R1 ;POINT TO TEXT
JSR PC, PUTS ;OUTPUT IT
JSR PC, GETC ;GET A CHAR
JMP CM.REF ;RETURN, REFRESH
CM.ESC:
;;; JSR PC, CHKC ;GET ESCAPE DISPATCH CHAR
;;; BCS 2$ ;WELL, MAYBE NOT
JSR PC, GETC ;ALWAYS GET CHAR IN R0
MOV #ESCTBL, R1 ;POINT TO TABLE
1$: CMP (R1)+, R0 ;THIS IT?
BEQ 3$ ;YEP!
TST (R1)+ ;NO, DISCARD ADDR
BNE 1$ ;END?
2$: JMP FLEEP ;YES, WE'VE BEEN HAD!!
3$: JMP @(R1) ;GO!!, RETURN STATUS TO TOP
ESCTBL: .WORD 'A, CM.N ;<ESC>A - NORTH ON VT52 KEYPAD
.WORD 'B, CM.S ;<ESC>B - SOUTH ON VT52 KEYPAD
.WORD 'C, CM.E ;<ESC>C - EAST ON VT52 KEYPAD
.WORD 'D, CM.W ;<ESC>D - WEST ON VT52 KEYPAD
.WORD 'P, CM.RUN ;<ESC>P - BLU ON VT52 KEYPAD == RUN
.WORD 'Q, CM.CLR ;<ESC>Q - RED ON VT52 KEYPAD == CLEAR
.WORD 'R, RETT ;<ESC>R - GRY ON VT52 KEYPAD == NO-OP
.WORD 0, 0
CM.RUN: JSR PC, DOGEN ;DO IT!!
JSR PC, FIXSCR ;FIX UP SCREEN
TST STATES+<ALIVE*2> ;ANY LIVING CELLS
BEQ 3$ ;NO!!
MOV STATES+<BIRTH*2>, R0
ADD STATES+<DEATH*2>, R0
BEQ 2$ ;STABLE
1$: JSR PC, CHKC ;ANY INPUT?
BCC 4$ ;YES, RETURN
; MOV R1, SLPSEC ;SECONDS TO SLEEP
; BEQ CM.RUN ;NONE
; JSR PC, SLEEP ;DOZE
BR CM.RUN ;LOOP
2$: ; "STABLE"
3$: ; "ALL DEAD"
4$: ; "HALTED"
JMP CM.HOM ;HOME THE CURSOR, RETURN TRUE
FIXSCR: JMP UPDATE
CM.DEL: JSR PC, CM.W ;GO WEST..
BCC CM.KIL ;OK?, NOW KILL
RTS PC
CM.KIL: JSR PC, GO.ERA ;ERASE A CELL
MOV #SPACE, R0
JSR PC, PUTC
JSR PC, CURLFT
CM.RTT: JMP RETT
CM.TOG: JSR PC, GO.TOG ;TOGGLE A CELL
BR CM.RTT
CM.NEW: JSR PC, GO.DEP ;DEPOSIT A CELL
CM.DEP: MOV #STAR, R0
BR CM.ER2
CM.REF: JSR PC, FRESH
BR CM.RTT
CM.N: JSR PC, GO.UP ;TRY TO GO UP
BCS FLEEP ;NO GO
JSR PC, CURUP ;MOVE CURSOR
BR RETT
CM.S: JSR PC, GO.DWN ;TRY TO GO DOWN
BCS FLEEP ;SORRY!
JSR PC, CURDWN ;MOVE CURSOR
BR RETT
CM.SPA: JSR PC, GO.ERA ;ERASE
CM.ERA: MOV #SPACE, R0 ;SPACE
CM.ER2: JSR PC, PUTC
JSR PC, CURLFT ;GO BACK LEFT
CM.E: JSR PC, GO.RGH ;TRY TO GO RIGHT
BCS FLEEP ;FRAID NOT
JSR PC, CURRGT ;MOVE CURSOR
BR RETT
CM.W: JSR PC, GO.LFT ;TRY TO GO LEFT
BCS FLEEP ;SORRY CHARLIE
JSR PC, CURLFT ;MOVE CURSOR
BR RETT
CM.NE: JSR PC, CM.N ;NORTH
BCS FLEEP ;NO
JSR PC, CM.E ;EAST
BCC RETT ;OK
JSR PC, CM.S ;EAST LOST, FIX UP
BR FLEEP
CM.NW: JSR PC, CM.N ;NORTH
BCS FLEEP ;NO
JSR PC, CM.W ;WEST
BCC RETT ;OK
JSR PC, CM.S ;WEST LOST, FIX UP
BR FLEEP
CM.SE: JSR PC, CM.S ;SOUTH
BCS FLEEP ;NO
JSR PC, CM.E ;EAST
BCC RETT ;OK
JSR PC, CM.N ;EAST LOST, FIX UP
BR FLEEP
CM.SW: JSR PC, CM.S ;SOUTH
BCS FLEEP ;NO
JSR PC, CM.W ;WEST
BCC RETT ;OK
JSR PC, CM.N ;WEST LOST, FIX UP
BR FLEEP
FLEEP: MOV #'G-100, R0 ;CTRL-G
JSR PC, PUTC ;SAY IT
BR RETF ;SAY YOU ARE SORRY
CM.CLR: MOV #BOARD+TOP, R0 ;START OF ACTIVE BOARD
1$: MOVB #DEAD, (R0)+ ;MAKE DEAD
CMP R0, #BOARD+BOT ;DONE?
BLT 1$ ;NOPE
JSR PC, CLRSCR ;ZAP SCREEN
CM.HOM: JSR PC, CURHOM ;HOME CURSOR
JSR PC, GO.HOM ;HOME EDIT POINTERS
BR RETT
CM.QUI: JSR PC, DOQUIT ;ENVIRONMENT DEPENDANT
BR RETT
.SBTTL CELL MANIPULATION
GO.HOM: MOV #1, XPOS
MOV #1, YPOS
MOV #BOARD+VTOP, CELPOS
RTS PC
GO.DEP: MOVB #ALIVE, @CELPOS ;LIVE CELL
RTS PC
GO.TOG: TSTB @CELPOS ;DEAD CELL?
BEQ GO.DEP ;YES, MAKE LIVE
GO.ERA: MOVB #DEAD, @CELPOS ;DEAD CELL
RTS PC
GO.UP: DEC YPOS ;GO UP 1 LINE
BEQ 1$ ;TOO FAR?
ADD #UP, CELPOS ;MOVE CELL POINTER UP
BR RETT
1$: INC YPOS ;FIX POSN
RETF: SEC ;SET CARRY
RTS PC
GO.DWN: CMP YPOS, #SCRLEN ;COMPARE POSN TO SCREEN LENGTH
BEQ RETF ;ON THE EDGE NOW
INC YPOS ;ELSE, DOWN A LINE
ADD #DOWN, CELPOS ;AND UPDATE CELL POINTER
RETT: CLC ;HAPPY RETURN
RTS PC
GO.LFT: DEC XPOS ;OVER ONE ON X AXIS
BEQ 1$ ;OOOPS!
ADD #LEFT, CELPOS ;FIX CELL POINTER TOO
BR RETT ;GOOD RETURN
1$: INC XPOS ;FIXUP POSN
BR RETF ;FAIL
GO.RGH: CMP XPOS, #SCRWID ;ON THE EDGE
BEQ RETF ;YES, GO NO FURTHER
INC XPOS ;SLIDE OVER ONE
ADD #RIGHT, CELPOS ;SHIFT CELL POINTER
BR RETT
.SBTTL DOGEN - DO NEXT GENERATION
;CALL:
; JSR PC, DOGEN
;RETURNS:
; CHANGE BITS SET IN BOARD
DOGEN: MOV #BOARD+TOP, R0
CLR STATES+<DEAD*2> ;CLEAR DEAD COUNT
CLR STATES+<ALIVE*2> ;CLEAR ALIVE COUNT
CLR STATES+<BIRTH*2> ;CLEAR BIRTH COUNT
CLR STATES+<DEATH*2> ;CLEAR DEATH TOLL
BEGROW: MOV #FLDWID, R1 ;LIVE CELLS IN A ROW
CLR SUML ;NO LIVE CELLS TO THE LEFT
CLR SUMC ;ACCUMULATE CENTER SUM
BITB #ALIVE, UP(R0) ;ABOVE MAY HAVE CHANGE BIT SET
BEQ 1$ ;ALIVE?
INC SUMC ;IT WAS!
1$: TSTB DOWN(R0) ;BOTTOM CELL NOT CHANGED
BEQ 2$ ;ALIVE?
INC SUMC ;BUMP
2$: TSTB (R0) ;NOR CURRENT CELL
BEQ DORGHT ;ALIVE?
INC SUMC ;YES
BR DORGHT ;JOIN THE 'HUMAN' RACE
NXTCEL: INC R0 ;BUMP UP ONE CELL
MOV SUMC, SUML ;CENTER COLM BECOMES LEFT
MOV SUMR, SUMC ;AND RIGHT BECOMES CENTER
DORGHT: CLR R2 ;CALCULATE RIGHT SUM
BITB #ALIVE, UP+RIGHT(R0) ;UPPER RIGHT MIGHT BE CHANGED
BEQ 1$ ;ALIVE?
INC R2 ;YEP!
1$: BITB #ALIVE, RIGHT(R0) ;RIGHT, MAY HAVE CHANGED
BEQ 2$ ;ALIVE?
INC R2 ;BUMP COUNT
2$: TSTB RIGHT+DOWN(R0) ;BOTTOM RIGHT
BEQ 3$ ;ALIVE?
INC R2
3$: MOV R2, SUMR ;SAVE AS RIGHT SUM
ADD SUMC, R2 ;ADD IN CENTER COLM
ADD SUML, R2 ;AND LEFT COLM
TSTB (R0) ;LOOK AT CURRENT CELL
BNE 4$ ;LIVE?
MOVB DEDTAB(R2), R2 ;GET NEW STATUS FOR DEAD CELL
BR GONEXT
4$: MOVB LIVTAB-1(R2), R2 ;GET NEW STATUS FOR LIVE CELL
GONEXT: MOVB R2, (R0) ;STORE NEW CELL STATE
ASL R2 ;MAKE WORD OFFSET
INC STATES(R2) ;TALLY STATES
SOB R1, NXTCEL ;TICK OFF THIS CELL
CMP #BOT+BOARD, R0 ;DONE WITH BOTTOM ROW?
BLE DONE
ADD #WIDTH-FLDWID+1, R0 ;GO TO FRONT OF NEXT ROW
BR BEGROW ;AND START THE NEW ROW!
.POPJ:
DONE: RTS PC
; NEIGHBORS= 0 1 2 3 4 5 6 7 8
LIVTAB: .BYTE DEATH, DEATH, ALIVE, ALIVE, DEATH, DEATH, DEATH, DEATH, DEATH
DEDTAB: .BYTE DEAD, DEAD, DEAD, BIRTH, DEAD, DEAD, DEAD, DEAD, DEAD
.SBTTL FRESH - REPAINT SCREEN
FRESH: JSR PC, CLRSCR ;CLEAR THE SCREEN
MOV #BOARD+VTOP, R4 ;BOARD POINTER
MOV #1, R1 ;CURSOR NOW AT X=1
MOV R1, R2 ;AND Y=1
MOV #YTOP, YTEMP ;STARTING ROW
MOV #SCRLEN+1, R5 ;LINE COUNT
BR FR.ROW ;START A ROW
FR.NXT: INC XTEMP ;NEXT CELL IN A ROW
INC R4 ;UPDATE CELL PTR
FR.1ST: MOVB (R4), R0 ;GET CELL CONTENTS
BEQ FR.GO ;EMPTY, KEEP GOING
MOVB FR.TAB(R0), (R4) ;GET NEW STATE
BEQ FR.GO ;QUIT IF NOW DEAD
CMP R1, XTEMP ;IS X CORRECT?
BNE 1$ ;NO, USE CURSOR FUNCTIONS
CMP R2, YTEMP ;AND Y?
BEQ 2$ ;YES, JUST TYPE *
1$: MOV XTEMP, R1
MOV YTEMP, R2
JSR PC, GOPOS
2$: MOV #STAR, R0
JSR PC, PUTC ;PRINT LIVE CELL
INC R1 ;ADD 1 TO X
FR.GO: SOB R3, FR.NXT ;TICK OFF THIS CELL
DEC R5 ;TICK OFF THIS ROW
BEQ FR.RET ;DONE
INC YTEMP ;NO, START FRESH ROW
ADD #WIDTH-SCRWID+1, R4 ;GO TO FRONT OF NEXT ROW
FR.ROW: MOV #XTOP, XTEMP ;CURSOR SHOULD BE HERE
MOV #SCRWID, R3 ;WIDTH OF A LINE
BR FR.1ST
FR.RET: RTS PC
; DEAD, ALIVE, BIRTH, DEATH
FR.TAB: .BYTE DEAD, ALIVE, ALIVE, DEAD
.SBTTL UPDATE - CHANGE SCREEN
UPDATE: MOV #BOARD+VTOP, R4 ;BOARD POINTER
CLR R1 ;UNKNOWN CURSOR POSN
CLR R2 ;DITTO
MOV #YTOP, YTEMP ;ROW=1
MOV #SCRLEN+1, R5 ;LINES+1 TO UPDATE
BR UP.ROW ;START A ROW
UP.NXT: INC XTEMP ;NEXT CELL IN A ROW
INC R4 ;UPDATE CELL PTR
UP.1ST: MOVB (R4), R0 ;GET CELL CONTENTS
BEQ UP.GO ;EMPTY, KEEP GOING
MOVB UP.TAB(R0), (R4) ;GET NEW STATE
MOVB UP.CHR(R0), R0 ;GET NEW CHAR
BEQ UP.GO ;QUIT IF NO CHANGE
CMP R1, XTEMP ;IS X CORRECT?
BNE 1$ ;NO, USE CURSOR FUNCTIONS
CMP R2, YTEMP ;AND Y?
BEQ 2$ ;YES, JUST TYPE CHAR
1$: MOV XTEMP, R1 ;LOAD NEW XTEMP
MOV YTEMP, R2 ;AND YTEMP
MOV R0, -(SP) ;SAVE R0
JSR PC, GOPOS ;CURSOR ADDRESSING
MOV (SP)+, R0 ;RESTORE R0
2$: JSR PC, PUTC ;PRINT LIVE CELL (CHAR IN R0)
INC R1 ;ADD 1 TO X
UP.GO: SOB R3, UP.NXT ;TICK OFF THIS CELL
DEC R5 ;TICK OFF THIS LINE
BEQ UP.RET ;ALL DONE?
INC YTEMP ;START FRESH ROW
ADD #3, R4 ;GO TO FRONT OF NEXT ROW
UP.ROW: MOV #XTOP, XTEMP
MOV #FLDWID, R3 ;WIDTH OF A LINE
BR UP.1ST
UP.RET: RTS PC
; DEAD, ALIVE, BIRTH, DEATH
UP.TAB: .BYTE DEAD, ALIVE, ALIVE, DEAD
UP.CHR: .BYTE 0, 0, STAR, SPACE
.SBTTL CURSOR PRIMATIVES - VT52 ONLY
CLRSCR: MOV #CLRSTR, R1
JMP PUTS
; R1=X, R2=Y, 1 BASED
GOPOS: MOV #33, R0 ;ESC
JSR PC, PUTC
MOV #'Y, R0 ;Y
JSR PC, PUTC
MOV R2, R0
ADD #31., R0
JSR PC, PUTC ;Y POSN
MOV R1, R0
ADD #31., R0
BR PUTC ;X POSN
CLRSTR: .BYTE 33, 'H, 33, 'J, 0
.EVEN
CURUP: MOV #'A, R1
BR PUTESC
CURDWN: MOV #'B, R1
BR PUTESC
CURLFT: MOV #'D, R1
BR PUTESC
CURRGT: MOV #'C, R1
BR PUTESC
CURHOM: MOV #'H, R1
BR PUTESC
PUTESC: MOV #33, R0
JSR PC, PUTC
MOV R1, R0
BR PUTC
; ********* STAND ALONE GOODIES *********
PUTS: MOVB (R1)+, R0
BEQ 1$
JSR PC, PUTC
BR PUTS
1$: RTS PC
PUTC: TSTB @#TPS ;WAIT FOR PRINTER NOT BUSY
BPL PUTC
MOVB R0,@#TPB ;PRINT
RTS PC
GETC: TSTB @#TKS ;WAIT FOR A CHAR
BPL GETC
MOVB @#TKB,R0 ;INPUT
RTS PC
CHKC: TSTB @#TKS ;A CHAR?
BPL 1$ ;NOPE
MOVB @#TKB,R0 ;INPUT
CLC ;HAPPY RET
RTS PC
1$: SEC ;SAD RETURN
RTS PC
DOQUIT: HALT
RTS PC
.SBTTL HELP TEXT
CR='M-100
LF='J-100
.MACRO LINE STR
.ASCII \STR\<CR><LF>
.ENDM
HLPMES:
LINE <Hello and welcome to LIVE !!>
LINE <>
LINE <Movement Commands:>
LINE <Q W E 7 8 9 ^P>
LINE <A D 4 6 ^B ^F>
LINE <Z X C 1 2 3 ^N>
LINE <>
LINE <Character(s) Action>
LINE <============ ======>
LINE <.* Create cell>
LINE <G Start>
LINE <K Clear screen>
LINE <0,SPACE Clear cell>
LINE <S5 Toggle cell>
LINE <H? This mess>
LINE <R,^L Refresh screen>
LINE <^J Down line>
LINE <^H Move Left>
LINE <^D Clear cell>
LINE <^Z Exit>
LINE <DEL Rubout>
LINE <>
.ASCIZ /(type any key to return)/
.END START