perm filename CATCHE.PAL[V,VDS] blob sn#277821 filedate 1977-04-26 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00008 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	.TITLE CATCHER
C00005 00003	START OF MAIN PROGRAM
C00008 00004	READ IN THE REST OF THE BLOCK AND VERIFY CHECKSUM
C00010 00005	GET STARTING ADDR OF PROGRAM
C00011 00006	TELETYPE INPUT/OUTPUT ROUTINES
C00013 00007	TELEPHONE INPUT/OUTPUT ROUTINES
C00016 00008	LOCAL STORAGE AREA
C00017 ENDMK
C⊗;
.TITLE CATCHER


;ABSOLUTE MEMORY ADDRESS ASSIGNMENTS

.IF1
	.PRINT \STARTING ADDR. (DEFAULT=110000) ← \
	.TTYMA SA
	  .IFNB SA
	    STKTOP=SA
	  .IFF
	    STKTOP=110000	;TOP OF PUSH DOWN STACK AND STARTING ADDRESS
				;   OF CODE   (FOR LSI-11 WITH 20K WORDS)
	  .ENDC
	.ENDM
.ENDC

CLKTRP	=100		;CLOCK INTERRUPT VECTOR
LOCK	=200		;PS TO LOCK OUT INTERRUPTS

;I/O REGISTERS

TTYIS	=177560		;TTY INPUT STATUS
TTYIR	=177562		;TTY INPUT REG
TTYOS	=177564		;TTY OUTPUT STATUS
TTYOR 	=177566		;TTY OUTPUT REG

TELIS	=177570		;TEL INPUT STATUS
TELIR	=177572		;TEL INPUT REG
TELOS	=177574		;TEL OUTPUT STATUS
TELOR 	=177576		;TEL OUTPUT REG

;REGISTER DEFINTIONS

PC	=%7		;PROGRAM COUNTER
SP	=%6		;STACK POINTER
SG	==%5		;STRING POINTER
R5	=%5
R4	=%4		;GENERAL REGISTERS
R3	=%3
R2	=%2
R1	=%1
R0	=%0
L.BC	=%5		;STORAGE FOR ABSOLUTE LOADER
L.ADR	=%4
L.CKSM	=%3
L.BYTE	=%2
L.WRD	=%1

;LOW CORE TRAP VECTORS

   .=4
	.WORD .+2,HALT	;ILLEGAL MEMORY REFERENCE
	.WORD .+2,HALT	;ILLEGAL INSTRUCTION
	.WORD .+2,HALT	;BPT INSTRUCTION AND T BIT
	.WORD .+2,HALT	;IOT INSTRUCTION
	.WORD .+2,HALT	;POWER FAIL
	.WORD .+2,HALT	;EMT INSTRUCTION
	.WORD .+2,HALT	;TRAP INSTRUCTION
   .=244
	.WORD .+2,HALT	;FIS

   .=CLKTRP+2
	RTI		;CLOCK TRAP
   .=CLKTRP
	CLKTRP+2

;MACRO DEFINITIONS FOR LSI INSTRUCTION SET

.MACRO MTPS PSW
	.WORD	106427,PSW
.ENDM
;START OF MAIN PROGRAM

.=STKTOP

START:	RESET
	MTPS	LOCK		;LOCK OUT INTERRUPTS
	MOV	#STKTOP,SP	;PUSH DOWN STACK
	MOV	#HELLO,SG	;SAY HELLO
	JSR	PC,TYPSTR

;START PASSING CHARACTERS BETWEEN TTY AND TEL UNTIL (CNTRL) B

PASS:	JSR	PC,TELTIC	;PASS TELE TO TTY
	BCC	1$
	JSR	PC,TYPCHR
1$:	JSR	PC,TYPTIC	;PASS TTY TO TELE
	BCC	PASS
	JSR	PC,PASCHR
	CMP	R0,#17		;(CNTRL)O ?
	BNE	2$
	HALT			;YES, EXIT TO ODT
2$:	CMP	R0,#2		;(CNTRL)B ?
	BNE	PASS		;NO, KEEP PASSING

;START OF TELEPHONE LOADER

	MOV	#TELLOD,SG	;INFORM USER THAT LOADER STARTED
	JSR	PC,TYPSTR
	CLR	@#BLKCNT	;NUMBER OF BLOCKS RECEIVED
	CLR	@#HIGHAD	;HIGHEST MEMORY ADDR LOADED

;LOOK FOR BEGINNING OF A BLOCK = 000001

LOADER:	MOV	#'G,R0		;SIGNAL TELE, READY TO READ BLOCK
	JSR	PC,PASCHR
	CLR	CHKNUM		;INDICATE NO CHECKSUM ERROR
READBK:	MOV	#1,L.CKSM	;INITIALIZE CHECK SUM
	JSR	PC,GET6BT	;READ A FRAME
