Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-04 - decus/20-0125/scroll.p11
There are 2 other files named scroll.p11 in the archive. Click here to see a list.
	.NLIST	TTM,CND
	.TITLE	SCROLL - GT40 SCROLLER
	.SBTTL	GENERAL PARAMETER DEFINITIONS
	.ENABL	AMA
	.MCALL	GRAPHIC
	GRAPHIC
	;
	; REGISTER DEFINITIONS
R0=%0
R1=%1
R2=%2
R3=%3
R4=%4
R5=%5
SP=%6
PC=%7
PSW=177776				; PROCESSOR STATUS WORD
	;
	; DEVICE REGISTERS
	;
IS.GT=175610				; GT40 INPUT STATUS REGISTER
IB.GT=175612				; GT40 INPUT BUFFER REGISTER
OS.GT=175614				; GT40 OUTPUT STATUS REGISTER
OB.GT=175616				; GT40 OUTPUT BUFFER REGISTER
	;
IS.KB=177560				; KEYBOARD INPUT STATUS REGISTER
IB.KB=177562				; KEYBOARD INPUT BUFFER REGISTER
	;
	; SCREEN AND SCROLLING PARAMETERS
	;
	.RADIX	10
LNS.SC=31				; NUMBER OF LINES
LST.SC=23				; Y POSITION OF LAST LINE (RASTER UNITS)
FST.SC=LNS.SC*24-1			; Y POSITION OF FIRST LINE (RASTER UNITS)
CHR.SC=72				; NUMBER OF CHARACTERS PER LINE
LSZ.SC=CHR.SC+8				; BYTES PER LINE
DST.SC=24				; VERTICAL DISTANCE BETWEEN CHARACTERS
	.PAGE
	.SBTTL	SPECIAL CHARACTERS
	.RADIX	8
	;
CR.CH=15				; CARRIAGE RETURN
LF.CH=12				; LINE FEED
EOS.CH=37				; CLEAR SCREEN
CRS.CH=137				; CURSOR IS UNDERSCORE
BEL.CH=7				; BEL.CH
SP.CH=40				; SPACE
RUB.CH=177				; RUBOUT
SO.CH=16				; SHIFT-OUT
SI.CH=17				; SHIFT-IN
	.PAGE
	.SBTTL	INTERRUPT VECTORS
	.=4
	.WORD	$BSINT,000		; BUS ERROR, LEVEL 0
	.=60
KB$VEC:	.WORD	$KBINT,200		; KEYBOARD INTERRUPT, LEVEL 4
	.=300
DL$VEC:	.WORD	$DLINT,340		; DL-11 INTERRUPT, LEVEL 7 
	.=330
	.WORD	$TMINT,340		; TIME-OUT INTERRUPT, LEVEL 7
	.PAGE
	.SBTTL	LOCAL MACROS
	;
	.MACRO	CALL 	..ROUT		; MACRO TO CALL A ROUTINE
	JSR	PC,..ROUT		; VIA THE PC
	.ENDM
	;
	.MACRO	RETURN			; MACRO TO DO A RETURN
	RTS	PC			; VIA THE PC
	.ENDM
	;
	.MACRO	SAVREG			; MACRO TO SAVE REGISTERS
	MOV	#340,@#PSW		; NO INTERRUPTS DURING SAVE
	CALL 	$SAVRG			; PLACE THEM ON THE STACK
	CLR	@#PSW			; RE-ENABLE INTERRUPTS
	.ENDM
	;
	.MACRO	RESREG			; MACRO TO RESTORE REGISTERS
	MOV	#340,@#PSW		; NO INTERRUPTS DURING RESTORE
	CALL 	$RESRG			; GET THEM FROM STACK
	CLR	@#PSW			; RE-ENABLE INTERRUPTS
	.ENDM
	;
	.MACRO	PUSH 	..		; MACRO TO
	MOV	..,-(SP)		; PUSH ONTO STACK
	.ENDM
	;
	.MACRO	POP 	..		; MACRO TO POP
	MOV	(SP)+,..		; OFF STACK
	.ENDM
	;
	.MACRO	SOB 	..R,..DEST	; MACRO TO SIMULATE SOB INSTRUCTION
	DEC	..R			; DECREMENT THE REGISTER
	BGT	..DEST			; BRANCH BACK IF GREATER
	.ENDM
	.PAGE
	.=1000
	;
	; MAINLINE, RESUME ADDRESS IS 1000 (OCTAL)
	;
$START:	RESET				;
	RESET				; FIX THINGS
	RESET				;
	MOV	#37776,SP		; SET STACK TO TOP OF CORE
	CALL 	$CDINI			; INTIALIZE CDF, START DISPLAY
	MOV	#100,@#IS.KB		; ENABLE KEYBOARD INTERRUPTS
	MOV	#100,@#IS.GT		; ENABLE DL-11 INTERRUPTS
	MOV	#FIRST.,@#DPC		; START THE DISPLAY
