;;; This is the Scelbi Basic Program from 1974 known as
;;; SCELBAL by Mark G. Arnold (MGA) and Nat Wadsworth  
;;;
;;;  Copyright 1975 Scelbi Computer Consulting, Inc.
;;;  All rights reserved
;;;
;;; MGA gives permission to use SCELBAL for 
;;; educational, historical, non-commercial purposes.
;;; Versions of this have been circulating on the web since
;;; about 2000; this version is authorized by MGA (Mar 2012)
;;; with the understanding no warranty is expressed or implied.
;;; As stated in the original, "no responsibility is assumed for
;;; for inaccuracies or for the success or failure of
;;; various applications to which the information herein
;;; may be applied."
;;; 
;;; SCELBAL is the only open-source, floating-point 
;;; high-level language ever implemented on Intel's first
;;; general-purpose microprocessor, the 8008.  It was
;;; published in book form:
;;;
;;;  SCELBAL: A Higher-Level Language for 8008/8080 Systems
;;;
;;; (Tiny BASIC only used 16-bit integers; the MCM\70
;;; was a closed system; calculators implemented with 8008
;;; were floating-point, but not high-level.)
;;;
;;; This version is modified to assemble with the
;;; as8 assembler (using the -octal option) 
;;; for the Intel 8008 by Thomas E. Jones.
;;; This current form is made up non-relocatable so that
;;; locations of all code and data is identical to the
;;; original SCELBAL documents and patches.  It should be
;;; reasonable after debugging code to convert this to a
;;; relocatable and ROMable code with variables in RAM.
;;; This code originates from a version made by 
;;;
;;;    Steve Loboyko in 2001.
;;;
;;; This version has all 3 patches for SCELBAL (the two
;;; pasted in the original manual, and a third which was
;;; written in SCELBAL UPDATE publication, as well as
;;; a couple changes to constants which didn't actually
;;; require a patch, just changes to bytes of data or
;;; arguments to an instruction--one of these (Tucker) was 
;;; incorrect and restored to original by MGA March 2012).
;;; 
;;; This comment must be incorporated with any version of SCELBAL
;;; downloaded, distributed, posted or disemenated.
	

ENDPGRAM:  EQU 055       ;MGA 4/10/12 as in orig; for his ROMable Loboyko said 077       [077]
BGNPGRAM:  EQU 033       ;MGA 4/10/12 as in orig; for his ROMable Loboyko said 044       [044]
	
;;; Here are labels originally attempting to make the code
;;; relocatable.  These 4 pages contain variable data
;;; which needs to be relocated from ROM to RAM.
;;; I can't vouch for ALL references to these pages in
;;; the code being switched to these labels, but they
;;; seem to be.
	
OLDPG1:		EQU	001#000
OLDPG26:	EQU	026#000
OLDPG27:	EQU	027#000
OLDPG57:	EQU	057#000


;;; Page zero will contain the I/O Routines.  These are actually
;;; just as suggested by Scelbal Manual for Serial I/O.

	ORG 000#100		; save a bit of space before this
	
save:	
load:	JMP EXEC		; By default, save and load isn't implemented.

INPORT:	EQU 2
OUTPORT: EQU 2

;;; HERE IS THE USER DEFINED CHARACTER INPUT TO READ FROM SERIAL PORT
	
CINP:	INP INPORT
	NDA
	JTS CINP
	XRA
	LBI 104

MORE1:	DCB
	JFZ MORE1
	OUT OUTPORT
	CAL TIMER
	CAL NEXBIT
	CAL NEXBIT
	CAL NEXBIT
	CAL NEXBIT
	CAL NEXBIT
	CAL NEXBIT
	CAL NEXBIT
	CAL NEXBIT

STOP:	LAI 001
	OUT OUTPORT
	LAB
	RLC
	LBI 314

MORE3:	DCB
	JFZ MORE3
	RET

NEXBIT:	INP INPORT
	NDI 200
	RLC
	OUT OUTPORT
	RRC
	ADB
	RRC
TIMER:	LBI 213
MORE2:	DCB
	JFZ MORE2
	LBA
	RET
;;; no user defined functions yet, stop here if we see one.
UDEFX:	HLT

;;; HERE IS THE USER DEFINED PRINT ROUTINE FOR A SERIAL PORT
	
CPRINT:	NDA
	RAL
	OUT OUTPORT
	RAR
	CAL TIMER
	CAL BITOUT
	CAL BITOUT
	CAL BITOUT
	CAL BITOUT
	CAL BITOUT
	CAL BITOUT
	CAL BITOUT
	CAL BITOUT
	LBA
	LAI 001
	OUT OUTPORT
	LAB
	CAL TIMER
	LBI 103
	JMP MORE3

BITOUT:	OUT OUTPORT
	RRC
	CAL TIMER
	RET
;;; THE ABOVE MUST CONCLUDE BEFORE BY PAGE 1 STARTS
	
	
;;; Page one has many constants and variables.
	
	ORG 001#000
	DATA *4
	DATA 000,000,100,001	; STORES FLOATING POINT CONSTANT +1.0
	DATA *3
	DATA 000		; EXPONENT COUNTER
	DATA 000,000,000,000	; STORES FLOATING POINT NUMBER TEMPORARILLY
	DATA *4
	DATA 000,000,300,001	; STORES FLOATING POINT CONSTANT -1.0
	DATA 000,000,000,000	; SCRATCH PAD AREA (16 BYTES)
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 001,120,162,002	; STORES RANDOM NUMBER GENERATOR CONSTANT VALUE
	DATA *4
	DATA 003,150,157,014	; STORES RANDOM NUMBER GENERATOR CONSTANT VALUE
	DATA 000,000,000,000	; SCRATCH PAD AREA (12 BYTES) (01 064-077)
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000		; SIGN INDICATOR
	DATA 000		; BITS COUNTER
	DATA 000,000		; SIGN INDICATOR
	DATA 000		; INPUT DIGIT COUNTER
	DATA 000		; TEMP STORATE
	DATA 000		; OUTPUT DIGIT COUNTER
	DATA 000 		; FP MODE INDICATOR
	DATA *7			; NOT ASSIGNED (SHOULD BE 01 111-117)
	DATA 000,000,000,000	; FPACC EXTENSION
	DATA 000,000,000,000	; FPACC LSW, NSW, MSW, EXPONENT
	DATA 000,000,000,000	; FPOP  Extension
	DATA 000,000,000,000	; FPOP  LSW, NSW, MSW, EXPONENT
	DATA 000,000,000,000	; FLOATING POINT WORKING AREA
	DATA 000,000,000,000	; (SHOULD BE AT 01 140-01-167)
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA *8			; NOT ASSIGNED (SHOULD BE 01 170-01 177)
	DATA 000,000,000,000	; TEMPORARY REGISTER STORAGE AREA (D,E,H&L)
	DATA *4			; NOT ASSIGNED (01 204-01 207)
	DATA 000,000,120,004	; STORES FLOATING POINT CONSTANT +10.0
	DATA 147,146,146,375	; STORES FLOATING POINT CONSTANT +0.1
	DATA 000		; GETINP COUNTER
	DATA *6			; NOT ASSIGNED (01 221-01 226)
	DATA 000		; ARITHMETIC STACK POINTER (01 227)
	DATA 000		; ARITHMETIC STACK (NOT CLEAR HOW LONG)
	ORG 001#272
	DATA 004		; CC FOR SAVE
	DATA "SAVE"
	DATA 004		; CC FOR LOAD
	DATA "LOAD"
	DATA 000,000,000,000	; UNCLEAR WHAT THIS IS (01 304-01 317) ZEROS
	DATA 000,000,000,000	; (PROBABLY STEP, FOR/NEXT, AND ARRAY PTR TEMP)
	DATA 000,000,000,000
	;; AT THIS POINT WE SHOULD BE AT LOCATION 01 320
	DATA 4
	DATA "THEN"
	DATA 2
	DATA "TO"
	DATA 4
	DATA "STEP"
	DATA 4
	DATA "LIST"
	DATA 3
	DATA "RUN"
	DATA 3
	DATA "SCR
	DATA 013		; CC FOR "READY" MESSAGE
	DATA 224,215,212	; CTRL-T, CARRIAGE RETURN, LINE FEED
	DATA "READY"
	DATA 215,212,212	; CARRIAGE RETURN, LINE FEED, LINE FEED;
	DATA 011
	DATA " AT LINE "
	;; THIS SHOULD BE THE END OF PAGE 01

	
	ORG 002#000		; START PAGE 02, THE CODE
	

SYNTAX:    CAL CLESYM             ;Clear the SYMBOL BUFFER area
           LLI 340                ;Set L to start of LINE NUMBER BUFFER
           LHI \HB\OLDPG26        ;** Set H to page of LINE NUMBER BUFFER
           LMI 000                ;Initialize line number buff by placing zero as (cc)
           LLI 201                ;Change pointer to syntax counter/pointer storage loc.
           LMI 001                ;Set pointer to first character (after cc) in line buffer
SYNTX1:    LLI 201                ;Set pointer to syntax cntr/pntr storage location
           CAL GETCHR             ;Fetch the character pointed to by contents of syntax
           JTZ SYNTX2             ;Cntr/pntr from the line input buffer. If character was
           CPI 260                ;A space, ignore. Else, test to see if character was ASCII
           JTS SYNTX3             ;Code for a decimal digit. If not a decimal digit, consider
           CPI 272                ;Line number to have been processed by jumping
           JFS SYNTX3             ;Over the remainder of this SYNTX1 section.
           LLI 340                ;If have decimal digit, set pointer to start of LINE
           CAL CONCT1             ;NUMBER BUFFER and append incoming digit there.
SYNTX2:    LLI 201                ;Reset L to syntax cntr/pntr storage location. Call sub-
           CAL LOOP               ;Routine to advance pntr and test for end of inr)ut buffer
           JFZ SYNTX1             ;If not end of input buffer, go back for next digit
           LLI 203                ;If end of buffer, only had a line number in the line.
           LMI 000                ;Set pntr to TOKEN storage location. Set TOKEN = 000.
           RET                    ;Return to caller.
SYNTX3:    LLI 201                ;Reset pointer to syntax cntr/pntr and fetch
           LBM                    ;Position of next character after the line number
           LLI 202                ;Change pntr to SCAN pntr storage location
           LMB                    ;Store address when SCAN takes up after line number
SYNTX4:    LLI 202                ;Set pntr to SCAN pntr stomge location
           CAL GETCHR             ;Fetch the character pointed to by contents of the SCAN
           JTZ SYNTX6             ;Pointer storage location. If character was ASCII code
           CPI 275                ;For space, ignore. Else, compare character with "=" sign
           JTZ SYNTX7             ;If is an equal sign, go set TOKEN for IMPLIED LET.
           CPI 250                ;Else, compare character with left parenthesis " ( "
           JTZ SYNTX8             ;If left parenthesis, go set TOKEN for implied array LET
           CAL CONCTS             ;Otherwise, concatenate the character onto the string
           LLI 203                ;Being constructed in the SYMBOL BUFFER. Now set
           LMI 001                ;Up TOKEN storage location to an initial value of 001.
           LHI \HB\OLDPG27        ;** Set H to point to start of KEYWORD TABLE.
           LLI 000                ;Set L to point to start of KEYWORD TABLE.
SYNTX5:    LDI \HB\OLDPG26        ;** Set D to page of SYMBOL BUFFER
           LEI 120                ;Set E to start of SYMBOL BUFFER
           CAL STRCP              ;Compare char string presently in SYMBOL BUFFER
           RTZ                    ;With entry in KEYWORD TABLE. Exit if match.
           CAL SWITCH             ;TOKEN will be set to keyword found. Else, switch
SYNTXL:    INL                    ;Pointers to get table address back and advance pntr to
           LAM                    ;KEYWORD TABLE. Now look for start of next entry
           NDI 300                ;In KEYWORD TABLE by looking for (cc) byte which
           JFZ SYNTXL             ;Will NOT have a one in the two most sig. bits. Advance
           CAL SWITCH             ;Pntr til next entry found. Then switch pointers apin so
           LLI 203                ;Table pointer is in D&E. Put addr of TOKEN in L.
           LHI \HB\OLDPG26        ;** And page of TOKEN in H. Fetch the value currently
           LBM                    ;In TOKEN and advance it to account for going on to
           INB                    ;The next entry in the KEYWORD TABLE.
           LMB                    ;Restore the updated TOKEN value back to storage.
           CAL SWITCH             ;Restore the keyword table pointer back to H&L.
           LAB                    ;Put TOKEN count in ACC.
           CPI 015                ;See if have tested all entries in the keyword table.
           JFZ SYNTX5             ;If not, continue checking the keyword table.
SYNTX6:    LLI 202                ;Set L to SCAN pointer storage location
           LHI \HB\OLDPG26        ;** Set H to page of SCAN pointer stomge location
           CAL LOOP               ;Call routine to advance pntr & test for end of In buffer
           JFZ SYNTX4             ;Go back and add another character to SYMBOL BUFF
           LLI 203                ;And search table for KEYWORD again. Unless reach
           LMI 377                ;End of line input buffer. In which case set TOKEN=377
           RET                    ;As an error indicator and exit to calling routine.
SYNTX7:    LLI 203                ;Set pointer to TOKEN storage register. Set TOKEN
           LMI 015                ;Equal to 015 when "=" sign found for IMPLIED LET.
           RET                    ;Exit to calling routine.
SYNTX8:    LLI 203                ;Set pointer to TOKEN storage register. Set TOKEN
           LMI 016                ;Equal to 016 when "(" found for IMPLIED array LET.
           RET                    ;Exit to calling routine.

                                  ;The following are subroutines used by SYNTAX and
                                  ;other routines in SCELBAL.

BIGERR:    LAI 302                ;Load ASCII code for letters B and G to indicate BIG
           LCI 307                ;ERROR (for when buffer, stack,etc., overflows).
ERROR:     CAL ECHO               ;Call user provided display routine to print ASCII code
           LAC                    ;In accumulator. Transfer ASCII code from C to ACC
           CAL ECHO               ;And repeat to display error codes.
           JMP FINERR             ;Go cpmplete error message (AT LINE) as required.
GETCHR:    LAM                    ;Get pointer from memory location pointed to by H&L
           CPI 120                ;See if within range of line input buffer.
           JFS BIGERR             ;If not then have an overflow condition = error.
           LLA                    ;Else can use it as addr of character to fetch from the
           LHI \HB\OLDPG26        ;** LINE INPUT BUFFER by setting up H too.
           LAM                    ;Fetch the character from the line input buffer.
           CPI 240                ;See if it is ASCII code for space.
           RET                    ;Return to caller with flags set according to comparison.
CLESYM:    LLI 120                ;Set L to start of SYMBOL BUFFER.
           LHI \HB\OLDPG26        ;** Set H to page of SYMBOL BUFFER.
           LMI 000                ;Place a zero byte at start of SYMBOL BUFFER.
           RET                    ;To effectively clear the buffer. Then exit to caller.


                                  ;Subroutine to concatenate (append) a character to the
                                  ;SYMBOL BUFFER. Character must be alphanumeric.

CONCTA:    CPI 301                ;See if character code less than that for letter A.
           JTS CONCTN             ;If so, go see if it is numeric.
           CPI 333                ;See if character code greater than that for letter Z.
           JTS CONCTS             ;If not, have valid alphabetical character.
CONCTN:    CPI 260                ;Else, see if character in valid numeric range.
           JTS CONCTE             ;If not, have an error condition.
           CPI 272                ;Continue to check for valid number.
           JFS CONCTE             ;If not, have an error condition.
CONCTS:    LLI 120                ;If character alphanumeric, can concatenate. Set pointer
           LHI \HB\OLDPG26        ;** To starting address of SYMBOL BUFFER.
CONCT1:    LCM                    ;Fetch old character count in SYMBOL BUFFER.
           INC                    ;Increment the value to account for adding new
           LMC                    ;Character to the buffer. Restore updated (cc).
           LBA                    ;Save character to be appended in register B.
           CAL INDEXC             ;Add (cc) to address in H & L to get new end of buffer
           LMB                    ;Address and append the new character to buffer
           LAI 000                ;Clear the accumulator
           RET                    ;Exit to caller
CONCTE:    JMP SYNERR             ;If character to be appended not alphanumeric, ERROR!

                                  ;Subroutine to compare
                                  ;character strings pointed to by
                                  ;register pairs D & E and H & L.

STRCP:     LAM                    ;Fetch (cc) of first string.
           CAL SWITCH             ;Switch pointers and fetch length of second string (cc)
           LBM                    ;Into register B. Compare the lengths of the two strings.
           CPB                    ;If they are not the same
           RFZ                    ;Return to caller with flags set to non-zero condition
           CAL SWITCH             ;Else, exchange the pointers back to first string.
STRCPL:    CAL ADV                ;Advance the pointer to string number 1 and fetch a
           LAM                    ;Character from that string into the accumulator.
           CAL SWITCH             ;Now switch the pointers to string number 2.
           CAL ADV                ;Advance the pointer in line number 2.
STRCPE:    CPM                    ;Compare char in stxing 1 (ACC) to string 2 (memory)
           RFZ                    ;If not equal, return to cauer with flags set to non-zero
           CAL SWITCH             ;Else, exchange pointers to restore pntr to string 1
           DCB                    ;Decrement the string length counter in register B
           JFZ STRCPL             ;If not finiahed, continue testing entire string
           RET                    ;If complete match, return with flag in zero condition
STRCPC:    LAM                    ;Fetch character pointed to by pointer to string 1
           CAL SWITCH             ;Exchange pointer to examine string 2
           JMP STRCPE             ;Continue the string comparison loop

                                  ;Subroutine to advance the two byte
                                  ;value in CPU registers H and L.

ADV:       INL                    ;Advance value in register L.
           RFZ                    ;If new value not zero, return to caller.
           INH                    ;Else must increment value in H
           RET                    ;Before retuming to caller

                                  ;Subroutine to advance a buffer pointer
                                  ;and test to see if the end of the buffer
                                  ;has been reached.

LOOP:      LBM                    ;Fetch memory location pointed to by H & L into B.
           INB                    ;Increment the value.
           LMB                    ;Restore it back to memory.
           LLI 000                ;Change pointer to start of INPUT LINE BUFFER
           LAM                    ;Fetch buffer length (cc) value into the accumulator
           DCB                    ;Make value in B original value
           CPB                    ;See if buffer length same as that in B
           RET                    ;Return with flags yielding results of the comparison

                                  ;The following subroutine is used to
                                  ;input characters from the system's
                                  ;input device (such as a keyboard)
                                  ;into the LINE INPUT BUFFER. Routine has limited
                                  ;editing capability included.
                                  ;(Rubout = delete previous character(s) entered.)
;;; This label, STRIN:	should be location 03 014
STRIN:     LCI 000                ;Initialize register C to zero.
STRIN1:    CAL CINPUT             ;Call user provided device input subroutine to fetch one
           CPI 377                ;Character from the input device. Is it ASCII code for
           JFZ NOTDEL             ;Rubout? Skip to next section if not rubout.
           LAI 334                ;Else, load ASCII code for backslash into ACC.
           CAL ECHO               ;Call user display driver to present backslash as a delete
           DCC                    ;Indicator. Now decrement the input character counter.
           JTS STRIN              ;If at beginning of line do NOT decrement H and L.
           CAL DEC                ;Else, decrement H & L line pointer to erase previous
           JMP STRIN1             ;Entry, then go back for a new input.
NOTDEL:    CPI 203                ;See if character inputted was'CONTROL C'
           JTZ CTRLC              ;If so, stop inputting and go back to the EXECutive
           CPI 215                ;If not, see if character was carriage-return
           JTZ STRINF             ;If so, have end of line of input
           CPI 212                ;If not, see if character was line-feed
           JTZ STRIN1             ;If so, ignore the input, get another character
           CAL ADV                ;If none of the above, advance contents of H & L
           INC                    ;Increment the character counter
           LMA                    ;Store the new character in the line input buffer
           LAC                    ;Put new character count in the accumulator
           CPI 120                ;Make sure maximum buffer size not exceeded
           JFS BIGERR             ;If buffer size exceeded, go display BG error message
           JMP STRIN1             ;Else can go back to look for next input
STRINF:    LBC                    ;Transfer character count from C to B
           CAL SUBHL              ;Subtract B from H & L to get starting address of
           LMC                    ;The string and place the character count (cc) there
           CAL CRLF               ;Provide a line ending CR & LF combination on the
           RET                    ;Display device. Then exit to caller.

                                  ;Subroutine to subtract contents of CPU register B from
                                  ;the two byte value in CPU registers H & L.

SUBHL:     LAL                    ;Load contents of register L into the accumulator
           SUB                    ;Subtract the contents of register B
           LLA                    ;Restore the new value back to L
           RFC                    ;If no carry, then no underflow. Exit to caller.
           DCH                    ;Else must also decrement contents of H.
           RET                    ;Before retuming to caller.

                                  ;Subroutine to display a character string on the system's
                                  ;display device.

TEXTC:     LCM                    ;Fetch (cc) from the first location in the buffer (H & L
           LAM                    ;Pointing there upon entry) into register B and ACC.
           NDA                    ;Test the character count value.
           RTZ                    ;No display if (cc) is zero.
TEXTCL:    CAL ADV                ;Advance pointer to next location in buffer
           LAM                    ;Fetch a character from the buffer into ACC
           CAL ECHO               ;Call the user's display driver subroutine
           DCC                    ;Decrement the (cc)
           JFZ TEXTCL             ;If character counter not zero, continue display
           RET                    ;Exit to caller when (cc) is zero.

                                  ;Subroutine to provide carriage-return and line-feed
                                  ;combination to system's display device. Routine also
                                  ;initializes a column counter to zero. Column counter
                                  ;is used by selected output routines to count the num-
                                  ;ber of characters that have been displayed on a line.

CRLF:      LAI 215                ;Load ASCII code for carriage-return into ACC
           CAL ECHO               ;Call user provided display driver subroutine
           LAI 212                ;Load ASCII code for line-feed into ACC
           CAL ECHO               ;Call user provided display driver subroutine
           LLI 043                ;Set L to point to COLUMN COUNTER storage location
           LHI \HB\OLDPG1         ;** Set H to page of COLUMN COUNTER
           LMI 001                ;Initialize COLUMN COUNTER to a value of one
           LHD                    ;Restore H from D (saved by ECHO subroutine)
           LLE                    ;Restore L from E (saved by ECHO subroutine)
           RET                    ;Then exit to calling routine

                                  ;Subroutine to decrement double-byte value in CPU
                                  ;registers H and L.

DEC:       DCL                    ;Decrement contents of L
           INL                    ;Now increment to exercise CPU flags
           JFZ DECNO              ;If L not presently zero, skip decrementing H
           DCH                    ;Else decrement H
DECNO:     DCL                    ;Do the actual decrement of L
           RET                    ;Return to caller


                                  ;Subroutine to index the value in CPU registers H and L
                                  ;by the contents of CPU register B.

INDEXB:    LAL                    ;Load L into the accumulator
           ADB                    ;Add B to that value
           LLA                    ;Restore the new value to L
           RFC                    ;If no carry,  return to caller
           INH                    ;Else, increment value in H
           RET                    ;Before returning to caller

                                  ;The following subroutine is used to
                                  ;display the ASCII encoded character in the ACC on the
                                  ;system's display device. This routine calls a routine
                                  ;labeled CINPUT which must be provided by the user to
                                  ;actually drive the system's output device. The subroutine
                                  ;below also increments an output column counter each time
                                  ;it is used.

ECHO:      LDH                    ;Save entry value of H in register D
           LEL                    ;And save entry value of L in register E
           LLI 043                ;Set L to point to COLUMN COUNTER storage location
           LHI \HB\OLDPG1         ;** Set H to page of COLUMN COUNTER
           LBM                    ;Fetch the value in the COLUMN COUNTER
           INB                    ;And increment it for each character displayed
           LMB                    ;Restore the updated count in memory
           CAL CPRINT              ;tt Call the user's device driver subroutine
           LHD                    ;Restore entry value of H from D
           LLE                    ;Restore entry value of L from E
           RET                    ;Return to calling routine
CINPUT:	   JMP CINP               ;Reference to user defined input subroutine

;;; The label EVAL: SHOULD BE AT 03 224
EVAL:      LLI 227                ;Load L with address of ARITHMETIC STACK pointer
           LHI \HB\OLDPG1         ;** Set H to page of ARITHMETIC STACK pointer
           LMI 224                ;Initialize ARITH STACK pointer value to addr minus 4
           INL                    ;Advance memory pointer to FUN/ARRAY STACK pntr
           LHI \HB\OLDPG26        ;** Set H to page of FUN/ARRAY STACK pointer
           LMI 000                ;Initialize FUNIARRAY STACK pointer to start of stack
           CAL CLESYM             ;Initialize the SYMBOL BUFFER to empty condition
           LLI 210                ;Load L with address of OPERATOR STACK pointer
           LMI 000                ;Initialize OPERATOR STACK pointer value
           LLI 276                ;Set L to address of EVAL pointer (start of expression)
           LBM                    ;Fetch the EVAL pointer value into register B
           LLI 200                ;Set up a working pointer register in this location
           LMB                    ;And initialize EVAL CURRENT pointer
SCAN1:     LLI 200                ;Load L with address of EVAL CURRENT pointer
           CAL GETCHR             ;Fetch a character in the expression being evaluated
           JTZ SCAN10             ;If character is a space, jump out of this section
           CPI 253                ;See if character is a "+" sign
           JFZ SCAN2              ;If not, continue checking for an operator
           LLI 176                ;If yes, set pointer to PARSER TOKEN storage location
           LMI 001                ;Place TOKEN value for "+" sign in PARSER TOKEN
           JMP SCANFN             ;Go to PARSER subroutine entry point
SCAN2:     CPI 255                ;See if character is a minus ("-") sign
           JFZ SCAN4              ;If not, continue checking for an operator
           LLI 120                ;If yes, check the length of the symbol stored in the
           LAM                    ;SYMBOL BUFFER by fetching the (cc) byte
           NDA                    ;And testing to see if (cc) is zero
           JFZ SCAN3              ;If length not zero, then not a unary minus indicator
           LLI 176                ;Else, check to see if last operator was a right parenthesi
           LAM                    ;By fetching the value in the PARSER TOKEN storage
           CPI 007                ;Location and seeing if it is token value for ")"
           JTZ SCAN3              ;If last operator was I')" then do not have a unary minus
           CPI 003                ;Check to see if last operator was C4*~2
           JTZ SYNERR             ;If yes, then have a syntax error
           CPI 005                ;Check to see if last operator was exponentiation
           JTZ SYNERR             ;If yes, then have a syntax error
           LLI 120                ;If none of the above, then minus sign is unary, put
           LMI 001                ;Character string representing the
           INL                    ;Value zero in the SYMBOL BUFFER in string format
           LMI 260                ;(Character count (cc) followed by ASCII code for zero)
SCAN3:     LLI 176                ;Set L to address of PARSER TOKEN storage location
           LMI 002                ;Set PARSER TOKEN value for minus operator
SCANFN:    CAL PARSER             ;Call the PARSER subroutine to process current symbol
           JMP SCAN10             ;And operator. Then jump to continue processing.
SCAN4:     CPI 252                ;See if character fetched from expression is
           JFZ SCAN5              ;If not, continue checking for an operator
           LLI 176                ;If yes, set pointer to PARSER TOKEN storage location
           LMI 003                ;Place TOKEN value for "*" (multiplication) operator in
           JMP SCANFN             ;PARSER TOKEN and go to PARSER subroutine entry
SCAN5:     CPI 257                ;See if character fetched from expression is
           JFZ SCAN6              ;If not, continue checking for an operator
           LLI 176                ;If yes, set pointer to PARSER TOKEN storage location
           LMI 004                ;Place TOKEN value for "/" (division) operator in
           JMP SCANFN             ;PARSER TOKEN and go to PARSER subroutine entry
SCAN6:     CPI 250                ;See if character fetched from expression is
           JFZ SCAN7              ;If not, continue checking for an operator
           LLI 230                ;If yes, load L with address of FUN/ARRAY STACK
           LBM                    ;Pointer. Fetch the value in the stack pointer. Increment
           INB                    ;It to indicate number of "(" operators encountered.
           LMB                    ;Restore the updated stack pointer back to memory
           CAL FUNARR             ;Call subroutine to process possible FUNCTION or
           LLI 176                ;ARRAY variable subscript. Ihen set pointer to
           LMI 006                ;PARSER TOKEN storage and set value for operator
           JMP SCANFN             ;Go to PARSER subroutine entry point.
SCAN7:     CPI 251                ;See if character fetched from expression is
           JFZ SCAN8              ;If not, continue checking for an operator
           LLI 176                ;If yes, load L with address of PARSER TOKEN
           LMI 007                ;Set PARSER TOKEN value to reflect ")"
           CAL PARSER             ;Call the  PARSER subroutine to process current symbol
	
           CAL PRIGHT             ;Call subroutine to handle FUNCTION or ARRAY
           LLI 230                ;Load L with address of FUN/ARRAY STACK pointer
           LHI \HB\OLDPG26        ;** Set H to page of FUN/ARRAY STACK pointer
           LBM                    ;Fetch the value in the stack pointer. Decrement it
           DCB                    ;To account for left parenthesis just processed.
           LMB                    ;Restore the updated value back to memory.
           JMP SCAN10             ;Jump to continue processing expression.
SCAN8:     CPI 336                ;See if character fetched from expression is " t
           JFZ SCAN9              ;If not, continue checking for an operator
           LLI 176                ;If yes, load L with address of PARSER TOKEN
           LMI 005                ;Put in value for exponentiation
           JMP SCANFN             ;Go to PARSER subroutine entry point.
SCAN9:     CPI 274                ;See if character fetched is the "less than" sign
           JFZ SCAN11             ;If not, continue checking for an operator
           LLI 200                ;If yes, set L to the EVAL CURRENT pointer
           LBM                    ;Fetch the pointer
           INB                    ;Increment it to point to the next character
           LMB                    ;Restore the updated pointer value
           CAL GETCHR             ;Fetch the next character in the expression
           CPI 275                ;Is the character the "= 9 $ sign?
           JTZ SCAN13             ;If so, have 'less than or equal" combination
           CPI 276                ;Is the character the "greater than" sign?
           JTZ SCAN15             ;If so, have "less than or greater than" combination
           LLI 200                ;Else character is not part of the operator. Set L back
           LBM                    ;To the EVAL CURRENT pointer. Fetch the pointer
           DCB                    ;Value and decriment it back one character in the
           LMB                    ;Expression. Restore the original pointer value.
           LLI 176                ;Have just the 'less than" operator. Set L to the
           LMI 011                ;PARSER TOKEN storage location and set the value for
           JMP SCANFN             ;The 'less than" sign then go to PARSER entry point.
