.TITLE DECOMP - Decompress Input Records .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: DECOMP.MAC ; Author: Robin Miller & Gary Larsen ; Date: October 27, 1982 ; ; Description: ; ; This routine decompresses records that were compressed. ; ; Modification History: ; ;- .ENABL AMA .NLIST BEX .MCALL GET$, WRITE$, WAIT$ .SBTTL DECOMP - Decompress The Input Records ;+ ; ; DECOMP - Decompress the input records. ; ; Inputs: ; The input and output files must be open. ; ; Outputs: ; All registers are preserved. ; ;- DECOMP::CALL $SAVAL ; Save all registers. MOV #ARGBLK,R5 ; Address of the argument block. MOV #BUFADR,O.BADR(R5) ; Setup start of output buffer. CLR @O.BLEN(R5) ; Initialize the byte count. MOV #WRKBUF,O.RADR(R5) ; Address for converted text. (02) CALL WRTATR ; Write the original attributes. BCC DLOOP ; If CC, success. RETURN ; Else return ... ; Loop reading the input records. .ENABL LSB DLOOP:: BIT #B.CTRC,STATUS ; CTRL/C typed to stop decompress ? BNE 100$ ; If NE, yes (stop decompressing). ;02 GET$ #INFDB,#RECADR,#RECSIZ ; Get the next input record. ;02 BCS 90$ ; If CS, had an error ;02 INC RECNUM ; Bump the record number. CALL GETM ; Get the record. (02) BCS 100$ ; If CS, we had an error. (02) MOV O.RADR(R5),R4 ; Address for converted text. (02) CALL DOT2F ; Now convert it. (02) BCS 100$ ; If CS, we had an error. (02) ;02 MOV F.NRBD(R0),@O.RLEN(R5) ; Copy the record byte count. ;02 MOV F.NRBD+2(R0),O.RADR(R5) ; Copy the record address. ;02 ADD @O.RLEN(R5),COMLEN ; Accumulate compressed length. MOV O.RADR(R5),R0 ; Copy the record address. ; Determine the type of String Control Byte. 10$: DEC @O.RLEN(R5) ; Adjust the input record count. MOVB (R0)+,R2 ; Copy the string control byte. BEQ 60$ ; If EQ, end of record SCB. BPL 80$ ; If PL, invalid SCB encountered. BIC #^C377,R2 ; Cleanup the high byte. ; Check for a continuation SCB. CMP #B.MBON,R2 ; Is this a continuation SCB ? BEQ DLOOP ; If EQ, yes (get the next record). ; We have some data coming, now find out what kind of data. MOV R2,R3 ; Copy the string control byte. BIC #^C77,R3 ; Presume a non-duplicate string. BITB #B.NDUP,R2 ; Did we guess right ? BNE 50$ ; If NE, yes (data after the SCB). ; Duplicate character coming. BIC #^C37,R3 ; Isolate the duplicate count. MOVB #SPACE,R4 ; Presume duplicate is a blank. BITB #B.NBLA,R2 ; Did we guess right ? BEQ 20$ ; If EQ, yes MOVB (R0)+,R4 ; Nope, dup. character follows SCB. DEC @O.RLEN(R5) ; Adjust the input record count. ; Copy the duplicate character the appropriate # of times. 20$: MOVB R4,@O.BADR(R5) ; Copy the duplicate character. INC O.BADR(R5) ; Point to the next output address. INC @O.BLEN(R5) ; Adjust the output buffer count. SOB R3,20$ ; And loop until done. BR 10$ ; Another SCB is next. ; A non-duplicate string control byte was encountered. R3 = count. 50$: MOVB (R0)+,@O.BADR(R5) ; Copy the next data character. DEC @O.RLEN(R5) ; Adjust the input record count. INC O.BADR(R5) ; Point to the next output address. INC @O.BLEN(R5) ; Adjust the output buffer length. SOB R3,50$ ; And loop until done. BR 10$ ; Another SCB is next. ; The output buffer is full, now write it to the output file. 60$: CMP @O.BLEN(R5),#BLKSIZ ; Is this the correct block size ? BEQ 70$ ; If EQ, Yes. ERRMSG BADCNT,<%MISH-F-BADCNT, bad output block size.> BR 100$ ; And use common return. 70$: CALL WRTBLK ; Write the block to the file. BCS 100$ ; If CS, we had an error. ADD @O.BLEN(R5),ORGLEN ; Accumulate the original length. MOV #BUFADR,O.BADR(R5) ; Reset start of the output buffer. CLR @O.BLEN(R5) ; Initialize the buffer byte count. ;02 TST @O.RLEN(R5) ; Is there more in this input record ? ;02 BGT 10$ ; If GT, yes (another SCB is next). JMP DLOOP ; Nope, get the next input record. 80$: ERRMSG INVSCB,<%MISH-F-INVSCB, invalid string control byte.> BR 100$ ; And use common return ... ; Error encountered reading the input file. ;0290$: TST @O.BLEN(R5) ; Is there anything to output ? ;02 BEQ 95$ ; If EQ, no. ;02 CALL WRTBLK ; Yes, write it to the output file. ;0295$: CMPB F.ERR(R0),#IE.EOF ; Did we encounter end of file ? ;02 BEQ 100$ ; If EQ, yes (only error expected). ;02 CALL FILERR ; Else, report the error. ;02 BR 110$ ; And close the files. ; Finish up the output FDB before closing it. 100$: MOV #OUTFDB,R0 ; Address of the output FDB. MOV SFFBY,F.FFBY(R0) ; Save the first free byte. BEQ 110$ ; If EQ, leave EOF block alone. SUB #1,F.EFBK+2(R0) ; Else, point to the last block. SBC F.EFBK(R0) ; Subtract out carry (if any). 110$: CALL WRTTOT ; And write the totals. RETURN .DSABL LSB .SBTTL WRTBLK - Write The Block To The File ;+ ; ; WRTBLK - Write the block to the output file. ; ; Inputs: ; None. ; ; Outputs: ; Carry bit clear/set = success/failure. ; ; All registers are preserved. ; ;- WRTBLK::JSR R2,$SAVVR ; Save R0 - R2. INC BLKNUM ; Count the number of blocks. MOV #OUTFDB,R0 ; Address of the output FDB. WRITE$ R0 ; Write the output block. BCS 90$ ; If CS, we had an error. WAIT$ R0 ; Wait for the write. BCC 100$ ; If CC, success. 90$: CALL FILERR ; Report the file error. 100$: RETURN .END