.TITLE ANALYZ - Analyze Compressed 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: ANALYZ.MAC ; Author: Robin Miller & Gary Larsen ; Date: October 29, 1982 ; ; Description: ; ; Analyze Mish file header. ; ; Modification History: ; ;- .ENABL AMA .NLIST BEX .MCALL GET$ ; Messages: RECM: .ASCIZ "Record number " BLKM: .ASCIZ "Block number " OLENM: .ASCIZ "The original data length = " CLENM: .ASCIZ ", the compressed data length = " ; VT100 escape sequences. REVON: .ASCIZ "[7m" ; VT100 Reverse Video REVOFF: .ASCIZ "[0m" ; Turn off attributes .EVEN .SBTTL ATTON/OFF - Special VT100 Routines. ;+ ; ; ATTON/OFF - Turn on/off VT100 video attributes. ; ; Inputs: ; R0 = the output buffer address. ; ; Outputs: ; R0 = the updated buffer address. ; ; All registers are preserved. ; ;- ATTON:: JSR R5,.SAVR1 ; Save R1 - R5 BIT #B.REV,STATUS ; Did the users request it ? BEQ 10$ ; If EQ, no (skip it then). MOV #REVON,R1 ; Turn on reverse video. CALL MOVEC ; Move the character string. MOV #-1,ATRFLG ; Show attributes are on. 10$: RETURN ATTOFF::JSR R5,.SAVR1 ; Save R1 - R5 TST ATRFLG ; Are attributes turned on ? BEQ 10$ ; If EQ, no MOV #REVOFF,R1 ; Yes, turn them off. CALL MOVEC ; Move the character string. CLR ATRFLG ; Show attributes are off. 10$: RETURN .SBTTL CVTSCB - Convert The String Control Byte ;+ ; ; CVTSCB - Convert the String Control Byte to Hex or Octal ASCII. ; ; Inputs: ; R0 = the output buffer address. ; R1 = the String Control Byte. ; ; Outputs: ; R0 = the updated buffer address. ; C bit clear/set = data is coming/another SCB is next. ; If data is coming, ; SCBCNT = the data count. ; ; All other registers are perserved. ; ;- CVTSCB::JSR R5,.SAVR1 ; Save R1 - R5. CLR SCBCNT ; Initialize the SCB data count. ; Put String Control Byte in reverse video. CALL ATTON ; Yes, turn on reverse video. BIT #B.HEX,STATUS ; Is the data type hexadecimal ? BNE 30$ ; If NE, yes ; Convert to Octal ASCII. BIC #^C377,R1 ; Clean up the sign extend. CALL CVTOCT ; Convert it to octal ASCII. BR 40$ ; And continue ... ; Convert to Hexadecimal ASCII. 30$: CALL CVTHEX ; Convert it to hexadecimal. ; Check for end of terminal screen width. 40$: CALL ATTOFF ; Turn attributes off (if on). MOVB #SPACE,(R0)+ ; Separate with a space. ; Determine the type of String Control Byte. BIC #^C77,R1 ; Presume non-duplicate count. BITB #B.MBON,@SCBADR ; Is this an end of record SCB ? BEQ 90$ ; If EQ, yes (another SCB is next). BITB #177,@SCBADR ; Is this a continuation SCB ? BEQ 90$ ; If EQ, yes BITB #B.NDUP,@SCBADR ; Is this a non-duplicate count ? BNE 50$ ; If NE, yes (data after the SCB). ; Duplicate character coming. BIC #^C37,R1 ; Isolate the duplicate count. ADD R1,ORGLEN ; Accumulate original record length. MOV #1,R1 ; If non-blank, character follows SCB. BITB #B.NBLA,@SCBADR ; Is duplicate character a blank ? BEQ 90$ ; If EQ, yes (another SCB is next). BR 60$ ; Skip adding of the SCB count again. ; Either data or duplicate character follows this SCB. 50$: ADD R1,ORGLEN ; Accumulate the original length. 60$: MOV R1,SCBCNT ; Save the data count for this SCB. CLC ; Show data follows this SCB. BR 100$ ; And use common return ... 90$: SEC ; Show another SCB is next. 100$: RETURN .SBTTL ANALYZ - Analyze And Format The Output Buffer ;+ ; ; ANALYZ - Analyze and format the output buffer. ; ; Inputs: ; The input and output files must be open. ; ; Outputs: ; All registers are preserved. ; ;- ANALYZ::CALL $SAVAL ; Save all registers MOV #ARGBLK,R5 ; Address of the argument block. MOV #WRKBUF,O.RADR(R5) ; Address for converted text. (02) CALL GETHDR ; Get the header record. BCS 10$ ; If CS, we didn'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 10$ ; If CS, we had an error. (02) CLR T2FHDR ; Show header done. (02) MOV #HDRBUF,R0 ; Address of input file header (02) CALL FMTHDR ; Now format and output it. BIT #B.DATA,STATUS ; Analyze compressed data also ? BNE ALOOP ; If NE, yes. 10$: RETURN ; Else, we're all done. ; Loop reading the input records. ALOOP:: BIT #B.CTRC,STATUS ; CTRL/C typed to abort ? BNE 100$ ; If NE, yes (stop outputting). ;(02) INC RECNUM ; Bump the record number. ;(02) GET$ #INFDB,#RECADR,#RECSIZ ; Get the next input record. ;(02) BCS 90$ ; If CS, had an error ;(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) MOV @O.RLEN(R5),COMLEN ; Copy the compressed length. 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) INC BLKNUM ; Bump the block number. (02) CALL WRTREC ; Write the record number. CALL UNCOMP ; Uncompress the input record. BCS 100$ ; If CS, we had a PUT$ error. CALL WRTLEN ; Write the record lengths. BR ALOOP ; And get the next record. ; Error encountered reading the input file. 90$: CMPB F.ERR(R0),#IE.EOF ; Did we encounter end of file ? BEQ 100$ ; If EQ, Yes (only error expected). CALL FILERR ; Else, report the error. 100$: RETURN .SBTTL EXPAND - Expand The ASCII Character ;+ ; ; EXPAND - Expand the ASCII character. ; ; This routine converts the next binary character to printable ASCII. If ; character is a control byte, it is converted to the up arrow/character ; (i.e., CTRL/A becomes ^A). ; ; Inputs: ; R0 = the output buffer address. ; R1 = the binary character. ; ; Outputs: ; R0 = the updated buffer address. ; ; All other registers are preserved. ; ;- EXPAND::JSR R5,.SAVR1 ; Save R1 - R5 BIT #B.HEX,STATUS ; Outputting in hexadecimal ? BNE 10$ ; If NE, yes MOVB #SPACE,(R0)+ ; No, start octal with a space. 10$: BIC #^C177,R1 ; Clear parity and high byte. CMPB R1,#DELETE ; Is this a delete character ? BNE 15$ ; If NE, no BICB #40,R1 ; Else, make it printable. BR 20$ ; And treat it like control. 15$: CMPB R1,#SPACE ; Is this a control character ? BHIS 30$ ; If HIS, no (printable character). ADD #64.,R1 ; Make control character printable. ; Format the control character. 20$: MOVB #'^,(R0)+ ; Start with an up arrow. MOVB R1,(R0)+ ; Now copy the character. BR 40$ ; Now finish with a space. ; Normal printable character. 30$: MOVB R1,(R0)+ ; Copy the character. MOVB #SPACE,(R0)+ ; Pad with another space. 40$: MOVB #SPACE,(R0)+ ; And yet another space. 100$: RETURN .SBTTL UNCOMP - Uncompress The Record/Buffer ;+ ; ; UNCOMP - Uncompress the record/buffer. ; ; Inputs: ; R5 = The argument block address. ; ; Outputs: ; C bit clear/set = success/failure from PUT$. ; ; All registers are preserved. ; ;- UNCOMP::CALL $SAVAL ; Save all the registers, ; Now format the output buffer in hexadecimal/octal ASCII. MOV @O.RLEN(R5),R3 ; Copy the input buffer length. BEQ 100$ ; If EQ, there is none. MOV O.RADR(R5),R2 ; Copy the input buffer address. MOV #FMTBUF,R0 ; Address of format buffer. CLR R4 ; Format buffer byte count. 10$: CALL 60$ ; Check for end of screen. MOV R2,SCBADR ; Save the SCB address. MOVB (R2)+,R1 ; The first byte is a SCB. ADD FIELDW,R4 ; Accumulate the screen width. CALL CVTSCB ; Convert and format the SCB. BCS 50$ ; If CS, process the next SCB. ; Data follows the String Control Byte, SCBCNT = the data count. 20$: CALL 60$ ; Check for end of screen. MOVB (R2)+,R1 ; Get the next data character. CALL EXPAND ; Expand the ASCII character. ADD FIELDW,R4 ; Accumulate the screen width. DEC R3 ; Adjust the buffer count. BEQ 55$ ; If EQ, there is no more. DEC SCBCNT ; Adjust the data count. BGT 20$ ; If GT, more to come. 50$: DEC R3 ; Adjust the buffer count. BGT 10$ ; If GT, more to go. 55$: CALL WRTCON ; Else, write the buffer. BR 100$ ; Use common return. ; Subroutine to check for end of terminal screen. 60$: CMP R4,#80. ; Exceeding the terminal width ? BLO 70$ ; If LO, no (just return). CALL WRTCON ; Yes, output the buffer. BCC 70$ ; If CC, success. TST (SP)+ ; Else, clean off the stack. BR 100$ ; And get out of here. 70$: RETURN 100$: RETURN .SBTTL WRTFMT - Write The Format Buffer ;+ ; ; WRTFMT - Write the format buffer to the output file. ; ; Inputs: ; R0 = the updated output buffer address. ; ; Outputs: ; C bit clear/set = success/failure from PUT$. ; R0 = start of the format buffer. ; ; All other registers are preserved. ; ;- WRTFMT::JSR R5,.SAVR1 ; Save R1 - R5. MOV #FMTBUF,R1 ; Start of the format buffer. MOV R0,R2 ; Copy the updated buffer address. SUB R1,R2 ; Calculate the byte count. MOV #OUTFDB,R0 ; Address of the output FDB. CALL WRTFDB ; Go write the buffer. MOV #FMTBUF,R0 ; Reset the output buffer address. RETURN .SBTTL WRTCON - Write Continuation Record ;+ ; ; WRTCON - Write a continuation record. ; ; Inputs: ; R0 = the updated output buffer address. ; ; Outputs: ; C bit clear/set = success/failure from PUT$. ; R0 = start of the format buffer (plus continuation characters). ; R4 = the continuation byte count (same as the field width). ; ; All other registers are preserved. ; ;- WRTCON::CMPB -(R0),#SPACE ; Is the last character a space ? BEQ WRTCON ; If EQ, yes (check the next) INC R0 ; Point to the last character. CALL WRTFMT ; Write the format buffer. BCS 30$ ; If CS, we had an error. MOVB #'-,(R0)+ ; Setup for continuation line. MOV FIELDW,R4 ; Copy the field width. BIT #B.HEX,STATUS ; Outputting in hexadecimal ? BNE 20$ ; If NE, yes MOVB #'-,(R0)+ ; No, add one more for octal. 20$: MOVB #'>,(R0)+ ; Rest of MOVB #SPACE,(R0)+ ; continuation line. 30$: RETURN .SBTTL WRTREC - Write the Record Number ;+ ; ; WRTREC - Write the record number. ; ; Inputs: ; BLKNUM = The block number. ; ; Outputs: ; C bit clear/set = success/failure on PUT$. ; ; All registers are preserved. ; ;- WRTREC::JSR R2,$SAVVR ; Save R0 - R2. ; Format the record number. MOV #FMTBUF,R0 ; Address of the output buffer. ;(02) MOV #RECM,R1 ; Address of the record message. MOV #BLKM,R1 ; Address of the block message. CALL MOVEC ; Copy it. ;(02) MOV RECNUM,R1 ; Copy the record number. MOV BLKNUM,R1 ; Copy the block number. CALL CVTDEC ; Convert it to decimal ASCII. CALL WRTFMT ; Write the format buffer. CALL WRTBLA ; And write a blank line. RETURN .SBTTL WRTLEN - Write The Lengths ;+ ; ; WRTLEN - Write the original and compressed lengths. ; ; Inputs: ; ORGLEN = the original length. ; COMLEN = the compressed length. ; ; Outputs: ; C bit clear/set = success/failure on PUT$. ; ; All registers are preserved. ; ;- WRTLEN::JSR R2,$SAVVR ; Save R0 - R2. ; Format the original byte count. CALL WRTBLA ; Write a blank record first. MOV #FMTBUF,R0 ; The output buffer address. MOV #OLENM,R1 ; Address of original message. CALL MOVEC ; Copy it. MOV ORGLEN,R1 ; Copy the original length. CALL CVTDEC ; Convert it to decimal ASCII. ; Format the compressed byte count. MOV #CLENM,R1 ; Address of compressed message. CALL MOVEC ; Copy it. MOV COMLEN,R1 ; Copy the compressed length. CALL CVTDEC ; Convert it to decimal ASCII. ; Write the lengths and clear the counts. CALL WRTFMT ; Write the format buffer. CALL WRTSEP ; Write the record separator. CLR ORGLEN ; Initialize original length. CLR COMLEN ; Initialize compressed length. RETURN .SBTTL WRTSEP - Write The Record Separator. ;+ ; ; WRTSEP - Write the record separtor. ; ; Inputs: ; None. ; ; Outputs: ; C bit clear/set = success/failure from PUT$. ; ; All other registers are preserved. ; ;- WRTSEP::CALL $SAVAL ; Save all the registers. MOV #40.,R3 ; Set the loop count MOV #80.,R4 ; Set the byte count. MOV #FMTBUF,R0 ; Set the format buffer address. 10$: MOV #"$*,(R0)+ ; Use "$*" as the separator. SOB R3,10$ ; And loop until done CALL WRTFMT ; Write the format buffer. RETURN .END