SCAN11:    CPI 275                ;See if character fetched is the "= " sign
           JFZ SCAN12             ;If not, continue checking for an operator
           LLI 200                ;If yes, set L to the EVAL CURRENT pointer
           LBM                    ;Fetch the pointer
           INB                    ;Increment it to point to the next character
           LMB                    ;Restore the updated pointer value
           CAL GETCHR             ;Fetch the next character in the expression
           CPI 274                ;Is the character the "less than" sign?
           JTZ SCAN13             ;If so, have "less than or equal" combination
           CPI 276                ;Is the character the "greater than" sign?
           JTZ SCAN14             ;If so, have "equal or greater than" combination
           LLI 200                ;Else character is not part of the operator. Set L back
           LBM                    ;To the EVAL CURRENT pointer. Fetch the pointer
           DCB                    ;Value and decrement it back one character in the
           LMB                    ;Expression. Restore the original pointer value.
           LLI 176                ;Just have '~-- " operator. Set L to the PARSER TOKEN
           LMI 012                ;Storage location and set the value for the sign.
           JMP SCANFN             ;Go to the PARSER entry point.
SCAN12:    CPI 276                ;See if character fetched is the "greater than" sign
           JFZ SCAN16             ;If not, go append the character to the SYMBOL BUFF
           LLI 200                ;If so, set L to the EVAL CURRENT pointer
           LBM                    ;Fetch the pointer
           INB                    ;Increment it to point to the next character
           LMB                    ;Restore the updated pointer value
           CAL GETCHR             ;Fetch the next character in the expression
           CPI 274                ;Is the character the "less than" sign?
           JTZ SCAN15             ;If so, have "less than or greater than" combination
           CPI 275                ;Is the character the "= " sign?
           JTZ SCAN14             ;If so, have the "equal to or greater than " combination
           LLI 200                ;Else character is not part of the operator. Set L back
           LBM                    ;To the EVAL CURRENT pointer. Fetch the pointer
           DCB                    ;Value and decrement it back one character in the
           LMB                    ;Expression. Restore the original pointer value.
           LLI 176                ;Have just the "greater than" operator. Set L to the
           LMI 013                ;PARSER TOKEN storage location and set the value for
           JMP SCANFN             ;The "greater than" sign then go to PARSER entry
SCAN13:    LLI 176                ;When have 'less than or equal" combination set L to
           LMI 014                ;PARSER TOKEN storage location and set the value.
           JMP SCANFN             ;Then go to the PARSER entry point.
SCAN14:    LLI 176                ;When have "equal to or greater than" combination set L
           LMI 015                ;To PARSER TOKEN storage location and set the value.
           JMP SCANFN             ;Then go to the PARSER entry point.
SCAN15:    LLI 176                ;When have 'less than or greater than" combination set
           LMI 016                ;L to PARSER TOKEN storage location and set value.
           JMP SCANFN             ;Then go to the PARSER entry point.
SCAN16:    CAL CONCTS             ;Concatenate the character to the SYMBOL BUFFER
SCAN10:    LLI 200                ;Set L to the EVAL CURRENT pointer storage location
           LHI \HB\OLDPG26        ;** Set H to page of EVAL CURRENT pointer
           LBM                    ;Fetch the EVAL CURRENT pointer value into B
           INB                    ;Increment the pointer value to point to next character
           LMB                    ;In the expression and restore the updated value.
           LLI 277                ;Set L to EVAL FINISH storage location.
           LAM                    ;Fetch the EVAL FINISH value into the accumulator.
           DCB                    ;Set B to last character processed in the expression.
           CPB                    ;See if last character was at EVAL FINISH location.
           JFZ SCAN1              ;If not, continue processing the expression. Else, jump
           JMP PARSEP             ;To final evaluation procedure and test.  (Directs routine
           HLT                    ;To a dislocated section.) Safety Halt in unused byte.
PARSER:    LLI 120                ;Load L with starting address of SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Load H with page of SYMBOL BUFFER
           LAM                    ;Fetch the (cc) for  contents of SYMBOL BUFFER
           NDA                    ;Into the ACC and see if buffer is  empty
           JTZ PARSE              ;If empty then no need to convert contents
           INL                    ;If not empty, advance buffer pointer
           LAM                    ;Fetch the first character in the buffer
           CPI 256                ;See if it is ASCII code for decimal sign
           JTZ PARNUM             ;If yes, consider contents of buffer to be a number
           CPI 260                ;If not decimal sign, see if first character represents
           JTS LOOKUP             ;A deciinal digit, if not, should have a variable
           CPI 272                ;Continue to test for a decimal digit
           JFS LOOKUP             ;If not, go look up the variable nwne
PARNUM:    DCL                    ;If SYMBOL BUFFER contains number, decrement
           LAM                    ;Buffer pointer back to (cc) and fetch it to ACC
           CPI 001                ;See if length of string in buffer is just one
           JTZ NOEXPO             ;If so, cannot have number with scientific notation
           ADL                    ;If not, add length to buffer pointer to
           LLA                    ;Point to last character in the buffer
           LAM                    ;Fetch the last character in buffer and see if it
           CPI 305                ;Represents letter E for Exponent
           JFZ NOEXPO             ;If not, cannot have number with scientific notation
           LLI 200                ;If yes, have part of a scientific number, set pointer to
           CAL GETCHR             ;Get the operator that follows the E and append it to
           JMP CONCTS             ;The SYMBOL BUFFER and return to EVAL routine
NOEXPO:    LLI 227                ;Load L with address of ARITHMETIC STACK pointer
           LHI \HB\OLDPG1         ;** Load H with page of ARITHMETIC STACK pointer
           LAM                    ;Fetch AS pointer value to ACC and add four to account
           ADI 004                ;For the number of bytes required to store a number in
           LMA                    ;Floating point format. Restore pointer to mernory.
           LLA                    ;Then, change L to point to entry position in the AS
           CAL FSTORE             ;Place contents of the FPACC onto top of the AS
           LLI 120                ;Change L to point to start of the SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Set H to page of the SYMBOL BUFFER
           CAL DINPUT             ;Convert number in the buffer to floating point format
           JMP PARSE              ;In the FPACC then jump to check operator sign.
LOOKUP:    LLI 370                ;Load L with address of LOOK-UP COUNTER
           LHI \HB\OLDPG26        ;** Load H with page of the counter
           LMI 000                ;Initialize the counter to zero
           LLI 120                ;Load L with starting address of the SYMBOL BUFFER
           LDI \HB\OLDPG27        ;** Load D with page of the VARIABLES TABLE
           LEI 210                ;Load E with start of the VARL433LES TABLE
           LAM                    ;Fetch the (cc) for the string in the SYMBOL BUFFER
           CPI 001                ;See if the name length is just one character. If not,
           JFZ LOOKU1             ;Should be two so proceed to look-up routine. Else,
           LLI 122                ;Change L to second character byte in the buffer and set
           LMI 000                ;It to zero to provide compatibility with entries in table
LOOKU1:    LLI 121                ;Load L with addr of first character in the SYMBOL
           LHI \HB\OLDPG26        ;** BUFFER. Set H to page of the SYMBOL BUFFER.
           CAL SWITCH             ;Exchange contents of D&E with H&L so that can
           LAM                    ;Fetch the first character of a name in the VARIABLES
           INL                    ;TABLE. Advance the table pointer and save the
           LBM                    ;Second byte of name in B. Then advance the pointer
           INL                    ;Again to reach first bvte of floating point forrnatted
           CAL SWITCH             ;Number in table. Now exchange D&E with H&L and
           CPM                    ;Compare first byte in table against first char in buffer
           JFZ LOOKU2             ;If not the same, go try next entry in table. If same,
           INL                    ;Advance pointer to next char in buffer. Transfer the
           LAB                    ;Character in B (second byte in table entry) to the ACC
           CPM                    ;Compare it against second character in the buffer.
           JTZ LOOKU4             ;If match, have found the name in the VARIABLES tbl.
LOOKU2:    CAL AD4DE              ;Call subroutine to add four to the pointer in D&E to
           LLI 370                ;Advance the table pointer over value bytes. Then set
           LHI \HB\OLDPG26        ;** Up H and L to point to LOOK-UP COUNTER.
           LBM                    ;Fetch counter value (counts number of entries tested
           INB                    ;In the VARIABLES TABLE), increment it
           LMB                    ;And restore it back to meynory
           LLI 077                ;Load L with address of SYMBOL VARIABLES counter
           LHI \HB\OLDPG27        ;** Do same for H. (Counts number of names in table.)
           LAB                    ;Place LOOK-UP COUNTER value in the accumulator.
           CPM                    ;Compare it with number of entries in the table.
           JFZ LOOKU1             ;If have not reached end of table, keep looking for name.
           LLI 077                ;If reach end of table without match, need to add name
           LHI \HB\OLDPG27        ;** To table. First set H & L to the SYMBOL
           LBM                    ;VARIABLES counter. Fetch the counter value and
           INB                    ;Increment to account for new name being added to the
           LMB                    ;Table. Restore the updated count to meinory. Also,
           LAB                    ;Move the new counter value to the accumulator and
           CPI 025                ;Check to see that table size is not exceeded. If try to
           JFS BIGERR             ;Go over 20 (decirnal) entries then have BIG error.
           LLI 121                ;Else, set L to point to first character in the SYMBOL
           LHI \HB\OLDPG26        ;** BUFFER and set H to proper page. Set the number
           LBI 002                ;Of bytes to be transferred into register B as a counter.
           CAL MOVEIT             ;Move the symbol name from the buffer to the
           LLE                    ;VARIABLES TABLE. Now set up H & L with value
           LHD                    ;Contained in D & E after moving ops (points to first
           XRA                    ;Byte of the value to be associated with the symbol
           LMA                    ;Name.) Clear the accumulator and place zero in all four
           INL                    ;Bytes associated with the variable name entered
           LMA                    ;In the VARIABLES TABLE
           INL                    ;In order to
           LMA                    ;Assign an
           INL                    ;Initial value
           LMA                    ;To the variable narne
           LAL                    ;Then transfer the address in L to the acc'umulator
           SUI 004                ;Subtract four to reset the pointer to start of zeroing ops
           LEA                    ;Restore the address in D & E to be in same state as if
           LDH                    ;Name was found in the table in the LOOKUP routine
LOOKU4:    CAL SAVEHL             ;Save current address to VARIABLES TABLE
           LLI 227                ;Load L with address of ARITHMETIC STACK pointer
           LHI \HB\OLDPG1         ;** Load H with page of the pointer
           LAM                    ;Fetch the AS pointer value to the accumulator
           ADI 004                ;Add four to account for next floating point forrnatted
           LMA                    ;Number to be stored in the stack. Restore the stack
           LLA                    ;Pointer to memory and set it up in register L too.
           CAL FSTORE             ;Place the value in the FPACC on the top of the
           CAL RESTHL             ;ARITHMETIC STACK. Restore the VARIABLES
           CAL SWITCH             ;TABLE pointer to H&L and move it to D&E. Now load
           CAL FLOAD              ;The VARIABLE value from the table to the FPACC.
PARSE:     CAL CLESYM             ;Clear the SYMBOL BUFFER
           LLI 176                ;Load L with address of PARSER TOKEN VALUE
           LAM                    ;And fetch the token value into the accumulator
           CPI 007                ;Is it token value for right parenthesis ")" ? If so, have
           JTZ PARSE2             ;Special case where must perforin ops til find a "(" !
           ADI 240                ;Else, fon-n address to HEIRARCHY IN table and
           LLA                    ;Set L to point to HEIRARCHY IN VALUE in the table
           LBM                    ;Fetch the heirarchy value from the table to register B
           LLI 210                ;Set L to OPERATOR STACK pointer storage location
           LCM                    ;Fetch the OS pointer into CPU register C
           CAL INDEXC             ;Add OS pointer to address of OS pointer storage loc
           LAM                    ;Fetch the token value for the operator at top of the OS
           ADI 257                ;And form address to HEIRARCHY OUT table
           LLA                    ;Set L to point to HEIRARCHY OUT VALUE in the
           LAB                    ;Table. Move the HEIRARCHY IN value to the ACC.
           CPM                    ;Compare the HEIRARCHY IN with the HEIRARCHY
           JTZ PARSE1             ;OUT value. If heirarchy of current operator equal to or
           JTS PARSE1             ;Less than operator on top of OS stack, perfo
           LLI 176                ;Operation indicated in top of OS stack. Else, fetch the
           LBM                    ;Current operator token value into register B.
           LLI 210                ;Load L with address of the OPERATOR STACK pntr
           LCM                    ;Fetch the stack pointer value
           INC                    ;Increment it to account for new entry on the stack
           LMC                    ;Restore the stack pointer value to memory
           CAL INDEXC             ;For in pointer to next entry in OPERATOR STACK
           LMB                    ;Place the current operator token value on top of the OS
           RET                    ;Exit back to the EVAL routine.
PARSE1:    LLI 210                ;Load L with address of the OPERATOR STACK pntr
           LAM                    ;Fetch the stack pointer value to the accumulator
           ADL                    ;Add in the value of the stack pointer address to form
           LLA                    ;Address that points to top entry in the OS
           LAM                    ;Fetch the token value at the top of the OS to the ACC
           NDA                    ;Check to see if the token value is zero for end of stack
           RTZ                    ;Exit back to the EVAL routine if stack empty
           LLI 210                ;Else, reset L to the OS pointer storage location
           LCM                    ;Fetch the pointer value
           DCC                    ;Decrement it to account for operator rernoved from
           LMC                    ;The OPERATOR STACK and restore the pointer value
           CAL FPOPER             ;Perform the operation obtained from the top of the OS
           JMP PARSE              ;Continue to compare current operator against top of OS
PARSE2:    LLI 210                ;Load L with address of the OPERATOR STACK pntr
           LHI \HB\OLDPG26        ;** Load H with page of the pointer
           LAM                    ;Fetch the stack pointer value to the accumulator
           ADL                    ;Add in the value of the stack pointer address to form
           LLA                    ;Address that points to top entry in the OS
           LAM                    ;Fetch the token value at the top of the 0 S to the ACC
           NDA                    ;Check to see if the token value is zero for end of stack
           JTZ PARNER             ;If end of stack, then have a parenthesis error condx
           LLI 210                ;Else, reset L to the OS pointer storage location
           LCM                    ;Fetch the pointer value
           DCC                    ;Decrement it to account for operator removed from
           LMC                    ;The OPERATOR STACK and restore the pointer value
           CPI 006                ;Check to see if token value is "(" to close parenthesis
           RTZ                    ;If so, exit back to EVAL routine.
           CAL FPOPER             ;Else, perforin the op obtained from the top of the OS
           JMP PARSE2             ;Continue to process data in parenthesis
FPOPER:    LLI 371                ;Load L with address of TEMP OP storage location
           LHI \HB\OLDPG26        ;** Load H with page of TEMP OP storage location
           LMA                    ;Store OP (from top of OPERATOR STACK)
           LLI 227                ;Change L to address of ARff HMETIC STACK pointer
           LHI \HB\OLDPG1         ;** Load H with page of AS pointer
           LAM                    ;Fetch AS pointer value into ACC
           LLA                    ;Set L to top of ARITHMETIC STACK
           CAL OPLOAD             ;Transfer number from ARffHMETIC STACK to FPOP
           LLI 227                ;Restore pointer to AS pointer
           LAM                    ;Fetch the pointer value to the ACC and subtract four
           SUI 004                ;To remove top value from the ARITHMETIC STACK
           LMA                    ;Restore the updated AS pointer to memory
           LLI 371                ;Set L to address of TEMP OP storage location
           LHI \HB\OLDPG26        ;** Set H to page of TEMP OP storage location
           LAM                    ;Fetch the operator token value to the ACC
           CPI 001                ;Find out which kind of operation indicated
           JTZ FPADD              ;Perforn addition if have plus operator
           CPI 002                ;If not plus, see if minus
           JTZ FPSUB              ;Perform subtraction if have minus operator
           CPI 003                ;If not minus, see if multiplication
           JTZ FPMULT             ;Perform multiplication if have multiplication operator
           CPI 004                ;If not multiplication, see if division
           JTZ FPDIV              ;Perform division if have division operator
           CPI 005                ;If not division, see if exponentiation
           JTZ INTEXP             ;Perform exponentiation if have exponentiation operator
           CPI 011                ;If not exponentiation, see if "less than" operator
           JTZ LT                 ;Perform compaison for "less than" op if indicated
           CPI 012                ;If not 'less than" see if have "equal" operator
           JTZ EQ                 ;Perforin comparison for "equal" op if indicated
           CPI 013                ;If not "equal" see if have "greater than" operator
           JTZ GT                 ;Perform comparison for "greater than" op if indicated
           CPI 014                ;If not "'greater than" see if have 'less than or equal" op
           JTZ LE                 ;Perform comparison for the combination op if indicated
           CPI 015                ;See if have "equal to or greater than" operator
           JTZ GE                 ;Perform comparison for the combination op if indicated
           CPI 016                ;See if have "less than or greater than" operator
           JTZ NE                 ;Perform comparison for the combination op if indicated
PARNER:    LLI 230                ;If cannot find operator, expression is not balanced
           LHI \HB\OLDPG26        ;** Set H and L to address of F/A STACK pointer
           LMI 000                ;Clear the F/A STACK pointer to re-initialize
           LAI 311                ;Load ASCII code for letter I into the accumulator
           LCI 250                ;And code for "(" character into register C
           JMP ERROR              ;Go display 1( for "Imbalanced Parenthesis") error msg
LT:        CAL FPSUB              ;Subtract contents of FPACC from FPOP to compare
           LLI 126                ;Set L to point to the MSW of the FPACC (Contains
           LAM                    ;Result of the subtraction.) Fetch the MSW of the
           NDA                    ;FPACC to the accumulator and test to see if result is
           JTS CTRUE              ;Positive or negative. Set up the FPACC as a function
           JMP CFALSE             ;Of the result obtained.
EQ:        CAL FPSUB              ;Subtract contents of FPACC from FPOP to compare
           LLI 126                ;Set L to point to the MSW of the FPACC (Contains
           LAM                    ;Result of the subtraction.) Fetch the MSW of the
           NDA                    ;FPACC to the accumulator and test to see if result is
           JTZ CTRUE              ;Equal. Set up the FPACC as a function
           JMP CFALSE             ;Of the result obtained.
GT:        CAL FPSUB              ;Subtract contents of FPACC from FPOP to compare
           LLI 126                ;Set L to point to the MSW of the FPACC (Contains
           LAM                    ;Result of the subtraction.) Fetch the MSW of the
           NDA                    ;FPACC to the accumulator and test to see if result is
           JTZ CFALSE             ;Positive, Negative, or Equal. Set up the FPACC
           JFS CTRUE              ;As a function
           JMP CFALSE             ;Of the result obtained.
LE:        CAL FPSUB              ;Subtract contents of FPACC from FPOP to compare
           LLI 126                ;Set L to point to the MSW of the FPACC (Contains
           LAM                    ;Result of the subtraction.) Fetch the MSW of the
           NDA                    ;FPACC to the accumulator and test to see if result is
           JTZ CTRUE              ;Positive, Negative, or Equal. Set up the FPACC
           JTS CTRUE              ;As a function
           JMP CFALSE             ;Of the result obtained
GE:        CAL FPSUB              ;Submit contents of FPACC from FPOP to compare
           LLI 126                ;Set L to point to the MSW of the FPACC (Contains
           LAM                    ;Result of the subtraction.) Fetch the MSW of the
           NDA                    ;FPACC to the accumulator and test to see if result is
           JFS CTRUE              ;Positive or Negative. Set up the FPACC
           JMP CFALSE             ;As a function of the result obtained
NE:        CAL FPSUB              ;Subtract contents of FPACC from FPOP to compare
           LLI 126                ;Set L to point to the MSW of the FPACC (Contains
           LAM                    ;Result of the subtraction.) Fetch the MSW of the
           NDA                    ;FPACC to the accumulator and test to see if result is
           JTZ CFALSE             ;Equal. Set up the FPACC as a function of the result.
CTRUE:
FPONE:     LLI 004                ;Load L with address of floating point value +1.0
           JMP FLOAD              ;Load FPACC with value +1.0 and exit to caller
CFALSE:    LLI 127                ;Load L with address of FPACC Exponent register
           LMI 000                ;Set the FPACC Exponent to zero and then set the
           JMP FPZERO             ;Mantissa portion of the FPACC to zero. Exit to caller.
AD4DE:     LAE                    ;Subroutine to add four to the value in register E.
           ADI 004                ;Move contents of E to the ACC and add four.
           LEA                    ;Restore the updated value back to register E.
           RET                    ;Return to the calling routine.
INTEXP:    LLI 126                ;Load L with address of WSW of FPACC (Floating Point
           LHI \HB\OLDPG1         ;** ACCumulator). Load H with page of FPACC.
           LAM                    ;Fetch MSW of the FPACC into the accumulator.
           LLI 003                ;Load L with address of EXP TEMP storage location
           LMA                    ;Store the FPACC MSW value in EXP TEMP location
           NDA                    ;Test contents of the MSW of the FPACC. ff zero, then
           JTZ FPONE              ;Set FPACC equal to +1.0 (any nr to zero power = 1.0!)
           CTS FPCOMP             ;If MSW indicates negative number, complement
           CAL FPFIX              ;The FPACC. Then convert floating point number to
           LLI 124                ;Fixed point. Load L with address of LSW of fixed nr
           LBM                    ;Fetch the LSW into CPU register B.
           LLI 013                ;Set L to address of EXPONENT COUNTER
           LMB                    ;Place the fixed value in the EXP CNTR to indicate
           LLI 134                ;Number of multiplications needed (power). Now set L
           LEI 014                ;To LSW of FPOP and E to address of FP TEMP (LSW)
           LHI \HB\OLDPG1         ;** Set H to floating point working area page.
           LDH                    ;Set D to same page address.
           LBI 004                ;Set transfer (precision) counter. Call subroutine to move
           CAL MOVEIT             ;Contents of FPOP into FP TEMP registers to save
           CAL FPONE              ;Original value of FPOP. Now set FPACC to +1.0.
           LLI 003                ;Load L with pointer to original value of FPACC
           LAM                    ;(Stored in FP TEMP) MSW and fetch contents to ACC.
           NDA                    ;Test to see if raising to a negative power. If so, divide
           JTS DVLOOP             ;Instead of multiply!
MULOOP:    LLI 014                ;Load L with address of LSW of FP TEMP (original
           CAL FACXOP             ;Value in FPOP). Move FP TEMP into FPOP.
           CAL FPMULT             ;Multiply FPACC by FPOP. Result left in FPACC.
           LLI 013                ;Load L with address of EXPONENT COUNTER.
           LBM                    ;Fetch the counter value
           DCB                    ;Decrement it
           LMB                    ;Restore it to memory
           JFZ MULOOP             ;If counter not zero, continue exponentiation process
           RET                    ;When have raised to proper power, return to caller.
DVLOOP:    LLI 014                ;Load L with address of LSW of FP TEMP (original
           CAL FACXOP             ;Value in FPOP). Move FP TEMP into FPOP.
           CAL FPDIV              ;Divide FPACC by FPOP. Result left in FPACC.
           LLI 013                ;Load L with address of EXPONENT COUNTER
           LBM                    ;Fetch the counter value
           DCB                    ;Decrement it
           LMB                    ;Restore to memory
           JFZ DVLOOP             ;If counter not zero, continue exponentiation process
           RET                    ;When have raised to proper power, return to caller.

;;; The label PRIGHT: SHOULD BE UP TO 07 003
PRIGHT:    LLI 230                ;Load L with address of F/A STACK pointer
           LHI \HB\OLDPG26        ;** Load H with page of F/A STACK pointer
           LAM                    ;Fetch the pointer value into the ACC
           ADL                    ;Form pointer to top of the F/A STACK
           LLA                    ;Set L to point to top of the F/A STACK
           LAM                    ;Fetch the contents of the top of the F/A STACK into
           LMI 000                ;The ACC then clear the top of the F/A STACK
           LLI 203                ;Load L with address of F /A STACK TEMP storage
           LHI \HB\OLDPG27        ;** Location. Set H to page of F/A STACK TEMP
           LMA                    ;Store value from top of F/A STACK into temp loc.
           NDA                    ;Test to see if token value in top of stack was zero
           RTZ                    ;If so, just had simple grouping parenthesis!
           JTS PRIGH1             ;@@ If token value minus, indicates array subscript
           CPI 001                ;For positive token value, look for appropriate function
           JTZ INTX               ;If token value for INTeger function, go do it.
           CPI 002                ;Else, see if token value for SIGN function.
           JTZ SGNX               ;If so, go do it.
           CPI 003                ;Else, see if token value for ABSolute function
           JTZ ABSX               ;If so, go do it.
           CPI 004                ;If not, see if token value for SQuare Root function
           JTZ SQRX               ;If so, go do it.
           CPI 005                ;If not, see if token value for TAB function
           JTZ TABX               ;If so, go do it.
           CPI 006                ;If not, see if token value for RaNDom function
           JTZ RNDX               ;If so, go find a random number.
           CPI 007                ;If not, see if token value for CHaRacter function
           JTZ CHRX               ;If so, go perform the function.
           CPI 010                ;Else, see if token for user defined machine language
           JTZ UDEFX              ;# Function. If so, perform the User DEfined Function
           HLT                    ;Safety halt. Program should not reach this location!

;;; The label FUNARR SHOULD BE AT 07 100
FUNARR:    LLI 120                ;Load L with starting address of SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Load H with page of SYMBOL BUFFER
           LAM                    ;Fetch the (cc) for contents of buffer to the ACC
           NDA                    ;See if (cc) is zero, if so buffer is empty, return to
           RTZ                    ;Caller as have simple grouping parenthesis sign
           LLI 202                ;Else set L to TEMP COUNTER location
           LHI \HB\OLDPG27        ;** Set H to TEMP COUNTER page
           LMI 000                ;Initialize TEMP COUNTER to zero
FUNAR1:    LLI 202                ;Load L with address of TEMP COUNTER
           LHI \HB\OLDPG27        ;** Load H with page of TEMP COUNTER
           LBM                    ;Fetch the counter value to register B
           INB                    ;Increment the counter
           LMB                    ;Restore the updated value to memory
           LCI 002                ;Initialize C to a value of two for future ops
           LLI 274                ;Load L with starting address (less four) of FUNCTION
           LHI \HB\OLDPG26        ;** LOOK-UP TABLE. Set H to table page.
           CAL TABADR             ;Find address of next entry in the table
           LDI \HB\OLDPG26        ;** Load D with page of SYMBOL BUFFER
           LEI 120                ;Load E with starting address of SYMBOL BUFFER
           CAL STRCP              ;Compare entry in FUNCTION LOOK-UP TABLE with
           JTZ FUNAR4             ;Contents of SYMBOL BUFFER. If find match, go set
           LLI 202                ;Up the function token value. Else, set L to the TEMP
           LHI \HB\OLDPG27        ;** COUNTER and set H to the proper page. Fetch the
           LAM                    ;Current counter value and see if have tried all eight
           CPI 010                ;Possible functions in the table.
           JFZ FUNAR1             ;If not, go back and check the next entry.
           LLI 202                ;If have tried all of the entries in the table, set L
           LHI \HB\OLDPG27        ;** As well as H to the address of the TEMP COUI,.7ER
           LMI 000                ;And reset it to zero. Now go see if have subscripted
           JMP FUNAR2             ;@@ Array (unless array capability not in program).
FAERR:     LLI 230                ;Load L with address of F/A STACK pointer
           LHI \HB\OLDPG26        ;** Load H with page of F/A STACK pointer
           LMI 000                ;Clear the F/A STACK pointer to reset on an error
           LAI 306                ;Load the ASCII code for letter F into the ACC
           LCI 301                ;Load the ASCII code for letter A into register C
           JMP ERROR              ;Go display the FA error message
FUNAR4:    LLI 202                ;Load L with address of TEMP COUNTER
           LHI \HB\OLDPG27        ;** Set H to page of TEMP COUNTER
           LBM                    ;Load value in counter to register B. This is FUNCTION
           LLI 230                ;TOKEN VALUE. Cbange- L to F/A STACK pointer.
           LHI \HB\OLDPG26        ;** Load H with page of F/A STACK pointer.
           LCM                    ;Fetch the F/A STACK pointer value into register C.
           CAL INDEXC             ;Form the address to the top of the F/A STACK.
           LMB                    ;Store the FUNCTION TOKEN VALUE in the F/A
           JMP CLESYM             ;STACK. Then exit by clearing the SYMBOL BUFFER.
TABADR:    LAB                    ;Move the TEMP COUNTER value from B to ACC
TABAD1:    RLC                    ;Multiply by four using this loop to form value equal
           DCC                    ;To number of bytes per entry (4) times current entry
           JFZ TABAD1             ;In the FUNCTION LOOK-UP TABLE.
           ADL                    ;Add this value to the starting address of the table.
           LLA                    ;Form pointer to next entry in table
           RFC                    ;If no carry return to caller
           INH                    ;Else, increment H before
           RET                    ;Returning to caller

;;; The label INTX SHOULD BE AT 07 243
INTX:      LLI 126                ;Load L with address of MSW of the FPACC
           LHI \HB\OLDPG1         ;** Load H with the page of the PPACC
           LAM                    ;Fetch the MSW of the FPACC into the accumulator
           NDA                    ;Test the sign of the number in the FPACC. If
           JFS INT1               ;Positive jump ahead to integerize
           LLI 014                ;If negative, load L with address of FP TEMP registers
           CAL FSTORE             ;Store the value in the FPACC in FP TEMP
           CAL FPFIX              ;Convert the value in FPACC from floating point to
           LLI 123                ;Fixed point. Load L with address of FPACC
           LMI 000                ;Extension register and clear it.
           CAL FPFLT              ;Convert fixed binary back to FP to integerize
           LLI 014                ;Load L with address of FP TEMP registers
           CAL OPLOAD             ;Load the value in FP TEMP into FPOP
           CAL FPSUB              ;Subtract integerized value from original
           LLI 126                ;Set L to address of MSW of FPACC
           LAM                    ;Fetch the MSW of the FPACC into the accumulator
           NDA                    ;See if original value and integerized value the same
           JTZ INT2               ;If so, have integer value in FP TEMP
           LLI 014                ;Else, load L with address of FP TEMP registers
           CAL FLOAD              ;Restore FPACC to original (non-integerized) value
           LLI 024                ;Set L to register containing small value
           CAL FACXOP             ;Set up to add small value to original value in FPACC
           CAL FPADD              ;Perform the addition
