home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit5a190 / ckvhex.mar < prev    next >
Text File  |  2020-01-01  |  19KB  |  630 lines

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