home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / extra / vmsdeh.16b < prev    next >
Text File  |  1988-08-23  |  17KB  |  601 lines

  1.     .TITLE    DEHEX
  2.     .SBTTL    Stuart Hecht
  3.  
  4.     .LIBRARY /SYS$LIBRARY:STARLET/
  5.     .LIBRARY /SYS$LIBRARY:LIB/
  6.     .IDENT    /1.0.00/
  7.  
  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 set hexidecimal strings created by the hexify program and 
  13. ;  recreate the source file(s).
  14. ;--
  15.  
  16.     .EXTRN    LIB$GET_INPUT
  17.     .EXTRN    LIB$PUT_SCREEN
  18.     .MCALL    $FAB                ; RMS calls
  19.     .MCALL    $RAB
  20.     .MCALL    $CLOSE
  21.     .MCALL    $CONNECT
  22.     .MCALL    $CREATE
  23.     .MCALL    $DISCONNECT
  24.     .MCALL    $GET
  25.     .MCALL    $OPEN
  26.     .MCALL    $WRITE
  27.     .MCALL    $RAB_STORE
  28.     .MCALL    $FAB_STORE
  29.  
  30.  
  31.     .SBTTL    Definitions of symbols
  32.  
  33. DWRLUN    =1                ; Disk read LUN
  34. DWWLUN    =5                ; Disk write LUN
  35. TRUE    =1                ; True
  36. FALSE    =0                ; False
  37. KNORMAL    =0                ; No error
  38. LEFTBYTE=^O377*^O400            ; All ones in left byte
  39. HEXOFFSET=7                ; Offset to get to 'A from '9+1
  40. CR    =13.                ; Carriage return
  41. LF    =10.                ; Line feed
  42. MAX.MSG    =256.                ; Maximum number of chars from XK
  43. RCV.SOH    =^A/:/                ; Receive start of packet
  44. RCV.EOL    =13.                ; End of line character
  45. MSB    =128.                ; Most significant bit
  46. ; Packet types currently supported
  47. PKDATA    =00                ; Data packet code
  48. PKRFM    =255.                ; Record format
  49. PKRAT    =254.                ; Record attributes
  50. PKMRS    =253.                ; Maximum record size
  51. PKALQ    =252.                ; File length(blocks)
  52. PKFILNM    =251.                ; File name
  53. PKEOF    =250.                ; End of task file
  54. ;
  55.  
  56.  
  57.  
  58.     .SBTTL    RMS Data
  59.  
  60.     .PSECT    $PLIT$,LONG
  61.  
  62. DEFALT:    .ASCIZ    'SYS$DISK:'        ; System default.
  63. DEFALN    =.-DEFALT            ; Size of the default device.
  64.     .EVEN
  65.  
  66.  
  67.     .SBTTL    Data
  68.  
  69.  
  70. M$FILE:    .BYTE    CR,LF
  71.     .ASCII    'Please type the file name: '
  72. L$FILE=    .-M$FILE
  73.  
  74. M$CRLF:    .BYTE    CR,LF            ; Data for carriage return/line feed
  75. L$CRLF    =.-M$CRLF
  76.  
  77. M$AK:
  78.     .ASCII    'Y'            ; Data for aknowledged
  79.  
  80. M$NAK:
  81.     .ASCII    'N'            ; Data for not aknowledged
  82.  
  83. M$UN:
  84.     .ASCII    'U'            ; Data for unrecognized code
  85.  
  86. M$RMS:    .BYTE    CR,LF,LF
  87.     .ASCII    'RMS ERROR'
  88. L$RMS    =.-M$RMS
  89.  
  90. M$REC:    .BYTE    CR,LF,LF
  91.     .ASCII    'RECEIVE ERROR - Try again.'
  92. L$REC    =.-M$REC
  93.     .EVEN
  94.  
  95.  
  96.  
  97.     .SBTTL    Storage locations
  98.  
  99.     .PSECT    $OWN$,LONG
  100.     .ALIGN    LONG
  101.  
  102. MSGDSC:    .BLKW    1            ; Data block for terminal output
  103.     .BYTE    DSC$K_DTYPE_T
  104.     .BYTE    DSC$K_CLASS_S
  105. ADDR:    .ADDRESS ADDR
  106.  
  107. INP_STR_D:                ; Key string desciptor
  108.      .BLKL    1
  109. INP_BUF: .ADDRESS ADDR
  110.  
  111. INP_STR_LEN:                ; Key string length
  112.     .BLKL    1
  113.  
  114. WTCOUNT: .BLKL    1            ; Number of characters written
  115. LENGTH:    .BLKL    1            ; Length of data portion of packet
  116. OPENFL:    .BLKL    1            ; Tells us if the file is open
  117.  
  118. CHKSUM:    .BLKL    1            ; Checksum for the line
  119. ADDRESS: .BLKL    1            ; Current address
  120. ALQLOC:    .BLKW    2            ; Storage for allocation
  121.  
  122. OUT.N:    .BLKB    28.            ; Space for output file name
  123. OUT.L    =.-OUT.N            ; Length of output file name
  124.  
  125. INP.N:    .BLKB    28.            ; Space for input file name
  126. INP.L    =.-INP.N            ; Length of input file name
  127.  
  128.     .EVEN                ; Need to start RDBUF on even boundary
  129. RDBUF:    .BLKB    MAX.MSG            ; XK read buffer
  130.     .EVEN
  131. WTBUF:    .BLKB    512.            ; Disk write buffer
  132.     .EVEN
  133.  
  134.  
  135.  
  136.  
  137.     .SBTTL    RMS Data structures
  138.     .ALIGN    LONG
  139.  
  140. RDFAB::    $FAB    DNA=DEFALT,DNS=DEFALN,FNA=INP.N,FNS=INP.L,LCH=DWRLUN,FAC=GET,SHR=GET
  141.  
  142.     .ALIGN    LONG
  143. RDRAB::    $RAB    FAB=RDFAB,RAC=SEQ
  144.                     ; Beginning of RAB block.
  145.  
  146.     .ALIGN    LONG
  147. WTFAB::    $FAB    DNA=DEFALT,DNS=DEFALN,FNA=OUT.N,FNS=OUT.L,LCH=DWWLUN,FAC=PUT,SHR=NIL
  148.  
  149. WTRAB::    $RAB    FAB=WTFAB,RAC=SEQ
  150.                     ; Beginning of RAB block.
  151.  
  152.  
  153.  
  154.     .SBTTL    Start of program
  155.  
  156.     .PSECT    $CODE$,LONG,EXE
  157.  
  158. DEHEX::    .WORD    ^M<IV>
  159. FILE:    MOVAB    M$FILE,R11        ; Output the get file name message
  160.     MOVZBL    #L$FILE,R12
  161.     MOVAB    INP.N,R10        ; Get the file name
  162.     MOVZBL    #INP.L,R1
  163.     JSB    READ
  164.     TSTL    R0            ; Check for no input
  165.     BEQL    FILE            ; Go back and get some
  166.  
  167. ;Open the file
  168.     MOVAL    RDFAB,R1        ; Put address of FAB into R1.
  169.     $FAB_STORE FAB=R1,FNS=R0    ; Tell RMS file name length
  170.     $OPEN    #RDFAB            ; Open the file
  171.     JSB    RMSERR            ; Check for file error
  172.     MOVAL    RDRAB,R1        ; Put address of RAB into R1.
  173.  
  174. ; Put address of user buffer and size and record buffer and size in RAB.
  175.     $RAB_STORE RAB=R1,UBF=RDBUF,RBF=RDBUF,USZ=#MAX.MSG,RSZ=#MAX.MSG
  176.     $CONNECT #RDRAB            ; Connect to record.
  177.     JSB    RMSERR            ; Check for file error
  178.  
  179.  
  180.  
  181.     .SBTTL    Do the real work
  182. ;++
  183. ; Do the actual work
  184. ;--
  185. BEGIN:    MOVAL    M$CRLF,R10        ; Get a return/linefeed and output them
  186.     MOVZBL    #L$CRLF,R1
  187.     JSB    WRITE
  188.  
  189. 20$:    CLRL    WTCOUNT            ; Initialize the pointer
  190.     CLRL    ADDRESS            ; Initialize the address
  191.     CLRL    OPENFL            ; Set the file to not open
  192.  
  193.  
  194.     .SBTTL    Main loop
  195.  
  196. ; Main loop to get data
  197. DOLIN:
  198.     CLRL    CHKSUM            ; Clear the checksum
  199.     JSB    RECEIVE            ; Get the line
  200.     JSB    CVTBIN            ; Convert it to a real number
  201.     MOVL    R10,LENGTH        ; Save the length
  202.  
  203.     JSB    CVTBIN            ; get two bytes
  204.     MOVL    R10,R3            ; Save high order of address
  205.     ASHL    #8.,R3,R3        ; Shift to correct spot
  206.     JSB    CVTBIN            ; get two bytes
  207.     BISL    R10,R3            ; Save high order of address
  208.     ASHL    #8.,R3,R3        ; Shift to correct spot
  209.     JSB    CVTBIN            ; get two bytes
  210.     BISL    R10,R3            ; Save high order of address
  211.     ASHL    #8.,R3,R3        ; Shift to correct spot
  212.     JSB    CVTBIN            ; 
  213.     BISL    R10,R3            ; Fill in the low order of address
  214.     JSB    CVTBIN            ; thus we should have filled
  215.                     ; the longword
  216.  
  217.     CMPL    #PKDATA,R10        ; Check to see if this is regular data
  218.     BNEQ    NOTDAT            ; If not then check the special cases
  219.  
  220. ; Check for end of hex file
  221.     TSTL    R3            ; Check to see if the address is all
  222.     BNEQ    DATST            ;  zero, if not then branch
  223.     TSTL    LENGTH            ; Check to see if the length is zero
  224.     BNEQ    DATST            ;  also, if not then branch
  225.     JMP    FINISH            ; Must be end of hex file so finish up
  226.  
  227. ; Regular data to put into the file
  228. DATST:    TSTL    OPENFL            ; Check to see if the file is open yet
  229.     BNEQ    DAT1            ; If it is then skip the open
  230.     JSB    OPEN            ; Open the file
  231. DAT1:    CMPL    R3,ADDRESS        ; Check for null compression
  232.     BEQL    10$            ; If none compressed then continue past
  233.     CLRL    R10            ; Make a null
  234.     JSB    PUT            ;  and put it into the file
  235.     INCL    ADDRESS            ; Point to next address
  236.     BRW    DATST            ; Go see if there are any more nulls
  237.  
  238. ; Go to work on the HEX we got on the line
  239. 10$:    MOVL    LENGTH,R2        ; Get the length
  240.     TSTL    R2            ; See if there is any data
  241.     BEQL    30$            ; If not then branch
  242. 25$:    JSB    CVTBIN            ; Convert it
  243.     JSB    PUT            ; Put the character in the file
  244.     INCL    ADDRESS            ; Increment the address
  245.     SOBGTR    R2,25$            ; Repeat until all done
  246. 30$:    BRW    LINDON            ; Go finish this line
  247.  
  248.  
  249.  
  250.  
  251. NOTDAT:    MOVAL    WTFAB,R5        ; Get the FAB address
  252.     CMPL    #PKRFM,R10        ; Check to see if this is record fmt
  253.     BNEQ    NOTRFM            ; If not then don't do this stuff
  254.  
  255. ; Store the Record format (FIX, VAR, ...)
  256.     JSB    CVTBIN            ;
  257.     $FAB_STORE FAB=R5,RFM=R10    ; Store the record format
  258.     BRW    LINDON            ; Go finish this line
  259.  
  260. NOTRFM:    CMPL    #PKRAT,R10        ; Check to see if this is record type
  261.     BNEQ    NOTRAT            ; If not then branch
  262.  
  263. ; Store the record type (CR, ...)
  264.     JSB    CVTBIN            ;
  265.     $FAB_STORE FAB=R5,RAT=R10    ; Store the record type
  266.     BRW    LINDON            ; Go finish this line
  267.  
  268. NOTRAT:    CMPL    #PKMRS,R10        ; Check to see if this is max record
  269.     BNEQ    NOTMRS            ;  size, branch if not
  270.  
  271. ; Get the maximum record size (512. for tasks)
  272.     JSB    CVTBIN            ; Convert high order byte
  273.     MOVL    R10,R3            ; Save it
  274.     ASHL    #8.,R3,R3        ; Shift it to the high order byte
  275.     JSB    CVTBIN            ; Convert low order byte
  276.     BISL    R10,R3            ; Put low order word into R3 also
  277.     $FAB_STORE FAB=R5,MRS=R3    ; Store the maximum record size
  278.     BRW    LINDON            ; Go finish this line
  279.  
  280. NOTMRS:    CMPL    #PKALQ,R10        ; Check to see if this is allocation
  281.     BNEQ    NOTALQ            ; If not then branch
  282.  
  283. ; Get the file length (in blocks)
  284.     JSB    CVTBIN            ; Convert high order byte
  285.     MOVL    R10,R3            ; Save it
  286.     ASHL    #8.,R3,R3        ; Shift it to the high order byte
  287.     JSB    CVTBIN            ; Convert low order byte
  288.     BISL    R10,R3            ; Put low order word into R3 also
  289.     MOVW    R3,ALQLOC        ; Save it
  290.     CLRW     ALQLOC+2        ; clear out high word
  291.     $FAB_STORE FAB=R5,ALQ=ALQLOC    ; Store the allocation
  292.     BRW    LINDON            ; Go finish this line
  293.  
  294. NOTALQ:    CMPL    #PKFILNM,R10        ; Check to see if this is file name
  295.     BNEQ    NOTFILNM        ; If not then branch
  296.  
  297. ; Get the file name
  298.     MOVL    LENGTH,R2        ; Get the length
  299.     $FAB_STORE FAB=R5,FNS=R2    ; Store the file name length
  300.     MOVAB    OUT.N,R3        ; Get the output file name address
  301. 25$:    JSB    CVTBIN            ; Convert next character of the name
  302.     MOVB    R10,(R3)+        ; Save the character
  303.     SOBGTR    R2,25$            ; Repeat until all done
  304.     MOVAB    M$CRLF,R10        ;
  305.     MOVZBL    #L$CRLF,R1        ;
  306.     JSB    WRITE            ; Output a return/line feed
  307.     MOVAB    OUT.N,R10        ;
  308.     MOVL    LENGTH,R1        ;
  309.     JSB    WRITE            ; Output the file name
  310.     MOVAB    M$CRLF,R10        ;
  311.     MOVZBL    #L$CRLF,R1        ;
  312.     JSB    WRITE            ; Output a return/line feed
  313.     BRW    LINDON            ; Go finish this line
  314.  
  315.  
  316.  
  317.  
  318. NOTFILNM:
  319.     CMPL    #PKEOF,R10        ; Check to see if this is end of task
  320.     BNEQ    NOTPKEOF        ; If not then branch
  321.  
  322. ; End of ouput file record found
  323.     JSB    CLTSK            ; Close the task file
  324.     CLRL    WTCOUNT            ; Initialize the pointer
  325.     CLRL    ADDRESS            ; Initialize the address
  326.     JMP    LINDON            ; Go finish this line
  327.  
  328. ; Unknown code
  329. NOTPKEOF:                ; Since we don't know what the code
  330.     MOVAB    M$UN,R10        ;   just send the unknown code text to
  331.     MOVZBL    #1,R1            ;   the terminal
  332.     JSB    WRITE            ;
  333.     JMP    DOLIN            ; Go do next input line
  334.     
  335.  
  336.  
  337.     .SBTTL    Finished with this line
  338.  
  339. ; Line processed without a problem
  340. LINDON:
  341. ;    MOVAL    M$AK,R10
  342. ;    MOVZBL    #1,R1
  343. ;    JSB    WRITE            ; Write to the terminal
  344.     JMP    DOLIN            ; Good so do next line
  345.  
  346.  
  347.  
  348.     .SBTTL    Finish up
  349. ;++
  350. ;Finish up
  351. ;--
  352. FINISH:
  353. ; Close the file(s)
  354.     JSB    CLTSK            ; Close the task file if it isn't yet
  355.     MOVAL    RDFAB,R1        ; Get FAB for input file
  356.     $CLOSE    R1            ; Close the input file
  357.     JSB    RMSERR            ; Check for file error
  358. END:    MOVL    #SS$_NORMAL,R0        ; Set up successful completion
  359.     RET
  360.  
  361.  
  362.     .SBTTL    Close file
  363.  
  364. ;++
  365. ; Close the output file if there is one open
  366. ;
  367. ; If there is an error the program stops with an RMS error
  368. ;
  369. ; Registers destroyed:    R0, R1
  370. ; The OPENFL state is changed to file not open (OPENFL=0).
  371. ;--
  372.  
  373. CLTSK:    TSTL    OPENFL            ; See if the task file is open
  374.     BEQL    10$            ; If not then just return
  375.  
  376. ; Write last buffer if needed
  377.     TSTL    WTCOUNT            ; See if there is any data not written
  378.     BEQL    8$            ; If not then branch
  379.     MOVAL    WTRAB,R1        ; Get the RAB address
  380.     $RAB_STORE RAB=R1,RSZ=WTCOUNT    ; Put its size into the RAB.
  381.     $WRITE    R1            ; Put the buffer of data.
  382.     JSB    RMSERR            ; Check for file error
  383.  
  384. ; Close the file
  385. 8$:    MOVAL    WTFAB,R1        ; Get FAB for output file
  386.     $CLOSE    R1            ; Close output file
  387.     JSB    RMSERR            ; Check for file error
  388.     CLRL    OPENFL            ; Set the state to file not open
  389. 10$:    RSB                ; Return to sender    
  390.     
  391.  
  392.  
  393.     .SBTTL    Output and input to/from terminal
  394. ;++
  395. ; Write data to terminal.
  396. ;    R10    Address of data to output
  397. ;    R1    Length of data
  398. ;--
  399. WRITE:
  400.     MOVW    R1,MSGDSC        ; Store the length in the descript blk
  401.     MOVL    R10,ADDR        ; Store the address of the ASCII
  402.     PUSHAQ    MSGDSC            ; Push the descriptor block address
  403.     CALLS    #1,G^LIB$PUT_OUTPUT    ; Do the output
  404.     RSB                ; Return to sender
  405.  
  406. ;++
  407. ; Read from the terminal
  408. ;    R10    Address of buffer
  409. ;    R1    Number of characters to read
  410. ;    R11    Input prompt address
  411. ;    R12    Length of prompt
  412. ;
  413. ;Returned:
  414. ;    R0    Number of characters read
  415. ;--
  416. READ:
  417.     MOVL    R1,INP_STR_D        ; Store the buffer length in desc block
  418.     MOVL    R10,INP_BUF        ; Store the buffer address in desc blk
  419.     MOVL    R11,ADDR        ; Store prompt address in desc block
  420.     MOVW    R12,MSGDSC        ; Store length in desctriptor block
  421.     PUSHAB    INP_STR_LEN        ; Address for string length
  422.     PUSHAQ    MSGDSC            ; Push address of prompt descriptor blk
  423.     PUSHAB    INP_STR_D        ; String buffer descriptor
  424.     CALLS    #3,G^LIB$GET_INPUT    ; Get input string value
  425.     MOVL    INP_STR_LEN,R0        ; Get actual input length back
  426.     RSB                ; Return to sender
  427.  
  428.  
  429.  
  430.     .SBTTL    RMS error routine
  431. ;++
  432. ;Check for RMS error
  433. ; Call with:        R0    Status of last RMS call (automatically stored 
  434. ;                  in R0 by RMS after an operation)
  435. ;
  436. ; Returned:        R0    Status
  437. ; Registers destroyed:    R0
  438. ; Program stops after error message is displayed if there is any type of error.
  439. ;--
  440. RMSERR:
  441.     BLBC    R0,60$            ; If error, go check it out
  442.     MOVL    #KNORMAL,R0        ; Set up a successful return code.
  443.     RSB                ; Return to caller
  444.  
  445. ; Here if there is an RMS error we don't know how to handle
  446. 60$:    PUSHL    R0            ; Save the error code
  447.     MOVAB    M$RMS,R10        ; Get the address and length of the
  448.     MOVL    #L$RMS,R1        ;   message to output
  449.     JSB    WRITE            ; Output it
  450.     POPL    R0            ; Get the error code back
  451.     RET                ; Exit program
  452.  
  453.  
  454.  
  455.     .SBTTL    Open the output file
  456. ;++
  457. ; Create and open the output file and set the file open flag
  458. ;
  459. ; Registers destroyed:    R0, R1
  460. ; Program stops after error message is displayed if there is any type of error.
  461. ;--
  462.  
  463. OPEN:    MOVL    #TRUE,OPENFL        ; State that the file is open
  464.     MOVAL    WTFAB,R1        ; Put address of FAB into R1.
  465.     $FAB_STORE FAB=R1,FAC=<BIO,GET>    ; Set the block I/O in FAB.
  466.     $FAB_STORE FAB=R1,FOP=CTG    ; Tell RMS to make the task contiguous
  467.     $CREATE    #WTFAB            ; Create the file
  468.     JSB    RMSERR            ; Check for file error
  469.     MOVAL    WTRAB,R1        ; Put address of RAB into R1.
  470.  
  471. ; Put address of user buffer and record buffer and sizes into RAB
  472.     $RAB_STORE RAB=R1,UBF=WTBUF,RBF=WTBUF,USZ=#512.,RSZ=#512.
  473.     $CONNECT #WTRAB            ; Connect to record.
  474.     JSB    RMSERR            ; Check for file error
  475.     RSB                ; Return to sender
  476.  
  477.  
  478.     .SBTTL    Put a character to the file
  479. ;++
  480. ; Put a character to the output file.
  481. ; The buffer is only written when 512. characters have been sent to the routine
  482. ; If the file does not end on a boundary then the buffer will have to be 
  483. ; written by some other routine.
  484. ; Call with:        R10    Contains the character to be put into file
  485. ; Registers destroyed:    R1, R10
  486. ;
  487. ; Program stops after error message is displayed if there is any type of error.
  488. ;--
  489.  
  490. PUT:    PUSHL    R10            ; Save the character
  491.     MOVL    WTCOUNT,R10        ; Get the offset into the buffer
  492.     MOVB    (SP),WTBUF(R10)        ; Put the character
  493.     TSTL    (SP)+            ; Restore the stack
  494.     INCL    WTCOUNT            ; Increment the offset into the buffer
  495.     CMPL    WTCOUNT,#512.        ; Check to see if we are past the end
  496.     BNEQ    10$            ; If not then branch
  497.     MOVAL    WTRAB,R1        ; Get the RAB address
  498.     $RAB_STORE RAB=R1,RSZ=WTCOUNT    ; Put its size into the RAB.
  499.     $WRITE    R1            ; Put the buffer of data.
  500.     JSB    RMSERR            ; Check for file error
  501.     CLRL    WTCOUNT            ; Clear the pointer
  502. 10$:    RSB                ; Return to sender
  503.  
  504.  
  505.     .SBTTL     Convert to binary
  506. ;++
  507. ; Convert 2 hexidecimal digits to binary
  508. ; Input is from the input buffer pointed to by R4 (it is incremented twice)
  509. ;
  510. ; Call with:        R4    The pointer into the input buffer
  511. ; Returned:        R10    The binary walue
  512. ; Registers destroyed:    R10,R1
  513. ;--
  514.  
  515. CVTBIN:
  516.     CLRL    R10            ; Clear R10 for the BISB
  517.     BISB    (R4)+,R10        ; Get the next digit
  518.     JSB    BIN            ;   in place and convert to binary
  519.     ASHL    #4,R10,R10        ; Multiply the result by 16
  520.     MOVL    R10,R1            ;  and save it
  521.     CLRL    R10            ; Clear R10
  522.     BISB    (R4)+,R10        ; Get the next digit
  523.     JSB    BIN            ; Convert to binary
  524.     BISL    R1,R10            ; Set the correct bits for high order
  525.     ADDL2    R10,CHKSUM        ; Add the value to the checksum
  526.     RSB                ; Return to sender
  527.  
  528. BIN:    CMPL    R10,#^A/9/        ; Check to see if above '9
  529.     BLEQ    1$            ; If not then branch
  530.     SUBL2    #HEXOFFSET,R10        ; Subtract offset to alphabet
  531. 1$:    SUBL2    #48.,R10        ; Make binary
  532.     RSB                ; Return to sender
  533.  
  534.  
  535.  
  536.     .SBTTL    Receive a line of data
  537.  
  538. ;++
  539. ; This will get a line of data from the input device
  540. ;
  541. ; Returned:        R4    Address of start of data buffer
  542. ; Registers destroyed:    R0, R1, R3, R4
  543. ;
  544. ; A checksum error will cause a NAK to be sent and input to be read again
  545. ; A real error will cause an error message to be output and the program to stop
  546. ;--
  547.  
  548. RECEIVE:
  549. ; Here to read from a file
  550.     MOVAL    RDRAB,R1        ; Get the RAB address
  551.     $GET    R1            ; Get the record
  552.     JSB    RMSERR            ; Check for file error
  553.     MOVZWL    #MAX.MSG,R3        ; Assume we got a full buffer
  554.  
  555. ; Here to check the data we got
  556. RECCHK:    MOVAL    RDBUF,R4        ; Get the address of the information
  557.     CLRL    R1            ; Clear the data start address 
  558. 80$:    BICB    #MSB,(R4)        ; Clear parity bit
  559.     CMPB    (R4)+,#RCV.SOH        ; Check for start of header
  560.     BNEQ    81$            ; If not the just keep going
  561.     MOVL    R4,R1            ; Start of header so save it
  562. 81$:    SOBGTR    R3,80$            ; Repeat until done
  563.     TSTL    R1            ; Check to see if we got a SOH
  564.     BNEQ    85$            ; If good then skip the jump
  565.     JMP    RECEIVE            ; If not then re-read
  566. 85$:    MOVL    R1,R4            ; Move to R4 for use
  567.     PUSHL    R4            ; Save SOH pointer on stack
  568.  
  569.     JSB    CVTBIN            ; Convert all to binary to see if
  570.     MOVL    R10,R3            ; Get the length of data
  571.     ADDL2    #6,R3            ; Add the length of address and field
  572.                     ;   type and checksum
  573.     BLSS    94$            ; If we have a negative number then 
  574.                     ;   must have been a bad length
  575.     CMPL    R3,#MAX.MSG/2-1        ; If we got some length that is out of
  576.     BGEQ    94$            ;   range then NAK right away
  577. 92$:    JSB    CVTBIN            ; Convert all to binary to see if
  578.     SOBGTR    R3,92$            ;   the checksum is OK
  579. 93$:    BICL    #LEFTBYTE,CHKSUM    ; We only want an 8 bit checksum
  580.     TSTL    CHKSUM            ; Test for a zero checksum
  581.     BEQL    95$            ; If OK then exit normally
  582. 94$:    CLRL    CHKSUM            ; Clear the checksum for the line
  583.  
  584. ;    MOVAL    M$NAK,R10        ; Get the address of the message
  585.  
  586.     MOVZBL    #1,R1            ; Only write the first character to
  587.     JSB    WRITE            ;   the terminal
  588.     TSTL    (SP)+            ; Pull the pointer off the stack
  589.     JMP    RECEIVE            ; Try to get the line again
  590.  
  591. ; Return to sender
  592. 95$:    POPL    R4            ; Get the pointer back
  593.     RSB                ; Return to sender
  594.  
  595.  
  596.  
  597.     .SBTTL    End of the Dehexify
  598.  
  599.     .END    DEHEX
  600.