INT1:      CAL FPFIX              ;Convert the number in FPACC from floating point
           LLI 123                ;To fixed point. Load L with address of FPACC
           LMI 000                ;Extension register and clear it. Now convert the number
           JMP FPFLT              ;Back to floating point to integerize it and exit to caller
INT2:      LLI 014                ;Load L with address of FP TEMP registers. Transfer
           JMP FLOAD              ;Number from FP TEMP (orig) to FPACC and return.
ABSX:      LLI 126                ;Load L with address of MSW of the FPACC
           LHI \HB\OLDPG1         ;** Set H to page of the FPACC
           LAM                    ;Fetch the MSW of the FPACC into the accumulator
           NDA                    ;Test the sign of the number to see if it is positive.
           JTS FPCOMP             ;If negative, complement the number before returning.
           RET                    ;Else, just return with absolute value in the FPACC.
SGNX:      LLI 126                ;Load L with address of MSW of the FPACC
           LHI \HB\OLDPG1         ;** Load H with the page of the FPACC
           LAM                    ;Fetch the MSW of the FPACC into the accumulator
           NDA                    ;Test to see if the FPACC is zero
           RTZ                    ;Return to caller if FPACC is zero
           JFS FPONE              ;If FPACC is positive, load +1.0 into FPACC and exit
           LLI 024                ;If FPACC is negative, set up to load -1.0 into the
           JMP FLOAD              ;FPACC and exit to caller
CHRX:      CAL FPFIX              ;Convert contents of FPACC from floating point to
           LLI 124                ;Fixed point. Load L with address of LSW of fixed
           LAM                    ;Value. Fetch this byte into the accumulator.
           CAL ECHO               ;Display the value.
           LLI 177                ;Set L to address of the TAB FLAG
           LHI \HB\OLDPG26        ;** Set H to page of the TAB FLAG
           LMI 377                ;Set TAB FLAG (to inhibit display of FP value)
           RET                    ;Exit to caller.
TABX:      CAL FPFIX              ;Convert contents of FPACC from floating point to
TAB1:      LLI 124                ;Fixed point. Load L with address of 1,SW of fixed
           LAM                    ;Value. Fetch this byte into the accumulator.
           LLI 043                ;Load L with address of COLUMN COUNTER
           SUM                    ;Subtract value in C-OLUMN COUNTER from desired
           LLI 177                ;TAB position. Load L with address of the TAB FLAG.
           LHI \HB\OLDPG26        ;** Set H to page of the TAB FLAG.
           LMI 377                ;Set TAB FLAG (to inhibit display of FP value)
           JTS BACKSP             ;If beyond TAB point desired, simulate back spacing
           RTZ                    ;Return to caller if at desired TAB location
TABC:      LCA                    ;Else, put difference count in register C
           LAI 240                ;Place ASCII code for space in ACC
TABLOP:    CAL ECHO               ;Display space on output device
           DCC                    ;Decrement displacement counter
           JFZ TABLOP             ;If have not reached TAB position, continue to space
           RET                    ;Else, return to calling routine.

;;; The label STOSYM should be AT 10 055
STOSYM:    LLI 201                ;Load L with address of ARRAY FLAG
           LHI \HB\OLDPG27        ;** Load H with page of ARRAY FLAG
           LAM                    ;Fetch the value of the ARRAY FLAG into the ACC
           NDA                    ;Check to see if the flag is set indicating processing an
           JTZ STOSY1             ;Array variable value. Jump ahead if flag not set.
           LMI 000                ;If ARRAY FLAG was set, clear it for next time.
           LLI 204                ;Then load L with address of array address storage loc
           LLM                    ;Fetch the array storage address as new pointer
           LHI \HB\OLDPG57        ;tt Set H to ARRAY VALUES page   ****************
           JMP FSTORE             ;Store the array variable value and exit to caller.
STOSY1:    LLI 370                ;Load L with address of TEMP CNTR
           LHI \HB\OLDPG26        ;** Load H with page of TEMP CNTR
           LMI 000                ;Initialize the TEMP CNTR by clearing it
           LLI 120                ;Load L with starting address of SYMBOL BUFFER
           LDI \HB\OLDPG27        ;** Load D with page of VARIABLES LOOK-UP table
           LEI 210                ;Load E with starting addr of VARIABLES LOOK-UP
           LAM                    ;Table. Fetch the (cc) for the SYMBOL BUFFER into
           CPI 001                ;The ACC and see if length of variable name is just one
           JFZ STOSY2             ;Character. If not, skip next couple of instructions.
           LLI 122                ;Else, set pointer to second character location in the
           LMI 000                ;SYMBOL BUFFER and set it to zero
STOSY2:    LLI 121                ;load L with address of first character in the SYMBOL
           LHI \HB\OLDPG26        ;** BUFFER. Load H with page of the buffer.
           CAL SWITCH             ;Exchange pointer to buffer for pointer to VARIABLES
           LAM                    ;LOOK-UP table. Fetch first char in a name from the
           INL                    ;Table. Advance the pointer to second char in a name.
           LBM                    ;Fetch the second character into register B.
           INL                    ;Advance the pointer to first byte of a value in the table.
           CAL SWITCH             ;Exchange table pointer for pointer to SYMBOL BUFF
           CPM                    ;Compare first character in buffer against first character
           JFZ STOSY3             ;In table entry. If no match, try next entry in the table.
           INL                    ;If match, advance pointer to second character in buffer.
           LAB                    ;Move second character obtained from table into ACC.
           CPM                    ;Compare second characters in table and buffer.
           JTZ STOSY5             ;If same, have found the variable name in the table.
STOSY3:    CAL AD4DE              ;Add four to pointer in registers D&E to skip over value
           LLI 370                ;Portion of entry in table. Load L with address of TEMP
           LHI \HB\OLDPG26        ;** CNTR. Load H with page of TEMP CNTR.
           LBM                    ;Fetch the counter
           INB                    ;Increment the counter
           LMB                    ;Restore it to storage
           LLI 077                ;Set L to address of VARIABLES CNTR (indicates
           LHI \HB\OLDPG27        ;** Number of variables currently in table.) Set H too
           LAB                    ;Move the TEMP CNTR value into the ACC. (Number of
           CPM                    ;Entries checked.) Compare with number of entries in
           JFZ STOSY2             ;The table. If have not checked all entries, try next one.
           LLI 077                ;If have checked all entries, load L with address of the
           LHI \HB\OLDPG27        ;** VARIABLES CNTR. Set H too. Fetch the counter
           LBM                    ;Value and incrernent it to account for
           INB                    ;New variable nwne that will now be
           LMB                    ;Added to the table. Save the new value.
           LAB                    ;Place the new counter value into the accumulator
           CPI 025                ;And check to see that adding new variable name to the
           JFS BIGERR             ;Table will not cause table overflow. Big Error if it does!
           LLI 121                ;If room available in table, set L to address of first
           LHI \HB\OLDPG26        ;** Caracter in the SYMBOL BUFFER. Set H too.
           LBI 002                ;Set a counter for number of characters to transfer.
           CAL MOVEIT             ;Move the variable name from buffer to table.
STOSY5:    CAL SWITCH             ;Exchange buffer pointer for table pointer.
           CAL FSTORE             ;Transfer new mathematical value into the table.
           JMP CLESYM             ;Clear the SYMBOL BUFFER and exit to calling routine.

                                  ;The subroutines below are used by some of the routines
                                  ;in this chapter as well as other parts of the program.

SAVESY:    LLI 120                ;Load L with the address of the start of the SYMBOL
           LHI \HB\OLDPG26        ;** BUFFER. Load H with the page of the buffer.
           LDH                    ;Load register D with the page of the AUX SYMBOL
           LEI 144                ;BUFFER and set register E to start of that buffer.
           JMP MOVECP             ;Transfer SYMBOL BF contents to AUX SYMBOL BF

RESTSY:    LLI 144                ;Load L with address of start of AUX SYMBOL BUFF
           LHI \HB\OLDPG26        ;** Load H with page of AUX SYMBOL BUFFER
           LDH                    ;Set D to page of SYMBOL BUFFER (same as H)
           LEI 120                ;Load E with start of SYMBOL BUFFER
MOVECP:    LBM                    ;Load (cc) for source string (first byte in source buffer)
           INB                    ;Add one to (cc) to include (cc) byte itself
           JMP MOVEIT             ;Move the source string to destination buffer

;;; The label Exec SHOULD BE AT 10 266 (This is the start of the code)
EXEC:      LLI 352                ;Load L with address of READY message
           LHI \HB\OLDPG1         ;** Load H with page of READY message
           CAL TEXTC              ;Call subroutine to display the READY message

EXEC1:     LLI 000                ;Load L with starting address of INPUT LINE BUFFER
           LHI \HB\OLDPG26        ;** Load H with page of INPUT LINE BUFFER
           CAL STRIN              ;Call subroutine to input a line into the buffer
           LAM                    ;The STRIN subroutine will exit with pointer set to the
           NDA                    ;CHARACTER COUNT for the line inputted. Fetch the
           JTZ EXEC1              ;Value of the counter, if it is zero then line was blank.
           LLI 335                ;Load L with address of LIST in look up table
           LHI \HB\OLDPG1         ;Load H with address of LIST in look up table
           LDI \HB\OLDPG26        ;Load D with page of line input buffer
           LEI 000                ;Load E with start of line input buffer
           CAL STRCP              ;Call string compare subroutine to see if first word in
           JFZ NOLIST             ;Input buffer is LIST. Jump 3 ahead if not LIST.
           LLI 000                ;If LIST, set up pointers to start of USER PROGRAM
           LHI BGNPGRAM           ;BUFFER. (Note user could alter this starting addr)   *****

                                  ;Next portion of program will LIST the contents of the
                                  ;USER PROGRAM BUFFER until an end of buffer
                                  ;(zero byte) indicator is detected.

LIST:      LAM                    ;Fetch the first byte of a line in the USER PROGRAM
           NDA                    ;BUFFER and see if it is zero. If so, have finished LIST
           JTZ EXEC               ;So go back to start of Executive and display READY.
           CAL TEXTC              ;Else call subroutine to display a line of information
           CAL ADV                ;Now call subroutine to advance buffer pointer to
           CAL CRLF               ;Character count in next line. Also display a CR & LF.
           JMP LIST               ;Continue LISTing process

                                  ;If line inputted by operator did not contain a LIST comman
                                  ;continue program to see if RUN or SCRatch command.

NOLIST:    LLI 342                ;Load L with address of RUN in look up table
           LHI \HB\OLDPG1         ;** Load H with address of RUN in look up table
           LEI 000                ;Load E with start of line input buffer
           LDI \HB\OLDPG26        ;** Load D with page of line input buffer
           LEI 000                ;(Reserve 2 locs in case of patching by duplicating above)
           CAL STRCP              ;Call string compare subroutine to see if first word in
           JTZ RUN                ;Input buffer is RUN. Go to RUN routine if match.
           LDI \HB\OLDPG26        ;** If not RUN command, reset address pointers back
           LEI 000                ;To the start of the line input buffer
           LLI 346                ;Load L with address of SCR in look up table
           LHI \HB\OLDPG1         ;** Load H with page of SCR in look up table
           CAL STRCP              ;Call string compare subroutine to see if first word in
           JFZ NOSCR              ;Input buffer is SCR. If not then jump ahead.
           LHI \HB\OLDPG26        ;** If found SCR command then load memory pointer
           LLI 364                ;With address of a pointer storage location. Set that
           LMI BGNPGRAM           ;tt Storage location to page of start of USER PRO-  *******
           INL                    ;GRAM BUFFER. (Buffer start loc may be altered).
           LMI 000                ;Then adv pntr and do same for low addr portion of pntr
           LLI 077                ;Now set pointer to address of VARIABLES counter
           LHI \HB\OLDPG27        ;** Storage location. Initialize this counter by placing
           LMI 001                ;The count of one into it. Now change the memory pntr
;MGA 3/31/12 put it back to 001; solves nested FOR/NEXT, but limits vars to 19
;   as the letter from James Tucker (1/77) mentioned
;   apparently, James didn't test FOR/NEXT; original Loboyko didn't have this
;;;           LMI 001                ;The count of one into it. Now change the memory pntr
;;; Apparently, in Page 3 of Issue 4 of Scelbal update (1/77) they say the above should change.
;;; This makes the SCR command clear the whole variable space, otherwise one space is lost.  
           LLI 075                ;To storage location for number of dimensioned arrays
           LMI 000                ;@@ And initialize to zero. (@@ = Substitute NOPs if
           LLI 120                ;@@ DIMension capability not used in package.) Also
           LMI 000                ;@@ Initialize l'st byte of array name table to zero.
           LLI 210                ;Set pointer to storage location for the first byte of the
           LMI 000                ;VARIABLES symbol table. Initialize it to zero too.
           INL                    ;Advance the pointer and zero the second location
           LMI 000                ;In the Variables table also.
           LHI BGNPGRAM           ;tt Load H with page of start of USER PROGRAM    **********
           LLI 000                ;BUFFER. (Buffer start location could be altered.)
           LMI 000                ;Clear first location to indicate end of user program.
           LHI \HB\OLDPG57        ;@@ Load H with page of ARRAYS storage
SCRLOP:    LMI 000                ;@@ And form a loop to clear out all the locations
           INL                    ;@@ On the ARRAYS storage page. (@@ These become
           JFZ SCRLOP             ;@@ NOPs if DIMension capability deleted fm package.)
           JMP EXEC               ;SCRatch operations completed, go back to EXEC.

                                  ;If line inputted did not contain RUN or SCRatch com-
                                  ;mand, program continues by testing for SAVE or LOAD
                                  ;commands. If it does not find either of these com-
                                  ;mands, then operator did not input an executive com-
                                  ;mand. Program then sets up to see if the first entry in
                                  ;the line inputted is a LINE NUMBER.

NOSCR:     LEI 272                ;Load E with address of SAVE in look up table
           LDI \HB\OLDPG1         ;Load D with page of look up table
           LHI \HB\OLDPG26        ;Load H with page of input line buffer
           LLI 000                ;Set L to start of input line buffer
           CAL STRCP              ;Call string compare subroutine to see if first word in
           JTZ SAVE               ;tt Input buffer is SAVE. If so, go to user's SAVE rtn
           LLI 277                ;If not SAVE then load L with address of LOAD in look
           LHI \HB\OLDPG1         ;Up table and load H with page of look up table
           LDI \HB\OLDPG26        ;Load D with page of input line buffer
           LEI 000                ;And L to start of input line buffer
           CAL STRCP              ;Call string compare subroutine to see if first word in
           JTZ LOAD               ;tt Input buffer is LOAD. If so, go to user's LOAD rtn
           LLI 360                ;If not LOAD then set pointer to address of storage loc
           LHI \HB\OLDPG26        ;** For USER PROGRAM BUFFER pointer. Initialize this
           LMI BGNPGRAM           ;tt Pointer to the starting address of the program buffer.
           INL                    ;Advance memory pntr. Since pointer storage requires
           LMI 000                ;Two locations, initialize the low addr portion also.
           CAL SYNTAX             ;Call the SYNTAX subroutine to obtain a TOKEN indi-
           LLI 203                ;Cator which will be stored in this location. Upon return
           LHI \HB\OLDPG26        ;** From SYNTAX subroutine set memory pointer to
           LAM                    ;The TOKEN indicator storage location and fetch the
           NDA                    ;Value of the TOKEN. If the value of the syntax TOKEN
           JFS SYNTOK             ;Is positive then have a valid entry.
SYNERR:    LAI 323                ;However, if SYNTAX returns a negative value TOKEN
           LCI 331                ;Then have an error condition. Set up the letters SY in
           JMP ERROR              ;ASCII code and go to display error message to operator.
SYNTOK:    LLI 340                ;Set pointer to start of LINE NUMBER storage area
           LAM                    ;First byte there will contain the length of the line
           NDA                    ;Number character string. Fetch that value (cc).
           JTZ DIRECT             ;DIRECT If line number blank, have a DIRECT statement!
           LLI 360                ;If have a line number must get line in input buffer into
           LMI BGNPGRAM           ;tt User program buffer. Initialize pointer to user buffer.
           INL                    ;This is a two byte pointer so after initializing page addr
           LMI 000                ;Advance pointer and initialize location on page address

                                  ;If the line in the LINE INPUT BUFFER has a line num-
                                  ;ber then the line is to be placed in the USER PRO-
                                  ;GRAM BUFFER. It is now necessary to determine
                                  ;where the new line is to be placed in the USER PRO-
                                  ;GRAM BUFFER. This is dictated by the value of the
                                  ;new line number in relation to the line numbers cur-
                                  ;rently in the program buffer. The next portion of the
                                  ;program goes through the contents of the USER PRO-
                                  ;GRAM BUFFER comparing the values of the line num-
                                  ;bers already stored against the value of the line number
                                  ;currently being held in the LINE INPUT BUFFER.
                                  ;Appropriate action is then taken to Insert or Append,
                                  ;Change, or Delete a line in the program buffer.

GETAUX:    LLI 201                ;Set memory pointer to line character pointer storage
           LHI \HB\OLDPG26        ;** Location and then initialize that storage location
           LMI 001                ;To point to the 1'st character in a line
           LLI 350                ;Set memory pointer to addr of start of auxiliary line
           LMI 000                ;Number storage area and initialize first byte to zero
GETAU0:    LLI 201                ;Set memory pointer to line character pointer storage loc
           CAL GETCHP             ;Fetch a char in line pointed to by line pointer
           JTZ GETAU1             ;If character is a space, skip it by going to advance pntrs
           CPI 260                ;If not a space check to see if character represents a
           JTS GETAU2             ;Valid decimal digit in the range 0 to 9 by testing the
           CPI 272                ;ASCII code value obtained. If not a deciznal digit then
           JFS GETAU2             ;Assume have obtained the line number. Go process.
           LLI 350                ;If valid decimal digit want to append the digit to the
           LHI \HB\OLDPG26        ;** Current string being built up in the auxiliary line
           CAL CONCT1             ;Number storage area so call sub to concat a character.
GETAU1:    LLI 201                ;Reset memory pointer to line character pntr storage loc
           LHI \HB\OLDPG26        ;On the appropriate page.
           LBM
           INB                    ;Fetch the pointer, increment it, and restore new value
           LMB
           LLI 360                ;Set memory pointer to pgm buff line pntr storage loc
           LHI \HB\OLDPG26
           LCM                    ;Bring the high order byte of this double byte pointer
           INL                    ;Into CPU register C. Then advance the memory pntr
           LLM                    ;And bring the low order byte into register L. Now trans-
           LHC                    ;Fer the higher order portion into memory pointer H.
           LAM                    ;Obtain the char cntr (cc) which indicates the length of
           DCB                    ;The line being pointed to by the user program line pntr
           CPB                    ;Compare this with the value of the chars processed so
           JFZ GETAU0             ;Far in current line. If not equal, continue getting line n
GETAU2:    LLI 360                ;Reset mem pntr to pgm buffer line pntr storage
           LHI \HB\OLDPG26        ;** On this page and place the high order byte
           LDM                    ;Of this pointer into CPU register D
           INL                    ;Advance the memory pointer, fetch the second
           LLM                    ;Byte of the pgm buffer line pointer into register L
           LHD                    ;Now make the memory pointer equal to this value
           LAM                    ;Fetch the first byte of a line in the program buffer
           NDA                    ;Test to see if end of contents of pgm buff (zero byte)
           JFZ NOTEND             ;If not zero continue processing. If zero have reached
           JMP NOSAME             ;End of buffer contents so go APPEND line to buffer.
;;; there are some open addresses here.  Above JUMP starts at 11-304;
;;; The below label patch3 should start at 11 307
PATCH3:	   LLI 201		; ptr to A/V storage
	   LHI \HB\OLDPG27      ; MGA 3/31/12 make relocatable; prev: LHI 027
	   LMI 000		; clear A/V flag
	   JMP EXEC

	ORG 011#336		
NOTEND:    LLI 350                ;Load L with addr of auxiliary line number storage loc
           LHI \HB\OLDPG26        ;Load H with addr of aux line number storage loc
           LDI \HB\OLDPG26        ;Load D with addr of line number buffer location
           LEI 340                ;Load E with address of line number buffer location
           CAL STRCP              ;Compare line nr in input buffer with line number in
           JTS CONTIN             ;User program buffer. If lesser in value keep looking.
           JFZ NOSAME             ;If greater in value then go to Insert line in pgm buffer
           LLI 360                ;If same values then must remove the line with the same
           LHI \HB\OLDPG26        ;** Line number from the user program buffer. Set up
           LCM                    ;The CPU memory pointer to point to the current
           INL                    ;Position in the user program buffer by retrieving that
           LLM                    ;Pointer from its storage location. Then obtain the first
           LHC                    ;Byte of data pointed to which will be the character
           LBM                    ;Count for that line (cc). Add one to the cc value to take
           INB                    ;Account of the (cc) byte itself and then remove that
           CAL REMOVE             ;Many bytes to effectively delete the line fm the user
           LLI 203                ;Program buffer. Now see if line in input buffer consists
           LHI \HB\OLDPG26        ;** Only of a line number by checking SYNTAX
           LAM                    ;TOKEN value. Fetch the TOKEN value from its
           NDA                    ;Storage location. If it is zero then input buffer only
           JTZ EXEC               ;Contains a line number. Action is a pure Delete.
NOSAME:    LLI 360                ;Reset memory pointer to program buffer
           LHI \HB\OLDPG26        ;Line pointer storage location
           LDM                    ;Load high order byte into CPU register D
           INL                    ;Advance memory pointer
           LEM                    ;Load low order byte into CPU register E
           LLI 000                ;Load L with address of start of line input buffer
           LHI \HB\OLDPG26        ;** Do same for CPU register H
           LBM                    ;Get length of line input buffer
           INB                    ;Advance length by one to include (cc) byte
           CAL INSERT             ;Go make room to insert line into user program buffer
           LLI 360                ;Reset memory pointer to program buffer
           LHI \HB\OLDPG26        ;** Line pointer storage location
           LDM                    ;Load higher byte into CPU register D
           INL                    ;Advance memory pointer
           LEM                    ;Load low order byte into CPU register E
           LLI 000                ;Load L with address of start of line input buffer
           LHI \HB\OLDPG26        ;** Do same for CPU register H
           CAL MOVEC              ;Call subroutine to Insert line in input buffer into the
           JMP EXEC1              ;User program buffer then go back to start of EXEC.
MOVEC:     LBM                    ;Fetch length of string in line input buffer
           INB                    ;Increment that value to provide for (cc)
MOVEPG:    LAM                    ;Fetch character from line input buffer
           CAL ADV                ;Advance pointer for line input buffer
           CAL SWITCH             ;Switch memory pointer to point to user pgm buffer
           LMA                    ;Deposit character fm input buff into user pgm buff
           CAL ADV                ;Advance pointer for user program buffer
           CAL SWITCH             ;Switch memory pntr back to point to input buffer
           DCB                    ;Decrement character counter stored in CPU register B
           JFZ MOVEPG             ;If counter does not go to zero continue transfer ops
           RET                    ;When counter equals zero return to calling routine
CONTIN:    LLI 360                ;Reset memory pointer to program buffer
           LHI \HB\OLDPG26        ;** Line pointer storage location
           LDM                    ;Load high order byte into CPU register D
           INL                    ;Advance memory pointer
           LEM                    ;Load low order byte into CPU register E
           LHD                    ;Now set CPU register H to high part of address
           LLE                    ;And set CPU register L to low part of address
           LBM                    ;Fetch the character counter (cc) byte fm line in
           INB                    ;Program buffer and add one to compensate for (cc)
           CAL ADBDE              ;Add length of line value to old value to get new pointer
           LLI 360                ;Reset memory pointer to program buffer
           LHI \HB\OLDPG26        ;** Line pointer storage location
           LMD                    ;Restore new high portion
           INL                    ;Advance memory pointer
           LME                    ;And restore new low portion
           JMP GETAUX             ;Continue til find point at which to enter new line
GETCHP:    LHI \HB\OLDPG26        ;** Load H with pointer page (low portion set upon
           LBM                    ;Entry). Now fetch pointer into CPU register B.
           LLI 360                ;Reset pntr to pgm buffer line pointer storage location
           LDM                    ;Load high order byte into CPU register D
           INL                    ;Advance memory pointer
           LEM                    ;Load low order byte into CPU register E
           CAL ADBDE              ;Add pointer to pgm buffer pointer to obtain address of
           LHD                    ;Desired character. Place high part of new addr in H.
           LLE                    ;And low part of new address in E.
           LAM                    ;Fetch character from position in line in user pgm buffer
           CPI 240                ;See if it is the ASCII code for space
           RET                    ;Return to caller with flags set to indicate result
REMOVE:    CAL INDEXB             ;Add (cc) plus one to addr of start of line
           LCM                    ;Obtain byte from indexed location and
           CAL SUBHL              ;Subtract character count to obtain old location
           LMC                    ;Put new byte in old location
           LAC                    ;As well as in the Accumulator
           NDA                    ;Test to see if zero byte to indicate end of user pgm buff
           JTZ REMOV1             ;If it is end of user pgm buffer, go complete process
           CAL ADV                ;Otherwise add one to the present pointer value
           JMP REMOVE             ;And continue removing chamcters from the user pgm bf
REMOV1:    LLI 364                ;Load L with end of user pgm buffer pointer storage loc
           LHI \HB\OLDPG26        ;** Load H with page of that pointer storage location
           LDM                    ;Get page portion of end of pgm buffer address
           INL                    ;Advance memory pointer
           LAM                    ;And get low portion of end of pgm buffer address into
           SUB                    ;Accumulator then subtract displacement value in B
           LMA                    ;Restore new low portion of end of pgm buffer address
           RFC                    ;If subtract did not cause carry can return now
           DCL                    ;Otherwise decrement memory pointer back to page
           DCD                    ;Storage location, decrement page value to give new page
           LMD                    ;And store new page value back in buffer pntr storage loc
           RET                    ;Then return to calling routine
INSERT:    LLI 364                ;Load L with end of user pgm buffer pointer storage loc
           LHI \HB\OLDPG26        ;** Load H with page of that pointer storage location
           LAM                    ; Get page portion of end of program buffer address
           INL                    ;Advance memory pointer
           LLM                    ;Load low portion of end of program buffer address
           LHA                    ;Into L and finish setting up memory pointer
           CAL INDEXB             ;Add (cc) of line in input buffer to form new end of
           LAH                    ;Program buffer address. Fetch new end of buffer page
           CPI ENDPGRAM           ;tt Address and see if this value would exceed user's
           JFS BIGERR             ;System capabilit'y. Go display error message if so!
           CAL SUBHL              ;Else restore original value of end of buffer address
INSER1:    LCM                    ;Bring byte pointed to by H & L into CPU register C
           CAL INDEXB             ;Add displacement value to current memory pointer
           LMC                    ;Store the byte in the new location
           CAL SUBHL              ;Now subtract displacement value from H & L
           CAL CPHLDE             ;Compare this with the address stored in D & E
           JTZ INSER3             ;If same then go finish up Insert operation
           CAL DEC                ;Else set pointer to the byte before the byte just
           JMP INSER1             ;Processed and continue the Insert operation
INSER3:
INCLIN:    LLI 000                ;Load L with start of line input buffer
           LHI \HB\OLDPG26        ;** Load H with page of start of line input buffer
           LBM                    ;Fetch length of the line in line input buffer
           INB                    ;Increment value by one to include (cc) byte
           LLI 364                ;Set memory pointer to end of user pgrn buffer pointer
           LDM                    ;Storage location on same page and fetch page address
           INL                    ;Of this pointer into D. Then advance memory pointer
           LEM                    ;And get low part of this pointer into CPU register E.
           CAL ADBDE              ;Now add displacement (cc) of line in input buffer to
           LME                    ;The end of program buffer pointer. Replace the updated
           DCL                    ;Low portion of the new pointer value back in stomge
           LMD                    ;And restore the new page value back into storage
           RET                    ;Then return to calling routine
CPHLDE:    LAH                    ;Subroutine to compare if the contents of CPU registers
           CPD                    ;H & L are equal to registers D & E. First compare
           RFZ                    ;Register H to D. Return with flags set if not equal. If
           LAL                    ;Equal continue by comparing register L to E.
           CPE                    ;IF L equals E then H & L equal to D & E so return to
           RET                    ;Calling routines with flags set to equality status
ADBDE:     LAE                    ;Subroutine to add the contents of CPU register B (single
           ADB                    ;Byte value) to the double byte value in registers D & E.
           LEA                    ;First add B to E to form new least significant byte
           RFC                    ;Restore new value to E and exit if no carry resulted
           IND                    ;If had a carry then must increment most significant byte
           RET                    ;In register D before returning to calling routine
CTRLC:     LAI 336                ;Set up ASCII code for t (up arrow) in Accumulator.
           LCI 303                ;Set up ASCII code for letter 'C' in CPU register C.
           JMP ERROR              ;Go display the 'Control C' condition message.
FINERR:    LLI 340                ;Load L with starting address of line number storage area
           LHI \HB\OLDPG26        ;** Load H with page of line number storage area
           LAM                    ;Get (cc) for line number string. If length is zero meaning
           NDA                    ;There is no line number stored in the buffer then jump
           JTZ FINER1             ;Ahead to avoid displaying "AT LINE" message
           LLI 366                ;Else load L with address of start of "AT LINE" message
           LHI \HB\OLDPG1         ;** Stored on this page
           CAL TEXTC              ;Call subroutine to display the "AT LINE" message
           LLI 340                ;Now reset L to starting address of line number storage
           LHI \HB\OLDPG26        ;** Area and do same for CPU register H
           CAL TEXTC              ;Call subroutine to display the line number
FINER1:    CAL CRLF               ;Call subroutine to provide a carriage-return and line-feed
	   JMP PATCH3 
;;; The following is the old code, before patch 3
;;;           JMP EXEC               ;To the display device then return to EXECUTIVE.
DVERR:     LAI 304                ;Set up ASCII code for letter 'D' in Accumulator
           LCI 332                ;Set up ASCII code for letter 'Z' in CPU register C
           JMP ERROR              ;Go display the 'DZ' (divide by zero) error message
FIXERR:    LAI 306                ;Set up ASCII code for letter 'F' in Accumulator
           LCI 330                ;Set up ASCII code for letter 'X' in CPU register C
           JMP ERROR              ;Go display the 'FX' (FiX) error message
