;
; PDP-11 4K SINGLE USER BASIC INTERPRETER
;
;	COPYRIGHT 1969, 1970, DIGITAL EQUIPMENT CORPORATION
;
;	WRITTEN BY DAVE KNIGHT AND JEFF SCOTT
;
.	=	42
	.BYTE	007,'A	;VERSION 007A
;
; REGISTER ASSIGNMENTS
;
R0	=	%0		;TEMPORARY AND PARAMETER TRANSFER
R1	=	%1		;TEMPORARY AND PARAMETER TRANSFER
R2	=	%2		;SCRATCH
R3	=	%3		;SCRATCH
R4	=	%4		;SCRATCH
R5	=	%5		;USER LIST POINTER
SP	=	%6		;BASIC STACK POINTER
PC	=	%7		;PROGRAM COUNTER
;
; I/O DEVICE ASSIGNMENTS
;
TTY0	=	177564		;ADDRESS OF TTY0 STATUS REGISTER
KBD0	=	177560		;ADDRESS OF KBD0 STATUS REGISTER
LSR	=	177560		;LOW SPEED READER ADDRESS
LSP	=	177564		;LOW SPEED PUNCH ADDRESS
HSR	=	177550		;HIGH SPEED READER ADDRESS
HSP	=	177554		;HIGH SPEED PUNCH ADDRESS
;
; TRAP AND INTERRUPT ASSIGNMENTS
;
TRAP	=	104400		;TRAP PROTOTYPE
;
; TRAP VECTOR CONTENTS
;
.	=	0		;START OF VECTORS
	JMP	RESTRT		;BASIC RESTARTS AT LOCATION ZERO
TRP04:	.+2			;PROCESSOR ERROR - 4
	0
	.+2			;UNIMPLEMENTED INSTRUCTION - 10
	0
	.+2			;TRACE - 14
	0
	.+2			;IOT - 20
	0
	.+2			;POWER FAIL - 24
	0
	.+2			;EMT - 30
	0
	TRAP00			;TRAP HANDLER - 34
	0
;
.	=	50		;EXF COMMUNICATIONS ARE PUT HERE
USRLOC:	56			;FORCE AN ERROR AT LOC 56 IF NOT DONE RIGHT
USRRET:	JMP	@#56		;THIS JUMP DOES THE SAME
	EXFERR			;ERROR HERE IF EXF FUNCTION NO GOOD
.	=	60		;SKIP OVER COMMUNICATIONS AREA
	CTRL00			;TELETYPE KEYBOARD - 60
	0
	.+2			;TELETYPE PRINTER - 64
	0
	.+2			;PAPER TAPE READER - 70
	0
	.+2			;PAPER TAPE PUNCH - 74
	0
