.TITLE SCREEN SCOPE "WATCH" FOR TECO .NLIST TTM .LIST TOC,MEB,BEX .DSABL REG,GBL .SBTTL SCOPE "WATCH" FOR TECO ; LAST EDIT ON 12-MAR-80 BY MARK BRAMHALL .IDENT /V36/ .SBTTL ASSEMBLY PARAMETERS ; I$$SOB ASSEMBLE FOR HARDWARE 'SOB' INSTRUCTION (D=NO) ; I$$MUL ASSEMBLE FOR HARDWARE 'MUL' INSTRUCTION (D=NO) .SBTTL GENERAL PDP-11 DEFINITIONS ; GENERAL REGISTER DEFINITIONS R0 = %0 R1 = %1 R2 = %2 R3 = %3 R4 = %4 R5 = %5 SP = %6 PC = %7 .SBTTL ASCII CHARACTER DEFINITIONS TAB = 011 ;ASCII HORIZONTAL TAB LF = 012 ;ASCII LINE FEED VT = 013 ;ASCII VERTICAL TAB FF = 014 ;ASCII FORM FEED CR = 015 ;ASCII CARRIAGE RETURN ESC = 033 ;ASCII ESCAPE (ALSO CALLED ALTMODE) SPACE = 040 ;ASCII SPACE DEL = 177 ;ASCII DELETE (ALSO CALLED RUBOUT) .SBTTL GRAPHIC SYMBOL DEFINITIONS OVRSYM = 1. ;A LINE WHICH OVERFLOWS THE SCREEN'S WIDTH LFDSYM = 2. ;CURSOR POSITIONED ON IMMEDIATELY AFTER ;ALSO, "SEE ALL" MODE SYMBOL FOR CTLSYM = 3. ;"SEE ALL" MODE SYMBOL FOR CONTROL CHARACTER FLAG VTBSYM = 4. ;"SEE ALL" MODE SYMBOL FOR EOBSYM = 5. ;AT END OF BUFFER ENDING WITHOUT FFDSYM = 6. ;AT END OF BUFFER ENDING WITH ;ALSO, "SEE ALL" MODE SYMBOL FOR TABSYM = 7. ;"SEE ALL" MODE SYMBOL FOR NULSYM = 8. ;"SEE ALL" MODE SYMBOL FOR NULL SPACING RETSYM = 9. ;"SEE ALL" MODE SYMBOL FOR OVPSYM = 10. ;"SEE ALL" MODE SYMBOL FOR OVERPRINT ESCSYM = 11. ;"SEE ALL" MODE SYMBOL FOR .SBTTL DEFAULT AND SET UP THE ASSEMBLY PARAMETERS .IIF NDF I$$SOB, I$$SOB=0 ;DEFAULT TO NO HARDWARE 'SOB' .IF EQ I$$SOB .MACRO SOB REG,DST DEC REG BNE DST .ENDM SOB .SBTTL ASSEMBLED WITHOUT HARDWARE 'SOB' INSTRUCTION .IFF ;EQ I$$SOB .SBTTL ASSEMBLED WITH HARDWARE 'SOB' INSTRUCTION .ENDC ;EQ I$$SOB .IIF NDF I$$MUL, I$$MUL=0 ;DEFAULT TO NO HARDWARE 'MUL' .IF EQ I$$MUL .MACRO MULHSZ JSR PC,MULHSZ .ENDM MULHSZ .SBTTL ASSEMBLED WITHOUT HARDWARE 'MUL' INSTRUCTION .IFF ;EQ I$$MUL .MACRO MULHSZ MUL HTSIZE+RWSIZE(R5),R1 .GLOBL RWSIZE .ENDM MULHSZ .SBTTL ASSEMBLED WITH HARDWARE 'MUL' INSTRUCTION .ENDC ;EQ I$$MUL .SBTTL SCOPE "WATCH" ROUTINE ;+ ; SCREEN - SCOPE "WATCH" ROUTINE. ; ; IF NFLG(R5) >= 0 THEN "W" COMMAND ; ; R0 = N OF "NW" IF "NW" ; NWATCH(R5) IF "W" ; ; JSR PC,SCREEN ; ; IF NFLG(R5) < 0 THEN ":W" COMMAND ; ; R0 = N OF "N:W" OR "M,N:W" ; ; IF CFLG(R5) <> -1 THEN "N:W" COMMAND ; ; IF CFLG(R5) = -1 THEN "M,N:W" COMMAND ; ; M(R5) = M OF "M,N:W" ; ; JSR PC,SCREEN ; ; R0 = RETURNED VALUE ;- .PSECT SCREEN,RO,I,GBL,REL,OVR SCREEN: BIT #ET$IAS,ETYPE(R5) ;IS THE SCOPE AVAILABLE? BEQ 30$ ;NOPE, QUICKLY EXIT... TST NFLG(R5) ;WHAT KIND OF CALL IS THIS? BPL 10$ ;"W" COMMAND, GO PROCESS IT MOV #SCRPRM,-(SP) ;":W" COMMAND, GO OFF TO PARAMETER HANDLING BR 50$ ; AFTER LOADING THE DUMB OVERLAY... .GLOBL ET$IAS, ETYPE, NFLG .SBTTL HANDLE W COMMANDS (SCOPE UPDATE) ;+ ; HANDLE W COMMANDS (SCOPE UPDATE). ; ; W NOP ; 0W SET DEFAULT CURSOR LINE; FORGET EVERYTHING ; +NW SET CURSOR LINE TO N; FORGET EVERYTHING ; -1W UPDATE SCOPE SCREEN ; -NW FORGET TOP N-1 LINES OF SCREEN ; -1000W FORGET THAT OUTPUT WAS DONE ;- 10$: TST R0 ;CHECK OUT THE ARGUMENT'S SIGN BMI 40$ ;ARG <0, GO PROCESS A REAL CALL BEQ 20$ ;ARG =0, GO FORGET EVERYTHING CMP R0,NWATCH(R5) ;ARG >0, IS IT THE DEFAULT VALUE? BEQ 30$ ;YES, DO NOTHING 20$: CLR INITFL+RWSIZE(R5) ;FORGET THE ENTIRE SCREEN CLR MRKFLG+RWSIZE(R5) ;CLEAR ANY SET "MARK" CLR TOPDOT+RWSIZE(R5) ;CLEAR LAST STARTING POSITION MOV #SPACE,SEEALL+RWSIZE(R5) ;RESET "SEEING ALL" FLAG CLR HLDFLG+RWSIZE(R5) ;RESET "HOLD SCREEN" FLAG 30$: RTS PC ;EXIT 40$: MOV #SCRUPD,-(SP) ;GO OFF TO PROCESS A REAL CALL 50$: JMP SCRLOD ; AFTER LOADING THE DUMB OVERLAY... .GLOBL NWATCH, RWSIZE, SCRLOD .SBTTL START PROCESSING A REAL CALL .PSECT SCRSUB,RO,I,GBL,REL,CON .ENABL LSB SCRUPD::JSR R0,SCRSAV ;SAVE REGISTERS, SET RETURN, ETC. COM R0 ;MAKE COUNT OF CHANGED LINES POSITIVE BEQ DOIT ;BRANCH IF NO SPECIAL SCREEN MODS CMP R0,#1000.-1 ;SPECIAL CASE (<= -1000.)? BHIS 20$ ;YES, JUST RESET THE OUTPUT DONE FLAG MOV VTSIZE+RWSIZE(R5),R1 ;PUT MAXIMUM LEGAL COUNT INTO ODD REG CMP R0,R1 ;IS ARGUMENT OVER MAXIMUM? BHI CLRSCN ;YES, USE MAXIMUM MOV R0,R1 ;NO, USE ARGUMENT CLRSCN: MULHSZ ;MULTIPLY LINE COUNT TO GET BYTES ASR R1 ; THEN MAKE THAT WORDS MOV MAPPTR+RWSIZE(R5),R0 ;GET A POINTER TO THE MAP 10$: CLR (R0)+ ;CLEAR WHAT WE THINK IT LOOKS LIKE SOB R1,10$ ; FOR THAT MANY LINES 20$: MOV #-1,PRELIN+RWSIZE(R5) ;CLOBBER LAST KNOWN CURSOR BIC #2,OUTDNE(R5) ;CLEAR TERMINAL OUTPUT FLAG (+2) RTS PC ; AND EXIT .DSABL LSB .GLOBL RWSIZE, OUTDNE .SBTTL START SCREEN UPDATE, CHECK FOR HOLDING SCREEN DOIT: JSR R4,SETJSR ;SET UP FOR .WORD FTRANS ; COUNTING LINES MOV P(R5),R0 ;GET CURRENT POINTER MOV R0,-(SP) ; AND SAVE IT MOV #SCROUT,-(SP) ;GUESS AT VALID SCREEN "HOLD" TST HLDFLG+RWSIZE(R5) ;TRY TO "HOLD" THE SCREEN? BEQ FCURLN ;NOPE MOV TOPDOT+RWSIZE(R5),R4 ;YEP, GET TOP-OF-SCREEN POSITION +1 DEC R4 ; THEN MAKE IT ZERO BASED MOV R4,LINPTR+RWSIZE(R5) ;SAVE IT IN CASE WE USE IT MOV ZZ(R5),R1 ;GET TOTAL SIZE OF TEXT BUFFER CMP R4,R1 ;IS TOP POSITION OUTSIDE OF BUFFER? BHI FCURLN ;YES, FORGET HOLDING THE SCREEN THIS TIME... CMP R0,R4 ;IS CURRENT POINTER BELOW TOP POSITION? BLO FCURLN ;YES, DON'T HOLD SCREEN THIS TIME... ADD TXSTOR(R5),R0 ;MAKE CURRENT POINTER ABSOLUTE MOV R0,CURPOS+RWSIZE(R5) ; AND SET IT INC BUINDX+RWSIZE(R5) ;SET FAKE NON-ZERO MAP POINTER SUB R4,R1 ;FIND SIZE TO END OF BUFFER JSR PC,DOTEXT ; AND SPAN LINES IN THAT TEXT TST CURABS+RWSIZE(R5) ;DID WE SPAN THE CURSOR LOCATION? BEQ 10$ ;NOPE, CAN'T HOLD THIS TIME... MOV HLDFLG+RWSIZE(R5),R2 ;YEP, GET "HOLD" FLAG AGAIN BMI CHKSCN ;FLAG <0 => ALWAYS HOLD SCREEN IF POSSIBLE CMP CURLIN+RWSIZE(R5),R2 ;ELSE CHECK FOR TOO FAR UP ON SCREEN BLO 10$ ;TOO FAR UP, DON'T HOLD THE SCREEN MOV VTSIZE+RWSIZE(R5),R3 ;GET SCREEN'S SIZE SUB R2,R3 ; AND FIND FIRST ILLEGAL BOTTOM LINE CMP CURLIN+RWSIZE(R5),R3 ;CHECK FOR TOO FAR DOWN ON SCREEN BLO CHKSCN ;WITHIN RANGE, WE CAN HOLD THE SCREEN 10$: JSR R4,SETJSR ;CAN'T HOLD, RE-SET UP FOR .WORD FTRANS ; COUNTING LINES .GLOBL P, RWSIZE, ZZ, TXSTOR .SBTTL LOCATE CURSOR LINE FCURLN: CLR R0 ;SET THE ARGUMENT FOR "0L" JSR PC,.VVV.V ;DO 0L (START OF CURSOR LINE) MOV R1,R4 ;SET START OF THE CURSOR LINE MOV ZZ(R5),R1 ;GET TOTAL SIZE OF TEXT BUFFER SUB R4,R1 ; AND FIND SIZE TO END OF BUFFER JSR PC,DOTEXT ;NOW COUNT LINES IN THAT TEXT MOV VTSIZE+RWSIZE(R5),R0 ;SET THE SCREEN'S SIZE MOV NWATCH(R5),(SP) ;GET THE STANDARD CURSOR LINE NUMBER BEQ 10$ ;ZERO, MAKE IT VALID CMP R0,(SP) ;MIGHT BE VALID, CHECK UPPER LIMIT BHI 30$ ;IT IS VALID, USE IT 10$: MOV R0,R2 ;SET SCREEN'S SIZE MOV #-1,(SP) ;PRESET COUNTER FOR DIVIDE BY 3 20$: INC (SP) ;COUNT IN ANSWER SUB #3,R2 ; AND SUBTRACT FROM SIZE BHIS 20$ ; THEN LOOP IF MORE TO GO ASL (SP) ;FINALLY FORM 2/3RD'S OF SIZE 30$: SUB BUSTRT+RWSIZE(R5),R0 ;CALC LINE NUMBER OF CURSOR LINE CMP R0,(SP) ;SHOULD WE USE THE CALCULATED VALUE? BLOS 40$ ;NOPE, USE STANDARD MOV R0,(SP) ;YEP, USE CALCULATED 40$: MOV #FSCRLN,-(SP) ;SET FOR FULL SCREEN ADJUSTMENT .ENABL LSB CHKSCN::MOV CHCKBP+RWSIZE(R5),R2 ;GET POINTER TO CHECKING BUFFER MOV (SP),-(SP) ;MOVE RETURN ADDRESS UP A WORD MOV R2,2(SP) ; SO WE CAN SAVE START OF THE BUFFER CLR (R2) ;INDICATE NO MOVEMENT INITIALLY & FILL BUFFER INC INITFL+RWSIZE(R5) ;KNOWN SCREEN STATE? BMI 20$ ;UNKNOWN, BUT ALL FIXED UP (WAS -2) BNE 10$ ;NOPE (WASN'T -1) TST OUTDNE(R5) ;HAS ANY OUTPUT BEEN DONE? BEQ 30$ ;NO 10$: MOV #FIXSEQ,R3 ;SET SEQUENCE TO FIX UP TERMINAL JSR PC,DOTYPE ; AND GO DO IT 20$: INC (R2) ;SET FLAG TO AVOID FILLING CHECKING BUFFER MOV VTSIZE+RWSIZE(R5),R1 ;SET THE FULL SCREEN LENGTH JSR PC,CLRSCN ; AND GO CLEAR OUT THE SCREEN MAP, ETC. 30$: TST PRELIN+RWSIZE(R5) ;DO WE KNOW WHERE THE CURSOR IS NOW? BPL 40$ ;YES SCRHOM::MOV #HOMSEQ,R3 ;NO, SET SEQUENCE TO HOME JSR PC,DOTYPE ; AND GO DO IT CLR PRELIN+RWSIZE(R5) ;CURSOR LINE IS NOW ZERO CLR PRECOL+RWSIZE(R5) ;CURSOR COLUMN IS NOW ZERO 40$: RTS PC ;OFF TO WHOEVER... .DSABL LSB .GLOBL .VVV.V, ZZ, RWSIZE, NWATCH, OUTDNE, FIXSEQ, HOMSEQ .SBTTL FIND LINES FOR SCREEN FTOPLN: MOV CHCKBP+RWSIZE(R5),R2 ;GET POINTER TO CHECKING BUFFER AGAIN MOV R2,-(SP) ; AND SAVE IT CLR (R2) ;TRY FILLING IT AGAIN MOV #12.,R0 ;SET FOR 12L JSR PC,.VVV.V ; AND GO USE TECO'S MOVER FSCRLN: JSR R4,SETJSR ;SET UP FOR .WORD FTRANS ; FINDING CURSOR LINE CLR (R3) ; CLEARING "NUMCHR" (# CHARS FOUND) 10$: JSR R4,SETJSR ;RE-SET UP FOR .WORD FTRANS ; FINDING CURSOR LINE MOV R2,-(R3) ; RE-SAVING THAT "BUSTRT" VALUE MOV P(R5),LINPTR+RWSIZE(R5) ;SAVE OLD LINE INDEX BEQ TRYTOP ;AT TOP OF PAGE, QUIT THIS LOOP MOV #-1,R0 ;GET TO START OF PREVIOUS TEXT LINE JSR PC,.VVV.V ; USING TECO'S MOVER MOV R1,R4 ;NEW 'P' IS RETURNED IN R1, MAKE COPY SUB LINPTR+RWSIZE(R5),R1 ;MAKE R1 CONTAIN NEG R1 ; ONLY CHARS IN -1L MOV (SP),R2 ;GET CHECKING BUFFER POINTER TSTB (R2) ;IS IT ALREADY FILLED? BEQ 20$ ;NO, BUT ALWAYS TRY FILLING IT BPL 50$ ;NO, BUT WE'RE NOT TRYING TO FILL IT CMP NUMCHR+RWSIZE(R5),#15. ;YES, BUT FILLED WITH ENOUGH CHARS? BHIS 50$ ;ALL FILLED UP CMP R1,NUMCHR+RWSIZE(R5) ;WOULD THIS LINE HAVE MORE CHARACTERS? BLOS 50$ ;NO, DON'T TRY IT 20$: TST BUSTRT+RWSIZE(R5) ;IS THIS THE FIRST TIME THROUGH? BEQ 30$ ;YES, LEAVE IT AS A "SHORT" LINE MOV R1,NUMCHR+RWSIZE(R5) ;NO, SAVE # OF CHARACTERS IN THIS LINE 30$: MOV #-1,(R2)+ ;MARK AS TENTATIVELY USED NOW MOV R2,BUINDX+RWSIZE(R5) ;SET STARTING FILL IN POINTER MOV #CCHAR,OUTCHR+RWSIZE(R5) ; AND CHANGE THE OUTPUT ROUTINE MOV HTSIZE+RWSIZE(R5),R0 ;GET SIZE OF LINE IN BYTES ASR R0 ; THEN MAKE THAT WORDS 40$: MOV (PC)+,(R2)+ ;BLANK .BYTE SPACE,SPACE ; USING 'S SOB R0,40$ ; THE WHOLE FILLIN BUFFER 50$: MOV BUSTRT+RWSIZE(R5),SVSTRT+RWSIZE(R5) ;SAVE STARTING VALUE JSR PC,DOTEXT ;FORMAT A LINE MOV BUSTRT+RWSIZE(R5),R0 ;GET FINISHING LINE NUMBER MOV (SP),R2 ;GET BACK CHECKING BUFFER POINTER TST (R2)+ ;DOES CHECKING BUFFER LINE NEED SETTING? BPL 60$ ;NOPE MOVB R0,-(R2) ;YEP, SO SAVE LINE NUMBER 60$: CMP R0,2(SP) ;WOULD WE BE AT TOP? BLO 10$ ;BRANCH IF NOT MOV SVSTRT+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;RESTORE CORRECT VALUE .GLOBL RWSIZE, .VVV.V, P .SBTTL CHECK THE CHECKING BUFFER .ENABL LSB 10$: MOV (SP)+,R2 ;GET CHECKING BUFFER POINTER TSTB (R2)+ ;DID WE FILL IT? BEQ 20$ ;NO, BUT WE WANTED TO BGT SCROUT ;NO, AND WE DIDN'T EVEN TRY... TST HLDFLG+RWSIZE(R5) ;YES, ARE WE TRYING TO FULLY HOLD SCREEN? BMI SCROUT ;WE'RE FULLY HOLDING, DON'T ATTEMPT TO SCROLL MOVB (R2)+,R0 ;NOT HOLDING, SAVE THE "BUSTRT" VALUE MOV BUSTRT+RWSIZE(R5),R1 ;GET ENDING "BUSTRT" VALUE SUB R0,R1 ;CALCULATE THE BUFFERED LINE NUMBER MULHSZ ;FIND OFFSET OF THE BUFFERED LINE CLR -(SP) ;START MOVEMENT AT 0 CLR R4 ; WHICH IS AN OFFSET OF 0 BR FNDMOV ;ENTER THE MOVE CHECKING LOOP TRYTOP: COM 2(SP) ;SET CURSOR LINE <0 IF FIRST TIME THROUGH BPL 10$ ;SECOND TIME, ALWAYS TRY TO MATCH LINES CMP NUMCHR+RWSIZE(R5),#15. ;FIRST TIME, DID WE GET ENOUGH CHARS? BHIS 10$ ;GOT ENOUGH, SO CHECK FOR A MATCH NOMOVE: TST (SP)+ ;JUNK THE STACK ITEM 20$: TST (SP) ;SHOULD WE TRY ANOTHER WAY (<0 CURSOR LINE)? BMI FTOPLN ;YEP, SO GO TRY THAT OTHER WAY... BR SCROUT ;NOPE, JUST PUNT .DSABL LSB .GLOBL RWSIZE .SBTTL ATTEMPT TO SCROLL THE SCREEN .ENABL LSB 10$: NEG (SP) ;REVERSE MOVEMENT NUMBER NEG R4 ; AND REVERSE MOVEMENT OFFSET BMI FNDMOV ;NOW NEGATIVE, TRY IT CMP (SP),#12. ;NOW POSITIVE, SHOULD WE CONTINUE? BHI NOMOVE ;NOPE, CAN'T FIND A MATCHING LINE INC (SP) ;GO 1 PLACE FURTHER ADD HTSIZE+RWSIZE(R5),R4 ; IN BOTH PLACES FNDMOV: MOV R1,R2 ;COPY THE BUFFERED LINE'S OFFSET ADD R4,R2 ;BUILD OFFSET POINTER FOR THIS TRY BMI 10$ ;BELOW MAP, DON'T TRY IT ADD MAPPTR+RWSIZE(R5),R2 ;MAKE BUFFERED LINE POINTER ABSOLUTE CMP R2,TXSTOR(R5) ;IS THIS OFFSET OUT OF THE SCREEN? BHIS 10$ ;TOO FAR OUT, GO TRY ANOTHER MOVE MOV CHCKBP+RWSIZE(R5),R3 ;GET A POINTER TO CHECK BUFFER TST (R3)+ ; SKIPPING THE FLAG WORD MOV HTSIZE+RWSIZE(R5),R0 ;GET LINE SIZE IN BYTES ASR R0 ; THEN MAKE THAT WORDS 20$: MOV (R2)+,-(SP) ;GET WORD FROM THE SCREEN MAP BIC (PC)+,(SP) ; AND REMOVE ANY FLAG BIT(S) .BYTE 200,200 CMP (R3)+,(SP)+ ;DOES CHECK MATCH SCREEN? BEQ 30$ ;YES, AND EXACTLY AT THAT CMP -2(R2),(PC)+ ;NO, WERE THOSE CHARACTERS "FORGOTTEN"? .BYTE 200,200 BNE 10$ ;NOPE, A TRUE MISMATCH... 30$: SOB R0,20$ ;LOOP .DSABL LSB .GLOBL RWSIZE, TXSTOR .SBTTL DO THE SCREEN SCROLLING DOMOVE: MOV (SP)+,R1 ;GET THE MOVEMENT AMOUNT CLR R2 ;SET CURSOR TO COLUMN 0 MOV VTSIZ1+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;SET LAST SCREEN LINE MOV #SCUSEQ,R3 ;SEQUENCE TO RAISE SCREEN MOV R1,R4 ;SAVE THAT MOVE COUNT BEQ SCROUT ;NO MOVEMENT, SO QUIT BPL 10$ ;ASSUMPTION RIGHT, MOVING SCREEN UP MOV CRTYPE(R5),R3 ;MOVING DOWN, GET THE SCOPE TYPE INDEX CMPB @SCDSEQ(R3),#200 ;REALLY A SEQUENCE THERE? BEQ SCROUT ;NOPE, JUST PUNT... MOV #SCDSEQ,R3 ;SEQUENCE TO LOWER SCREEN CLR BUSTRT+RWSIZE(R5) ;FIX TO LOWER SCREEN NEG R4 ;MAKE COUNT POSITIVE 10$: JSR PC,DOSEQ ;POSITION THE SCREEN SOB R4,10$ ; THE CORRECT NUMBER OF TIMES MOV MAPPTR+RWSIZE(R5),R2 ;GET POINTER TO START OF MAP MOV TXSTOR(R5),R0 ;SET POINTER TO END OF MAP MULHSZ ;CALC OFFSET TO START MOVE FROM TST R1 ;CHECK THE MOVE DIRECTION BMI 40$ ;BRANCH IF TO MOVE INTERNAL MAP DOWN ADD R2,R1 ;ADD IN MAP BASE 20$: MOV (R1)+,(R2)+ ;MOVE THE DATA CMP R1,R0 ;DID WE MOVE LAST DATA BYTE? BLO 20$ ;BRANCH IF NOT 30$: MOV (PC)+,(R2)+ ;FILL REMAINDER .BYTE SPACE,SPACE ; WITH BLANKS CMP R2,R0 ;ARE WE AT END OF TABLE? BLO 30$ ;BRANCH IF NOT BR SCROUT ;ELSE DONE SHIFTING 40$: ADD R0,R1 ;POINT TO END OF DATA TO BE MOVED 50$: MOV -(R1),-(R0) ;MOVE THE DATA CMP R1,R2 ;ARE WE AT THE TOP? BHI 50$ ;BRANCH IF NOT 60$: MOV (PC)+,-(R0) ;FILL REMAINDER .BYTE SPACE,SPACE ; WITH BLANKS CMP R0,R2 ;ARE WE AT TOP? BHI 60$ ;BRANCH IF NOT .GLOBL RWSIZE, SCUSEQ, CRTYPE, SCDSEQ, TXSTOR .SBTTL FIND MARK'D REGION, OUTPUT SCREEN IMAGE SCROUT::TST (SP)+ ;POP THAT JUNK STACK ITEM JSR R4,SETJSR ;SET UP FOR .WORD RTRANS ; THE REAL OUTPUT MOV LINPTR+RWSIZE(R5),R4 ;GET STARTING POINT OF TEXT MOV R4,TOPDOT+RWSIZE(R5) ; AND SAVE IT INC TOPDOT+RWSIZE(R5) ; MAKING IT STARTING POINT +1 MOV ZZ(R5),R1 ;GET END OF TEXT SUB R4,R1 ; AND FIND AMOUNT OF TEXT TO DO MOV MAPPTR+RWSIZE(R5),BUINDX+RWSIZE(R5) ;INIT INDEX INTO THE MAP MOV (SP),P(R5) ;FINALLY REFIX POINTER ADD TXSTOR(R5),(SP) ;COMPUTE CURSOR POINTER MOV CRTYPE(R5),R3 ;GET THE SCOPE TYPE CMPB @MONSEQ(R3),#200 ;DOES THE MARK'D REGION FEATURE EXIST? BEQ 20$ ;NOPE, SO DON'T TRY FOR IT... MOV MRKFLG+RWSIZE(R5),R0 ;GET "MARK" IF ANY BEQ 20$ ;NONE DEC R0 ;ONE, MAKE "MARK" LESS ONE ADD TXSTOR(R5),R0 ; AND ABSOLUTE MOV (SP),MRKHGH+RWSIZE(R5) ;SAVE HIGH LIMIT OF MARK'D REGION CMP R0,(SP) ;WAS THAT REALLY THE HIGH LIMIT? BLOS 10$ ;YES MOV R0,MRKHGH+RWSIZE(R5) ;NO, THIS IS THE HIGH LIMIT MOV (SP),R0 ; AND THIS IS THE REAL LOW LIMIT 10$: MOV R0,MRKLOW+RWSIZE(R5) ;SAVE LOW LIMIT OF MARK'D REGION 20$: MOV (SP),CURPOS+RWSIZE(R5) ;SET POSITION OF CURSOR JSR PC,DOTEXT ;NOW REALLY UPDATE THE SCREEN MOV (SP)+,R4 ;GET CURSOR POSITION IN TEXT BUFFER MOV VTSIZ1+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;PRESET CURSOR AT LOWER MOV HTSIZ1+RWSIZE(R5),R2 ; RIGHT OF SCREEN MOV CURABS+RWSIZE(R5),R1 ;DID WE FIND THE CURSOR? BEQ 30$ ;NO MOV CURLIN+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;SET THE LINE FOR CURSOR MOV CURCOL+RWSIZE(R5),R2 ; AND SET THE COLUMN TST P(R5) ;CURSOR AT START OF TEXT BUFFER? BEQ 30$ ;YES, CAN'T BE BETWEEN (NO PRIOR) CMP P(R5),ZZ(R5) ;CURSOR AT END OF TEXT BUFFER? BHIS 30$ ;YES, CAN'T BE BETWEEN (NO CURRENT) CMPB (R4),#LF ;ELSE CHECK FOR CURRENT BEING A BNE 30$ ;NOT TRUE CMPB -(R4),#CR ;TRUE, CHECK FOR PRIOR BEING A BNE 30$ ;NOT TRUE EITHER CMPB (R4)+,(R4)+ ;ALL TRUE, CORRECT TEXT POINTER MOV #LFDSYM,R0 ;SET BETWEEN AND SYMBOL JSR PC,VTCHAR ; AND GO OUTPUT THAT SYMBOL DEC R2 ;BACK UP THE COLUMN NUMBER 30$: JSR PC,SETCUR ;SET THE FINAL CURSOR POSITION .GLOBL RWSIZE, ZZ, P, TXSTOR, CRTYPE, MONSEQ .SBTTL ALL DONE, FINISH UP FINISH: TST GRPON+RWSIZE(R5) ;DID WE LEAVE GRAPHIC MODE TURNED ON? BEQ 10$ ;NO MOV #GOFSEQ,R3 ;YES, SET SEQUENCE TO TURN IT OFF JSR PC,DOTYPE ; AND GO DO IT 10$: TST MRKON+RWSIZE(R5) ;DID WE LEAVE MARK'D REGION TURNED ON? BEQ 20$ ;NO MOV #MOFSEQ,R3 ;YES, SET SEQUENCE TO TURN IT OFF JSR PC,DOTYPE ; AND GO DO IT 20$: MOV #-1,INITFL+RWSIZE(R5) ;NOW WE KNOW WHAT'S ON THE SCREEN SCRDNE::JSR PC,TYPEBC ;FORCE OUT ANY PARTIAL BUFFER CLR OUTDNE(R5) ;CLEAR TERMINAL OUTPUT FLAG RTS PC ;FINALLY WE CAN EXIT .GLOBL RWSIZE, GOFSEQ, MOFSEQ, TYPEBC, OUTDNE .SBTTL OUTPUT SOME TEXT ;+ ; DOTEXT - OUTPUT SOME TEXT. ; ; R1 = CHARACTER COUNT ; R4 -> TEXT BUFFER (RELATIVE "TXSTOR") ; ; JSR PC,DOTEXT ; ; R0 = UNDEFINED ; R1 = UNDEFINED ; R2 = UNDEFINED ; R3 = UNDEFINED ; R4 = UNDEFINED ;- DOTEXT: ADD TXSTOR(R5),R4 ;MAKE TEXT POINTER ABSOLUTE MOV R1,-(SP) ;SAVE THE CHARACTER COUNT ;CLC ;SET C=0 FOR NOT OVERPRINT (FROM THE 'ADD') BR 60$ ; AND GO START DOING THAT TEXT... 10$: MOV #RETSYM,R0 ;ASSUME SEEING ALL, SET THE SYMBOL MOV (SP),-(SP) ;MORE CHARACTER(S) COMING (& SAVE >=0 FLAG)? BNE 20$ ;YEP, CHECK FOR NEXT MOV R4,-(SP) ;NOPE, COPY CURRENT CHARACTER +1 POINTER SUB TXSTOR(R5),(SP) ; AND MAKE IT RELATIVE CMP (SP)+,ZZ(R5) ;ARE WE AT THE END OF THE BUFFER? BLO 40$ ;NOT AT END, SO NO OVERPRINT BR 30$ ;AT END, CALL IT OVERPRINT 20$: CMPB (R4),#LF ;IS NEXT A ? BEQ 40$ ;IT IS , ALL IS O.K. 30$: INC R0 ;NOT , SET THE OVERPRINT SYMBOL .IIF NE RETSYM+1-OVPSYM, .ERROR ;THE ABOVE WON'T WORK COM (SP) ; AND FLAG OVERPRINT WITH <0 FLAG 40$: TST SEEALL+RWSIZE(R5) ;REALLY SEEING ALL? BPL 50$ ;NO JSR PC,310$ ;GO OUTPUT [OVERPRINT] SYMBOL IF WE CAN 50$: JSR PC,320$ ;GO SET HIGHEST COLUMN NUMBER ASL (SP)+ ;WHAT DOES THAT FLAG SAY (C=1 IF OVERPRINT)? 60$: BIC R2,R2 ;RESET COLUMN COUNTER (KEEPING C-BIT) MOV BUINDX+RWSIZE(R5),R1 ;RESET MAP POINTER BCC 120$ ;IF C=0 THEN NOT OVERPRINT, JUST CONTINUE TST SEEALL+RWSIZE(R5) ;IT IS OVERPRINT, SEEING ALL? BMI 170$ ;YES, GO TO A NEW LINE TST OVRPOS+RWSIZE(R5) ;ELSE IS THIS A CONTINUATION OVERFLOW LINE? BPL 120$ ;NOPE, JUST CONTINUE BR 100$ ;YEP, START THE LINE WITH "OVRSYM" AGAIN... .GLOBL TXSTOR, ZZ, RWSIZE 70$: CMPB (R4),#CR ;AVOID SEQUENCE IF OVERFLOW ON BEQ 140$ ;BRANCH IF MOV #OVRSYM,R0 ;ELSE SET THE OVERFLOW SYMBOL BIT #ET$TRU,ETYPE(R5) ;TRUNCATING OVERFLOW LINES? BEQ 80$ ;NO, DISPLAY OVERFLOW ON NEXT LINE INC R4 ;YES, EAT THE CHARACTER JSR PC,310$ ;OUTPUT OVERFLOW SYMBOL IF NEEDED CMP R2,OVRPOS+RWSIZE(R5) ;A NEW "OVRSYM" POSITION? BLOS 120$ ;NOPE, JUST CONTINUE MOV R2,OVRPOS+RWSIZE(R5) ;YEP, SET THE NEW HIGHER POSITION BR 120$ ; THEN CONTINUE 80$: INC (SP) ;REMEMBER TO GET THE CHARACTER AGAIN TST SEEALL+RWSIZE(R5) ;SEEING ALL? BPL 90$ ;NO JSR PC,@OUTCHR+RWSIZE(R5) ;YES, PUT OVERFLOW SYMBOL AT LINE'S END 90$: JSR PC,320$ ;GO SET HIGHEST COLUMN NUMBER CLR R2 ;SIMULATE CARRIAGE RETURN JSR PC,NEWLIN ; AND GO TO THE NEXT LINE BCS 190$ ;BRANCH IF AT BOTTOM OF SCREEN DEC OVRPOS+RWSIZE(R5) ;INDICATE CONTINUATION OVERFLOW LINE 100$: MOV #OVRSYM,R0 ;SET OVRFLOW SYMBOL FOR CONTINUATION LINE JSR PC,@OUTCHR+RWSIZE(R5) ; AND GO OUTPUT IT MOVB SEEALL+RWSIZE(R5),R0 ;FOLLOW IT WITH OR SYMBOL 110$: JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT A CHARACTER 120$: CMP R4,CURPOS+RWSIZE(R5) ;IS THIS WHERE THE CURSOR BELONGS? BNE 130$ ;BRANCH IF NOT MOV R1,CURABS+RWSIZE(R5) ;SAVE THE MAP POSITION MOV BUSTRT+RWSIZE(R5),CURLIN+RWSIZE(R5) ;SAVE THE LINE NUMBER MOV R2,CURCOL+RWSIZE(R5) ;SAVE THE COLUMN NUMBER CMP R2,HTSIZE+RWSIZE(R5) ;IS THE COLUMN NUMBER ILLEGAL? BLO 130$ ;NOPE MOV HTSIZ1+RWSIZE(R5),CURCOL+RWSIZE(R5) ;YEP, SO FIX IT 130$: DEC (SP) ;KNOCK DOWN CHARACTER COUNT BMI 260$ ;BRANCH IF NO MORE, GO DO END OF SCREEN CMP R2,HTSIZ2+RWSIZE(R5) ;ABOUT TO OVERFLOW? BHIS 70$ ;BRANCH IF TRUE 140$: MOVB (R4)+,R0 ;GET A BYTE OF TEXT BIC #^C<177>,R0 ; AND TRIM TO ONLY 7-BIT ASCII .GLOBL ET$TRU, ETYPE, RWSIZE CMP R0,#DEL ;IS IT ? BEQ 220$ ;BRANCH IF YES (TREAT AS CONTROL CHAR) CMP R0,#SPACE ;IS IT SPECIAL? BHIS 110$ ;BRANCH IF NOT CMP R0,#TAB ;IS IT A ? BEQ 200$ ;BRANCH IF IT IS BLO 220$ ;BRANCH IF MUST BE REGULAR CONTROL CHAR CMP R0,#CR ;IS IT A ? BEQ 10$ ;YES, GO PROCESS BHI 220$ ;BRANCH IF .GT. , MAY BE ... SUB #LF,R0 ;R0=0 FOR , R0=1 FOR , R0=2 FOR ASL R0 ;R0=0 FOR , R0=2 FOR , R0=4 FOR TST SEEALL+RWSIZE(R5) ;SEEING ALL? BPL 180$ ;NO TST (R0)+ ;YES, R0=2 FOR , 4 FOR , 6 FOR .IIF NE LFDSYM-2, .ERROR ;THE ABOVE WON'T WORK .IIF NE VTBSYM-4, .ERROR ;THE ABOVE WON'T WORK .IIF NE FFDSYM-6, .ERROR ;THE ABOVE WON'T WORK MOV R2,-(SP) ;AT LEFT MARGIN (AND SAVE CURRENT COLUMN)? BNE 150$ ;NOPE, TRY TO OUTPUT THE SYMBOL TST RTMOST+RWSIZE(R5) ;YEP, WAS ANYTHING OUTPUT ON THIS LINE? BEQ 150$ ;NOTHING EVER OUTPUT, SO TRY THE SYMBOL CMP R0,#LFDSYM ;SOMETHING OUTPUT, IS IT ? BEQ 160$ ;JUST GO TO THE NEW LINE IF JSR PC,NEWLIN ; OR , GO TO THE NEXT LINE MOV (SP)+,R2 ;RESTORE CORRECT CURRENT COLUMN (A ZERO...) BCS 280$ ;BRANCH IF AT BOTTOM OF SCREEN MOV R2,-(SP) ;RE-SAVE CORRECT CURRENT COLUMN (A ZERO...) 150$: JSR PC,310$ ;GO OUTPUT THE SYMBOL IF WE CAN JSR PC,320$ ;GO SET HIGHEST COLUMN NUMBER 160$: MOV (SP)+,R2 ;RESTORE TO CORRECT CURRENT COLUMN 170$: CLR R0 ;ONLY DO A SINGLE NEW LINE 180$: JSR PC,NEWLIN ;HANDLE A NEW SCOPE LINE 190$: BCS 280$ ;BRANCH IF AT BOTTOM OF SCREEN DEC R0 ;KEEP COUNT FOR 'S AND 'S BMI 120$ ;BRANCH IF DONE WITH CHAR BR 180$ ; ELSE CONTINUE .GLOBL RWSIZE 200$: MOV SEEALL+RWSIZE(R5),R0 ;GET STARTING & CHECK SEEING ALL BPL 210$ ;NOT SEEING ALL, USE THE MOV #TABSYM,R0 ;SEEING ALL, USE SYMBOL INITIALLY 210$: JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT THE CHARACTER BIT R2,#7 ;AT A TAB STOP? BEQ 120$ ;DONE WITH THE TAB IF SO CMP R2,HTSIZ2+RWSIZE(R5) ;ELSE ABOUT TO OVERFLOW LINE? BHIS 120$ ;YES, QUIT MOVB SEEALL+RWSIZE(R5),R0 ;FOLLOW WITH OR SYMBOL BR 210$ ; AND LOOP... 220$: MOV #'$,-(SP) ;GUESS AT (USE "$") TST SEEALL+RWSIZE(R5) ;SEEING ALL? BPL 230$ ;NO MOV #ESCSYM,(SP) ;YES, USE THIS SYMBOL FOR 230$: CMP R0,#ESC ;GOOD GUESS? BEQ 250$ ;YES, GOES AS SPECIFIED ADD #100,R0 ;NO, PUT CHARACTER INTO RANGE BIC #^C<177>,R0 ; AND MASK IT FOR SAFETY ( CASE) MOV R0,(SP) ;SAVE MODIFIED CHARACTER MOV #'^,R0 ;SET UP ARROW AS CONTROL CHARACTER FLAG TST SEEALL+RWSIZE(R5) ;SEEING ALL? BPL 240$ ;NO MOV #CTLSYM,R0 ;YES, USE THE CONTROL CHAR FLAG SYMBOL 240$: JSR PC,@OUTCHR+RWSIZE(R5) ;OUTPUT CONTROL CHARACTER FLAG 250$: MOV (SP)+,R0 ;GET THE CHARACTER BACK BR 110$ ; AND CONTINUE WITH MODIFIED CHARACTER .GLOBL RWSIZE 260$: SUB TXSTOR(R5),R4 ;MAKE TEXT POINTER RELATIVE AGAIN CMP R4,ZZ(R5) ;AT END OF BUFFER NOW? BLO 280$ ;NOPE MOV #EOBSYM,R0 ;YEP, SET END OF BUFFER W/O SYMBOL TST FFFLAG(R5) ;DOES BUFFER END WITH A ? BEQ 270$ ;NO INC R0 ;YES, SET END OF BUFFER W/ SYMBOL .IIF NE EOBSYM+1-FFDSYM, .ERROR ;THE ABOVE WON'T WORK 270$: JSR PC,310$ ;GO OUTPUT END OF BUFFER SYMBOL IF WE CAN TST EOFLAG(R5) ;AT END OF FILE NOW? BEQ 280$ ;NOPE MOV #EOBSYM,R0 ;YEP, SET END OF BUFFER SYMBOL JSR PC,310$ ; AND GO OUTPUT IT IF WE CAN 280$: MOV BUSTRT+RWSIZE(R5),(SP) ;SAVE ENDING LINE # (OVER CHAR COUNT) TST HLDFLG+RWSIZE(R5) ;ARE WE FULLY HOLDING THE SCREEN? BMI 290$ ;YES, NEVER USE ERASE TO END-OF-SCREEN TST SCROLN+RWSIZE(R5) ;ARE WE IN SCROLLING MODE? BNE 290$ ;YES, CAN'T USE ERASE TO END-OF-SCREEN MOV CRTYPE(R5),R3 ;ELSE GET THE SCOPE TYPE CMPB @EOSSEQ(R3),#200 ;DOES EOS SEQUENCE EXIST? BNE 300$ ;YES, SO GO USE IT 290$: JSR PC,NEWLIX ;CALL TO BLANK ONE LINE BCC 290$ ;LOOP IF MORE TO DO... MOV (SP)+,BUSTRT+RWSIZE(R5) ;DONE, RESTORE ORIGINAL ENDING LINE # RTS PC ; AND EXIT 300$: TST (SP)+ ;JUNK ENDING LINE # MOV #EOSSEQ,R3 ;SET EOS SEQUENCE FOR BLANKING MOV TXSTOR(R5),R0 ;POINT TO END OF SCREEN MAP JMP @OUTBLN+RWSIZE(R5) ;CALL BLANKER FOR REST OF SCREEN, THEN EXIT 310$: MOV OVRPOS+RWSIZE(R5),R3 ;GET CURRENT "OVRSYM" POSITION +1 DEC R3 ;FIND REAL POSITION (NONE & CONTINUATION <0) CMP R2,R3 ;ARE WE AT OR PAST "OVRSYM"? BHIS 330$ ;YES, CAN'T OUTPUT MORE ON THIS LINE JMP @OUTCHR+RWSIZE(R5) ;NO, OUTPUT THE CHARACTER, THEN EXIT 320$: CMP R2,RTMOST+RWSIZE(R5) ;CHECK RIGHTMOST COLUMN ON LINE BLOS 330$ ;BRANCH IF NOT AT IT MOV R2,RTMOST+RWSIZE(R5) ;ELSE SAVE HIGHEST FOR CLEARING REMAINDER 330$: RTS PC ;EXIT .GLOBL TXSTOR, ZZ, FFFLAG, EOFLAG, RWSIZE, CRTYPE, EOSSEQ .SBTTL GO TO A NEW LINE ;+ ; NEWLIN - PROCESS END OF LINE, GO TO THE NEXT LINE. ; ; R2 = COLUMN # ; ; JSR PC,NEWLIN ; ; R1 -> NEW LINE IN MAP ; R3 = UNDEFINED ; ; IF C=0 ('BCC') THEN NOT BEYOND BOTTOM OF SCREEN ; IF C=1 ('BCS') THEN BEYOND BOTTOM OF SCREEN ;- .ENABL LSB NEWLIN: MOV R0,-(SP) ;SAVE R0 MOV R2,-(SP) ;SAVE R2 (COLUMN #) 10$: MOV BUINDX+RWSIZE(R5),R0 ;CALCULATE END OF ADD HTSIZE+RWSIZE(R5),R0 ; LINE POINTER CMP R0,TXSTOR(R5) ;ARE WE OFF END OF SCREEN MAP? BLOS 20$ ;NOPE MOV TXSTOR(R5),R0 ;YEP, RESET TO WITHIN MAP 20$: MOV #EOLSEQ,R3 ;SET SEQUENCE TO CLEAR ONLY THIS LINE JSR PC,@OUTBLN+RWSIZE(R5) ; AND ERASE THE REMAINDER OF LINE IF ANY MOV R0,BUINDX+RWSIZE(R5) ;UPDATE TO NEW LINE IN MAP INC BUSTRT+RWSIZE(R5) ; AND GO TO NEXT LINE # MOV R0,R1 ;SET NEW LINE'S MAP POINTER CLR OVRPOS+RWSIZE(R5) ;NO "OVRSYM" ON NEW LINE YET CLR RTMOST+RWSIZE(R5) ;CLEAR RIGHTMOST COLUMN FOR NEW LINE CLR R2 ; AND START FROM COLUMN 0 30$: CMP R2,(SP) ;UP TO OLD COLUMN POSITION? BLO 50$ ;NOPE, OUTPUT SOME FILL 40$: MOV (SP)+,R2 ;RESTORE R2 (COLUMN #) MOV (SP)+,R0 ;RESTORE R0 CMP VTSIZ1+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;CMP (#LINES-1) VS (LINE#) ;BHIS ;NOT OFF SCREEN, EXIT C=0 ('BHIS'='BCC') ;BLO ;OFF SCREEN, EXIT C=1 ('BLO'='BCS') RTS PC ;EXIT WITH C-BIT INDICATION 50$: CMP VTSIZ1+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;ALREADY OFF SCREEN? BLO 40$ ;YES, FORGET IT MOVB SEEALL+RWSIZE(R5),R0 ;SET OR SYMBOL JSR PC,@OUTCHR+RWSIZE(R5) ; AND OUTPUT IT BR 30$ ;GO CHECK AGAIN... .GLOBL RWSIZE, TXSTOR, EOLSEQ ;+ ; NEWLIX - SPECIAL PROCESS END OF LINE FOR BLANKING REST OF SCREEN. ; ; R2 = COLUMN # ; ; JSR PC,NEWLIX ; ; R1 -> NEW LINE IN MAP ; R2 = 0 (COLUMN #) ; R3 = UNDEFINED ; ; IF C=0 ('BCC') THEN NOT BEYOND BOTTOM OF SCREEN ; IF C=1 ('BCS') THEN BEYOND BOTTOM OF SCREEN ;- NEWLIX: MOV R0,-(SP) ;SAVE R0 CLR -(SP) ;NEW NEXT COLUMN # IS ZERO BR 10$ ;NOW GO DO IT .DSABL LSB .SBTTL OUTPUT A CHARACTER ;+ ; VTCHAR - REAL OUTPUT OF A CHARACTER. ; ; R0 = CHARACTER ; R1 -> MAP ; R2 = COLUMN # ; R4 -> TEXT (+1) ; ; JSR PC,VTCHAR ; ; R0 = UNDEFINED ; R1 -> MAP (UPDATED) ; R2 = COLUMN # (UPDATED) ; R3 = UNDEFINED ;- VTCHAR: CMP R4,MRKHGH+RWSIZE(R5) ;ABOVE MARK'D REGION? BHI 10$ ;YES CMP R4,MRKLOW+RWSIZE(R5) ;BELOW THE MARK'D REGION? BLOS 10$ ;YES BIS #200,R0 ;WITHIN MARK'D REGION, FLAG IT 10$: CMPB R0,(R1)+ ;ARE CHARACTERS THE SAME? BEQ FCHAR ;BRANCH IF YES, DON'T SEND IT! CMP BUSTRT+RWSIZE(R5),PRELIN+RWSIZE(R5) ;AT CORRECT LINE? BNE 40$ ;NO, DO DIRECT CURSOR ADDRESSING MOV R2,R3 ;YES, GET DESIRED COLUMN # SUB PRECOL+RWSIZE(R5),R3 ; AND FIND DELTA CHANGE BEQ 50$ ;ABSOLUTELY CORRECT, JUST DO CHARACTER OUTPUT MOV R1,-(SP) ;ELSE SAVE BUMPED MAP POSITION MOV CRTYPE(R5),R1 ;GET THE SCOPE TYPE CMP R3,POSTBL(R1) ;WITHIN RANGE FOR THE SPEED-UP? BHI 30$ ;NO, DO DIRECT ADDRESSING MOV (SP),R1 ;YES, GET BACK BUMPED MAP POSITION MOVB R0,-(R1) ; AND STORE CHARACTER IN THE MAP SUB R3,R2 ;BACK UP THE COLUMN NUMBER SUB R3,R1 ;BACK UP THE MAP POINTER 20$: MOVB (R1)+,R0 ;GET BACK A CHARACTER FROM MAP CMP R1,(SP) ;UP TO OUR POSITION YET? BHIS 30$ ;YES, DONE JSR PC,50$ ;NO, GO OUTPUT THE CHARACTER BR 20$ ; AND LOOP... 30$: MOV (SP)+,R1 ;RESTORE BUMPED MAP POSITION 40$: JSR PC,SETCUR ;POSITION THE CURSOR .GLOBL RWSIZE, CRTYPE, POSTBL 50$: CLR -(SP) ;GUESS AT DESIRING MARK'D REGION OFF (0) MOVB R0,-1(R1) ;STORE THE CHARACTER BPL 60$ ;NOT FLAGGED BIC #^C<177>,R0 ;FLAGGED, TRIM IT BACK AGAIN COM (SP) ;WE WANT MARK'D REGION ON 60$: CMP (SP)+,MRKON+RWSIZE(R5) ;CONDITIONED FOR MARK'D REGION? BEQ 80$ ;YES, JUST CONTINUE MOV #MOFSEQ,R3 ;NO, GUESS AT TURNING OFF MARK'D REGION COM MRKON+RWSIZE(R5) ;NOW FLIP THE FLOP BEQ 70$ ;MARK'D REGION NOW OFF, SO TURN IT OFF MOV #MONSEQ,R3 ;MARK'D REGION NOW ON, SET TO TURN IT ON 70$: JSR PC,DOTYPE ;GO OUTPUT THE MARK'D REGION ON/OFF SEQUENCE 80$: CLR -(SP) ;GUESS AT DESIRING GRAPHICS OFF (0) CMP R0,#SPACE ;NORMAL CHARACTER? BHIS 90$ ;YES MOV CRTYPE(R5),R3 ;NO, GET THE SCOPE TYPE ADD GRPTBL(R3),R0 ;FIND INDEX INTO CORRECT SYMBOL TABLE MOVB -(R0),R0 ;GET THE CORRECT GRAPHICS CHARACTER COM (SP) ;WE WANT GRAPHICS ON 90$: CMP (SP)+,GRPON+RWSIZE(R5) ;CONDITIONED FOR NOT GRAPHICS? BEQ 110$ ;YES, JUST CONTINUE MOV #GOFSEQ,R3 ;NO, GUESS AT TURNING OFF GRAPHICS COM GRPON+RWSIZE(R5) ;NOW FLIP THE FLOP BEQ 100$ ;GRAPHICS NOW OFF, SO TURN IT OFF MOV #GONSEQ,R3 ;GRAPHICS NOW ON, SET TO TURN IT ON 100$: JSR PC,DOTYPE ;GO OUTPUT THE GRAPHICS ON/OFF SEQUENCE .GLOBL RWSIZE, MOFSEQ, MONSEQ, CRTYPE, GRPTBL, GOFSEQ, GONSEQ 110$: JSR PC,TYPEBF ;SEND THE CHARACTER INC PRECOL+RWSIZE(R5) ;INDICATE CURSOR MOVED 1 TO THE RIGHT ;+ ; FCHAR - FAKE OUTPUT OF A CHARACTER. ; ; R2 = COLUMN # ; ; JSR PC,FCHAR ; ; R2 = COLUMN # (UPDATED) ;- FCHAR: INC R2 ;ADVANCE COLUMN NUMBER RTS PC ; THEN EXIT ;+ ; CCHAR - BUFFER ALIGNMENT OUTPUT OF A CHARACTER. ; ; R0 = CHARACTER ; R1 -> CHECKING BUFFER ; R2 = COLUMN # ; ; JSR PC,CCHAR ; ; R1 -> CHECKING BUFFER (UPDATED) ; R2 = COLUMN # (UPDATED) ;- CCHAR: MOVB R0,(R1)+ ;SAVE CHARACTER IN CHECKING BUFFER BR FCHAR ;GO ADVANCE COLUMN AND EXIT .GLOBL TYPEBF, RWSIZE .SBTTL BLANK REMAINDER OF LINE/SCREEN ;+ ; VTBLNK - REAL OUTPUT BLANK REST OF LINE. ; ; R0 = MAP ADDRESS TO STOP AT ; R2 = COLUMN # ; R3 -> CLEARING SEQUENCE ; ; JSR PC,VTBLNK ;- VTBLNK: MOV R1,-(SP) ;SAVE MOV R2,-(SP) ; WORK MOV R4,-(SP) ; REGS MOV R0,-(SP) ;SAVE ADDRESS TO STOP AT CMP R2,RTMOST+RWSIZE(R5) ;CHECK FOR RIGHTMOST USED COLUMN BHIS 10$ ;R2 IS RIGHT MOV RTMOST+RWSIZE(R5),R2 ;ELSE UPDATE R2 10$: MOV BUINDX+RWSIZE(R5),R1 ;GET ADDRESS OF CURRENT LINE ADD R2,R1 ;POINT TO WHERE WE ARE IN BUFFER CLR R4 ;GUESS AT OFF THE END OF SCREEN CMP VTSIZ1+RWSIZE(R5),BUSTRT+RWSIZE(R5) ;REALLY OFF THE SCREEN? BLO 20$ ;YES COM R4 ;NO, FLAG TO DO CLEARING SEQUENCE ONCE 20$: CMP R1,(SP) ;ARE WE AT END YET? BHIS 60$ ;BRANCH IF YES BIT R1,#1 ;ON WORD BOUNDARY? BEQ 40$ ;BRANCH IF YES CMPB #SPACE,(R1)+ ;IS THIS A BLANK ALREADY? BEQ 20$ ;BRANCH IF YES MOVB #SPACE,-1(R1) ;SET IT TO A BLANK INC R4 ;HAVE WE DONE THE SEQUENCE? BNE 20$ ;BRANCH IF ALREADY DONE 30$: JSR PC,DOSEQ ;CLEAR LINE OR SCREEN... BR 20$ ; THEN CONTINUE 40$: CMP (PC)+,(R1)+ ;ARE THESE .BYTE SPACE,SPACE ; BLANKS ALREADY? BEQ 50$ ;YES MOV #SPACE*400+SPACE,-2(R1) ;SET LAST TWO TO BLANKS INC R4 ;HAVE WE DONE THE SEQUENCE? BEQ 30$ ;BRANCH IF WE NEED TO 50$: CMP R1,(SP) ;ARE WE AT END YET? BLO 40$ ;NOT YET 60$: MOV (SP)+,R0 ;RESTORE THE LIMIT MOV (SP)+,R4 ;RESTORE MOV (SP)+,R2 ; WORK MOV (SP)+,R1 ; REGS RTS PC ;EXIT .GLOBL RWSIZE ;+ ; FBLNK - FAKE BLANK REST OF LINE (FOR BUFFER ALIGNMENT). ; ; JSR PC,FBLNK ;- FBLNK: MOV #FCHAR,OUTCHR+RWSIZE(R5) ;RESET TO FAKE OUTPUT ROUTINE RTS PC ; AND EXIT .SBTTL SET SUBROUTINE ADDRESSES, ETC. ;+ ; SETJSR - SET SUBROUTINE ADDRESSES, ETC. ; ; JSR R4,SETJSR ; .WORD FTRANS -OR- RTRANS ; ; R2 = ORIGINAL "BUSTRT" VALUE ; R3 -> INTO "BUSTRT", "NUMCHR" @ "NUMCHR" ;- SETJSR: MOV #OUTCHR+RWSIZE,R3 ;GET ADDRESS OF FIRST VECTOR ADD R5,R3 ; ABSOLUTELY MOV (R4)+,R2 ;GET POINTER TO THE DESIRED TABLE MOV (R2)+,(R3)+ ;SET "OUTPUT A CHARACTER" ROUTINE MOV (R2)+,(R3)+ ;SET "PROCESS END OF LINE" ROUTINE .IIF NE OUTCHR+2-OUTBLN, .ERROR ;THE ABOVE WON'T WORK MOV #/2,R2 ;SET # WORDS TO CLEAR NOW .IIF NE OUTBLN+2-JSRSRT, .ERROR ;THE ABOVE WON'T WORK 10$: CLR (R3)+ ;CLEAR A WORD SOB R2,10$ ; AND LOOP... MOV (R3),R2 ;SAVE ORIGINAL "BUSTRT" VALUE .IIF NE JSREND-BUSTRT, .ERROR ;THE ABOVE WON'T WORK CLR (R3)+ ; THEN CLEAR CURRENT LINE NUMBER RTS R4 ;EXIT POINTING @ "NUMCHR" .IIF NE BUSTRT+2-NUMCHR, .ERROR ;THE ABOVE WON'T WORK FTRANS: .WORD FCHAR, FBLNK ;BUFFER ALIGNMENT SUBROUTINES RTRANS: .WORD VTCHAR, VTBLNK ;REAL OUTPUT SUBROUTINES .GLOBL RWSIZE .SBTTL DO SEQUENCES ;+ ; DOSEQ - DO SOME SEQUENCE AFTER POSITIONING CURSOR. ; ; R2 = COLUMN # ; R3 -> SEQUENCE ; ; JSR PC,DOSEQ ;- DOSEQ: JSR PC,SETCUR ;SET UP THE CURSOR ;+ ; DOTYPE - DO SOME SEQUENCE. ; ; R3 -> SEQUENCE ; ; JSR PC,DOTYPE ;- .ENABL LSB DOTYPE::MOV R0,-(SP) ;SAVE R0 MOV R3,-(SP) ; AND R3 ADD CRTYPE(R5),R3 ;FIND THE SEQUENCE'S POINTER MOV (R3),R3 ; AND GET THE REAL POINTER 10$: MOVB (R3)+,R0 ;GET A CHARACTER ASLB R0 ;CHECK FOR ENDING 200 BCS 40$ ;IT IS THE END BNE 20$ ;NOT A SEC ;A , FORCE INTO A 200 20$: RORB R0 ;NOT END, RESTORE CHARACTER JSR PC,TYPEBF ;ELSE BUFFER IT BR 10$ ; AND CONTINUE .GLOBL CRTYPE, TYPEBF .SBTTL POSITION THE CURSOR ;+ ; SETCUR - POSITION THE CURSOR. ; ; R2 = COLUMN # ; ; JSR PC,SETCUR ;- SETCUR: MOV R0,-(SP) ;SAVE R0 MOV BUSTRT+RWSIZE(R5),R0 ;GET LINE (ROW) NUMBER CMP R0,PRELIN+RWSIZE(R5) ;IS THIS THE RIGHT LINE? BNE 30$ ;BRANCH IF NOT, MUST SET CURSOR CMP R2,PRECOL+RWSIZE(R5) ;IS THIS THE RIGHT COLUMN? BEQ 50$ ;BRANCH IF SO, SO NEED TO POSITION 30$: MOV R3,-(SP) ;SAVE R3 JSR PC,DIRECT ;CALL FOR DIRECT CURSOR ADDRESSING MOV BUSTRT+RWSIZE(R5),PRELIN+RWSIZE(R5) ;SAVE CURSOR POS ON SCREEN MOV R2,PRECOL+RWSIZE(R5) ; BOTH LINE (ROW) AND COLUMN 40$: MOV (SP)+,R3 ;RESTORE R3 50$: MOV (SP)+,R0 ;RESTORE R0 RTS PC ; THEN EXIT .DSABL LSB .GLOBL RWSIZE, DIRECT .IF EQ I$$MUL .SBTTL MULTIPLY BY HORIZONTAL SIZE MULHSZ: MOV HTSIZE+RWSIZE(R5),-(SP) ;GET THE MULTIPLIER MOV R1,-(SP) ;SAVE THE MULTIPLICAND CLR R1 ;START ANSWER OFF AS A ZERO 10$: ASR 2(SP) ;BIT EXIST IN MULTIPLIER? BCC 30$ ;NOPE ADD (SP),R1 ;YEP, SO ADD IN MULTIPLICAND 20$: ASL (SP) ;SHIFT MULTIPLICAND 1 LEFT BR 10$ ; AND LOOP 30$: BNE 20$ ;MORE TO COME, CONTINUE CMP (SP)+,(SP)+ ;POP THE STACK ITEMS RTS PC ; AND EXIT .GLOBL RWSIZE .ENDC ;EQ I$$MUL .SBTTL HANDLE :W COMMANDS (PARAMETER READ/SET) .ENABL LSB 10$: JMP SCRINS ;OFF TO INSERT PROCESSING... 20$: BEQ 50$ ;SETTING "SEEALL" (+3) CMP R0,#5 ;"MARK" (+4) OR "HOLD" (+5)? BLO 40$ ;SETTING "MARK" (+4) BEQ 30$ ;SETTING "HOLD" (+5) CMP R0,#7 ;"TOP" (+6) OR "SCROLLED REGION" (+7)? BHIS 110$ ;SETTING "SCROLLED REGION" (+7), A NOP MOV R4,TOPDOT+RWSIZE(R5) ;SETTING "TOP" (+6) BR 110$ ; AND GO EXIT 30$: MOV R4,HLDFLG+RWSIZE(R5) ;SET THE "HOLD" FLAG BR 110$ ; AND GO EXIT 40$: MOV R4,MRKFLG+RWSIZE(R5) ;SET THE "MARK" POSITION (+4) BR 110$ ; AND GO EXIT 50$: MOV #SPACE,SEEALL+RWSIZE(R5) ;GUESS AT RESETING "SEEALL" FLAG TST R4 ;GOOD GUESS? BEQ 110$ ;YES, GO EXIT MOV #NULSYM!100000,SEEALL+RWSIZE(R5) ;NO, SET "SEEALL" FLAG BR 110$ ; AND GO EXIT ;+ ; SCRPRM - HANDLE :W COMMANDS (PARAMETER READ/SET). ; ; 0:W RETURN SCOPE TYPE ; 1:W RETURN HORIZONTAL SIZE ; 2:W RETURN VERTICAL SIZE ; 3:W RETURN "SEEALL" FLAG ; 4:W RETURN ANY ACTIVE "MARK" ; 5:W RETURN "HOLDING SCREEN" FLAG ; 6:W RETURN LAST TOP-OF-SCREEN POSITION ; 7:W RETURN SIZE OF SCROLLED REGION ; -256+N:W PROCESS INSERTS UNTIL CONTROL CHARACTER, ETC. ; ; X,0:W SET SCOPE TYPE TO X (X=0, 2, 4, OR 6) ; X,1:W SET HORIZONTAL SIZE (10.<=X<=254. AND EVEN) ; X,2:W SET VERTICAL SIZE (10.<=X<=127.) ; X,3:W SET "SEEALL" FLAG (X=0 OR X<>0) ; X,4:W SET ACTIVE "MARK" (X=0 => NONE, X<>0 => MARK @ X-1) ; X,5:W SET "HOLDING SCREEN" FLAG (X=0 OR X<>0) ; X,6:W SET TOP-OF-SCREEN (X=0 => NONE, X<>0 => TOP @ X-1) ; X,7:W SET SIZE OF SCROLLED REGION ; X,-256+N:W PROCESS INSERTS UNTIL CONTROL CHARACTER, ETC. ;- SCRPRM::TST R0 ;INSERT PROCESSING? BMI 10$ ;YES, SO GO DO IT JSR R0,SCRSAV ;SAVE REGISTERS, SET RETURN, ETC. .GLOBL RWSIZE INC CFLG(R5) ;READING OR SETTING (COMMA PRESENT)? BNE 110$ ;NO COMMA, WE ARE READING MOV M(R5),R4 ;COMMA, WE ARE SETTING, GET THE NEW VALUE CMP R0,#3 ;WHAT ARE WE SETTING? BHIS 20$ ;NOT "TYPE"(+0), "WIDTH"(+1), OR "HEIGHT"(+2) MOV R4,R1 ;PUT NEW THING HERE (NEW VERTICAL SIZE SPOT) MOV HTSIZE+RWSIZE(R5),R2 ;PUT OLD HORIZONTAL SIZE HERE MOV (PC)+,-(SP) ;SET RANGE MASK FOR .BYTE 1,-1 ; NOT ODD AND NOT OVER 255. DEC R0 ;WHAT ARE WE SETTING? BPL 60$ ;SETTING A SIZE (+1 OR +2) MOV #^C<6>,(SP) ;SETTING SCOPE TYPE (+0), MASK FOR VALID INDEX BIT R4,(SP)+ ;IS NEW THING A VALID INDEX? BNE 110$ ;INVALID, SO NO CHANGE... MOV VTSIZE+RWSIZE(R5),R1 ;GET OLD VERTICAL SIZE BR 90$ ; AND GO SET NEW PARAMETERS 60$: BEQ 70$ ;SETTING HORIZONTAL SIZE (+1) ASR (SP) ;SETTING VERTICAL SIZE (+2), ALLOW ODD, <=127. 70$: BIT R4,(SP)+ ;IS NEW SIZE WITHIN RANGE? BNE 110$ ;NO, SO NO CHANGE... CMP R4,#10. ;IS NEW SIZE UNDER THE VERY MINIMUM? BLO 110$ ;NO CHANGE IF SO... TST R0 ;O.K., WHAT SIZE WERE WE SETTING? BNE 80$ ;THE VERTICAL SIZE (+2) MOV R4,R2 ;THE HORIZONTAL SIZE (+1) MOV VTSIZE+RWSIZE(R5),R1 ;GET OLD VERTICAL SIZE 80$: MOV CRTYPE(R5),R4 ;GET OLD SCOPE TYPE 90$: MOV CRTYPE(R5),-(SP) ;SAVE OLD SCOPE TYPE MOV R4,CRTYPE(R5) ; THEN SET NEW SCOPE TYPE MOV VTSIZE+RWSIZE(R5),-(SP) ;SAVE OLD VERTICAL SIZE MOV R1,VTSIZE+RWSIZE(R5) ; THEN SET NEW VERTICAL SIZE MOV HTSIZE+RWSIZE(R5),R3 ;SAVE OLD HORIZONTAL SIZE MOV R2,HTSIZE+RWSIZE(R5) ; THEN SET NEW HORIZONTAL SIZE MOV MAPSIZ+RWSIZE(R5),R0 ;GET OLD -(SCREEN MAP SIZE) SUB R3,R0 ; THEN FORM OLD -(SIZE OF DYNAMIC REGION - 2) MOV SEEALL+RWSIZE(R5),-(SP) ;SAVE "SEEALL" FLAG MOV MRKFLG+RWSIZE(R5),-(SP) ;SAVE "MARK" POSITION MOV HLDFLG+RWSIZE(R5),-(SP) ;SAVE "HOLD" FLAG JSR PC,SETREG ;GO MODIFY THE READ/WRITE REGIONS MOV (SP)+,HLDFLG+RWSIZE(R5) ;RESTORE "HOLD" FLAG MOV (SP)+,MRKFLG+RWSIZE(R5) ;RESTORE "MARK" POSITION MOV (SP)+,SEEALL+RWSIZE(R5) ;RESTORE "SEEALL" FLAG BCS 100$ ;ALL O.K. MOV R3,HTSIZE+RWSIZE(R5) ;FAILED, RESTORE OLD HORIZONTAL SIZE MOV (SP)+,VTSIZE+RWSIZE(R5) ;RESTORE OLD VERTICAL SIZE MOV (SP)+,CRTYPE(R5) ;RESTORE OLD SCOPE TYPE BR 110$ ; THEN GO EXIT 100$: CMP (SP)+,(SP)+ ;POP SAVED OLD SCOPE TYPE & VERTICAL SIZE .GLOBL CFLG, M, RWSIZE, CRTYPE 110$: CLR CFLG(R5) ;CLEAR THE COMMA FLAG MOV HTSIZE+RWSIZE(R5),R0 ;GUESS AT HORIZONTAL SIZE (+1) DEC R0OFF+4(SP) ;GOOD GUESS? BEQ 150$ ;YES BMI 140$ ;NO, IT IS SCOPE TYPE (+0) MOV VTSIZE+RWSIZE(R5),R0 ;NOW GUESS AT VERTICAL POSITION (+2) SUB #2,R0OFF+4(SP) ;GOOD GUESS? BMI 150$ ;YES BEQ 130$ ;NO, IT IS "SEEALL" (+3) MOV MRKFLG+RWSIZE(R5),R0 ;NOW GUESS AT SET "MARK" (+4) SUB #2,R0OFF+4(SP) ;GOOD GUESS? BMI 150$ ;YES BEQ 120$ ;NO, IT IS "HOLD" (+5) MOV TOPDOT+RWSIZE(R5),R0 ;NOW GUESS AT "TOP" POSITION (+6) SUB #2,R0OFF+4(SP) ;GOOD GUESS? BMI 150$ ;YES MOV SCROLN+RWSIZE(R5),R0 ;NO, GET "SCROLLED REGION" (+7) BR 150$ ; AND GO EXIT WITH IT 120$: MOV HLDFLG+RWSIZE(R5),R0 ;GET "HOLD SCREEN" FLAG BR 150$ ; AND GO EXIT WITH IT 130$: CLR R0 ;GUESS AT "SEEING ALL" RESET TST SEEALL+RWSIZE(R5) ;GOOD GUESS? BPL 150$ ;YES, GO EXIT WITH IT COM R0 ;NO, SAY "SEEALL" IS SET BR 150$ ; AND GO EXIT WITH IT 140$: MOV CRTYPE(R5),R0 ;SET THE SCOPE TYPE 150$: MOV R0,R0OFF+4(SP) ;SET THE RETURNED VALUE (IN SAVED R0) RTS PC ; AND EXIT .DSABL LSB .GLOBL CFLG, RWSIZE, R0OFF, CRTYPE .SBTTL SET UP THE READ/WRITE REGIONS ;+ ; SETREG - SET UP THE READ/WRITE REGIONS. ; ; R0 = OLD -(SIZE OF DYNAMIC READ/WRITE REGION - 2) ; ; JSR PC,SETREG ; ; R0 = NEW -(SIZE OF SCREEN MAP) ; R1 = UNDEFINED ; R2 = UNDEFINED ; R4 = UNDEFINED ; ; IF C=1 ('BCS') THEN DYNAMIC REGION ALLOCATED ; IF C=0 ('BCC') THEN DYNAMIC REGION FAILED TO ALLOCATE ;- SETREG: MOV VTSIZE+RWSIZE(R5),R1 ;GET VERTICAL SIZE MULHSZ ; AND FIND (SIZE OF SCREEN MAP) MOV R1,-(SP) ;SAVE SIZE OF SCREEN MAP FOR LATER... ADD HTSIZE+RWSIZE(R5),R1 ;NOW HAVE (SIZE OF DYNAMIC - 2) ADD R1,R0 ;FORM (NEW-2)+(-(OLD-2))=(NEW)-(OLD)=(DELTA) BEQ 40$ ;WE ARE STAYING THE SAME, DELTA = 0 BPL 20$ ;WE ARE EXPANDING, DELTA > 0 SUB R0,CURFRE(R5) ;UPDATE CURRENT FREE SPACE, DELTA < 0 JSR PC,70$ ;SET THE NEW POINTERS, GET NEW START/END ADD R2,R0 ;FIND OLD TEXT START 10$: MOVB (R0)+,(R2)+ ;MOVE ONE BYTE DOWN POPPING CMP R2,R4 ;DONE? BLO 10$ ;NOT YET... BR 40$ ;ELSE CONTINUE 20$: MOV QZ(R5),R1 ;GET CURRENT Q-REG SIZE-IN-USE ADD R0,R1 ;UPDATE TO SIZE-TO-BE JSR PC,SIZEQR ;CALL FOR SIZING ON Q-REG AREA BCC 60$ ;FAILED, SORRY... (GO EXIT C=0 FOR ERROR) SUB R0,QMAX(R5) ;GOT IT, TAKE IT AWAY FROM Q-REG AREA JSR PC,70$ ;SET THE NEW POINTERS, GET NEW START/END ADD R4,R0 ;FIND OLD TEXT END 30$: MOVB -(R0),-(R4) ;MOVE ONE BYTE UP PUSHING CMP R4,R2 ;DONE? BHI 30$ ;NOT YET... .GLOBL RWSIZE, CURFRE, QZ, SIZEQR, QMAX 40$: MOV #CLRSRT+RWSIZE,R4 ;GET START OF AREA TO CLEAR ADD R5,R4 ; MAKING POINTER ABSOLUTE MOV #/2,R1 ;GET WORD SIZE OF AREA TO CLEAR 50$: CLR (R4)+ ;CLEAR THE SOB R1,50$ ; WHOLE AREA... MOV #SPACE,(R4)+ ;RESET THE "SEEING ALL" FLAG .IIF NE CLREND-SEEALL, .ERROR ;THE ABOVE WON'T WORK MOV (R4)+,R1 ;GET THE VERTICAL SIZE .IIF NE SEEALL+2-VTSIZE, .ERROR ;THE ABOVE WON'T WORK MOV (R4)+,R2 ;GET THE HORIZONTAL SIZE .IIF NE VTSIZE+2-HTSIZE, .ERROR ;THE ABOVE WON'T WORK MOV R1,(R4) ;PUT VERTICAL SIZE HERE DEC (R4)+ ; AND MAKE IT VERTICAL SIZE MINUS 1 .IIF NE HTSIZE+2-VTSIZ1, .ERROR ;THE ABOVE WON'T WORK MOV R2,(R4) ;PUT HORIZONTAL SIZE HERE DEC (R4) ; AND MAKE IT HORIZONTAL SIZE MINUS 1 .IIF NE VTSIZ1+2-HTSIZ1, .ERROR ;THE ABOVE WON'T WORK MOV (R4)+,(R4) ;MOVE HORIZONTAL SIZE -1 TO HERE DEC (R4)+ ; AND MAKE IT HORIZONTAL SIZE MINUS 2 .IIF NE HTSIZ1+2-HTSIZ2, .ERROR ;THE ABOVE WON'T WORK MOV (SP),R0 ;GET BACK +(SIZE OF SCREEN MAP) NEG R0 ; THEN MAKE IT -(SIZE OF SCREEN MAP) MOV R0,(R4) ;SET THAT INTO ITS SAVE SPOT .IIF NE HTSIZ2+2-MAPSIZ, .ERROR ;THE ABOVE WON'T WORK ;SEC ;EXIT C=1 FOR ALL O.K. (FROM 'NEG' ABOVE) 60$: MOV (SP)+,R1 ;GET RID OF STACK ITEM W/O CHANGING C-BIT RTS PC ;EXIT C=0 FOR ALLOCATION FAILURE 70$: ADD R0,TXSTOR(R5) ;UPDATE START OF TEXT (+ OR -) ADD R0,QRSTOR(R5) ;UPDATE START OF Q-REGS (+ OR -) NEG R0 ;NOW CHANGE THE SIGN OF DELTA MOV TXSTOR(R5),R2 ;SET THE NEW TEXT AREA START MOV QRSTOR(R5),R4 ;SET THE NEW Q-REG AREA START ADD QMAX(R5),R4 ; AND FIND NEW END OF BOTH AREAS RTS PC ;NOW EXIT .GLOBL RWSIZE, TXSTOR, QRSTOR, QMAX .SBTTL SAVE REGISTERS, SET RETURN, ETC. ;+ ; SCRSAV - SAVE REGISTERS, SET RETURN, ETC. ; ; JSR R0,SCRSAV ; ; R1 = UNDEFINED ; R2 = UNDEFINED ; R3 = UNDEFINED ; R4 = UNDEFINED ; SP -> CLEAN UP EXIT RETURN, SAVED "ET", 'SAVREG' SAVED REGISTERS... ;- SCRSAV::MOV (SP)+,OUTCHR+RWSIZE(R5) ;(RE-)SAVE SAVED R0 (FROM 'JSR R0,') JSR R4,SAVREG ;SAVE ALL REGISTERS & INIT TERMINAL OUTPUT MOV OUTCHR+RWSIZE(R5),R0OFF(SP) ;(RE-)RESTORE R0 IN ITS SAVE SPOT MOV ETYPE(R5),-(SP) ;SAVE INITIAL "ET" FLAG VALUE MOV R0,-(SP) ;MOVE RETURN ADDRESS TO THE STACK MOV MAPSIZ+RWSIZE(R5),R0 ;HAS THE SCREEN MAP BEEN ALLOCATED? BNE 10$ ;YEP MOV #2,R0 ;MAP NOT ALLOCATED, SET -(SIZE OF DYNAMIC - 2) JSR PC,SETREG ; AND GO SET UP THE READ/WRITE REGIONS BCC 30$ ;ERROR ALLOCATING MAP, GO DIE 10$: ADD TXSTOR(R5),R0 ;FORM POINTER TO START OF SCREEN MAP MOV R0,MAPPTR+RWSIZE(R5) ; AND SAVE IT SUB HTSIZE+RWSIZE(R5),R0 ;BACK UP BY ONE LINE TST -(R0) ; AND BY THE FLAG WORD MOV R0,CHCKBP+RWSIZE(R5) ; THEN STORE THAT POINTER ALSO MOV R0OFF+4(SP),R0 ;NOW GET BACK THE CALLING ARGUMENT BIS #ET$BIN,ETYPE(R5) ;ENSURE IMAGE MODE OUTPUT JSR PC,@(SP)+ ;DO A CO-ROUTINE CALL BACK BIT (SP)+,#ET$BIN ;DO WE NEED TO CLEAR IMAGE OUTPUT? BNE 20$ ;NOPE, IT WAS SET ON ENTRY BIC #ET$BIN,ETYPE(R5) ;YEP, SO CLEAR IT ALREADY 20$: RTS PC ;FINALLY WE CAN REALLY EXIT 30$: JMP $E$MEM ;ALLOCATION FAILED, SORRY... .GLOBL RWSIZE, SAVREG, R0OFF, ETYPE, TXSTOR, ET$BIN, $E$MEM .SBTTL HANDLE -256+N:W (INSERT PROCESSING, ETC.) ;+ ; SCRINS - HANDLE -256+N:W (INSERT PROCESSING, ETC.). ; ; R0 = -256.+N WHERE: ; ; N = +128. = 200 = <7> => DON'T STALL IF NO TERMINAL INPUT IS AVAILABLE ; +64. = 100 = <6> => EXIT ON ANY CHARACTER ; +32. = 40 = <5> => DON'T UPDATE SCREEN ; +16. = 20 = <4> => ** RESERVED ** ; +8. = 10 = <3> => TREAT M(R5) AS EXCEPTION CHARACTER(S) ; +4. = 4 = <2> => UPPER CASE ANY INSERT(S) ; +2. = 2 = <1> => TREAT AS AN EXCEPTION CHARACTER ; +1. = 1 = <0> => NO NEED TO INITIALLY UPDATE THE SCREEN ; ; IF CFLG(R5)=-1 THEN ; M(R5) = UPDATE INTERVAL IF <2> OF N IS 0 ; = EXCEPTION CHARACTER(S) IF <2> OF N IS 1 ; ; JSR PC,SCRINS ; ; R0 = RETURNED EXIT VALUE WHERE: ; ; R0 < 0 = <15>=1 => ONE OR MORE INSERT(S) WERE DONE ; R0 & 128. = <7>=1 => DON'T STALL SPECIFIED AND NO INPUT AVAILABLE ; R0 & 127. = <6-0> = EXCEPTION CHARACTER'S VALUE (177 IF <7>=1) ;- SI.OK == 1 ;SCREEN IMAGE IS O.K. SI.EXT == 2 ;TREAT AS AN EXCEPTION CHARACTER SI.UC == 4 ;UPPER CASE ANY INSERT(S) SI.EXM == 10 ;TREAT M(R5) AS EXCEPTION CHARACTER(S) ; == 20 ;** RESERVED ** SI.NUP == 40 ;DON'T UPDATE SCREEN SI.EXA == 100 ;EXIT ON ANY CHARACTER SI.NST == 200 ;DON'T STALL IF NO TERMINAL INPUT IS AVAILABLE SI.OKS == 400 ;ALL SET FOR A SIMPLE SCREEN UPDATE SI.INS == 100000 ;ONE OR MORE INSERT(S) WERE DONE .PSECT SCRINS,RO,I,GBL,REL,OVR SCRINS: MOV ETYPE(R5),-(SP) ;SAVE INITIAL "ETYPE" CLR CFLG(R5) ;ENSURE M,N FORMAT GETS TURNED OFF CLR -(SP) ;STACK A FLAG WORD MOVB R0,(SP) ; AND INSERT THE CALLING ARGUMENT BITS .GLOBL ETYPE, CFLG 10$: BIS #ET$CC!ET$CKE!ET$NCH,ETYPE(R5) ;INDICATE NO STALL, ETC. 20$: JSR PC,TLISTN ;READ FROM THE TERMINAL BIC #ET$CKE,ETYPE(R5) ;GO BACK TO TERMINAL STALL MODE BPL 30$ ;WHOOPS! CONTROL/C TYPED ;.IIF NE ET$CC-100000, .ERROR ;THE ABOVE WON'T WORK TST R0 ;DID WE GET ANYTHING? BPL 40$ ;YES TSTB (SP) ;NO STALL? BMI 60$ ;YES, EXIT W/ <7>=1 AND CODE 177 .IIF NE SI.NST-200, .ERROR ;THE ABOVE WON'T WORK BIT (SP),#SI.NUP!SI.OK ;NO UPDATE OR SCREEN O.K.? BNE 20$ ;ONE OR THE OTHER, SO READ W/ STALL MOV #-1,R0 ;NEED SCREEN UPDATE, SET R0 TO -1 JSR PC,SCRUPD ; AND GO UPDATE THE SCREEN INC (SP) ;SAY SCREEN IS ALL UPDATED .IIF NE SI.OK-1, .ERROR ;THE ABOVE WON'T WORK TST ETYPE(R5) ;WAS A CONTROL/C TYPED? BMI 20$ ;NO CONTROL/C, SO READ W/ STALL ;.IIF NE ET$CC-100000, .ERROR ;THE ABOVE WON'T WORK 30$: MOV #'C-100,R0 ;SET A CONTROL/C AS TYPED 40$: BIT (SP),#SI.EXA!SI.EXM!SI.UC ;EXIT ON ANY CHARACTER (ETC.)? BNE 60$ ;YES, EXIT CMPB R0,#DEL ;CONTROL CHARACTER? BHIS 60$ ;YES (177 TO 377), EXIT CMPB R0,#SPACE ;MIGHT BE... BHIS 50$ ;NORMAL GRAPHIC (040 TO 176), DO INSERT CMPB R0,#TAB ;CONTROL CHARACTER, IS IT ? BNE 60$ ;NO, OTHER, EXIT BIT (SP),#SI.EXT ;ALLOWING ? BNE 60$ ;NO, EXIT 50$: JSR PC,70$ ;GO SAVE REGISTERS AND DO TEXT BUFFER INSERT BIS #SI.INS!SI.OK,(SP) ;INDICATE ONE OR MORE INSERT(S) DONE DEC (SP) ; BUT INDICATE DISPLAY NOT NOW CORRECT .IIF NE SI.OK-1, .ERROR ;THE ABOVE WON'T WORK BR 10$ ;GO READ W/O STALL 60$: MOVB R0,(SP) ;PUT EXCEPTION CHARACTER VALUE INTO FLAG MOV (SP)+,R0 ; AND SET R0 FOR RETURNED VALUE BIC #^C,(SP) ;TRIM SAVED "ETYPE" BIC #ET$CC!ET$CKE!ET$NCH,ETYPE(R5) ;TURN OFF OUR BITS BIS (SP)+,ETYPE(R5) ; THEN RESTORE ORIGINAL "ETYPE" RTS PC ; AND EXIT 70$: JSR R4,SAVREG ;SAVE ALL REGISTERS JMP .III.I ; AND GO DO THE TEXT BUFFER INSERT; EXIT .GLOBL ET$CC, ET$CKE, ET$NCH, ETYPE, TLISTN, SAVREG, .III.I .SBTTL THE LAYOUT OF THE STATIC READ/WRITE REGION .PSECT ..ABS.,RW,D,LCL,ABS,OVR ..ABS.: . = 0!..ABS. OUTCHR::.BLKW ;-> "OUTPUT A CHARACTER" OUTBLN::.BLKW ;-> "PROCESS END OF LINE" CLRSRT: ;START OF 'SETREG' AREA TO CLEAR JSRSRT: ;START OF 'SETJSR' AREA TO CLEAR BUINDX: .BLKW ;-> TO LINE START IN MAP/CHECKING BUFFER CURPOS::.BLKW ;TEXT BUFFER POINTER OF CURSOR CURABS::.BLKW ;MAP POSITION OF CHARACTER UNDER CURSOR CURLIN: .BLKW ;LINE NUMBER OF CURSOR CURCOL::.BLKW ;COLUMN NUMBER OF CURSOR GRPON: .BLKW ;GRAPHICS TURNED ON FLAG MRKLOW: .BLKW ;START OF MARK'D REGION IN TEXT BUFFER MRKHGH: .BLKW ;END OF MARK'D REGION IN TEXT BUFFER MRKON: .BLKW ;MARK'D REGION TURNED ON FLAG RTMOST: .BLKW ;RIGHTMOST COLUMN SEEN OVRPOS: .BLKW ;COLUMN POSITION +1 OF "OVRSYM" JSREND: ;END OF 'SETJSR' AREA TO CLEAR BUSTRT: .BLKW ;CURRENT LINE NUMBER NUMCHR: .BLKW ;NUMBER OF CHARACTERS IN CHECKING LINE LINPTR::.BLKW ;CHARACTER POSITION (P) OF LINE START SVSTRT: .BLKW ;SAVED LINE NUMBER (BUSTRT) INITFL::.BLKW ;-1=>KNOWN; -2=>UNKNOWN, BUT FIXED; 0=>UNKNOWN TOPDOT::.BLKW ;LAST TOP-OF-SCREEN POSITION [SET/READ VIA 6:W] HLDFLG::.BLKW ;"HOLD SCREEN" FLAG [SET/READ VIA 5:W] PRELIN::.BLKW ;LAST SET LINE TO SCREEN (<0 => UNKNOWN) PRECOL::.BLKW ;LAST SET COLUMN TO SCREEN MRKFLG::.BLKW ;ACTIVE "MARK" IF ANY [SET/READ VIA 4:W] SCROLN::.BLKW ;SIZE OF SCROLLED REGION IF ANY [SET/READ VIA 7:W] CLREND: ;END OF 'SETREG' AREA TO CLEAR SEEALL::.BLKW ;"SEE ALL CHARACTERS" FLAG [SET/READ VIA 3:W] VTSIZE::.BLKW ;VERTICAL SIZE [SET/READ VIA 2:W] HTSIZE::.BLKW ;HORIZONTAL SIZE [SET/READ VIA 1:W] VTSIZ1::.BLKW ;VERTICAL SIZE -1 HTSIZ1: .BLKW ;HORIZONTAL SIZE -1 HTSIZ2::.BLKW ;HORIZONTAL SIZE -2 MAPSIZ: .BLKW ;-(SIZE OF THE SCREEN MAP) IN BYTES (0 => UNALLOCATED) MAPPTR: .BLKW ;POINTER TO THE SCREEN MAP CHCKBP: .BLKW ;POINTER TO: FLAG WORD, 1 LINE'S WORTH FOR CHECKING SRWSIZ:: ;SIZE OF THE STATIC READ/WRITE REGION IN BYTES .SBTTL THE LAYOUT OF THE DYNAMIC READ/WRITE REGION ; R5 -> .BLKB RWSIZE ;TECO'S READ/WRITE REGION ; RWSIZE+R5 -> .BLKB SRWSIZ ;SCREEN'S READ/WRITE REGION ; .BLKB ??? ;FOR RANDOM USE BY TECOIO ; CHCKBP+RWSIZE(R5) -> .BLKW ;FLAG WORD ; .BLKB HTSIZE(R5) ;CHECKING BUFFER ; MAPPTR+RWSIZE(R5) -> .BLKB VTSIZE(R5)*HTSIZE(R5) ;SCREEN MAP ; TXSTOR(R5) -> .BLKB ZMAX(R5) ;TEXT BUFFER ; QRSTOR(R5) -> .BLKB QMAX(R5) ;Q-REGISTERS ; .BLKB CURFRE(R5) ;FREE SPACE .END