NUMERR:    LAI 311                ;Set up ASCII code for letter 'I' in Accumulator
           LCI 316                ;Set up ASCII code for letter 'N' in CPU register C
           LLI 220                ;Load L with address of pointer used by DINPUT
           LHI \HB\OLDPG1         ;** Routine. Do same for register H.
           LMI 000                ;Clear the location
           JMP ERROR              ;Go display the'IN'(Illegal Number) error message

                                  ;The following subroutine, used by various sections of
                                  ;SCELBAL, will search the LINE INPUT BUGGER for
                                  ;a character string which is contained in a buffer starting
                                  ;at the address pointed to by CPU registers H & L when
                                  ;the subroutine is entered.

INSTR:     LDI \HB\OLDPG26        ;**Set D to starting page of LINE INPUT BUFFER
           LEI 000                ;Load E with starting location of LINE INPUT BUFFER
INSTR1:    CAL ADVDE              ;Advancer D & E pointer to the next location (input
           CAL SAVEHL             ;Buffer). Now save contents of d, E, H & L vefore the
           LBM                    ;Compare operations. Get length of TEST buffer in B.
           CAL ADV                ;Advance H & L buffer to first char in TEST buffer.
           CAL STRCPC             ;Compare contents of TEST buffer against input buffer
           JTZ RESTHL             ;For length B. If match, restore pntrs and exit to caller.
           CAL RESTHL             ;If no match, restore pointers for loop test.
           LLI 000                ;Load L with start of input buffer (to get the char cntr).
           LHI \HB\OLDPG26        ;**Load H with page of input buffer.
           LAM                    ;Get length of buffer (cc) into the accumulator.
           CPE                    ;Compare with current input buffer pointer value.
           JTZ INSTR2             ;If at end of buffer, jump ahead.
           CAL RESTHL             ;Else restore test string address (H&L) and input buffer
           JMP INSTR1             ;Address (D&E). Look gor occurrence of test string in ln.
           HLT                    ;Safety halt. If program reaches here have system failure.
INSTR2:    LEI 000                ;If reach end of input buffer without finding a match
           RET                    ;Load E with 000 as an indicator and return to caller.
ADVDE:     INE                    ;Subroutine to advance the pointer in the register
           RFZ                    ;Pair D & E. Advance contents of E. Return if not zero.
           IND                    ;If register E goes to 0 when advanced, then advance
           RET                    ;Register D too. Exit to calling routine.

;;; The label RUN should start at 13-170
RUN:       LLI 073                ;Load L with addr of GOSUB/RETURN stack pointer
           LHI \HB\OLDPG27        ;** Load H with page of same pointer
           LMI 000                ;Initialize the GOSUB/RETURN stack pointer to zero
           LLI 205                ;Load L with addr of FOR/NEXT stack pointer
           LMI 000                ;Initialize the FOR/NEXT stack pointer to zero
           LLI 360                ;Load L with addr of user pgm buffer line pointer
           LHI \HB\OLDPG26        ;** Load H with page of user pgm buffer line pointer
           LMI BGNPGRAM           ;tt Initialize pointer (may be altered by user)   *******
           INL                    ;Advance memory pointer to low portion of user pgm
           LMI 000                ;Buffer pointer and initialize to start of buffer
           JMP SAMLIN             ;Start executing user program with first line in buffer
NXTLIN:    LLI 360                ;Load L with addr of user program buffer line pointer
           LHI \HB\OLDPG26        ;** Load H with page of user pgm buffer line pointer
           LDM                    ;Place page addr of pgm buffer line pointer in D
           INL                    ;Advance the memory pointer
           LEM                    ;Place low addr of pgm buffer line pointer in E
           LHD                    ;Also put page addr of pgm buffer line pointer in H
           LLE                    ;And low addr of pgm buffer line pointer in L
           LBM                    ;Now fetch the (cc) of current line into register B
           INB                    ;Add one to account for (cc) byte itself
           CAL ADBDE              ;Add value in B to D&E to point to next line in
           LLI 360                ;User program buffer. Reset L to addr of user logrn
           LHI \HB\OLDPG26        ;** Buffer pointer storage location. Store the new
           LMD                    ;Updated user pgm line pointer in pointer storage
           INL                    ;Location. Store both the high portion
           LME                    ;And low portion. (Now points to next line to be
           LLI 340                ;Processed from user program buffer.) Change pointer
           LHI \HB\OLDPG26        ;** To address of line number buffer. Fetch the last
           LAM                    ;Line number (length) processed. Test to see if it was
           NDA                    ;Blank. If it was blank
           JTZ EXEC               ;Then stop processing and return to the Executive
           LAA                    ;Insert two effective NOPs here
           LAA                    ;In case of patching
SAMLIN:    LLI 360                ;Load L with addr of user program buffer line pointer
           LHI \HB\OLDPG26        ;** Load H with page of same pointer
           LCM                    ;Fetch the high portion of the pointer into register C
           INL                    ;Advance the memory pointer
           LLM                    ;Fetch the low portion of the pointer into register L
           LHC                    ;Now move the high portion into register H
           LDI \HB\OLDPG26        ;** Set D to page of line input buffer
           LEI 000                ;Set E to address of start of line input buffer
           CAL MOVEC              ;Move the line ftom the user program buffer into the
           LLI 000                ;Line input buffer. Now reset the pointer to the start
           LHI \HB\OLDPG26        ;** Of the line input buffer.
           LAM                    ;Fetch the first byte of the line input buffer (cc)
           NDA                    ;Test (cc) value to see if fetched a blank line
           JTZ EXEC               ;If fetched a blank line, return to the Executive
           CAL SYNTAX             ;Else call subrtn to strip off line nr & set statement toke

DIRECT:    LLI 203                ;Load L with address of syntax TOKEN storage location
           LHI \HB\OLDPG26        ;** Load H with page of syntax TOKEN location
           LAM                    ;Fetch the TOKEN value into the accumulator
           CPI 001                ;Is it token value for REM statement? If so, ignore the
           JTZ NXTLIN             ;Current line and go on to the next line in pgm buffer.
           CPI 002                ;Is it token value for IF statement?
           JTZ IF                 ;If yes, then go to the IF statement routine.
           CPI 003                ;Is it token value for LET statement? (Using keyword)
           JTZ LET                ;If yes, then go to the LET statement routine.
           CPI 004                ;Is it token value for GOTO statement?
           JTZ GOTO               ;If yes, then go to the GOTO statement routine.
           CPI 005                ;Is it token value for PRINT statement?
           JTZ PRINT              ;If yes, then go to the PRINT statement routine.
           CPI 006                ;Is it token value for INPUT statement?
           JTZ INPUT              ;If yes, then go to the INPUT statement routine.
           CPI 007                ;Is it token value for FOR statement?
           JTZ FOR                ;If yes, then go to the FOR statement routine.
           CPI 010                ;Is it token value for NEXT statement?
           JTZ NEXT               ;If yes, then go to the NEXT statement routine.
           CPI 011                ;Is it token value for GOSUB statement?
           JTZ GOSUB              ;If yes, then go to the GOSUB statement routine.
           CPI 012                ;Is it token value for RETURN statement?
           JTZ RETURN             ;If yes, then go to the RETURN statement routine.
           CPI 013                ;Is it token value for DIM statement?
           JTZ DIM                ;If yes, then go to the DIM statement routine.
           CPI 014                ;Is it token value for END statement?
           JTZ EXEC               ;If yes, then go back to the Executive, user pgm finished!
           CPI 015                ;Is it token value for IMPLIED LET statement?
           JTZ LET0               ;If yes, then go to special LET entry point.
           CPI 016                ;@@ Is it token value for ARRAY IMPLIED LET?
           JFZ SYNERR             ;If not, then assume a syntax error condition.
           CAL ARRAY1             ;@@ Else, perform array storage set up subroutine.
           LLI 206                ;@@ Set L to array pointer storage location.
           LHI \HB\OLDPG26        ;@@ * * Set H to array pointer storage location.
           LBM                    ;@@ Fetch array pointer to register B.
           LLI 202                ;@@ Change memory pointer to syntax pntr storage loc.
           LMB                    ;@@ Save array pointer value there.
           CAL SAVESY             ;@@ Save array name in auxiliary symbol buffer
           JMP LET1
PRINT:     LLI 202                ;Load L with address of SCAN pointer storage location
           LHI \HB\OLDPG26        ;** Load H with page of SCAN pointer
           LAM                    ;Fetch the pointer value (last character scanned by the
           LLI 000                ;SYNTAX routine). Change pointer to line buffer (cc).
           CPM                    ;Compare pointer value to buffer length. If not equal
           JTS PRINT1             ;Then line contains more than stand alone PRINT state-
           CAL CRLF               ;Ment. However, if just have PRINT statement then issue
           JMP NXTLIN             ;A carriage-return & line-feed combination, then exit.
PRINT1:    CAL CLESYM             ;Initialize the SYMBOL buffer for new entry.
           LLI 202                ;Load L with address of SCAN buffer pointer
           LHI \HB\OLDPG26        ;** Load H with page of SCAN pointer
           LBM                    ;Pointer points to last char scanned by SYNTAX. Need
           INB                    ;To increment it to point to next char in statement line.
           LLI 203                ;Load L with address of former TOKEN value. Use it as
           LMB                    ;Storage location for a PRINT statement pointer.
PRINT2:    LLI 203                ;Set memory pointer to PRINT pointer storage location
           CAL GETCHR             ;Fetch character in input buffer pointed to by PRINT
           CPI 247                ;Pointer. See if it is ASCII code for single quote mark.
           JTZ QUOTE              ;If so, go to QUOTE section to process text string.
           CPI 242                ;If not, see if it is ASCII code for double quote mark.
           JTZ QUOTE              ;If so, go to QUOTE section to process text string.
           CPI 254                ;If not, see if it is ASCII code for comma sign.
           JTZ PRINT3             ;If so, go evaluate expression.
           CPI 273                ;If not, see if it is ASCII code for semi-colon sign.
           JTZ PRINT3             ;If so, go evaluate expression.
           LLI 203                ;Load L with address of PRINT pointer storage location.
           CAL LOOP               ;Increment pointer and test for end of line.
           JFZ PRINT2             ;If not end of line, fetch the next character.
PRINT3:    LLI 202                ;Load L with address of SCAN pointer storage location
           LBM                    ;Fetch value of the pointer (last letter of KEYWORD)
           INB                    ;Add one to point to first character of expression
           LLI 276                ;Load L with addr of EVAL pointer storage location
           LMB                    ;Store addr at which EVAL should start scanning
           LLI 203                ;Load L with address of PRINT pointer
           LBM                    ;Which points to field terminator
           DCB                    ;Decrement pointer value to last character of expression
           LLI 277                ;Load L with address of EVAL FINISH pntr storage loc.
           LMB                    ;Place address value of last char in PRINT field there
           LLI 367                ;Load L with address of QUOTE flag
           LAM                    ;Fetch the value of the QUOTE flag into the ACC
           NDA                    ;Test the QUOTE flag status
           JTZ PRINT4             ;If field not quoted, proceed to evaluate expression
           LMI 000                ;If field quoted, then clear the QUOTE flag for next field
           JMP PRINT6             ;And skip the evaluation procedure
PRINT4:    CAL EVAL               ;Evaluate the current PRINT field
           LLI 177                ;Then load L,with address of the TAB flag
           LHI \HB\OLDPG26        ;** Load H with the page of the TAB flag
           LAM                    ;Fetch the value of the TAB flag into the accumulator
           NDA                    ;Test the TAB flag
           LLI 110                ;Change L to the FIXED/FLOAT flag location
           LHI \HB\OLDPG1         ;** Change H to the FIXED/FLOAT flag page
           LMI 377                ;Set FIXED/FLOAT flag to fixed point
PRINT5:    CTZ PFPOUT             ;If TAB flag not set, display value of expression
           LLI 177                ;Load L with address of TAB flag
           LHI \HB\OLDPG26        ;** Load H with page of TAB flag
           LMI 000                ;Reset TAB flag for next PRINT field
PRINT6:    LLI 203                ;Load L with address of PRINT pointer stomge location
           CAL GETCHR             ;Fetch the character pointed to by the PRINT pointer
           CPI 254                ;See if the last character scanned was a comma sign
           CTZ PCOMMA             ;If so, then display spaces to next TA.B location
           LLI 203                ;Reset L to address of PRINT pointer storage location
           LHI \HB\OLDPG26        ;** Reset H to page of PRINT pointer stomge location
           LBM                    ;Fetch the value of the pointer into register B
           LLI 202                ;Change L to SCAN pointer storage location
           LMB                    ;Place end of last field processed into SCAN pointer
           LLI 000                ;Change pointer to start of line input buffer
           LAB                    ;Place pntr to last char scanned into the accumulator
           CPM                    ;Compare this value to the (cc) for the line buffer
           JTS PRINT1             ;If not end of line, continue to process next field
           LLI 000                ;If end of line, fetch the last character in the line
           CAL GETCHR             ;And check to see if it
           CPI 254                ;Was a comma. If it was, go on to the next line in the
           JTZ NXTLIN             ;User program buffer without displaying a CR & LF.
           CPI 273                ;If not a comma, check to see if it was a semi-colon.
           JTZ NXTLIN             ;If so, do not provide a CR & LF combination.
           CAL CRLF               ;If not comma or semi-colon, provide CR & LF at end
           JMP NXTLIN             ;Of a PRINT statement. Go process next line of pgrm.
QUOTE:     LLI 367                ;Load L with address of QUOTE flag
           LMA                    ;Store type of quote in flag storage location
           CAL CLESYM             ;Initialize the SYMBOL buffer for new entry
           LLI 203                ;Load L with address of PRINT pointer
           LBM                    ;Fetch the PRINT pointer into register B
           INB                    ;Add one to advance over quote character
           LLI 204                ;Load L with address of QUOTE pointer
           LMB                    ;Store the beginning of the QUOTE field pointer
QUOTE1:    LLI 204                ;Load L with address of QUOTE pointer
           CAL GETCHR             ;Fetch the next character in the TEXT field
           LLI 367                ;Load L with the QUOTE flag (type of quote)
           CPM                    ;Compare to see if latest character this quote mark
           JTZ QUOTE2             ;If so, finish up this quote field
           CAL ECHO               ;If not, display the character as part of TEXT
           LLI 204                ;Reset L to QUOTE pointer storage location
           CAL LOOP               ;Increment QUOTE pointer and test for end of line
           JFZ QUOTE1             ;If not end of line, continue processing TEXT field
QUOTER:    LAI 311                ;If end of line before closing quote mark have an error
           LCI 321                ;So load ACC with I and register C with Q
           LLI 367                ;Load L with the address of the QUOTE flag
           LHI \HB\OLDPG26        ;** Load H with the page of the QUOTE flag
           LMI 000                ;Clear the QUOTE flag for future use
           JMP ERROR              ;Go display the IQ (Illegal Quote) error message
QUOTE2:    LLI 204                ;Load L with address of QUOTE pointer
           LBM                    ;Fetch the QUOTE pointer into register B
           LLI 202                ;Load L with address of SCAN pointer storage location
           LMB                    ;Store former QUOTE vointer as start of next field
           LAB                    ;Place QUOTE pointer into the accumulator
           LLI 000                ;Change L to point to start of the input line buffer
           CPM                    ;Compare QUOTE pointer value with (cc) value
           JFZ PRINT1             ;If not end of line, process next PRINT field
           CAL CRLF               ;Else display a CR & LF combination at the end of line
           LLI 367                ;Load L with the address of the TAB flag
           LHI \HB\OLDPG26        ;** Load H with the page of the TAB flag
           LMI 000                ;Clear the TAB flag for future use
           JMP NXTLIN             ;Go process next line of the program.

                                  ;The following subroutines are utilized by the PRINT
                                  ;routine.
;;; The label PFPOUT SHOULD BE AT 14 314
PFPOUT:    LLI 126                ;Load L with the address of the FPACC MSW (Floating
           LHI \HB\OLDPG1         ;** Point ACC). Load H with page of the FPACC MSW.
           LAM                    ;Fetch the FPACC MSW into the accumulator. Test to
           NDA                    ;See if the FPACC MSW is zero. If so, then simply go and
           JTZ ZERO               ;Display the value "0"
           INL                    ;Else advance the pointer to the FPACC Exponent
           LAM                    ;Fetch the FPACC Exponent into the accumulator
           NDA                    ;See if any exponent value. If not, mantissa is in range
           JTZ FRAC               ;0.5 to 1.0. Treat number as a fraction.
           JMP FPOUT              ;Else perform regular numerical output routine.
ZERO:      LAI 240                ;Load ASCII code for space into the ACC
           CAL ECHO               ;Display the space
           LAI 260                ;Load ASCII code for 0 into the ACC
           JMP ECHO               ;Display 0 and exit to calling routine
FRAC:      LLI 110                ;Load L with address of FIXED/FLOAT flag
           LMI 000                ;Reset it to indicate floating point mode
           JMP FPOUT              ;Display floating point number and return to caller
PCOMMA:    LLI 000                ;Load L with address of (cc) in line input buffer
           LAM                    ;Fetch the (cc) for the line into the ACC
           LLI 203                ;Change pointer to PRINT pointer storage location
           SUM                    ;Subtract value of PRINT pointer from line (cc)
           RTS                    ;If at end of buffer, do not TAB
           LLI 043                ;If not end, load L with address of COLUMN COUNTER
           LHI \HB\OLDPG1         ;** Set H to page of COLUMN COUNTER
           LAM                    ;Fetch COLUMN COUNTER into the accumulator
           NDI 360                ;Find the last TAB position (multiple of 16 decimal)
           ADI 020                ;Add 16 (decimal) to get new TAB position
           SUM                    ;Subtract current position from next TAB position
           LCA                    ;Store this value in register C as a counter
           LAI 240                ;Load the ACC with the ASCII code for space
PCOM1:     CAL ECHO               ;Display the space
           DCC                    ;Decrement the loop counter
           JFZ PCOM1              ;Continue displaying spaces until loop counter is zero
           RET                    ;Then return to calling routine
LET0:      CAL SAVESY             ;Entry point for IMPLIED LET statement. Save the
           LLI 202                ;Variable (to left of the equal sign). Set L to the SCAN
           LHI \HB\OLDPG26        ;** Pointer. Set H to the page of the SCAN pointer.
           LBM                    ;Fetch value of SCAN pointer. (Points to = sign in In bf)
           LLI 203                ;Change pointer to LET pointer (was TOKEN value)
           LMB                    ;Place the SCAN pointer value into the LET pointer
           JMP LET5               ;Continue processing the LET statement line
LET:       CAL CLESYM             ;Initialize the SYMBOL BUFFER for new entry
           LLI 144                ;Load L with address of start of AUX SYMBOL BUFF
           LHI \HB\OLDPG26        ;** Load H with page of AUX SYMBOL BUFFER
           LMI 000                ;Initialize AUX SYMBOL BUFFER
LET1:      LLI 202                ;Entry point for ARRAY IMPLIED LET statement.
           LHI \HB\OLDPG26        ;** Set pointer to SCAN pointer storage location
           LBM                    ;Fetch the SCAN pointer value (last letter scanned by
           INB                    ;SYNTAX subroutine) and add one to next character
           LLI 203                ;Change L to LET pointer storage location
           LMB                    ;Store former SCAN value (updated) in LET pointer
