.TITLE MISHDR - MISH Header Record .IDENT /1.0/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided or ; otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: MISHDR.MAC ; Author: Robin Miller & Gary Larsen ; Date: November 9, 1982 ; ; Description: ; ; This routine generates the header record from the input file. ; This record is used during de-compression to restore the original ; file attributes to the output file. ; ; Modification History: ; ;- .ENABL AMA .NLIST BEX DEBUG = 0 ; DEFINE FOR DDT DEBUGGING .MCALL DIR$, GET$, GTIM$, QIOW$ .MCALL FCSBT$, FDOFF$, FHDOF$, NBOFF$ ; Define the FDB bit and offsets. .IF NDF DEBUG FCSBT$ ; Define FCS bits. FDOFF$ DEF$L ; Define FDB offsets. FHDOF$ DEF$L ; Define file header offsets. NBOFF$ DEF$L ; Define FNB offsets. .IFF FCSBT$ DEF$G ; Define FCS bits globally. FDOFF$ DEF$G ; Define FDB offsets globally. FHDOF$ DEF$G ; Define file header offsets. NBOFF$ DEF$G ; Define FNB offsets globally. .ENDC ; ACP function codes to read and write file attributes: RFHBLK::.BYTE -1,5 ; Read UIC/protection/characteristics. .WORD HDRBUF+O.UIC ; Address where to store them. .BYTE -4,40 ; Read the record I/O area. .WORD HDRBUF+O.UFAT ; Address where to store them. .WORD 0 ; End of ACP QIO list. WFHBLK::.BYTE 2,3 ; Write protection / characteristics. .WORD HDRBUF+O.PROT ; Address where they are stored. .BYTE 4,40 ; Write the user file attributes. .WORD HDRBUF+O.UFAT ; Address where they are stored. .WORD 0 ; End of ACP QIO list. ; QIO's to read and write the file attributes. RFHDR: QIOW$ IO.RAT,INLUN,INEFN,,ISTAT,,<,RFHBLK,,,,> WFHDR: QIOW$ IO.WAT,OUTLUN,OUTEFN,,OSTAT,,<,WFHBLK,,,,> GTIME: GTIM$ DATBUF ; Get date and time. DATBUF: .BLKW 8. ; and store them here. T2FHDR::.WORD 0 ; Flag for doing file header. ; Define the header record offsets: HDRSIZ = 80. ; Size of our header record. HDRBUF::.BLKB HDRSIZ ; Buffer for MISH header record. ; Size Description: O.FILE == 0. ; (22) The file name in ASCII. O.FNAM == O.FILE+22. ; ( 6) The file name in Radix-50. O.FTYP == O.FNAM+6 ; ( 2) The file type in Radix-50. O.FVER == O.FTYP+2 ; ( 2) The version number in binary. O.UIC == O.FVER+2 ; ( 2) The binary file owner UIC. O.PROT == O.UIC+2 ; ( 2) The binary protection code. O.FCHA == O.PROT+2 ; ( 2) The file characteristics. O.UCHA == O.FCHA ; ( 1) The user file characteristics. O.SCHA == O.UCHA+1 ; ( 1) The system file characteristics. O.UFAT == O.FCHA+2 ; (32) The user file attributes. ; FCS uses the 1st 14 bytes. O.RTYP == O.UFAT ; ( 1) The record type. O.FORG == O.RTYP ; RMS format and organization. O.RATT == O.RTYP+1 ; ( 1) The record attributes. ; Same offset for RMS. O.RSIZ == O.RATT+1 ; ( 2) The maximum record size. ; Same offset for RMS. O.HIBK == O.RSIZ+2 ; ( 4) The highest block number. O.HVBN == O.HIBK ; RMS high virtual block number. O.EFBK == O.HIBK+4 ; ( 4) The end of file block number. O.HEOF == O.EFBK ; RMS end of file block number. O.FFBY == O.EFBK+4 ; ( 2) The 1st free byte in last block. ; Same offset for RMS. ; Start of RMS specific offsets: O.BKSZ == O.FFBY+2 ; ( 1) Bucket size (relative/indexed). O.HDSZ == O.BKSZ+1 ; ( 1) The fixed header size. O.MRS == O.HDSZ+1 ; ( 2) The maximum record size limit. O.DEQ == O.MRS+2 ; ( 2) The default extend quantity. ; O.DATE == O.UFAT+32. ; (10) The date this file was mished. .SBTTL GETHDR - Get The Header Record ;+ ; ; GETHDR - Get the header record from the input file. ; ; Inputs: ; The input file must be open. ; ; Outputs: ; R0 = address of the input FDB. ; C bit clear/set = success/failure. ; ; ;- GETHDR::GET$ #INFDB,#WRKBUF,#HDRSIZ ; Read the header record. BCC 5$ ; If CC, read was successful. CALL FILERR ; Else, report the error message. 5$: JSR R2,$SAVVR ; Save R0 - R2. (02) MOV #ARGBLK,R5 ; Setup the argument block (02) MOV F.NRBD(R0),R1 ; Copy the record byte count. (02) MOV #WRKBUF,R2 ; Address of work buffer. (02) ADD R1,R2 ; Setup buffer address. (02) GET$ #INFDB,R2,#HDRSIZ ; Get remainder of file header. (02) BCS 10$ ; If CS, we had an error (02) MOV #2,RECNUM ; Show we have read two records (02) ADD F.NRBD(R0),R1 ; Total byte count for header. (02) MOV R1,R3 ; Save byte count. (02) 10$: RETURN .SBTTL SETHDR - Setup The Output FDB Header ;+ ; ; SETHDR - Setup the output FDB header. ; ; This routine is used to read the header record from the input file ; and fill in the appropriate fields in the output FDB before opening ; the file. ; ; Inputs: ; The input file must be open. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- SETHDR::CALL $SAVAL ; All registers are preserved CALL GETHDR ; Get the header record. BCS 100$ ; If CS, couldn't get it. MOV #WRKBUF,R0 ; Address of buffer to convert. (02) MOV #HDRBUF,R4 ; Address of converted buffer. (02) MOV #-1,T2FHDR ; Show we are doing the header. (02) CALL DOT2F ; Convert the header record. (02) BCS 100$ ; If CS, we had an error. (02) CLR T2FHDR ; Show header done. (02) MOV #HDRBUF,R0 ; Address of input file header (02) MOV R0,R2 ; Copy the FDB address. ;02 MOV F.NRBD+2(R0),R0 ; Copy the record address. ; If no output file was specified, use the original file name. BIT #B.OFIL,STATUS ; Was an output file specified ? BNE 20$ ; If NE, yes. MOV R0,R1 ; Copy the file name address. MOV #OUTFIL,R0 ; No, copy the original name. CALL MOVEC ; Copy the file name. BIS #B.OFIL,STATUS ; Show we have a file now. MOV #HDRBUF,R0 ; And reset the record address. (02) ;02 MOV F.NRBD+2(R2),R0 ; And reset the record address. 20$: MOV #OUTFDB,R1 ; Address of the output FDB. ; Copy the file attributes. MOVB O.RTYP(R0),F.RTYP(R1) ; Copy the file type. MOVB O.RATT(R0),F.RATT(R1) ; Copy the file attributes. MOV O.RSIZ(R0),F.RSIZ(R1) ; Copy the maximum file size. MOV O.HIBK+2(R0),R2 ; Copy the blocks to allocate. BITB #UC.CON,O.FCHA(R0) ; Was original file contiguous ? BNE 50$ ; If NE, yes (leave positive). NEG R2 ; Make negative for non-continguous. 50$: MOV R2,F.CNTG(R1) ; Number of blocks to allocate. MOV #-5.,F.ALOC(R1) ; Just incase we need to extend. ; Since the F.FFBY field gets zeroed by WRITE$, we must save it and ; store it in the FDB just before the file gets CLOSEd. MOV O.FFBY(R0),SFFBY ; Save first free byte for CLOSE$. ; MOV O.FFBY(R0),F.FFBY(R1) ; First free byte in last block. CLC ; Show success. 100$: RETURN .SBTTL WRTATR - Write The User File Attributes ;+ ; ; WRTATR - Write the user file attributes. ; ; This routine is used to write the original user file attributes. This ; is needed because there is no way to write all the attribute bytes from ; standard FCS (FCS only used the first 14 bytes). RMS uses more than FCS. ; ; Inputs: ; The input file must be open. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- WRTATR::JSR R2,$SAVVR ; Save R0 - R2. DIR$ #WFHDR ; Write the file attributes. CALL CHKDIR ; Check the directive status. BCS 100$ ; If CS, it failed. MOVB OSTAT,R0 ; Else, copy the I/O status. BPL 100$ ; If PL, success. BIC #^C377,R0 ; Clear to show its an I/O error. CALL WRTERR ; Write the error message. 100$: RETURN .SBTTL WRTHDR - Write The Header Record ;+ ; ; WRTHDR - Write the header record for the compressed file. ; ; Inputs: ; R5 = the argument block address. ; The input and output files must be open. ; ; Outputs: ; All registers are preserved. ; ;- WRTHDR::JSR R2,$SAVVR ; Save R0 - R2. MOV #HDRBUF,R0 ; Address of the header record buffer. MOV #HDRSIZ/2,R1 ; and the header length in words. ; Initialize the header record to nulls. 10$: CLR (R0)+ ; Clear the entire buffer. SOB R1,10$ ; And loop until done. ; Now read the file header information. DIR$ #RFHDR ; Read the file header information. CALL CHKDIR ; Check the directive status. BCS 50$ ; If CS, it failed. MOVB ISTAT,R0 ; Else, copy the I/O status. BPL 20$ ; If PL, success. BIC #^C377,R0 ; Clear to show its an I/O error. CALL WRTERR ; Write the error message. BR 50$ ; And return failure ... ; Make the ASCII file name. 20$: MOV #HDRBUF+O.FILE,R0 ; Store the ASCII file name here. MOV INFDB+F.FNAM,R1 ; Copy the 1st part of file name. CALL $C5TA ; Convert RADIX-50 to ASCII. MOV INFDB+F.FNAM+2,R1 ; Copy the 2nd part of file name. BEQ 30$ ; If EQ, this is none. CALL $C5TA ; Convert it to ASCII. MOV INFDB+F.FNAM+4,R1 ; Copy the 3rd part of file name. BEQ 30$ ; If EQ, this is none. CALL $C5TA ; Convert it to ASCII. 30$: CMPB #SPACE,-(R0) ; Is the last character a space ? BEQ 30$ ; If EQ, yes (backup over them). INC R0 ; Point to the next character. MOVB #'.,(R0)+ ; Separate file name and file type. MOV INFDB+F.FTYP,R1 ; Copy the radix-50 file type. BEQ 35$ ; If EQ, there is none. CALL $C5TA ; Else, convert it to ASCII. 35$: CMPB #SPACE,-(R0) ; Is the last character a space ? BEQ 35$ ; If EQ, yes (backup over them). INC R0 ; No, adjust the pointer. CLRB (R0) ; And terminate with a null. ; Copy the radix-50 file name, file type, and binary version. MOV #INFDB,R0 ; Address of the input FDB. MOV #HDRBUF,R1 ; Address of header record buffer. MOV F.FNAM(R0),O.FNAM(R1) ; Copy the MOV F.FNAM+2(R0),O.FNAM+2(R1) ; radix-50 MOV F.FNAM+4(R0),O.FNAM+4(R1) ; file name. MOV F.FTYP(R0),O.FTYP(R1) ; Copy the radix-50 file type. MOV F.FVER(R0),O.FVER(R1) ; Copy the binary version number. ; Fill in the current date. DIR$ #GTIME ; Get the date and time. CALL CHKDIR ; Check/report any errors. BCS 40$ ; If CS, it failed. MOV #HDRBUF+O.DATE,R0 ; Store the formatted date here. MOV #DATBUF+G.TIYR,R1 ; Address of year/month/day. CALL $DAT ; Convert them to dd-mmm-yy. CLRB (R0) ; Terminate the date with null. ; Finally write the header record. 40$: ;01 MOV #HDRBUF,R1 ; The header record address ;01 MOV #HDRSIZ,R2 ; and the length. MOV #HDRBUF,R0 ; The header record address (01) MOV #HDRSIZ,R3 ; and length. (01) MOV #BUFADR,R4 ; Buffer to store header record.(01) CALL DOF2T ; Now convert it to text. (01) MOV #BUFADR,R1 ; Address of converted buffer (01) CALL EIGHTY ; write eighty bytes records (01) 50$: RETURN .END