ST.NUL:	WAIT				; WAIT FOR INTERRUPT
	BR	ST.NUL			; WAIT FOR NEXT INTERRUPT
	.PAGE
	.SBTTL	CHARACTER DISPLAY FILE INITIALIZATION
	; THIS SUBROUTINE INITIALIZES THE CHARACTER
	; DISPLAY FILE, AND CREATES CHARACTER POINTERS
	;
$CDINI:	SAVREG				; SAVE THE REGISTERS
	MOV	#FST.SC,R2		; Y POSITION OF TOP LINE
	MOV	#LNS.SC,R0		; NUMBER OF LINES
	MOV	#CDF.+2,R1		; R1 IS CDF. POINTER
CD.1:	TST	(R1)+			; POINT PAST POINT WORD
	CLR	(R1)+			; CLEAR X POSITION
	MOV	R2,(R1)+		; INSERT Y POSITION
	SUB	#DST.SC,R2		; UPDATE Y POSITION
	TST	(R1)+			; POINT PAST CHAR. INST.
	MOV	#CHR.SC/2,R3		; NUMBER OF WORDS PER LINE
CD.2:	CLR	(R1)+			; BLANK OUT THE LINE
	SOB 	R3,CD.2			; LOOP FOR ALL WORDS
	SOB 	R0,CD.1			; LOOP FOR ALL LINES
	CLR	CDF.X			; RESET CURSOR
	CLR	DL$CNT			; CLEAR CHARACTER COUNT
	MOV	#CDF.+10.+<LNS.SC-1*LSZ.SC>,DL$PNT
	MOV	DL$PNT,DL$ST		; POINTERS
	RESREG				; RESTORE THE THE REGISTERS
	RETURN				; AND RETURN
	.PAGE
	.SBTTL	BUS ERROR INTERRUPT ROUTINES
	; TIME-OUT INTERRUPT ROUTINE
	;
	; RESTART THE DISPLAY IMMEDIATELY
	;
$TMINT:	BIT	#100,@#DSR		; IS THIS A SHIFT INTERRUPT ?
	BNE	TM.OUT			; NO, IT IS A TIME-OUT
	MOV	#1,@#DPC		; IF SHIFT THEN RESUME DISPLAY
	RTI				; AND RETURN FROM INTERRUPT
	;
TM.OUT:	MOV	#FIRST.,@#DPC		; IF TIME-OUT, THEN RE-START
	RTI				; AND RETURN FROM INTERRUPT
	;
	; $BSINT - BUS ERROR
	;          MOST LIKELY ODD ADDRESS REFERENCE
	;
$BSINT:	INC	@#DSR			; IN THE EVENT OF AN ODD ADDRESS
	BR	$BSINT			; ERROR, BECOME NOISY
	.PAGE
	.SBTTL	KEYBOARD INTERRUPT ROUTINE
	;
	; THIS ROUTINE INPUTS ONE CHARACTER FROM THE LK40
	; KEYBOARD AND SENDS IT TO THE 10. IF THE CHARACTER
	; IS "EOS.CH" (ASCII 37) THE CHARACTER DISPLAY FILE
	; IS CLEARED
	;
$KBINT:	SAVREG				; SAVE THE REGISTERS
	MOVB	@#IB.KB,R0		; GET THE KEYBOARD CHARACTER
	BIC	#177600,R0		; CLEAR THE TOP BYTE AND PARITY
	CMP	R0,#EOS.CH		; CLEAR SCREEN ?
	BNE	KB.SND			; NO SEND THE CHARACTER
	CALL 	$CDINI			; YES - INITIALIZE THE SCREEN
	BR	KB.RET			; AND RETURN FROM INTERRUPT
KB.SND:	TSTB	@#OS.GT			; IS THE 10 READY
	BPL	KB.SND			; WAIT IF NOT READY
	MOVB	R0,@#OB.GT		; SEND THE CHARACTER
KB.RET:	RESREG				; RESTORE THE REGISTERS
	RTI				; RETURN FROM INTERRUPT
	.PAGE
	.SBTTL	DL-11 INTERRUPT ROUTINE
	; THIS ROUTINE INPUTS ONE CHARACTER FROM THE 10
	; AND ADDS IT TO THE DISPLAY FILE. IF NECESSARY
	; THE DISPLAY FILE IS SCROLLED
	;
DL$ST:	.WORD	0			; POINTER TO START OF LINE
DL$CNT:	.WORD	0			; CHARACTER COUNT
DL$PNT:	.WORD	0			; CHARACTER POINTER
	;
$DLINT:	SAVREG				; SAVE THE REGISTERS
	MOVB	@#IB.GT,R0		; GET THE CHARACTER
	BIC	#177600,R0		; CLEAR TOP BYTE AND PARITY
	CMP	R0,#BEL.CH		; IS THIS A BELL ?
	BNE	DL.NOB			; NO SO CONTINUE
	INC	@#DSR			; YES SO RING
	BR	DL.RET			; AND RETURN
