home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / vmshex / vmshex.16b < prev   
Text File  |  1988-08-23  |  16KB  |  579 lines

  1.     .TITLE    HEXIFY
  2.     .SBTTL    Stuart Hecht
  3.  
  4.     .LIBRARY /SYS$LIBRARY:STARLET/
  5.     .LIBRARY /SYS$LIBRARY:LIB/
  6.  
  7.     .IDENT    /1.0.00/
  8.  
  9. ;++
  10. ;NOTE - This the "old" version, that uses 16-bit internal length fields
  11. ;  rather than 32-bit ones.
  12. ;This will take a task file and turn it into hexidecimal strings
  13. ;--
  14.  
  15.     .EXTRN    LIB$GET_INPUT
  16.     .EXTRN    LIB$PUT_SCREEN
  17.     .MCALL    $FAB            ; RMS calls
  18.     .MCALL    $RAB
  19.     .MCALL    $CLOSE
  20.     .MCALL    $CONNECT
  21.     .MCALL    $CREATE
  22.     .MCALL    $DISCONNECT
  23.     .MCALL    $READ
  24.     .MCALL    $OPEN
  25.     .MCALL    $PUT
  26.     .MCALL    $RAB_STORE
  27.     .MCALL    $FAB_STORE
  28.  
  29.  
  30.     .SBTTL    Definitions of symbols
  31.  
  32. DWRLUN    =1                ; Disk read LUN
  33. DWWLUN    =5                ; Disk write LUN
  34. KNORMAL    =0                ; No error
  35. EOF    =-1                ; End of file error code
  36. LEFTBYTE=^O377*^O400            ; All one in left byte
  37. HEXOFFSET=7                ; Offset to get to 'A from '9+1
  38. CR    =13.                ; Carriage return
  39. LF    =10.                ; Line feed
  40. ; Packet types currently created
  41. PKDATA    =0                ; Data packet code
  42. PKRFM    =255.                ; Record format
  43. PKRAT    =254.                ; Record attributes
  44. PKMRS    =253.                ; Maximum record size
  45. PKALQ    =252.                ; File length(blocks)
  46. PKFILNM    =251.                ; File name
  47. PKEOF    =250.                ; End of file
  48.  
  49.  
  50.  
  51.     .SBTTL    Data
  52.  
  53.     .PSECT    $PLIT$,LONG
  54. M$FILN:    .BYTE    CR,LF,LF
  55.     .ASCII    'Input file name: '
  56. L$FILN    =.-M$FILN
  57.  
  58. M$OFLN:    .BYTE    CR,LF,LF
  59.     .ASCII    'Output file name (or return for the default): '
  60. L$OFLN    =.-M$OFLN
  61.  
  62. M$NEXF:    .BYTE    CR,LF,LF
  63.     .ASCII    'Press return to finish or type the name of another file'
  64.     .BYTE    CR,LF
  65.     .ASCII    'to append to the HEX file: '
  66. L$NEXF    =.-M$NEXF
  67.  
  68. M$RMS:    .BYTE    CR,LF,LF
  69.     .ASCII    'RMS ERROR'
  70. L$RMS    =.-M$RMS
  71.     .EVEN
  72.  
  73.  
  74.     .SBTTL    RMS Data
  75.  
  76. DEFALT:    .ASCIZ    'SYS$DISK:'        ; System default.
  77. DEFALN    =.-DEFALT            ; Size of the default device.
  78.     .EVEN
  79.  
  80.  
  81.  
  82.     .SBTTL    Storage locations
  83.  
  84.     .PSECT    $OWN$,LONG
  85.     .ALIGN    LONG
  86.  
  87. MSGDSC:    .BLKW    1            ; Data block for terminal output
  88.     .BYTE    DSC$K_DTYPE_T
  89.     .BYTE    DSC$K_CLASS_S
  90. ADDR:    .ADDRESS ADDR
  91.  
  92. INP_STR_D:                ; Key string desciptor
  93.      .BLKL    1
  94. INP_BUF: .ADDRESS ADDR
  95.  
  96. INP_STR_LEN:                ; Key string length
  97.     .BLKL    1
  98.  
  99.  
  100. BUCOUNT: .BLKL    1            ; Number of character available in the
  101.                     ;   buffer (returned from RMS)
  102. RDCOUNT: .BLKL    1            ; Number of characters read from buffer
  103. WTCOUNT: .BLKL    1            ; Number of characters written
  104. CHCOUNT: .BLKL    1            ; Number of characters written to buff.
  105. NULCOUNT: .BLKL    1            ; Number of nulls not yet written
  106.  
  107. CHKSUM:    .BLKL    1            ; Checksum for the line
  108. ADDRESS: .BLKL    1            ; Current address
  109.  
  110. INP.N:    .BLKB    28.            ; Space for input file name
  111. INP.L    =.-INP.N            ; Length of input file name
  112. OUT.N:    .BLKB    28.            ; Space for output file name
  113. OUT.L    =.-OUT.N            ; Length of input file name
  114.  
  115. RDBUF:    .BLKB    512.            ; Disk read buffer
  116. WTBUF:    .BLKB    512.            ; Disk write buffer
  117.     .EVEN
  118.  
  119.  
  120.  
  121.  
  122.     .SBTTL    RMS Data structures
  123.     .ALIGN LONG
  124. RDFAB::    $FAB    DNA=DEFALT,DNS=DEFALN,FNA=INP.N,FNS=INP.L,LCH=DWRLUN,FAC=<GET,BIO>,SHR=GET
  125.  
  126.     .ALIGN LONG
  127. RDRAB::    $RAB    FAB=RDFAB,RAC=SEQ
  128.                     ; Beginning of RAB block.
  129.  
  130.  
  131.  
  132.     .ALIGN LONG
  133. WTFAB::    $FAB    DNA=DEFALT,DNS=DEFALN,FNA=OUT.N,FNS=OUT.L,LCH=DWWLUN,FAC=PUT,SHR=NIL,ORG=SEQ,RAT=CR,RFM=VAR
  134.  
  135.     .ALIGN LONG
  136. WTRAB::    $RAB    FAB=WTFAB,RAC=SEQ
  137.                     ; Beginning of RAB block.
  138.  
  139.  
  140.  
  141.     .SBTTL    Main line code
  142.  
  143.     .PSECT    $CODE$,LONG,EXE
  144.  
  145.     .ALIGN LONG
  146. HEXIFY:: .WORD    ^M<IV>            ; For CALLS that is used from operating system
  147. NOINP:
  148.     MOVAB    M$FILN,R11        ; Get the input prompt address
  149.     MOVL    #L$FILN,R12
  150.     MOVAB    INP.N,R10        ; Get address of input and length
  151.     MOVL    #INP.L,R1        ;
  152.     JSB    READ            ; Read the input file name
  153.     TSTL    R0            ; See if we got anything
  154.     BEQL    NOINP            ; If no input then try again
  155.     MOVL    R0,R5            ; Save length
  156.  
  157.     MOVAB    M$OFLN,R11        ; Get the address of the prompt
  158.     MOVL    #L$OFLN,R12
  159.     MOVAB    OUT.N,R10        ; Get address of output file name
  160.     MOVL    #OUT.L,R1        ;  and length
  161.     JSB    READ            ; Read the output file name
  162.     MOVL    R0,R3            ; Save length
  163.     TSTL    R3            ; See if we got any input
  164.     BNEQ    GOTFIL            ; Yes so branch
  165.  
  166. ; Here so use the default output file name
  167.     MOVL    R5,R0            ; Get the input file length back
  168.     MOVAB    INP.N,R2        ; Get input address
  169.     MOVAB    OUT.N,R3        ; Point at buffer
  170.     CLRL    R1            ; Clear the character count
  171. 2$:    CMPB    (R2),#^A/./        ; Check for an extension
  172.     BEQL    10$            ; If an extension then ignore rest
  173.                     ;   of line
  174.     MOVB    (R2)+,(R3)+        ; Move into the output file name
  175.     INCW    R1            ; Increment counter
  176.     SOBGTR    R0,2$            ; Branch until done
  177.  
  178. 10$:    MOVB    #^A/./,(R3)+        ; Write the extension for output file
  179.     MOVB    #^A/H/,(R3)+        ;
  180.     MOVB    #^A/E/,(R3)+        ;
  181.     MOVB    #^A/X/,(R3)+        ;
  182.     ADDW3    #4,R1,R3        ; Get final character count
  183.  
  184.  
  185. ;++
  186. ;Open files
  187. ;--
  188. GOTFIL:
  189. ;Create output file
  190.     MOVAL    WTFAB,R1        ; Put address of FAB into R1.
  191.     $FAB_STORE FAB=R1,FNS=R3    ; Tell RMS file name length
  192.     
  193.     $CREATE    #WTFAB            ; Create the file
  194.     JSB    RMSERR            ; Check for file error
  195.     MOVAL    WTRAB,R1        ; Put address of RAB into R1.
  196.     $RAB_STORE RAB=R1,UBF=WTBUF,RBF=WTBUF,USZ=#512.,RSZ=#512.
  197.                     ; Put address of user buffer in RAB.
  198.     $CONNECT #WTRAB            ; Connect to record.
  199.     JSB    RMSERR            ; Check for file error
  200. ;Open input file
  201. AGAINSAM:
  202.     MOVAL    RDFAB,R1        ; Put address of FAB into R1.
  203.     $FAB_STORE FAB=R1,FNS=R5    ; Tell RMS file name length
  204.     $OPEN    #RDFAB            ; Open the file
  205.     JSB    RMSERR            ; Check for file error
  206.     MOVAL    RDRAB,R1        ; Put address of RAB into R1.
  207.     $RAB_STORE RAB=R1,UBF=RDBUF,RBF=RDBUF,USZ=#512.,RSZ=#512.
  208.     $CONNECT #RDRAB            ; Connect to record.
  209.     JSB    RMSERR            ; Check for file error
  210.  
  211.  
  212.  
  213. ;++
  214. ;Do the actual work
  215. ;--
  216.     MOVZWL    #512.,RDCOUNT        ; Initialize buffer pointers
  217.     MOVZWL    #512.,BUCOUNT        ;
  218.     CLRL    WTCOUNT            ;
  219.     CLRL    ADDRESS            ; Initialize the address
  220.     CLRL    NULCOUNT        ; Initialize the number of nulls
  221.     MOVAL    RDFAB,R5        ; Get the FAB address
  222. ;Get the Record format (FIX, VAR, ...)
  223.     MOVZBL    #PKRFM,R10        ; Set packet type to record format
  224.     JSB    HEADER            ; Output the header
  225.  
  226.     MOVZBL    FAB$B_RFM(R5),R10
  227.     JSB    CVTH            ; Put the record format code into buff
  228.     INCL    CHCOUNT            ; Increment counter
  229.     JSB    PUTLIN            ; Write the line out
  230. ;Get the record type (CR, ...)
  231.     MOVZBL    #PKRAT,R10        ; Set packet type to record type
  232.     JSB    HEADER            ; Output the header
  233.     MOVZBL    FAB$B_RAT(R5),R10
  234.     JSB    CVTH            ; Put the record type into buffer
  235.     INCL    CHCOUNT            ; Increment counter
  236.     JSB    PUTLIN            ; Write the line out
  237. ;Get the maximum record size (512. for tasks)
  238.     MOVZBL    #PKMRS,R10        ; Set packet type to max record size
  239.     JSB    HEADER            ; Output the header
  240.     MOVZWL    FAB$W_MRS(R5),R10
  241.     PUSHL    R10            ; Save for low order
  242.     EXTZV    #8.,#8.,R10,R10        ; Get high order byte
  243.     JSB    CVTH            ; Put the record size into buffer
  244.     INCL    CHCOUNT            ; Increment counter
  245.     POPL    R10            ; Get size back
  246.     JSB    CVTH            ; Put the record size into buffer
  247.     INCL    CHCOUNT            ; Increment counter
  248.     JSB    PUTLIN            ; Write the line out
  249. ;Get the file length (in blocks)
  250.     MOVZWL    #PKALQ,R10        ; Set packet type to file length
  251.     JSB    HEADER            ; Output the header
  252.     MOVL    FAB$L_ALQ(R5),R10
  253.     PUSHL    R10            ; Save for low order
  254.     EXTZV    #8.,#8.,R10,R10        ; Get high order byte
  255.     JSB    CVTH            ; Put the allocation into buffer
  256.     INCL    CHCOUNT            ; Increment counter
  257.     POPL    R10            ; Get allocation back
  258.     JSB    CVTH            ; Put the low order into the buffer
  259.     INCL    CHCOUNT            ; Increment counter
  260.     JSB    PUTLIN            ; Write the line out
  261. ;Get the file name
  262.     MOVZBL    #PKFILNM,R10        ; Set packet type to file name
  263.     JSB    HEADER            ; Output the header
  264.     MOVZBL    FAB$B_FNS(R5),R4
  265.     MOVAB    INP.N,R3        ; Get the input file name address
  266. 25$:    MOVZBL    (R3)+,R10        ; Get the next character
  267.     JSB    CVTH            ; Buffer the next character of the name
  268.     INCL    CHCOUNT            ; Increment counter
  269.     SOBGTR    R4,25$            ; Repeat until all done
  270.     JSB    PUTLIN            ; Write the line out
  271.  
  272.  
  273.  
  274. ;++
  275. ; Start moving real data
  276. ;--
  277. NEXLIN:
  278.     JSB    GET            ; Get a character from the buffer
  279.     CMPL    R10,#EOF        ; Check for end of file
  280.     BEQL    FINISH            ; If at end the finish up
  281.     TSTL    R10            ; Check for null character
  282.     BNEQ    DOLIN            ; Not null so just do regular stuff
  283.     INCL    ADDRESS            ; Point to next location
  284.     BRB    NEXLIN            ;  save space and try again
  285. DOLIN:    PUSHL    R10            ; Save the character we have
  286.     MOVZWL    #PKDATA,R10        ; Set packet type to plain old data
  287.     JSB    HEADER            ; Put the standard header into buffer
  288.  
  289.     POPL    R10            ; Get the original character back
  290. LINAGA:    JSB    CVTHEX            ; Convert the character to hex codes
  291.     INCL    ADDRESS            ; Point to next location
  292.     INCL    CHCOUNT            ; Increment the character count
  293.     CMPL    CHCOUNT,#^O36        ; Check to see if we should finish
  294.     BNEQ    LINMOR            ;  this line
  295.     JSB    PUTLIN            ; Put the whole line to disk
  296.     BRW    NEXLIN            ; Go do the next line
  297.  
  298. LINMOR:    JSB    GET            ; Get the next character
  299.     CMPL    R10,#EOF        ; Is it an end of file?
  300.     BNEQ    LINAGA            ; No, then just handle normally
  301. ;    JSB    PUTLIN            ; Yes, write the current line
  302.     DECL    ADDRESS            ; Reset address to correct value
  303.     BRW    FIN1            ; Finish up
  304.  
  305.  
  306.  
  307.     .SBTTL    Finish up
  308.  
  309. ;++
  310. ;Finish up
  311. ;--
  312. FINISH:
  313.     MOVZBL    #PKDATA,R10        ; Set packet type to plain old data
  314.     JSB    HEADER            ; Insert the header so the extra
  315.                     ;  nulls are seen
  316. FIN1:    TSTL    NULCOUNT        ; See if no nulls left
  317.     BEQL    FIN            ; If none then branch
  318.     CLRL    R10            ; Get a null
  319.     DECL    NULCOUNT        ; Decrement the counter
  320.     JSB    CVTH            ; Convert to HEX (w/o null compression)
  321. FIN:    JSB    PUTLIN            ; Put the current buffer to disk
  322. ; Write out the end of task file line
  323.     CLRL    CHCOUNT            ; Clear character count
  324.     MOVZBL    #PKEOF,R10        ; Get end of task file packet type
  325.     JSB    HEADER            ; Make the header
  326.     JSB    PUTLIN            ; Write the line
  327. ; Close the input (task) file
  328.     MOVAL    RDFAB,R1        ; Get the FAB for input file
  329.     $CLOSE    R1            ; Close input file
  330.     JSB    RMSERR            ; Check for file error
  331. ; See about another file to append
  332.     MOVAB    M$NEXF,R11        ; See if another file should be
  333.     MOVL    #L$NEXF,R12        ;   appended to the HEX file
  334.     MOVAB    INP.N,R10        ;
  335.     MOVL    #INP.L,R1        ; Get address of input and length
  336.     JSB    READ            ; Read the input file name
  337.     TSTL    R0            ; See if we got anything
  338.     BEQL    LEAVE            ; If no input then leave
  339.     MOVL    R0,R5            ; Put the length in R5 for the open
  340.     JMP    AGAINSAM        ; Repeat process for this file
  341. ; Write out end of hex file line        
  342. LEAVE:    CLRL    CHKSUM            ; Clear the checksum for this line
  343.     CLRL    CHCOUNT            ; Clear character count
  344.     MOVZBL    #^A/:/,R10        ; Get the start character
  345.     JSB    BUFFER            ; Put it into the buffer
  346.     MOVZBL    #8.,R5            ; Get the number of nulls needed
  347. FINREP:    MOVZBL    #^A/0/,R10        ; Set the character to 'null'
  348.     JSB    BUFFER            ; Put it into the buffer
  349.     SOBGTR    R5,FINREP        ; Repeat if not done
  350.     JSB    PUTLIN            ; Write the buffer to disk
  351. ; Close the HEX file
  352.     MOVAL    WTFAB,R1        ; Get FAB for output file
  353.     $CLOSE    R1            ; Close output file
  354.     JSB    RMSERR            ; Check for file error
  355.  
  356. END:    
  357.     MOVL    #SS$_NORMAL,R0        ; Set up successful completion
  358.     RET                ; Exit program
  359.  
  360.  
  361.     .SBTTL    Put a data line
  362. ;++
  363. ;Finish a line up by inserting the length and the checksum and doing a PUT
  364. ;--
  365.  
  366. PUTLIN:
  367.     MOVL    CHCOUNT,R10        ; Get the actual character count
  368.     SUBL2    NULCOUNT,R10        ; Don't include the nulls since we
  369.                     ;  won't write them
  370.     CLRL    NULCOUNT        ; Clear the null count since the
  371.                     ;  address will serve to insert nulls
  372.     PUSHL    WTCOUNT            ; Save it on the stack
  373.     MOVZBL    #1,WTCOUNT        ; Move a one into the char count to get
  374.     JSB    CVTH            ;  to the length and then put length in
  375.     POPL    WTCOUNT            ; Restore the correct count
  376.  
  377.     MNEGL    CHKSUM,R10        ; Negate it
  378.     JSB    CVTH            ; Put the negative checksum into buffer
  379.  
  380.     JSB    PUT            ; Put the line to disk
  381.     RSB                ; Return to sender
  382.  
  383.  
  384.  
  385.     .SBTTL    Create the header for the data line
  386. ;++
  387. ;This routine will put the starting stuff into the buffer
  388. ;R10 contains the record type
  389. ;--
  390.  
  391. HEADER:    CLRL    CHKSUM            ; Clear the checksum for this line
  392.     CLRL    CHCOUNT            ; Clear character count
  393.     PUSHL    R10            ; Save the record type
  394.     MOVZBL    #^A/:/,R10        ; Move a colon into first char position
  395.     JSB    BUFFER            ;   of the buffer
  396.     CLRL    R10            ; Move a fake length into the buffer
  397.     JSB    CVTH            ;
  398.     MOVZBL    ADDRESS+3,R10        ; Get the 4th byte of the
  399.     JSB    CVTH            ;  address and put into the buffer
  400.     MOVZBL    ADDRESS+2,R10        ; Get the 3rd byte of the
  401.     JSB    CVTH            ;  address and put into the buffer
  402.     MOVZBL    ADDRESS+1,R10        ; Get the 2nd byte of the
  403.     JSB    CVTH            ;  address and put into the buffer
  404.     MOVZBL    ADDRESS,R10        ; Get the 1rst byte of address and
  405.     JSB    CVTH            ;  buffer it
  406.     POPL    R10            ; Get the line record type
  407.     JSB    CVTH            ;  and buffer the code
  408.     RSB                ; Return to sender
  409.  
  410.  
  411.     .SBTTL    Output and input to/from terminal
  412. ;++
  413. ; Write data to terminal.
  414. ;    R10    Address of data to output
  415. ;    R1    Length of data
  416. ;--
  417. WRITE:
  418.     MOVW    R1,MSGDSC        ; Store the length in the descript blk
  419.     MOVL    R10,ADDR        ; Store the address of the ASCII
  420.     PUSHAQ    MSGDSC            ; Push the descriptor block address
  421.     CALLS    #1,G^LIB$PUT_OUTPUT    ; Do the output
  422.     RSB                ; Return to sender
  423.  
  424. ;++
  425. ; Read from the terminal
  426. ;    R10    Address of buffer
  427. ;    R1    Number of characters to read
  428. ;    R11    Input prompt address
  429. ;    R12    Length of prompt
  430. ;
  431. ;Returned:
  432. ;    R0    Number of characters read
  433. ;--
  434. READ:
  435.     MOVL    R1,INP_STR_D        ; Store the buffer length in desc block
  436.     MOVL    R10,INP_BUF        ; Store the buffer address in desc blk
  437.     MOVL    R11,ADDR        ; Store prompt address in desc block
  438.     MOVW    R12,MSGDSC        ; Store length in desctriptor block
  439.     PUSHAB    INP_STR_LEN        ; Address for string length
  440.     PUSHAQ    MSGDSC            ; Push address of prompt descriptor blk
  441.     PUSHAB    INP_STR_D        ; String buffer descriptor
  442.     CALLS    #3,G^LIB$GET_INPUT    ; Get input string value
  443.     MOVL    INP_STR_LEN,R0        ; Get actual input length back
  444.     RSB                ; Return to sender
  445.  
  446.  
  447.  
  448.     .SBTTL    RMS error routine
  449. ;++
  450. ;Check for RMS error
  451. ;--
  452. RMSERR:
  453.     BLBC    R0,60$            ; If error, go check it out
  454.     MOVL    #KNORMAL,R0        ; Set up a successful return code.
  455.     RSB                ; Return to caller
  456.  
  457. ; Here if there is an error
  458. 60$:    CMPL    #RMS$_EOF,R0        ; Check for EOF
  459.     BNEQ    70$            ; If not then branch
  460.     MOVL    #EOF,R0            ; Tell sender we have end of file
  461.     RSB                ; Return
  462.  
  463. ; Here if there is an RMS error we don't know how to handle
  464. 70$:    PUSHL    R0            ; Save the error code
  465.     MOVAB    M$RMS,R10        ; Get the address and length of the
  466.     MOVL    #L$RMS,R1        ;   message to output
  467.     JSB    WRITE            ; Output it
  468.     POPL    R0            ; Get the error code back
  469.     RET                ; Exit program
  470.  
  471.  
  472.  
  473.     .SBTTL    Get a character from the file
  474. ;++
  475. ;Get a character from the input file.
  476. ;
  477. ;    Returned:
  478. ;        R10    Contains the character if not at end of file
  479. ;            Contains #EOF if at end of file
  480. ;--
  481.  
  482. GET:    MOVL    RDCOUNT,R10        ; Get the offset into the buffer
  483.     CMPL    R10,BUCOUNT        ; Check to see if we are past the end
  484.     BNEQ    10$            ; If not then branch
  485.     MOVAL    RDRAB,R1        ; Get the RAB address
  486.     $RAB_STORE RAB=R1,UBF=RDBUF,USZ=#512.
  487.     $READ    R1            ; Get the next buffer of data.
  488.     JSB    RMSERR            ; Check for file error
  489.     CMPL    R0,#EOF            ; Check for end of file error
  490.     BNEQ    5$            ; If not then branch
  491.     MOVL    R0,R10            ; Move the status to the correct spot
  492.     RSB                ; Return with error code
  493. 5$:
  494.     MOVZWL    RAB$W_RSZ+RDRAB,R10
  495.     MOVL    R10,BUCOUNT        ; Save the record size
  496.     CLRL    R10            ; Clear the pointer
  497.     CLRL    RDCOUNT            ; . . . 
  498. 10$:    MOVZBL    RDBUF(R10),R10        ; Get the next character
  499.     INCL    RDCOUNT            ; Increment the offset into the buffer
  500.     RSB                ; Return to sender
  501.  
  502.  
  503.     .SBTTL    Buffer a character of the data line
  504. ;++
  505. ; Buffer the character in R10
  506. ;--
  507.  
  508. BUFFER:    PUSHL    R10            ; Save the character on the stack
  509.     MOVL    WTCOUNT,R10        ; Get the offset into the buffer
  510.     CMPL    #512.,R10        ; Get too big?
  511.     BGTR    BUFOK
  512.     NOP
  513. BUFOK:    MOVB    (SP),WTBUF(R10)        ; Move the character to the buffer
  514.     TSTL    (SP)+            ; Remove the junk
  515.     INCL    WTCOUNT            ; Increment the pointer
  516. BUFRTS:    RSB                ; Return to sender
  517.  
  518.  
  519.  
  520.     .SBTTL    Put a record to the file
  521. ;++
  522. ;Write the record
  523. ;--
  524.  
  525. PUT:
  526.     MOVL    WTCOUNT,R10        ; Get the count
  527.     MOVAL    WTRAB,R1        ; Get the RAB address
  528.     $RAB_STORE RAB=R1,RSZ=R10
  529.     $PUT    R1            ; Output the record
  530.     JSB    RMSERR            ; Check for file error
  531.     CLRL    WTCOUNT            ; Clear the counter for next record
  532.     RSB                ; Return
  533.  
  534.  
  535.  
  536.     .SBTTL    Convert to Hexadecimal ASCII digits
  537. ;++
  538. ; Convert a word to 2 ASCII hexadecimal digits
  539. ;--
  540.  
  541. CVTHEX:
  542.     TSTL    R10            ; See if this is a null
  543.     BNEQ    CVTH            ; If not then just branch
  544.     INCL    NULCOUNT        ; A null so just increment the count
  545.     RSB                ;  for later and leave
  546.  
  547. ; Convert a word to 2 ASCII hexadecimal digits without null compression
  548. CVTH:    PUSHL    R10            ; Save the character on the stack
  549. 10$:    TSTL    NULCOUNT        ; Check to see if there are nulls
  550.     BEQL    20$            ; If not then just branch
  551.     CLRL    R10            ; Put a null in R10
  552.     JSB    CVT1            ; Put the null in the buffer
  553.     DECL    NULCOUNT        ; Decrement null counter
  554.     BRB    10$            ; Repeat
  555. 20$:    POPL    R10            ; Get the original value back
  556.  
  557. CVT1:    ADDL2    R10,CHKSUM        ; Add the value to the checksum
  558.     MOVL    R10,R1            ; Save the value
  559.     EXTZV    #4,#4,R10,R10        ; Get high order digit
  560.     JSB    HEX            ;   in place and convert to Hex
  561.     JSB    BUFFER            ; Buffer the Hex character
  562.     EXTZV    #0,#4,R1,R10        ; Get right digit
  563.     JSB    HEX            ; Convert to Hex
  564.     JSB    BUFFER            ; Buffer the Hex character
  565.     RSB                ; Return to sender
  566.  
  567. HEX:    MOVL    R10,R2            ; Move the base to R2 
  568.     CMPL    R2,#9.            ; Check to see if above '9
  569.     BLEQ    1$            ; If not then branch
  570.     ADDL2    #HEXOFFSET,R10        ; Add offset to alphabet
  571. 1$:    ADDL2    #48.,R10        ; Make ASCII
  572.     RSB                ; Return to sender
  573.  
  574.  
  575.  
  576.     .SBTTL    End of Hexify
  577.  
  578.     .END    HEXIFY
  579.