perm filename IO.PAL[V,VDS]1 blob sn#264833 filedate 1977-02-15 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	.TITLE IO
C00003 00003	"TYPSTR"  - TELETYPE OUTPUT ROUTINE
C00006 00004	"INSTR" - TELETYPE INPUT ROUTINE
C00009 00005	"RNUM" - STRING TO SCALED INTEGER NUMBER CONVERSION
C00016 00006	"PNUM" - PRINTS A SCALED INTEGER AS A REAL NUMBER
C00020 00007	"CLRCMA"&"PRTCMA"
C00022 ENDMK
C⊗;
.TITLE IO

;CONSOLE TELETYPE INTEFACE LOCATIONS

TTYIS	=177560	
TTYIR	=177562	
TTYOS	=177564	
TTYOR	=177566	
;"TYPSTR"  - TELETYPE OUTPUT ROUTINE

;"TYPSTR" OUTPUTS A STRING ENDING WITH A NULL CHARACTER.  A POINTER TO
;THE START OF THE STRING MUST BE LOADED INTO THE SP REGISTER.  NO
;OTHER REGISTERS ARE AFFECTED.

TYPSTR:	MOV	R0,-(SP)
	MOVB	(SG)+,R0	;FIRST BYTE OF THE STRING
TSLOOP:	JSR	PC,TYPCHR	;TYPE THIS CHARACTER
	MOVB	(SG)+,R0	;NEXT BYTE
	BNE	TSLOOP		;REPEAT TILL END OF THE STRING
	MOV	(SP)+,R0
	RTS	PC

TYPCHR:	TSTB	@#TTYOS		;TTY AVAILABLE?
	BPL	TYPCHR		;NO, BUSY WAIT
	MOVB	R0,@#TTYOR	;YES, SEND OFF THE CHARACTER
	CMP	#12,R0		;WAS IT A LINE FEED?
	BNE	TYPRET		;IF NOT THAT CODE, THEN DONE
	CLR	R0		;OUTPUT 3 NULLS
	JSR	PC,TYPCHR
 	JSR	PC,TYPCHR
	JSR	PC,TYPCHR
TYPRET:	RTS	PC


;"LINOUT" TYPES A ASC STRING OF CHARACTERS ON TO THE TELETYPE.  THE
;ASC STRING IS A ASSUME TO END WITH A NULL CHARACTER.  A CR/LF IS
;ADDED TO THE END OF THE STRING DURING TYPE OUT.

LINOUT:	JSR	PC,TYPSTR
	MOV	#CRLFX,SG
	JSR	PC,TYPSTR
	RTS	PC


;"CRLF" IS A SUBROUTINE FOR TYPING OUT ONE CARRIAGE RETURN AND LINE
;FEED ON THE TELETYPE.

CRLF:	MOV	#CRLFX,SG
	JSR	PC,TYPSTR
	RTS	PC
CRLFX:	.BYTE	15,12,0,0


;"NULLS" PRINTS OUT A SERIES OF NULL CHARACTERS THAT SERVES
;AS A LEADER FOR PUNCHED PAPER TAPES.

NULLS:	MOV	R0,-(SP)
	MOV	R1,-(SP)
	MOV	#80.,R1		;PUNCH THIS MANY NULLS
	CLR	R0
	JSR	PC,TYPCHR	;PUNCH A NULL
	SOB	R1,.-4
	MOV	(SP)+,R1
	MOV	(SP)+,R0
	RTS	PC

;END OF OUTPUT ROUTINES
;"INSTR" - TELETYPE INPUT ROUTINE

;THE STRING BYTE POINTER MUST BE IN SG.  A CARRIAGE RETURN IS ASSUMED
;TO BE THE ACTIVATION CHARACTER.  A RUB OUT IS A DELETING BACKSPACE
;CHARACTER.  AT THE COMPLETION OF THIS ROUTINE, A NULL CHARACTER IS
;PLACED IN THE INPUT STRING.  SG IS LEFT UNCHANGED