LET2:      LLI 203                ;Set L to gtorage location of LET pointer
           CAL GETCHR             ;Fetch the character pointed to by the LET pointer
           JTZ LET4               ;If character is a space, ignore it
           CPI 275                ;See if character is the equal (=) sign
           JTZ LET5               ;If so, go process other side of the statement (after
           CPI 250                ;@@ If not, see if character is a right parenthesis
           JFZ LET3               ;If not, continue looking for equal sign
           CAL ARRAY              ;@@ If so, have subscript. Call array set up subroutine.
           LLI 206                ;@@ Load L with address of ARRAY pointer
           LHI \HB\OLDPG26        ;@@ ** Load H with page of ARRAY pointer
           LBM                    ;@@ Fetch value (points to ")" character of subscript)
           LLI 203                ;@@ Load L with address of LET pointer
           LMB                    ;@@ Place ARRAY pointer value as new LET pointer
           JMP LET4               ;@@ Continue to look for = sign in statement line
LET3:      LLI 144                ;Reset L to start of AUX SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Load H with page of AUX SYMBOL BUFFER
           CAL CONCT1             ;Concatenate character to the AUX SYMBOL BUFFER
LET4:      LLI 203                ;Load L with address of LET pointer storage location
           CAL LOOP               ;Add one to pointer and test for end of line input buffer
           JFZ LET2               ;If not end of line, continue looking for the equal sign
LETERR:    LAI 314                ;If do not find an equal sign in the LET statement line
           LCI 305                ;Then have a LE (Let Error). Load the code for L and E
           JMP ERROR              ;Into registers ACC and C and go display the error msg.
LET5:      LLI 203                ;When find the equal sign, reset L to point to the LET
           LHI \HB\OLDPG26        ;** Pointer and H to the proper page. Fetch the pointer
           LBM                    ;Value into register B and add one to advance pointer
           INB                    ;Over the equal sign to first char in the expression.
           LLI 276                ;Set L to point to the address of the EVAL pointer
           LMB                    ;Set EVAL pointer to start evaluating right after the
           LLI 000                ;Equal sign. Now change L to start of line input buffer.
           LBM                    ;Fetch the (cc) value into register B. (Length of line.)
           LLI 277                ;Load L with EVAL FINISH pointer storage location.
           LMB                    ;Set it to stop evaluating at end of the line.
           CAL EVAL               ;Call the subroutine to evaluate the expression.
           CAL RESTSY             ;Restore the name of the variable to receive new value.
           CAL STOSYM             ;Store the new value for the variable in variables table.
           JMP NXTLIN             ;Go process next line of the program.
GOTO:      LLI 350                ;Load L with start of AUX LINE NR BUFFER
           LHI \HB\OLDPG26        ;** Load H with page of AUX LINE NR BUFFER
           LMI 000                ;Initialize the AUX LINE NR BUFFER to zero
           LLI 202                ;Load L with address of SCAN pointer storage location
           LBM                    ;Fetch pointer value (last char scanned by SYNTAX)
           INB                    ;Add one to skip over the last 0 in GOTO keyword
           LLI 203                ;Change pointer to GOTO pointer (formerly TOKEN)
           LMB                    ;Store the updated SCAN pointer as the GOTO pointer
GOTO1:     LLI 203                ;Load L with address of GOTO pointer
           CAL GETCHR             ;Fetch the character pointed to by the GOTO pointer
           JTZ GOTO2              ;If character was a space, ignore it
           CPI 260                ;See if character is in the range of a decimal digit
           JTS GOTO3              ;If not, must have end of the line number digit string
           CPI 272                ;Continue to test for decitnal digit
           JFS GOTO3              ;If not, mugt have end of the line number digit string
           LLI 350                ;If valid decimal digit, load L with addr of AUX LINE
           CAL CONCT1             ;NR BUFFER and concatenate digit to the buffer.
GOTO2:     LLI 203                ;Reset pointer to GOTO pointer storage location
           CAL LOOP               ;Advance the pointer value and test for end of line
           JFZ GOTO1              ;If not end of line, fetch next digit in GOTO line number
GOTO3:	   LLI 360                ;Set L to user program buffer pointer storage location
           LHI \HB\OLDPG26        ;** Set H to page of program buffer pointer
           LMI BGNPGRAM           ;Initialize high part of pointer to start of pgm buffer
           INL                    ;Advance the memory point
           LMI 000                ;Initialize the low part of pointer to start of pgm buffer
GOTO4:     CAL CLESYM             ;Clear the SYMBOL BUFFER
           LLI 204                ;Load L with address of GOTO SEARCH pointer
           LMI 001                ;Initialize to one for first char of line
GOTO5:     LLI 204                ;Load L with address of GOTO SEARCH pointer
           CAL GETCHP             ;Fetch character pointed to by GOTO SEARCH pointer
           JTZ GOTO6              ;From line pointed to in user program buffer. Ignore
           CPI 260                ;Spaces. Check to see if character is a decirnal digit.
           JTS GOTO7              ;If not, then have processed line number at the start of
           CPI 272                ;The current line. Continue the check for a valid decimal
           JFS GOTO7              ;Digit. If have a decirnal digit then concatenate the digit
           CAL CONCTS             ;Onto the current string in the SYMBOL BUFFER,
GOTO6:     LLI 204                ;Change L to the address of the GOTO SEARCH pointer
           LHI \HB\OLDPG26        ;** And H to the proper page of the pointer
           LBM                    ;Fetch the GOTO SEARCH pointer value
           INB                    ;Increment the GOTO SEARCH pointer
           LMB                    ;And restore it back to memory
           LLI 360                ;Change L to address of user program buffer pointer
           LCM                    ;Save the high part of this pointer value in register C
           INL                    ;Advance L to the low part of the pgrn buffer pointer
           LLM                    ;Now load it into L
           LHC                    ;And transfer C into H to point to start of the line
           LAM                    ;Fetch the (cc) of the current line being pointed to in the
           DCB                    ;User pgm buff. Decrernent B to previous value. Compare
           CPB                    ;GOTO SEARCH pointer value to length of current line.
           JFZ GOTO5              ;If not end of line then continue getting current line nr.
GOTO7:     LLI 120                ;Load L with address of start of the SYMBOL BUFFER
           LHI \HB\OLDPG26        ;Set H to the page of the SYMBOL BUFFER
           LDI \HB\OLDPG26        ;Set D to the page of the AUX LINE NR BUFFER
           LEI 350                ;Set E to the start of the AUX LINE NR BUFFER
           CAL STRCP              ;Compare GOTO line number against current line nr.
           JTZ SAMLIN             ;If they match, found GOTO line. Pick up ops there!
           LLI 360                ;Else, set L to user program buffer pntr storage location
           LHI \HB\OLDPG26        ;** Set H to page of user program buffer pointer
           LDM                    ;Fetch the high part of this pointer into register D
           INL                    ;Advance the memory pointer
           LEM                    ;Fetch the low part into register E
           LHD                    ;Transfer the pointer to H
           LLE                    ;And L. Fetch the (cc) of the current line into register
           LBM                    ;B and then add one to account for the (cc) byte to get
           INB                    ;Total length of the current line in the user pgm buffer
           CAL ADBDE              ;Add the total length to the pointer value in D & E
           LLI 360                ;To get the starting address of the next line in the user
           LHI \HB\OLDPG26        ;** User program buffer. Place the new value for the user
           LMD                    ;Program buffer pointer back into the user program
           INL                    ;Buffer pointer storage locations so that it points to the
           LME                    ;Next line to be processed in the user program buffer.
           LLI 364                ;Load L with address of end of user pgm buffer storage
           LAD                    ;Location (page address) and fetch end of buffer page.
           CPM                    ;Compare this with next line pointer (updated).
           JFZ GOTO4              ;If not end of buffer, keep looking for the specified line
           INL                    ;If have same page addresses, check the low address
           LAE                    ;Portions to see if
           CPM                    ;Have reached end of user program buffer
           JFZ GOTO4              ;If not, continue looking. If end of buffer without
GOTOER:    LAI 325                ;Finding specified line, then have an error condition.
           LCI 316                ;Load ACC and register C with code for "UN" and go
           JMP ERROR              ;Display "Undefined Line" error message.
IF:        LLI 202                ;Set L to SCAN pointer storage location.
           LHI \HB\OLDPG26        ;** Load H to page of SCAN pointer storage location.
           LBM                    ;Fetch the SCAN pointer value to register B.
           INB                    ;Add one to advance pointer over last char scanned.
           LLI 276                ;Change L to address of EVAL pointer. Set up EVAL
           LMB                    ;Pointer to begin evaluation with next char in the line.
           CAL CLESYM             ;Clear the SYMBOL BUFFER.
           LLI 320                ;Set L to starting address of THEN in look-up table.
           LHI \HB\OLDPG1         ;** Set H to page of the look-up table.
           CAL INSTR              ;Search for occurrence of THEN in the line input buffer.
           LAE                    ;Transfer register E to ACC. If THEN not found
           NDA                    ;The value in E will be zero.
           JFZ IF1                ;If THEN found, can evaluate the IF expression.
           LLI 013                ;If THEN not found, set L to Auting address of GOTO
           LHI \HB\OLDPG27        ;** In the KEYWORD look-up table. Set H to table
           CAL INSTR              ;Search for occurrence of GOTO in the line input buffer.
           LAE                    ;Transfer E to ACC. If GOTO not found
           NDA                    ;The value in E will be zero.
           JFZ IF1                ;If GOTO found, can evaluate the IF expression.
IFERR:     LAI 311                ;Set ASCII code for letter I in ACC
           LCI 306                ;And code for letter F in register C
           JMP ERROR              ;Go display the IF error message
IF1:       LLI 277                ;Load L with addr of EVAL FINISH pointer storage loc
           LHI \HB\OLDPG26        ;** Load H with page of storage location
           DCE                    ;Subtract one from pointer in E and set the EVAL
           LME                    ;FINISH pointer so that it will evaluate up to the THEN
           CAL EVAL               ;Or GOTO directive. Evaluate the expression.
           LLI 126                ;Load L with address of FPACC Most Significant Word
           LHI \HB\OLDPG1         ;** Load H with page of FPACC MSW
           LAM                    ;Fetch the FPACC MSW into the accumulator
           NDA                    ;Test the value of the FPACC MSW
           JTZ NXTLIN             ;If it is zero, IF condition failed, ignore rest of line.
           LLI 277                ;If not, load L with addr of EVAL FINISH pointer
           LHI \HB\OLDPG26        ;** Set H to the appmpriate page
           LAM                    ;Fetch the value in the EVAL FINISH pointer
           ADI 005                ;Add five to skip over THEN or GOTO directive
           LLI 202                ;Change L to SCAN pointer stomge location
           LMA                    ;Set up the SCAN pointer to location after THEN or
           LBA                    ;GOTO directive. Also put this value in register B.
           INB                    ;Add one to the value in B to point to next character
           LLI 204                ;After THEN or GOTO. Change L to addr of THEN pntr
           LMB                    ;Storage location and store the pointer value.
IF2:       LLI 204                ;Load L with the address of the THEN pointer
           CAL GETCHR             ;Fetch the character pointed to by the THEN pointer
           JFZ IF3                ;If character is not a space, exit this loop
           LLI 204                ;If fetch a space, ignore. Reset L to the THEN pointer
           CAL LOOP               ;Add one to the THEN pointer and test for end of line
           JFZ IF2                ;If not end of line, keep looking for a character other
           JMP IFERR              ;Than a space. If reach end of line first, then error
IF3:       CPI 260                ;When find a character see if it is numeric.
           JTS IF4                ;If not numeric, then should have a new type of
           CPI 272                ;Statement. If numeric, then should have a line number.
           JTS GOTO               ;So process as though have a GOTO statement!
IF4:       LLI 000                ;Load L with addr of start of line input buffer.
           LAM                    ;Fetch the (cc) byte to get length of line value.
           LLI 204                ;Change L to current value of THEN pointer (where first
           SUM                    ;Non-space char. found after THEN or GOTO). Subtract
           LBA                    ;This value from length of line to get remainder. Now
           INB                    ;Have length of second statement portion. Add one for
           LCM                    ;(cc) count. Save THEN pointer value in register C.
           LLI 000                ;Reset L to start of line input buffer. Now put length of
           LMB                    ;Second statement into (cc) position of input buffer.
           LLC                    ;Set L to where second statement starts.
           LDI \HB\OLDPG26        ;** Set D to page of line input buffer.
           LEI 001                ;Set E to first character position of line input buffer.
           CAL MOVEIT             ;Move the second statement up in line to become first!
           LLI 202                ;Load L with address of new SCAN pointer. Load
           LMI 001                ;It with starting position for SYNTAX scan.
           CAL SYNTX4             ;Use special entry to SYNTAX to get new TOKEN value.
           JMP DIRECT             ;Process the second statement in the original line.
GOSUB:     LLI 340                ;Load L with start of LINE NUMBER BUFFER
           LHI \HB\OLDPG26        ;Fetch (cc) of cuffent line number into register D
           LDM                    ;Fetch high value (page) of pgm line pointer to D
           IND                    ;Test contents of register by first incrementing
           DCD                    ;And then decrementing the value in the register
           JTZ GOSUB1             ;If no line number, then processing a DIRECT statement
           LLI 360                ;Else, load L with address of user pgm buff line pointer
           LDM                    ;Fetch high value (page) of pgm line pointer to D
           INL                    ;Advance the memory pointer
           LEM                    ;Fetch the low part of pgm line pointer to E
GOSUB1:    LLI 073                ;Set L to address of GOSUB STACK POINTER
           LHI \HB\OLDPG27        ;** Set H to page of GOSUB STACK POINTER
           LAM                    ;Fetch value in GOSUB stack pointer to ACC
           ADI 002                ;Add two to current stack pointer for new data to be
           CPI 021                ;Placed on the stack and see if stack overflows
           JFS GOSERR             ;If stack filled, have an error condition
           LMA                    ;Else, store updated stack pointer
           LLI 076                ;Load L with address of start of stack less offset (2)
           ADL                    ;Add GOSUB stack pointer to base address
           LLA                    ;To get pointer to top of stack (page byte)
           LMD                    ;Store page part of pgm buffer line pointer in stack
           INL                    ;Advance pointer to next byte in stack
           LME                    ;Store low part of pgm buffer line pointer in stack
           JMP GOTO               ;Proceed from here as though processing a GOTO
RETURN:    LLI 073                ;Set L to address of GOSUB STACK POINTER
           LHI \HB\OLDPG27        ;** Set H to page of GOSUB STACK POINTER
           LAM                    ;Fetch the value of GOSUB stack pointer to ACC
           SUI 002                ;Subtract two for data to be removed from stack
           JTS RETERR             ;If stack underflow, then have an error condition
           LMA                    ;Restore new stack pointer to memory
           ADI 002                ;Add two to point to previous top of stack
           LLI 076                ;Load L with address of start of GOSUB stack less two
           ADL                    ;Add address of previous top of stack to base value
           LLA                    ;Set pointer to high address value in the stack
           LDM                    ;Fetch the high address value from stack to register D
           IND                    ;Exercise the register contents to see if high address
           DCD                    ;Obtained is zero. If so, original GOSUB statement was
           JTZ EXEC               ;A DIRECT statement. Must return to Executive!
           INL                    ;Else, advance pointer to get low address value from the
           LEM                    ;Stack into CPU register E.
           LLI 360                ;Load L with address of user pgm line pointer storage
           LHI \HB\OLDPG26        ;** Location. Load H with page of user pgm line pntr.
           LMD                    ;Put high address from stack into pgm line pointer.
           INL                    ;Advance the memory pointer
           LME                    ;Put low address from stack into pgrn line pointer.
           JMP NXTLIN             ;Execute the next line after originating GOSUB line!
GOSERR:    LAI 307                ;Load ASCII code for letter G into accumulator
           LCI 323                ;Load ASCII code for letter S into register C
           JMP ERROR              ;Go display GoSub (GS) error message.
RETERR:    LAI 322                ;Load ASCII code for letter R into accumulator
           LCI 324                ;Load ASCII code for letter T into register C
           JMP ERROR              ;Go display ReTurn (RT) error message.
INPUT:     CAL CLESYM             ;Clear the SYMBOL BUFFER
           LLI 202                ;Load L with address of SCAN pointer storage location
           LBM                    ;Fetch value of SCAN pointer to register B
           INB                    ;Increment value to point to next chamcter
           LLI 203                ;Change L to point to INPUT pointer (formerly TOKEN)
           LMB                    ;Updated SCAN pointer becomes INPUT pointer
INPUT1:    LLI 203                ;Load L with address of INPUT pointer
           CAL GETCHR             ;Fetch a character from the line input buffer
           JTZ INPUT3             ;If character is a space, ignore it. Else,
           CPI 254                ;See if character is a comma. If so, process the
           JTZ INPUT4             ;Variable that preceeds the comma.
           CPI 250                ;If not, see if character is a left parenthesis.
           JFZ INPUT2             ;If not, continue processing to build up symbolic variable
           CAL ARRAY2             ;@@ If so, call array subscripting subroutine
           LLI 206                ;@@ Load L with address of array set up pointer
           LHI \HB\OLDPG26        ;@@ ** Load H with page of array set up pointer
           LBM                    ;@@ Fetch pointer value (point to ")" of subscript)
           LLI 203                ;@@ Change pointer to address of INPUT pointer
           LMB                    ;@@ Update INPUT pointer
           JMP INPUT3             ;@@ Jump over concatenate instruction below
INPUT2:    CAL CONCTS             ;Concatenate character to SYMBOL BUFFER
INPUT3:    LLI 203                ;Load L with address of INPUT pointer
           CAL LOOP               ;Increment INPUT pointer and test for end of line
           JFZ INPUT1             ;If not end of line, go get next character
           CAL INPUTX             ;If end of buffer, get input for variable in the SYMBOL
           CAL STOSYM             ;BUFFER and store the value in the VARIABLES table
           JMP NXTLIN             ;Then continue to interpret next statement line
INPUT4:    CAL INPUTX             ;Get input from user for variable in SYMBOL BUFFER
           CAL STOSYM             ;Store the inputted value in the VARIABLES table
           LHI \HB\OLDPG26        ;** Set H to page of INPUT pointer
           LLI 203                ;Set L to location of INPUT pointer
           LBM                    ;Fetch pointer value for last character examined
           LLI 202                ;Change L to point to SCAN pointer storage location
           LMB                    ;Update the SCAN pointer
           JMP INPUT              ;Continue processing statement line for next variable
INPUTX:    LLI 120                ;Load L with start of SYMBOL BUFFER (contains cc)
           LAM                    ;Fetch the (cc) (length of symbol in the buffer) to ACC
           ADL                    ;Add (cc) to base address to set up
           LLA                    ;Pointer to last character in the SYMBOL BUFFER
           LAM                    ;Fetch the last character in the SYMBOL BUFFER
           CPI 244                ;See if the last chamcter was a $ sign
           JFZ INPUTN             ;If not a $ sign, get variable value as a numerical entry
           LLI 120                ;If $ sign, reset L to start of the SYMBOL BUFFER
           LBM                    ;Fetch the (cc) for the variable in the SYMBOL BUFF
           DCB                    ;Subtract one from (cc) to chop off the $ sign
           LMB                    ;Restore the new (cc) for the SYMBOL BUFFER
           CAL FP0                ;Call subroutine to zero the floating point accumulator
           CAL CINPUT             ;Input one character from system input device
           LLI 124                ;Load L with address of the LSW of the FPACC
           LMA                    ;Place the ASCII code for the character inputted there
           JMP FPFLT              ;Convert value to floating point format in FPACC
INPUTN:    LLI 144                ;Load L with address of start of AUX SYMBOL BUFF
           LHI \HB\OLDPG26        ;** Load H with page of AUX SYMBOL BUFFER
           LAI 277                ;Load accumulator with ASCII code for ? mark
           CAL ECHO               ;Call output subroutine to display the ? mark
           CAL STRIN              ;Input string of characters (number) fm input device
           JMP DINPUT             ;Convert decimal string into binary floating point nr.
FP0:       LHI \HB\OLDPG1         ;** Load H with floating point working registers page
           JMP CFALSE             ;Zero the floating point accumulator & exit to caller
FOR:       LLI 144                ;Load L with address of AUX SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Load H with page of AUX SYMBOL BUFFER
           LMI 000                ;Initialize buffer by clearing first byte
           LLI 146                ;Load L with location of second character in buffer
           LMI 000                ;Clear that location in case of single character variable
           LLI 205                ;Load L with address of FOR/NEXT STACK pointer
           LHI \HB\OLDPG27        ;** Load H with page of FOR/NEXT STACK pointer
           LBM                    ;Fetch the FOR/NEXT STACK pointer
           INB                    ;Increment it in preparation for pushing operation
           LMB                    ;Restore it back to its storage location
           LLI 360                ;Load L with address of user pgrn buffer line pointer
           LHI \HB\OLDPG26        ;** Set H to page of line pointer
           LDM                    ;Fetch page address of pgm buffer line pntr into D
           INL                    ;Advance the memory pointer to pick up low part
           LEM                    ;Fetch low address of pgm buffer line pntr into E
           LAB                    ;Restore updated FOR/NEXT STACK pointer to ACC
           RLC                    ;Rotate it left to multiply by two, then rotate it again to
           RLC                    ;Multiply by four. Add this value to the base address of
           ADI 134                ;The FOR/NEXT STACK to point to the new top of
           LLA                    ;The FOR/NEXT STACK and set up to point to stack
           LHI \HB\OLDPG27        ;** Set H for page of the FOR/NEXT STACK
           LMD                    ;Store the page portion of the user pgrn buffer line pntr
           INL                    ;In the FORINEXT STACK, advance register 4 then
           LME                    ;Store the low portion of the pgrn line pntr on the stack
           LLI 325                ;Change L to point to start of TO string which is stored
           LHI \HB\OLDPG1         ;** In a text strings storage area on this page
           CAL INSTR              ;Search the statement line for the occurrence of TO
           LAE                    ;Register E wiU be zero if TO not found. Move E to ACC
           NDA                    ;To make a test
           JFZ FOR1               ;If TO found then proceed with FOR statement
FORERR:    LAI 306                ;Else have a For Error. Load ACC with ASCII code for
           LCI 305                ;Letter F and register C with code for letter E.
           JMP ERROR              ;Then go display the FE message.
FOR1:      LLI 202                ;Load L with address of SCAN pointer storage location
           LHI \HB\OLDPG26        ;** Set H to page of the SCAN pointer
           LBM                    ;Fetch pointer value to ACC (points to letter R in the
           INB                    ;For directive). Increment it to point to next character
           LLI 204                ;In the line. Change register L and set this value up
           LMB                    ;As an updated FOR pointer.
           LLI 203                ;Set L to address of TO pointer (formerly TOKEN)
           LME                    ;Save pointer to TO in the TO pointer!
FOR2:      LLI 204                ;Load L with address of the FOR pointer
           CAL GETCHR             ;Fetch a character from the statement line
           JTZ FOR3               ;If it is a space, ignore it
           CPI 275                ;Test to see if character is the "=" sign
           JTZ FOR4               ;If so, variable name is in the AUX SYMBOLBUFFER
           LLI 144                ;If not, then set L to point to start of the AUX SYMBOL
           CAL CONCT1             ;BUFFER and concatenate the character onto the buffer
FOR3:      LLI 204                ;Reset L to address of the FOR pointer
           CAL LOOP               ;Increment the pointer and see if end of line
           JFZ FOR2               ;If not end of line, continue looking for the "=" sign
           JMP FORERR             ;If reach end of line before "=" sign, then have error
FOR4:      LLI 204                ;Set L with address of the FOR pointer
           LBM                    ;Fetch pointer value to ACC (pointing to sign)
           INB                    ;Increment it to skip over the "=" sign
           LLI 276                ;Set L to address of the EVAL pointer
           LMB                    ;Restore the updated pointer to storage
           LLI 203                ;Set L to the address of the TO pointer
           LBM                    ;Fetch pointer value to ACC (pointing to letter T in TO)
           DCB                    ;Decrement it to point to character before the T in TO
           LLI 277                ;Set L to EVAL FINISH pointer storage location
           LMB                    ;Store the EVAL FINISH pointer value
           CAL EVAL               ;Evaluate the expression between the "=" sign and TO
           CAL RESTSY             ;Directive. Place the variable name in the variables table.
           LLI 144                ;Load L with starting address of the AUX SYMBOL BF
           LHI \HB\OLDPG26        ;** Load H with the page of the AUX SYMBOL BUFF
           LAM                    ;Fetch the (cc) for the name in the buffer
           CPI 001                ;See if the symbol (name) length is just one character
           JFZ FOR5               ;If not, go directly to place name in FOR/NEXT STACK
           LLI 146                ;If so, set L to point to second character location in the
           LMI 000                ;AUX SYMBOL BUFFER and set it equal to zero.
           JMP FOR5               ;This jump directs program over ontrs/cntrs/table area
;;; LAST LINE SHOULD START AT 17 365
;;; PATCH AREA FOLLOWS THIS
	
	ORG 020#000
FPFIX:     LLI 126                ;Set L to point to MSW of FPACC
           LHI \HB\OLDPG1         ;** Set H to point to page of FPACC
           LAM                    ;Fetch MSW of FPACC
           LLI 100                ;Change pointer to SIGN indicator on same page
           LMA                    ;Place MSW of FPACC into SIGN indicator
           NDA                    ;Now test sign bit of MSW of FPACC
           CTS FPCOMP             ;Two's complement value in FPACC if negative
           LLI 127                ;Change pointer to FPACC Exponent register
           LAI 027                ;Set accumulator to 23 (decimal) for number of bits
           LBM                    ;Load FPACC Exponent into CPU register B
           INB                    ;Exercise the value in register B
           DCB                    ;To set CPU flags
           JTS FPZERO             ;If FPACC Exponent is negative set FPACC to zero
           SUB                    ;Subtract value of FPACC Exponent from 23 decimal
           JTS FIXERR             ;If Exp larger than 23 decimal cannot convert
           LCA                    ;Else place result in register C as counter for number
FPFIXL:    LLI 126                ;Of rotate ops. Set pointer to MSW of FPACC
           LBI 003                ;Set precision counter (number of bytes in mantissa)
           CAL ROTATR             ;Rotate FPACC right the number of places indicated
           DCC                    ;By count in register C to effectively rotate all the
           JFZ FPFIXL             ;Significant bits to the left of the floating point decimal
           JMP RESIGN             ;Point. Go check original sign & negate answer if req'd.

                                  ;Following subroutine clears the FPACC to the zero
                                  ;condition.

FPZERO:    LLI 126                ;Set L to point to MSW of FPACC
           XRA                    ;Clear the accumulator
           LMA                    ;Set the MSW of FPACC to zero
           DCL                    ;Decrement the pointer
           LMA                    ;Set the next significant word of FPACC to zero
           DCL                    ;Decrement the pointer
           LMA                    ;Set the LSW of FPACC to zero
           DCL                    ;Decrement the pointer
           LMA                    ;Set the auxiliary FPACC byte to zero
           RET                    ;Exit to calling routine

                                  ;The next instruction is a special entry point to
                                  ;the FPNORM subroutine that is used when a number is
                                  ;converted from fixed to floating point. The FPNORM
                                  ;label is the entry point when a number already in float-
                                  ;ing point fonnat is to be normalized.

FPFLT:     LBI 027                ;For fixed to float set CPU register B to 23 decimal
FPNORM:    LAB                    ;Get CPU register B into ACC to check for special case
           LHI \HB\OLDPG1         ;** Set H to page of FPACC
           LLI 127                ;Set L to FPACC Exponent byte
           NDA                    ;Set CPU flags to test what was in CPU register B
           JTZ NOEXC0             ;If B was zero then do standard normalization
           LMB                    ;Else set Exponent of FPACC to 23 decimal
NOEXC0:    DCL                    ;Change pointer to MSW of FPACC
           LAM                    ;Fetch MSW of FPACC into accumulator
           LLI 100                ;Change pointer to SIGN indicator storage location
           LMA                    ;Place the MSW of FPACC there for future reference
           NDA                    ;Set CPU flags to test MSW of FPACC
           JFS ACZERT             ;If sign bit not set then jump ahead to do next test
           LBI 004                ;If sign bit set, number in FPACC is negative. Set up
           LLI 123                ;For two's complement operation
           CAL COMPLM             ;And negate the value in the FPACC to make it positive
ACZERT:    LLI 126                ;Reset pointer to MSW of FPACC
           LBI 004                ;Set precision counter to number of bytes in FPACC
LOOK0:     LAM                    ;Plus one. Fetch a byte of the FPACC.
           NDA                    ;Set CPU flags
           JFZ ACNONZ             ;If find anything then FPACC is not zero
           DCL                    ;Else decrement pointer to NSW of FPACC
           DCB                    ;Decrement precision counter
           JFZ LOOK0              ;Continue checking to see if FPACC contains anything
           LLI 127                ;Until precision counter is zero. If reach here then
           XRA                    ;Reset pointer to FPACC Exponent. Clear the ACC and
           LMA                    ;Clear out the FPACC Exponent. Value of FPACC is zip!
           RET                    ;Exit to calling routine
ACNONZ:    LLI 123                ;If FPACC has any value set pointer to LSW minus one
           LBI 004                ;Set precision counter to number of bytes in FPACC
           CAL ROTATL             ;Plus one for special cases. Rotate the contents of the
           LAM                    ;FPACC to the LEFT. Pointer will be set to MSW after
           NDA                    ;Rotate ops. Fetch MSW and see if have anything in
           JTS ACCSET             ;Most significant bit position. If so, have rotated enough
           INL                    ;If not, advance pointer to FPACC Exponent. Fetch
           LBM                    ;The value of the Exponent and decrement it by one
           DCB                    ;To compensate for the rotate left of the mantissa
           LMB                    ;Restore the new value of the Exponent
           JMP ACNONZ             ;Continue rotating ops to normalize the FPACC
ACCSET:    LLI 126                ;Set pntr to FPACC MSW. Now must provide room for
           LBI 003                ;Sign bit in nonnalized FPACC. Set precision counter.
           CAL ROTATR             ;Rotate the FPACC once to the right now.
RESIGN:    LLI 100                ;Set the pointer to SIGN indicator storage location
           LAM                    ;Fetch the original sign of the FPACC
           NDA                    ;Set CPU flags
           RFS                    ;If original sign of FPACC was positive, can exit now.

FPCOMP:    LLI 124                ; However, if original sign was negative, must now restore
           LBI 003                ;The FPACC to negative by performing two's comple-
           JMP COMPLM             ;Ment on FPACC. Return to caring rtn via COMPLM.

                                  ;Floating point ADDITION. Adds contents of FPACC to
                                  ;FPOP and leaves result in FPACC. Routine first checks
                                  ;to see if either register contains zero. If so addition
                                  ;result is already present!

FPADD:     LLI 126                ;Set L to point to MSW of FPACC
           LHI \HB\OLDPG1         ;** Do same for register H
           LAM                    ;Fetch MSW of FPACC to accumulator
           NDA                    ;Set CPU flags after loading op
           JFZ NONZAC             ;If accumulator non-zero then FPACC has some value
MOVOP:     LLI 124                ;But, if accumulator was zero then normalized FPACC
           LDH                    ;Must also be zero. Thus answer to addition is simply the
           LEL                    ;Value in FPOP. Set up pointers to transfer contents of
           LLI 134                ;FPOP to FPACC by pointing to the LSW of both
           LBI 004                ;Registers and perform the transfer. Then exit to calling
           JMP MOVEIT             ;Routine with answer in FPACC via MOVEIT.
NONZAC:    LLI 136                ;If FPACC was non-zero then check to see if FPOP has
           LAM                    ;Some value by obtaining MSW of FPOP
           NDA                    ;Set CPU flags after loading op. If MSW zero then
           RTZ                    ;Normalized FPOP must be zero. Answer is in FPACC!

                                  ;If neither FPACC or FPOP was zero then must perform
                                  ;addition operation. Must first check to see if two num-
                                  ;bers are within significant mnge. If not, largest number
                                  ;is answer. If numbers within range, then must align ex-
                                  ;ponents before perforrning the addition of the man-
                                  ;tissa.

CKEQEX:    LLI 127                ;Set pointer to FPACC Exponent storage location.
           LAM                    ;Fetch the Exponent value to the accumulator.
           LLI 137                ;Change the pointer to the FPOP Exponent
           CPM                    ;Compare the values of the exponents. If they are the
           JTZ SHACOP             ;Same then can immediately proceed to add operations.
           LBA                    ;If not the same, store FPACC Exponent size in regis B
           LAM                    ;Fetch the FPOP Exponent size into the ACC
           SBB                    ;Subtract the FPACC Exponent from the FPOP Exp.
           JFS SKPNEG             ;If result is positive jump over the next few instructions
           LBA                    ;If result was negative, store the result in B
           XRA                    ;Clear the accumulator
           SBB                    ;Subtract register B to negate the original value
SKPNEG:    CPI 030                ;See if difference is less than 24 decimal.
           JTS LINEUP             ;If so, can align exponents. Go do it.
           LAM                    ;If not, find out which number is largest. Fetch FPOP
           LLI 127                ;Exponent into ACC. Change pointer to FPACC Exp.
           SUM                    ;Subtract FPACC from FPOP. If result is negative then
           RTS                    ;was larger. Return with answer in FPACC.
           LLI 124                ;If result was positive, larger value in FPOP. Set pointers
           JMP MOVOP              ;To transfer FPOP into FPACC and then exit to caller.
LINEUP:    LAM                    ;Fetch FPOP Exponent into accumulator.
           LLI 127                ;Change pointer to FPACC Exponent.
           SUM                    ;Subtract FPACC Exponent from FPOP Exponent. If
           JTS SHIFT0             ;Result is negative FPACC is larger. Go shift FPOP.
           LCA                    ;If result positive FPOP larger, must shift FPACC. Store
MORACC:    LLI 127                ;Difference count in C. Reset pointer to FPACC Exp
           CAL SHLOOP             ;Call the SHift LOOP to rotate FPACC mantissa RIGHT
           DCC                    ;And INCREMENT Exponent. Decr difference counter
           JFZ MORACC             ;Continue rotate operations until diff counter is zero
           JMP SHACOP             ;Go do final alignment and perform addition process
SHIFT0:    LCA                    ;Routine to shift FPOP. Set difference count into reg. C
MOROP:     LLI 137                ;Set pointer to FPOP Exponent.
           CAL SHLOOP             ;Call the SHift LOOP to rotate FPOP mantissa RIGHT
           INC                    ;And INCREMENT Exponent. Then incr difference cntr
           JFZ MOROP              ;Continue rotate opemtions until diff counter is zero
;;; The below two instructions are changed by PATCH NR.1
;;;SHACOP:    LLI 123                ;Set pointer to FPACC LSW minus one to provide extra
;;;           LMI 000                ;Byte for addition ops. Clear that location to zero.
SHACOP:	   CAL PATCH1		; patch 1 inserts a few lines at 30-000
	   LAA
	
;;;           LLI 133
;;;           LMI 000                ;THIS IS PATCH #1
           LLI 127                ;Change pointer to FPACC Exponent
           CAL SHLOOP             ;Rotate FPACC mantissa RIGHT & Increment Exponent
           LLI 137                ;Change pointer to FPOP Exponent
           CAL SHLOOP             ;Rotate FPOP mantissa RIGHT & Increment Exponent
           LDH                    ;Rotate ops provide room for overflow. Now set up
           LEI 123                ;Pointers to LSW minus one for both FPACC & FPOP
           LBI 004                ;(FPOP already set after SHLOOP). Set precision counter
           CAL ADDER              ;Call quad precision ADDITION subroutine.
           LBI 000                ;Set CPU register B to indicate standard normalization
           JMP FPNORM             ;Go normalize the result and exit to caller.
SHLOOP:    LBM                    ;Shifting loop. First fetch Exponent currently being
           INB                    ;Pointed to and Increment the value by one.
           LMB                    ;Return the updated Exponent value to memory.
           DCL                    ;Decrement the pointer to mantissa portion MSW
           LBI 004                ;Set precision counter
FSHIFT:    LAM                    ;Fetch MSW of mantissa
           NDA                    ;Set CPU flags after load ops
           JFS ROTATR             ;If MSB not a one can do normal rotate ops
BRING1:    RAL                    ;If MSB is a one need to set up carrv bit for the negative
           JMP ROTR               ;Number case. Then make special entry to ROTATR sub

                                  ;The following subroutine moves the contents of a string
                                  ;of memory locations from the address pointed to by
                                  ;CPU registers H & L to the address specified by the con-
                                  ;tents of registers D & E when the routine is entered. The
                                  ;process continues until the counter in register B is zero.

MOVEIT:    LAM                    ;Fetch a word from memory string A
           INL                    ;Advance A string pointer
           CAL SWITCH             ;Switch pointer to string B
           LMA                    ;Put word from string A into string B
           INL                    ;Advance B string pointer
           CAL SWITCH             ;Switch pointer back to string A
           DCB                    ;Decrement loop counter
           RTZ                    ;Return to calling routine when counter reaches zero
           JMP MOVEIT             ;Else continue transfer operations

                                  ;The following subroutine SUBTRACTS the
                                  ;contents of the FLOATING POINT ACCUMULATOR from the
                                  ;contents of the FLOATING POINT OPERAND and
                                  ;leaves the result in the FPACC. The routine merely
                                  ;negates the value in the FPACC and then goes to the
                                  ;FPADD subroutine just presented.

FPSUB:     LLI 124                ;Set L to address of LSW of FPACC
           LHI \HB\OLDPG1         ;** Set H to page of FPACC
           LBI 003                ;Set precision counter
           CAL COMPLM             ;Two's complement the value in the FPACC
           JMP FPADD              ;Now go add the negated value to perform subtraction!

                                  ;The first part of the FLOATING POINT MULTIPLI-
                                  ;CATION subroutine calls a subroutine to check the
                                  ;original signs of the numbers that are to be multi-
                                  ;plied and perform working register clearing functions.
                                  ;Next the exponents of the numbers to be multiplied
                                  ;are added together.

FPMULT:    CAL CKSIGN             ;Call routine to set up registers & ck signs of numbers
ADDEXP:    LLI 137                ;Set pointer to FPOP Exponent
           LAM                    ;Fetch FPOP Exponent into the accumulator
           LLI 127                ;Change pointer to FPACC Exponent
           ADM                    ;Add FPACC Exponent to FPOP Exponent
           ADI 001                ;Add one more to total for algorithm compensation
           LMA                    ;Store result in FPACC Exponent location
SETMCT:    LLI 102                ;Change pointer to bit counter storage location
           LMI 027                ;Initialize bit counter to 23 decimal

                                  ;Next portion of the FPMULT routine is the iinplernen-
                                  ;tation of the algorithm illustrated in the flow chart
                                  ;above. This portion multiplies the values of the two
                                  ;mantissas. The final value is rounded off to leave the
                                  ;23 most significant bits as the answer that is stored
                                  ;back in the FPACC.

MULTIP:    LLI 126                ;Set pointer to MSW of FPACC mantissa
           LBI 003                ;Set precision counter
           CAL ROTATR             ;Rotate FPACC (multiplier) RIGHT into carry bit
           CTC ADOPPP             ;If carry is a one, add multiplicand to partial-product
           LLI 146                ;Set pointer to partial-product most significant byte
           LBI 006                ;Set precision counter (p-p register is double length)
           CAL ROTATR             ;Shift partial-product RIGHT
           LLI 102                ;Set pointer to bit counter storage location
           LCM                    ;Fetch current value of bit counter
           DCC                    ;Decrement the value of the bit counter
           LMC                    ;Restore the updated bit counter to its storage location
           JFZ MULTIP             ;If have not multiplied for 23 (deciinal) bits, keep going
           LLI 146                ;If have done 23 (decimal) bits, set pntr to p-p MSW
           LBI 006                ;Set precision counter (for double length)
           CAL ROTATR             ;Shift partial-product once more to the RIGHT
           LLI 143                ;Set pointer to access 24'th bit in partial-product
           LAM                    ;Fetch the byte containing the 24'th bit
           RAL                    ;Position the 24'th bit to be MSB in the accumulator
           NDA                    ;Set the CPU flags after to rotate operation and test to
           CTS MROUND             ;See if 24'th bit of p-p is a ONE. If so, must round-off
           LLI 123                ;Now set up pointers
           LEL                    ;To perform transfer
           LDH                    ;Of the multiplication results
           LLI 143                ;From the partial-product location
           LBI 004                ;To the FPACC

	
EXMLDV:    CAL MOVEIT             ;Perform the transfer from p-p to FPACC
           LBI 000                ;Set up CPU register B to indicate regular normalization
           CAL FPNORM             ;Normalize the result of multiplication
           LLI 101                ;Now set the pointer to the original SIGNS indicator
           LAM                    ;Fetch the indicator
           NDA                    ;Exercise the CPU flags
           RFZ                    ;If indicator is non-zero, answer is positive, can exit her
           JMP FPCOMP             ;If not, answer must be negated, exit via 2's complement.

                                  ;The following portions of the FPMULT
                                  ;routine set up working locations in memory by clearing
                                  ;locations for an expanded FPOP area and the partial-produc
                                  ;area. Next, the signs of the two numbers to be multiplied
                                  ;are examined. Negative numbers are negated
                                  ;in preparation for the multiplication
                                  ;algorithm. A SIGNS indicator register is set up during
                                  ;this process to indicate whether the final result of the
                                  ;multiplication should be positive or negative. (Negative
                                  ;if original signs of the two numbers to be multiplied are
                                  ;different.)

CKSIGN:    LLI 140                ;Set pointer to start of partial-product working area
           LHI \HB\OLDPG1         ;** Set H to proper page
           LBI 010                ;Set up a loop counter in CPU register B
           XRA                    ;Clear the accumulator

CLRNEX:    LMA                    ;Now clear out locations for the partial-product
           INL                    ;Working registers
           DCB                    ;Until the loop counter
           JFZ CLRNEX             ;Is zero
CLROPL:    LBI 004                ;Set a loop counter
           LLI 130                ;Set up pointer
CLRNX1:    LMA                    ;Clear out some extra registers so that the
           INL                    ;FPOP may be extended in length
           DCB                    ;Perform clearing ops until loop counter
           JFZ CLRNX1             ;Is zero
           LLI 101                ;Set pointer to M/D SIGNS indicator storage location
           LMI 001                ;Set initial value of SIGNS indicator to plus one
           LLI 126                ;Change pointer to MSW of FPACC
           LAM                    ;Fetch MSW of mantissa into accumulator
           NDA                    ;Test flags
           JTS NEGFPA             ;If MSB in MSW of FPACC is a one, number is negative
OPSGNT:    LLI 136                ;Set pointer to MSW of FPOP
           LAM                    ;Fetch MSW of mantissa into accumulator
           NDA                    ;Test flags
           RFS                    ;Return to caller if number in FPOP is positive
           LLI 101                ;Else change pointer to M/D SIGNS indicator
           LCM                    ;Fetch the value in the SIGNS indicator
           DCC                    ;Decrement the value by one
           LMC                    ;Restore the new value back to storage location
           LLI 134                ;Set pointer to LSW of FPOP
           LBI 003                ;Set precision counter
           JMP COMPLM             ;Two's complement value of FPOP & return to caller
NEGFPA:    LLI 101                ;Set pointer to M/D SIGNS indicator
           LCM                    ;Fetch the value in the SIGNS indicator
           DCC                    ;Decrement the value by one
           LMC                    ;Restore the new value back to storage location
           LLI 124                ;Set pointer to LSW of FPACC
           LBI 003                ;Set precision counter
           CAL COMPLM             ;Two's complement value of FPACC
           JMP OPSGNT             ;Proceed to check sign of FPOP

                                  ;The following subroutine adds the double length (six regis
                                  ;multiplicand in FPOP to the partial-product register when
                                  ;called on by the multiplication algorithm.

ADOPPP:    LEI 141                ;Pointer to LSW of partial-product
           LDH                    ;On same page as FPOP
           LLI 131                ;LSIV of FPOP which contains extended multiplicand
           LBI 006                ;Set precision counter (double length working registers)
           JMP ADDER              ;Add multiplicand to partial-product & return to caller

MROUND:    LBI 003                ;Set up precision counter
           LAI 100                ;Prepare to add one to 24'th bit of partial-product
           ADM                    ;Add one to the 24'th bit of the partial-product
CROUND:    LMA                    ;Restore the updated byte to memory
           INL                    ;Advance the memory pointer to next most significant
           LAI 000                ;Byte of partial-product, then clear ACC without
           ACM                    ;Disturbing carry bit. Now perform add with carry to
           DCB                    ;Propagate any rounding in the partial-product registers.
           JFZ CROUND             ;If cotinter is not zero continue propagating any carry
           LMA                    ;Restore final byte to memory
           RET                    ;Exit to calling routine

FPDIV:     CAL CKSIGN             ;Call routine to set up registers & ck signs of numbers
           LLI 126                ;Set pointer to MSW of FPACC (divisor)
           LAM                    ;Fetch MSW of FPACC to accumulator
           NDA                    ;Exercise CPU flags
           JTZ DVERR              ;If MSW of FPACC is zero go display 'DZ' error message
SUBEXP:    LLI 137                ;Set pointer to FPOP (dividend) Exponent
           LAM                    ;Get FPOP Exponent into accumulator
           LLI 127                ;Change pointer to FPACC (divisor) Exponent
           SUM                    ;Subtract divisor exponent from dividend exponent
           ADI 001                ;Add one for algorithm compensation
           LMA                    ;Place result in FPACC Exponent
SETDCT:    LLI 102                ;Set pointer to bit counter storage location
           LMI 027                ;Initialize bit counter to 23 decimal

                                  ;Main division algorithm for mantissas

DIVIDE:    CAL SETSUB             ;Go subtmct divisor from dividend
           JTS NOGO               ;If result is negative then place a zero bit in quotient
           LEI 134                ;If result zero or positive then move remainder after
           LLI 131                ;Subtraction from working area to become new dividend
           LBI 003                ;Set up moving pointers and initialize precision counter
           CAL MOVEIT             ;Perform the transfer
           LAI 001                ;Place a one into least significant bit of accumulator
           RAR                    ;And rotate it out into the carry bit
           JMP QUOROT             ;Proceed to rotate the carry bit into the current quotient
NOGO:      XRA                    ;When result is negative, put a zero in the carry bit, then
QUOROT:    LLI 144                ;Set up pointer to LSW of quotient register
           LBI 003                ;Set precision counter
           CAL ROTL               ;Rotate carry bit into quotient by using special entry to
           LLI 134                ;ROTATL subroutine. Now set up pointer to dividend
           LBI 003                ;LSW and set precision counter
           CAL ROTATL             ;Rotate the current dividend to the left
           LLI 102                ;Set pointer to bit counter storage location
           LCM                    ;Fetch the value of the bit counter
           DCC                    ;Decrement the value by one
           LMC                    ;Restore the new counter value to storage
           JFZ DIVIDE             ;If bit counter is not zero, continue division process
           CAL SETSUB             ;After 23 (decimal) bits, do subtraction once more for
           JTS DVEXIT             ;Possible rounding. Jump ahead if no rounding required.
           LLI 144                ;If rounding required set pointer to LSW of quotient
           LAM                    ;Fetch LSW of quotient to accumulator
           ADI 001                ;Add one to 23rd bit of quotient
           LMA                    ;Restore updated LSW of quotient
           LAI 000                ;Clear accumulator without disturbing carry bit
           INL                    ;Advance pointer to next significant byte of quotient
           ACM                    ;Propagate any carry as part of rounding process
           LMA                    ;Restore the updated byte of quotient
           LAI 000                ;Clear ACC again without disturbing carry bit
           INL                    ;Advance pointer to MSW of quotient
           ACM                    ;Propagate any carry to finish rounding process
           LMA                    ;Restore the updated byte of quotient
           JFS DVEXIT             ;If most significant bit of quotient is zero, go finish up
           LBI 003                ;If not, set precision counter
           CAL ROTATR             ;And rotate quotient to the right to clear the sign bit
           LLI 127                ;Set pointer to FPACC Exponent
           LBM                    ;Fetch FPACC exponent
           INB                    ;Increment the value to compensate for the rotate right
           LMB                    ;Restore the updated exponent value
DVEXIT:    LLI 143                ;Set up pointers
           LEI 123                ;To transfer the quotient into the FPACC
           LBI 004                ;Set precision counter
                                  ;THIS IS A CORRECTION FOUND IN THE NOTES
           JMP EXMLDV             ;And exit through FPMULT routine at EXMLDV

                                  ;Subroutine to subtract divisor from dividend. Used by
                                  ;main DIVIDE subroutine.

SETSUB:    LEI 131                ;Set pointer to LSW of working area
           LDH                    ;On same page as FPACC
           LLI 124                ;Set pointer to LSW of FPACC (divisor)
           LBI 003                ;Set precision counter
           CAL MOVEIT             ;Perform transfer
           LEI 131                ;Reset pointer to LSW of working area (now divisor)
           LLI 134                ;Reset pointer to LSW of FPOP (dividend)
           LBI 003                ;Set precision counter
           CAL SUBBER             ;Subtract divisor from dividend
           LAM                    ;Get MSW of the result of the subtraction operations
           NDA                    ;Exercise CPU flags
           RET                    ;Return to caller with status
ADDER:     NDA                    ;Initialize the carry bit to zero upon entry
ADDMOR:    LAM                    ;Fetch byte from register group A
           CAL SWITCH             ;Switch memory pointer to register group B
           ACM                    ;Add byte from A to byte from B with carry
           LMA                    ;Leave result in register group B
           DCB                    ;Decrement number of bytes (precision) counter
           RTZ                    ;Return to caller when all bytes in group processed
           INL                    ;Else advance pointer for register group B
           CAL SWITCH             ;Switch memory pointer back to register group A
           INL                    ;Advance the pointer for register group A
           JMP ADDMOR             ;Continue the multi-byte addition operation

                                  ;N'th precision two's complement (negate)
                                  ;subroutine. Performs a two's complement on the multi-byte
                                  ;registers tarting at the address pointed
                                  ; to by H & L (least significant byte) upon entry.

COMPLM:    LAM                    ;Fetch the least significant byte of the number to ACC
           XRI 377                ;Exclusive OR to complement the byte
           ADI 001                ;Add one to form two's complement of byte
MORCOM:    LMA                    ;Restore the negated byte to memory
           RAR                    ;Save the carry bit
           LDA                    ;In CPU register D
           DCB                    ;Decrement number of bytes (precision) counter
           RTZ                    ;Return to caller when all bytes in number processed
           INL                    ;Else advance the pointer
           LAM                    ;Fetch the next byte of the number to ACC
           XRI 377                ;Exclusive OR to complement the byte
           LEA                    ;Save complemented value in register E temporarily
           LAD                    ;Restore previous carry status to ACC
           RAL                    ;And rotate it out to the carry bit
           LAI 000                ;Clear ACC without disturbing carry status
           ACE                    ;Add in any carry to complemented value
           JMP MORCOM             ;Continue the two's complement procedure as req'd

                                  ;N'th precision rotate left subroutine. Rotates a multi-
                                  ;byte number left starting at the address initially
                                  ;specified by the contents of CPU registers H & L upon
                                  ;subroutine entry (LSW). First entry point will clear
                                  ;the carry bit before beginning rotate operations. Second
                                  ;entry point does not clear the carry bit.

ROTATL:    NDA                    ;Clear the carry bit at this entry point
ROTL:      LAM                    ;Fetch a byte from memory
           RAL                    ;Rotate it left (bring carry into LSB, push MSB to carry)
           LMA                    ;Restore rotated word to memory
           DCB                    ;Decrement precision counter
           RTZ                    ;Exit to caller when finished
           INL                    ;Else advance pointer to next byte
           JMP ROTL               ;Continue rotate left operations


                                  ;N'th precision rotate
                                  ;right subroutine. Opposite of
                                  ;above subroutine.

ROTATR:    NDA                    ;Clear the carry bit at this entry point
ROTR:      LAM                    ;Fetch a byte from memory
           RAR                    ;Rotate it right (carry into MSB, LSB to carry)
           LMA                    ;Restore rotated word to memory
           DCB                    ;Decrement precision counter
           RTZ                    ;Exit to caller when finished
           DCL                    ;Else decrement pointer to next byte
           JMP ROTR               ;Continue rotate right operations

                                  ;N'th precision subtraction subroutine.
                                  ;Number starting at location pointed to by D & E (least
                                  ;significant byte) is subtracted from number starting at
                                  ;address specified by contents of H & L.

SUBBER:    NDA                    ;Initialize the carry bit to zero upon entry
SUBTRA:    LAM                    ;Fetch byte from register group A
           CAL SWITCH             ;Switch memory pointer to register group B
           SBM                    ;Subtract byte from group B ftom that in group A
           LMA                    ;Leave result in register group B
           DCB                    ;Decrement number of bytes (precision) counter
           RTZ                    ;Return to caller when all bytes in group processed
           INL                    ;Else advance pointer for register group B
           CAL SWITCH             ;Switch memory pointer back to register group A
           INL                    ;Advance the pointer for register group A
           JMP SUBTRA             ;Continue the multi-byte subtraction operation

                                  ;The next subroutine will transfer the four byte
                                  ;register string (generally a number in floating point
                                  ;format) from the starting address pointed to by CPU
                                  ;registers H & L when the subroutine is entered to
                                  ;the FPACC (floating point accumulator registers).

FLOAD:     LDI \HB\OLDPG1         ;** Set page address of FPACC
           LEI 124                ;Set address of least signficant byte of FPACC
           LBI 004                ;Set precision counter to four bytes (mantissa bytes
           JMP MOVEIT             ;Plus Exponent) and exit via the transfer routine

                                  ;The next several subroutines are used to perform
                                  ;floating pojnt register loading and transfer operations.

FSTORE:    LEL                    ;Transfer contents of register L to E
           LDH                    ;Transfer contents of register H to D
           LLI 124                ;Set L to least significant byte of FPACC mantissa
           LHI \HB\OLDPG1         ;** Set page to FPACC storage area
           JMP SETIT              ;Go transfer FPACC contents to area pointed to by D&E
OPLOAD:    LDI \HB\OLDPG1         ;** Set page to FPOP storage area
           LEI 134                ;Set pointer to least significant byte of FPOP
SETIT:     LBI 004                ;Set precision counter. Transfer from H & L area to
           JMP MOVEIT             ;Locations pointed to by D & E

                                  ;The next subroutine perforins a double transfer opera-
                                  ;tion. It first transfers the contents of the FPACC into
                                  ;the FPOP. It then transfers new data (as pointed to by
                                  ;H & L upon entry to the subroutine) into the FPACC.

FACXOP:    CAL SAVEHL             ;Save contents of H & L upon entry to subroutine
           LLI 124                ;Set pointer to FPACC LSW
           LHI \HB\OLDPG1         ;** Set pointer to page of FPACC
           CAL OPLOAD             ;Transfer FPACC to FPOP
           CAL RESTHL             ;Recover original subroutine entry values for H & L
           JMP FLOAD              ;Transfer registers pointed to by H & L into the FPACC

                                  ;Subroutine to save the contents of CPU registers D, E, H
                                  ;and L in a temporary storage area in memory.

SAVEHL:    LAH                    ;Transfer value in H to ACC
           LBL                    ;And value in L to B
           LLI 200                ;Now set L to start of tempomry storage locations
           LHI \HB\OLDPG1         ;** And set H to storage area page
           LMA                    ;Save A (entry value of H) in memory
           INL                    ;Advance pointer
           LMB                    ;Save B (entry value of L) in memory
           INL                    ;Advance pointer
           LMD                    ;Save D in memory
           INL                    ;Advance pointer
           LME                    ;Save E in memory
           LHA                    ;Restore entry value of H
           LLB                    ;Restore entry value of L
           RET                    ;Exit to calling routine

                                  ;Subroutine to restore the contents of CPU registers D,
                                  ;E, H and L from temporary storage in memory.

RESTHL:    LLI 200                ;Set L to start of temporary storage locations
           LHI \HB\OLDPG1         ;** Set H to storage area page
           LAM                    ;Fetch stored value for li iii ACC
           INL                    ;Advance pointer
           LBM                    ;Fetch stored value for L into B
           INL                    ;Advance pointer
           LDM                    ;Fetch stored value for T.)
           INL                    ;Advance pointer
           LEM                    ;Fetch stored value for
           LHA                    ;Restore  saved value for H
           LLB                    ;Restore saved value for L
           LAM                    ;Leave stored value for E in ACC
           RET                    ;Exit to calling routine

                                  ;Subroutine to exchange the contents of H & L with
                                  ;D & E.

SWITCH:    LCH                    ;Transfer register H to C temporarily
           LHD                    ;Place value of D into H
           LDC                    ;Now put former H from C into D
           LCL                    ;Transfer register L to C temporarily
           LLE                    ;Place value of E into L
           LEC                    ;Now put former L from C into E
           RET                    ;Exit to calling routine
GETINP:    LHI \HB\OLDPG1         ;** Set H to page of GETINP character counter
           LLI 220                ;Set L to address of GETINP character counter
           LCM                    ;Load counter value into CPU register C
           INC                    ;Exercise the counter in order
           DCC                    ;To set CPU flags. If counter is non-zero, then indexing
           JFZ NOT0               ;Register (GETINP counter) is all set so jump ahead.
           LLE                    ;But, if counter zero, then starting to process a new
           LHD                    ;Character string. Transfer char string buffer pointer into
           LCM                    ;H & L and fetch the string's character count value (cc)
           INC                    ;Increment the (cc) by one to take account of (cc) byte
           CAL INDEXC             ;Add contents of regis C to H & L to point to end of the
           LMI 000                ;Character string in buffer and place a zero byte marker
NOT0:      LLI 220                ;Set L back to address of GETINP counter which is used
           LHI \HB\OLDPG1         ;** As an indexing value. Set H to correct page.
           LCM                    ;Fetch the value of GETINP counter into register C
           INC                    ;Increment the value in C
           LMC                    ;Restore the updated value for future use
           LLE                    ;Bring the base address of the character string buffer into
           LHD                    ;CPU registers H & L
           CAL INDEXC             ;Add contents of register C to form indexed address of
           LAM                    ;Next character to be fetched as input. Fetch the next
           NDA                    ;Character. Exercise the CPU flags.
           LHI \HB\OLDPG1         ;** Restore page pointer to floating point working area
           RFZ                    ;If character is non-zero, not end of string, exit to calle
           LLI 220                ;If zero character, must reset GETINP counter for next
           LMI 000                ;String. Reset pointer and clear GETINP counter to zero
           RET                    ;Then exit to calling routine

                                  ;Following subroutine causes register C to be used as an
                                  ;indexing register. Value in C is added to address in H
                                  ;and L to form new address.

INDEXC:    LAL                    ;Place value from register L into accumulator
           ADC                    ;Add quantity in register C
           LLA                    ;Restore updated value back to L
           RFC                    ;Exit to caller if no carry from addition
           INH                    ;But, if have carry then must increment register H
           RET                    ;Before returning to calling routine

                                  ;Main Decimal INPUT subroutine to convert strings of
                                  ;ASCII characters representing decimal fixed or floating
                                  ;point numbers to binary floating point numbers.

DINPUT:    LEL                    ;Save entry value of register L in E. (Pointer to buffer
           LDH                    ;Containing ASCII character string.) Do same for H to D.
           LHI \HB\OLDPG1         ;** Set H to page of floating point working registers
           LLI 150                ;Set L to start of decirnal-to-binary working area
           XRA                    ;Clear the accumulator
           LBI 010                ;Set up a loop counter
CLRNX2:    LMA                    ;Deposit zero in working area to initialize
           INL                    ;Advance the memory pointer
           DCB                    ;Decrement the loop counter
           JFZ CLRNX2             ;Clear working area until loop counter is zero
           LLI 103                ;Set pointer to floating point temporary registers and
           LBI 004                ;Indicators working area. Set up a loop counter.
CLRNX3:    LMA                    ;Deposit zero in working area to initialize
           INL                    ;Advance the memory pointer
           DCB                    ;Decrement the loop counter
           JFZ CLRNX3             ;Clear working area until loop counter is zero
           CAL GETINP             ;Fetch a character from the ASCII chax string buffer
           CPI 253                ;(Typically the SYMBOL/TOKEN buffer). See if it is
           JTZ NINPUT             ;Code for + sign. Jump ahead if code for + sign.
           CPI 255                ;See if code for minus (-) sign.
           JFZ NOTPLM             ;Jump ahead if not code for minus sign. If code for
           LLI 103                ;Minus sign, set pointer to MINUS flag storage location.
           LMA                    ;Set the MINUS flag to indicate a minus number
NINPUT:    CAL GETINP             ;Fetch another character from the ASCII char string
NOTPLM:    CPI 256                ;See if character represents a period (decimal point) in
           JTZ PERIOD             ;Input string. Jump ahead if yes.
           CPI 305                ;If not period, see if code for E as in Exponent
           JTZ FNDEXP             ;Jump ahead if yes.
           CPI 240                ;Else see if code for space.
           JTZ NINPUT             ;Ignore space character, go fetch another character.
           NDA                    ;If none of the above see if zero byte
           JTZ ENDINP             ;Indicating end of input char string. If yes, jumn ahead.
           CPI 260                ;If not end of string, check to see
           JTS NUMERR             ;If character represents
           CPI 272                ;A valid decimal number (0 to 9)
           JFS NUMERR             ;Display error message if not a valid digit at this point!
           LLI 156                ;For valid digit, set pointer to MSW of temporary
           LCA                    ;Decimal to binary holding registers. Save character in C.
           LAI 370                ;Form mask for sizing in accumulator. Now see if
           NDM                    ;Holding register has enough room for the conversion of
           JFZ NINPUT             ;Another digit. Ignore the input if no more room.
           LLI 105                ;If have room in register then set pointer to input digit
           LBM                    ;Counter location. Fetch the present value.
           INB                    ;Increment it to account for incoming digit.
           LMB                    ;Restore updated count to storage location.
           CAL DECBIN             ;Call the DECimal to BINary conversion routine to add
           JMP NINPUT             ;In the new digit in holding registers. Continue inputting.
PERIOD:    LBA                    ;Save character code in register B
           LLI 106                ;Set pointer to PERIOD indicator storage location
           LAM                    ;Fetch value in PERIOD indicator
           NDA                    ;Exercise CPU flags
           JFZ NUMERR             ;If already have a period then display error message
           LLI 105                ;If not, change pointer to digit counter storage location
           LMA                    ;Clear the digit counter back to zero
           INL                    ;Advance pointer to PERIOD indicator
           LMB                    ;Set the PERIOD indicator
           JMP NINPUT             ;Continue processing the input character string
FNDEXP:    CAL GETINP             ;Get next character in Exponent
           CPI 253                ;See if it is code for + sign
           JTZ EXPINP             ;Jump ahead if yes.
           CPI 255                ;If not + sign, see if minus sign
           JFZ NOEXPS             ;If not minus sign then jump ahead
           LLI 104                ;For minus sign, set pointer to EXP SIGN indicator
           LMA                    ;Set the EXP SIGN indicator for a minus exponent
EXPINP:    CAL GETINP             ;Fetch the next character in the decimal exponent
NOEXPS:    NDA                    ;Exercise the CPU flags
           JTZ ENDINP             ;If character inputted was zero, then end of input string
           CPI 260                ;If not end of string, check to see
           JTS NUMERR             ;If character represents
           CPI 272                ;A valid decimal number (0 to 9)
           JFS NUMERR             ;Display error message if not a valid digit at this point!
           NDI 017                ;Else trim the ASCII code to BCD
           LBA                    ;And save in register B
           LLI 157                ;Set pointer to input exponent storage location
           LAI 003                ;Set accumulator equal to three
           CPM                    ;See if any previous digit in exponent greater than three
           JTS NUMERR             ;Display error message if yes
           LCM                    ;Else save any previous value in register C
           LAM                    ;And also place any previous value in accumulator
           NDA                    ;Clear the carry bit with this instruction
           RAL                    ;Single precision multiply by ten algorithm
           RAL                    ;Two rotate lefts equals times four
           ADC                    ;Adding in the digit makes total times five
           RAL                    ;Rotating left again equals times ten
           ADB                    ;now add in digit just inputted
           LMA                    ;Restore the value to exponent storage location
           JMP EXPINP             ;Go get any additional exponent int)ut