1$:	DECB	R0		;1 → START OF BLOCK
	BNE	READBK
	JSR	PC,GET6BT	;0 → START OF BLOCK
	BNE	1$
	JSR	PC,GET6BT	;0 → START OF BLOCK
	BNE	1$

;AT THE START OF A BLOCK, NOW GET THE BYTE COUNT AND LOAD ADDR.

	CLR	BYTE2		;MARK START OF WORD
	JSR	PC,GETWRD	;GET AND SAVE BYTE COUNT
	MOV	L.WRD,L.BC
	SUB	#6,L.BC		;ADJUST FOR 4 BYTES WE ALREADY GOT+2
	BEQ	SAVSTR		;BYTE COUNT = 6 → JUMP BLOCK
	JSR	PC,GETWRD	;GET AND SAVE LOAD ADDRESS
	MOV	L.WRD,L.ADR
;READ IN THE REST OF THE BLOCK AND VERIFY CHECKSUM

2$:	JSR	PC,GETBYT	;NEXT BYTE
	BMI	3$ 		;BRANCH IF END OF BLOCK
	MOVB	L.BYTE,(L.ADR)+	;LOAD BYTE INTO MEMORY
	BR	2$

3$:	TSTB	L.CKSM		;CHECK SUM OK?
	BNE	BADCHK		;NO
	DEC	L.ADR		;YES, SAVE HIGHEST ADDR LOADED
	CMP	L.ADR,HIGHAD
	BLE	.+6
	MOV	L.ADR,HIGHAD
	MOV	BLKCNT,R0	;INDICATE ANOTHER BLOCK LOADED
	INC	R0
	BIC	#177770,R0
	MOV	R0,BLKCNT
	ADD	#60,R0
	JSR	PC,TYPCHR
	BR	LOADER

BADCHK:	CMP	CHKNUM,#4	;CHECK SUM ERROR 4 TIMES IN A ROW?
	BGE	1$		;GIVE UP TRYING TO READ
	INC	CHKNUM
	MOV	#CHECKE,SG	;SIGNAL ERROR
	JSR	PC,TYPSTR
	MOV	#'C,R0		;TRY RE-READING BLOCK
	JSR	PC,PASCHR
	BR	READBK

1$:	MOV	#FATAL,SG	;SIGNAL FATAL ERROR
	JSR	PC,TYPSTR
	MOV	#SWITCH,SG
	JSR	PC,TYPSTR
	MOV	#'F,R0
	JSR	PC,PASCHR
	JMP	PASS
;GET STARTING ADDR OF PROGRAM

SAVSTR:	JSR	PC,GETWRD	;GET JUMP ADDR
	MOV	L.WRD,L.ADR
	JSR	PC,GETWRD	;COMPUTE CHECKSUM
	TSTB	L.CKSM		;CHECK SUM OK?
	BNE	BADCHK		;NO
	ASR	L.ADR		;NO ADDRESS IF ODD NUMBER
	BCC	.+4
	CLR	L.ADR
	ASL	L.ADR		;SAVE STARTING ADDRESS

;ALL DONE, TYPE LOAD INFORMATION AND GO BACK TO PASSER

	MOV	#STRADR,SG	;TYPE STARTING ADDRESS
	JSR	PC,TYPSTR
	MOV	L.ADR,R0
	JSR	PC,TYPOCT
	MOV	#HIGADR,SG	;TYPE HIGH LOAD ADDRESS
	JSR	PC,TYPSTR
	MOV	HIGHAD,R0
	JSR	PC,TYPOCT
	MOV	#LOADDN,SG	;SIGNAL LOADER ALL DONE
	JSR	PC,TYPSTR
	MOV	#'D,R0
	JSR	PC,PASCHR
	JMP	PASS

;END OF LOADER
;TELETYPE INPUT/OUTPUT ROUTINES

;OUTPUT ROUTINES

TYPSTR:	MOV	R0,-(SP)
	BR	3$
1$:	JSR	PC,TYPCHR	;LF FOLLOWED BY 3 NULLS
	CLR	R0
	JSR	PC,TYPCHR
	JSR	PC,TYPCHR
2$:	JSR	PC,TYPCHR
3$:	MOVB	(SG)+,R0	;GET BYTE
	BEQ	4$		;END OF STRING?
	CMP	#12,R0		;WAS IT A LINE FEED?
	BNE	2$		;NO
	BR	1$
4$:	MOV	(SP)+,R0
	RTS	PC

TYPCHR:	TSTB	@#TTYOS		;TTY AVAILABLE?
	BPL	TYPCHR		;NO, BUSY WAIT
	MOVB	R0,@#TTYOR	;YES, SEND OFF THE CHARACTER
	RTS	PC

TYPOCT:	MOV	R0,R1		;NORMALIZE FOR DIVISION
1$:	CLR	R0
	DIV	#8,R0		;PICK OFF 3 LSB
	ADD	#'0,R1		;ADD ASC BASE
	MOV	R1,-(SP)	;STACK DIGITS IN REVERSE ORDER
	MOV	R0,R1
	BEQ	2$
	JSR	PC,1$		;RECURSIVE CALL
