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