;REGISTERS USED:
;
;	SG PASSES THE ARGUMENT AND IS NOT MODIFIED

INSTR:	MOV	SG,-(SP)
	MOV	R0,-(SP)
	CLR	@#CCNT		;RESET CHARACTER COUNT
IN2:	INCB	@#TTYIS		;START PAPER TAPE READER IF NEC.
	TSTB	@#TTYIS		;TTY READY?
	BPL	.-4
	MOVB	@#TTYIR,R0	;GET A CHARACTER
	BIC	#177600,R0	;MASK OFF - MAKE IT 7 BITS
	CMP	R0,#177		;BACK SPACE?
	BNE	IN3		;BRANCH IF NOT
	TST	@#CCNT		;CANT DO ANYTHING IF NO CHARACTERS
	BEQ	IN2		;BRANCH IF CANT COMPLY
	DEC	SG		;REMOVE LAST CHARACTER FROM BUFFER
	DEC	@#CCNT
	MOV	#134,R0		;TYPE \ TO INDICATE RUB OUT
	BR	IN4
IN3:	CMP	R0,#15		;C/R?
	BEQ	IN5		;TERMINATE IF ITS A CR
	CMP	R0,#40		;LEGAL CHARACTER?
	BLT	IN2		;IGNOR IT IS ITS NOT LEGAL
	MOVB	R0,(SG)+	;ELSE SAVE THE CHARACTER
	INC	@#CCNT		;INCREMENT CHARACTER COUNT
IN4:	TSTB	@#TTYOS		;ECHO
	BPL	.-4
	MOVB	R0,@#TTYOR
	BR	IN2
IN5:	MOVB	R0,(SG)+	;END OF STRING, PUT IN A CR
	CLRB	(SG) 		;PUT IN A NULL CHARACTER
	JSR	PC,CRLF		;TYPE CR/LF
	MOV	(SP)+,R0
	MOV	(SP)+,SG
	RTS	PC
CCNT:	0

;END OF "INSTR"
;"RNUM" - STRING TO SCALED INTEGER NUMBER CONVERSION