2$:	MOV	(SP)+,R0
	JSR	PC,TYPCHR	;PRINT THE NUMBER
	RTS	PC


;INPUT ROUTINES

INCHR:	TSTB	@#TTYIS		;TTY READY?
	BPL	.-4
	BR	GETCHR

TYPTIC:	TSTB	@#TTYIS		;CHARACTER TYPED ON TTY?
	BPL	TICKDN		;NO, ERROR RETURN
GETCHR:	MOVB	@#TTYIR,R0	;GET THE CHARACTER
	BIC	#177600,R0	;CHANGE TO 7 BIT
	SEC			;C ← 1
TICKDN:	RTS	PC
;TELEPHONE INPUT/OUTPUT ROUTINES

;OUTPUT ROUTINES

PASCHR:	TSTB	@#TELOS		;TELE AVAILABLE?
	BPL	PASCHR		;NO, BUSY WAIT
	MOVB	R0,@#TELOR	;YES, SEND OFF THE CHARACTER
	RTS	PC


;CHARACTER INPUT ROUTINES

TELTIC:	TSTB	@#TELIS		;CHARACTER PASSED THROUGH TELE?
	BPL	TELTDN		;NO, ERROR RETURN
MOVCHR:	MOVB	@#TELIR,R0	;GET THE CHARACTER
	BIC	#177600,R0	;CHANGE TO 7 BIT
	SEC			;C ← 1
TELTDN:	RTS	PC


;BINARY INPUT ROUTINES

GET6BT:	JSR	PC,TELTIC	;CHECK FOR 7 BIT CHARACTER FOR TELE
	BCS	1$		;GOT ONE
	JSR	PC,TYPTIC	;ELSE CHECK FOR ABORT COMMAND FROM TTY
	BCC	GET6BT
	CMP	R0,#3 		;(CNTRL)C ?
	BNE	GET6BT
	MOV	#'F,R0		;TELL PASSER THIS IS A ABORT COMMAND
	JSR	PC,PASCHR
	MOV	#ABORT,SG	;TELL TTY
	JSR	PC,TYPSTR
	MOV	#SWITCH,SG
	JSR	PC,TYPSTR
	MOV	#STKTOP,SP	;CLEAR STACK
	JMP	PASS

1$:	CMP	R0,#12		;IGNOR LF'S AND CR'S
	BEQ	GET6BT
	CMP	R0,#15
	BEQ	GET6BT
	CMP	R0,#173		;TAB → CR GETS 173 → 177
	BLT	2$
	SUB	#162,R0
2$:	CMP	R0,#100		;BINARY OR ASCII?
	BLE	3$
	JSR	PC,TYPCHR	;PASS ASCII TO TTY
	BR	GET6BT
3$:	DEC	R0		;CONVERT TO 6 BIT
	RTS	PC

GETWRD:	JSR	PC,GET6BT	;GET 3, 6 BIT CHAR. TO FORM WORD
	ASHC	#-6,R0
	JSR	PC,GET6BT
	ASHC	#-6,R0
	JSR	PC,GET6BT
	ASHC	#-4,R0
	ADD	L.WRD,L.CKSM	;ADD 2 BYTES TO CHECK SUM
	SWAB	L.WRD
	ADD	L.WRD,L.CKSM
	SWAB	L.WRD
	RTS	PC

GETBYT:	SWAB	L.WRD		;NEED 2ND BYTE OF OLD WORD?
	COM	BYTE2
	BEQ	1$		;YES
	JSR	PC,GETWRD	;ELSE GET 1ST BYTE OF NEW WORD
1$:	MOV	L.WRD,L.BYTE
	DEC	L.BC		;DECREMENT BYTE COUNT
	RTS	PC
;LOCAL STORAGE AREA

BLKCNT:	0
CHKNUM:	0
BYTE2:	0
HIGHAD:	0

HELLO:	.ASCIZ	/

HI, I'M THE CATCHER AND I'M READY TO GO ( CNTRL O → ODT )

/
TELLOD:	.ASCIZ	/
TELEPHONE LOADER STARTING, TYPE (CNTRL)C TO ABORT
/
CHECKE:	.ASCIZ	/
CHECK SUM ERROR
/
STRADR:	.ASCIZ	/
PROGRAM STARTING ADDRESS: /
HIGADR:	.ASCIZ	/
HIGH LOAD ADDRESS: /
FATAL:	.ASCIZ	/
[FATAL] CHECKSUM ERROR 4 TIMES IN A ROW, /
ABORT:	.ASCIZ	/
[FATAL] ABORT COMMAND FROM TTY, /
LOADDN:	.ASCII	/

LOADING COMPLETED, /
SWITCH:	.ASCIZ	/SWITCHING BACK TO TELE-TTY MODE

/
.EVEN

.END START