ENDINP:    LLI 103                ;Set pointer to mantissa SIGN indicator
           LAM                    ;Fetch the SIGN indicator to the acclimulator
           NDA                    ;Exercise the CPU flags
           JTZ FININP             ;If SIGN indicator is zero, go finish up as nr is positive
           LLI 154                ;But, if indicator is non-zero, number is negative
           LBI 003                ;Set pntr to LSW of storage registers, set precision entr
           CAL COMPLM             ;Negate the triple-precision number in holding registers
FININP:    LLI 153                ;Set pointer to input storage LS~V minus one
           XRA                    ;Clear the accumulator
           LMA                    ;Clear the LSW minus one location
           LDH                    ;Set register D to floating point working page
           LEI 123                ;Set E to address of FPACC LSW minus one
           LBI 004                ;Set precision counter
           CAL MOVEIT             ;Move number from input register to FPACC
           CAL FPFLT              ;Now convert the binary fixed point to floating point
           LLI 104                ;Set pointer to Exponent SIGN indicator location
           LAM                    ;Fetch the value of the EXP SIGN indicator
           NDA                    ;Exercise the CPU flags
           LLI 157                ;Reset pointer to input exponent storage location
           JTZ POSEXP             ;If EXP SIGN indicator zero, exponent is positive
           LAM                    ;Else, exponent is negative so must negate
           XRI 377                ;The value in the input exponent storage location
           ADI 001                ;By performing this two's complement
           LMA                    ;Restore the negated value to exponent storage location
POSEXP:    LLI 106                ;Set pointer to PERIOD indicator storage location
           LAM                    ;Fetch the contents of the PERIOD indicator
           NDA                    ;Exercise the CPU flags
           JTZ EXPOK              ;If PERIOD indicator clear, no decimal point involved
           LLI 105                ;If have a decimal point, set pointer to digit counter
           XRA                    ;Storage location. Clear the accumulator.
           SUM                    ;And get a negated value of the digit counter in ACC
EXPOK:     LLI 157                ;Change pointer to input exponent storage location
           ADM                    ;Add this value to negated digit counter value
           LMA                    ;Restore new value to storage location
           JTS MINEXP             ;If new value is minus, skip over next subroutine
           RTZ                    ;If new value is zero, no further processing required

                                  ;Following subroutine will multiply the floating point
                                  ;binary number stored in FPACC by ten tirnes the
                                  ;value stored in the deciinal exponent storage location.

FPX10:     LLI 210                ;Set pointer to registers containing floating point
           LHI \HB\OLDPG1         ;** Binary representation of 10 (decimal).
           CAL FACXOP             ;Transfer FPACC to FPOP and 10 (dec) to FPACC
           CAL FPMULT             ;Multiply FPOP (formerly FPACC) by 10 (decimal)
           LLI 157                ;Set pointer to decimal exponent storage location
           LCM                    ;Fetch the exponent value
           DCC                    ;Decrement
           LMC                    ;Restore to storage
           JFZ FPX10              ;If exponent value is not zero, continue multiplication
           RET                    ;When exponent is zero can exit. Conversion completed.

                                  ;Following subroutine will multiply the floating point
                                  ;binary number stored in PPACC by 0.1 times the value
                                  ;(negative) stored in the decimal exponent storage location

MINEXP:
FPD10:     LLI 214                ;Set pointer to registers containing floating point
           LHI \HB\OLDPG1         ;** Binary representation of 0.1 (decimal).
           CAL FACXOP             ;Transfer FPACC to FPOP and 0.1 (dec) to FPACC
           CAL FPMULT             ;Multitply FPOP (formerly FPACC) by 0.1 (decimal)
           LLI 157                ;Set pointer to decimal exponent storage location
           LBM                    ;Fetch the exponent value
           INB                    ;Increment
           LMB                    ;Restore to storage
           JFZ FPD10              ;If exponent value is not zero, continue multiplication
           RET                    ;When exponent is zero can exit. Conversion completed.

                                  ;Following subroutine is used
                                  ;to convert decimal charac-
                                  ;ters to binary fixed point forinat
                                  ;in a triple-precision format.

DECBIN:    CAL SAVEHL             ;Save entry value of D, E, H and L in memory
           LLI 153                ;Set pointer to temporary storage location
           LAC                    ;Restore character inputted to accumulator
           NDI 017                ;Trim ASCII code to BCD
           LMA                    ;Store temporarily
           LEI 150                ;Set pointer to working area LSW of multi-byte register
           LLI 154                ;Set another pointer to LSW of conversion register
           LDH                    ;Make sure D set to page of working area
           LBI 003                ;Set precision counter
           CAL MOVEIT             ;Move original value of conversion register to working
           LLI 154                ;Register. Reset pointer to LSW of conversion register.
           LBI 003                ;Set precision counter
           CAL ROTATL             ;Rotate register left, (Multiplies value by two.)
           LLI 154                ;Reset pointer to LSW.
           LBI 003                ;Set precision counter
           CAL ROTATL             ;Multiply by two again (total now times four).
           LEI 154                ;Set pointer to LSW of conversion register.
           LLI 150                ;Set pointer to LSW of working register (original value).
           LBI 003                ;Set precision counter.
           CAL ADDER              ;Add original value to rotated value (now times five).
           LLI 154                ;Reset pointer to LSW
           LBI 003                ;Set precision counter
           CAL ROTATL             ;Multiply by two once more (total now times ten).
           LLI 152                ;Set pointer to clear working register locatiotis
           XRA                    ;Clear the accumulator
           LMA                    ;Clear MSW of working register
           DCL                    ;Decrement pointer
           LMA                    ;Clear next byte
           LLI 153                ;Set pointer to current digit storage location
           LAM                    ;Fetch the current digit
           LLI 150                ;Change pointer to LSW of working register
           LMA                    ;Deposit the current digit in LSW of working register
           LEI 154                ;Set pointer to conversion register LSW
           LBI 003                ;Set precision counter
           CAL ADDER              ;Add current digit to conversion register to complete
           JMP RESTHL             ;Conversion. Exit to caller by restoring CPU registers.
FPOUT:     LHI \HB\OLDPG1         ;** Set H to working area for floating point routines
           LLI 157                ;Set pointer to decimal exponent storage location
           LMI 000                ;Initialize storage location to zero
           LLI 126                ;Change pointer to FPACC (number to be outputted)
           LAM                    ;And fetch MSW of FPACC
           NDA                    ;Test the contents of MSW of FPACC
           JTS OUTNEG             ;If most significant bit of MSW is a one, have a minus nr.
           LAI 240                ;Else number is positive, set ASCII code for space for a
           JMP AHEAD1             ;Positive number and go display a space
OUTNEG:    LLI 124                ;If number in FPACC is negative must negate in order
           LBI 003                ;To display. Set pntr to LSW of FPACC & set prec. cntr.
           CAL COMPLM             ;Negate the number in the FPACC to make it positive
           LAI 255                ;But load ACC with ASCII code for minus sign
AHEAD1:    CAL ECHO               ;Call user display driver to output space or minus sign
           LLI 110                ;Set pointer to FIXED/FLOAT indicator
           LAM                    ;Fetch value of FIXED/FLOAT indicator
           NDA                    ;Test contents of indicator. If contents are zero, calling
           JTZ OUTFLT             ;Routine has directed floating point output format.
           LLI 127                ;If indicator non-zero, fixed point fonnat requested if
           LAI 027                ;Possible. Point to FPACC Exponent. Put 23 decimal in
           LBM                    ;Accumulator. Fetch FPACC Exponent into register B
           INB                    ;And exercise the register to test its
           DCB                    ;Original contents. If FPACC Exponent is negative in
           JTS OUTFLT             ;Value then go to floating point output forrnat. If value
           SUB                    ;Is positive, subtract value from 23 (decimal). If result
           JTS OUTFLT             ;Negative, number is too big to use fixed format.
           JMP OUTFIX             ;Else, can use fixed format so skip next routine
