From 0c9864e7e56ae5f80d10784b68363a61fef7e90b Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Fri, 1 Jun 2018 20:26:38 +0200 Subject: [PATCH] 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. --- Makefile | 2 +- build/misc.tcl | 4 + doc/programs.md | 1 + src/budd/live.palx | 605 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 611 insertions(+), 1 deletion(-) create mode 100755 src/budd/live.palx diff --git a/Makefile b/Makefile index df24ca59..298d7f73 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SRC = system syseng sysen1 sysen2 sysen3 sysnet kshack dragon channa \ spcwar rwg libmax rat z emaxim rz maxtul aljabr cffk das ell ellen \ jim jm jpg macrak maxdoc maxsrc mrg munfas paulw reh rlb rlb% share \ tensor transl wgd zz graphs lmlib pratt quux scheme gsb ejs mudsys \ - draw wl taa tj6 + draw wl taa tj6 budd DOC = info _info_ sysdoc sysnet syshst kshack _teco_ emacs emacs1 c kcc \ chprog sail draw wl pc tj6 share _glpr_ _xgpr_ inquir mudman system \ xfont diff --git a/build/misc.tcl b/build/misc.tcl index caf12099..4e50decd 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -462,6 +462,10 @@ respond "*" ":link sys1;ts %,sys1;ts who%\r" respond "*" ":midas sys;ts palx_sysen1;palx\r" expect ":KILL" +# Phil Budne's PALX Game of Life. +respond "*" ":cwd budd\r" +respond "*" ":palx live palx\r" + # itsdev respond "*" ":link syseng;chsdef 999999,system;chsdef >\r" respond "*" ":midas device;chaos itsdev_bawden;itsdev\r" diff --git a/doc/programs.md b/doc/programs.md index ea8d5e2c..09a708b7 100644 --- a/doc/programs.md +++ b/doc/programs.md @@ -100,6 +100,7 @@ - LIMERI, print limerics. - LIMSER, Chaosnet limeric service. - LISP, lisp interpreter and runtime library (autoloads only). +- LIVE, PALX Game of Life. - LOADP, displays system load. - LOCK, shut down system. - LOOKUP, looks up user info in INQUIR database. diff --git a/src/budd/live.palx b/src/budd/live.palx new file mode 100755 index 00000000..4a3c8226 --- /dev/null +++ b/src/budd/live.palx @@ -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=*WIDTH-2 ;LAST ACTIVE CELL + +VTOP=TOP++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 ;A - NORTH ON VT52 KEYPAD + .WORD 'B, CM.S ;B - SOUTH ON VT52 KEYPAD + .WORD 'C, CM.E ;C - EAST ON VT52 KEYPAD + .WORD 'D, CM.W ;D - WEST ON VT52 KEYPAD + .WORD 'P, CM.RUN ;P - BLU ON VT52 KEYPAD == RUN + .WORD 'Q, CM.CLR ;Q - RED ON VT52 KEYPAD == CLEAR + .WORD 'R, RETT ;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+ ;ANY LIVING CELLS + BEQ 3$ ;NO!! + + MOV STATES+, R0 + ADD STATES+, 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+ ;CLEAR DEAD COUNT + CLR STATES+ ;CLEAR ALIVE COUNT + CLR STATES+ ;CLEAR BIRTH COUNT + CLR STATES+ ;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\ +.ENDM + +HLPMES: +LINE +LINE <> +LINE +LINE +LINE +LINE +LINE <> +LINE +LINE <============ ======> +LINE <.* Create cell> +LINE +LINE +LINE <0,SPACE Clear cell> +LINE +LINE +LINE +LINE <^J Down line> +LINE <^H Move Left> +LINE <^D Clear cell> +LINE <^Z Exit> +LINE +LINE <> +.ASCIZ /(type any key to return)/ + + .END START