.TITLE HEXIFY .SBTTL Stuart Hecht and Eric McQueen .LIBRARY /SYS$LIBRARY:STARLET/ .LIBRARY /SYS$LIBRARY:LIB/ .IDENT /1.1.00/ ;++ ;This will take a task file and turn it into hexidecimal strings ;-- .EXTRN LIB$GET_INPUT .EXTRN LIB$PUT_OUTPUT .EXTRN DSC$K_DTYPE_T .EXTRN DSC$K_CLASS_S .EXTRN SS$_NORMAL .EXTRN RMS$_EOF .MCALL $FAB ; RMS calls .MCALL $RAB .MCALL $CLOSE .MCALL $CONNECT .MCALL $CREATE .MCALL $DISCONNECT .MCALL $READ .MCALL $OPEN .MCALL $PUT .MCALL $RAB_STORE .MCALL $FAB_STORE .SBTTL Definitions of symbols DWRLUN =1 ; Disk read LUN DWWLUN =5 ; Disk write LUN KNORMAL =0 ; No error EOF =-1 ; End of file error code LEFTBYTE=^O377*^O400 ; All one in left byte HEXOFFSET=7 ; Offset to get to 'A from '9+1 CR =13. ; Carriage return LF =10. ; Line feed ; Packet types currently created PKDATA =0 ; Data packet code PKRFM =255. ; Record format PKRAT =254. ; Record attributes PKMRS =253. ; Maximum record size PKALQ =252. ; File length(blocks) PKFILNM =251. ; File name PKEOF =250. ; End of file .SBTTL Data .PSECT $PLIT$,LONG M$FILN: .BYTE CR,LF,LF .ASCII 'Input file name: ' L$FILN =.-M$FILN M$OFLN: .BYTE CR,LF,LF .ASCII 'Output file name (or return for the default): ' L$OFLN =.-M$OFLN M$NEXF: .BYTE CR,LF,LF .ASCII 'Press return to finish or type the name of another file' .BYTE CR,LF .ASCII 'to append to the HEX file: ' L$NEXF =.-M$NEXF M$RMS: .BYTE CR,LF,LF .ASCII 'RMS ERROR' L$RMS =.-M$RMS .EVEN .SBTTL RMS Data DEFALT: .ASCIZ 'SYS$DISK:' ; System default. DEFALN =.-DEFALT ; Size of the default device. .EVEN .SBTTL Storage locations .PSECT $OWN$,LONG .ALIGN LONG MSGDSC: .BLKW 1 ; Data block for terminal output .BYTE DSC$K_DTYPE_T .BYTE DSC$K_CLASS_S ADDR: .ADDRESS ADDR LNGADR: .BLKL 1 INP_STR_D: ; Key string desciptor .BLKL 1 INP_BUF: .ADDRESS ADDR INP_STR_LEN: ; Key string length .BLKL 1 BUCOUNT: .BLKL 1 ; Number of character available in the ; buffer (returned from RMS) RDCOUNT: .BLKL 1 ; Number of characters read from buffer WTCOUNT: .BLKL 1 ; Number of characters written CHCOUNT: .BLKL 1 ; Number of characters written to buff. NULCOUNT: .BLKL 1 ; Number of nulls not yet written CHKSUM: .BLKL 1 ; Checksum for the line ADDRESS: .BLKL 1 ; Current address INP.N: .BLKB 28. ; Space for input file name INP.L =.-INP.N ; Length of input file name OUT.N: .BLKB 28. ; Space for output file name OUT.L =.-OUT.N ; Length of input file name RDBUF: .BLKB 512. ; Disk read buffer WTBUF: .BLKB 512. ; Disk write buffer .EVEN .SBTTL RMS Data structures .ALIGN LONG RDFAB:: $FAB DNA=DEFALT,DNS=DEFALN,FNA=INP.N,FNS=INP.L,- LCH=DWRLUN,FAC=,SHR=GET .ALIGN LONG RDRAB:: $RAB FAB=RDFAB,RAC=SEQ ; Beginning of RAB block. .ALIGN LONG WTFAB:: $FAB DNA=DEFALT,DNS=DEFALN,FNA=OUT.N,FNS=OUT.L,- LCH=DWWLUN,FAC=PUT,SHR=NIL,ORG=SEQ,RAT=CR,RFM=VAR .ALIGN LONG WTRAB:: $RAB FAB=WTFAB,RAC=SEQ ; Beginning of RAB block. .SBTTL Main line code .PSECT $CODE$,LONG,EXE .ALIGN LONG HEXIFY:: .WORD ^M<> ; For CALLS that is used from operating system NOINP: MOVAB M$FILN,R11 ; Get the input prompt address MOVL #L$FILN,R12 MOVAB INP.N,R10 ; Get address of input and length MOVL #INP.L,R1 ; JSB READ ; Read the input file name TSTL R0 ; See if we got anything BEQL NOINP ; If no input then try again MOVL R0,R5 ; Save length MOVAB M$OFLN,R11 ; Get the address of the prompt MOVL #L$OFLN,R12 MOVAB OUT.N,R10 ; Get address of output file name MOVL #OUT.L,R1 ; and length JSB READ ; Read the output file name MOVL R0,R3 ; Save length TSTL R3 ; See if we got any input BNEQ GOTFIL ; Yes so branch ; Here so use the default output file name MOVL R5,R0 ; Get the input file length back MOVAB INP.N,R2 ; Get input address MOVAB OUT.N,R3 ; Point at buffer CLRL R1 ; Clear the character count 2$: CMPB (R2),#^A/./ ; Check for an extension BEQL 10$ ; If an extension then ignore rest ; of line MOVB (R2)+,(R3)+ ; Move into the output file name INCW R1 ; Increment counter SOBGTR R0,2$ ; Branch until done 10$: MOVB #^A/./,(R3)+ ; Write the extension for output file MOVB #^A/H/,(R3)+ ; MOVB #^A/E/,(R3)+ ; MOVB #^A/X/,(R3)+ ; ADDW3 #4,R1,R3 ; Get final character count ;++ ;Open files ;-- GOTFIL: ;Create output file MOVAL WTFAB,R1 ; Put address of FAB into R1. $FAB_STORE FAB=R1,FNS=R3 ; Tell RMS file name length $CREATE #WTFAB ; Create the file JSB RMSERR ; Check for file error MOVAL WTRAB,R1 ; Put address of RAB into R1. $RAB_STORE RAB=R1,UBF=WTBUF,RBF=WTBUF,USZ=#512.,RSZ=#512. ; Put address of user buffer in RAB. $CONNECT #WTRAB ; Connect to record. JSB RMSERR ; Check for file error ;Open input file AGAINSAM: MOVAL RDFAB,R1 ; Put address of FAB into R1. $FAB_STORE FAB=R1,FNS=R5 ; Tell RMS file name length $OPEN #RDFAB ; Open the file JSB RMSERR ; Check for file error MOVAL RDRAB,R1 ; Put address of RAB into R1. $RAB_STORE RAB=R1,UBF=RDBUF,RBF=RDBUF,USZ=#512.,RSZ=#512. $CONNECT #RDRAB ; Connect to record. JSB RMSERR ; Check for file error ;++ ;Do the actual work ;-- MOVZWL #512.,RDCOUNT ; Initialize buffer pointers MOVZWL #512.,BUCOUNT ; CLRL WTCOUNT ; CLRL ADDRESS ; Initialize the address CLRL NULCOUNT ; Initialize the number of nulls MOVAL RDFAB,R5 ; Get the FAB address ;Get the Record format (FIX, VAR, ...) MOVZBL #PKRFM,R10 ; Set packet type to record format JSB HEADER ; Output the header MOVZBL FAB$B_RFM(R5),R10 JSB CVTH ; Put the record format code into buff INCL CHCOUNT ; Increment counter JSB PUTLIN ; Write the line out ;Get the record type (CR, ...) MOVZBL #PKRAT,R10 ; Set packet type to record type JSB HEADER ; Output the header MOVZBL FAB$B_RAT(R5),R10 JSB CVTH ; Put the record type into buffer INCL CHCOUNT ; Increment counter JSB PUTLIN ; Write the line out ;Get the maximum record size (512. for tasks) MOVZBL #PKMRS,R10 ; Set packet type to max record size JSB HEADER ; Output the header MOVZWL FAB$W_MRS(R5),R10 PUSHL R10 ; Save for low order EXTZV #8.,#8.,R10,R10 ; Get high order byte JSB CVTH ; Put the record size into buffer INCL CHCOUNT ; Increment counter POPL R10 ; Get size back JSB CVTH ; Put the record size into buffer INCL CHCOUNT ; Increment counter JSB PUTLIN ; Write the line out ;Get the file length (in blocks) MOVZWL #PKALQ,R10 ; Set packet type to file length JSB HEADER ; Output the header MOVL FAB$L_ALQ(R5),R10 PUSHL R10 ; Save for low order EXTZV #8.,#8.,R10,R10 ; Get high order byte JSB CVTH ; Put the allocation into buffer INCL CHCOUNT ; Increment counter POPL R10 ; Get allocation back JSB CVTH ; Put the low order into the buffer INCL CHCOUNT ; Increment counter JSB PUTLIN ; Write the line out ;Get the file name MOVZBL #PKFILNM,R10 ; Set packet type to file name JSB HEADER ; Output the header MOVZBL FAB$B_FNS(R5),R4 MOVAB INP.N,R3 ; Get the input file name address 25$: MOVZBL (R3)+,R10 ; Get the next character JSB CVTH ; Buffer the next character of the name INCL CHCOUNT ; Increment counter SOBGTR R4,25$ ; Repeat until all done JSB PUTLIN ; Write the line out ;++ ; Start moving real data ;-- NEXLIN: JSB GET ; Get a character from the buffer CMPL R10,#EOF ; Check for end of file BEQL FINISH ; If at end the finish up TSTL R10 ; Check for null character BNEQ DOLIN ; Not null so just do regular stuff INCL ADDRESS ; Point to next location BRB NEXLIN ; save space and try again DOLIN: PUSHL R10 ; Save the character we have MOVZWL #PKDATA,R10 ; Set packet type to plain old data JSB HEADER ; Put the standard header into buffer POPL R10 ; Get the original character back LINAGA: JSB CVTHEX ; Convert the character to hex codes INCL ADDRESS ; Point to next location INCL CHCOUNT ; Increment the character count CMPL CHCOUNT,#^O36 ; Check to see if we should finish BNEQ LINMOR ; this line JSB PUTLIN ; Put the whole line to disk BRW NEXLIN ; Go do the next line LINMOR: JSB GET ; Get the next character CMPL R10,#EOF ; Is it an end of file? BNEQ LINAGA ; No, then just handle normally ; JSB PUTLIN ; Yes, write the current line DECL ADDRESS ; Reset address to correct value BRW FIN1 ; Finish up .SBTTL Finish up ;++ ;Finish up ;-- FINISH: MOVZBL #PKDATA,R10 ; Set packet type to plain old data JSB HEADER ; Insert the header so the extra ; nulls are seen FIN1: TSTL NULCOUNT ; See if no nulls left BEQL FIN ; If none then branch CLRL R10 ; Get a null DECL NULCOUNT ; Decrement the counter JSB CVTH ; Convert to HEX (w/o null compression) FIN: JSB PUTLIN ; Put the current buffer to disk ; Write out the end of task file line CLRL CHCOUNT ; Clear character count MOVZBL #PKEOF,R10 ; Get end of task file packet type JSB HEADER ; Make the header JSB PUTLIN ; Write the line ; Close the input (task) file MOVAL RDFAB,R1 ; Get the FAB for input file $CLOSE R1 ; Close input file JSB RMSERR ; Check for file error ; See about another file to append MOVAB M$NEXF,R11 ; See if another file should be MOVL #L$NEXF,R12 ; appended to the HEX file MOVAB INP.N,R10 ; MOVL #INP.L,R1 ; Get address of input and length JSB READ ; Read the input file name TSTL R0 ; See if we got anything BEQL LEAVE ; If no input then leave MOVL R0,R5 ; Put the length in R5 for the open JMP AGAINSAM ; Repeat process for this file ; Write out end of hex file line LEAVE: CLRL CHKSUM ; Clear the checksum for this line CLRL CHCOUNT ; Clear character count MOVZBL #^A/