.TITLE VIEW A FILE ON A VT-100 .ENABL LC ; Copyright (C) 1981 Berez Associates .MCALL .EXIT,.MTATCH,.MTGET,.MTSET,.MTDTCH,.TTYIN,.TTYOUT .MCALL .PRINT,.CSIGEN,.SETTOP,.LOOKUP .MCALL .WRITE,.READW,.WAIT,.QSET ;CONSTANTS ERRBYT= 52 ;ERROR CODE BYTE JSW= 44 ;JOB STATUS WORD BUFTOP= 50 ;TOP OF MEMORY INCHAN= 3 ;INPUT (FILE) CHANNEL TTCHAN= 1 ;OUTPUT (TERMINAL) CHANNEL ;CHARACTER DEFINITIONS ESC= 33 TAB= 11 CR= 15 LF= 12 FF= 14 RUBOUT= 177 SPACE= 40 BELL= 7 EOF= 32 ;MACROS ;DISPLAY ERROR MESSAGE AND EXIT .MACRO ERROR STR .CSECT STRING $$$=. .ASCIZ \STR\ .CSECT CODE JSR R5,ERROR .WORD $$$ .ENDM ERROR ;PUT A TERMINAL COMMAND IN OUTPUT BUFFER .MACRO COMAND STR .CSECT STRING $$$=. .ASCIZ \STR\ .CSECT CODE JSR R5,COMAND .WORD $$$ .ENDM COMAND .CSECT DATA AREA: .BLKW 5 ;USED BY RT MACROS ;;TTSTAT: .BLKW 4 ;TERMINAL STATUS WORDS ;;STATSV: -1 ;SAVED TERMINAL CONFIG WORD ;;TRMNUM: 0 ;TERMINAL NUMBER IN USE DEFTYP: .RAD50 /LST/ ;DEFAULT INPUT FILE TYPE .WORD 0,0,0 BUFBOT: .WORD BUFFER ;BOTTOM OF BUFFER, ABOVE HANDLERS OBUF1: 0 ;FIRST OUTPUT BUFFER LOCATION OBUF2: 0 ;SECOND OUTPUT BUFFER LOCATION OBUFE: 0 ;END OF SECOND BUFFER OUTBUF: 0 ;CURRENT OUTPUT BUFFER OUTPTR: 0 ;NEXT OUTPUT CHARACTER LOCATION OBFEND: 0 ;END OF CURRENT OUTPUT BUFFER INBUF: 0 ;INPUT BUFFER IBFEND: 0 ;END OF INPUT BUFFER TTNAME: .RAD50 /TT / ;TERMINAL NAME FOR .LOOKUP .WORD 0,0,0 WIDE: 0 ;WIDE SCREEN OUTPUT? REVVID: 0 ;REVERSE VIDEO? FORM: 0 ;SHOW FORM-FEEDS? CONTRL: 0 ;SHOW CONTROL-CHARACTERS? SPACES: 0 ;SHOW SPACES? WIDTH: 0 ;LINE WIDTH CURBLK: -1 ;FIRST INPUT FILE BLOCK IN CORE INPTR: 0 ;NEXT CHARACTER TO READ EOFFLG: 0 ;END-OF-FILE ON CURRENT PAGE? DOWN: 1 ;MOVING DOWN? INVERS: 0 ;IN INVERSE VIDEO MODE? SPECS: 0 ;IN SPECIAL CHARACTER SET MODE? INLEN: 0 ;INPUT BUFFER LENGTH IN WORDS IBLKS: 0 ;NUMBER OF BLOCKS IN BUFFER LASTWD: 0 ;LAST WORD POINTER HPOS: 0 ;HORIZONTAL POSITION TO START FIRST LINE QADDR: .BLKW 10. ;EXTRA QUEUE ELEMENT .CSECT STRING TRMINI: .ASCII //)0/<200> SETWID: .ASCII /[?3h/<200> ;SET TERMINAL WIDTH TO 132 UNSWID: .ASCII /[?3l/<200> ;RESET TERMINAL WIDTH TO 80 SETREV: .ASCII /[?5h/<200> ;SET REVERSE VIDEO MODE ERRMSG: .ASCII /?VIEW-F-/<200> ;ERROR MESSAGE HEADER TRESET: .ASCII /[m/<17>/[q//[?3l//[?5l//[?2l/<200> HLPSTR: .ASCII /VIEW Switches:/ ;HELP TEXT .ASCII \ /W Wide screen output\ .ASCII \ /A Show all characters\ .ASCII \ /R Reverse video\ .ASCII \ /H Help text\ .ASCII \VIEW Commands:\ .ASCII \ D Move down file\ .ASCII \ U Move up file\ .ASCII \ Next page\ .ASCII \ 1-9 Next n pages\ .ASCII \ T Top of file\ .ASCII \ B Bottom of file\ .ASCII \ W Toggle screen width\ .ASCII \ F Toggle form-feed mode\ .ASCII \ C Toggle controls mode\ .ASCII \ S Toggle spaces mode\ .ASCII \ Q Quit\ .ASCII \VIEW Lights:\ .ASCII \ L1 Moving down\ .ASCII \ L2 Moving up\ .ASCIZ \Copyright (C) 1981 Berez Associates\ .CSECT CODE .ENABL LSB START: MOV #10000,@#JSW ;SET SINGLE CHARACTER INPUT MODE ;; MOV #-1,R1 ;;1$: INC R1 ;NEXT TERMINAL NUMBER ;; .MTATCH #AREA,#0,R1 ;TRY TO ATTACH IT ;; BCC 2$ ;GOT IT ;; CMPB @#ERRBYT,#2 ;PAST LAST TERMINAL? ;; BNE 1$ ;NO ;; ERROR ;YES, INFORM LOSER ;;2$: .MTGET #AREA,#TTSTAT,R1 ;GET STATUS ;; BCS 1$ ;SHOULDN'T REALLY FAIL ;; TST TTSTAT+6 ;IS THIS THE CONSOLE? ;; BMI 3$ ;YES ;; .MTDTCH #AREA,R1 ;NO, DETACH THE TERMINAL ;; BR 1$ ;;3$: MOV TTSTAT,STATSV ;SAVE OLD STATUS FOR LATER ;; MOV #10201,TTSTAT ;SET CONFIG WORD ;; .MTSET #AREA,#TTSTAT,R1 ;; BCC 4$ ;; ERROR ;;4$: MOV R1,TRMNUM ;REMEMBER CONSOLE TERMINAL NUMBER .CSIGEN BUFBOT,#DEFTYP,#0 ;OPEN FILE TO BE VIEWED BCC 1$ ERROR 1$: MOV (SP)+,R1 ;NUMBER OF SWITCHES ENTERED BEQ 8$ ;NONE 2$: MOV (SP)+,R2 ;GET NEXT SWITCH BPL 3$ ;NO ARGUMENT? TST (SP)+ ;FLUSH ARGUMENT 3$: CMPB R2,#'W BNE 4$ INC WIDE ;USE WIDE SCREEN OUTPUT BR 7$ 4$: CMPB R2,#'A ;SHOW ALL? BNE 5$ INC FORM ;SHOW FORM-FEEDS INC CONTRL ;SHOW CONTROL-CHARACTERS INC SPACES ;SHOW SPACES BR 7$ 5$: CMPB R2,#'H BNE 6$ .PRINT #HLPSTR ;SHOW HELP TEXT JMP EXIT2 ;AND EXIT 6$: CMPB R2,#'R BNE 7$ INC REVVID ;USE REVERSE VIDEO 7$: SOB R1,2$ 8$: MOV R0,BUFBOT ;FIRST WORD AFTER HANDLER, IF ANY .QSET #QADDR,#1 ;GET AN EXTRA QUEUE ELEMENT .LOOKUP #AREA,#TTCHAN,#TTNAME ;OPEN CHANNEL TO TERMINAL BCC RESTRT ERROR RESTRT: MOV #80.*24.+1500.,R1 ;OUTPUT BUFFER SIZE, ASSUMING NARROW LINES MOV #80.,WIDTH ;LINE WIDTH TST WIDE ;WIDE LINES DESIRED? BEQ 9$ ;NO MOV #132.*24.+1500.,R1 ;YES, MODIFY EARLIER ASSUMPTION MOV #132.,WIDTH ;CHANGE THIS, TOO 9$: MOV BUFBOT,R2 ;BEGINNING OF AVAILABLE BUFFER SPACE MOV R2,OBUF1 ;PUT FIRST OUTPUT BUFFER HERE ADD R1,R2 ;ADD BUFFER SIZE MOV R2,OBUF2 ;SECOND OUTPUT BUFFER FOLLOWS FIRST ADD R1,R2 MOV R2,OBUFE ;END OF OUTPUT BUFFERS MOV OBUF1,OUTBUF ;SELECT FIRST BUFFER FIRST MOV OBUF2,OBFEND DEC R2 ;ROUND UP TO BLOCK BOUNDARY FOR CONVENIENCE BIC #777,R2 ADD #1000,R2 MOV R2,INBUF ;START INPUT BUFFER HERE ADD #14000,R2 ;ALLOW ROOM FOR INPUT BUFFER AND DATA STACK SUB #2,R2 ;POINT TO LAST DESIRED WORD .SETTOP R2 ;TRY TO GET THE MEMORY MOV R0,R5 ;LAST AVAILABLE LOCATION ;; ADD #2,R5 ;INITIAL DATA STACK POINTER SUB #4000,R0 ;RESERVE SPACE FOR PAGE STACK (POINTER IN R5) BIC #777,R0 ;ROUND DOWN TO BLOCK BOUNDARY MOV R0,IBFEND ;END OF INPUT BUFFER SUB INBUF,R0 ;SIZE OF INPUT BUFFER BHI 10$ ;MUST BE POSITIVE ERROR 10$: ASR R0 MOV R0,INLEN ;SAVE LENGTH IN WORDS SWAB R0 MOV R0,IBLKS ;SAVE NUMBER OF BLOCKS ;; .TTYOUT #ESC ;ASK TERMINAL TO IDENTIFY ITSELF ;; .TTYOUT #'Z ;; .TTYIN ;LOOK FOR VT-100 IN VT-52 MODE ;; CMP R0,#ESC ;; BNE 13$ ;; .TTYIN ;; CMP R0,#'/ ;; BNE 13$ ;; .TTYIN ;; CMP R0,#'Z ;; BEQ 11$ ;;13$: ERROR 11$: .PRINT #TRMINI ;INITIALIZE TERMINAL (ANSI MODE & CHAR SET) TST WIDE ;WIDE OUTPUT? BEQ 12$ ;NO .PRINT #SETWID ;YES, SET TERMINAL WIDTH 12$: TST REVVID ;REVERSE VIDEO? BEQ 13$ ;NO .PRINT #SETREV ;YES, SELECT IT 13$: CLR -(R5) ;SET UP POINTERS FOR FIRST PAGE MOV INBUF,-(R5) CLR -(R5) .DSABL LSB .ENABL LSB NEWPAG: JSR PC,SETPTR ;POINT TO PAGE IN INPUT FILE ADD #6,R5 ;CLEAN UP STACK 1$: JSR PC,GETPAG ;GET (FORMAT) NEXT OUTPUT PAGE 2$: JSR PC,OUTPAG ;QUEUE THE PAGE FOR OUTPUT 3$: JSR PC,GETPAG ;GET THE NEXT ONE WHILE LAST ONE PRINTS 4$: .TTYIN ;GET COMMAND FROM USER CMP R0,#SPACE ;SPACE MEANS NEXT PAGE BEQ 2$ CMP R0,#'1 ;1 IS SAME AS SPACE BEQ 2$ CMP R0,#'D ;D MEANS SWITCH TO DOWN MODE & NEXT PAGE BNE 5$ TST DOWN ;ALREADY IN D MODE? BNE 2$ ;YES, ACT LIKE SPACE INC DOWN ;NO, SET MODE & GET PROPER PAGE SUB #6,R5 ;POINT TO PROPER PAGE (PRINTED PREVIOUSLY) BR NEWPAG ;SET THE POINTER 5$: CMP R0,#'U ;U MEANS SWITCH TO UP MODE & NEXT PAGE BNE 6$ TST DOWN ;ALREADY IN U MODE? BEQ 2$ ;YES, ACT LIKE SPACE CLR DOWN ;NO, SET MODE & GET PROPER PAGE BR 1$ 6$: CMP R0,#'T ;T MEANS TOP OF FILE BNE 7$ GOTOP: MOV @#BUFTOP,R5 ;RESET STACK TO BEGINNING OF FILE SUB #6,R5 INC DOWN ;MAKE SURE WE'RE IN DOWN MODE CLR EOFFLG ;NO LONGER AT EOF, EITHER BR NEWPAG ;GET FIRST PAGE 7$: CMP R0,#'B ;B MEANS BOTTOM OF FILE BNE 9$ TST DOWN ;ALREADY GOING DOWN? BNE 8$ ;YES INC DOWN ;NO, CHANGE DIRECTION SUB #6,R5 ;AND POINT TO PROPER FILE POSITION JSR PC,SETPTR ADD #6,R5 8$: JSR PC,GETPAG TST EOFFLG BEQ 8$ ;SKIP PAGES UNTIL END OF FILE JSR PC,OUTPAG ;PRINT THE PAGE JSR PC,GETPAG ;ONE MORE FOR GOOD MEASURE CLR DOWN ;NOW SWITCH TO UP MODE BR 3$ ;AND GET NEXT USER COMMAND 9$: CMP R0,#'W ;W MEANS TOGGLE SCREEN WIDTH BNE 12$ INC DOWN ;SET PROPER STATE CLR EOFFLG TST WIDE ;ALREADY WIDE? BEQ 10$ CLR WIDE ;YES, CLEAR IT .PRINT #UNSWID ;CHANGE TERMINAL WIDTH BACK TO NORMAL BR 11$ 10$: INC WIDE ;NO, SET IT 11$: MOV #-1,CURBLK ;FORGET BLOCKS READ JMP RESTRT ;MUST RESTART TO CHANGE SCREEN WIDTH 12$: CMP R0,#'F ;F MEANS TOGGLE FORM MODE BNE 14$ TST FORM ;ALREADY SET? BEQ 13$ CLR FORM ;YES, CLEAR IT BR GOTOP ;AND GO TO TOP OF FILE 13$: INC FORM ;NO, SET IT BR GOTOP ;ETC. 14$: CMP R0,#'C ;C MEANS TOGGLE CONTROL MODE BNE 16$ TST CONTRL ;ALREADY SET? BEQ 15$ CLR CONTRL ;YES, CLEAR IT BR GOTOP ;AND GO TO TOP OF FILE 15$: INC CONTRL ;NO, SET IT BR GOTOP ;ETC. 16$: CMP R0,#'S ;S MEANS TOGGLE SPACES MODE BNE 18$ TST SPACES ;ALREADY SET? BEQ 17$ CLR SPACES ;YES, CLEAR IT BR GOTOP ;AND GO TO TOP OF FILE 17$: INC SPACES ;NO, SET IT BR GOTOP ;ETC. 18$: CMP R0,#'Q ;Q MEANS QUIT BNE 19$ JMP EXIT 19$: CMP R0,#'2 ;DIGIT 2-9? BLT 22$ CMP R0,#'9 BGT 22$ SUB #'1,R0 ;NUMBER OF EXTRA PAGES TO SKIP MOV @#BUFTOP,R1 SUB #12.,R1 ;TOP-OF-STACK FOR COMPARISON 20$: MOV R0,-(SP) JSR PC,GETPAG ;SKIP A PAGE MOV (SP)+,R0 CMP R5,R1 ;AT BEGINNING OF FILE? BEQ 21$ ;YES, STOP HERE TST EOFFLG ;AT END OF FILE? BNE 21$ ;YES, STOP HERE SOB R0,20$ ;SKIP N-1 PAGES 21$: JMP 2$ ;SHOW N'TH PAGE 22$: .TTYOUT #BELL ;FEEP & GET ANOTHER CHARACTER JMP 4$ .DSABL LSB ;GET (FORMAT) NEXT OUTPUT PAGE .ENABL LSB GETPAG: MOV OUTBUF,R2 ;GET OUTPUT POINTER COMAND <[H> ;TOP OF SCREEN COMAND <[q> ;CLEAR LIGHTS TST DOWN ;PAGING DOWN? BEQ PGUP ;NO TST EOFFLG ;ARE WE AT END OF FILE? BEQ PGDOWN ;NO BMI 1$ ;YES, BUT WE'VE ALREADY BEEN HERE NEG EOFFLG ;REMEMBER THAT WE WERE HERE SUB #6,R5 ;SET STACK IN CASE WE BACK UP FROM HERE CLR OUTPTR ;SET FLAG FOR OUTPAG 1$: RTS PC PGDOWN: COMAND <[1q> ;PAGING DOWN, TURN ON LIGHT 1 MOV CURBLK,-(R5) ;SAVE CURRENT BLOCK NUMBER MOV INPTR,-(R5) ;ALSO SAVE CHARACTER POINTER MOV HPOS,R3 ;GET HORIZONTAL POSITION FROM LAST PAGE MOV R3,-(R5) ;SAVE IT, TOO CMP R5,IBFEND ;CHECK FOR STACK OVERFLOW BHIS PGBEG ;NO OVERFLOW ERROR PGUP: COMAND <[2q> ;PAGING UP, TURN ON LIGHT 2 ADD #12.,R5 ;POP OFF CURRENT PAGE POINTERS (ONE UNPRINTED) CMP R5,@#BUFTOP ;WAS THIS THE FIRST PAGE? BLO 3$ ;NO BNE 2$ ;FIRST TIME BACK TO FIRST PAGE? ADD #6,R5 ;YES, SET UP POINTER FOR DOWN MOTION 2$: SUB #12.,R5 ;NO, LEAVE PAGE STACK UNCHANGED MOVB #7,(R2)+ ;IF AT FIRST PAGE, SIMPLY FEEP AT USER JMP PDONE1 ;AND RETURN 3$: CLR EOFFLG ;IF WE WERE AT EOF, WE AREN'T ANYMORE JSR PC,SETPTR ;SET THE INPUT POINTER FOR THIS PAGE MOV (R5),R3 ;GET PROPER HPOS FOR THIS PAGE SUB #6,R5 ;RESTORE POINTER FOR NEXT PAGE PGBEG: CLR INVERS ;EXIT ANY SPECIAL MODES COMAND <[m> ;NON-INVERTED MODE CLR SPECS MOVB #17,(R2)+ ;NON-SPECIAL CHARACTER MODE CLR R4 ;INITIALIZE LINE COUNTER TST R3 ;START AT BEGINNING OF LINE? BEQ NXTLIN ;YES COMAND <[> ;NO, MOVE CURSOR MOV R3,R0 JSR PC,PUTNUM ;PUT POSITION NUMBER IN BUFFER MOVB #'C,(R2)+ ;MOVE CURSOR RIGHT NXTLIN: COMAND <[2K> ;START LINE CLEAR NXTCHR: JSR PC,GETCHR ;GET A CHARACTER FROM FILE BR EOF0 ;NO MORE CHARACTERS BR NXTCH1 EOF0: JMP GOTEOF NXTCH1: TST R0 BEQ NXTCHR ;IGNORE NULLS CMP R0,#RUBOUT ;RUBOUT IS ALWAYS HANDLED SPECIALLY BNE 4$ MOV #'?,R0 BR CTRL 4$: CMP R0,#SPACE ;CONTROL CHARACTER OR SPACE? BGT OUTCHR ;NO, DO NOTHING SPECIAL BLT 5$ ;CONTROL CHARACTER TST SPACES ;SPACE, SHOW SPACES? BEQ OUTCHR ;NO MOV #176,R0 ;YES, DISPLAY SYMBOL BR SPECCH 5$: CMP R0,#TAB ;TAB? BNE 7$ ;NO TST CONTRL ;YES, SHOW CONTROLS? BEQ 6$ ;NO, HANDLE CURSOR MOVEMENT MOV #'b,R0 ;YES, DISPLAY HORIZONTAL TAB SYMBOL BR SCTRL 6$: BIC #7,R3 ;UPDATE HPOS ADD #10,R3 BR IMAGE 7$: CMP R0,#BELL ;BELL? BNE 8$ ;NO TST CONTRL ;SHOW CONTROLS? BEQ IMAGE ;NO, DISPLAY WITH NO CURSOR MOVEMENT BR CTRL0 ;YES, SHOW IT 8$: CMP R0,#CR ;CARRIAGE RETURN? BNE 11$ ;NO TST CONTRL ;SHOW CONTROLS? BEQ 10$ ;NO, HANDLE NORMALLY JSR PC,GETCHR ;YES, SEE IF NEXT CHARACTER IS A LF BR GOTEOF ;END OF FILE CMP R0,#LF ;WELL? BEQ 9$ ;YES, JUST PROCESS BOTH NORMALLY DEC INPTR ;NO, UNREAD IT MOV #'d,R0 ;AND SHOW CR BR SCTRL 9$: MOVB #CR,(R2)+ ;BUFFER THE CR CLR R3 ;CURSOR RETURNS TO BEGINNING OF LINE BR 22$ ;AND LINE IS ENDED 10$: CLR R3 ;CURSOR RETURNS TO BEGINNING OF LINE BR IMAGE 11$: CMP R0,#LF ;LINE FEED? BNE 12$ ;NO TST CONTRL ;YES, SHOW CONTROLS? BEQ 22$ ;NO, NORMAL END OF LINE MOV #'e,R0 ;YES, THIS MUST BE A NAKED LF BR SCTRL 12$: CMP R0,#FF ;FORM FEED? BNE 13$ ;NO TST FORM ;YES, SHOW FORM FEEDS? BEQ PDONE ;NO, END OF PAGE MOV #'c,R0 ;YES, USE FORM FEED SYMBOL BR SCTRL 13$: CMP R0,#ESC ;ESCAPE PRINTED AS DIAMOND BNE CTRL0 MOV #'`,R0 BR SPECCH CTRL0: BIS #100,R0 ;USE CORRESPONDING ALPHA CHARACTER CTRL: TST INVERS ;ALREADY IN INVERSE MODE? BNE OUTCH1 ;YES INC INVERS ;NO, ENTER IT COMAND <[7m> ;INVERSE VIDEO MODE 14$: BR OUTCH1 ;NOW DISPLAY CHARACTER SCTRL: TST INVERS ;ALREADY IN INVERSE MODE? BNE 15$ ;YES INC INVERS ;NO, ENTER IT COMAND <[7m> ;INVERSE VIDEO MODE BR 15$ SPECCH: TST INVERS ;ARE WE IN INVERSE MODE? BEQ 15$ ;NO CLR INVERS ;YES, CLEAR IT COMAND <[m> ;NON-INVERTED MODE 15$: TST SPECS ;ALREADY IN SPECIAL SET? BNE 16$ ;YES INC SPECS ;NO, SELECT SPECIAL SET MOVB #16,(R2)+ 16$: MOVB R0,(R2)+ ;DISPLAY CHARACTER 17$: INC R3 ;ALL OF THIS TAKES ONE POSITION BR 19$ OUTCHR: TST INVERS ;ARE WE IN INVERSE MODE? BEQ 18$ ;NO CLR INVERS ;YES, CLEAR IT COMAND <[m> ;NON-INVERTED MODE 18$: TST SPECS ;ARE WE IN SPECIAL SET? BEQ OUTCH1 ;NO CLR SPECS ;YES, CLEAR IT MOVB #17,(R2)+ OUTCH1: INC R3 ;BUMP HPOS FOR NORMAL CHARACTERS IMAGE: MOVB R0,(R2)+ ;TRANSFER CHARACTER TO OUTPUT BUFFER 19$: CMP R3,WIDTH ;END OF LINE? BGE 20$ ;YES JMP NXTCHR ;NO, CONTINUE GETTING CHARACTERS 20$: JSR PC,GETCHR ;YES, SEE IF NEXT CHARACTER IS A CR BR GOTEOF ;END OF FILE CMP R0,#CR ;WELL? BNE 21$ ;NO JMP NXTCH1 ;YES, JUST PROCESS IT NORMALLY 21$: DEC INPTR ;NO, UNREAD IT MOVB #CR,(R2)+ ;SIMULATE A CARRIAGE RETURN & LINE FEED CLR R3 22$: INC R4 ;BUMP LINE COUNTER CMP R4,#24. ;END OF PAGE? BEQ PDONE1 ;YES MOVB #LF,(R2)+ ;NO, OUTPUT THE LF JMP NXTLIN ;AND CONTINUE GOTEOF: INC EOFFLG ;END OF FILE, SET THE FLAG PDONE: COMAND <[J> ;CLEAR REST OF PAGE PDONE1: MOV R2,OUTPTR ;SAVE UPDATED OUTPUT POINTER MOV R3,HPOS ;AND UPDATED HORIZONTAL POSITION RTS PC .DSABL LSB ;OUTPUT A PAGE TO THE TERMINAL .ENABL LSB OUTPAG: TST OUTPTR ;END OF FILE? BNE 1$ ;NO .TTYOUT #BELL ;YES, JUST FEEP RTS PC ;AND RETURN 1$: .WAIT #TTCHAN ;ENSURE THAT PREVIOUS OUTPUT IS COMPLETE BCS 4$ ;ERROR MOV OUTPTR,R1 ;GET CURRENT OUTPUT POINTER CMP R1,OBFEND ;PAST LEGAL END OF BUFFER? BLOS 2$ ;NO ERROR 2$: SUB OUTBUF,R1 ;NUMBER OF BYTES TO OUTPUT ROR R1 ;CONVERT TO WORDS BCC 3$ ;NOT ODD INC R1 ;ODD, INCREMENT WORD COUNT CLRB @OUTPTR ;ZERO EXTRA CHARACTER 3$: .WRITE #AREA,#TTCHAN,OUTBUF,R1,#0 ;TRANSFER CHARACTERS BCC 5$ 4$: ERROR 5$: CMP OUTBUF,OBUF1 ;WAS THIS BUFFER 1? BNE 6$ ;NO MOV OBUF2,OUTBUF ;YES, USE BUFFER 2 NEXT MOV OBUFE,OBFEND BR 7$ 6$: MOV OBUF1,OUTBUF ;WAS BUFFER 2, SWITCH TO BUFFER 1 MOV OBUF2,OBFEND 7$: MOV OUTBUF,OUTPTR ;RESET OUTPUT POINTER RTS PC .DSABL LSB ;PUT A TERMINAL COMMAND IN OUTPUT BUFFER COMAND: MOVB #ESC,(R2)+ ;COMMANDS START WITH AN ESCAPE MOV R0,-(SP) MOV R1,-(SP) MOV (R5)+,R1 ;STRING TO TRANSFER 1$: MOVB (R1)+,R0 ;NEXT CHARACTER BEQ 2$ ;END OF STRING MOVB R0,(R2)+ ;TRANSFER IT BR 1$ ;LOOP 2$: MOV (SP)+,R1 MOV (SP)+,R0 RTS R5 ;DECODE NUMBER IN R0 AND TRANSFER IT TO OUTPUT BUFFER PUTNUM: CMP R0,#100. ;AT LEAST 100? BLT 1$ ;NO SUB #100.,R0 ;YES, OUTPUT LEADING 1 MOVB #'1,(R2)+ 1$: MOV R1,-(SP) CMP R0,#10. ;AT LEAST 10? BLT 3$ ;NO MOV #'0-1,R1 ;YES, DIVIDE BY 10 2$: INC R1 SUB #10.,R0 BGE 2$ ADD #10.,R0 MOVB R1,(R2)+ ;OUTPUT TENS DIGIT 3$: ADD #'0,R0 ;OUTPUT ONES DIGIT MOVB R0,(R2)+ MOV (SP)+,R1 RTS PC ;SET INPUT POINTER TO PROPER FILE POSITION (FROM R5 STACK) SETPTR: CMP 4(R5),CURBLK ;PROPER BLOCK ALREADY IN CORE? BEQ 1$ ;YES MOV 4(R5),CURBLK ;NO, GET IT JSR PC,SETBLK 1$: MOV 2(R5),INPTR ;RESET INPUT POINTER MOV (R5),HPOS ;AND HORIZONTAL POSITION RTS PC ;SET CURRENT BLOCK .ENABL LSB SETBLK: .READW #AREA,#INCHAN,INBUF,INLEN,CURBLK ;READ PROPER AREA INTO CORE BCC 1$ TSTB @#ERRBYT ;END OF FILE? BEQ 1$ ;YES, DON'T WORRY ERROR 1$: ASL R0 ;NUMBER OF BYTES TRANSFERED ADD INBUF,R0 ;FIND LASTWD (ACTUALLY, NEXT WORD AFTER LAST) MOV R0,LASTWD ;SAVE IT RTS PC .DSABL LSB ;GET A CHARACTER FROM INPUT BUFFER, SKIP ON SUCCESS GETCHR: CMP INPTR,IBFEND ;AT END OF BUFFER? BNE 1$ ;NO ADD IBLKS,CURBLK ;CALCULATE NEXT BLOCK TO READ JSR PC,SETBLK ;GET IT MOV INBUF,INPTR ;RESET INPUT POINTER 1$: CMP INPTR,LASTWD ;AT END OF FILE? BEQ 2$ ;YES, FAILURE RETURN MOVB @INPTR,R0 ;NO, TRANSFER A CHARACTER INC INPTR ;UPDATE POINTER ADD #2,(SP) ;SUCCESSFUL RETURN 2$: RTS PC ;ERROR HANDLER ERROR: .PRINT #TRESET ;RESET TERMINAL .PRINT #ERRMSG ;PRINT MESSAGE HEADER .PRINT (R5) ;ACTUAL MESSAGE BR EXIT2 ;SKIP RESET SO MESSAGE WON'T DISAPPEAR ;NORMAL EXIT AND ERROR ENTRY EXIT: .PRINT #TRESET ;RESET TERMINAL EXIT2: ;; CMP STATSV,#-1 ;TERMINAL STATUS CHANGED? ;; BEQ 1$ ;NO ;; MOV STATSV,TTSTAT ;YES, RESTORE OLD STATUS ;; .MTSET #AREA,#TTSTAT,TRMNUM 1$: .EXIT ;QUIT ;BEGINNING OF BUFFER AREA ABOVE PROGRAM BUFFER: .END START