OUTFLT:    LLI 110                ;Set pointer to FIXED/FLOAT indicator.
           LMI 000                ;Clear indicator to indicate floating point output format
           LAI 260                ;Load ASCII code for '0' into accumulator
           CAL ECHO               ;Call user display driver to output '0' as first character
           LAI 256                ;Number string. Now load ASCII code for decimal point.
           CAL ECHO               ;Call user display driver to output '.'as second character.
OUTFIX:    LLI 127                ;Set pointer to FPACC Exponent
           LAI 377                ;Load accumulator with minus one
           ADM                    ;Add value in FPACC Exponent
           LMA                    ;Restore compensated exponent value

                                  ;Next portion of routine establishes the value for the
                                  ;decimal exponent that will be outputted by processing
                                  ;the binary exponent value in the FPACC.

DECEXT:    JFS DECEXD             ;If compensated exponent value is zero or positive
           LAI 004                ;Then go multiply FPACC by 0.1 (decimal). Else,
           ADM                    ;Add four to the exponent value.
           JFS DECOUT             ;If exponent now zero or positive, ready to output
           LLI 210                ;If exponent negative, multiply FPACC by 10 (decimal)
           LHI \HB\OLDPG1         ;** Set pointer to registers holding 10 (dec) in binary
           CAL FACXOP             ;Floating point format. Set up for multiplication.
           CAL FPMULT             ;Perform the multiplication. Answer in FPACC.
           LLI 157                ;Set pointer to decimal exponent storage location.
           LCM                    ;Each time the FPACC is multiplied by ten, need to
           DCC                    ;Decrement the value in the decinial exponent storage
           LMC                    ;Location. (This establishes decimal exponent value!)
DECREP:    LLI 127                ;Reset pointer to FPACC Exponent
           LAM                    ;Fetch value in exponent
           NDA                    ;Test value
           JMP DECEXT             ;Repeat process as required
