Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1556 lines
42 KiB

  1. page
  2. ;---------------------------Module-Header-------------------------------;
  3. ; Module Name: IBMCOM1.ASM
  4. ;
  5. ; Copyright (c) Microsoft Corporation 1985-1990. All Rights Reserved.
  6. ;
  7. ;----------------------------Private-Routine----------------------------;
  8. ;
  9. ; DoLPT - Do Function To LPT port
  10. ;
  11. ; The given function (output or reset) is performed to the
  12. ; passed LPT port.
  13. ;
  14. ; Before a character is sent, a check is made to see if the device
  15. ; will be able to accept the character. If it can, then the character
  16. ; will be sent. If not, then an error will be returned. If the
  17. ; printer is selected and busy and no error, then the code returned
  18. ; will be CE_TXFULL and the handshake bits will be set in HSFlag
  19. ; to simulate that a handshake was received.
  20. ;
  21. ; If the BIOS ROM code is examined, you will note that they wait for
  22. ; the busy character from the last charcater to be cleared before
  23. ; they strobe in the current character. This can take a long time
  24. ; on the standard EPSON class printer (1 mSec to greater than
  25. ; 300 mSec if the last character actually caused printing).
  26. ;
  27. ; Because of this, several status read retrys will be made before
  28. ; declaring that the device is actually busy. If only one status
  29. ; read is performed, the spooler will yeild, take a while to get
  30. ; back here, and things will be really slow. What difference does
  31. ; it really make if we or the BIOS does the delay, at least we can
  32. ; break out of it at some point when it seems hopeless.
  33. ;
  34. ; The OKIHACK: Okidata reports a 50 ns. 2.2 volt pulse on the paper
  35. ; out signal on the trailing edge of the Busy signal. If we see this
  36. ; glitch then we report paper out. So we try to get the status twice...
  37. ; if it changes between the two tries we keep getting the status.
  38. ;
  39. ;
  40. ; Entry:
  41. ; AH = cid
  42. ; AL = character to output
  43. ; CH = Function request. 0 = Output, 1 = Initialize, 2 = Status
  44. ; DS:SI -> DEB for the port
  45. ; Returns:
  46. ; AX = 0 if no errors occured
  47. ; Error Returns:
  48. ; AX = error code
  49. ; Registers Preserved:
  50. ; SI,DI
  51. ; Registers Destroyed:
  52. ; AX,BX,CX,DX,ES,FLAGS
  53. ; History:
  54. ; sudeepb 10-Jan-1993 changed the costly cli/sti with non-trapping
  55. ; FCLI/FSTI macros
  56. ;-----------------------------------------------------------------------;
  57. ;------------------------------Pseudo-Code------------------------------;
  58. ; {
  59. ; }
  60. ;-----------------------------------------------------------------------;
  61. assumes ds,Data
  62. assumes es,nothing
  63. include vint.inc
  64. externFP OutputDebugString
  65. dbmsg macro msg
  66. .286
  67. push cs
  68. push offset $ + 3 + 5 + 2 ; push + far call + short jump
  69. call OutputDebugString
  70. jmp short @F
  71. db msg,13,10,0
  72. @@:
  73. endm
  74. iodelay macro
  75. jmp $+2
  76. jmp $+2
  77. endm
  78. public DoLPT ;Publics for debugging
  79. public LPT_Reset
  80. public LPT_Outchar
  81. public LPT_Strobe
  82. public LPT_GetStatus
  83. public DoLPT40
  84. ; status bit defines
  85. L_BITS equ 0F8h ; the status bits we want
  86. L_BITS_INVERT equ 048h ; must invert to match BIOS
  87. L_DEVBUSY equ 080h ; device busy bit
  88. L_TIMEOUT equ 001h ; timeout bit
  89. ; control bit defines
  90. L_NORMAL equ 00Ch ; normal state: selected, no reset
  91. L_RESET equ 008h ; reset state
  92. L_STROBE equ 00Dh ; tell printer we have char
  93. DoLPT proc near
  94. mov dx,Port[si] ;Get port address
  95. ; DX = port address
  96. ; CH = operation: 0 = write, 1 = init, 2 = status
  97. ; AL = character
  98. or ch, ch
  99. jz LPT_OutChar
  100. cmp ch, 1
  101. jz LPT_Reset
  102. jmp LPT_GetStatus
  103. ret
  104. LPT_Reset:
  105. inc dx
  106. inc dx
  107. mov al, L_RESET
  108. iodelay
  109. out dx, al
  110. push dx
  111. cCall GetSystemMsecCount
  112. mov bx, ax
  113. LPT_ResetDelay:
  114. push bx
  115. cCall GetSystemMsecCount
  116. pop bx
  117. sub ax, bx
  118. cmp ax, 300 ; 1/3 sec as good as any
  119. jbe LPT_ResetDelay
  120. pop dx
  121. mov al, L_NORMAL
  122. iodelay
  123. iodelay
  124. out dx, al
  125. dec dx
  126. dec dx
  127. jmp LPT_GetStatus
  128. LPT_OutChar:
  129. push ax ; save character to be written
  130. ; first check to see if printer is ready for us
  131. push di
  132. push dx
  133. call GetSystemMSecCount
  134. mov di, ax
  135. pop dx
  136. LPT_WaitReady:
  137. inc dx ; point to status port
  138. iodelay
  139. in al, dx ; get status bits
  140. and al, L_BITS ; mask unused ones
  141. xor al, L_BITS_INVERT ; flip a couple
  142. xchg al, ah
  143. ifndef NOOKIHACK
  144. iodelay
  145. in al, dx
  146. dec dx
  147. and al, L_BITS
  148. xor al, L_BITS_INVERT
  149. cmp al, ah ; did any bits change?
  150. jnz LPT_WaitReady
  151. else
  152. dec dx
  153. endif
  154. test ah, PS_PaperOut or PS_IOError
  155. jnz LPT_PrinterNotReady
  156. test ah, PS_Select
  157. jz LPT_PrinterNotReady
  158. test ah, PS_NotBusy
  159. jnz LPT_PrinterReady
  160. push ax
  161. push dx
  162. call GetSystemMSecCount
  163. pop dx
  164. pop bx
  165. sub ax, di
  166. cmp ax, 300 ; 1/3 sec timeout
  167. jbe LPT_WaitReady
  168. ; The device seems to be selected and powered up, but is just
  169. ; busy (some printers seem to show selected but busy when they
  170. ; are taken offline). Show that the transmit queue is full and
  171. ; that the hold handshakes are set. This is so the windows
  172. ; spooler will retry (and do yields so that other apps may run).
  173. or ComErr[si],CE_TXFULL ;Show queue full
  174. mov ah,bh
  175. or ah, L_TIMEOUT
  176. LPT_PrinterNotReady:
  177. pop di
  178. pop cx ; throw away character
  179. jmp LPT_ReturnStatus
  180. LPT_PrinterReady:
  181. pop di ; get di back
  182. pop ax ; get character back
  183. iodelay
  184. out dx, al ; write character to port
  185. inc dx ; access status port
  186. LPT_Strobe:
  187. inc dx ; control port
  188. mov al, L_STROBE ; set strobe high
  189. iodelay
  190. iodelay
  191. iodelay
  192. iodelay
  193. out dx, al ; ...
  194. mov al, L_NORMAL ;
  195. iodelay
  196. iodelay
  197. iodelay
  198. iodelay
  199. out dx, al ; set strobe low
  200. sub dx, 2 ; point back to port base
  201. ; FALL THRU
  202. LPT_GetStatus:
  203. inc dx ; point to status port
  204. LPT_GS1:
  205. iodelay
  206. iodelay
  207. in al, dx ; get status bits
  208. and al, L_BITS ; mask unused ones
  209. xor al, L_BITS_INVERT ; flip a couple
  210. mov ah, al
  211. ifndef NOOKIHACK
  212. in al, dx
  213. and al, L_BITS
  214. xor al, L_BITS_INVERT
  215. cmp al, ah
  216. jnz LPT_GS1 ; if they changed try again...
  217. endif
  218. LPT_ReturnStatus:
  219. assumes ds,Data
  220. and ax,(PS_PaperOut+PS_Select+PS_IOError+PS_Timeout)*256
  221. shr ah,1
  222. adc ah,al ;Get back Timeout bit
  223. xor ah,HIGH CE_DNS ;Invert selected bit
  224. .errnz LOW CE_DNS
  225. or by ComErr+1[si],ah ;Save comm error
  226. ret
  227. .errnz CE_PTO-0200h
  228. .errnz CE_IOE-0400h
  229. .errnz CE_DNS-0800h
  230. .errnz CE_OOP-1000h
  231. DoLPT40:
  232. assumes ds,Data
  233. or ComErr[si],CE_TXFULL ;Show queue full
  234. ret
  235. DoLPT endp
  236. page
  237. ;----------------------------Private-Routine----------------------------;
  238. ;
  239. ; TXI - Transmit A Character Immediately
  240. ;
  241. ; Set up a character to be transmitted "immediately".
  242. ; by placing the character in a location that guarantees
  243. ; it to be the next character transmitted.
  244. ;
  245. ; The check to see if the immediate character can be placed has
  246. ; already been made prior to entry.
  247. ;
  248. ; Interrupts must be disabled before entering this code
  249. ;
  250. ; Entry:
  251. ; AH = Character
  252. ; DS:SI --> DEB
  253. ; Returns:
  254. ; None
  255. ; Error Returns:
  256. ; None
  257. ; Registers Preserved:
  258. ; BX,CX,SI,DI,DS,ES
  259. ; Registers Destroyed:
  260. ; AL,DX,FLAGS
  261. ; History:
  262. ;-----------------------------------------------------------------------;
  263. ;------------------------------Pseudo-Code------------------------------;
  264. ; {
  265. ; }
  266. ;-----------------------------------------------------------------------;
  267. assumes ds,Data
  268. assumes es,nothing
  269. public TXI ;Public for debugging
  270. TXI proc near
  271. ; FCLI ;Must be done by caller!
  272. or EFlags[si],fTxImmed ;Show char to xmit
  273. mov ImmedChar[si],ah ;Set character to transmit next
  274. ; jmp short KickTx ;Kick Xmit just in case
  275. errn$ KickTx
  276. TXI endp
  277. page
  278. ;----------------------------Private-Routine----------------------------;
  279. ;
  280. ; KickTx - Kick Transmitter
  281. ;
  282. ; "Kick" the transmitter interrupt routine into operation.
  283. ; If the Transmitter Holding Register isn't empty, then
  284. ; nothing needs to be done. If it is empty, then the xmit
  285. ; interrupt needs to enabled in the IER.
  286. ;
  287. ; Entry:
  288. ; DS:SI --> DEB
  289. ; INTERRUPTS DISABLED!
  290. ; Returns:
  291. ; None
  292. ; Error Returns:
  293. ; None
  294. ; Registers Preserved:
  295. ; BX,CX,SI,DI,DS,ES
  296. ; Registers Destroyed:
  297. ; AX,DX,FLAGS
  298. ; History:
  299. ;-----------------------------------------------------------------------;
  300. ;------------------------------Pseudo-Code------------------------------;
  301. ; {
  302. ; }
  303. ;-----------------------------------------------------------------------;
  304. assumes ds,Data
  305. assumes es,nothing
  306. public KickTx ;Public for debugging
  307. KickTx proc near
  308. ; FCLI ;Done by caller
  309. mov dx,Port[si] ;Get device I/O address
  310. add dl,ACE_LSR ;Point at the line status reg
  311. pin al,dx ;And get it
  312. and al,ACE_THRE ;Check transmitter holding reg status
  313. jz KickTx10 ;Busy, interrupt will hit soon enough
  314. sub dl,ACE_LSR-ACE_IER ;--> Interrupt enable register
  315. pin al,dx ;Get current IER state
  316. test al,ACE_THREI ;Interrupt already enabled?
  317. jnz KickTx10 ; Yes, don't reenable it
  318. or al,ACE_THREI ; No, enable it
  319. pout dx,al
  320. pause ;8250, 8250-B bug requires
  321. pout dx,al ; writting register twice
  322. KickTx10:
  323. ; FSTI ;Done by caller
  324. ret
  325. KickTx endp
  326. page
  327. ;----------------------------Private-Routine----------------------------;
  328. ;
  329. ; GetDEB - Get Pointer To Device's DEB
  330. ;
  331. ; Returns a pointer to appropriate DEB, based on device number.
  332. ;
  333. ; Entry:
  334. ; AH = cid
  335. ; Returns:
  336. ; 'C' clear
  337. ; 'S' set if LPT device
  338. ; DS:SI --> DEB is valid cid
  339. ; AH = cid
  340. ; Error Returns:
  341. ; 'C' set if error (cid is invalid)
  342. ; AX = 8000h
  343. ; Registers Preserved:
  344. ; BX,CX,DX,DI,DS,ES
  345. ; Registers Destroyed:
  346. ; AX,SI,FLAGS
  347. ; History:
  348. ;-----------------------------------------------------------------------;
  349. ;------------------------------Pseudo-Code------------------------------;
  350. ; {
  351. ; }
  352. ;-----------------------------------------------------------------------;
  353. assumes ds,Data
  354. assumes es,nothing
  355. public GetDEB ;Public for debugging
  356. GetDEB proc near
  357. cmp ah,LPTx+MAXLPT ;Within range?
  358. ja GetDEB30 ;No, return invalid ID
  359. mov si,DataOFFSET LPT3 ;Assume LPT3
  360. je GetDEB10 ;It's LPT3
  361. cmp ah,MAXCOM ;Is cid within range for a com port?
  362. ja GetDEB20 ; No, check for a LPT port 1 and 2
  363. mov si,DataOFFSET Comm4 ;Assume COM4 [rkh] ...
  364. je GetDEB10 ;It was COM4
  365. mov si,DataOFFSET Comm3 ;Assume COM3
  366. cmp ah,MAXCOM-1 ;Is cid within range for a com port?
  367. je GetDEB10 ;It was COM3
  368. mov si,DataOFFSET Comm2 ;Assume COM2
  369. cmp ah,MAXCOM-2 ;Is cid within range for a com port?
  370. je GetDEB10 ;It was COM2
  371. mov si,DataOFFSET Comm1 ;It was COM1
  372. GetDEB10:
  373. or ah,ah ;Set 'S' if LPT, clear 'C'
  374. ret
  375. .errnz LPTx-10000000b
  376. GetDEB20:
  377. mov si,DataOFFSET LPT1 ;Assume LPT1
  378. cmp ah,LPTx
  379. je GetDEB10 ;Its LPT1
  380. mov si,DataOFFSET LPT2 ;Assume LPT2
  381. ja GetDEB10 ;Its LPT2
  382. GetDEB30:
  383. mov ax,8000h ;Set error code
  384. stc ;Set 'C' to show error
  385. ret
  386. GetDEB endp
  387. page
  388. ;----------------------------Public Routine-----------------------------;
  389. ;
  390. ; $SETQUE - Set up Queue Pointers
  391. ;
  392. ; Sets pointers to Receive and Transmit Queues, as provided by the
  393. ; caller, and initializes those queues to be empty.
  394. ;
  395. ; Queues must be set before $INICOM is called!
  396. ;
  397. ; Entry:
  398. ; AH = Device ID
  399. ; ES:BX --> Queue Definition Block
  400. ; Returns:
  401. ; AX = 0 if no errors occured
  402. ; Error Returns:
  403. ; AX = error code
  404. ; Registers Preserved:
  405. ; BX,DX,SI,DI,DS
  406. ; Registers Destroyed:
  407. ; AX,CX,ES,FLAGS
  408. ; History:
  409. ;-----------------------------------------------------------------------;
  410. ;------------------------------Pseudo-Code------------------------------;
  411. ; {
  412. ; }
  413. ;-----------------------------------------------------------------------;
  414. assumes ds,Data
  415. assumes es,nothing
  416. public $SETQUE
  417. $SETQUE proc near
  418. push si ;These will be used
  419. push di
  420. call GetDEB ;Get DEB
  421. jc SetQue10 ;Invalid, ignore the call
  422. js SetQue10 ;Ignore call for LPT ports
  423. push ds ;Set ds:si --> QDB
  424. push es ;Set es:di --> to ComDCB.QInAddr
  425. pop ds
  426. assumes ds,nothing
  427. pop es
  428. assumes es,Data
  429. lea di,QInAddr[si]
  430. mov si,bx
  431. mov cx,(SIZE QDB)/2
  432. .errnz (SIZE QDB) AND 1
  433. xor ax,ax ;Will do some zero filling
  434. cld
  435. FCLI ;No one else can play with queues
  436. rep movsw
  437. mov cl,(EFlags-QInCount)/2
  438. .errnz (EFlags-QInCount) AND 0FE01h
  439. rep stosw
  440. FSTI
  441. push es ;Restore the data segment
  442. pop ds
  443. assumes ds,Data
  444. assumes es,nothing
  445. SetQue10:
  446. pop di ;Restore saved registers
  447. pop si
  448. ret
  449. ; The above code made a few assumptions about how memory
  450. ; was allocated within the structures:
  451. .errnz (QueueRxSize-QueueRxAddr)-(QInSize-QInAddr)
  452. .errnz (QueueTxAddr-QueueRxSize)-(QOutAddr-QInSize)
  453. .errnz (QueueTxSize-QueueTxAddr)-(QOutSize-QOutAddr)
  454. .errnz QueueRxSize-QueueRxAddr-4
  455. .errnz QueueTxAddr-QueueRxSize-2
  456. .errnz QueueTxSize-QueueTxAddr-4
  457. .errnz QInSize-QInAddr-4
  458. .errnz QOutAddr-QInSize-2
  459. .errnz QOutSize-QOutAddr-4
  460. .errnz QInCount-QOutSize-2
  461. .errnz QInGet-QInCount-2
  462. .errnz QInPut-QInGet-2
  463. .errnz QOutCount-QInPut-2
  464. .errnz QOutGet-QOutCount-2
  465. .errnz QOutPut-QOutGet-2
  466. .errnz EFlags-QOutPut-2 ;First non-queue item
  467. $SETQUE endp
  468. page
  469. ;----------------------------Public Routine-----------------------------;
  470. ;
  471. ; $EVT - Set Event Mask
  472. ;
  473. ; Set up event word and mask. Returns a pointer to a word in which
  474. ; certain bits, as enabled by the mask, will be set when certain
  475. ; events occur.
  476. ;
  477. ; Entry:
  478. ; AH = Device ID
  479. ; BX = Event enable mask
  480. ; Returns:
  481. ; DX:AX --> event word.
  482. ; Error Returns:
  483. ; AX = 0 if error
  484. ; Registers Preserved:
  485. ; BX,CX,SI,DI,DS,ES
  486. ; Registers Destroyed:
  487. ; AX,DX,FLAGS
  488. ; History:
  489. ;-----------------------------------------------------------------------;
  490. ;------------------------------Pseudo-Code------------------------------;
  491. ; {
  492. ; }
  493. ;-----------------------------------------------------------------------;
  494. assumes ds,Data
  495. assumes es,nothing
  496. public $EVT
  497. $EVT proc near
  498. push si
  499. xor dx,dx ;In case of error
  500. call GetDEB ;Get pointer to DEB
  501. mov ax,dx ;Finish setting error return value
  502. jc Evt10 ;Illegal id, return error
  503. js Evt10 ;LPTx, return error
  504. mov EvtMask[si],bx ;Save the new event mask
  505. lea ax,EvtWord[si] ;Get address of event word
  506. mov dx,ds ; into dx:ax
  507. Evt10:
  508. pop si
  509. ret
  510. $EVT endp
  511. page
  512. ;----------------------------Public Routine-----------------------------;
  513. ;
  514. ; $EVTGET - Get Event Word
  515. ;
  516. ; Return and clear fields in the event word. This routine MUST be used
  517. ; by applications to read the event word, as it is the ONLY way they
  518. ; can be assured that an event is not lost between reading the flags
  519. ; and resetting some.
  520. ;
  521. ; Entry:
  522. ; AH = Device ID
  523. ; BX = Event clear mask
  524. ; Returns:
  525. ; AX = event word
  526. ; Error Returns:
  527. ; None
  528. ; Registers Preserved:
  529. ; AX,CX,SI,DI,DS,ES
  530. ; Registers Destroyed:
  531. ; BX,FLAGS
  532. ; History:
  533. ;-----------------------------------------------------------------------;
  534. ;------------------------------Pseudo-Code------------------------------;
  535. ; {
  536. ; }
  537. ;-----------------------------------------------------------------------;
  538. assumes ds,Data
  539. assumes es,nothing
  540. public $EVTGET
  541. $EVTGET proc near
  542. push si
  543. call GetDEB
  544. mov ah,0 ;In case of error (AL already 0)
  545. jc EvtGet10 ;Illegal ID
  546. js EvtGet10 ;Illegal ID
  547. FCLI ;No interrupts allowed
  548. mov ax,EvtWord[si] ;Get the current event word
  549. not bx ;Convert mask for our purposes
  550. and bx,ax ;Clear events that user wants us to
  551. mov EvtWord[si],bx ;And save those results
  552. FSTI ;Magic over
  553. EvtGet10:
  554. pop si
  555. ret
  556. $EVTGET endp
  557. page
  558. ;----------------------------Public Routine-----------------------------;
  559. ;
  560. ; $STACOM - Return Status Information
  561. ;
  562. ; Returns the number of bytes in both queues.
  563. ;
  564. ; LPT ports will show both queues empty.
  565. ; and resetting some.
  566. ;
  567. ; Entry:
  568. ; AH = Device ID
  569. ; ES:BX = Pointer to status structure to be updated.
  570. ; = Null if not to update
  571. ; Returns:
  572. ; AX = comm error word
  573. ; Status Structure Updated.
  574. ; Error Returns:
  575. ; AX = error code
  576. ; Registers Preserved:
  577. ; SI,DI,DS,ES
  578. ; Registers Destroyed:
  579. ; AX,BX,CX,DX,FLAGS
  580. ; History:
  581. ;-----------------------------------------------------------------------;
  582. ;------------------------------Pseudo-Code------------------------------;
  583. ; {
  584. ; }
  585. ;-----------------------------------------------------------------------;
  586. assumes ds,Data
  587. assumes es,nothing
  588. public $STACOM
  589. $STACOM proc near
  590. push si
  591. call GetDEB ;Get DEB pointer in SI
  592. jc StaCom30 ;Invalid ID
  593. mov cx,es ;Is the pointer NULL?
  594. or cx,bx
  595. jz StaCom25 ; Yes, just return error code
  596. xor cx,cx
  597. xor dx,dx
  598. or ah,ah ;Set 'S' if LPT port
  599. mov ax,cx ;For LPTs, everything is zero
  600. js StaCom20 ;LPT port
  601. ; Need to get the status for a com port. Since not all the
  602. ; status is contained within EFlags, it has to be assembled.
  603. ; Also note that currently there is no way to specify RLSD
  604. ; as a handshaking line, so fRLSDHold is always returned false.
  605. mov al,MSRShadow[si] ;Get state of hardware lines
  606. and al,OutHHSLines[si] ;Mask off required bits
  607. xor al,OutHHSLines[si] ;1 = line low
  608. mov cl,4 ;Align bits
  609. shr al,cl ;al = fCTSHold + fDSRHold
  610. .errnz ACE_CTS-00010000b
  611. .errnz ACE_DSR-00100000b
  612. .errnz fCTSHold-00000001b
  613. .errnz fDSRHold-00000010b
  614. mov ah,HSFlag[si] ;Get fXOffHold+fXOffSent
  615. and ah,XOffReceived+XOffSent
  616. or al,ah
  617. .errnz XOffReceived-fXOFFHold
  618. .errnz XOffSent-fXOFFSent
  619. mov ah,EFlags[si] ;Get fEOF+fTxImmed
  620. and ah,fEOF+fTxImmed
  621. or al,ah
  622. mov cx,QInCount[si] ;Get input queue count
  623. mov dx,QOutCount[si] ;Get tx queue count
  624. StaCom20:
  625. mov es:StatFlags[bx],al
  626. mov es:StatRxCount[bx],cx
  627. mov es:StatTxCount[bx],dx
  628. StaCom25:
  629. xor ax,ax ;Return old com error
  630. xchg ax,ComErr[si] ; and clear it out
  631. StaCom30:
  632. pop si
  633. ret
  634. $STACOM endp
  635. page
  636. ;----------------------------Public Routine-----------------------------;
  637. ;
  638. ; $SetBrk - Set Break
  639. ;
  640. ; Clamp the Tx data line low. Does not wait for the
  641. ; transmitter holding register and shift registers to empty.
  642. ;
  643. ; LPT ports will just return the comm error word
  644. ;
  645. ; Entry:
  646. ; AH = Device ID
  647. ; Returns:
  648. ; AX = comm error word
  649. ; Error Returns:
  650. ; AX = error code
  651. ; Registers Preserved:
  652. ; SI,DI,DS,ES
  653. ; Registers Destroyed:
  654. ; AX,BX,CX,DX,FLAGS
  655. ; History:
  656. ;-----------------------------------------------------------------------;
  657. ;------------------------------Pseudo-Code------------------------------;
  658. ; {
  659. ; }
  660. ;-----------------------------------------------------------------------;
  661. assumes ds,Data
  662. assumes es,nothing
  663. public $SETBRK
  664. $SETBRK proc near
  665. mov cx,0FF00h+ACE_SB ;Will be setting break
  666. jmp short ClrBrk10
  667. .errnz BreakSet-ACE_SB ;Must be same bits
  668. $SETBRK endp
  669. page
  670. ;----------------------------Public Routine-----------------------------;
  671. ;
  672. ; $CLRBRK - Clear Break
  673. ;
  674. ; Release any BREAK clamp on the Tx data line.
  675. ;
  676. ; LPT ports will just return the comm error word
  677. ;
  678. ; Entry:
  679. ; AH = Device ID
  680. ; Returns:
  681. ; AX = comm error word
  682. ; Error Returns:
  683. ; AX = error code
  684. ; Registers Preserved:
  685. ; SI,DI,DS,ES
  686. ; Registers Destroyed:
  687. ; AX,BX,CX,DX,FLAGS
  688. ; History:
  689. ;-----------------------------------------------------------------------;
  690. ;------------------------------Pseudo-Code------------------------------;
  691. ; {
  692. ; }
  693. ;-----------------------------------------------------------------------;
  694. assumes ds,Data
  695. assumes es,nothing
  696. public $CLRBRK
  697. $CLRBRK proc near
  698. mov cx,(NOT ACE_SB) SHL 8
  699. .errnz BreakSet-ACE_SB ;Must be same bits
  700. ClrBrk10:
  701. push si
  702. call GetDEB ;Get DEB address
  703. jc ClrBrk30 ;Invalid ID
  704. js ClrBrk20 ;Ignored for LPT ports
  705. FCLI
  706. and HSFlag[si],ch ;Set or clear the BreakSet bit
  707. or HSFlag[si],cl
  708. ; ch = mask to remove bits in the Line Control Register
  709. ; cl = mask to turn bits on in the Line Control Register
  710. mov dx,Port[si] ;Get comm device base I/O port
  711. add dl,ACE_LCR ;Point at the Line Control Regieter
  712. pin al,dx ;Get old line control value
  713. and al,ch ;Turn off desired bits
  714. or al,cl ;Turn on desired bits
  715. pause
  716. pout dx,al ;Output New LCR.
  717. FSTI
  718. ClrBrk20:
  719. mov ax,ComErr[si] ;Return Status Word
  720. ClrBrk30:
  721. pop si
  722. ret
  723. $CLRBRK endp
  724. page
  725. ;----------------------------Public Routine-----------------------------;
  726. ;
  727. ; $EXTCOM - Extended Comm Functions
  728. ;
  729. ; A number of extended functions are routed through this entry point.
  730. ;
  731. ; Functions currently implemented:
  732. ;
  733. ; 0: Ignored
  734. ; 1: SETXOFF - Exactly as if X-OFF character has been received.
  735. ; 2: SETXON - Exactly as if X-ON character has been received.
  736. ; 3: SETRTS - Set the RTS signal
  737. ; 4: CLRRTS - Clear the RTS signal
  738. ; 5: SETDTR - Set the DTR signal
  739. ; 6: CLRDTR - Clear the DTR signal
  740. ; 7: RESET - Yank on reset line if available (LPT devices)
  741. ;
  742. ; Entry:
  743. ; AH = Device ID
  744. ; BL = Function Code
  745. ; (0-127 are MS-defined, 128-255 are OEM defined)
  746. ; Returns:
  747. ; AX = comm error word
  748. ; Error Returns:
  749. ; AX = error code
  750. ; Registers Preserved:
  751. ; SI,DI,DS
  752. ; Registers Destroyed:
  753. ; AX,BX,CX,DX,ES,FLAGS
  754. ; History:
  755. ;-----------------------------------------------------------------------;
  756. ;------------------------------Pseudo-Code------------------------------;
  757. ; {
  758. ; }
  759. ;-----------------------------------------------------------------------;
  760. ; Dispatch table for the extended functions
  761. ExtTab dw ExtComDummy ;Function 0: Never Mind
  762. dw ExtCom_FN1 ;1: Set X-Off
  763. dw ExtCom_FN2 ;2: Clear X-Off
  764. dw ExtCom_FN3 ;3: Set RTS
  765. dw ExtCom_FN4 ;4: Clear RTS
  766. dw ExtCom_FN5 ;5: Set DSR
  767. dw ExtCom_FN6 ;6: Clear DSR
  768. dw ExtCom_FN7 ;7: Reset printer
  769. assumes ds,Data
  770. assumes es,nothing
  771. public $EXTCOM
  772. $EXTCOM proc near
  773. push si
  774. call GetDEB ;Get DEB pointer
  775. jc ExtCom40 ;Invalid ID, return error
  776. mov dx,Port[si] ; get port address
  777. jns ExtCom10 ;Its a COM port
  778. cmp bl,7 ;RESET extended function?
  779. jne ExtCom30 ; No, return error word
  780. jmp short ExtCom20 ; Yes, invoke the function
  781. ExtCom10:
  782. cmp bl,7 ;Last fcn supported +1
  783. jnc ExtCom30 ;Not an implemented function.
  784. ExtCom20:
  785. xor bh,bh
  786. add bx,bx ;Shift for the call
  787. FCLI ;Consider as critical sections
  788. call ExtTab[bx] ; and perform the function
  789. FSTI
  790. ExtCom30:
  791. mov ax,ComErr[si] ;Return standard error word
  792. ExtCom40:
  793. pop si
  794. ExtComDummy:
  795. ret
  796. $EXTCOM endp
  797. page
  798. ;----------------------------Private-Routine----------------------------;
  799. ;
  800. ; ExtCom_FN1 - Extended Function Set X-Off
  801. ;
  802. ; Analagous to receiving an X-OFF character. Bufferred transmision of
  803. ; characters is halted until an X-ON character is received, or until
  804. ; we fake that with a Clear X-Off call.
  805. ;
  806. ; Entry:
  807. ; interrupts disabled
  808. ; dx = port base address
  809. ; Returns:
  810. ; None
  811. ; Error Returns:
  812. ; None
  813. ; Registers Preserved:
  814. ; SI,DI,DS
  815. ; Registers Destroyed:
  816. ; AX,BX,CX,DX,ES,FLAGS
  817. ; History:
  818. ;-----------------------------------------------------------------------;
  819. ;------------------------------Pseudo-Code------------------------------;
  820. ; {
  821. ; }
  822. ;-----------------------------------------------------------------------;
  823. assumes ds,Data
  824. assumes es,nothing
  825. public ExtCom_FN1
  826. ExtCom_FN1 proc near
  827. or HSFlag[si],XOffReceived
  828. ret
  829. ExtCom_FN1 endp
  830. page
  831. ;----------------------------Private-Routine----------------------------;
  832. ;
  833. ; ExtCom_FN2 - Extended Function Clear X-Off
  834. ;
  835. ; Analagous to receiving an X-ON character. Buffered
  836. ; transmission of characters is restarted.
  837. ;
  838. ; Entry:
  839. ; interrupts disabled
  840. ; dx = port base address
  841. ; Returns:
  842. ; None
  843. ; Error Returns:
  844. ; None
  845. ; Registers Preserved:
  846. ; SI,DI,DS
  847. ; Registers Destroyed:
  848. ; AX,BX,CX,DX,ES,FLAGS
  849. ; History:
  850. ;-----------------------------------------------------------------------;
  851. ;------------------------------Pseudo-Code------------------------------;
  852. ; {
  853. ; }
  854. ;-----------------------------------------------------------------------;
  855. assumes ds,Data
  856. assumes es,nothing
  857. public ExtCom_FN2
  858. ExtCom_FN2 proc near
  859. and HSFlag[si],NOT XOffReceived
  860. jmp KickTx ;Kick transmitter interrupts on
  861. ExtCom_FN2 endp
  862. page
  863. ;----------------------------Private-Routine----------------------------;
  864. ;
  865. ; ExtCom_FN3 - Extended Function Set RTS
  866. ;
  867. ; Set the RTS signal active.
  868. ;
  869. ; Entry:
  870. ; interrupts disabled
  871. ; dx = port base address
  872. ; Returns:
  873. ; None
  874. ; Error Returns:
  875. ; None
  876. ; Registers Preserved:
  877. ; SI,DI,DS
  878. ; Registers Destroyed:
  879. ; AX,BX,CX,DX,ES,FLAGS
  880. ; History:
  881. ;-----------------------------------------------------------------------;
  882. ;------------------------------Pseudo-Code------------------------------;
  883. ; {
  884. ; }
  885. ;-----------------------------------------------------------------------;
  886. assumes ds,Data
  887. assumes es,nothing
  888. public ExtCom_FN3
  889. ExtCom_FN3 proc near
  890. add dl,ACE_MCR ;Point at Modem Control Register
  891. pin al,dx ;Get current settings
  892. or al,ACE_RTS ;Set RTS
  893. pause
  894. pout dx,al ;And update
  895. ret
  896. ExtCom_FN3 endp
  897. page
  898. ;----------------------------Private-Routine----------------------------;
  899. ;
  900. ; ExtCom_FN4 - Extended Function Clear RTS
  901. ;
  902. ; Set the RTS signal inactive.
  903. ;
  904. ; Entry:
  905. ; interrupts disabled
  906. ; dx = port base address
  907. ; Returns:
  908. ; None
  909. ; Error Returns:
  910. ; None
  911. ; Registers Preserved:
  912. ; SI,DI,DS
  913. ; Registers Destroyed:
  914. ; AX,BX,CX,DX,ES,FLAGS
  915. ; History:
  916. ;-----------------------------------------------------------------------;
  917. ;------------------------------Pseudo-Code------------------------------;
  918. ; {
  919. ; }
  920. ;-----------------------------------------------------------------------;
  921. assumes ds,Data
  922. assumes es,nothing
  923. public ExtCom_FN4
  924. ExtCom_FN4 proc near
  925. add dl,ACE_MCR ;Point at Modem Control Register
  926. pin al,dx ;Get current settings
  927. and al,NOT ACE_RTS ;Clear RTS
  928. pause
  929. pout dx,al ;And update
  930. ret
  931. ExtCom_FN4 endp
  932. page
  933. ;----------------------------Private-Routine----------------------------;
  934. ;
  935. ; ExtCom_FN5 - Extended Function Set DTR
  936. ;
  937. ; Set the DTR signal active.
  938. ;
  939. ; Entry:
  940. ; interrupts disabled
  941. ; dx = port base address
  942. ; Returns:
  943. ; None
  944. ; Error Returns:
  945. ; None
  946. ; Registers Preserved:
  947. ; SI,DI,DS
  948. ; Registers Destroyed:
  949. ; AX,BX,CX,DX,ES,FLAGS
  950. ; History:
  951. ;-----------------------------------------------------------------------;
  952. ;------------------------------Pseudo-Code------------------------------;
  953. ; {
  954. ; }
  955. ;-----------------------------------------------------------------------;
  956. assumes ds,Data
  957. assumes es,nothing
  958. public ExtCom_FN5
  959. ExtCom_FN5 proc near
  960. add dl,ACE_MCR ;Point at Modem Control Register
  961. pin al,dx ;Get current settings
  962. or al,ACE_DTR ;Set DTR
  963. pause
  964. pout dx,al ;And update
  965. ret
  966. ExtCom_FN5 endp
  967. page
  968. ;----------------------------Private-Routine----------------------------;
  969. ;
  970. ; ExtCom_FN6 - Extended Function Clear DTR
  971. ;
  972. ; Set the DTR signal inactive.
  973. ;
  974. ; Entry:
  975. ; interrupts disabled
  976. ; dx = port base address
  977. ; Returns:
  978. ; None
  979. ; Error Returns:
  980. ; None
  981. ; Registers Preserved:
  982. ; SI,DI,DS
  983. ; Registers Destroyed:
  984. ; AX,BX,CX,DX,ES,FLAGS
  985. ; History:
  986. ;-----------------------------------------------------------------------;
  987. ;------------------------------Pseudo-Code------------------------------;
  988. ; {
  989. ; }
  990. ;-----------------------------------------------------------------------;
  991. assumes ds,Data
  992. assumes es,nothing
  993. public ExtCom_FN6
  994. ExtCom_FN6 proc near
  995. add dl,ACE_MCR ;Point at Modem Control Register
  996. pin al,dx ;Get current settings
  997. and al,NOT ACE_DTR ;Clear DTR
  998. pause
  999. pout dx,al ;And update
  1000. ret
  1001. ExtCom_FN6 endp
  1002. page
  1003. ;----------------------------Private-Routine----------------------------;
  1004. ;
  1005. ; ExtCom_FN7 - Extended Function Reset Printer
  1006. ;
  1007. ; Assert the RESET line on an LPT port
  1008. ;
  1009. ; Entry:
  1010. ; interrupts disabled
  1011. ; dx = port base address
  1012. ; Returns:
  1013. ; None
  1014. ; Error Returns:
  1015. ; None
  1016. ; Registers Preserved:
  1017. ; SI,DI,DS
  1018. ; Registers Destroyed:
  1019. ; AX,BX,CX,DX,ES,FLAGS
  1020. ; History:
  1021. ;-----------------------------------------------------------------------;
  1022. ;------------------------------Pseudo-Code------------------------------;
  1023. ; {
  1024. ; }
  1025. ;-----------------------------------------------------------------------;
  1026. assumes ds,Data
  1027. assumes es,nothing
  1028. public ExtCom_FN7
  1029. ExtCom_FN7 proc near
  1030. FSTI ;Not called at interrupt time
  1031. mov ch,1 ;ROM BIOS Reset Port
  1032. call DoLPT ;Perform the function
  1033. ret
  1034. ExtCom_FN7 endp
  1035. page
  1036. ;----------------------------Public Routine-----------------------------;
  1037. ;
  1038. ; $DCBPtr - Return Pointer To DCB
  1039. ;
  1040. ; Returns a long pointer to the DCB for the requested device.
  1041. ;
  1042. ; Entry:
  1043. ; AH = Device ID
  1044. ; Returns:
  1045. ; DX:AX = pointer to DCB.
  1046. ; Error Returns:
  1047. ; DX:AX = 0
  1048. ; Registers Preserved:
  1049. ; SI,DI,DS
  1050. ; Registers Destroyed:
  1051. ; BX,CX,ES,FLAGS
  1052. ; History:
  1053. ;-----------------------------------------------------------------------;
  1054. ;------------------------------Pseudo-Code------------------------------;
  1055. ; {
  1056. ; }
  1057. ;-----------------------------------------------------------------------;
  1058. assumes ds,Data
  1059. assumes es,nothing
  1060. public $DCBPTR
  1061. $DCBPTR proc near
  1062. push si
  1063. xor dx,dx
  1064. call GetDEB ;Get pointer to DEB
  1065. mov ax,dx
  1066. jc DCBPtr10 ;Jump if invalid device
  1067. mov ax,si ;else return value here
  1068. mov dx,ds
  1069. DCBPtr10:
  1070. pop si
  1071. ret
  1072. $DCBPTR endp
  1073. page
  1074. ;----------------------------Public Routine-----------------------------;
  1075. ;
  1076. ; $RECCOM - Receive Characters From Device
  1077. ;
  1078. ; Read Byte From RS232 Input Queue If Data Is Ready
  1079. ;
  1080. ; LPT ports will return with an indication that no characters are
  1081. ; available.
  1082. ;
  1083. ; Entry:
  1084. ; AH = Device ID
  1085. ; Returns:
  1086. ; 'Z' clear if data available
  1087. ; AL = byte
  1088. ; Error Returns:
  1089. ; 'Z' Set if error or no data
  1090. ; AX = error code
  1091. ; AX = 0 if no data
  1092. ; Registers Preserved:
  1093. ; SI,DI,DS
  1094. ; Registers Destroyed:
  1095. ; AX,BX,CX,DX,ES,FLAGS
  1096. ; History:
  1097. ;-----------------------------------------------------------------------;
  1098. ;------------------------------Pseudo-Code------------------------------;
  1099. ; {
  1100. ; }
  1101. ;-----------------------------------------------------------------------;
  1102. assumes ds,Data
  1103. assumes es,nothing
  1104. public $RECCOM
  1105. $RECCOM proc near
  1106. push si ;Once again, save some registers
  1107. push di
  1108. call GetDEB ;Get DEB pointer in SI
  1109. jc RecCom10 ;Invalid Port [rkh] ...
  1110. js RecCom20 ;LPT port, return no characters
  1111. jmp short RecCom30
  1112. RecCom10:
  1113. jmp RecCom100 ; Invalid Port
  1114. RecCom20:
  1115. jmp RecCom95 ;LPT port, return no characters
  1116. ; Before removing any charcters from the input queue, check to see
  1117. ; if XON needs to be issued. If it needs to be issued, set the
  1118. ; flag that will force it and arm transmit interrupts.
  1119. RecCom30:
  1120. test Flags[si],fEnqAck+fEtxAck ;Enq or Etx Ack?
  1121. jz RecCom32 ; No
  1122. test HSFlag[si],EnqReceived+HHSDropped ;Enq recvd or lines dropped?
  1123. jz RecCom60 ; No Enq recvd & no lines dropped
  1124. jmp short RecCom34
  1125. RecCom32:
  1126. test HSFlag[si],HSSent ;Handshake sent?
  1127. jz RecCom60 ; No XOFF sent & no lines dropped
  1128. RecCom34:
  1129. mov ax,QInCount[si] ;Get current count of input chars
  1130. cmp ax,XONLim[si] ;See if at XOn limit
  1131. ja RecCom60 ;Not at XOn limit yet
  1132. ; If any hardware lines are down, then raise them. Then see
  1133. ; about sending XON.
  1134. mov dx,Port[si] ;Get the port
  1135. mov ah,HHSLines[si] ;Get hardware lines mask
  1136. FCLI ;Handle this as a critical section
  1137. mov cl,HSFlag[si] ;Get handshaking flags
  1138. or ah,ah ;Any hardware lines to play with?
  1139. jz RecCom40 ; No
  1140. add dl,ACE_MCR ;--> Modem control register
  1141. pin al,dx
  1142. or al,ah ;Turn on the hardware bits
  1143. pause
  1144. pout dx,al
  1145. and cl,NOT HHSDropped ;Show hardware lines back up
  1146. RecCom40:
  1147. test Flags[si],fEnqAck+fEtxAck ;Enq or Etx Ack?
  1148. jz RecCom47 ; No
  1149. test cl,EnqReceived ;Did we receive Enq?
  1150. jz RecCom55 ; No
  1151. and cl,NOT EnqReceived
  1152. jmp short RecCom50
  1153. RecCom47:
  1154. test cl,XOffSent ;Did we send XOFF?
  1155. jz RecCom55 ; No
  1156. and cl,NOT XOffSent ;Remove XOFF sent flag
  1157. RecCom50:
  1158. or cl,XOnPending ;Show XON or ACK must be sent
  1159. call KickTx ;Kick xmit if needed
  1160. RecCom55:
  1161. mov HSFlag[si],cl ;Store handshake flag
  1162. FSTI ;Can allow interrupts now
  1163. ; Now we can get down to the business at hand, and remove a character
  1164. ; from the receive queue. If a communications error exists, we return
  1165. ; that, and nothing else.
  1166. RecCom60:
  1167. xor ax,ax
  1168. or ax,ComErr[si] ;Any Errors?
  1169. jnz RecCom100 ; Yes, return the error code
  1170. or ax,QInCount[si] ;Get current input char count
  1171. jz RecCom90 ;No characters in the queue
  1172. les di,QInAddr[si] ;Get queue pointer
  1173. assumes es,nothing
  1174. mov bx,QInGet[si] ;Also get the index to head
  1175. mov al,es:[bx][di] ;Finally, get byte from queue
  1176. inc bx ;Update queue index
  1177. cmp bx,QInSize[si] ;See if time for wrap-around
  1178. jc RecCom70 ;Jump if no wrap
  1179. xor bx,bx ;wrap by zeroing the index
  1180. RecCom70:
  1181. mov QInGet[si],bx ;Save new head pointer
  1182. dec QInCount[si] ;Dec # of bytes in queue
  1183. RecCom80:
  1184. or sp,sp ;Reset PSW.Z
  1185. pop di
  1186. pop si
  1187. ret
  1188. ; No characters in the input queue. Check to see if EOF
  1189. ; was received, and return it if it was. Otherwise show
  1190. ; no characters.
  1191. RecCom90:
  1192. test Flags[si],fBinary ;Are we doing binary stuff?
  1193. jnz RecCom95 ; Yes, show no characters
  1194. mov al,EOFChar[si] ;Assume EOF
  1195. test EFlags[si],fEOF ;Has end of file char been received?
  1196. jnz RecCom80 ; Yes, show end of file
  1197. RecCom95:
  1198. xor ax,ax ;Show no more characters
  1199. ; Return with 'Z' to show error or no characters
  1200. RecCom100:
  1201. xor cx,cx ;Set PSW.Z
  1202. pop di
  1203. pop si
  1204. ret
  1205. $RECCOM endp
  1206. page
  1207. ;----------------------------Public Routine-----------------------------;
  1208. ;
  1209. ; $FLUSH - Flush The Input and Output Queues
  1210. ;
  1211. ; This is a hard initialization of the transmit and receive queue's,
  1212. ; which immediately empties the given queue.
  1213. ;
  1214. ; LPT ports will just return the device error word
  1215. ;
  1216. ; Entry:
  1217. ; AH = Device ID
  1218. ; BH = Queue # to clear (0=Tx, 1=Rx)
  1219. ; Returns:
  1220. ; AX = Device Error Word. (Not reset)
  1221. ; Error Returns:
  1222. ; AX = error code
  1223. ; Registers Preserved:
  1224. ; SI,DI,DS
  1225. ; Registers Destroyed:
  1226. ; AX,BX,CX,DX,ES,FLAGS
  1227. ; History:
  1228. ;-----------------------------------------------------------------------;
  1229. ;------------------------------Pseudo-Code------------------------------;
  1230. ; {
  1231. ; }
  1232. ;-----------------------------------------------------------------------;
  1233. assumes ds,Data
  1234. assumes es,nothing
  1235. public $FLUSH
  1236. $FLUSH proc near
  1237. push si
  1238. push di
  1239. call GetDEB ;si --> DEB
  1240. jc Flush40 ;Invalid ID
  1241. js Flush30 ;LPT port, return any error
  1242. mov cx,QOutCount-QInCount ;# of bytes to zero
  1243. lea di,QInCount[si] ;--> receive queue data
  1244. or bh,bh ;Transmit queue?
  1245. jnz Flush10 ; No, input queue
  1246. add di,cx ; Yes, --> xmit queue data
  1247. Flush10:
  1248. cld
  1249. push ds
  1250. pop es
  1251. assumes es,nothing
  1252. xor al,al
  1253. FCLI ;Time to worry about critical sections
  1254. rep stosb
  1255. FSTI
  1256. .errnz QInGet-QInCount-2
  1257. .errnz QInPut-QInGet-2
  1258. .errnz QOutCount-QInPut-2
  1259. .errnz QOutGet-QOutCount-2
  1260. .errnz QOutPut-QOutGet-2
  1261. or bh,bh ;Rx queue?
  1262. jz Flush30 ; No, xmit queue
  1263. ; If the queue to be cleared is the receive queue, any
  1264. ; hardware handshake must be cleared to prevent a possible
  1265. ; deadlock situation. Since we just zeroed the queue count,
  1266. ; a quick call to $RecCom should do wonders to clear any
  1267. ; receive handshake (i.e. send XON if needed).
  1268. Flush20:
  1269. call $RECCOM ;Take care of handshakes here
  1270. Flush30:
  1271. mov ax,ComErr[si] ;And return the error word.
  1272. Flush40:
  1273. pop di
  1274. pop si
  1275. ret
  1276. $FLUSH endp
  1277. ifdef DEBUG
  1278. public KickTx10
  1279. public GetDEB10
  1280. public GetDEB20
  1281. public GetDEB30
  1282. public SetQue10
  1283. public Evt10
  1284. public EvtGet10
  1285. public StaCom20
  1286. public StaCom25
  1287. public StaCom30
  1288. public ClrBrk10
  1289. public ClrBrk20
  1290. public ClrBrk30
  1291. public ExtCom10
  1292. public ExtCom20
  1293. public ExtCom30
  1294. public ExtCom40
  1295. public ExtComDummy
  1296. public DCBPtr10
  1297. public RecCom30
  1298. public RecCom40
  1299. public RecCom50
  1300. public RecCom60
  1301. public RecCom70
  1302. public RecCom80
  1303. public RecCom90
  1304. public RecCom95
  1305. public RecCom100
  1306. public Flush10
  1307. public Flush20
  1308. public Flush30
  1309. public Flush40
  1310. endif