PROCEDURE ,010000 ;+ ; abstract: IND ; ; This module has support for the include files for ; RUNOFF. ; ; calling sequence: ; ; MOV #new_file_name,R0 ; MOV #new_file_name_length,R1 ; CALL newfil ; open a new file ; ; CALL pshfil ; push current file on stack ; ; CALL popfil ; attempt to pop old file from ; ; stack. If the stack is now ; ; empty, the carry bit is set. ; ; written: 24-JAN-80, -1.0.0-, Bruce C. Wright ; verified: 24-JAN-80, -1.0.0-, Bruce C. Wright ; modified: 18-SEP-80, -1.0.1-, M.T.E. Woodbury ; modified: 18-MAR-81, -1.0.2-, M.T.E. Woodbury ;- .MCALL OFID$R,OPNS$R,CLOSE$,CSI$,CSI$1,CSI$2,FDBF$R .MCALL FDOP$R,NMBLK$ ; ; The include file list is a singly-linked list. Its header is ; in FILHD, and the first word of all of the entries points to ; the next entry. There is no limit on the number of entries ; which may be allocated, except for the amount of dynamic storage ; available. An entry represents a saved file, e. g., the current ; file does NOT have an entry in the include list. On an end-of- ; file, the top entry in the list (which is handled as a LIFO ; list), is restored and processing continues as if no end-of-file ; had occurred. The reserved words in the list (as shown ; below) are not used and are not anticipated to ever be used, but ; are reserved to make the list entry exactly equal to three index ; entries without the text, hopefully reducing the fragmentation ; of the free space. Note that the length of the allocated block ; precedes a block, so that the actual length of an allocated ; index block is 6. words rather than 5. words as used in the ; index subroutines (the sixth word is invisible to the index ; subroutines). The number of words allocated by an include entry ; is 17. in the declared part and 1. (the length word) in the ; system part, so that it is exactly equal to 18. words or three ; index entries. ; FI.LNK = 0 ; 1 link to next file block FI.FID = FI.LNK+2 ; 2 fid of current file FI.DID = FI.FID+6 ; 5 did of current file FI.DEV = FI.DID+6 ; 8 device name of current file FI.UNI = FI.DEV+2 ; 9 device unit # of current file FI.BLK = FI.UNI+2 ; 10 block # of saved file FI.BYT = FI.BLK+4 ; 12 byte within block FI.SEL = FI.BYT+2 ; 13 selection string FI.LEN = FI.SEL+10 ; 17 ** no reserved words ** CODE IND POPFIL:: MOV R5,-(SP) ; save r5 MOV FILHD,R5 ; get file list head. BNE 10$ ; it's there -- pop files. MOV (SP)+,R5 ; recover R5 SEC ; show were not able to open file. RETURN ; and return to the caller. 10$: CLOSE$ #TTLDMY ; close the current file. BCS FILERR ; error? MOV (R5),FILHD ; indirect to next element in chain. MOV FI.FID(R5),F.FNB+N.FID(R0) ; move in the fid MOV FI.FID+2(R5),F.FNB+N.FID+2(R0) MOV FI.FID+4(R5),F.FNB+N.FID+4(R0) ; ... MOV FI.DID(R5),F.FNB+N.DID(R0) ; move in the did MOV FI.DID+2(R5),F.FNB+N.DID+2(R0) ; ... MOV FI.DID+4(R5),F.FNB+N.DID+4(R0) MOV FI.DEV(R5),F.FNB+N.DVNM(R0) ; move in the device MOV FI.UNI(R5),F.FNB+N.UNIT(R0) ; move in the unit CALL SAVFNB ; restore default context OFID$R R0 ; open the file by file-id BCS FILERR ; error? MOV R1,-(SP) ; save regs for .POINT MOV R2,-(SP) ; MOV R3,-(SP) ; MOV FI.BLK(R5),R1 ; get high order bits of block MOV FI.BLK+2(R5),R2 ; get low order bits of block # MOV FI.BYT(R5),R3 ; get the byte offset. CALL .POINT ; point back into the file. MOV (SP)+,R3 ; Recover registers MOV (SP)+,R2 ; ... BCC 20$ ; J if no errors CMP F.ERR(R0),# ; Is it end-of-file? BNE FILERR ; J if not, some other error. MOV R5,R1 ; Get the area to free. CALL FREE ; Free it. MOV (SP)+,R1 ; Recover R1 MOV (SP)+,R5 ; Recover R5 BR POPFIL ; And try to pop another level. 20$: MOV FI.SEL(R5),SELECT ; Restore selection string ;1.0.2 MOV FI.SEL+2(R5),SELECT+2 ;1.0.2 MOV FI.SEL+4(R5),SELECT+4 ;1.0.2 MOV FI.SEL+6(R5),SELECT+6 ;1.0.2 MOV R5,R1 ; remember the block address. CALL FREE ; free it up. MOV (SP)+,R1 ; recover r1 MOV (SP)+,R5 ; recover R5 CLC ; show no error. RETURN ; and return to the caller. FILERR: MOV R0,-(SP) ; save R0 DIAG INDERR,FCS ; it's an FCS error! JMP RUNOFF ; and re-start. PSHFIL:: MOV R0,-(SP) ; save registers MOV R1,-(SP) ; ... MOV R2,-(SP) ; ... MOV R3,-(SP) ; ... MOV #FI.LEN,R1 ; try to pick a node. CALL ALLOC ; allocate it. MOV R1,-(SP) ; save it MOV #TTLDMY,R0 ; get input fdb CALL .MARK ; mark current position. BCS FILERR ; error? MOV (SP)+,R0 ; remember picked node. MOV R1,FI.BLK(R0) ; remember high order bits of block # MOV R2,FI.BLK+2(R0) ; remember lower order bits MOV R3,FI.BYT(R0) ; remember current byte offset in block MOV TTLDMY+F.FNB+N.FID,FI.FID(R0) ; save fid MOV TTLDMY+F.FNB+N.FID+2,FI.FID+2(R0) ; ... MOV TTLDMY+F.FNB+N.FID+4,FI.FID+4(R0) ; ... MOV TTLDMY+F.FNB+N.DID,FI.DID(R0) ; save did MOV TTLDMY+F.FNB+N.DID+2,FI.DID+2(R0) ; ... MOV TTLDMY+F.FNB+N.DID+4,FI.DID+4(R0) ; ... MOV TTLDMY+F.FNB+N.DVNM,FI.DEV(R0) ; save device MOV TTLDMY+F.FNB+N.UNIT,FI.UNI(R0) ; and unit MOV SELECT,FI.SEL(R0) ; remember current select string ;1.0.2 MOV SELECT+2,FI.SEL+2(R0) ;1.0.2 MOV SELECT+4,FI.SEL+4(R0) ;1.0.2 MOV SELECT+6,FI.SEL+6(R0) ;1.0.2 MOV FILHD,FI.LNK(R0) ; link into the chain. MOV R0,FILHD ; and remember the current one. MOV #TTLDMY,R0 ; save default context CALL SAVFNB ; CLOSE$ R0 ; close the file. BCS FILERR ; error? MOV (SP)+,R3 ; recover registers MOV (SP)+,R2 ; ... MOV (SP)+,R1 ; ... MOV (SP)+,R0 ; ... RETURN ; and return to the caller. NEWFIL:: MOV R2,-(SP) ; save R2 MOV R0,-(SP) ; Save R0 MOV R0,R2 ; remember file name pointer. CSI$1 #CSIBLK,R2,R1 ; perform preliminary parse. BCS SYNERR ; syntax error? BITB #CS.EQU,CSIBLK+C.STAT ; is there an = here? BNE SYNERR ; yes, error. ; CLR SELECT ; clear the selection sting ;1.0.2 CSI$2 R0,OUTPUT,#INCSW ; get a file name. BCS SYNERR ; syntax error? BITB #CS.EQU!CS.WLD!CS.MOR,CSIBLK+C.STAT ; bad things set? BNE SYNERR ; yes, error. .IF DF R$$STS FDBF$R #TTLDMY,,,#2,#FD.RAH ; Say we want multi-buffering .IFF FDBF$R #TTLDMY,,,#1 ; Say no multi-buffering .ENDC FDOP$R R0,,,#DFNB ; Set default file context OPNS$R R0,,#CSIBLK+C.DSDS ; open the file. BCS FILERR ; error? MOV (SP)+,R0 ; Recover R0 MOV (SP)+,R2 ; recover R2 RETURN ; and return to the caller. SYNERR: MOV R0,-(SP) ; save FDB address. DIAG MGCDME,FCS ; report syntax error. JMP RUNOFF ; and restart program. ; SAVFNB: MOV F.FNB+N.DID(R0),DFNB+N.DID ; Save did MOV F.FNB+N.DID+2(R0),DFNB+N.DID+2 ; ... MOV F.FNB+N.DID+4(R0),DFNB+N.DID+4 ; MOV F.FNB+N.DVNM(R0),DFNB+N.DVNM ; Save device info MOV F.FNB+N.UNIT(R0),DFNB+N.UNIT ; ... RETURN ; DATA INDD FILHD:: .WORD 0 CSI$ CSIBLK: .BLKB C.SIZE DFNB: NMBLK$ ,RNO ; Default extension .END