DECEXD:    LLI 214                ;If exponent is positive, multiply FPACC by 0.1
           LHI \HB\OLDPG1         ;** Set pointer to registers holding 0.1 dec in binary
           CAL FACXOP             ;Floating point format. Set up for multipli(-ation.
           CAL FPMULT             ;Perform the multiplication. Answer in FPACC.
           LLI 157                ;Set pointer to decimal exponent storage location.
           LBM                    ;Each time the FPACC is multiplied by one tenth, need
           INB                    ;To increment the value in the decimal exponent storage
           LMB                    ;Location. (This establishes decimal exponent value!)
           JMP DECREP             ;Repeat process as required

                                  ;The next section outputs the mantissa
                                  ;(or fixed point number) by converting the value remaining
                                  ;in the FPACC (after the decimal exponent equivalent has
                                  ;been extracted from the original value if required by the
                                  ;previous routines) to a string of decirnal digits.
DECOUT:    LEI 164                ;Set pointer to LSW of output working register
           LDH                    ;Set D to same page value as H
           LLI 124                ;Set pointer to LSW of FPACC
           LBI 003                ;Set precision counter
           CAL MOVEIT             ;Move value in FPACC to output working register
           LLI 167                ;Set pointer to MSW plus one of output working register
           LMI 000                ;Clear that location to 0
           LLI 164                ;Set pointer to LSW of output working register
           LBI 003                ;Set precision counter
           CAL ROTATL             ;Rotate register left once to compensate for sign bit
           CAL OUTX10             ;Multiply output register by 10, overflow into N4SW+ 1
COMPEN:    LLI 127                ;Set pointer back to FPACC Exponent
           LBM                    ;Compensate for any remainder in the binary exponent
           INB                    ;By performing a rotate right on the output working
           LMB                    ;Register until the binary exponent becomes zero
           JTZ OUTDIG             ;Go output decimal digits when this loop is finished
           LLI 167                ;Binary exponent compensating loop. Setpointe'r to
           LBI 004                ;Working register MSW+L. Set precision counter.
           CAL ROTATR             ;Rotate working register to the right.
           JMP COMPEN             ;Repeat loop as required.
OUTDIG:    LLI 107                ;Set pointer to output digit counter storage location
           LMI 007                ;Initialize to value of seven
           LLI 167                ;Change pointer to output working register MSW+L
           LAM                    ;Fetch MSW+L byte containing BCD of digit to be
           NDA                    ;Displayed. Test the contents of this byte.
           JTZ ZERODG             ;If zero jump to ZERODG routine.
OUTDGS:    LLI 167                ;Reset pointer to working register MSW+L
           LAM                    ;Fetch BCD of digit to be outputted
           NDA                    ;Exercise CPU flags
           JFZ OUTDGX             ;If not zero, go display the digit
           LLI 110                ;If zero, change pointer to FIXED/FLOAT indicator
           LAM                    ;Fetch the indicator into the accumulator
           NDA                    ;Test value of indicator
           JTZ OUTZER             ;If in floating point mode, go display the digit
           LLI 157                ;Else change pointer to decimal exponent storage
           LCM                    ;Location, which, for fixed point, will have a positive
           DCC                    ;Value for all digits before the decimal point. Decrement
           INC                    ;And increment to exercise flags. See if count is positive.
           JFS OUTZER             ;If positive, must display any zero digit.
           LLI 166                ;If not, change pointer to MSW of working register
           LAM                    ;And test to see if any significant digits coming up
           NDI 340                ;By forming a mask and testing for presence of bits
           JFZ OUTZER             ;If more significant digits coming up soon, display the
           RET                    ;Zero digit. Else, exit to calling routine. Finished.
OUTZER:    XRA                    ;Clear the accumulator to restore zero digit value
OUTDGX:    ADI 260                ;Add 260 (octal) to BCD code in ACC to form ASCII
           CAL ECHO               ;Code and call the user's display driver subroutine
DECRDG:    LLI 110                ;Set pointer to FIXED/FLOAT indicator storage
           LAM                    ;Fetch the indicator to the accumulator
           NDA                    ;Exercise the CPU flags
           JFZ CKDECP             ;If indicator non-zero, doing fixed point output
           LLI 107                ;Else, get output digit counter
           LCM
           DCC                    ;Decrement the digit counter & restore to storage
           LMC
           JTZ EXPOUT             ;When digit counter is zero, go take care of exponent
PUSHIT:    CAL OUTX10             ;Else push next BCD digit out of working register
           JMP OUTDGS             ;And continue the outputting process
CKDECP:    LLI 157                ;For fixed point output, decimal exponent serves as
           LCM                    ;Counter for number of digits before decimal point
           DCC                    ;Fetch the counter and decrement it to account for
           LMC                    ;Current digit being processed. Restore to storage.
           JFZ NODECP             ;If count does not go to zero, jump ahead.
           LAI 256                ;When count reaches zero, load ASCII code for period
           CAL ECHO               ;And call user's display driver to display decimal point
NODECP:    LLI 107                ;Set pointer to output digit counter storage location
           LCM                    ;Fetch the digit counter
           DCC                    ;Decrement the value
           LMC                    ;Restore to storage
           RTZ                    ;If counter reaches zero, exit to caller. Finished.
           JMP PUSHIT             ;Else continue to output the number.
ZERODG:    LLI 157                ;If first digit of floating point number is a zero, set
           LCM                    ;Pointer to decimal exponent storage location.
           DCC                    ;Decrement the value to compensate for skipping
           LMC                    ;Display of first digit. Restore to storage.
           LLI 166                ;Change pointer to MSW of output working register
           LAM                    ;Fetch MSW of output working register
           NDA                    ;Test the contents
           JFZ DECRDG             ;If non-zero, continue outputting
           DCL                    ;Else decrement pointer to next byte in working register
           LAM                    ;Fetch its contents
           NDA                    ;Test
           JFZ DECRDG             ;If non-zero, continue outputting
           DCL                    ;Else decrement pointer to LSW of working register
           LAM                    ;Fetch its contents
           NDA                    ;Test
           JFZ DECRDG             ;If non-zero, continue outputting
           LLI 157                ;If decimal mantissa is zero, set pointer to decirnal
           LMA                    ;Exponent storage and clear it
           JMP DECRDG             ;Finish outputting

                                  ;Following routine multiplies the binary number in the
                                  ;output working register by ten to push the most signifi-
                                  ;cant digit out to the MSW+L byte.

OUTX10:    LLI 167                ;Set pointer to work ing register M SW+ 1
           LMI 000                ;Clear it in preparation for receiving next digit pushed
           LLI 164                ;Into it. Change pointer to working register LSW.
           LDH                    ;Set up register D to same page as H.
           LEI 160                ;Set second pointer to LSW of second working register
           LBI 004                ;Set precision counter
           CAL MOVEIT             ;Move first working register into second
           LLI 164                ;Reset pointer to LSW of first working register
           LBI 004                ;Set precision counter
           CAL ROTATL             ;Rotate contents of first working register left (X 2)
           LLI 164                ;Reset pointer to LSW
           LBI 004                ;Reset precision counter
           CAL ROTATL             ;Rotate contents left again (X 4)
           LLI 160                ;Set pointer to LSW of original value in 2'nd register
           LEI 164                ;Set pointer to LSW of rotated value
           LBI 004                ;Set precision counter
           CAL ADDER              ;Add rotated value to original value (X 5)
           LLI 164                ;Reset pointer to LSW of first working register
           LBI 004                ;Set precision counter
           CAL ROTATL             ;Rotate contents left again (X 10)
           RET                    ;Exit to calling routine

                                  ;The final group of routines in the floating point output
                                  ;section take care of outputting the decimal exponent
                                  ;portion of floating point numbers.

EXPOUT:    LLI 157                ;Set pointer to decimal exponent storage location
           LAM                    ;Fetch value to the accumulator
           NDA                    ;Test the value
           RTZ                    ;If zero, then no exponent portion. Exit to caller.
           LAI 305                ;Else, load ACC with ASCII code for letter E.
           CAL ECHO               ;Display E for Exponent via user's display driver rtn
           LAM                    ;Get decimal exponent value back into ACC
           NDA                    ;Test again
           JTS EXOUTN             ;If value is negative, skip ahead
           LAI 253                ;If positive, load ASCII code for + sign
           JMP AHEAD2             ;Jump to display the + sign
EXOUTN:    XRI 377                ;When decimal exponent is negative, must negate
           ADI 001                ;Value for display purposes. Perform two's complement
           LMA                    ;And restore the negated value to storage location
           LAI 255                ;Load ASCII code for minus sign
AHEAD2:    CAL ECHO               ;Display the ASCII character in ACC
           LBI 000                ;Clear register B
           LAM                    ;Fetch the decimal exponent value back into ACC
SUB12:     SUI 012                ;Subtract 10 (decimal) from value in ACC
           JTS TOMUCH             ;Break out of loop when accumulator goes negative
           LMA                    ;Else restore value to storage location
           INB                    ;Increment register B as a counter
           JMP SUB12              ;Repeat loop to form tens value of decimal exponent
TOMUCH:    LAI 260                ;Load base ASCII value for digit into the accumulator
           ADB                    ;Add to the count in B to forin tens digit of decimal
           CAL ECHO               ;Exponent. Display via user's driver subroutine
           LAM                    ;Fetch remainder of decimal exponent value
           ADI 260                ;Add in ASCII base value to form final digit
           CAL ECHO               ;Display second digit of decirnal exponent
           RET                    ;Finished outputting. Return to caller.
;;; The above RETURN SHOULD BE AT 25 367

;;; NOW OPEN AREA UP TO 26 000 CAN BE USED FOR PATCHING...

	ORG 026#000
	DATA 000		; CC FOR INPUT LINE BUFFER
	DATA *79 		; THE INPUT LINE BUFFER
	DATA 000,000,000,000	; THESE ARE SYMBOL BUFFER STORAGE
	DATA 000,000,000,000
	DATA 000,000,000,000	; SHOULD BE 26-120 TO 26 143
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000	; THESE LOCATIONS ARE AUXILIARY SYMBOL BUFFER
	DATA 000,000,000,000
	DATA 000,000,000,000	; SHOULD BE 26 144 TO 26 175
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000
	DATA 000		; TEMP SCAN STORAGE REGISTER
	DATA 000		; TAB FLAG
	DATA 000		; EVAL CURRENT TEMP REG.
	DATA 000		; SYNTAX LINE NUMBER
	DATA 000		; SCAN TEMPORARY REGISTER
	DATA 000		; STATEMENT TOKEN
	DATA 000,000		; TEMPORARY WORKING REGISTERS
	DATA 000,000		; ARRAY POINTERS
;;; NOW WE SHOULD BE UP TO 26 210
	DATA 000		; OPERATOR STACK POINTER
	DATA *15		; OPERATOR STACK
	DATA 000		; FUN/ARRAY STACK POINTER
	DATA *7			; FUNCTION/ARRAY STACK
;;; THE LAST BYTE SHOULD HAVE BEEN 26 237


	;; HEIRARCHY TABLE (FOR OUT OF STACK OPS)
	;; USED BY PARSER ROUTINE.
;;; This SHOULD START AT 26 240
	DATA 000		; EOS
	DATA 003		; PLUS SIGN
	DATA 003		; MINUS SIGN
	DATA 004		; MULTIPLICATION SIGN
	DATA 004		; DIVISION SIGN
	DATA 005		; EXPONENT SIGN
	DATA 006		; LEFT PARENTHESIS
	DATA 001		; RIGHT PARENTHESIS
	DATA 002		; NOT ASSIGNED
	DATA 002		; LESS THAN SIGN
	DATA 002		; Equal sign
	DATA 002		; GREATER THAN SIGN
	DATA 002		; LESS THAN OR EQUAL COMBO
	DATA 002		; EQUAL OR GREATER THAN
	DATA 002		; LESS THAN OR GREATER THAN

	;; HEIRARCHY TABLE (FOR INTO STACK OPS)
	;; USED BY PARSER ROUTINE.
;;; This SHOULD START AT 26 257
	DATA 000		; EOS
	DATA 003		; PLUS SIGN
	DATA 003		; MINUS SIGN
	DATA 004		; MULTIPLICATION SIGN
	DATA 004		; DIVISION SIGN
	DATA 005		; EXPONENTIATION SIGN
	DATA 001		; LEFT PARENTHESIS
	DATA 001		; RIGHT PARENTHESIS
	DATA 002		; NOT ASSIGNED
	DATA 002		; LESS THAN SIGN
	DATA 002		; EQUAL SIGN
	DATA 002		; GREATER THAN SIGN
	DATA 002		; LESS THAN OR EQUAL SIGN
	DATA 002		; EQUAL TO OR GREATER THAN
	DATA 002		; LESS THAN OR GREATER THAN

	DATA 000		; EVAL START POINTER
	DATA 000		; EVAL FINISH POINTER

	;; FUNCTION NAMES TABLE
;;; This SHOULD START AT 26 300
	DATA 3
	DATA "INT"
	DATA 3
	DATA "SGN"
	DATA 3
	DATA "ABS"
	DATA 3
	DATA "SQR"
	DATA 3
	DATA "TAB"
	DATA 3
	DATA "RND"
	DATA 3
	DATA "CHR"
	DATA 3
	DATA "UDF"

	DATA 000,000,000,000	; LINE NUMBER BUFFER STORAGE
	DATA 000,000,000,000	; (SHOULD BE 340-347)
	DATA 000,000,000,000	; AUX LINE NUMBER BUFFER
	DATA 000,000,000,000	; (SHOULD BE 350-357)
;;; The following data is a change in page 3 of Scelbal update issue 4
;;; which apparently makes the "INSERT" command work correctly, the
;;; first time (later SCR commands load 33 into this spot) 
	DATA 033 		; USER PGM LINE PTR (PG)
	DATA 000 		; USER PGM LINE PTR (LOW)
	DATA 000 		; AUX PGM LINE PTR (PG)
	DATA 000 		; AUX PGM LINE PTR (LOW)
	DATA 000 		; END OF USER PGM BUFFER PTR (PG)
	DATA 000 		; END OF USER PGM BUFFER PTR (LOW)
	DATA 000		; PARENTHESIS COUNTER (366)
	DATA 000		; QUOTE INDICATOR
	DATA 000		; TABLE COUNTER (370)
;;; locations 371-377 NOT ASSIGNED

	ORG 027#000
	DATA 3
	DATA "REM"
	DATA 2
	DATA "IF"
	DATA 3    ;MGA 3/31/12 Loboyko transcription error
	DATA "LET"
	DATA 4
	DATA "GOTO"
	DATA 5
	DATA "PRINT"
	DATA 5
	DATA "INPUT"
	DATA 3
	DATA "FOR"
	DATA 4
	DATA "NEXT"
	DATA 5
	DATA "GOSUB"
	DATA 6    ;MGA 4/12/12 another Loboyko transcription error
	DATA "RETURN"
	DATA 3
	DATA "DIM"
	DATA 3
	DATA "END"
	DATA 0			; END OF TABLE, SHOULD BE 072

	DATA 000		; GOSUB STACK POINTER
	DATA *1			; NOT ASSIGNED;
	DATA 000		; NUMBER OF ARRAYS COUNTER
	DATA 000		; ARRAY POINTER
	DATA 000		; VARIABLES COUNTER SHOULD BE 077
	DATA 000,000,000,000	; USED AS THE GOSUB STACK 100-117
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000	; USED AS ARRAY VARIABLES TABLE
	DATA 000,000,000,000	; SHOULD BE 120-137
	DATA 000,000,000,000
	DATA 000,000,000,000

	DATA 000,000,000,000	; USED FOR FOR/NEXT STACK STORAGE
	DATA 000,000,000,000	; SHOULD BE 140 TO 177
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000,000,000,000
	DATA 000		; FOR/NEXT STACK POINTER
	DATA 000		; ARRAY/VARIABLE FLAG
	DATA 000  		; STOSYM COUNTER
	DATA 000		; FUN/ARRAY STACK POINTER (203
	DATA 000		; ARRAY VALUES POINTER
	DATA *3			; NOT USED (SHOULD BE 205-207)
	DATA 000		; USED AS VARIABLES SYMBOL TABLE
	DATA *119		; (SHOULD BE 211-377 RESERVED)
;;; The above should cover 211 to 377
	;; THERE ARE NOW ADDRESSES AT START OF PAGE 30, NOT ASSIGNED;


;;; The following is PATCH NR.1
	ORG 030#000
PATCH1:	LLI 123
	LMI 000
	LLI 133
	LMI 000
	RET

	
	
	ORG 030#013
	
NEXT:      LLI 144                ;Load L with start of AUX SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Set H to page of AUX SYMBOL BUFFER
           LMI 000                ;Initialize AUX SYMBOL BUFFER by clearing first byte
           LLI 202                ;Change L to address of SCAN pointer
           LBM                    ;Fetch pointer value to CPU register B
           INB                    ;Add one to the current pointer value
           LLI 201                ;Load L with address of NEXT pointer storage location
           LMB                    ;Place the updated SCAN pointer as the NEXT pointer
NEXT1:     LLI 201                ;Reset L to address of NEXT pointer storage location
           CAL GETCHR             ;Fetch the character pointed to by the NEXT pointer
           JTZ NEXT2              ;If the character is a space, ignore it
           LLI 144                ;Else, load L with start of AUX SYMBOL BUFFER
           CAL CONCT1             ;Concatenate the character onto the AUX SYMBOL BF
NEXT2:     LLI 201                ;Reset L to address of NEXT pointer storage location
           CAL LOOP               ;Advance the NEXT pointer and see if end of line
           JFZ NEXT1              ;Fetch next character in line if not end of line
           LLI 144                ;When reach end of line, should have variable name
           LAM                    ;In the AUX SYMBOL BUFFER. Fetch the (cc) for
           CPI 001                ;The buffer and see if variable name is just one letter
           JFZ NEXT3              ;If more than one proceed directly to look for name
           LLI 146                ;In FOR/NEXT STACK. If have just a one letter name
           LMI 000                ;Then set second character in buffer to zero
NEXT3:     LLI 205                ;Load L with address of FOR/NEXT STACK pointer
           LHI \HB\OLDPG27        ;** Set H to page of FOR/NEXT STACK pointer
           LAM                    ;Fetch the FOR/NEXT STACK pointer value to ACC
           RLC                    ;Rotate value left to multiply by two. Then rotate it
           RLC                    ;Left again to multiply by four. Add base address plus
           ADI 136                ;Two to form pointer to variable name in top of stack
           LHI \HB\OLDPG27        ;** Set H to page of FOR/NEXT STACK
           LLA                    ;Move pointer value from ACC to CPU register L
           LDI \HB\OLDPG26        ;** Set register D to page of AUX SYMBOL BUFFER
           LEI 145                ;Set register E to first character in the buffer
           LBI 002                ;Set B to serve as a character counter
           CAL STRCPC             ;See if variable name in the NEXT statement same as
           JTZ NEXT4              ;That stored in the top of the FOR/NEXT STACK
FORNXT:    LAI 306                ;Load ACC with ASCII code for letter F
           LCI 316                ;Load register C with ASCII code for letter N
           JMP ERROR              ;Display For/Next (FN) error message if required
NEXT4:     LLI 360                ;Load L with address of user program line pointer
           LHI \HB\OLDPG26        ;** Load H with page of user pgm line pntr storage loc.
           LDM                    ;Fetch the page portion of the line pointer into D
           INL                    ;Advance the memory pointer
           LEM                    ;Fetch the low portion of the line pointer into E
           INL                    ;Advance pntr to AUXILIARY LINE POINTER storage
           LMD                    ;Location and store value of line pointer there too (page)
           INL                    ;Advance pointer to second byte of AUXILIARY line
           LME                    ;Pointer and store value of line pointer (low portion)
           LLI 205                ;Load L with address of FOR/NEXT STACK pointer
           LHI \HB\OLDPG27        ;** Set H to page of FOR/NEXT STACK pointer
           LAM                    ;Fetch the FOR/NEXT STACK pointer value to ACC
           RLC                    ;Rotate value left to multiply by two. Then rotate it
           RLC                    ;Left again to multiply by four. Add base address to
           ADI 134                ;Form pointer to top of FOR/NEXT STACK and place
           LLA                    ;The pointer value into CPU register L. Fetch the page
           LDM                    ;Address of the associated FOR statement line pointer
           INL                    ;Into register D. Advance the pointer and fetch the low
           LEM                    ;Address value into register E. Prepare to change user
           LLI 360                ;Program line pointer to the FOR statement line by
           LHI \HB\OLDPG26        ;** Setting H & L to the user pgrn line pntr storage loc.
           LMD                    ;Place the page value in the pointer storage location
           INL                    ;Advance the memory pointer
           LME                    ;Place the low value in the pointer storage location
           LHD                    ;Now set up H and L to point to the start of the
           LLE                    ;Associated FOR statement line in the user pgm buffer
           LDI \HB\OLDPG26        ;** Change D to point to the line input buffer
           LEI 000                ;And set L to the gtart of the line input buffer
           CAL MOVEC              ;Move the associated FOR statement line into the input
           LLI 325                ;Line buffer. Set L to point to start of TO string which is
           LHI \HB\OLDPG1         ;** Stored in a text strings storage area on this page
           CAL INSTR              ;Search the statement line for the occurrence of TO
           LAE                    ;Register E will be zero if TO not found. Move E to ACC
           NDA                    ;To make a test. If TO found then proceed to set up for
           JTZ FORNXT             ;Evaluation. If TO not found, then have error condition.
           ADI 002                ;Advance the pointer over the characters in TO string
           LLI 276                ;Change L to point to EVAL pointer storage location
           LHI \HB\OLDPG26        ;** Set H to page of EVAL pointer. Set up the starting
           LMA                    ;Position for the EVAL subroutine (after TO string)
           LLI 330                ;Set L to point to start of STEP string which is stored
           LHI \HB\OLDPG1         ;** In text stxings storage area on this page. Search the
           CAL INSTR              ;Statement line for the occurrence of STEP
           LAE                    ;Register E will be zero if STEP not found. Move E to
           NDA                    ;The accumulator to make a test. If STEP found must
           JFZ NEXT5              ;Evaluate expression after STEP to get STEP SIZE.
           LLI 004                ;Else, have an IMPLIED STEP SIZE of 1.0. Set pointer
           LHI \HB\OLDPG1         ;** To start of storage area for 1.0 in floating point
           CAL FLOAD              ;Format and call subroutine to load FPACC with 1.0
           LLI 304                ;Set L to start of FOR/NEXT STEP SIZE storage loc.
           CAL FSTORE             ;Store the value 1.0 in the F/N STEP SIZE registers
           LLI 000                ;Change L to the start of the input line buffer
           LHI \HB\OLDPG26        ;** Set H to the page of the input line buffer
           LBM                    ;Fetch the (cc) into CPU register B (length of FOR line)
           LLI 277                ;Change L to EVAL FINISH pointer stomge location
           LMB                    ;Set the EVAL FINISH pointer to the end of the line
           CAL EVAL               ;Evaluate the LIMIT expression to obtain FOR LIMIT
           LLI 310                ;Load L with address of start of F/N LIMIT registers
           LHI \HB\OLDPG1         ;** Load H with page of FOR/NEXT LIMIT registers
           CAL FSTORE  ;MGA 3/31/12 no lab here Store the FOR/NEXT LIMIT value
           JMP NEXT6              ;Since have IMPLIED STEP jump ahead
NEXT5:     DCE  ;MGA 3/21/12 lab here When have STEP directive, subtract one from pointer
           LLI 277                ;To get to character before S in STEP. Save this value in
           LHI \HB\OLDPG26        ;** The EVAL FINISH pointer stomge location to serve
           LME                    ;As evaluation end location when obtaining TO Iiinit
           CAL EVAL               ;Evaluate the LIMIT expression to obtain FOR LIMIT
           LLI 310                ;Load L with address of start of FIN LIMIT registers
           LHI \HB\OLDPG1         ;** Load H with page of FORINEXT LIMIT registers
           CAL FSTORE             ;Store the FOR/NEXT LIMIT value
           LLI 277                ;Reset L to EVAL FINISH pointer storage location
           LHI \HB\OLDPG26        ;** Set H to page of EVAL FINISH pointer storage loc.
           LAM                    ;Fetch the pointer value (character before S in STEP)
           ADI 005                ;Add five to change pointer to character after P in STEP
           DCL                    ;Decrement L to point to EVAL (start) pointer
           LMA                    ;Set up the starting position for the EVAL subroutine
           LLI 000                ; Load L with starting address of the line input buffer
           LBM                    ;Fetch the (cc) for the line input buffer (line length)
           LLI 277                ;Change L to the EVAL FINISH storage location
           LMB                    ;Set the EVAL FINISH pointer
           CAL EVAL               ;Evaluate the STEP SIZE expression
           LLI 304                ;Load L with address of start of F/N STEP registers
           LHI \HB\OLDPG1         ;** Set H to page of FIN STEP registers
           CAL FSTORE             ;Store the FOR/NEXT STEP SIZE value
NEXT6:     LLI 144                ;Load L with address of AUX SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Set H to page of the AUX SYMBOL BUFFER
           LMI 000                ;Initialize AUX SUMBOL BUFFER with a zero byte
           LLI 034                ;Set L to start of FOR string which is stored in the
           LHI \HB\OLDPG27        ;** KEYWORD look-up table on this page
           CAL INSTR              ;Search the statement line for the FOR directive
           LAE                    ;Register E will be zero if FOR not found. Move E to
           NDA                    ;ACC and -make test to see if FOR directive located
           LLI 202                ;Load L with address of SCAN pointer
           LHI \HB\OLDPG26        ;** Load H with page of SCAN pointer
           LMA                    ;Set up pointer to occurrence of FOR directive in line
           JTZ FORNXT             ;If FOR not found, have an error condition
           ADI 003                ;If have FOR, add three to advance pointer over FOR
           LLI 203                ;Set L to point to F/N pointer storage location
           LMA                    ;Set F/N pointer to character after FOR directive
NEXT7:     LLI 203                ;Set L to point to FIN pointer storage location
           CAL GETCHR             ;Fetch a character from position pointed to by FIN pntr
           JTZ NEXT8              ;If character is a space, ignore it
           CPI 275                ;Else, test to see if character is "=" sign
           JTZ NEXT9              ;If yes, have picked up variable name, jump ahead
           LLI 144                ;If not, set L to the start of the AUX SYMBOL BUFFER
           CAL CONCT1             ;And store the character in the AUX SYMBOL BUFFER
NEXT8:     LLI 203                ;Load L with address of the F/N pointer
           CAL LOOP               ;Increment the pointer and see if end of the line
           JFZ NEXT7              ;If not, continue fetching characters
           JMP FORNXT             ;If end of line before "=" sign then have error condx
NEXT9:     LLI 202                ;Load L with address of SCAN pointer
           LHI \HB\OLDPG26        ;** Load H with page of SCAN pointer
           LAM                    ;Fetch pointer value to ACC (points to start of FOR
           ADI 003                ;Directive) and add three to move pointer over FOR
           LLI 276                ;Directive. Change L to EVAL pointer storage location
           LMA                    ;Set EVAL pointer to character after FOR in line
           LLI 203                ;Load L with address of FIN pointer storage location
           LBM                    ;Fetch pointer to register B (points to "=" sign) and
           DCB                    ;Decrement the pointer (to character before "=" sign)
           LLI 277                ;Load L with address of EVAL FINISH pointer
           LMB                    ;Set EVAL FINISH pointer
           CAL EVAL               ;Call subroutine to obtain current value of the variable
           LLI 304                ;Load L with address of start of F/N STEP registers
           LHI \HB\OLDPG1         ;** Set H to page of F/N STEP registers
           CAL FACXOP             ;Call subroutine to set up FP registers for addition
           CAL FPADD              ;Add FIN STEP size to current VARIABLE value
           LLI 314                ;Load L with address of FIN TEMP storage registers
           LHI \HB\OLDPG1         ;**Set H to page of FIN TEMP storage registers
           CAL FSTORE             ;Save the result of the addition in F/N TEMP registers
           LLI 310                ;Load L with starting address of F/N LIMIT registers
           CAL FACXOP             ;Call subroutine to set up FP registers for subtraction
           CAL FPSUB              ;Subtract F/N LIMIT value from VARIABLE value
           LLI 306                ;Set pointer to MSW of F/N STEP registers
           LAM                    ;Fetch this value into the ACC
           NDA                    ;Test to see if STEP value might be zero
           LLI 126                ;Load L with address of MSW of FPACC
           LAM                    ;Fetch this value into the ACC
           JTZ FORNXT             ;If STEP size was zero, then endless loop, an error condx
           JTS NEXT11             ;If STEP size less than zero make alternate test on limit
           NDA                    ;Test the contents of the MSW of the FPACC
           JTS NEXT12             ;Continue FORINEXT loop if current variable value is
           JTZ NEXT12             ;Less than or equal to the F/N LIMIT value
NEXT10:    LLI 363                ;If out of LIMIT range, load L with address of the AUX
           LHI \HB\OLDPG26        ;** PGM LINE pointer. (Contains pointer to the NEXT
           LEM                    ;Statement line that initiated this routine.) Fetch the
           DCL                    ;Low part of the address into E, decrement the memory
           LDM                    ;And get the page part of the address into CPU register
           DCL                    ;Decrement memory pointer to the low portion of the
           LME                    ;User pgm buffer line pointer (regular pointer) and set it
           DCL                    ;With the value from the AUX line pntr, decrement the
           LMD                    ;Pointer and do the same for the page portion
           LLI 205                ;Set L to address of FOR/NEXT STACK pointer
           LHI \HB\OLDPG27        ;** Set H to page of FOR/NEXT STACK pointer
           LBM                    ;Fetch and decrement the
           DCB                    ;FOR/NEXT STACK pointer value
           LMB                    ;To perform effective popping operation
           JMP NXTLIN             ;Statement line after NEXT statement is done next
NEXT11:    NDA                    ;When F/N STEP is negative, reverse test so that if the
           JFS NEXT12             ;Variable value is greater than or equal to the F/N LIMIT
           JMP NEXT10             ;The FOR/NEXT loop continues. Else it is finished.
NEXT12:    LLI 314                ;Load L with address of FIN TEMP storage registers
           LHI \HB\OLDPG1         ;** Set H to FIN TEMP storage registers page
           CAL FLOAD              ;Transfer the updated variable value to the FPACC
           CAL RESTSY             ;Restore the variable name and value
           CAL STOSYM             ;In the VARIABLES table. Exit routine so that
           JMP NXTLIN             ;Statement line after FOR statement is done next

;;; The label BACKSP SHOULD BE AT 31 217

BACKSP:    LAI 215                ;Load ASCII code for carriage-return into the ACC
           CAL ECHO               ;Display the carriage-return
           CAL ECHO               ;Repeat to provide extra time if TTY
           LLI 043                ;Load L with address of COLUMN COUNTER
           LHI \HB\OLDPG1         ;** Set H to page of COLUMN COUNTER
           LMI 001                ;Set COLUMN COUNTER to first column
           LLI 124                ;Set L to address containing desired TAB position
           LAM                    ;Fetch the desired TAB position value
           NDA                    ;Test to see if it is
           RTS                    ;Negative or zero
           RTZ                    ;In which case return to caller
           JMP TAB1               ;Else, proceed to perform the TAB operation.

	
;;; The label FOR5 SHOULD START AT 31 246
	
FOR5:      LLI 205                ;Load L with address of the FOR/NEXT STACK pointer
           LHI \HB\OLDPG27        ;** Load H with page of the FOR/NEXT STACK pntr
           LAM                    ;Fetch the stack pointer to the ACC.
           RLC                    ;Rotate it left to multiply by two, then rotate it again to
           RLC                    ;Multiply by four. Add this value to the base address
           ADI 136                ;Plus two of the base address to point to the next part of
           LEA                    ;The FOR/NEXT STACK. Place this value in register E.
           LDH                    ;Set D to the FORINEXT STACK area page.
           LLI 145                ;Load L with the address of the first character in the
           LHI \HB\OLDPG26        ;** AUX SYMBOL BUFFER and set up H to this page.
           LBI 002                ;Set up register B as a number of bytes to move counter.
           CAL MOVEIT             ;Move the variable name into the FOR/NEXT STACK.
           CAL STOSYM             ;Store initial variable value in the VARIABLES TABLE.
           JMP NXTLIN             ;Continue with next line in user program buffer.


;;; The label PARSEP SHOULD START AT 31 300
PARSEP:    LLI 176                ;Load L with PARSER TOKEN storage location. Set
           LMI 000                ;The value indicating end of expression. Call the
           CAL PARSER             ;PARSER subroutine for final time for the expression.
           LLI 227                ;Change L to point to the ARITH STACK pointer.
           LHI \HB\OLDPG1         ;** Set H to the page of the ARITH STACK pointer.
           LAM                    ;Fetch the ARITH STACK pointer value.
           CPI 230                ;Should indicate only one value (answer) in stack.
           RTZ                    ;Exit with answer in FPACC if ARITH STACK is O.K.
           JMP SYNERR             ;Else have a syntax error!
	
	
;;; THERE IS SOME BLANK ADDRESSES HERE 317-NEXT PAGE
	

	ORG 032#000
SQRX:      LLI 014                ;Load L with address of FP TEMP registers
           LHI \HB\OLDPG1         ;** Set H to page of FP TEMP. Move contents of FPACC
           CAL FSTORE             ;[Argument of SQR(X)] into FP TEMP for storage.
           LLI 126                ;Load L with MSW of FPACC
           LAM                    ;Fetch the MSW into the accumulator
           NDA                    ;Check the sign of the number in the FPACC
           JTS SQRERR             ;If number negative, cannot take square root
           JTZ CFALSE             ;If number is zero, return with zero value in FPACC
           LLI 017                ;Load L with address of FP TEMP Exponent register
           LAM                    ;Fetch the Exponent value into the ACC
           NDA                    ;Check sign of the Fxponent
           JTS NEGEXP             ;If Exponent less than zero, process negative Exponent
           RAR                    ;If Exponent positive, rotate right to divide by two
           LBA                    ;And save the result in CPU register B
           LAI 000                ;Clear the accumulator without disturbing Carry bit
           RAL                    ;Rotate Carry bit into the ACC to save remainder
           LMA                    ;Store the remainder back in FP TEMP Exponent reg.
           JMP SQREXP             ;Jump to continue processing
NEGEXP:    LBA                    ;For negative Exponent, form two Is complement by
           XRA                    ;Placing the positive value in CPU register B, clearing
           SUB                    ;The accumulator, and then subtracting B from the ACC
           NDA                    ;Clear the Carry bit after the complementing operation
           RAR                    ;Rotate the value right to divide by two
           LBA                    ;Save the result in CPU register B
           LAI 000                ;Clear the accumulator without disturbing Carry bit
           ACA                    ;Add Carry bit to the accumulator as remainder
           LMA                    ;Store the remainder back in FP TEMP Exponent reg
           JTZ NOREMD             ;If remainder was zero skip ahead. If not, increment the
           INB                    ;Result of the divide by two ops to compen for negative
NOREMD:    XRA                    ;Clear the accumulator
           SUB                    ;Subtract the quotient of the divide by two op to
           LBA                    ;Form two's complement and save the result in register B
SQREXP:    LLI 013                ;Load L with address of TEMP register
           LMB                    ;Store Fxponent quotient from above ops in TEMP
           LLI 004                ;Load L with address of FP registers containing +1.0
           LEI 034                ;Load E with address of SQR APPROX working registers
           LDH                    ;Set D to same page as H
           LBI 004                ;Set up register B as a number of bytes to move counter
           CAL MOVEIT             ;Transfer value +1.0 into SQR APPROX registers
           CAL CFALSE             ;Now clear the FPACC registers
           LLI 044                ;Load L with address of LAST SQR APPROX temp regs.
           CAL FSTORE             ;Initialize the LAST SQR APPROX regs to value of zero
SQRLOP:    LLI 034                ;Load L with address of SQR APPROX working registers
           CAL FLOAD              ;Transfer SQR APPROX into the FPACC
           LLI 014                ;Load L with address of SQR ARG storage registers
           CAL OPLOAD             ;Transfer SQR ARG into the FPOP
           CAL FPDIV              ;Divde SQR ARG by SQR APPROX (Fon-n X/A)
           LLI 034                ;Load L with address of SQR APPROX registers
           CAL OPLOAD             ;Transfer SQR APPROX into the FPOP
           CAL FPADD              ;Add to form value (X/A + A)
           LLI 127                ;Load L with address of FPACC Exponent register
           LBM                    ;Fetch Exponent value into CPU register B
           DCB                    ;Subtract one to effectively divide FPACC by two
           LMB                    ;Restore to memory. (Now have ((X/A + A) /2)
           LLI 034                ;Load L with address of SQR APPROX registers
           CAL FSTORE             ;Store contents of FPACC as new SQR APPROX
           LLI 044                ;Load L with address of LAST SQR APPROX registers
           CAL OPLOAD             ;Transfer LAST SQR APPROX into the FPOP
           CAL FPSUB              ;Subtract (LAST SQR APPROX - SQR APPROX)
           LLI 127                ;Load L with address of FPACC Exponent
           LAM                    ;Fetch the Exponent into the accumulator
           CPI 367                ;See if difference less than 2 to the minus ninth
;;; The below is changed for PATCH 2
;;; following is the original code
;;;           JTS SQRCNV             ;If so, approximation has converged
;;; Now is the new line
	   JMP PATCH2
;;;;           DCL
;;;;           LAM
;;;;           NDA
;;;;           JTZ SQRCNV             ;THIS IS PATCH #2
SQR1:	   LLI 034                ;Else, load L with address of SQR APPROX
           LDH                    ;Set D to same page as H
           LEI 044                ;And E with address of LAST SQR APPROX
           LBI 004                ;Set up register B as a number of bytes to move counter
           CAL MOVEIT             ;Transfer SQR APPROX into LAST SQR APPROX
           JMP SQRLOP             ;Continue ops until approximation converges
SQRCNV:    LLI 013                ;Load L with address of TEMP register. Fetch the
           LAM                    ;Exponenent quotient store there into accumulator.
           LLI 037                ;Change L to point to SQR APPROX exponent.
           ADM                    ;Add SQR APPROX exponent to quotient value.
           LMA                    ;Store sum back in SQR APPROX Exponent register.
           LLI 034                ;Load L with address of SQR APPROX. Transfer the
           JMP FLOAD              ;SQR APPROX into FPACC as answer and exit.
SQRERR:    LAI 323                ;Load ASCII code for letter S into the accumulator.
           LCI 321                ;Load ASCII code for letter Q into CPU register C.
           JMP ERROR              ;Display the SQuare root (SQ) error message.
;;; above instruction starts at 223
;;; some blank addresses available here.
	ORG 032#240
RNDX:      LLI 064                ;Load L with address of SEED storage registers
           LHI \HB\OLDPG1         ;** Set H to page for floating point working registers
           CAL FLOAD              ;Transfer SEED into the FPACC
           LLI 050                ;Load L with address of random constant A
           CAL OPLOAD             ;Transfer random constant A into the FPOP
           CAL FPMULT             ;Multiply to form (SEED * A)
           LLI 060                ;Load L with address of random constant C
           CAL OPLOAD             ;Transfer random constant C into the FPOP
           CAL FPADD              ;Add to fom (SEED * A) + C
           LLI 064                ;Load L with address of SEED storage registers
           CAL FSTORE             ;Store I (SEED * A) + C] in former SEED registers
           LLI 127                ;Load L with address of FPACC Exponent register
           LAM                    ;Fetch Exponent value into the accumulator
           SUI 020                ;Subtract 16 (decimal) to effectively divide by 65,536
           LMA                    ;Now FPACC = [((SEED * A) + C)/65,536]
           CAL FPFIX              ;Convert floating to fixed point to obtain integer part
           LLI 123                ;Load L with address of FPACC Extension register
           LMI 000                ;Clear the FPACC Extension register
           LLI 127                ;Load L with address of FPACC Exponent
           LMI 000                ;Clear the FPACC Exponent register
           CAL FPFLT              ;Fetch INT(((SEED * A) + C)/65,536) into the FPACC
           LLI 127                ;Load L with address of FPACC Exponent
           LAM                    ;Fetch FPACC Exponent into the accumulator
           ADI 020                ;Add 16 (decimal) to effectively multiply by 65,536
           LMA                    ;(65,536 * INT[ ((SEED * A) + C)/65,5361) in FPACC
           LLI 064                ;Load L with address of [(SEED * A) + C]
           CAL OPLOAD             ;Transfer it into FPOP. Subtract FPACC to form
           CAL FPSUB              ;[(SEED * A) + C] MOD 65,536
           LLI 064                ;Load L with address of former SEED registers
           CAL FSTORE             ;Store SEED MOD 65,536 in place of [(SEED * A) + Cl
           LLI 127                ;Load L with address of FPACC Exponent
           LAM                    ;Fetch FPACC Exponent into the ACC and subtract
           SUI 020                ;16 (decimal) to form (SEED MOD 65,536)/65,536
           LMA                    ;So that random number in FPACC is between
           RET                    ;0.0 and +1.0 and exit to calling routine
;;; THE ABOVE RETURN SHOULD BE 32 351
	

;;; NOTE OPEN ADDRESSES TO END OF PAGE 32

;;; following is PATCH 2
	ORG 032#364
PATCH2:	JTS SQRCNV
	DCL
	LAM
	NDA
	JTZ SQRCNV
	JMP SQR1
;;; The above jump should start at 32 375
	

	;; PAGES 33 TO REMAINDER OF MEMORY
	;; OR START OF OPTIONAL ARRAY HANDLING
	;; ROUTINES USED AS USER PROGRAM BUFFER



	;; OPTIONAL ARRAY ROUTINES ASSEMBLED FOR OPERATION
	;; IN THE UPPER 3 PAGES OF A 12K SYSTEM ARE LISTED HERE.

	ORG 055#000
	
PRIGH1:    LLI 126                ;Load L with address of the MSW in the FPACC
           LHI \HB\OLDPG1         ;** Set H to page of FPACC
           LAM                    ;Fetch MSW of FPACC into the ACC.
           NDA                    ;Test to see if value in FPACC is positive.
           JTS OUTRNG             ;If not, go display error message.
           CAL FPFIX              ;If O.K. then convert floating point to fixed point
           LLI 124                ;Load L with address of LSAL of converted value
           LAM                    ;Fetch the LSW of the value into the ACC
           SUI 001                ;Subtract one from the value to establish proper
           RLC                    ;Origin for future ops. Now rotate the value twice
           RLC                    ;To effectively multiply by four. Save the
           LCA                    ;Calculated result in CPU register C
           LLI 203                ;Load L with address of F/A STACK TEMP
           LHI \HB\OLDPG27        ;** Load H with page of F/A STACK TEMP
           LAM                    ;Fetch the value into the accumulator
           XRI 377                ;Complement the value
           RLC                    ;Rotate the value twice to multiply by four (the number
           RLC                    ;Of bytes per entry in the ARRAY VARIABLES table).
           ADI 120                ;Add the starting address of the ARRAY VARIABLES
           LHI \HB\OLDPG27        ;** TABLE to forin pointer. Set page address in H.
           LLA                    ;Point to the name in the ARRAY VARIABLES
           INL                    ;Increment the pointer value twice to move over the
           INL                    ;Name in the table and point to starting address for the
           LAM                    ;Array values in the ARRAY VALUES table. Fetch this
           ADC                    ;Address to the ACC. Now add in the figure calculated
           LLA                    ;To reach desired subscripted data storage location. Set
           LHI \HB\OLDPG57        ;tt The pointer to that location. Load the floating point
           JMP FLOAD              ;Value stored there into the FPACC and exit to caller.
	
	
;;; The label FUNAR2 SHOULD START AT 55-054
FUNAR2:    LLI 202                ;Load L with address of TEMP COUNTER
           LHI \HB\OLDPG27        ;** Load H with page of counter
           LBM                    ;Fetch the counter value
           INB                    ;Increment the value
           LMB                    ;Restore the value to memory
           LCI 002                ;Initialize register C to a value of two for future ops
           LLI 114                ;Load L with address of start of ARRAY VARIABLES
           LHI \HB\OLDPG27        ;** TABLE (less four). Set H to page of the table.
           CAL TABADR             ;Calculate address of start of next narne in table.
           LDI \HB\OLDPG26        ;** Load D with page of the SYMBOL BUFFER
           LEI 120                ;Set E to starting address of the SYMBOL BUFFER
           CAL STRCP              ;Compare name in ARRAY VARIABLES table to the
           JTZ FUNAR3             ;Contents of the SYMBOL BUFFER. If match, go set up
           LLI 202                ;Array token value. Else, reset L to address of TEMP
           LHI \HB\OLDPG27        ;** COUNTER. Set H to page of TEMP COUNTER.
           LAM                    ;Fetch the counter value into the accumulator.
           LLI 075                ;Change L to number of arrays storage location.
           CPM                    ;Compare number of entries checked against number
           JFZ FUNAR2             ;Possible. Keep searching table if not finished.
           JMP FAERR              ;If finished and no match than have F/A error condx.
FUNAR3:    LLI 202                ;Load L with address of TEMP COUNTER
           LHI \HB\OLDPG27        ;** Load H with page of counter.
           XRA                    ;Clear the accumulator. Subtract the value in the TEMP
           SBM                    ;COUNTER from zero to obtain two's complement.
           LMA                    ;Place this back in counter location as ARRAY TOKEN
           JMP FUNAR4             ;VALUE (negative). Go place the value on F/A STACK.
	

;;; The label OUTRNG STARTS AT 55 136
OUTRNG:    LAI 317                ;Load the ASCII code for letter 0 into the accumulator
           LCI 322                ;Load the ASCII code for letter R into register C
           JMP ERROR              ;Go display Out of Range (OR) error message.
	


	
ARRAY:     CAL RESTSY             ;Transfer contents of AUX SYMBOL BUFFER into the
           JMP ARRAY2             ;SYMBOL BUFFER. (Entry when have actual LET)
ARRAY1:    LLI 202                ;Load L with address of SCAN pointer
           JMP ARRAY3             ;Proceed to process. (Entry point for IMPLIED LET)
ARRAY2:    LLI 203                ;Load L with address of LET pointer
ARRAY3:    LHI \HB\OLDPG26        ;** Set H to pointer page
           LBM                    ;Fetch pointer to location where "(" found in statement
           INB                    ;Line. Increment it to point to next character in the line.
           LLI 276                ;Load L with address of EVAL pointer and load it with
           LMB                    ;The starting address for the EVAL routine
           LLI 206                ;Change L to address of ARRAY SETUP pointer
           LMB                    ;And also store address in that location
ARRAY4:    LLI 206                ;Load L with address of ARRAY SETUP pointer
           CAL GETCHR             ;Fetch character pointed to by ARRAY SETUP pntr
           CPI 251                ;See if character is ")" ? If so, then have located
           JTZ ARRAY5             ;End of the subscript. If not, reset
           LLI 206                ;to the ARRAY SETUP pointer. Increment the
           CAL LOOP               ;Pointer and test for the end of the statement line.
           JFZ ARRAY4             ;If not end of line, continue looking for right paren.
           LAI 301                ;If reach end of line before right parenthesis than load
           LCI 306                ;ASCII code for letters A and F and display message
           JMP ERROR              ;Indicating Array Forrnat (AF) error condition
ARRAY5:    LLI 206                ;Load L with address of ARRAY SETUP pointer
           LBM                    ;Fetch pointer (pointing to ")"sign) into register B
           DCB                    ;Decrement it to move back to end of subscript number
           LLI 277                ;Load L with address of EVAL FINISH pointer location
           LMB                    ;Place the pointer value in the EVAL FINISH pointer
           LLI 207                ;Load L with address of LOOP COUNTER
           LMI 000                ;Initialize LOOP COUNTER to value of zero
ARRAY6:    LLI 207                ;Load L with address of LOOP COUNTER
           LHI \HB\OLDPG26        ;** Load H with page of LOOP COUNTER
           LBM                    ;Fetch the counter value
           INB                    ;Increment it
           LMB                    ;Restore the counter value to memory
           LCI 002                ;Set up counter in register C for future ops
           LLI 114                ;Load L with address of start of ARRAY VARIABLES
           LHI \HB\OLDPG27        ;** Table less four). Set H to page of the table.
           CAL TABADR             ;Calculate the address of next entry in the table
           LEI 120                ;Load register E with starting address of SYMBOL BUFF
           LDI \HB\OLDPG26        ;** Set D to page of SYMBOL BUFFER
           CAL STRCP              ;Compare entry in table against contents of SYMBOL BF
           JTZ ARRAY7             ;If match, have found array naine in the table.
           LLI 207                ;Else, set L to address of the LOOP COUNTER
           LHI \HB\OLDPG26        ;** Set H to page of the LOOP COUNTER
           LAM                    ;Fetch the counter value to the ACC
           LLI 075                ;Change L to the counter containing number of arrays
           LHI \HB\OLDPG27        ;** Set H to the proper page
           CPM                    ;Compare number of arrays to count in LOOP CNTR
           JFZ ARRAY6             ;If more entries in the table, continue looking for match
           JMP FAERR              ;If no matching name in table then have an error condx.
ARRAY7:    CAL EVAL               ;Call subroutine to evaluate subscript expression
           CAL FPFIX              ;Convert the subscript value obtained to fixed forrnat
           LLI 207                ;Load L with address of LOOP COUNTER
           LHI \HB\OLDPG26        ;** Set H to page of the LOOP COUNTER
           LBM                    ;Fetch the value in the LOOP COUNTER into the ACC
           LCI 002                ;Set up counter in register C future ops
           LLI 114                ;Load L with address of ARRAY VARIABLES
           LHI \HB\OLDPG27        ;** Table less four). Set H to page of the table.
           CAL TABADR             ;Calculate the address of entry in the table
           INL                    ;Advance the ARRAY VARIABLES table pointer twice
           INL                    ;To advance pointer over array name.
           LCM                    ;Fetch array base address in ARRAY VALUES table
           LLI 124                ;Load L with address of subscript value
           LHI \HB\OLDPG1         ;** Set H to page of subscript value
           LAM                    ;Fetch the subscript value into the accumulator
           SUI 001                ;Subtract one from subscript value to allow for zero
           RLC                    ;Origin. Now multiply by four
           RLC                    ;Using rotates (number of bytes required for each entry
           ADC                    ;In the ARRAY VALUES table). Add in base address to
           LLI 204                ;The calculated value to form final address in the
           LHI \HB\OLDPG27        ;** ARRAY VALUES table. Now set H & L to TEMP
           LMA                    ;ARRAY ELEMENT storage location & store the addr.
           LLI 201                ;Change L to point to ARRAY FLAG
           LMI 377                ;Set the ARRAY FLAG for future use
           RET                    ;Exit to calling routine

	
;;; The label DIM SHOULD START AT 55 365
DIM:       CAL CLESYM             ;Initialize the SYMBOL BUFFER to cleared condition
           LLI 202                ;Load L with address of SCAN pointer
           LBM                    ;Fetch SCAN pointer value into register B
           INB                    ;Add one to the SCAN pointer value
           LLI 203                ;Change L to DIM pointer (formerly TOKEN) storage
           LMB                    ;Store the updated SCAN pointer as the DIM pointer
DIM1:      LLI 203                ;Load L with the address of DIM pointer storage location
           CAL GETCHR             ;Fetch a character from the line input buffer
           JTZ DIM2               ;If character fetched is a space, ignore it
           CPI 250                ;Else see if character is "(" left parenthesis
           JTZ DIM3               ;If so, should have ARRAY VARIABLE naine in buffer
           CAL CONCTS             ;If not, append the character to the SYMBOL BUFFER
DIM2:      LLI 203                ;Load L with the address of DIM pointer stomge location
           CAL LOOP               ;Increment the pointer and see if end of line
           JFZ DIM1               ;If not end of line, fetch next character
           JMP DIMERR             ;Else have a DIMension error condition
DIM3:      LLI 206                ;Load L with address of ARRAY pointer storage loc
           LMI 000                ;Initialize ARRAY pointer to starting value of zero
DIM4:      LLI 206                ;Load L with address of ARRAY pointer storage loc
           LHI \HB\OLDPG26        ;** Set H to page of ARRAY pointer storage location
           LAM                    ;Fetch value in ARRAY pointer to ACC (effectively
           RLC                    ;Represents number of arrays defined in pgm). Rotate
           RLC                    ;Left twice to multiply by four (niunber of bytes per
           ADI 114                ;entry in ARRAY VARIABLES table). Add to base
           LHI \HB\OLDPG27        ;** Address to form pointer to ARRAY VARIA.BLES
           LLA                    ;Table and set up H & L as the memory pointer.
           LEI 120                ;Load E with starting address of the SYMBOL BUFFER
           LDI \HB\OLDPG26        ;** Load D with the page address of the SYMBOL BUFF
           CAL STRCP              ;Compare contents of SYMBOL BF to entry in ARRAY
           JTZ DIM9               ;VARIABLES table. If same, have duplicate array name.
           LLI 206                ;Else, load L with address of ARRAY pointer storage
           LHI \HB\OLDPG26        ;** Load H with page of ARRAY pointer storage
           LBM                    ;Fetch the ARRAY pointer value to register B
           INB                    ;Increment the value
           LMB                    ;Restore it to ARRAY pointer storage location
           LLI 075                ;Change L to number of arrays storage location
           LHI \HB\OLDPG27        ;** Set H to page of the number of arrays stomge loc
           LAM                    ;Fetch the number of arrays value to the ACC
           DCB                    ;Restore B to previous count
           CPB                    ;Compare number of arrays tested against nr defined
           JFZ DIM4               ;If not equal, continue searching ARRAY VARIABLES
           LLI 075                ;Table. When table searched with no match, then must
           LHI \HB\OLDPG27        ;** Append naine to table. First set pointer to number
           LBM                    ;Of arrays storage location. Fetch that value and
           INB                    ;Add one to account for new name being added.
           LMB                    ;Restore the updated value back to memory.
           LLI 076                ;Change pointer to ARRAY TEMP pointer storage
           LMB                    ;Store pointer to current array in ARRAY TEMP too.
           LLI 206                ;Load L with address of ARRAY pointer stomge loc.
           LHI \HB\OLDPG26        ;** Set H to page of ARRAY pointer storage location
           LMB                    ;And update it also for new array being added.
           LAM                    ;Fetch the current ARRAY pointer value to the ACC
           RLC                    ;Multiply it times four by performing two rotate left
           RLC                    ;Operations and add it to base value to form address in
           ADI 114                ;The ARRAY VARIABLES table. Place the low part
           LEA                    ;Of this calculated address value into register E.
           LDI \HB\OLDPG27        ;** Set register D to the page of the table.
           LLI 120                ;Load L with the start of the SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Load H with the page of the SYMBOL BUFFER
           CAL MOVEC              ;Move the array name from the SYMBOL BUFFER to
           CAL CLESYM             ;The ARRAY VARIABLES table. Then clear the
           LLI 203                ;SYMBOL BUFFER. Reset L to the DIM pointer storage
           LHI \HB\OLDPG26        ;** Location. Set H to the DIM pointer page.
           LBM                    ;Fetch the pointer value (points to "(" part of DIM
           INB                    ;Statement). Increment the pointer to next character in
           LLI 204                ;The line input buffer. Cbange L to DIMEN pointer.
           LMB                    ;Store the updated DIM pointer in DIMEN storage loc.
DIM5:      LLI 204                ;Set L to DIMEN pointer storage location
           CAL GETCHR             ;Fetch character in line input buffer
           JTZ DIM6               ;Ignore character for space
           CPI 251                ;If not space, see if character is right parenthesis
           JTZ DIM7               ;If yes, process DIMension size (array length)
           CPI 260                ;If not, see if character is a valid decimal number
           JTS DIMERR             ;If not valid number, have DIMension error condition
           CPI 272                ;Continue testing for valid decitnal number
           JFS DIMERR             ;If not valid number, then DIMension error condition
           CAL CONCTS             ;If valid decirnal number, append digit to SYMBOL BF
DIM6:      LLI 204                ;Set L to DIMEN pointer storage location
           CAL LOOP               ;Advance the pointer value and check for end of the line
           JFZ DIM5               ;If not end of line, continue fetching DIMension size
           JMP DIMERR             ;If end of line before right parenthesis, have error condx.
DIM7:      LLI 120                ;Load L with address of start of SYMBOL BUFFER
           LHI \HB\OLDPG26        ;** Load H with page of SYMBOL BUFFER. (Now
           CAL DINPUT             ;Contains DIMension size.) Convert buffer to floating
           CAL FPFIX              ;Point number and then reformat to fixed point.
           LLI 124                ;Load L with address of LSW of fixed point number
           LAM                    ; And fetch the low order byte of the nr into the ACC
           RLC                    ;Rotate it left two tirnes to multiply it by four (the
           RLC                    ;Number of bytes required to store a floating point nr).
           LCA                    ;Store this value in CPU register C temporarily
           LLI 076                ;Set L to ARRAY TEMP storage location.
           LHI \HB\OLDPG27        ;** Set H to ARRAY TEMP pointer page.
           LAM                    ;Fetch the value in ARRAY TEMP (points to ARRAY
           SUI 001                ;VARIABLES table). Subtract one from the pointer
           RLC                    ;Value and multiply the result by four using rotate left
           RLC                    ;Instructions. Add this value to a base address
           ADI 122                ;(Augmented by two) to point to ARRAY VALUES
           LLA                    ;Pointer storage location in the ARRAY VARIABLES
           LHI \HB\OLDPG27        ;Table and set the pointer up in registers H & L.
           LBM                    ;Fetch the starting address in the ARRAY VALUES
           ADI 004                ;Table for the previous array into register B. Now add
           LLA                    ;Four to the ARRAY VARIABLES table pointer to
           LAB                    ;Point to curront ARRAY VALUES starting address.
           ADC                    ;Add the previous array starting address plus number of
           LMA                    ;Bytes required and store as starting loc for next array
DIM8:      LLI 204                ;Set L to address of DIMEN pointer storage location
           LHI \HB\OLDPG26        ;** Set H to page of DIMEN pointer
           LBM                    ;Fetch pointer value (points to ") " in line)
           LLI 203                ;Change L to DIM pointer storage location
           LMB                    ;Store former DIMEN value back in DIM pointer
DIM9:      LLI 203                ;Load L with address of DIM pointer storage location
           CAL GETCHR             ;Fetch a character from the line input buffer
           CPI 254                ;See if character is a comma (,) sign
           JTZ DIM10              ;If yes, have another array being defined on the line
           LLI 203                ;If not, reset L to the DIM pointer
           CAL LOOP               ;Increment the pointer and see if end of the line
           JFZ DIM9               ;If not end of the line, keep looking for a comma
           JMP NXTLIN             ;Else exit the DIM statement routine to continue pgm
DIM10:     LLI 203                ;Set L to DIM pointer storage location
           LBM                    ;Fetch pointer value (points to comma sign just found)
           LLI 202                ;Load L with address of SCAN pointer storage location
           LMB                    ;Place DIM pointer into the-SCAN pointer
           JMP DIM                ;Continue processing DIM statement line for next array
DIMERR:    LAI 304                ;On error condition, load ASCII code for letter D in ACC
           LCI 305                ;And ASCII code for letter E in CPU register C
           JMP ERROR              ;Go display the Dirnension Error (DE) message.

	




