.TITLE MISUTL - MISH Utility Routines .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: MISUTL.MAC ; Author: Robin Miller ; Date: October 20, 1982 ; ; Description: ; ; This module contains general purpose utility routines. ; ; Modification History: ; ;- .ENABL AMA .NLIST BEX .MCALL GET$, ASTX$S .SBTTL CTRLC - CONTROL/C AST ROUTINE ;+ ; ; CTRLC - Control/C AST routine. ; ; This routine is entered when the users types CTRL/C to abort. ; ;- CTRLC:: BIS #B.CTRC,STATUS ; Show Control/C was typed. TST (SP)+ ; Remove CTRL/C from stack. ASTX$S ; Exit from the AST. .SBTTL CUPPER - CONVERT CHARACTER TO UPPER CASE ;+ ; ; CUPPER - Convert character to upper case. ; ; Inputs: ; (R2) = character to convert. ; ; Outputs: ; (R2) = the converted character. ; ;- CUPPER::CMPB (R2),#'a ; POSSIBLE LOWERCASE ? BLO 10$ ; IF LO, NO CMPB (R2),#'z ; REALLY LOWERCASE ? BHI 10$ ; IF HI, NO BICB #40,(R2) ; CONVERT TO UPPERCASE 10$: RETURN .SBTTL CVTDEC - Convert Binary Number To Decimal ASCII ;+ ; ; CVTDEC - Convert binary number to Decimal ASCII. ; ; Inputs: ; R0 = the output buffer address. ; R1 = the binary number to convert. ; ; Outputs: ; R0 = the updated output buffer address. ; ; All other registers are preserved. ; ;- CVTDEC::JSR R5,.SAVR1 ; Save R1 - R5 MOV #030012,R2 ; WIDTH=6 ! ZERO-SUPPRESS ! DECIMAL CALL $CBTA ; Convert it to decimal ASCII. RETURN .SBTTL CVTDTD - Convert Double Precision Binary To Decimal ASCII ;+ ; ; CVTDTD - Convert double precision binary number to decimal ASCII. ; ; Inputs: ; R0 = the output buffer address. ; R1 = address of the double precision number. ; ; Outputs: ; R0 = the updated output buffer address. ; ; All other registers are preserved. ; ;- CVTDTD::JSR R5,.SAVR1 ; Save R1 - R5 CLR R2 ; Suppress leading zeroes. CALL $CDDMG ; Convert it to decimal ASCII. RETURN .SBTTL CVTHEX - Convert Binary Number To Hexadecimal ASCII ;+ ; ; CVTHEX - Convert binary number to hexadecimal ASCII. ; ; Inputs: ; R0 = the output buffer address. ; R1 = the binary number to convert. ; ; Outputs: ; R0 = the updated output buffer address. ; ; All other registers are preserved. ; ;- CVTHEX::JSR R5,.SAVR1 ; Save R1 - R5 MOV #011020,R2 ; WIDTH=2 ! ZERO-FILL ! HEX CALL $CBTA ; Convert it to ASCII HEX. RETURN .SBTTL CVTOCT - Convert Binary Number To Octal ASCII ;+ ; ; CVTOCT - Convert binary number to octal ASCII. ; ; Inputs: ; R0 = the output buffer address. ; R1 = the binary number to convert. ; ; Outputs: ; R0 = the updated output buffer address. ; ; All other registers are preserved. ; ;- CVTOCT::JSR R5,.SAVR1 ; Save R1 - R5 MOV #015010,R2 ; WIDTH=3 ! ZERO-FILL ! OCTAL CALL $CBTA ; Convert it to ASCII octal. RETURN .SBTTL FILERR - Report A File Error ;+ ; ; FILERR - Report a file error. ; ; Inputs: ; R0 = the address of the FDB which had the error. ; ; Outputs: ; The C bit is set to indicate an error occured. ; ; All registers are preserved. ; ;- FILERR::JSR R2,$SAVVR ; Save R0 - R2 MOV F.ERR(R0),R0 ; Copy the FCS error code. CALL WRTERR ; Write the error message. RETURN .SBTTL MOVEC - Move A Character String ;+ ; ; MOVEC - Move a character string. ; ; Inputs: ; R0 = the output buffer address. ; R1 = the character string to move (terminated by NULL). ; ; Outputs: ; R0 = the updated buffer address. ; ;- MOVEC:: MOVB (R1)+,(R0)+ ; Copy the next character. BNE MOVEC ; If NE, more to copy DEC R0 ; Point to the null byte RETURN .SBTTL DOF2T - Convert sector to ASCII text ;+ ; ; DOF2T - Convert sector to ASCII text ; ; Inputs: ; R0 = the input buffer address. ; R3 = the size of the input buffer. ; R4 = the output buffer address. ; R5 = the argument block address. ; ; Outputs: ; All registers are preserved ; ;- DOF2T:: CALL $SAVAL ; Preserve all registers MOV R5,-(SP) ; Save argument block address CLR R5 ; R5 will be used to count number ; of converted bytes BIT #1,R3 ; Is the byte count even BEQ 5$ ; If EQ, yes MOV R0,R1 ; Address of input buffer ADD R3,R1 ; Point to the end of the buffer CLRB (R1) ; Clear the additional byte INC R3 ; Make input buffer count even 5$: ASR R3 ; Convert to word count 10$: MOV (R0)+,R1 ; 2 bytes to be converted to ascii MOV R1,R2 ; Move word to be converted BIC #^C77,R2 ; Isolate low 6 bits ADD #CVTSET,R2 ; Make printable ascii (0-5) MOVB R2,(R4)+ ; Copy this byte to output buffer ASH #-6,R1 ; SHIFT RIGHT 6 BITS MOV R1,R2 ; Prepare to convert next 6 bits BIC #^C77,R2 ; Isolate low 6 bits ADD #CVTSET,R2 ; Make printable ascii (6-11) MOVB R2,(R4)+ ; Copy this byte to output buffer ASH #-6,R1 ; Shift right 6 bits MOV R1,R2 ; Restore word for last 4 bits BIC #^C17,R2 ; Isolate low 4 bits ADD #CVTSET,R2 ; Make printable ascii (12-15) MOVB R2,(R4)+ ; Copy this byte to output buffer ADD #3,R5 ; Adjust the byte count SOB R3,10$ ; Do them all MOV R5,R3 ; Put new byte count in R3 MOV (SP)+,R5 ; Restore argument block address MOV R3,@O.BLEN(R5) ; Insert new byte count in argblk RETURN .SBTTL DOT2F - Convert ASCII text to Fixed length ;+ ; ; DOT2F - Convert ASCII text to Fixed length ; Inputs: ; R0 = the input buffer address. ; R3 = the size of the input buffer. ; R4 = the output buffer address. ; ; Outputs: ; All registers are preserved ; C bit clear/set = success/error ; ;- .ENABL LSB DOT2F:: CALL $SAVAL ; Preserve all registers. CLR WRKLEN ; Initialize the converted byte count. 10$: CLR R2 ; Setup R2 for divide. DIV #3,R2 ; Get the word count. MOV R2,R3 ; The number of words to convert. ASL R2 ; Find the number of bytes. ADD R2,WRKLEN ; Count the number of bytes in WRKBUF. CMP WRKLEN,#BUFEND ; Have we filled the output buffer ? BLE 20$ ; If LE, no. ERRMSG EXCBUF,<%MISH-F-EXCBUF, exceeded output buffer.> SEC ; Show failure BR 50$ ; and return 20$: MOVB (R0)+,R2 ; First byte for conversion. SUB #CVTSET,R2 ; Convert back from ascii. BIC #^C77,R2 ; Isolate low 6 bits. MOV R2,R1 ; Save low bits (0-5). MOVB (R0)+,R2 ; Next byte to convert. SUB #CVTSET,R2 ; Convert back from ascii. BIC #^C77,R2 ; Isolate low 6 bits. ASH #6,R2 ; Set up bits 6-11. ADD R2,R1 ; Move bits into r1. MOVB (R0)+,R2 ; Get last part of word. SUB #CVTSET,R2 ; Convert back from ascii. BIC #^C17,R2 ; Isolate low 4 bits. ASH #12.,R2 ; Set up high 4 bits (12-15). ADD R2,R1 ; Add in the high 4 bits. MOV R1,(R4)+ ; Put word in output buffer. SOB R3,20$ ; Restore the whole buffer. TST T2FHDR ; Are we doing the header ? BLT 50$ ; If LT, yes. MOV #WRKBUF,R0 ; Address of buffer to check. MOV WRKLEN,R1 ; Number of bytes in buffer. CALL EORSCB ; Do we have an end SCB. BCC 50$ ; If CC, yes. CALL GETM ; Get the next record. BCC 10$ ; and convert back from ascii. ERRMSG UNEOF,<%MISH-F-UNEOF, unexpected end of file encountered.> SEC ; Show obscure VMS bug. 50$: MOV WRKLEN,@O.RLEN(R5) ; and store them in the ARGBLK. RETURN ; and decompress .DSABL LSB .SBTTL GETM - Get the next record ;+ ; ; GETM - Get the next record ; Inputs: ; None ; Outputs: ; R0 = the input record address ; R3 = the record byte count ; C bit clear/set = success/error ; ;- GETM:: GET$ #INFDB,#RECADR,#RECSIZ ; Get the next input record. BCS 10$ ; If CS, had an error INC RECNUM ; Bump the record number. ADD F.NRBD(R0),COMLEN ; Accumulate compressed length. MOV F.NRBD(R0),R3 ; Copy the record byte count. MOV F.NRBD+2(R0),R0 ; Copy the record address. CLC ; Tell them no error. BR 40$ ; And exit. ; Error encountered reading the input file. 10$: CMPB F.ERR(R0),#IE.EOF ; Did we encounter end of file ? BEQ 20$ ; If EQ, yes (only error expected). CALL FILERR ; Else, report the error. 20$: SEC ; Return an error. 40$: RETURN .SBTTL EORSCB - Find End of Record SCB ;+ ; ; EORSCB - Find End of Record SCB ; ; Inputs: ; R0 = Address of input buffer. ; R1 = Byte count of input buffer. ; ; Outputs: ; C bit clear means success ; ; ;- EORSCB:: CALL $SAVAL ; Save all registers. 10$: CLC ; Presume success. BITB #B.MBON,(R0) ; End of record SCB ? BEQ 100$ ; If EQ, yes. MOVB (R0),R2 ; Copy the SCB. BITB #B.NDUP,(R0) ; Non-duplicate SCB. BNE 20$ ; If NE, yes (data coming after SCB). ; Duplicate string coming. ; BIC #^C37,R2 ; Isolate the duplicate count. CLR R2 ; Presume duplicate of blank. BITB #B.NBLA,(R0) ; Is duplication character a blank ? BEQ 30$ ; If EQ, yes. INC R2 ; One byte of data following. BR 30$ ; No, continue. ; Non-duplicate character count. 20$: BIC #^C77,R2 ; Isolate the character count. ; Point to the next SCB. 30$: INC R2 ; Count the SCB byte. SUB R2,R1 ; Adjust the buffer count. BLE 90$ ; If LE, count exhausted. ADD R2,R0 ; Point to the next SCB. BR 10$ ; Loop until done. 90$: SEC ; Show end SCB not found. 100$: RETURN .END