ENDVEC	=	.	;END OF ALL KNOWN VECTORS
;
; BASIC TRAP AND ERROR HANDLER - ALL SUBROUTINE AND
;	ERROR CALLS IN BASIC ARE MADE BY
;	TRAP CALLS - UNDER NORMAL CIRCUMSTANCES JSR'S ARE VERBOTEN.
;
;	SUBROUTINE CALLS ARE DIFFERENTIATED FROM ERROR CALLS ACCORDING
;	TO THE LOWER 8 BITS OF THE TRAP CALL.  ALL SUBROUTINE CALLS WILL
;	BE EVEN.  ALL ERROR CALLS WILL BE ODD.  THE LOWER 8 BITS OF AN
;	ERROR CALL IS THE ERROR NUMBER MULTIPLIED BY TWO PLUS ONE
;	(E.G. - ERROR #5 HAS A CODED VALUE OF 013).  ERRORS NUMBERED 
;	FROM 0 TO "FENCE" INCLUSIVE ARE FATAL.  ERRORS FROM "FENCE"+1
;	TO 127 ARE NON-FATAL.
;
; THE FOLLOWING IS A LIST OF IMPLEMENTED TRAP
;	SUBROUTINE CALLS.  ADDITIONAL
;	CALLS MAY BE ADDED AT THE END OF THE LIST.  ANY CHANGES
;	MADE IN THIS LIST MUST BE REFLECTED IN THE TRAP ADDRESS
;	TABLE TRAP01
;
;
PRINTC	=	TRAP		;PRNT00 - PRINT CHARACTER
CRLF	=	PRINTC+2		;CRLF00 - TYPE <CR,LF>
PRNTLN	=	CRLF+2		;PRLN00 - PRINT LINE NUMBER
ATOF	=	PRNTLN+2		;ATOF00 - ASCII TO FLOATING
ATOI	=	ATOF+2		;ATOI00 - ASCII TO INTEGER
ITOA	=	ATOI+2		;ITOA00 - INTEGER TO ASCII
JTOA	=	ITOA+2		;JTOA00 - DOUBLE INTEGER TO ASCII
IMUL	=	JTOA+2		;IMUL00 - INTEGER MULTIPLY
ADDF	=	IMUL+2		;ADDF00 - FLOATING ADD
SUBF	=	ADDF+2		;SUBF00 - FLOATING SUBTRACT
NEGF	=	SUBF+2		;NEGF00 - FLOATING NEGATE
DIVF	=	NEGF+2		;DIVF00 - FLOATING DIVIDE
MULF	=	DIVF+2		;MULF00 - FLOATING MULTIPLY
MOVF	=	MULF+2		;MOVF00 - MOVE FLOATING
CMPF	=	MOVF+2		;CMPF00 - COMPARE FLOATING
FLT	=	CMPF+2		;FLT00 - CONVERT SINGLE FIXED TO FLOATING
FIX	=	FLT+2		;FIX00 - FLOATING TO SINGLE FIXED
FIXS	=	FIX+2		;SPECIAL FIX
M.INIT	=	FIXS+2		;FLOATING	->I
M.FRAC	=	M.INIT+2		;POINT		  I
M.SETU	=	M.FRAC+2		;PACKAGE	  I
M.DOPO	=	M.SETU+2		;SPECIAL	  I
M.MOVE	=	M.DOPO+2		;PURPOSE	  I
M.INI2	=	M.MOVE+2		;CALLS		  I
M.APPR	=	M.INI2+2		;  DO		  I
M.DPIM	=	M.APPR+2		;  NOT		  I
M.DPID	=	M.DPIM+2		;  USE		<-I
PRINTL	=	M.DPID+2		;PRN00 - PRINT LINE, R0=FBA, R1=LBA
TSTCH	=	PRINTL+2		;TEST ALPHABETIC VS NUMERIC IN R2
SKIP	=	TSTCH+2		;SKIP BLANKS IN INPUT TEXT
FINDLN	=	SKIP+2		;FIND LINE NUMBER SPECIFIED IN R0
SQUISH	=	FINDLN+2		;DELETE TEXT TO TERMINATOR AND PACK
PACK	=	SQUISH+2		;PACK LINE INTO WORKING STORAGE
SRCHLF	=	PACK+2		;FIND LINE FEED USING R1 POINTER
TSTOK	=	SRCHLF+2		;CHECK FOR ENOUGH USER SPACE
GETNUM	=	TSTOK+2		;GET COMMAND PARAMETER
JUNKIT	=	GETNUM+2		;SKIP OVER TRASH TO LOGICAL END OF LINE
PUSH	=	JUNKIT+2		;PUSH ONE WORD INTO USER LIST
SRLST	=	PUSH+2		;SEARCH FOR ITEM IN USER STORAGE
CLRUSR	=	SRLST+2		;DELETE TEMPORARY USER SPACE IF ANY
SCRNCH	=	CLRUSR+2		;DELETE N BYTES FROM USER SPACE
ARYLG	=	SCRNCH+2		;COMPUTE ARRAY LENGTH
DIMCHK	=	ARYLG+2		;CHECK LEGAL DIMENSION
GETVAR	=	DIMCHK+2		;GET TRUNCATED VARIABLE
MULSIX	=	GETVAR+2		;MULTIPLY R0 BY SIX
SUBSCR	=	MULSIX+2		;COMPUTE A SUBSCRIPT EXPRESSION
TXTADR	=	SUBSCR+2		;GET EVEN ADDRESS FOR START OF USER STORAGE
EVAL	=	TXTADR+2		;EVALUATE AN EXPRESSION
TWOCHR	=	EVAL+2		;PACK TWO CHARACTERS IN R4
MOVSTK	=	TWOCHR+2		;MOVE R4,R3,R2 TO THE STACK
GETADR	=	MOVSTK+2		;GET ADDRESS OF VARIABLE ELEMENT
PSHNAM	=	GETADR+2	;PUSH NAMED VARIABLE ON LIST
PUTAWY	=	PSHNAM+2	;PUSH A VALUE ON USER LIST
BASQ	=	PUTAWY+2	;BASIC INITIALIZATION QUESTIONS
				;DO NOT USE AFTER INITIALIZING
;
; THE FOLLOWING IS A LIST OF IMPLEMENTED ERROR CALLS.  ALL ERRORS LESS
;	THAN "FENCE" ARE FATAL, ALL GREATER ARE NON-FATAL.
;
FENCE	=	100	;BOUNDARY BETWEEN FATAL AND NON-FATAL.
;
; FATAL ERROR CALLS
;
OVFERR	=	TRAP+1		;USER STORAGE OVERFLOW - 0
UNRERR	=	OVFERR+2	;UNRECOGNIZED STATEMENT - 1
GOERR	=	UNRERR+2	;ILLEGAL GOTO OR GOSUB - 2
ILCERR	=	GOERR+2		;ILLEGAL CHARACTER TERMINATING STMT - 3
RETERR	=	ILCERR+2	;RETURN WITHOUT GOSUB - 4
SBSERR	=	RETERR+2		;BADLY FORMED SUBSCRIPT - 5
SUBERR	=	SBSERR+2	;SUBSCRIPT OUT OF RANGE - 6
PARERR	=	SUBERR+2	;MISMATCHED PARENTHESES - 7
LETERR	=	PARERR+2	;ILLEGAL LET - 8
OPRERR	=	LETERR+2	;ILLEGAL RELATIONAL OPERATOR IN IF - 9
IFERR	=	OPRERR+2	;ILLEGAL IF - 10
PRNERR	=	IFERR+2		;ILLEGAL PRINT - 11
LINERR	=	PRNERR+2	;INPUT LINE TOO LONG - 12
DIMERR	=	LINERR+2	;BAD DIMENSION - 13
DMVERR	=	DIMERR+2	;NOT ENOUGH ROOM IN STORAGE FOR THE ARRAY - 14
DEFERR	=	DMVERR+2	;BADLY FORMED DEFINE - 15
LNNERR	=	DEFERR+2	;ILLEGAL LINE NUMBER OR DIMENSION VALUE - 16
DMDERR	=	LNNERR+2	;DIM OF PREVIOUSLY DECLARED OR USED ITEM - 17
INPERR	=	DMDERR+2	;BAD VARIABLE IN INPUT LIST - 18
REAERR	=	INPERR+2	;BAD VARIABLE IN READ LIST - 19
RE1ERR	=	REAERR+2	;OUT OF DATA - 20
RE2ERR	=	RE1ERR+2	;BAD FORMAT IN A DATA STATEMENT - 21
FORERR	=	RE2ERR+2	;ILLEGAL FOR STATEMENT - 22
NXTERR	=	FORERR+2	;NO NEXT MATCHING FOR - 23
NXMERR	=	NXTERR+2	;NEXT WITHOUT FOR - 24
UNMERR	=	NXMERR+2	;UNMATCHED QUOTES IN STATEMENT - 25
EXFERR	=	UNMERR+2	;EXTERNAL FUNCTION NOT PROPERLY SET UP - 26
ILFERR	=	EXFERR+2	;ILL FORMED EXPRESSION - 27
				;(PROBABLY MISSING EXPONENT ON E FORMAT NUMBER)
;
; NON-FATAL ERROR CALLS
;
LOGERR	=	TRAP+377	;LOG OF NEGATIVE OR ZERO NUMBER - 127
SQRERR	=	LOGERR-2	;SQUARE ROOT OF NEGATIVE NUMBER - 126
DVFERR	=	SQRERR-2	;DIV.-MUL. OVERFLOW OR UNDERFLOW - 125
FIXERR	=	DVFERR-2	;NUMBER TOO LARGE TO FIX - 124
NXVERR	=	FIXERR-2	;NON-EXISTENT VARIABLE - 123
IN1ERR	=	NXVERR-2	;TOO MUCH DATA TYPED - 122
IN2ERR	=	IN1ERR-2	;NOT ENOUGH DATA TYPED - 121
IN3ERR	=	IN2ERR-2	;ILLEGAL CHARACTERS ON INPUT - 120
;
; END OF DIAGNOSTIC CALLS
;
;
.	=	ENDVEC
;
; TRAP AND ERROR HANDLER
;	FATAL ERRORS WIPE OUT THE SYSTEM STACK AND RETURN TO THE
;	COMMAND INTERPRETER AFTER GIVING THE DIAGNOSTIC.  NON-FATAL
;	ERRORS RETURN TO THE CALLING ROUTINE.
;
TRAP00:	MOV	@SP,2(SP)	;GET RID OF UNUSED STATUS
	SUB	#2,@SP		;POINT TO LOCATION OF TRAP
	MOV	@(SP)+,-(SP)	;GET THE TRAP INSTRUCTION
	ASR	@SP		;IS IT AN ERROR CALL?
	BCS	ERRR00		;JUMP IF ERROR CALL
	ASL	@SP		;RESTORE CALL
	ADD	#TRAP01-TRAP,@SP	;GET ADDRESS OF DESIRED ROUTINE
	MOV	@(SP)+,PC	;GO TO IT
;
ERRR00:	BIC	#177600,@SP	;GET ERROR CODE
	MOV	(SP)+,R2
	CMP	R2,#FENCE	;IS IT FATAL?
	BGT	ERRR01		;JUMP IF NON-FATAL
	CLR	OLDF
	MOV	#1,ECHO
	MOV	ENDUSR,SP	;ZAP THE STACK
	MOV	#STOP02,-(SP)	;GET NEW RETURN ADDRESS
ERRR01:	MOV	R1,-(SP)	;SAVE TEXT POINTER
	MOV	R2,R1
	MOV	#ERRR02,R0	;ASCII DESTINATION
	MOV	R1,-(SP)	;SAVE ERROR CODE
	ITOA
	CRLF
	MOV	#ERRR03,R0	;START OF MESSAGE
	PRINTL			;PRINT THE LINE
	PRNTLN			;AND THE LINE NUMBER
	CRLF
	TST	(SP)+		;GET THE ERROR CODE
	BNE	ERRR04		;IS IT OVERFLOW?
	CLRUSR			;YES, CLEAR THE DATA AREA
ERRR04:	MOV	(SP)+,R1	;RESTORE R1
	RTS	PC		;AND RETURN
ERRR03:	.ASCII	/ERROR/
ERRR02:	.ASCII	/       /
	.ASCII	/AT LINE /
	.BYTE	0
	.EVEN
;
;
TRAP01:	PRNT00		;TYPE ONE CHARACTER FROM R2
	CRLF00		;TYPE <CR,LF>
	PRLN00		;TYPE LINE NUMBER
	ATOF00		;ASCII TO FLOATING
	ATOI00		;ASCII TO INTEGER
	ITOA00		;INTEGER TO ASCII
	JTOA00		;DOUBLE INTEGER TO ASCII
	IMUL00		;INTEGER MULTIPLY
	ADDF00		;FLOATING ADD
	SUBF00		;FLOATING SUBTRACT
	NEGF00		;FLOATING NEGATE
	DIVF00		;FLOATING DIVIDE
	MULF00		;FLOATING MULTIPLY
	MOVF00		;MOVE FLOATING
	CMPF00		;COMPARE FLOATING
	FLT00		;FLOAT
	FIX00		;FIX
	FIXS00		;SPECIAL FIX
	MINIT
	MFRAC
	MSETU
	MDOPO
	MMOVE
	MINI2
	MAPPR
	MDPIM
	MDPID
	PRN00		;PRINT LINE - R0=FBA, R1=LBA
	TST00		;TEST ALPHABETIC VS NUMERIC
	SKIP00		;SKIP BLANKS IN WORKING STORAGE
	FIND00		;FIND LINE NUMBER SPECIFIED IN R0
	SQU00		;DELETE TEXT TO TERMINATOR
	PCK00		;PACK LINE INTO WORKING STORAGE
	SRCH00		;SEARCH FOR LINE FEED
	TSTU00		;CHECK FOR ENOUGH USER SPACE
	GET00		;GET PARAMETERS FOR COMMAND
	JUNK00			;FIND LOGICAL END OF LINE
	PUSH00		;PUSH ONE WORD ON THE USER STACK
	SRL00		;SEARCH FOR ITEM IN USER STORAGE
	CLRU00		;DELETE TEMPORARY USER SPACE IF ANY
	SCR00		;DELETE N BYTES FROM USER SPACE
	ARYL00		;COMPUTE ARRAY LENGTH
	DIMC00		;CHECK LEGAL DIMENSION
	GETV00		;GET TRUNCATED VARIABLE
	MLS00		;MULTIPLY R0 BY SIX
	SUBS00		;COMPUTE SUBSCRIPT EXPRESSION
	TXT00		;GET EVEN USER STORAGE ADDRESS
	EVAL00		;EVALUATE EXPRESSION
	TWO00		;PACK TWO CHARACTERS IN R4
	MOVS00		;MOVE R4,R3,R2 TO THE STACK
	GTDR00		;GET ADDRESS OF VARIABLE ELEMENT
	PSH00		;PUSH NAMED VARIABLE ON LIST
	PUT00		;PUSH A VALUE ON THE LIST
	BASX		;INITIALIZATION QUESTIONS
;
; END OF TRAP HANDLER

	.EOT		;END OF TAPE 1