DL.NOB:	CMP	R0,#CR.CH		; CARRIAGE RETURN ?
	BEQ	DL.RET			; YES, SO IGNORE
	CMP	R0,#RUB.CH		; FILLER ?
	BEQ	DL.RET			; YES, SO IGNORE IT
	CMP	R0,#LF.CH		; LINE FEED ?
	BNE	DL.CHR			; NO, SO PRINT CHARACTER
	CALL 	$SCROL			; <LF>, SO SCROLL
	BR	DL.RET			; AND RETURN
	;
DL.CHR:	CMP	DL$CNT,#CHR.SC		; ENOUGH ROOM ON LINE ?
	BGE	DL.RET			; NO, SO IGNORE
	CMP	R0,#40			; PRINTABLE CHARACTER ?
	BLT	DL.RET			; NO, SO IGNORE
	MOVB	R0,@DL$PNT		; INSERT THE CHARACTER
	INC	DL$PNT			; INCREMENT POINTER
	INC	DL$CNT			; INCREMENT CHARACTER COUNT
	ADD	#14.,CDF.X		; MOVE CURSOR
DL.RET:	RESREG				; RESTORE THE REGISTERS
	RTI				; RETURN FROM INTERRUPT
	.PAGE
	.SBTTL	SCROLLING ROUTINE
	; THIS ROUTINE IS CALLED WHENEVER THE 10
	; OUTPUTS A LINE FEED. EVERY LINE IS
	; SHIFTED UP ONE POSITION, AND THE BOTTOM
	; LINE BECOMES AVAILABLE FOR OUTPUT
	;
$SCROL:	MOV	#LNS.SC,R0		; NUMBER OF LINES
	MOV	#CDF.+2,R1		; CDF. POINTER
SC.LUP:	ADD	#DST.SC,4(R1)		; SHIFT LINE UP
	CMP	4(R1),#FST.SC		; IS THIS LINE AVAILABLE
	BLE	SC.SNT			; NO, CONTINUE SHIFTING
	MOV	#LST.SC,4(R1)		; MAKE THIS THE LAST LINE
	MOV	R1,DL$PNT		; GET POINTER
	ADD	#8.,DL$PNT		; AND FIX IT UP
	MOV	DL$PNT,DL$ST		; AND START POINTER
	CLR	DL$CNT			; CLEAR CHARACTER COUNT
	CLR	CDF.X			; RESET CURSOR
	MOV	DL$PNT,R2		; POINTER TO LINE
	MOV	#CHR.SC/2,R3		; NUMBER OF WORDS PER LINE
SC.1:	CLR	(R2)+			; BLANK OUT LINE
	SOB 	R3,SC.1			; LOOP FOR ALL WORDS
	;
SC.SNT:	ADD	#LSZ.SC,R1		; POINT TO NEXT LINE
	SOB 	R0,SC.LUP		; LOOP FOR ALL LINES
	RETURN				; RETURN
	.PAGE
	.SBTTL	UTILITY ROUTINES
	;
$SAVRG:	POP 	SA$RET			; SAVE RETURN ADDRESS
	PUSH 	R0			;
	PUSH 	R1			;
	PUSH 	R2			; PUSH ALL REGISTERS
	PUSH 	R3			; ONTO THE STACK
	PUSH 	R4			;
	PUSH 	R5			;
	JMP	@SA$RET			; SP & PC NOT SAVED
SA$RET:	.WORD	0			; TEMPORARY STORAGE
	;
$RESRG:	POP 	RE$RET			; SAVE RETURN ADDRESS
	POP 	R5			;
	POP 	R4			;
	POP 	R3			; POP ALL REGISTERS
	POP 	R2			; OFF THE STACK
	POP 	R1			;
	POP 	R0			;
	JMP	@RE$RET			; SP & PC NOT RESTORED
RE$RET:	.WORD	0			; TEMPORARY STORAGE
	.PAGE
	.SBTTL	SCROLL DISPLAY FILES
	; FIRST DISPLAY FILE
	;
FIRST.:	STATSA ! SINOF ! ITAL0 ! LPDARK ; LOAD STATUS A, NO INTERRUPTS
					; NORMAL FONT
					; L.P. HITS NOT BRIGHTENED
	CHAR				; CHARACTER MODE
	.BYTE	<SI.CH>,0		; SHIFT IN
FI.END:	DJMP,CDF.			; ONTO CHARACTER DISPLAY FILE
	.PAGE
	; CHARACTER DISPLAY FILE
	;
CDF.:	STATSA!ITAL0			; NO ITALICS
	.REPT	<LNS.SC>
	.WORD	POINT!INT4!BLKOFF
	.WORD	0, 0
	CHAR
	.BLKB	<CHR.SC>
	.ENDR
	;
	POINT!INT4!BLKON
CDF.X:	.WORD	0, <LST.SC>
	CHAR!BLKON
	.BYTE	<CRS.CH>, 0
CD.END:	DJMP,FIRST.			; LOOP THROUGH DISPLAY FILE
	;
	;
	;
	.END	$START