;THIS ROUTINE CONVERTS A REAL NUMBER STRING OF THE FORM SIII.DDD INTO
;A SCALED INTEGER.  "S" IS AN OPTIONAL SIGN CHARACTER, III IS THE
;INTEGER FIELD, AND DDD IS THE DECIMAL FRACTION FIELD.  THE LENGTH OF
;EACH FIELD IS VARIABLE AND EITHER THE INTEGER OF FRACTIONAL FIELD CAN
;BE OMITTED.  IF THE FRACTIONAL FIELD IS MISSING, THE DECIMAL POINT
;NEED NOT BE TYPED.  LEADING SPACE CHARACTERS ARE IGNORED AND SCANNING
;CONTINUES UNTIL AN UNEXPECTED CHARACTER IS ENCOUNTERED.  AFTER THE
;NUMBER IS READ IN, IT IS CONVERTED TO A SINGLE 16 BIT INTEGER NUMBER
;ACCORDING TO THE FOLLOWING FORMULA:
;
;	INTEGER NUMBER ← (NUMBER*10↑X*2↑14)/SCALE
;   WHERE 
;	X ← 5 - (MAX. # OF INTEGER DIGITS ANY NUMBER CAN HAVE)
;	SCALE ← INTEGER(LARGEST NUMBER TO READ IN*10↑X)/2
;
;THERE ARE SEVERAL ENTRIES POINTS INTO THIS PROGRAM.  IT ENTRY POINTS
;SETS UP "X" AND "SCALE" TO HANDLE A PARTICULAR TYPE OF NUMBER.  A
;TYPICAL CALLING SEQUENCE FOLLOWS:
;
;		MOV	#STRING,SG	;POINT TO ASC STRING
;		JSR	PC,GETINT	;DECODE A INTEGER NUMBER
;		BCS	ERROR		;BRANCH IF NUMBER TOO LARGE OR
;					;  NO NUMBER FOUND
;		MOV	R0,NUMBER
;
;IF THE INPUT STRING IS INVALID, THE C BIT IS SET AND R1 IS RETURNED 
;NON-ZERO.  IF NO NUMBER WAS ENCOUNTERED, THE C BIT IS SET AND R1 IS
;ZERO.  OTHERWISE THE C BIT IS CLEARED.  SG IS LEFT POINTING AT THE
;FIRST CHARACTER FOLLOWING THE NUMBER.

;REGISTERS USED:
;	SG, R0, R1  PASS ARGUMENTS AND ARE ALTERED

;MULTIPLE ENTRY POINTS

GETANG:	MOV	#2,-(SP)	;ANGLES:  -360 ≤ THETA < 360
	MOV	#18000.,-(SP)
	BR	RNUM

GETDIS:	MOV	#3,-(SP)	;DISTANCES -32 ≤ D < 32
	MOV	#16000.,-(SP)
	BR	RNUM

GETINT:	CLR	-(SP)		;INTEGERS '100000 ≤ INT ≤ 77777
	MOV	#40000,-(SP)
	
;START OF MAIN PROGRAM

RNUM:	MOV	R3,-(SP)	;SAVE REGISTERS
	MOV	R2,-(SP)
	CLR	-(SP)		;INDICATE NO NUMBER ENCOUNTERED YET
	CLR	R0    		;ACCUMULATE NUMBER IN HERE
	CLR	R1

;SCAN PAST LEADING ZEROS AND CHECK FOR SIGN CHARACTER

CHKSP:	MOVB	(SG)+,R2	;PICK UP A CHARACTER
	CMP	#40,R2		;IGNOR SPACE CHARACTERS
	BEQ	CHKSP
	CMP	#53,R2		;IGNOR "+"
	BEQ	FNDSGN
	CMP	#55,R2		;"-"?
	BNE	CHKZRO 		;BRANCH IF NOT
	NEG 	6(SP)   	;ELSE COMPLEMENT SCALE FACTOR
FNDSGN:	MOVB	#BADNUM,(SP)	;INDICATE SIGN ENCOUNTERED
SKPZRO:	MOVB	(SG)+,R2	;SKIP OVER LEADING ZEROS
CHKZRO:	CMP	#60,R2
	BNE	.+10
	MOV	#BADNUM+400,(SP);INDICATE DIGIT ENCOUNTERED
	BR	SKPZRO

;CHECK IF CHARACTER IS A DIGIT

	MOV	#6,R3		;5-X IS THE # OF INT. DIG. TO READ
	SUB	10(SP),R3
	BR	.+4
CHKDG: 	MOVB	(SG)+,R2	;GET THE NEXT CHARACTER
       	CMP 	R2,#60		;COMPARE TO ASC ZERO
	BLT	CHKDP		;BRANCH IF OUT OF RANGE
	CMP	R2,#71		;COMPARE TO ASC 9
	BGT	CHKDP
	JSR	PC,ADDDIG	;ACCUMULATE SUM
	MOV	#BADNUM+400,(SP);INDICATE DIGIT ENCOUNTERED
	SOB	R3,CHKDG	
	BR	BADSYN		;BRANCH IF TOO MANY INTEGERS READ IN

;CHECK IF THE CHARACTER IS A DECIMAL POINT AND PICK UP FRACTION PART

CHKDP:	MOV	10(SP),R3	;GET X
      	CMP	#56,R2		;"."?
	BNE	NORM		;SKIP IF NOT D.P.
	MOVB	#BADNUM,(SP)	;INDICATE D.P. ENCOUNTERED
GETFC:	MOVB	(SG)+,R2	;GET NEXT CHARACTER
	CMP	R2,#60		;BRANCH IF NOT A DIGIT
	BLT	NORM
	CMP	R2,#71
	BGT	NORM
	MOV	#BADNUM+400,(SP);INDICATE DIGIT ENCOUNTERED
	DEC	R3		;IGNOR IF ALREADY READ IN FRACTION
	BMI	GETFC
	JSR	PC,ADDDIG	;ACCUMULATE SUM
	BR	GETFC

;EXIT IF NO NUMBER ENCOUNTERED, ELSE NORMALIZE AND SCALE

NORM:	TSTB	1(SP)		;CHECK IF ANY NUMBERS ENCOUNTERED
	BEQ	BADSYN		;BRANCH IF NONE FOUND
	TST	R3		;BRANCH IF NUMBER ALREADY NORMALIZED
	BLE	SCALIT
NORMIT:	MOV	#60,R2		;ELSE SUM ← SUM*10+0
	JSR	PC,ADDDIG
	SOB	R3,NORMIT
SCALIT:	ASHC	#14.,R0		;SUM ← SUM*2↑14
	DIV	6(SP),R0	;SUM ← SUM/SCALE
	BVC	RNUMDN		;EXIT CLEANLY IF NO ERROR

;EXIT SEQUENCE

BADSYN:	SEC			;INDICATE SOME TYPE OF ERROR
RNUMDN:	MOVB	(SP)+,R1	;THIS IS PART OF THE ERROR CODE
	MOV	(SP)+,R2
	MOV	(SP)+,R3
	BIT	(SP)+,(SP)+	;CLEAR X AND SCALE OFF STACK
	DEC	SG		;ADJUST STRING POINTER
	RTS	PC

;SUBR TO ADD ANOTHER DIGIT TO THE ACCUMULATED SUM IN R0,R1

ADDDIG:	ASHC	#1,R0		;SUM*2
	MOV	R0,-(SP)	;SAVE IT
	MOV	R1,-(SP)
	ASHC	#2,R0		;SUM*8
	ADD	(SP)+,R1	;SUM*8+SUM*2
	ADC	R0
	ADD	(SP)+,R0
	BIC	#60,R2		;MASK OUT ASC BASE OF NEW DIGIT
	ADD	R2,R1		;SUM*10+NEW DIGIT
	ADC	R0
	RTS	PC


;END OF "RNUM"
;"PNUM" - PRINTS A SCALED INTEGER AS A REAL NUMBER

;PERFORMS THE REVERSE OPERATION OF RNUM.  A TYPICAL CALLING SEQUENCE
;TO ONE OF THE MULTIPLY ENTRY POINTS FOLLOWS:
;
;		MOV	NUMBER,R0	;SCALED INTEGER
;		MOV	#STRING,SG	;PUT CONVERTED STRING IN HERE
;		JSR	PC,PUTINT
;
;AFTER CONVERSION, THE STRING POINTER IS LEFT POINTING AT A NULL
;CHARACTER WHICH FOLLOWS THE FINAL CHARACTER OF THE CONVERTED
;NUMBER.

;REGISTERS USED:
;	R0, SG PASS ARGUMENTS AND R0,R1,SG ARE ALTERED

;MULTIPLE ENTRY POINTS

PRTANG:	MOV	#18000.,R1	;ANGLES
	MOV	#2-6,-(SP)
	BR	PNUM

PRTDIS:	MOV	#16000.,R1	;DISTANCES
	MOV	#3-6,-(SP)
	BR	PNUM

PRTINT:	MOV	#40000,R1
	MOV	#0-6,-(SP)

;START OF MAIN PROGRAM

PNUM:	MOV	R2,-(SP)	;SAVE REGISTERS
	MOV	R3,-(SP)
	MOV	#-60,-(SP)	;THIS + ASC 0 = NULL CHARACTER
	MOV	#60,R3		;ASSUME NUMBER POSITIVE
	MUL	R1,R0		;SCALE NUMBER UP
	BGE	NUMPOS		;SKIP IF NUMBER > 0
	MOV	#55,R3		;ELSE SAVE NEGATIVE SIGN
	COM	R0		;ABS(NUMBER)
	NEG	R1
	BCS	.+4
	INC	R0
NUMPOS:	ADD	#20000,R1	;ROUND OFF
	ADC	R0
        ASHC	#-14.,R0	;NORMALIZE
	MOV	#4,R2		;4 DECIMAL DIGITS + 1
DIVLP:	DIV	#10.,R0
	MOV	R1,-(SP)	;LEAST SIGNIFICANT DIGIT
	MOV	R0,R1		;POSITION FOR NEXT DIVISION
	CLR	R0
	SOB	R2,DIVLP
	MOV	#6,R0		;COUNT TO PRINT 5 DIGITS AND NULL
	MOV	16(SP),R2	;GET X
	BR	.+4		;FORM COMPLETE STRING
POPTHM:	MOV	(SP)+,R1	;GET BACK A DIGIT
	INC	R2		;BUMP UP INTEGER DIGIT COUNT
	BCS	CHKDCM		;BRANCH IF SIGN ALREADY PRINTED
	BEQ	SETSGN		;GO PRINT SIGN BEFORE DECIMAL PT
	TST	R1		
	BNE	.+10  
	MOVB	#40,(SG)+
	BR	NXTDG
	BIC	#20,R3		;SPACE=+ OR - BEFORE 1ST DIGIT
SETSGN:	MOVB	R3,(SG)+	;SIGN CHARACTER
	TST	R2		;TIME TO PRINT DEC. PT?
CHKDCM:	BNE	.+6
	MOVB	#56,(SG)+	;SEND OFF DECIMAL POINT
	ADD	#60,R1		;ADD ASC BASE TO NUMBER AND SEND OFF
	MOVB	R1,(SG)+
	SEC			;INDICATE SIGN PRINTED
NXTDG:	SOB	R0,POPTHM
	MOV	(SP)+,R3	;RESTORE REGISTERS
	MOV	(SP)+,R2
	TST	(SP)+      	;CLEAR X OFF STACK
	DEC	SG		;POINT TO NULL CHARACTER
	RTS	PC

;END OF "PNUM"
;"CLRCMA"&"PRTCMA"

;"CLRCMA" CAN BE CALLED FOLLOWING A STRING SCANNING ROUTINE TO ADJUST
;THE STRING POINTER IN SG TO SKIP OVER COMMA CHARACTERS WHICH ARE 
;USED TO SEPARATE NUMBERS.  SG MUST BE POINTING AT THE INPUT STRING.
;IF ANY CHARACTER OTHER THAN A SPACE OR C/R IS ENCOUNTERED BEFORE THE
;COMMA, THE C BIT IS SET, SG IS LEFT POINTING AT THE OFFENDING
;CHARACTER AND AN ERROR CODE IS SET IN R1.

CLRCMA:	CMPB	#40,(SG)+	;IGNOR LEADING SPACE CHARACTERS
	BEQ	.-4
	CMPB	#15,-(SG)	;EXIT IF END OF STRING
	BEQ	CLRCXX
	CMPB	#54,(SG)+	;SKIP OVER COMMA
	BEQ	CLRCXX
	DEC	SG		;ELSE SIGNAL ERROR
	MOV	#NOCOMA,R1
	SEC
CLRCXX:	RTS	PC


;"PRTCMA" PUTS A COMMA FOLLOWED BY A SPACE CHARACTER IN THE OUTPUT
;STRING.

PRTCMA:	MOVB	#54,(SG)+
	MOVB	#40,(SG)+
	CLRB	(SG)
	RTS	PC


;"TICKLE" RETURNS WITH THE C BIT SET IF A C/R CHARACTER HAS BEEN
;TYPED ON THE TELETYPE, OTHERWISE THE C BIT IS CLEARED.  THE
;CHARACTER TYPED IS FLUSHED.

TICKLE:	TSTB	@#TTYIS		;TTY KEYBOARD TICKLED?
	BPL	TICKDN		;NO
	MOVB	@#TTYIR,-(SP)	;DID SOMEONE TYPE A C/R?
	BIC	#200,(SP)
	CMPB	#15,(SP)+
	BNE	TICKDN		;NO
	SEC			;YES
	BR	.+4
TICKDN:	CLC
	RTS	PC

;END OF TICKLE