.TITLE RNFIO .IDENT /M04/ .MCALL QIOW$S,EXTK$S ;$DEBUG=1 ; FOR DEBUGGING ; ; COPYRIGHT (C) 1976 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU- ; SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY ; OTHER COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE ; AVAILABLE TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM ; AND TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE TO AND ; OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; ; VERSION M04 ; ; AUTHOR: L. WADE 1-JUN-72 ; ; MODIFIED BY: ; ; E. POLLACK U. OF W. 19-DEC-73 ; ; D. N. CUTLER 14-SEP-75 ; ; J. CLEMENT AUGUST 1982 ; ADDED STACKED I/O FOR SUPPORT OF REQUIRE STATEMENT ; REARRANGED LUNS FOR NEATNESS ; ; SIG MODIFICATION ;**NEW** ; SIG01 CHANGE DEVICE FOR WAIT TO TI ;**NEW** ; SIG02 INCORPORATE RSTS CHANGES ;**NEW** ; ; RUNOFF I/O ROUTINES ; ; MACRO LIBRARY CALLS ; ;SIG02 .MCALL GET$S,PUT$S,CLOSE$ ;SIG02 ; ;SIG02 ;+ ;**-17 ; ; FILE INPUT/OUTPUT ROUTINES ;- .IFDF $DEBUG SPACE: .WORD " CHROUT:: MOV R1,TEMP MOV R1,-(SP) ; save for restore BIC #177600,R1 ; clear extra bits CMPNE R1,#CR,10$ ; NOT CARRIAGE RET QIOW$S #IO.WAL,#1,#1,,,,<#CRM,#4> MOV (SP)+,R1 ; Restore RETURN 10$: CMPNE R1,#LF,20$ ; NOT LINE FEED QIOW$S #IO.WAL,#1,#1,,,,<#LFM,#4> MOV (SP)+,R1 ; Restore RETURN 20$: CMPNE R1,#TAB,30$ QIOW$S #IO.WAL,#1,#1,,,,<#TBM,#4> MOV (SP)+,R1 ; Restore RETURN 30$: CMP R1,#SPC ; PRINTABLE? BGE 40$ ; YES MOVB R1,CTM+1 ; NO BISB #'@,CTM+1 QIOW$S #IO.WAL,#1,#1,,,,<#CTM,#3> MOV (SP)+,R1 ; Restore RETURN 40$: QIOW$S #IO.WAL,#1,#1,,,,<#TEMP,#1> MOV (SP)+,R1 ; Restore RETURN CRM: .ASCII // LFM: .ASCII // TBM: .ASCII // CTM: .ASCII /<@>/ .EVEN .ENDC .PSECT $CODE,LCL,I,RO,CON ; ; OUTPUT ROUTINE ; CRLF:: MOV (PC)+,R1 ;GET CARRIAGE RETURN AND LINE FEED .BYTE LF,CR ; MOV PC,-(SP) ;SET TO REPEAT OUTPUT TWICE SWAB R1 ;SWAP CHARACTER TO RIGHT BYTE FOUT:: MOVB R1,@HFOUT+2 ;STORE CHARACTER IN BUFFER .IFDF $DEBUG CALL CHROUT .ENDC INC HFOUT+2 ;INCREMENT BUFFER POINTER DEC HFOUT+4 ;ANY MORE ROOM IN BUFFER? BEQ OUTPUT ;IF EQ NO RETURN ; ; ; SOURCE FILE INPUT ROUTINE ; FIN:: MOV BUFADD,R1 ; BUFFER HEADER ADDRESS CALL GBYT1 ; GET NEXT BYTE BCC 40$ ; FOUND ONE TSTNEB EOFSW,35$ ; END OF INPUT FILE? MOVB LUNSTK,R0 ; GET STACK POINTER MOV FDBTAB(R0),R0 ; NOW GET FDB BLOCK ADDRESS MOV BF.CAD(R1),R1 ; ACTUAL BUFFER ADD #BFLNK+1,R1 ; SKIP OVER LINKS GET$S R0,R1,#IBFSZ ; INPUT A RECORD BCC 20$ ; BR IF I/O OK CMPEQB #IE.EOF,F.ERR(R0),10$ ; IT IS END OF FILE ON INPUT CALL $ERMSG .WORD INPERR TSTNEB LUNSTK,5$ ; Is logical unit stack ok? JMP WRERR3 ; NO 5$: MOVB LUNSTK,R0 ; GET STACK POINTER MOV FDBTAB(R0),R0 ; NOW GET FDB BLOCK ADDRESS 10$: CLOSE$ R0 ; CLOSE INPUT FILE TSTB LUNSTK ; MORE LUNS IN STACK? BLE 30$ ; NO MORE MOVB LUNSTK,R0 ; GET POINTER SUB #2,R0 ; BACK UP IN STACK MOVB R0,LUNSTK ; SAVE IT MOV BUFTAB(R0),BUFADD ; NEW HEADER BR FIN ; NOW TRY AGAIN FOR CHAR 20$: MOV BUFADD,R1 ; BUFFER HEADER ADDRESS MOV F.NRBD(R0),BF.CNT(R1) ;GET BYTE COUNT OF LINE MOV BF.CAD(R1),R0 ; AND GET THE BUFFER ADDRESS ADD #BFLNK,R0 MOV R0,BF.ADD(R1) ; SAVE ADDRESS INC R0 ADD BF.CNT(R1),R0 ; ADVANCE POINTER TO END OF CHARACTERS MOVB #CR,(R0)+ ; SET CR/LF AT END OF LINE MOVB #LF,(R0)+ ; .IFDF $DEBUG MOV R2,-(SP) ; *** DEBUG MOV BF.ADD(R1),R2 ; *** DEBUG INC R2 ; *** DEBUG CORRECT FIRST DATA BYTE PUT$S #TTBLK,#SPACE,#1 ; *** DEBUG PUT$S #TTBLK,R2,BF.CNT(R1) ; *** DEBUG OUTPUT PUT$S #TTBLK,#SPACE,#1 ; *** DEBUG MOV (SP)+,R2 ; *** DEBUG .ENDC ADD #2,BF.CNT(R1) ;AND ADJUST BYTE COUNT MOV BF.CNT(R1),BF.MAX(R1) ; AND BUFFER SIZE CLR BF.FUL(R1) ; SET POINTER TO BOTTOM OF BUFFER BR FIN ; GET CHARACTER 30$: INCB EOFSW ; SET EOF 35$: MOV #LF,R1 ; AND OUTPUT END OF LINE 40$: RETURN TEMP: .WORD 0 ; ; THIS ROUTINE OUTPUTS THE CURRENT CONTENTS OF THE LINE BUFFER ; OUTPUT::MOV HFOUT,LSTBLK+F.NRBD ;CALCULATE LENGTH OF LINE TO OUTPUT SUB HFOUT+4,LSTBLK+F.NRBD ; BEQ OUT3 ; IF EQ EMPTY BUFFER CMP PAGENO,LOWPAG ; ONLY PRINT IN THE SELECTED PAGE BLO OUT1 ; RANGE CMPB CHPTN,LOWCHP ; chapter # too small? BLO OUT1 ; yes CMPB APNDN,LOWAPN ; appendix too small? BLO OUT1 ; yes CMP PAGENO,HGHPAG ; page number too big? BHI OUT2 ; yes, quit forever CMPB CHPTN,HGHCHP ; too big? BHI OUT2 ; yes, quit forever CMPB APNDN,HGHAPN ; appendix too big? BHI OUT2 ; yes, quit forever PUT$S #LSTBLK,#OUBUF ; OUTPUT LINE BCS WRERR3 ; IF CS ERROR OUT1: MOV HFOUT,HFOUT+4 MOV #OUBUF,HFOUT+2 OUT3: RETURN OUT2: CALL OUT1 ; RESET POINTERS TO AVOID SIDE EFFECTS TSTEQ HGHPAG,OUT3 ; SECOND TIME THROUGH? CLR HGHPAG JMP ENDFIL ; OTHERWISE INITIATE TERMINATION ; ; I/O ERROR EXITS ; WRERR3: CALL $ERMSG .WORD OUTERR WRERR4: JMP RUNOFF ; RESTART ; ; TERMINAL I/O ROUTINES ; ; ; CALL EROUT ; .WORD STRING ; ASCIZ STRING ADDRESS ; ; CALL TTOUT ; R1 = STRING ADDRESS ; R2 = LENGTH ; EROUT:: MOV @(SP),R1 ; GET ADDRESS OF INPUT STRING ADD #2,(SP) ; SKIP ADDRESS MOV R1,R2 ; DITTO 10$: TSTB (R2)+ ; FIND END OF STRING BNE 10$ ; NOT FOUND SUB R1,R2 ; LENGTH OF STRING TTOUT:: PUT$S #TTBLK,R1,R2 ; OUTPUT STRING RETURN ;+ ; READ TERMINAL INPUT RECORD ;- TTC4N:: GET$S #TTBLK ; GET A RECORD SIG01 CLR TTBLK+F.NRBD ; MAKE LINE EMPTY RETURN ; ; ; The following routines are designed to handle buffers in dynamic ; pool memory. The data should be accessed via these routines. The offset ; BF.FUL is the index to your data bytes. The BF.ADD always points to the ; current byte (one accessed last by GBYT or PBYT). All data in buffers should ; be accessed via these routines. The FNDBF,BEGBF routines set the ; current data index (BF.FUL) so you may use GBYT or GWRD to get the data. You ; may access the current byte via the offset BF.ADD,when BF.FUL is non zero, but no other bytes ; may be accessed directly. The routine RSTBF, and ENDBF set the index and then ; set up the buffers for input via PBYT,PWRD. After BEGBF,FNDBF reading past ; past the end of the data is inhibited. If CARRY is set the routine failed. ; CLRBF resets all pointers, deallocates all dynamic memory and sets the ; buffer chain ready for input. ; BFSIZ == 200 ; 128. BYTES OF DATA (MUST BE POWER OF 2) BFMSK = 177 ; BUFFER SIZE MASK ; ; R3=BUFFER HEADER ; R1=DATA BYTE TO PUT/GET/FIND ; R0=DESTROYED BY THESE ROUTINES ; ; ROUTINE TO CLEAR BUFFER FOR MORE DATA ; EXTRA BUFFERS ARE RETURNED TO POOL ; CLRBF:: .IFDF $DEBUG TST BF.CNT(R3) BGE 2$ 1$: CALL KILL 2$: TST BF.FUL(R3) BLT 1$ .ENDC MOV #BFSIZ,BF.CNT(R3) ; SET UP COUNT CLR BF.FUL(R3) ; RESET INDEX CLR BF.MAX(R3) ; RESET DATA RESIDENT CLR BF.SPC(R3) ; clear spacing char count MOV BF.BEG(R3),R0 ; GET HEAD OF CURRENT BUFFER CHAIN MOV R0,BF.CAD(R3) ; INTO CURRENT BUFFER ADDRESS MOV R0,BF.ADD(R3) ; INTO DATA ADDRESS ADD #BFLNK,BF.ADD(R3) ; POINTS TO FIRST BYTE-1 MOV (R0),R0 ; GET REST OF BUFFER CHAIN BEQ 10$ ; NONE! MOV LNKHD,@BF.END(R3) ; ADD BUFFER POOL TO END OF CHAIN MOV R0,LNKHD ; PUT COMPLETE CHAIN INTO POOL MOV BF.BEG(R3),BF.END(R3) ; LAST = FIRST BUFFER CLR @BF.BEG(R3) ; AND FIRST HAS NO FOEWARD LINK 10$: RETURN ; ; ROUTINE SETS POINTER TO START OF BUFFER FOR GETTING DATA ; IF BUFFER HAS NO DATA MAX SET, MAX=CURRENT INDEX ; BEGBF:: .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC MOV BF.BEG(R3),R0 ; FIRST BUFFER MOV R0,BF.CAD(R3) ; IS CURRENT ONE ADD #BFLNK,R0 ; POINTS TO DATA-1 MOV R0,BF.ADD(R3) ; SAVED MOV BF.MAX(R3),R0 ; MAX DATA SET? CMP R0,BF.FUL(R3) ; GREATER THAN CURRENT BHIS 10$ ; YES MOV BF.FUL(R3),R0 ; TOTAL DATA IN BUFFER MOV R0,BF.MAX(R3) ; SET SIZE TO MAX DATA SIZE 10$: CLR BF.FUL(R3) ; CLEAR INDEX CMP R0,#BFSIZ ; SMALLER THAN BUFFER SIZE? BLOS 20$ ; YES MOV #BFSIZ,R0 20$: MOV R0,(R3) ; SET COUNT .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC RETURN ; ; GETS NEXT BYTE FROM BUFFER ; GBYT:: MOV R3,R1 ; FOR GBYT1 ; ; SPECIAL PURPOSE ROUTINE ; R1=HEADER (INPUT) ; R1=DATA BYTE (OUTPUT) ; GBYT1:: TST (R1) ; BUFFER AT END BLE 20$ ; YES, GIVE ERROR DEC (R1)+ ; DECREMENT COUNT INC (R1)+ ; INCREMENT INDEX .IFDF $DEBUG BLT 26$ .ENDC INC (R1) ; NEXT BYTE MOVB @(R1),R1 ; GET BYTE 10$: CLC RETURN 20$: BEQ 25$ 26$: CALL KILL ; bad count 25$: CMPEQ BF.FUL(R1),BF.MAX(R1),40$ ; at end of buffers? MOV BF.CAD(R1),R0 ; GET CURRENT BUFFER MOV (R0),R0 ; GET NEXT BUFFER IN CHAIN BEQ 40$ ; NONE MOV BF.MAX(R1),(R1) ; NUMBER OF BYTES TOTAL SUB BF.FUL(R1),(R1) ; LESS INDEX=REMAINING CMP (R1),#BFSIZ ; IS IT OK BLOS 30$ ; YES MOV #BFSIZ,(R1) ; NO, MAKE IT FULL BUFFER SIZE 30$: MOV R0,BF.CAD(R1) ; NEW CURRENT BUFFER ADD #BFLNK,R0 ; POINTS TO BYTE IN FRONT OF FIRST MOV R0,BF.ADD(R1) ; SAVE ADDRESS .IFDF $DEBUG MOV R3,-(SP) ; *** DEBUG MOV R1,R3 CALL TEST MOV (SP)+,R3 ; DEBUG .ENDC BR GBYT1 ; AND GET THE BYTE FINALLY 40$: SEC RETURN ; ; PUTS NEXT BYTE INTO BUFFER ; PBYT:: MOV R3,R0 ; BUFFER HEADER .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC TST (R0) ; BUFFER AT END BLE 10$ ; YES, TRY TO ALLOCATE ANOTHER DEC (R0)+ ; DECREMENT REMAINDER COUNT INC (R0)+ ; INCREMENT INDEX INC (R0) ; INCREMENT ADDRESS MOVB R1,@(R0) ; SAVE BYTE CLC RETURN 10$: BITEQ #BFMSK,BF.FUL(R3),11$ ; legal end of buffer? JMP HLTER ; NO NO NO 11$: MOV BF.CAD(R3),R0 ; CURRENT ADDRESS MOV (R0),R0 ; ANOTHER IN CHAIN? BNE 20$ ; YES, USE IT MOV LNKHD,R0 ; GET BUFFER FROM POOL? BEQ 30$ ; NONE! MOV (R0),LNKHD ; REMOVE IT FROM POOL CLR (R0) ; NO FOREWARD LINK MOV BF.END(R3),2(R0) ; BACKWARD LINK MOV R0,BF.END(R3) ; MAKE THIS LAST BUFFER MOV R0,@BF.CAD(R3) ; FOREWARD LINK 20$: MOV #BFSIZ,(R3) ; NEW COUNT MOV R0,BF.CAD(R3) ; NEW CURRENT BUFFER ADD #BFLNK,R0 ; POINTS TO BYTE IN FRONT OF FIRST MOV R0,BF.ADD(R3) ; SAVE ADDRESS .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC BR PBYT ; AND GET THE BYTE FINALLY 30$: CALL EXTEND ; try to extend memory BCC 10$ ; success KILL: CALL $ERMSG .WORD CORERR ; NO MORE MEMORY AVAILABLE JMP RUNOFF ; KILL KILL KILL ; ; ROUTINE GETS 1 WORD FROM BUFFERS ; GWRD:: CALL GBYT ; GET LOWER BYTE MOV R1,-(SP) ; SAVE IT CALL GBYT ; NEXT UPPER BCS 10$ ; NO MORE MOVB R1,1(SP) MOV (SP)+,R1 ; GET RESULT CLC RETURN 10$: TST (SP)+ ; unstack SEC RETURN ; ; ROUTINE TO SAVE 1 WORD ; PWRD:: CALL PBYT ; SAVE LOWER BYTE SWAB R1 ; SWAP BYTES CALL PBYT ; SAVE UPPER SWAB R1 RETURN ; ; extend the available pool ; EXTEND: EXTK$S #5 BCC 10$ RETURN 10$: ADD #500,XTOP ; readjust top for extend ; ; subroutine to set up linked list of dynamic buffers ; LNKSET:: MOV XBOT,R0 ; save value ADD #BFSIZ+6,XBOT ; raise bottom BCS 40$ ; done CMP XBOT,XTOP ; too big BHIS 40$ ; yes MOV LNKHD,(R0) ; Save current linked buffer chain MOV R0,LNKHD ; put current buffer at head BR LNKSET ; try another 40$: SUB #BFSIZ+6,XBOT ; restore CLC RETURN ; ; RSTBF ; ROUTINE TO SET REQUESTED LOCATION AS END OF BUFFER READY FOR INPUT ; ; ENDBF ; SET TO END OF BUFFER + MADE READY FOR PUTTING TO BUFFER ; ENDBF:: MOV BF.MAX(R3),R1 ; LOCATION TO GO TO .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC CMP R1,BF.FUL(R3) ; is R1 really the end? BHIS RSTBF ; yes MOV BF.FUL(R3),R1 ; no get real end RSTBF:: CALL FNDBF ; GO TO IT CLR BF.MAX(R3) ; CLEAR DATA MAX MOV #BFSIZ,BF.CNT(R3) ; BUFFER SIZE SUB R1,BF.CNT(R3) ; ADJUST COUNT TO BUFFER SIZE .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC RETURN ; ; SETS POINTERS TO BUFFER LOCATION SPECIFIED IN R1 ; R1=0 IF BAD LOCATION SPEC ; IF MAX IS NOT SET MAX=CURRENT INDEX ; FNDBF:: .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC CMP BF.FUL(R3),BF.MAX(R3) ; CURRENT BIGGER THAN MAX? BLOS 10$ ; NO MOV BF.FUL(R3),BF.MAX(R3) ; RESET MAX 10$: CMP R1,BF.MAX(R3) ; GREATER THAN CURRENT BLOS 20$ ; NO SEC RETURN ; RETURN NO ACTION 20$: MOV BF.ADD(R3),R0 ; current address SUB BF.CAD(R3),R0 ; minus cuurrent buffer address SUB #BFLNK,R0 ; minus header offset=bytes this buff. SUB R0,BF.FUL(R3) ; now set index to start of buffer MOV BF.CAD(R3),R0 ; CURRENT BUFFER SUB BF.FUL(R3),R1 ; go foreward? BHI 40$ ; yes BEQ 60$ ; already there 30$: MOV 2(R0),R0 ; GO BACK 1 BUFFER .IFDF $DEBUG BNE 35$ CALL KILL 35$: .ENDC SUB #BFSIZ,BF.FUL(R3) ADD #BFSIZ,R1 ; add on buffer size BCC 30$ ; NOT THERE YET BR 60$ ; FOUND CORRECT ONE 40$: SUB #BFSIZ,R1 ; done yet BLOS 50$ ; yes ADD #BFSIZ,BF.FUL(R3) MOV (R0),R0 ; GO FOREWARD .IFDF $DEBUG BNE 45$ CALL KILL 45$: .ENDC BR 40$ 50$: ADD #BFSIZ,R1 ; ADJUST TO POSITIVE 60$: TSTNE R1,70$ ; index non zero? TSTEQ 2(R0),70$ ; no backward link? MOV 2(R0),R0 ; go back SUB #BFSIZ,BF.FUL(R3) ; move index back ADD #BFSIZ,R1 ; to point to last byte 70$: MOV R0,BF.CAD(R3) ; SAVE CURRENT BUFFER ADD R1,R0 ; ALMOST CURRENT DAT ADD #BFLNK,R0 ; DATA -1 MOV R0,BF.ADD(R3) ; SAVED ADD R1,BF.FUL(R3) ; CURRENT INDEX MOV BF.MAX(R3),BF.CNT(R3) ; MAX SUB BF.FUL(R3),BF.CNT(R3) ; - CURRENT = COUNT? MOV #BFSIZ,R0 ; BUFFER SIZE SUB R1,R0 ; - OFFSET = COUNT CMP R0,BF.CNT(R3) ; WHICH ONE? BGT 80$ ; PICK SMALLER MOV R0,BF.CNT(R3) ; SMALLER ONE 80$: .IFDF $DEBUG CALL TEST ; *** DEBUG .ENDC RETURN .IFDF $DEBUG TEST: CMP (R3),#BFSIZ ; too big? BHI 10$ ; yes TST BF.FUL(R3) ; too big? BLT 10$ MOV BF.CAD(R3),-(SP) ADD #BFLNK,(SP) CMP (SP),BF.ADD(R3) ; current address too small? BHI 10$ ; yes ADD #BFSIZ,(SP) SUB BF.CNT(R3),(SP) CMP (SP),BF.ADD(R3) ; current address too big? BLO 10$ TST (SP)+ return 10$: jmp kill .ENDC ; ; The input file is the exception to the buffer access rules. ; Since it is never extended it may be accessed directly. To ; simplify access the following 2 routines are used, without all ; of the overhead in the big routines. ; ; SUBROUTINE TO BACKSPACE INPUT FILE 1 CHARACTER ; ; ; QUICK ROUTINE TO FIND LOCATION IN INPUT FILE ; FNDIN:: CMP R1,#IBFSZ ; ADDRESS TOO BIG? BLOS 10$ ; NO CLR R1 ; YES TOO BIG 10$: MOV BF.MAX(R3),BF.CNT(R3) ; MAX SIZE SUB R1,BF.CNT(R3) ; NOW REMAINING SIZE MOV BF.CAD(R3),BF.ADD(R3) ; START OF BUFFER ADD #BFLNK,BF.ADD(R3) ; POINTS TO DATA-1 ADD R1,BF.ADD(R3) ; CURRENT ADDRESS MOV R1,BF.FUL(R3) ; NEW LOCATION RETURN ; BFLNK=3 ; Offset from buffer to data-1 .PSECT BUFFER,RW,GBL,D .MACRO BUFF,SIZE .WORD SIZE ; BF.CNT .WORD 0 ; BF.FUL .WORD 10$+BFLNK ; BF.ADD .WORD 10$ ; BF.CAD .WORD 10$ ; BF.BEG .WORD 10$ ; BF.END .BLKW 3 ; BF.MAX,SPC,HED 10$: .BLKW 2 ; buffer foreward/backward links .BLKB SIZE ; data area .ENDM ; ; extra header macro ; .MACRO BUFFHD,ADD .WORD 0 ; BF.CNT .WORD 0 ; BF.FUL .WORD ADD+BFLNK ; BF.ADD .WORD ADD ; BF.CAD .WORD ADD ; BF.BEG .WORD ADD ; BF.END .BLKW 3 ; BF.MAX,SPC,HED .ENDM ; ; BUFFER DEFINITIONS ; BFHED==6 ; 6 BYTE I/O HEADER BF.CNT==0 ; COUNT OF CHAR REMAINING BF.FUL==2 ; HOW MANY CHAR IT HAS (FULL) BF.ADD==4 ; CURRENT CHAR ADDRESS BF.CAD=6 ; CURRENT BUFFER BF.BEG=10 ; FIRST BUFFER ADDRESS BF.END=12 ; LAST BUFFER ADDRESS BF.MAX==14 ; MAX # BYTES BF.SPC==16 ; SPACING CHARS BF.HED==20 ; HEADER ; ; THE ACTUAL DATA BUFFER HAS THE FOLLOWING FORMAT ; WORD 1= FOREWARD LINK ; WORD 2= BACKWARD LINK ; 3 - N = N-4 BYTES OF DATA ; ; ; TEXT BUFFER HEADER (PRECEEDS TEXT) TEXT TERMINATED BY A NULL ; APPLIES TO FOOTNOTE + SECONDARY BUFFERS ; ; BYTE 0 LINE SKIP COUNT ; 1 FLAGS 1=CHANGE BAR ; 2 LEFT MARGIN SPACING ; 3 SPACES/EXPANDABLE SPACE ; 4 EXPANDABLE SPACES TO LEFT ; 5 LEFT/RIGHT INDICATOR ; ; ; IMPURE DATA STORAGE FOR INPUT BUFFERS ; LUNSTK::.BYTE 0,8. ; CURRENT TABLE POINTER, MAX POINTER SUBSTK:: .BYTE 0,6. ; current substitute pointer,max BUFADD::.WORD IBUF1 ; POINTS TO CURRENT INPUT HEADER ; *** .WORD SUBF1,SUBF2,SUBF3 ; points to substitution buffers FDBTAB::.WORD LUN4 ; POINTS TO FDB BLOCKS .WORD LUN5,LUN6,LUN7,LUN8 BUFTAB::.WORD IBUF1 ; POINTS TO INPUT BUFFERS ; *** .WORD IBUF2,IBUF3,IBUF4,IBUF5 .WORD 0 ; CURRENT NUMBER OF BYTES ; *** IBFSZ=140. ; BUFFER SIZE ; IBUF1: BUFF IBFSZ+4 IBUF2: BUFF IBFSZ+4 IBUF3: BUFF IBFSZ+4 IBUF4: BUFF IBFSZ+4 IBUF5: BUFF IBFSZ+4 ; ; substitution buffer headers ; SUBF1: BUFFHD SUBBUF SUBBUF: .BLKB BFSIZ+4 SUBF2: BUFFHD SUBBUF SUBF3: BUFFHD SUBBUF ; ; dynamic memory control locations ; XBOT:: .BLKW 1 ; BEGINNING OF ALLOCATED INDEX AREA XTOP:: .BLKW 1 ; HIGHEST VIRTUAL ADDRESS IN PROGRAM XFIRST:: .WORD 0 ; first index entry (first in alphabet) LNKHD:: .BLKW 1 ; POOL BUFFERS HEADER ; ; FOOTNOTE BUFFER ; FOTBF:: BUFF BFSIZ ; ; Index entry buffer ; INXBF:: BUFF BFSIZ ; ; COMMAND LINE INPUT BUFFER/ MESSAGE BUFFER/ GENERAL FORMAT BUFFER ; TTLIN==BFSIZ TTBF:: BUFF 0 TTBUF:: .BLKB BFSIZ+2 ; COMMAND LINE INPUT BUFFER ; ; FINAL OUTPUT BUFFER ; .WORD 0 HFOUT:: .WORD 256.,0,0 OUBUF:: .BLKB 256. ; ; ESCAPE SEQUENCE TABLE ; ESCBF:: BUFF BFSIZ ; ; SECONDARY TEXT BUFFER ; TX2BF:: BUFF BFSIZ ; ; TITLE BUFFERS ; TTLBF:: BUFF BFSIZ ; ; SUBTITLE BUFFER ; STLBF:: BUFF BFSIZ ; ; BACKSPACE BUFFER ; This buffer contains a line with spaces and underline chars. ; for underlining if not doing it by backspace. ; ULNSZ==150. ULNMAX:: .WORD 0 ; MAX NUMBER OF CHARS IN BUFFER UBUFF:: .BLKB ULNSZ+2 .END