home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / decpro300 / proxk.mac < prev   
Text File  |  2020-01-01  |  18KB  |  690 lines

  1.     .TITLE    KERXK - XK driver routines
  2.     .SBTTL    R McQueen/N Bush/D Stevens/S Hecht
  3.  
  4. ; Version number
  5.  
  6.     .IDENT    /1.0.04/
  7.  
  8. ; Directives
  9.  
  10.     .LIBRARY /KERMLB/        ; PRO/Kermit macro library
  11.  
  12.     .SBTTL    Revision History
  13.  
  14. ;++
  15. ; 1.0.00    By: Robert C. McQueen        On: 1-December-1983
  16. ;        Create this module from other modules
  17. ;
  18. ; 1.0.01    By: Robert C. McQueen        On: 16-Feb-1984
  19. ;        Use the correct timeout value.
  20. ;
  21. ; 1.0.02    By: Robert C. McQueen        On: 17-Feb-1984
  22. ;        Add an alternate entry point to the initialization.
  23. ;        One to allow setting the routine and buffer size and
  24. ;        the other to default to assembly limit and no routine.
  25. ;
  26. ; 1.0.03    By: Robert C. McQueen        On: 9-March-1984
  27. ;        Make $PLIT$ come out even and not odd.
  28. ;
  29. ; 1.0.04    By: Robert C. McQueen        On: 26-March-1984
  30. ;        Finish edit 1.0.01
  31. ;--
  32.  
  33.     .SBTTL    .MCALLs for RSX directives
  34.  
  35. ; The following are the various MCALLs that KERXK uses.
  36.  
  37.     .MCALL    ASTX$S            ; AST exiting command
  38.     .MCALL    QIOW$S            ; QIO and wait
  39.     .MCALL    QIOW$C            ; QIO and wait
  40.     .MCALL    QIO$S            ; QIO and no wait
  41.     .MCALL    MRKT$S            ; Set a mark time request
  42.     .MCALL    CMKT$S            ; Cancel mark time requests
  43.     .MCALL    SETF$S            ; Set event flags
  44.     .MCALL    WTSE$S            ; Wait for an event
  45.     .MCALL    WTLO$S            ; Wait for logical-or of event flags
  46.  
  47. ; The following causes the KERMIT definitions to be read and defined
  48.  
  49.     .MCALL    KERDEF            ; Get the KERMIT definitions
  50.     KERDEF                ; Define all of the KERMIT symbols
  51.     .MCALL    IOSBDF            ; IOSB definitions
  52.     IOSBDF                ; Define the symbols
  53.  
  54.     .MCALL    BLSRTN            ; Macro to define entry point
  55.     .MCALL    PJMP            ; Jump and return macro
  56.     .MCALL    ND            ; If not defined macro
  57.     .MCALL    BIT.            ; Bit mask definition macro
  58.  
  59. ; The following are local parameters for KERXK
  60.  
  61. ND    NM.XCH,    64.            ; Allow 64 characters in buffer
  62. ND    XKBUFLEN, 512.            ; Length of XK buffer (must be power of two)
  63.  
  64.     .GLOBL    XKBUFLEN
  65.  
  66.     .SBTTL    Data for the module
  67.  
  68.     .PSECT    $OWN$, RW, D        ; Make sure this goes in data space
  69.  
  70. XKSTAT:    .BLKB    4            ; IO status block
  71. XKBUFF::.BLKB    XKBUFLEN        ; Circular xk-queue.
  72.     .EVEN
  73. XKFREE::.BLKW    1            ; Counter of free buffer space.
  74. XKUSED::.BLKW    1            ; Counter of used buffer space.
  75. XKNXTC::.BLKW    1            ; Pointer to first valid character.
  76. XKFREC::.BLKW    1            ; Pointer to first free character.
  77. QUEFLG:    .BLKW    1            ; Flag to indicate I/O queue pending.
  78. ERRFLG:    .BLKB    1            ; Flag to store an error in.
  79.     .EVEN
  80. DMPRTN:    .BLKW    1            ; Routine to dump XK input
  81.  
  82. ;
  83. ; XK output data
  84. ;
  85. XKOBUF:    .BLKB    NM.XCH            ; Number of XK characters allowed
  86. XKONCH::.BLKW    1            ; Number of characters in XKOBUF
  87. XKOIDX:    .BLKW    1            ; Index to store characters into
  88. XOIOSB:    .BLKB    IB.MSZ            ; IOSB for QIO 
  89.  
  90.     .SBTTL    XK.INI - Initialize the XK driver
  91.  
  92. ;++
  93. ; This routine will initialize the XK port.  It will read the initial
  94. ; parameters from the XK port and store them into an internal block.  It
  95. ; will then set the XK port with the parameters from the [ZZSYS]KERMITXK.SYS
  96. ; file.
  97. ;
  98. ; Usage:
  99. ;
  100. ; Macro:
  101. ;    R0/ Number of characters to buffer from XK port
  102. ;        (Needed for slow speeds during terminal emulation)
  103. ;    R1/ Adress of routine to call from XK.AST
  104. ;    JSR    PC,XK.INI
  105. ;    (Return - R0 contains the error status if carry set, else good return)
  106. ;
  107. ; Bliss:
  108. ;    Status = XK_INI();
  109. ;
  110. ;--
  111.  
  112.     .PSECT    $CODE$, RO, I
  113.  
  114. XK.INT::
  115.     CLR    DMPRTN            ; No dump routine
  116.     MOV    #XKBUFLN-1,XKFREE    ; Initialize the number free
  117.     BR    XKINIT            ; Join the common code
  118.  
  119. XK.INI::
  120.     MOV    R1,DMPRTN        ; Store the dump routine
  121. ;
  122. ; Determine the number of characters that we should be buffering
  123. ;
  124.     CMP    #XKBUFLN-1,R0        ; Small enough?
  125.     BGT    4$            ; No, use the default
  126.     TST    R0            ; Have to use the default?
  127.     BNE    5$            ; No, use the given
  128. 4$:    MOV    #XKBUFLN-1,R0        ; Yes, use the default
  129. 5$:    MOV    R0,XKFREE        ; Store the amount we can buffer
  130.  
  131. XKINIT:
  132. ;
  133. ; First we will attach to the XK so that no one else can be screwing around
  134. ;with it behind our backs.
  135. ;
  136. 7$:    QIO$S    #IO.ATT,#XKLUN,#XKREFN,,#XKSTAT    ; Grab the device
  137.  
  138.     MOVB    XKSTAT,R0        ; Get the status
  139.     BLE    90$            ; Branch if so
  140.  
  141. ; Now read the current parameters.  These will be saved and restored when
  142. ;we exit.
  143.  
  144.     MOV    #ORGXKP,R0        ; Point at parameter list
  145.     MOV    #CURXKL,R1        ; And get the length
  146.     JSR    PC,XK.RD        ; Read the parameters
  147.  
  148. ; Here to set the desired parameters.
  149.  
  150. 30$:    MOV    #CURXKP,R0        ; Point at the parameter block
  151.     MOV    #CURXKL,R1        ; And the length
  152.     JSR    PC,XK.WT        ; Read the info
  153.     CLR    XKFREC            ; Init. XKFREC index to zero.
  154.     CLR    XKUSED            ; Set the amount of used space to 0.
  155.     CLR    XKNXTC            ; Init. XKNXTC index to zero.
  156.     MOV    #NM.XCH,XKONCH        ; Store the max number we can output
  157.  
  158. ;[02]    MOV    #XKBUFLEN-1,XKFREE    ; Set the amount of free space to max
  159.     MOV    #-1,QUEFLG        ; No QIO pending yet
  160.     CLRB    ERRFLG            ; And no errors
  161.  
  162. ; All done
  163.  
  164.     CLC                ; Clear carry
  165.     RTS    PC            ; Return to our caller
  166. ;
  167. ; Here if we failed to get the XK
  168. ;
  169. 90$:    QIOW$C    IO.KIL,XKLUN,XKREFN,,,,,$CODE$    ; Grab the device
  170.     SEC                ; Set the carry bit
  171.     RTS    PC            ; Return to the caller
  172.  
  173.     .SBTTL    XK.SHT - Shutdown the XK port
  174.  
  175. ;++
  176. ; This routine will shut down the XK port.  It will restore the parameters
  177. ; from the orginal XK parameters.  It will then return to the caller.
  178. ;
  179. ; Usage:
  180. ;
  181. ; Macro:
  182. ;    JSR    PC,XK.SHT
  183. ;    (Return)
  184. ;
  185. ; Bliss:
  186. ;
  187. ;    Status = XK_SHT ();
  188. ;--
  189.  
  190. ;    .PSECT    $CODE$, RO, I
  191.  
  192. XK.SHT::MOV    #ORGXKP,R0            ; Point at orignal parameters
  193.     MOV    #CURXKL,R1            ; And the length of the block
  194.     JSR    PC,XK.WT            ; Set them
  195.  
  196.     QIOW$C    IO.KIL,XKLUN,XKWEFN,,,,,$CODE$    ; Kill pending I/O queues.
  197.     QIOW$C    IO.DET,XKLUN,XKWEFN,,,,,$CODE$    ; Detach the device
  198.  
  199.     RTS    PC                ; And return
  200.  
  201.     .SBTTL    XK.RD - Read XK parameters into parameter block
  202.  
  203. ;++
  204. ; This routine will read XK parameters into the given parameter block.
  205. ; It will use the QIO to read the XK parameters and then move them into
  206. ; the internal KERMIT parameter block.
  207. ;
  208. ; Usage:
  209. ;
  210. ; Macro:
  211. ;    MOV    #Parameter.block,R0
  212. ;    MOV    #Parameter.block.length,R1    ; (in bytes)
  213. ;    JSR    PC,XK.RD
  214. ;    (Return - R0 contains the status)
  215. ;
  216. ; Note that the length must be an even number of bytes
  217. ;--
  218.  
  219.     .PSECT    $CODE$, RO, I
  220.  
  221. ; We assume that when we are called, the parameter block is in a totally
  222. ;random state.  We will set to read as many of the interesting parameters
  223. ;as we can fit into the block supplied.   This block should normally be
  224. ;long enough, but might not be if there is a version skew between two modules.
  225.  
  226. XK.RD::    JSR    R1,$SAVE4        ; Save some registers
  227.  
  228. ; If the block is large than our maximum, only use what we know about
  229.  
  230.     CMP    #PTPLEN*2,R1        ; Have enough items to fill the block?
  231.     BGE    5$            ; Yes, just enter loop
  232.     MOV    #PTPLEN*2,R1        ; No, can only move what we have
  233.  
  234. 5$:    MOV    R0,R2            ; Get a copy of the address
  235.     MOV    R1,R3            ; And the length
  236.  
  237. ; Now insert the parameter types into the block
  238.  
  239.  
  240.     MOV    #PARTYP,R4        ; Point at list of interesting parameters
  241.     ASR    R1            ; Make the length be words
  242.  
  243. 10$:    MOVB    (R4)+,(R0)+        ; Store the parameter type
  244.     CLRB    (R0)+            ; Clear its data byte
  245.     SOB    R1,10$            ; Loop for all that we have room for
  246.  
  247.  
  248. ; Now just do the QIO to read the parameters
  249.  
  250.     QIOW$S    #SF.GMC,#XKLUN,#XKREFN,,,,<R2,R3> ; Get the information
  251.     MOV    @#$DSW,R0        ; Get the result code
  252.  
  253.     RTS    PC            ; And return
  254.  
  255. ; List of parameters we should read.  Most important parameters first.
  256.  
  257.     .PSECT    $PLIT$, RO, D        ; Make sure this goes in data space
  258.  
  259. PARTYP:    .BYTE    TC.RSP            ; Receive speed
  260.     .BYTE    TC.XSP            ; Transmit speed
  261.     .BYTE    TC.FSZ            ; Frame size
  262.     .BYTE    TC.PAR            ; Parity enable/disable
  263.     .BYTE    TC.EPA            ; Odd or even parity (if enabled)
  264.     .BYTE    TC.STB            ; Number of stop bits
  265.     .BYTE    TC.8BC            ; pass 8 data bits per character
  266.     .BYTE    TC.BIN            ; XON/XOFF enable/disable
  267.     .BYTE    XT.MTP            ; Modem type
  268.     .BYTE    TC.ARC            ; Auto-answer ring count
  269.     .BYTE    TC.XMM            ; Enable/disable maintenance
  270. PTPLEN=    .-PARTYP            ; Number of parameters we handle
  271.     .EVEN                ; Make this go to the next word
  272.  
  273.     .SBTTL    XK.WT - Write XK parameters from a parameter block
  274.  
  275. ;++
  276. ; This routine will write the XK parameters from a given parameter block.
  277. ; This routine will move the internal parameters into the QIO block for the
  278. ; SMC QIO call.
  279. ;
  280. ; Usage:
  281. ;
  282. ; Macro:
  283. ;    MOV    #Parameter.block,R0
  284. ;    MOV    #Parameter.block.length,R1    ; (in bytes)
  285. ;    JSR    PC,XK.WT
  286. ;
  287. ;--
  288.  
  289.     .PSECT    $CODE$, RO, I
  290.  
  291. XK.WT::    CMP    #PTPLEN*2,R1        ; Block larger than we know about?
  292.     BGE    10$            ; No, leave it alone
  293.     MOV    #PTPLEN*2,R1        ; Yes, only use the portion which should be ok
  294.  
  295. 10$:    QIOW$S    #SF.SMC,#XKLUN,#XKWEFN,,,,<R0,R1> ; Set the new parameters
  296.  
  297.     RTS    PC            ; And return
  298.  
  299.     .SBTTL    XK.BRK - Send a break character to the XK port
  300.  
  301. ;++
  302. ; This routine will set a break character to the XK port.  It is used
  303. ; by the terminal emulation processing to handle the BREAK key.
  304. ;
  305. ; Usage:
  306. ;    JSR    PC,XK.BRK
  307. ;    (Return)
  308. ;
  309. ;--
  310.  
  311. XK.BRK::
  312. ;
  313. ; First kill any pending I/O
  314. ;
  315.     QIOW$C    IO.KIL,XKLUN,XKREFN,,,,,$CODE$    ; Kill the I/O
  316.     MOV    #-1,QUEFLG        ; No QIO pending    
  317. ;
  318. ; Now send the break character
  319. ;
  320.     QIOW$C    IO.BRK,XKLUN,XKAEFN,,,,0,$CODE$
  321.     RTS    PC            ; Return to the caller
  322.  
  323.     .SBTTL    XK.INP - Input a character from the XK port
  324.  
  325. ;++
  326. ; This routine will input a single character from the XK port.  It is used
  327. ; by RECEIVE to fill a packet buffer, and by SEND to clear the XK input
  328. ; buffer.
  329. ;
  330. ; Usage:
  331. ;
  332. ; Macro:
  333. ;    MOV    #Buffer.address,R1
  334. ;    MOV    #Time.to.wait,R2    ; Time in seconds, 0 = don't wait
  335. ;    JSR    PC,XK.INP
  336. ;
  337. ; On a good return (carry = 0):
  338. ;
  339. ;    R0/ Number of characters read (0 or 1)
  340. ;    R1 and R2 unchanged
  341. ;
  342. ; On a false return (carry = 1):
  343. ;
  344. ;    R0/ IE.xxx error code
  345. ;
  346. ;--
  347.  
  348.     .PSECT    $CODE$, RO, I
  349.  
  350. XK.INP::JSR    R1,$SAVE3        ; Save R1 to R3
  351. ;
  352. ; Before we do anything we check for an error in ERRFLG.
  353. ;
  354.     TSTB    ERRFLG            ; Any errors?
  355.     BNE    40$            ; Yes, handle them
  356. ;
  357. ; No error.  Do we have any characters in the buffer ?
  358. ;
  359.     TST    XKUSED            ; Is the buffer empty ?
  360.     BEQ    20$            ; Yes, branch.
  361. ;
  362. ; Here if we have characters
  363. ;
  364. 10$:    MOV    XKNXTC,R3        ; Put index into R3
  365.     ADD    #XKBUFF,R3        ;  .  .  .
  366.     MOVB    (R3),@R1        ; Return the char. pointed at.
  367.     INC    XKNXTC            ; Increment index to the next char.
  368.     BIC    #^C<XKBUFLEN-1>,XKNXTC    ; Clear the high order bits
  369.     INC    XKFREE            ; Increment the free space count.
  370.     DEC    XKUSED            ; Decrement the used space count.
  371.     JSR    PC,XK.QIO        ; Set up xk-que if necessary.
  372.     MOV    #1,R0            ; Set up return in R0.
  373.     BR    30$            ; Branch.
  374. ;
  375. ; Que an I/O read if necessary then see if we need to time out.
  376. ;
  377. 20$:    JSR    PC,XK.QIO        ; Set up xk-que if necessary.
  378.     TST    R2            ; Do we have no time-out ?
  379.     BEQ    25$            ; Yes, branch.
  380. ;
  381. ; We need to time out, wait for GENEFN, or XKREFN flags to be set.
  382. ;
  383.     BIT.    GENMSK,GENEFN        ; Define mask bit for GENEFN
  384.     BIT.    CONMSK,CONEFN        ; Define mask bit for XKREFN
  385.  
  386.     WTLO$S    0,#GENMSK!CONMSK    ; Wait for one of the 2 EFNs to be set.
  387. ;
  388. ; We either timed out or  we got some characters.
  389. ;
  390. 25$:    TST    XKUSED            ; Is the buffer empty ?
  391.     BNE    10$            ; No, branch.
  392.     CLR    R0            ; Set up "no char" return in R0.
  393. ;
  394. ; Exit routine provided we did not branch at first tst.
  395. ;
  396. 30$:    CLC                ; Clear carry.( no error )
  397.     RTS    PC            ; Return to caller.
  398. ;
  399. ; Exit routine for an error being detected.
  400. ;
  401. 40$:    MOVB    ERRFLG,R0        ; Move error code in R0.
  402.     SEC                ; Set carry.( error )
  403.     RTS    PC            ; Return to caller.
  404.  
  405.     .SBTTL    XK.CIB - Clear input buffer
  406.  
  407. ;++
  408. ; This routine will clear the XK's input buffer.  This is used to dump any
  409. ;accumulated garbage before we send any data.
  410. ;
  411. ; Usage:
  412. ;    JSR    XK.CIB        ; Clear the input buffer
  413. ;     (return here always)
  414. ;
  415. ;--
  416.  
  417.     .PSECT    $CODE$, RO, I
  418.  
  419. XK.CIB::
  420.     INC    QUEFLG            ; Is the queue flag clear ?
  421.     BNE    CIB.0            ; No, branch
  422.     QIOW$C    SF.SMC,XKLUN,XKREFN,,,,<CIBBLK,CIBLEN>,$CODE$ 
  423.                     ; Just do the function
  424.     MOV    #-1,QUEFLG        ; Flag no QIO pending
  425. CIB.0:    CLR    XKUSED            ; Reset used space count to zero.
  426.     CLR    XKFREC            ; Reset index to zero.
  427.     CLR    XKNXTC            ; Reset index to zero.
  428.     MOV    #XKBUFLEN-1,XKFREE    ; Reset free space count to the
  429.     RTS    PC            ; And return
  430.  
  431.     .PSECT    $PLIT$, RO, D
  432. CIBBLK:    .BYTE    TC.TBF,0        ; Clear buffer function
  433. CIBLEN=    .-CIBBLK            ; Define the length
  434.  
  435.     .SBTTL    XK.TIM - Set up timeout
  436.  
  437. ;++
  438. ; This routine will post the request for a timeout.  It will ask that GENEFN
  439. ; be set when the timeout period has expired.  If there is no timeout, it
  440. ; will not request the EFN.
  441. ;
  442. ; Usage:
  443. ;    JSR    PC,XK.TIM
  444. ;     (return here always)
  445. ;
  446. ; On return:
  447. ;    R0/ low order 0, high order number of seconds to wait on QIO's
  448. ;    R1-R5 preserved
  449. ;
  450. ;--
  451.  
  452.     .PSECT    $CODE$, RO, I
  453.  
  454. XK.TIM::MOVB    SEND.TIMEOUT,R0        ; Get the receive timeout
  455.     BNE    10$            ; Branch if time out
  456.     MOV    #377,R0            ; Otherwise use maximum wait for QIO
  457.  
  458. 10$:    SWAB    R0            ; So that we have seconds in high order
  459.     BIC    #377,R0            ; Make sure 10 sec. portion is clear
  460.  
  461.     TST    SEND.TIMEOUT        ; Check if any timeout at all
  462.     BEQ    99$            ; No, just go ahead and wait forever
  463.  
  464.     CMKT$S    #GENEFN            ; Make sure any old timeout is cleared
  465.  
  466.     MRKT$S    #GENEFN,SEND.TIMEOUT,#2. ; Macro to wait (send.timeout) seconds.
  467.                     ;   This uses the general EFN.
  468.  
  469. 99$:    RTS    PC            ; Return, R0 already set up
  470.  
  471.     .SBTTL    XK.QIO - Check for Qio read and issue one if none
  472.  
  473. ;++
  474. ; This routine queues up a single character read from the comm-port.
  475. ;  The characters read are stored in xkbuff starting at the offset
  476. ;  in XKFREC.  After the queue the flag is set to indicate that
  477. ;  we have set up the queue.
  478. ;
  479. ;  Usage:
  480. ;
  481. ;  Macro:
  482. ;    JSR    PC,XK.QIO ( test to make sure the flag is not set)
  483. ;
  484. ;
  485. ;    REGISTER USAGE:
  486. ;        R0 => Offset into the buffer.
  487. ;        (smashed)
  488. ;
  489. ;--
  490.  
  491.     .PSECT    $CODE$, RO, I
  492.  
  493. XK.QIO::INC    QUEFLG            ; Is the queue flag clear ?
  494.     BNE    99$            ; No, branch
  495.  
  496.     TST    XKFREE            ; Make sure we have at least one
  497.     BLE    100$            ; Position free
  498.     MOV    XKFREC,R0        ; Store the offset in R0.
  499.     ADD    #XKBUFF,R0        ; Add offset to buffer address.
  500.     CLR    QUEFLG            ; Flag QIO outstanding now
  501.     QIO$S    #IO.RAL,#XKLUN,#XKREFN,,#XKSTAT,#XK.AST,<R0,#1.>
  502. 99$:    RTS    PC            ; All done, return to caller.
  503.  
  504. 100$:    MOV    #-1,QUEFLG        ; Nothing free, reset the flag
  505.     RTS    PC            ; Return to the caller
  506.  
  507.     .SBTTL    Support XK.INP -- AST handling routine -- XK.AST
  508. ;++
  509. ; This is the AST routine to handle the reception of characters from
  510. ;  the communications port.
  511. ;
  512. ; Usage:
  513. ;    Called when I/O from comm port reads chars.
  514. ;    ( Returns to where ever it was when called)
  515. ;
  516. ; Register usage:
  517. ;        R0, R1, R2, R3 => Temporary locations for computations.
  518. ;        (No registers get smashed )
  519. ;
  520. ;--
  521.  
  522.     .PSECT    $CODE$, RO, I
  523.  
  524. XK.AST::MOV    R0,-(SP)        ; Save R0.
  525.     JSR    PC,5$            ; Call ourself so we can use standard 
  526.                     ;  save routine.
  527.     TST    DMPRTN            ; Have a routine to call
  528.     BEQ    1$            ; No, just skip this
  529.     JSR    PC,@DMPRTN        ; Call the routine
  530.  
  531. 1$:    MOV    (SP)+,R0        ; Restore R0.
  532.     TST    (SP)+            ; Remove the IOSB from the stack.
  533.     ASTX$S                ; And return.
  534.  
  535. ;
  536. ; We must save Registers R1 thru R3. Then clear out their old contents.
  537. ;
  538. 5$:    JSR    R1,$SAVE4        ; Save the registers
  539.     MOV    #-1,QUEFLG        ; If we got here, QIO is done
  540. ;
  541. ; Make sure that connect processing runs
  542. ;
  543.     SETF$S    #CONEFN            ; Flag connect must do something
  544. ;
  545. ; Make sure we didn't get an error.
  546. ;
  547.     TSTB    XKSTAT            ; What was the status of the I/O ?
  548.     BMI    40$            ; Branch if an error.
  549. ;
  550. ; Here if we got no error.  See if we got any characters.
  551. ;
  552.     TST    XKSTAT+2        ; Were any characters gotten ?
  553.     BEQ    30$            ; No characters, branch.
  554. ;
  555. ; Here if we got characters.
  556. ;
  557.     MOV    XKSTAT+2,R1        ; Get number of characters read
  558.  
  559.     ADD    R1,XKFREC        ; Increment the index, clear
  560.     BIC    #^C<XKBUFLEN-1>,XKFREC    ;  the high order byte.
  561.  
  562.     ADD    R1,XKUSED        ; Increment the used count,
  563.     SUB    R1,XKFREE        ; Decrement the index, clear
  564.  
  565.     TST    XKFREE            ; Test the free space count.
  566.     BEQ    20$            ; Branch if zero.
  567. ;
  568. ; Here if the buffer is not full.
  569. ;
  570. ; We want to queue up a request for the most characters we
  571. ; can.  This is MIN(XKFREE,(XKBUFLEN-XKFREC)).
  572.  
  573.     MOV    #XKBUFLEN,R2        ; Get max length
  574.     SUB    XKFREC,R2        ; Determine distance to end of buffer
  575.     CMP    R2,XKFREE        ; Can we fill all free space?
  576.     BLE    10$            ; If LE, we can only read to end of buffer
  577.     MOV    XKFREE,R2        ; Yes, get the max amount to read
  578.  
  579. ;
  580. ; All cases, queue an I/O for R2 number of characters with time-out 0.
  581. ;
  582. 10$:    MOV    XKFREC,R1        ; Get the index to store characters
  583.     ADD    #XKBUFF,R1        ; Add it to the buffer address.
  584.     INC    QUEFLG            ; QIO now pending
  585.     QIO$S    #IO.RAL!TF.TMO,#XKLUN,#XKREFN,,#XKSTAT,#XK.AST,<R1,R2,#0>
  586. 20$:    RTS    PC            ; All done
  587. ;
  588. ; Here if we got no characters.
  589. ;
  590. 30$:    PJMP    XK.QIO            ; Issue single character QIO
  591. ;
  592. ; Here if we got an I/O error
  593. ;
  594. 40$:    MOVB    XKSTAT,ERRFLG        ; Save error code and flag the error.
  595.     RTS    PC            ; And return
  596.  
  597.     .SBTTL    XK.OUT - Output a buffered character to the XK
  598.  
  599. ;++
  600. ; This routine will output characters to the XK port.
  601. ;
  602. ; Usage:
  603. ;    R1/ Character
  604. ;    JSR    PC,XKOUT
  605. ;    (Return)
  606. ;
  607. ;--
  608.  
  609.     .PSECT    $CODE$, RO, I
  610.  
  611. XK.OUT::TST    XKONCH            ; Have room for this character?
  612.     BNE    10$            ; Yes, output it
  613. ;
  614. ; Here to wait for output to finish
  615. ;
  616.     WTSE$S    #XKWEFN            ; No, wait for output to finish
  617.     BR    XK.OUT            ; Loop and try again
  618. ;
  619. ; Here to output the character to the XK port
  620. ;
  621. 10$:    MOV    XKOIDX,R0        ; Get the current index
  622.     MOVB    R1,XKOBUF(R0)        ; Store the character
  623.     DEC    XKONCH            ; Decrement the number free
  624.     ADD    #XKOBUF,R0        ; Point to the byte
  625.     QIO$S    #IO.WVB,#XKLUN,#XKWEFN,,#XOIOSB,#XKOAST,<R0,#1>
  626.     INC    XKOIDX            ; Point to the next free location
  627.     BIC    #^C<NM.XCH-1>,XKOIDX    ; Point to the next free slot
  628.     RTS    PC            ; Return to the caller
  629.  
  630.     .SBTTL    XKOAST - AST routine for XK output done QIOs
  631.  
  632. ;++
  633. ; This routine is called as an asynchronous trap routine for the XK
  634. ; output QIOs.  This will adjust the counts and set the event flag for the
  635. ; XK outputs.
  636. ;
  637. ; Usage:
  638. ;    QIO AST routine
  639. ;
  640. ;--
  641.  
  642.     .PSECT    $CODE$, RO, I
  643.  
  644. XKOAST:    INC    XKONCH            ; Count the character as sent
  645.     TST    (SP)+            ; Remove the item from the stack
  646.     ASTX$S                ; Return from AST
  647.  
  648.     .SBTTL    FNDXKP - Find an XK parameter in the parameter block
  649.  
  650. ;++
  651. ; This routine will find the XK parameter in the current processing block.
  652. ; It will return the address of the item in the parameter block.
  653. ;
  654. ; Usage:
  655. ;    R0/ Parameter type (TC.xxx or XT.xxx)
  656. ;    R1/ Address of block (assumed to be CURXKL in length)
  657. ;    JSR    PC,FNDXKP
  658. ;    (Return)
  659. ;
  660. ; On return:
  661. ;    R0/ Offset or 0 if not found
  662. ;
  663. ;--
  664.  
  665.     .PSECT    $CODE$,    RO, I
  666.  
  667.     .GLOBL    FNDXKP
  668.  
  669. FNDXKP:    JSR    R1,$SAVE2        ; Save R1 and R2
  670.     MOV    #<CURXKL/2>,R2        ; Get the length of the block
  671.  
  672. ; Here to loop attempting to find the parameter
  673.  
  674. 10$:    CMPB    R0,(R1)+        ; Is this the item?
  675.     BEQ    20$            ; Yes, leave loop
  676.     TSTB    (R1)+            ; Point to the next item
  677.     SOB    R2,10$            ; Loop for all parameters
  678.     CLR    R0            ; Return a zero
  679.     RTS    PC            ; Return the parameter
  680.  
  681. ; Here if we found the parameter in the block.  Return the address of
  682. ; the status of the parameter.
  683.  
  684. 20$:    MOV    R1,R0            ; Point to the parameter
  685.     RTS    PC            ; Return
  686.  
  687.     .SBTTL    End of KERXK
  688.  
  689.     .END
  690.