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.

1947 lines
52 KiB

  1. page,132
  2. ;---------------------------Module-Header-------------------------------;
  3. ; Module Name: IBMCOM.ASM
  4. ;
  5. ; !!!
  6. ;
  7. ; Created: Fri 06-Feb-1987 10:45:12
  8. ; Author: Walt Moore [waltm]
  9. ;
  10. ; Copyright (c) Microsoft Corporation 1985-1990. All Rights Reserved.
  11. ;
  12. ; General Description:
  13. ;
  14. ; History:
  15. ;
  16. ; ***************************************************************
  17. ; Tue Dec 19 1989 09:32:15 -by- Amit Chatterjee [amitc]
  18. ; ---------------------------------------------------------------
  19. ; Modified the 'InitAPort' routine called from 'ReactivateOpenCommPort'.
  20. ; If the out queue for a port has characters to send out then we must
  21. ; restart the trasmission process by faking a comm interrupt on that
  22. ; port.
  23. ; ***************************************************************
  24. ; Tue Nov 21 1989 09:46:50 -by- Amit Chatterjee [amitc]
  25. ; ---------------------------------------------------------------
  26. ; The base port addresses in the COMM1,COMM2,COMM3,COMM4 structures
  27. ; are being zeroed out when the corresponding comm port is closed.
  28. ; This is because the 'ReactivateOpenCommPort' function looks at it
  29. ; and if the port address is not zero decides that comm ports are
  30. ; open.
  31. ; ***************************************************************
  32. ; Tue Nov 14 1989 18:42:00 ADDED TWO EXPORTED FUNCTIONS
  33. ; ---------------------------------------------------------------
  34. ; Added two exported functions 'SuspendOpenCommPorts' and
  35. ; 'ReactivateOpenCommPorts' for 286 winoldap support. The first one simply
  36. ; releases the comm int vects and installs the originall one, the second one
  37. ; hooks back the comm driver comm vectors and then reads the receive buffer,
  38. ; the status and the IIR registers of all the available comm ports to
  39. ; remove pending interrupts. It also reprograms the PIC to enable interrupts
  40. ; on all open comm channels.
  41. ; ---------------------------------------------------------------
  42. ; -by- Amit Chatterjee [amitc]
  43. ; ***************************************************************
  44. ; Tue Aug 30 198? 12:52:00 MAJOR FIX TO HANDLE 8250B
  45. ; ---------------------------------------------------------------
  46. ;
  47. ; 8250B has the following peculiar charactersistic
  48. ; . The very first time (after reset) the Tx Holding Empty
  49. ; interrupt is enabled, an immediate interrupt is generated
  50. ;
  51. ; . After the first time, switching the Tx Holding Empty
  52. ; interrupt enable bit from disabled to enabled will NOT
  53. ; generate an immediate interrupt (unlike in 8250)
  54. ; Because of this the KICKTX routine fails to set the transmit cycle
  55. ; on if the machine has a 8250B
  56. ;
  57. ; This has been taken care as follows:
  58. ; . For the very first byte that is being transmitted, KICKTX
  59. ; is used to generate the first Tx Holding Empty interrupt
  60. ; . Subsequently, whenever we find that the transmit buffer
  61. ; is empty, we use a SOFTWARE INT (either INT 0Bh, or INT 0Ch)
  62. ; to force the first character out, once this is done the
  63. ; Tx Holding Empty interrupt will be generated once the buffer
  64. ; really is empty
  65. ; . Now we no longer disable the Tx Holding Empty interrupt
  66. ; in the Xmit ISR to ensure that even m/cs with 8250, use
  67. ; the software int to kick the tx interrupt on after the
  68. ; first time.
  69. ; . The software interrupt is also forced whenever an X-ON
  70. ; character is received.
  71. ;
  72. ; The code that implements the above logic is marked out with a line
  73. ; asterixes.
  74. ; ------------------------------------------------------------------
  75. ; -by- Amit Chatterjee [amitc]
  76. ; ******************************************************************
  77. ;
  78. ; 062587 HSFlag and Evtmask in DoLPT. These fields do not exist
  79. ; for LPT type devices. The code which manipulated them
  80. ; was removed
  81. ;
  82. ; KickTx from $SndCom - interrupts were not disabled when
  83. ; calling KickTx.
  84. ;
  85. ; $SetCom - added CLD at the start
  86. ;
  87. ; $SetQue - movsw ==> stosw
  88. ;
  89. ; 111285 Changed the Timeout from 7 to 30 seconds.
  90. ;
  91. ; 110885 Forgot to set EV_RxChar event when a character
  92. ; was received.
  93. ;
  94. ; 102985 INS8250, INS8250B bug with enabling interrupts.
  95. ; Setting ACE_ETBEI in the Interrupt Enable Register
  96. ; will cause an immediate interrupt regardless of
  97. ; whether the transmitter register is empty or not.
  98. ; The first interrupt MAY also be missed.
  99. ;
  100. ; The first case is not a problem since we only enable
  101. ; interrupts if the transmitter register is empty. The
  102. ; second problem was showing up on Microsoft System Cards
  103. ; in PC-XTs. The first interrupt was missed after a cold
  104. ; boot. National claims the fix is to write the register
  105. ; twice, which SEEMS to work...
  106. ;
  107. ; Added timeout code to $TRMCOM. If the number of
  108. ; characters in the output queue doesn't decrease
  109. ; in "Timeout" seconds, then the port will be closed
  110. ; anyway. Also flushed the input queue and added a
  111. ; discard-input flag for the data available interrupt
  112. ; code to discard any input received while terminating
  113. ; a port. $TRMCOM will return an error code if it
  114. ; discarded any output data.
  115. ;
  116. ; Removed infinite timeout test in MSRWait routine.
  117. ; Still bad, but it will timeout around 65 seconds
  118. ; instead of never.
  119. ;
  120. ; 102785 LPT initialization code was jumping to InitCom90,
  121. ; which was setting EFlags[si] to null. Well, LPTs
  122. ; don't have an EFlags field, so the null was getting
  123. ; stuffed over the LSB of BIOSPortLoc of the next LPT
  124. ; device.
  125. ;
  126. ; 101185 Save interrupt vector when opening a comm port
  127. ; and restore it when closing. Would you believe
  128. ; there are actually programs that assume the
  129. ; vector points to a non-specific 8259 ACK and
  130. ; an IRET!
  131. ;
  132. ; 100985 Added MS-NET support to gain exclusive control
  133. ; of an LPT port if DOS 3.x and not running in as
  134. ; a server, receiver, or messenger. Required to
  135. ; keep another application, such as command.com
  136. ; from closing the stream or mixing their output
  137. ; with ours.
  138. ; sudeepb 10-Jan-1993 changed the costly cli/sti with non-trapping
  139. ; FCLI/FSTI macros
  140. ;-----------------------------------------------------------------------;
  141. title IBMCom - IBM PC, PC-XT, PC-AT, PS/2 Communications Interface
  142. .xlist
  143. include cmacros.inc
  144. include comdev.inc
  145. include ins8250.inc
  146. include ibmcom.inc
  147. include vint.inc
  148. .list
  149. externNP GetDEB
  150. externNP DoLPT
  151. externNP StringToLPT
  152. externNP FindCOMPort
  153. externNP StealPort
  154. sBegin Data
  155. externB $MachineID
  156. sEnd Data
  157. sBegin Code
  158. assumes cs,Code
  159. assumes ds,Data
  160. page
  161. ;----------------------------Public Routine-----------------------------;
  162. ;
  163. ; $RECCOM - Receive Characters From Device
  164. ;
  165. ; Read Byte From RS232 Input Queue If Data Is Ready
  166. ;
  167. ; LPT ports will return with an indication that no characters are
  168. ; available.
  169. ;
  170. ; Entry:
  171. ; AH = Device ID
  172. ; Returns:
  173. ; 'Z' clear if data available
  174. ; AL = byte
  175. ; Error Returns:
  176. ; 'Z' Set if error or no data
  177. ; AX = error code
  178. ; AX = 0 if no data
  179. ; Registers Preserved:
  180. ; SI,DI,DS
  181. ; Registers Destroyed:
  182. ; AX,BX,CX,DX,ES,FLAGS
  183. ; History:
  184. ;-----------------------------------------------------------------------;
  185. ;------------------------------Pseudo-Code------------------------------;
  186. ; {
  187. ; }
  188. ;-----------------------------------------------------------------------;
  189. assumes ds,Data
  190. assumes es,nothing
  191. public $RECCOM
  192. $RECCOM proc near
  193. push si ;Once again, save some registers
  194. push di
  195. call GetDEB ;Get DEB pointer in SI
  196. jc RecCom10 ;Invalid Port [rkh] ...
  197. jns RecCom20 ;COM port
  198. jmp RecCom95 ;LPT port, return no characters
  199. RecCom10:
  200. jmp RecCom100 ; Invalid Port
  201. ; Before removing any charcters from the input queue, check to see
  202. ; if XON needs to be issued. If it needs to be issued, set the
  203. ; flag that will force it and arm transmit interrupts.
  204. RecCom20:
  205. test [si.DCB_Flags],fEnqAck+fEtxAck ;Enq or Etx Ack?
  206. jz RecCom32 ; No
  207. test HSFlag[si],EnqReceived+HHSDropped ;Enq recvd or lines dropped?
  208. jnz RecCom21 ; No Enq recvd & no lines dropped
  209. jmp RecCom60 ; No Enq recvd & no lines dropped
  210. RecCom21:
  211. jmp short RecCom34
  212. RecCom32:
  213. test HSFlag[si],HSSent ;Handshake sent?
  214. jnz RecCom33 ; No XOFF sent & no lines dropped
  215. jmp RecCom60 ; No XOFF sent & no lines dropped
  216. RecCom33:
  217. RecCom34:
  218. mov ax,QInCount[si] ;Get current count of input chars
  219. cmp ax,[si.DCB_XonLim] ;See if at XOn limit
  220. ja RecCom60 ;Not at XOn limit yet
  221. ; If any hardware lines are down, then raise them. Then see
  222. ; about sending XON.
  223. mov dx,Port[si] ;Get the port
  224. mov ah,HHSLines[si] ;Get hardware lines mask
  225. call DOCLI ;Handle this as a critical section
  226. mov cl,HSFlag[si] ;Get handshaking flags
  227. or ah,ah ;Any hardware lines to play with?
  228. jz RecCom40 ; No
  229. add dl,ACE_MCR ;--> Modem control register
  230. in al,dx
  231. or al,ah ;Turn on the hardware bits
  232. iodelay
  233. out dx,al
  234. and cl,NOT HHSDropped ;Show hardware lines back up
  235. RecCom40:
  236. test [si.DCB_Flags],fEnqAck+fEtxAck ;Enq or Etx Ack?
  237. jz RecCom47 ; No
  238. test cl,EnqReceived ;Did we receive Enq?
  239. jz RecCom55 ; No
  240. and cl,NOT EnqReceived
  241. jmp short RecCom50
  242. RecCom47:
  243. test cl,XOffSent ;Did we send XOFF?
  244. jz RecCom55 ; No
  245. and cl,NOT XOffSent ;Remove XOFF sent flag
  246. RecCom50:
  247. or cl,XOnPending ;Show XON or ACK must be sent
  248. call KickTx ;Kick xmit if needed
  249. RecCom55:
  250. mov HSFlag[si],cl ;Store handshake flag
  251. call DOSTI ;Can allow interrupts now
  252. ; Now we can get down to the business at hand, and remove a character
  253. ; from the receive queue. If a communications error exists, we return
  254. ; that, and nothing else.
  255. RecCom60:
  256. xor ax,ax
  257. or ax,ComErr[si] ;Any Errors?
  258. jnz RecCom100 ; Yes, return the error code
  259. or ax,QInCount[si] ;Get current input char count
  260. jz RecCom90 ;No characters in the queue
  261. les di,QInAddr[si] ;Get queue pointer
  262. assumes es,nothing
  263. mov bx,QInGet[si] ;Also get the index to head
  264. mov al,es:[bx][di] ;Finally, get byte from queue
  265. inc bx ;Update queue index
  266. cmp bx,QInSize[si] ;See if time for wrap-around
  267. jc RecCom70 ;Jump if no wrap
  268. xor bx,bx ;wrap by zeroing the index
  269. RecCom70:
  270. mov QInGet[si],bx ;Save new head pointer
  271. dec QInCount[si] ;Dec # of bytes in queue
  272. mov cx, [si.QinCount]
  273. cmp cx, [si.RecvTrigger] ;Q: have we read below trigger?
  274. jae RecCom80 ; N:
  275. and [si.NotifyFlagsHI], NOT CN_RECEIVE ; allow timeout notify again
  276. RecCom80:
  277. or sp,sp ;Reset PSW.Z
  278. pop di
  279. pop si
  280. ret
  281. ; No characters in the input queue. Check to see if EOF
  282. ; was received, and return it if it was. Otherwise show
  283. ; no characters.
  284. RecCom90:
  285. test [si.DCB_Flags],fBinary ;Are we doing binary stuff?
  286. jnz RecCom95 ; Yes, show no characters
  287. mov al,[si.DCB_EofChar] ;Assume EOF
  288. test EFlags[si],fEOF ;Has end of file char been received?
  289. jnz RecCom80 ; Yes, show end of file
  290. RecCom95:
  291. xor ax,ax ;Show no more characters
  292. ; Return with 'Z' to show error or no characters
  293. RecCom100:
  294. xor cx,cx ;Set PSW.Z
  295. pop di
  296. pop si
  297. ret
  298. $RECCOM endp
  299. page
  300. ;----------------------------Public Routine-----------------------------;
  301. ;
  302. ; $RECSTR - Receive Characters From Device
  303. ;
  304. ; Read Byte From RS232 Input Queue If Data Is Ready
  305. ;
  306. ; LPT ports will return with an indication that no characters are
  307. ; available.
  308. ;
  309. ; Entry:
  310. ; AH = Device ID
  311. ; ES:DI -> receive buffer
  312. ; CX max bytes to read
  313. ; Returns:
  314. ; 'Z' clear if data available
  315. ; AX = # of bytes read
  316. ; Error Returns:
  317. ; 'Z' Set if error or no data
  318. ; AX = error code
  319. ; AX = 0 if no data
  320. ; Registers Preserved:
  321. ; SI,DI,DS
  322. ; Registers Destroyed:
  323. ; AX,BX,CX,DX,ES,FLAGS
  324. ; History:
  325. ;-----------------------------------------------------------------------;
  326. ;------------------------------Pseudo-Code------------------------------;
  327. ; {
  328. ; }
  329. ;-----------------------------------------------------------------------;
  330. assumes ds,Data
  331. assumes es,nothing
  332. public $RECSTR
  333. $RECSTR proc near
  334. push si ;Once again, save some registers
  335. push di
  336. call GetDEB ;Get DEB pointer in SI
  337. jc RecStr10 ;Invalid Port [rkh] ...
  338. jns RecStr20 ;COM port
  339. jmp RecStr95 ;LPT port, return no characters
  340. RecStr10:
  341. jmp RecStr100 ; Invalid Port
  342. RecStr15:
  343. jmp RecStr90
  344. RecStr20:
  345. xor ax,ax
  346. or ax,ComErr[si] ;Any Errors?
  347. jnz RecStr10 ; Yes, return the error code
  348. or ax,QInCount[si] ;Get current input char count
  349. jz RecStr15 ;No characters in the queue
  350. cmp cx, ax ;Q: more chars available than can read?
  351. jbe short RecStr30 ; N:
  352. mov cx, ax ; Y: adjust # of chars to read
  353. RecStr30:
  354. push cx
  355. mov dx, QInSize[si]
  356. mov ax, QInGet[si]
  357. sub dx, ax ; dx = # of bytes before end of buf
  358. cmp dx, cx ;Q: more avail than can read?
  359. jbe short RecStr40 ; N:
  360. mov dx, cx ; Y: adjust avail count
  361. RecStr40:
  362. xchg cx, dx ; cx = # of bytes for 1st copy
  363. sub dx, cx ; dx = # of bytes for 2nd copy
  364. push ds
  365. push si
  366. lds bx, QInAddr[si]
  367. mov si, bx
  368. add si, ax ; ds:si -> first char in buffer
  369. cld
  370. rep movsb ; do first copy
  371. mov cx, dx
  372. jcxz short RecStr50 ; jump if no 2nd copy needed
  373. mov si, bx ; ds:si -> start of buffer
  374. rep movsb ; do 2nd copy
  375. RecStr50:
  376. sub si, bx ; si = new QInGet
  377. mov bx, si
  378. pop si
  379. pop ds
  380. pop cx
  381. call DOCLI
  382. mov QInGet[si], bx ; update QInGet
  383. sub QInCount[si], cx ; update count
  384. mov ax, QInCount[si]
  385. call DOSTI
  386. cmp ax, [si.RecvTrigger] ;Q: have we read below trigger?
  387. jae @F ; N:
  388. and [si.NotifyFlagsHI], NOT CN_RECEIVE ; allow timeout notify again
  389. @@:
  390. ; Check to see if XON needs to be issued. If it needs to be issued, set the
  391. ; flag that will force it and arm transmit interrupts.
  392. test [si.DCB_Flags],fEnqAck+fEtxAck ;Enq or Etx Ack?
  393. jz @F ; No
  394. test HSFlag[si],EnqReceived+HHSDropped ;Enq recvd or lines dropped?
  395. jnz RecStr58 ; No Enq recvd & no lines dropped
  396. jmp RecStr80 ; No Enq recvd & no lines dropped
  397. RecStr58:
  398. jmp short RecStr60
  399. @@:
  400. test HSFlag[si],HSSent ;Handshake sent?
  401. jnz RecStr59 ; No XOFF sent & no lines dropped
  402. jmp RecStr80 ; No XOFF sent & no lines dropped
  403. RecStr59:
  404. RecStr60:
  405. ;ax = current count of input chars
  406. cmp ax,[si.DCB_XonLim] ;See if at XOn limit
  407. ja RecStr80 ;Not at XOn limit yet
  408. ;; int 1
  409. ; If any hardware lines are down, then raise them. Then see
  410. ; about sending XON.
  411. mov dx,Port[si] ;Get the port
  412. mov ah,HHSLines[si] ;Get hardware lines mask
  413. push cx
  414. call DOCLI ;Handle this as a critical section
  415. mov cl,HSFlag[si] ;Get handshaking flags
  416. or ah,ah ;Any hardware lines to play with?
  417. jz @F ; No
  418. add dl,ACE_MCR ;--> Modem control register
  419. in al,dx
  420. or al,ah ;Turn on the hardware bits
  421. iodelay
  422. out dx,al
  423. and cl,NOT HHSDropped ;Show hardware lines back up
  424. @@:
  425. test [si.DCB_Flags],fEnqAck+fEtxAck ;Enq or Etx Ack?
  426. jz @F ; No
  427. test cl,EnqReceived ;Did we receive Enq?
  428. jz RecStr70 ; No
  429. and cl,NOT EnqReceived
  430. jmp short RecStr65
  431. @@:
  432. test cl,XOffSent ;Did we send XOFF?
  433. jz RecStr70 ; No
  434. and cl,NOT XOffSent ;Remove XOFF sent flag
  435. RecStr65:
  436. or cl,XOnPending ;Show XON or ACK must be sent
  437. call KickTx ;Kick xmit if needed
  438. RecStr70:
  439. mov HSFlag[si],cl ;Store handshake flag
  440. call DOSTI ;Can allow interrupts now
  441. pop cx
  442. RecStr80:
  443. mov ax, cx
  444. or sp,sp ;Reset PSW.Z
  445. pop di
  446. pop si
  447. ret
  448. ; No characters in the input queue. Check to see if EOF
  449. ; was received, and return it if it was. Otherwise show
  450. ; no characters.
  451. RecStr90:
  452. test [si.DCB_Flags],fBinary ;Are we doing binary stuff?
  453. jnz RecStr95 ; Yes, show no characters
  454. mov al,[si.DCB_EofChar] ;Assume EOF
  455. test EFlags[si],fEOF ;Has end of file char been received?
  456. jnz RecStr80 ; Yes, show end of file
  457. RecStr95:
  458. xor ax,ax ;Show no more characters
  459. ; Return with 'Z' to show error or no characters
  460. RecStr100:
  461. xor cx,cx ;Set PSW.Z
  462. pop di
  463. pop si
  464. ret
  465. $RECSTR endp
  466. page
  467. ;----------------------------Public Routine-----------------------------;
  468. ;
  469. ; $SNDIMM - Send A Character Immediately
  470. ;
  471. ; This routine either sends a character to the port immediately,
  472. ; or places the character in a special location which is used by
  473. ; the next transmit interrupt to transmit the character prior to
  474. ; those in the normal transmit queue.
  475. ;
  476. ; For LPT ports, the character is always sent immediately.
  477. ;
  478. ; Entry:
  479. ; AH = Device ID
  480. ; AL = Character
  481. ; Returns:
  482. ; AX = 0
  483. ; Error Returns:
  484. ; AX = 8000H if Bad ID
  485. ; AX = 4000H if couldn't send because another character
  486. ; transmitted "immediately" is waiting to be sent
  487. ; Registers Destroyed:
  488. ; AX,BX,CX,DX,ES,FLAGS
  489. ; History:
  490. ;-----------------------------------------------------------------------;
  491. assumes ds,Data
  492. assumes es,nothing
  493. public $SNDIMM
  494. $SNDIMM proc near
  495. push si
  496. call GetDEB ;Get pointer to the DEB
  497. jc SendImm20 ;Bad ID, return an error
  498. jns SendImm10 ;Its a COM port
  499. ; For LPT ports, call DoLPT to do the dirty work. If DoLPT
  500. ; returns an error code, map it to 4000h.
  501. xor ch,ch ;Show xmit character
  502. call DoLPT ;Do the work here
  503. or ax,ax ;Error occur?
  504. jz SendImm20 ; No, show all is OK
  505. mov ax,4000h ; Yes, return 4000h
  506. jmp short SendImm20
  507. SendImm10:
  508. mov dl, al
  509. mov ax,4000h ;In case we cannot send
  510. test EFlags[si],fTxImmed ;Another char waiting "immediately"?
  511. jnz SendImm20 ; Yes, return error
  512. mov ah,dl ;Set char for TXI
  513. call DOCLI ;TXI is critical section code
  514. call TXI ;Set character to tx immediately
  515. call DOSTI
  516. xor ax,ax ;Show all is OK
  517. SendImm20:
  518. pop si
  519. ret
  520. $SNDIMM endp
  521. page
  522. ;----------------------------Public Routine-----------------------------;
  523. ;
  524. ; $SNDCOM - Send Byte To Port
  525. ;
  526. ; The given byte is sent to the passed port if possible.
  527. ; If the output queue is full, an error will be returned.
  528. ;
  529. ; Entry:
  530. ; AH = Device ID
  531. ; AL = Character
  532. ; Returns:
  533. ; AX = 0
  534. ; Error Returns:
  535. ; AX = error code
  536. ; Registers Destroyed:
  537. ; AX,BX,CX,DX,ES,FLAGS
  538. ; History:
  539. ;-----------------------------------------------------------------------;
  540. assumes ds,Data
  541. assumes es,nothing
  542. public $SNDCOM
  543. $SNDCOM proc near
  544. push si
  545. push di
  546. call GetDEB ;--> DEB
  547. jc SendCom40 ;Invalid ID
  548. jns SendCom20 ;Its a COM port
  549. ; Handle the transmission of a LPT character. The ROM BIOS int 17
  550. ; call will be made to do the transmission. The port address will
  551. ; be restored during the call, then zeroed out upon return.
  552. SendCom10:
  553. xor ch,ch ;Show xmit character
  554. call DoLPT ;Do the work here
  555. jmp short SendCom40 ;Return the status to caller
  556. ; Send a character to a COM port. Return an error if control
  557. ; line timeout occurs or there is no room in the output queue.
  558. SendCom20:
  559. push ax ;Save character
  560. call MSRWait ;See if lines are correct for output
  561. pop ax ;Restore char
  562. jnz SendCom60 ;Timeout occured, return error
  563. mov cx,QOutSize[si] ;See if queue is full
  564. cmp cx,QOutCount[si]
  565. jle SendCom50 ;There is no room in the queue
  566. les di,QOutAddr[si] ;--> output queue
  567. assumes es,nothing
  568. mov bx,QOutPut[si] ;Get index into queue
  569. mov es:[bx][di],al ;Store the byte
  570. inc bx ;Update index
  571. cmp bx,cx ;Wrap time?
  572. jc SendCom30 ; No
  573. xor bx,bx ;Wrap-around is a new zero pointer
  574. SendCom30:
  575. call DOCLI
  576. mov QOutPut[si],bx ;Store updated pointer
  577. mov ax,QOutCount[si] ; get the count
  578. inc ax ; have the updated value in AX for test later
  579. mov QOutCount[si],ax ;Update queue population
  580. call KickTx ;Make sure xmit interrupt is armed
  581. call DOSTI
  582. xor ax,ax ;Show no error (that we know of)
  583. ;****************************************************************************
  584. SendCom40:
  585. pop di
  586. pop si
  587. ret
  588. SendCom50:
  589. or by ComErr+1[si],HIGH CE_TXFULL
  590. .errnz LOW CE_TXFULL
  591. SendCom60:
  592. mov ax,ComErr[si] ;Return error code to caller
  593. jmp short SendCom40
  594. $SNDCOM endp
  595. page
  596. ;----------------------------Public Routine-----------------------------;
  597. ;
  598. ; $SNDCOMSTR - Send buffer To Port
  599. ;
  600. ; The given buffer is sent to the passed port if possible.
  601. ; Once the output queue is detected as being full, a CE_TXFULL error
  602. ; will be indicated and AX will be returned as the # of chars actually
  603. ; queued.
  604. ;
  605. ; Entry:
  606. ; DS:SI --> DEB
  607. ; ES:DI --> buffer
  608. ; Returns:
  609. ; AX = # of bytes queued
  610. ; Registers Destroyed:
  611. ; AX,BX,CX,DX,DI,ES,FLAGS
  612. ; History:
  613. ;-----------------------------------------------------------------------;
  614. assumes ds,Data
  615. assumes es,nothing
  616. public $SNDCOMSTR
  617. $SNDCOMSTR proc near
  618. push cx ; save count
  619. call GetDEB
  620. jc cws_error ; jump if id invalid
  621. jns cws_comm ; jump if COM port
  622. call StringToLPT
  623. pop cx ; discard saved count, ax = # transfered
  624. jmp short cws_exit
  625. cws_error:
  626. pop ax
  627. sub ax, cx ; ax = # transfered
  628. cws_exit:
  629. ret
  630. cws_comm:
  631. call MSRWait ;See if lines are correct for output
  632. pop cx
  633. push cx
  634. jnz cws_error ;Timeout occured, return error
  635. mov dx, QOutSize[si] ;See if queue is full
  636. sub dx, QOutCount[si] ; dx = # of chars free in queue
  637. jg scs_loop
  638. jmp scs_full ;There is no room in the queue
  639. scs_loop:
  640. push cx ; save count left to send
  641. cmp cx, dx ;Q: room for buffer in queue?
  642. jbe @f ; Y:
  643. mov cx, dx ; N: adjust size to send
  644. @@:
  645. push cx ; save # of chars which will be copied
  646. push si
  647. push ds
  648. push di
  649. push es
  650. les bx,QOutAddr[si] ;--> output queue
  651. assumes es,nothing
  652. mov dx, QOutSize[si]
  653. mov di, QOutPut[si] ;Get index into queue
  654. sub dx, di ; dx = # of free chars before end of queue
  655. cmp dx, cx
  656. jbe @f
  657. mov dx, cx
  658. @@:
  659. xchg cx, dx ; cx = # of chars for 1st copy
  660. sub dx, cx ; dx = # of chars for 2nd copy
  661. pop ds
  662. pop si ; ds:si -> src buffer
  663. assumes ds,nothing
  664. add di, bx ; es:di -> current pos in queue
  665. cld
  666. rep movsb ; copy first section
  667. mov cx, dx
  668. jcxz @F
  669. mov di, bx ; circle back to start of queue
  670. rep movsb ; copy 2nd section
  671. @@:
  672. sub di, bx ; di last index into queue
  673. mov dx, di
  674. mov di, si ; last location in src buffer
  675. mov si, ds
  676. mov es, si ; es:di -> last loc in src buf
  677. pop ds
  678. pop si ; ds:si -> ComDEB
  679. assumes ds,data
  680. pop bx ; # of chars copied
  681. call DOCLI
  682. mov QOutPut[si], dx ;new index into queue
  683. add QOutCount[si], bx
  684. call KickTx
  685. call DOSTI
  686. pop cx
  687. sub cx, bx ; # of chars left to send
  688. jnz scs_full_2 ; jump if none
  689. scs_exit:
  690. pop ax
  691. sub ax, cx ; ax = # transfered
  692. ret
  693. scs_full:
  694. call DOCLI
  695. call KickTx
  696. call DOSTI
  697. scs_full_2:
  698. or by ComErr+1[si],HIGH CE_TXFULL
  699. .errnz LOW CE_TXFULL
  700. jmp scs_exit
  701. $SNDCOMSTR endp
  702. page
  703. ;----------------------------Public Routine-----------------------------;
  704. ;
  705. ; $FLUSH - Flush The Input and Output Queues
  706. ;
  707. ; This is a hard initialization of the transmit and receive queue's,
  708. ; which immediately empties the given queue.
  709. ;
  710. ; LPT ports will just return the device error word
  711. ;
  712. ; Entry:
  713. ; AH = Device ID
  714. ; BH = Queue # to clear (0=Tx, 1=Rx)
  715. ; Returns:
  716. ; AX = Device Error Word. (Not reset)
  717. ; Error Returns:
  718. ; AX = error code
  719. ; Registers Preserved:
  720. ; SI,DI,DS
  721. ; Registers Destroyed:
  722. ; AX,BX,CX,DX,ES,FLAGS
  723. ; History:
  724. ;-----------------------------------------------------------------------;
  725. ;------------------------------Pseudo-Code------------------------------;
  726. ; {
  727. ; }
  728. ;-----------------------------------------------------------------------;
  729. assumes ds,Data
  730. assumes es,nothing
  731. public $FLUSH
  732. $FLUSH proc near
  733. push si
  734. push di
  735. call GetDEB ;si --> DEB
  736. jc Flush40 ;Invalid ID
  737. js Flush30 ;LPT port, return any error
  738. mov cx,QOutCount-QInCount ;# of bytes to zero
  739. lea di,QInCount[si] ;--> receive queue data
  740. or bh,bh ;Transmit queue?
  741. jnz Flush10 ; No, input queue
  742. add di,cx ; Yes, --> xmit queue data
  743. Flush10:
  744. cld
  745. push ds
  746. pop es
  747. assumes es,nothing
  748. xor al,al
  749. call DOCLI ;Time to worry about critical sections
  750. rep stosb
  751. call DOSTI
  752. .errnz QInGet-QInCount-2
  753. .errnz QInPut-QInGet-2
  754. .errnz QOutCount-QInPut-2
  755. .errnz QOutGet-QOutCount-2
  756. .errnz QOutPut-QOutGet-2
  757. or bh,bh ;Rx queue?
  758. jz Flush30 ; No, xmit queue
  759. ; If the queue to be cleared is the receive queue, any
  760. ; hardware handshake must be cleared to prevent a possible
  761. ; deadlock situation. Since we just zeroed the queue count,
  762. ; a quick call to $RecCom should do wonders to clear any
  763. ; receive handshake (i.e. send XON if needed).
  764. Flush20:
  765. call $RECCOM ;Take care of handshakes here
  766. Flush30:
  767. mov ax,ComErr[si] ;And return the error word.
  768. Flush40:
  769. pop di
  770. pop si
  771. ret
  772. $FLUSH endp
  773. page
  774. ;----------------------------Private-Routine----------------------------;
  775. ;
  776. ; TXI - Transmit A Character Immediately
  777. ;
  778. ; Set up a character to be transmitted "immediately".
  779. ; by placing the character in a location that guarantees
  780. ; it to be the next character transmitted.
  781. ;
  782. ; The check to see if the immediate character can be placed has
  783. ; already been made prior to entry.
  784. ;
  785. ; Interrupts must be disabled before entering this code
  786. ;
  787. ; Entry:
  788. ; AH = Character
  789. ; DS:SI --> DEB
  790. ; Returns:
  791. ; None
  792. ; Error Returns:
  793. ; None
  794. ; Registers Preserved:
  795. ; BX,CX,SI,DI,DS,ES
  796. ; Registers Destroyed:
  797. ; L,DX,FLAGS
  798. ; History:
  799. ;-----------------------------------------------------------------------;
  800. ;------------------------------Pseudo-Code------------------------------;
  801. ; {
  802. ; }
  803. ;-----------------------------------------------------------------------;
  804. assumes ds,Data
  805. assumes es,nothing
  806. public TXI ;Public for debugging
  807. TXI proc near
  808. ; call DOCLI ;Must be done by caller!
  809. or EFlags[si],fTxImmed ;Show char to xmit
  810. mov ImmedChar[si],ah ;Set character to transmit next
  811. ; jmp short KickTx ;Kick Xmit just in case
  812. errn$ KickTx
  813. TXI endp
  814. page
  815. ;----------------------------Private-Routine----------------------------;
  816. ;
  817. ; KickTx - Kick Transmitter
  818. ;
  819. ; "Kick" the transmitter interrupt routine into operation.
  820. ; If the Transmitter Holding Register isn't empty, then
  821. ; nothing needs to be done. If it is empty, then the xmit
  822. ; interrupt needs to enabled in the IER.
  823. ;
  824. ; Entry:
  825. ; DS:SI --> DEB
  826. ; INTERRUPTS DISABLED!
  827. ; Returns:
  828. ; None
  829. ; Error Returns:
  830. ; None
  831. ; Registers Preserved:
  832. ; BX,CX,SI,DI,DS,ES
  833. ; Registers Destroyed:
  834. ; AX,DX,FLAGS
  835. ; History:
  836. ;-----------------------------------------------------------------------;
  837. ;------------------------------Pseudo-Code------------------------------;
  838. ; {
  839. ; }
  840. ;-----------------------------------------------------------------------;
  841. assumes ds,Data
  842. assumes es,nothing
  843. public KickTx ;Public for debugging
  844. KickTx proc near
  845. ; call DOCLI ;Done by caller
  846. test [si.VCDflags], 1 ;Q: we still own port?
  847. jnz can_we_steal ; N:
  848. enable_int:
  849. mov dx,Port[si] ;Get device I/O address
  850. add dl,ACE_IER ;--> Interrupt enable register
  851. in al,dx ;Get current IER state
  852. test al,ACE_ETBEI ;Interrupt already enabled?
  853. jnz KickTx10 ; Yes, don't reenable it
  854. or al,ACE_ETBEI ; No, enable it
  855. out dx,al
  856. iodelay ;8250, 8250-B bug requires
  857. out dx,al ; writting register twice
  858. KickTx10:
  859. ; call DOSTI ;Done by caller
  860. ret
  861. can_we_steal:
  862. call StealPort ; call VCD to see if we can steal
  863. ; the port back
  864. jnc short enable_int ; jump, if we got it
  865. ;
  866. ; flush out queue
  867. ;
  868. xor ax, ax
  869. mov [si.QOutCount], ax
  870. mov [si.QOutMod], ax
  871. mov ax, [si.QOutGet]
  872. mov [si.QOutPut], ax
  873. jmp short KickTx10 ; N:
  874. KickTx endp
  875. page
  876. ;----------------------------Private-Routine----------------------------;
  877. ;
  878. ; MSRWait - Modem Status Register Wait
  879. ;
  880. ; This routine checks the modem status register for CTS, DSR,
  881. ; and/or RLSD signals. If a timeout occurs while checking,
  882. ; the appropriate error code will be returned.
  883. ;
  884. ; This routine will not check for any signal with a corresponding
  885. ; time out value of 0 (ignore line).
  886. ;
  887. ; Entry:
  888. ; SI --> DEB
  889. ; Returns:
  890. ; AL = error code
  891. ; ComErr[si] updated
  892. ; 'Z' set if no timeout
  893. ; Error Returns:
  894. ; None
  895. ; Registers Destroyed:
  896. ; AX,CX,DX,FLAGS
  897. ; History:
  898. ;-----------------------------------------------------------------------;
  899. assumes ds,Data
  900. assumes es,nothing
  901. public MSRWait ;Public for debugging
  902. MSRWait proc near
  903. push di
  904. MSRRestart:
  905. xor di,di ;Init Timer
  906. MSRWait10:
  907. mov cx,11 ;Init Delay counter (used on non-ATs)
  908. MSRWait20:
  909. xor dh,dh ;Init error accumulator
  910. mov al,MSRShadow[si] ;Get Modem Status
  911. and al,MSRMask[si] ;Only leave bits of interest
  912. xor al,MSRMask[si] ;0 = line high
  913. jz MSRWait90 ;All lines of interest are high
  914. mov ah,al ;ah has 1 bits for down lines
  915. shl ah,1 ;Line Signal Detect low?
  916. jnc MSRWait30 ; No, it's high
  917. .errnz ACE_RLSD-10000000b
  918. cmp di,[si.DCB_RlsTimeout] ;RLSD timeout yet?
  919. jb MSRWait30 ; No
  920. or dh,CE_RLSDTO ;Show modem status timeout
  921. MSRWait30:
  922. shl ah,1 ;Data Set Ready low?
  923. shl ah,1
  924. .errnz ACE_DSR-00100000b
  925. jnc MSRWait40 ; No, it's high
  926. cmp di,[si.DCB_DsrTimeout] ;DSR timeout yet?
  927. jb MSRWait40 ; No
  928. or dh,CE_DSRTO ;Show data set ready timeout
  929. MSRWait40:
  930. shl ah,1 ;CTS low?
  931. jnc MSRWait50 ; No, it's high
  932. .errnz ACE_CTS-00010000b
  933. cmp di,[si.DCB_CtsTimeout] ;CTS timeout yet?
  934. jb MSRWait50 ; No
  935. or dh,CE_CTSTO ;Show clear to send timeout
  936. MSRWait50:
  937. or dh,dh ;Any timeout occur?
  938. jnz MSRWait80 ; Yes
  939. cmp [$MachineID],0FCh ;Is this a PC-AT? [rkh debug for PS/2]
  940. je MSRWait60 ; Yes, use ROM function
  941. loop MSRWait20 ; No, continue until timeout
  942. jmp short MSRWait70 ;Should have taken about a millisecond
  943. MSRWait60:
  944. push bx ;Special SALMON ROM routine to delay
  945. push di
  946. xor cx,cx ;Number of Microseconds to delay
  947. mov dx,1000 ; in CX:DX
  948. mov ah,86h
  949. int 15h ;Wait 1 millisecond
  950. pop di
  951. pop bx
  952. MSRWait70:
  953. inc di ;Timer +1
  954. jmp short MSRWait10 ;Until Timeout or Good status
  955. MSRWait80:
  956. xor ah,ah
  957. mov al,dh
  958. or by ComErr[si],al ;Return updated status
  959. .errnz HIGH CE_CTSTO
  960. .errnz HIGH CE_DSRTO
  961. .errnz HIGH CE_RLSDTO
  962. MSRWait90:
  963. or al,al ;Set 'Z' if no timeout
  964. pop di
  965. ret
  966. MSRWait endp
  967. page
  968. ;----------------------------Public Routine-----------------------------;
  969. ;
  970. ; $EVT - Set Event Mask
  971. ;
  972. ; Set up event word and mask. Returns a pointer to a word in which
  973. ; certain bits, as enabled by the mask, will be set when certain
  974. ; events occur.
  975. ;
  976. ; Entry:
  977. ; AH = Device ID
  978. ; BX = Event enable mask
  979. ; Returns:
  980. ; DX:AX --> event word.
  981. ; Error Returns:
  982. ; AX = 0 if error
  983. ; Registers Preserved:
  984. ; BX,CX,SI,DI,DS,ES
  985. ; Registers Destroyed:
  986. ; AX,DX,FLAGS
  987. ; History:
  988. ;-----------------------------------------------------------------------;
  989. ;------------------------------Pseudo-Code------------------------------;
  990. ; {
  991. ; }
  992. ;-----------------------------------------------------------------------;
  993. assumes ds,Data
  994. assumes es,nothing
  995. public $EVT
  996. $EVT proc near
  997. push si
  998. xor dx,dx ;In case of error
  999. call GetDEB ;Get pointer to DEB
  1000. mov ax,dx ;Finish setting error return value
  1001. jc Evt10 ;Illegal id, return error
  1002. js Evt10 ;LPTx, return error
  1003. mov EvtMask[si],bx ;Save the new event mask
  1004. lea ax,EvtWord[si] ;Get address of event word
  1005. mov dx,ds ; into dx:ax
  1006. Evt10:
  1007. pop si
  1008. ret
  1009. $EVT endp
  1010. page
  1011. ;----------------------------Public Routine-----------------------------;
  1012. ;
  1013. ; $EVTGET - Get Event Word
  1014. ;
  1015. ; Return and clear fields in the event word. This routine MUST be used
  1016. ; by applications to read the event word, as it is the ONLY way they
  1017. ; can be assured that an event is not lost between reading the flags
  1018. ; and resetting some.
  1019. ;
  1020. ; Entry:
  1021. ; AH = Device ID
  1022. ; BX = Event clear mask
  1023. ; Returns:
  1024. ; AX = event word
  1025. ; Error Returns:
  1026. ; None
  1027. ; Registers Preserved:
  1028. ; AX,CX,SI,DI,DS,ES
  1029. ; Registers Destroyed:
  1030. ; BX,FLAGS
  1031. ; History:
  1032. ;-----------------------------------------------------------------------;
  1033. ;------------------------------Pseudo-Code------------------------------;
  1034. ; {
  1035. ; }
  1036. ;-----------------------------------------------------------------------;
  1037. assumes ds,Data
  1038. assumes es,nothing
  1039. public $EVTGET
  1040. $EVTGET proc near
  1041. push si
  1042. call GetDEB
  1043. mov ah,0 ;In case of error (AL already 0)
  1044. jc EvtGet10 ;Illegal ID
  1045. js EvtGet10 ;Illegal ID
  1046. call DOCLI ;No interrupts allowed
  1047. mov ax,EvtWord[si] ;Get the current event word
  1048. not bx ;Convert mask for our purposes
  1049. and bx,ax ;Clear events that user wants us to
  1050. mov EvtWord[si],bx ;And save those results
  1051. call DOSTI ;Magic over
  1052. EvtGet10:
  1053. pop si
  1054. ret
  1055. $EVTGET endp
  1056. page
  1057. ;----------------------------Public Routine-----------------------------;
  1058. ;
  1059. ; $STACOM - Return Status Information
  1060. ;
  1061. ; Returns the number of bytes in both queues.
  1062. ;
  1063. ; LPT ports will show both queues empty.
  1064. ; and resetting some.
  1065. ;
  1066. ; Entry:
  1067. ; AH = Device ID
  1068. ; ES:BX = Pointer to status structure to be updated.
  1069. ; = Null if not to update
  1070. ; Returns:
  1071. ; AX = comm error word
  1072. ; Status Structure Updated.
  1073. ; Error Returns:
  1074. ; AX = error code
  1075. ; Registers Preserved:
  1076. ; SI,DI,DS,ES
  1077. ; Registers Destroyed:
  1078. ; AX,BX,CX,DX,FLAGS
  1079. ; History:
  1080. ;-----------------------------------------------------------------------;
  1081. ;------------------------------Pseudo-Code------------------------------;
  1082. ; {
  1083. ; }
  1084. ;-----------------------------------------------------------------------;
  1085. assumes ds,Data
  1086. assumes es,nothing
  1087. public $STACOM
  1088. $STACOM proc near
  1089. push si
  1090. call GetDEB ;Get DEB pointer in SI
  1091. jc StaCom30 ;Invalid ID
  1092. mov cx,es ;Is the pointer NULL?
  1093. or cx,bx
  1094. jz StaCom25 ; Yes, just return error code
  1095. xor cx,cx
  1096. xor dx,dx
  1097. or ah,ah ;Set 'S' if LPT port
  1098. mov ax,cx ;For LPTs, everything is zero
  1099. js StaCom20 ;LPT port
  1100. ; Need to get the status for a com port. Since not all the
  1101. ; status is contained within EFlags, it has to be assembled.
  1102. ; Also note that currently there is no way to specify RLSD
  1103. ; as a handshaking line, so fRLSDHold is always returned false.
  1104. mov al,MSRShadow[si] ;Get state of hardware lines
  1105. and al,OutHHSLines[si] ;Mask off required bits
  1106. xor al,OutHHSLines[si] ;1 = line low
  1107. mov cl,4 ;Align bits
  1108. shr al,cl ;al = fCTSHold + fDSRHold
  1109. .errnz ACE_CTS-00010000b
  1110. .errnz ACE_DSR-00100000b
  1111. .errnz fCTSHold-00000001b
  1112. .errnz fDSRHold-00000010b
  1113. mov ah,HSFlag[si] ;Get fXOffHold+fXOffSent
  1114. and ah,XOffReceived+XOffSent
  1115. or al,ah
  1116. .errnz XOffReceived-fXOFFHold
  1117. .errnz XOffSent-fXOFFSent
  1118. mov ah,EFlags[si] ;Get fEOF+fTxImmed
  1119. and ah,fEOF+fTxImmed
  1120. or al,ah
  1121. mov cx,QInCount[si] ;Get input queue count
  1122. mov dx,QOutCount[si] ;Get tx queue count
  1123. StaCom20:
  1124. mov es:[bx.COMS_BitMask1],al
  1125. mov es:[bx.COMS_cbInQue],cx
  1126. mov es:[bx.COMS_cbOutQue],dx
  1127. StaCom25:
  1128. xor ax,ax ;Return old com error
  1129. xchg ax,ComErr[si] ; and clear it out
  1130. StaCom30:
  1131. pop si
  1132. ret
  1133. $STACOM endp
  1134. page
  1135. ;----------------------------Public Routine-----------------------------;
  1136. ;
  1137. ; $SetBrk - Set Break
  1138. ;
  1139. ; Clamp the Tx data line low. Does not wait for the
  1140. ; transmitter holding register and shift registers to empty.
  1141. ;
  1142. ; LPT ports will just return the comm error word
  1143. ;
  1144. ; Entry:
  1145. ; AH = Device ID
  1146. ; Returns:
  1147. ; AX = comm error word
  1148. ; Error Returns:
  1149. ; AX = error code
  1150. ; Registers Preserved:
  1151. ; SI,DI,DS,ES
  1152. ; Registers Destroyed:
  1153. ; AX,BX,CX,DX,FLAGS
  1154. ; History:
  1155. ;-----------------------------------------------------------------------;
  1156. ;------------------------------Pseudo-Code------------------------------;
  1157. ; {
  1158. ; }
  1159. ;-----------------------------------------------------------------------;
  1160. assumes ds,Data
  1161. assumes es,nothing
  1162. public $SETBRK
  1163. $SETBRK proc near
  1164. mov cx,0FF00h+ACE_SB ;Will be setting break
  1165. jmp short ClrBrk10
  1166. .errnz BreakSet-ACE_SB ;Must be same bits
  1167. $SETBRK endp
  1168. page
  1169. ;----------------------------Public Routine-----------------------------;
  1170. ;
  1171. ; $CLRBRK - Clear Break
  1172. ;
  1173. ; Release any BREAK clamp on the Tx data line.
  1174. ;
  1175. ; LPT ports will just return the comm error word
  1176. ;
  1177. ; Entry:
  1178. ; AH = Device ID
  1179. ; Returns:
  1180. ; AX = comm error word
  1181. ; Error Returns:
  1182. ; AX = error code
  1183. ; Registers Preserved:
  1184. ; SI,DI,DS,ES
  1185. ; Registers Destroyed:
  1186. ; AX,BX,CX,DX,FLAGS
  1187. ; History:
  1188. ;-----------------------------------------------------------------------;
  1189. ;------------------------------Pseudo-Code------------------------------;
  1190. ; {
  1191. ; }
  1192. ;-----------------------------------------------------------------------;
  1193. assumes ds,Data
  1194. assumes es,nothing
  1195. public $CLRBRK
  1196. $CLRBRK proc near
  1197. mov cx,(NOT ACE_SB) SHL 8
  1198. .errnz BreakSet-ACE_SB ;Must be same bits
  1199. ClrBrk10:
  1200. push si
  1201. call GetDEB ;Get DEB address
  1202. jc ClrBrk30 ;Invalid ID
  1203. js ClrBrk20 ;Ignored for LPT ports
  1204. call DOCLI
  1205. and HSFlag[si],ch ;Set or clear the BreakSet bit
  1206. or HSFlag[si],cl
  1207. ; ch = mask to remove bits in the Line Control Register
  1208. ; cl = mask to turn bits on in the Line Control Register
  1209. mov dx,Port[si] ;Get comm device base I/O port
  1210. add dl,ACE_LCR ;Point at the Line Control Regieter
  1211. in al,dx ;Get old line control value
  1212. and al,ch ;Turn off desired bits
  1213. or al,cl ;Turn on desired bits
  1214. iodelay
  1215. out dx,al ;Output New LCR.
  1216. call DOSTI
  1217. ClrBrk20:
  1218. mov ax,ComErr[si] ;Return Status Word
  1219. ClrBrk30:
  1220. pop si
  1221. ret
  1222. $CLRBRK endp
  1223. page
  1224. ;----------------------------Public Routine-----------------------------;
  1225. ;
  1226. ; $EXTCOM - Extended Comm Functions
  1227. ;
  1228. ; A number of extended functions are routed through this entry point.
  1229. ;
  1230. ; Functions currently implemented:
  1231. ;
  1232. ; 0: Ignored
  1233. ; 1: SETXOFF - Exactly as if X-OFF character has been received.
  1234. ; 2: SETXON - Exactly as if X-ON character has been received.
  1235. ; 3: SETRTS - Set the RTS signal
  1236. ; 4: CLRRTS - Clear the RTS signal
  1237. ; 5: SETDTR - Set the DTR signal
  1238. ; 6: CLRDTR - Clear the DTR signal
  1239. ; 7: RESET - Yank on reset line if available (LPT devices)
  1240. ;
  1241. ; Entry:
  1242. ; AH = Device ID
  1243. ; BL = Function Code
  1244. ; (0-127 are MS-defined, 128-255 are OEM defined)
  1245. ; Returns:
  1246. ; AX = comm error word
  1247. ; Error Returns:
  1248. ; AX = error code
  1249. ; Registers Preserved:
  1250. ; SI,DI,DS
  1251. ; Registers Destroyed:
  1252. ; AX,BX,CX,DX,ES,FLAGS
  1253. ; History:
  1254. ;-----------------------------------------------------------------------;
  1255. ;------------------------------Pseudo-Code------------------------------;
  1256. ; {
  1257. ; }
  1258. ;-----------------------------------------------------------------------;
  1259. ; Dispatch table for the extended functions
  1260. ExtTab dw ExtComDummy ;Function 0: Never Mind
  1261. dw ExtCom_FN1 ;1: Set X-Off
  1262. dw ExtCom_FN2 ;2: Clear X-Off
  1263. dw ExtCom_FN3 ;3: Set RTS
  1264. dw ExtCom_FN4 ;4: Clear RTS
  1265. dw ExtCom_FN5 ;5: Set DSR
  1266. dw ExtCom_FN6 ;6: Clear DSR
  1267. dw ExtCom_FN7 ;7: Reset printer
  1268. dw ExtCom_FN8 ;8: Get Max LPT Port
  1269. dw ExtCom_FN9 ;9: Get Max COM Port
  1270. dw ExtCom_FN10 ;10: Get COM Port Base & IRQ
  1271. dw ExtCom_FN10 ;11: Get COM Port Base & IRQ
  1272. %OUT fix this for bld 32 -- GetBaseIRQ is now 10
  1273. assumes ds,Data
  1274. assumes es,nothing
  1275. public $EXTCOM
  1276. $EXTCOM proc near
  1277. push si
  1278. push di
  1279. call GetDEB ;Get DEB pointer
  1280. jc ExtCom40 ;Invalid ID, return error
  1281. mov dx,Port[si] ; get port address
  1282. jns ExtCom10 ;Its a COM port
  1283. cmp bl,7 ;RESET extended function?
  1284. jne ExtCom30 ; No, return error word
  1285. jmp short ExtCom20 ; Yes, invoke the function
  1286. ExtCom10:
  1287. cmp bl,11 ;Last fcn supported
  1288. ja ExtCom30 ;Not an implemented function.
  1289. ExtCom20:
  1290. xor bh,bh
  1291. add bx,bx ;Shift for the call
  1292. call DOCLI ;Consider as critical sections
  1293. call ExtTab[bx] ; and perform the function
  1294. call DOSTI
  1295. jc ExtCom40 ; jump if sub returns data in DX:AX
  1296. ExtCom30:
  1297. mov ax,ComErr[si] ;Return standard error word
  1298. xor dx, dx
  1299. ExtCom40:
  1300. pop di
  1301. pop si
  1302. ret
  1303. $EXTCOM endp
  1304. page
  1305. ;----------------------------Private-Routine----------------------------;
  1306. ;
  1307. ; ExtCom_FN1 - Extended Function Set X-Off
  1308. ;
  1309. ; Analagous to receiving an X-OFF character. Bufferred transmision of
  1310. ; characters is halted until an X-ON character is received, or until
  1311. ; we fake that with a Clear X-Off call.
  1312. ;
  1313. ; Entry:
  1314. ; interrupts disabled
  1315. ; dx = port base address
  1316. ; Returns:
  1317. ; None
  1318. ; Error Returns:
  1319. ; None
  1320. ; Registers Preserved:
  1321. ; SI,DI,DS
  1322. ; Registers Destroyed:
  1323. ; AX,BX,CX,DX,ES,FLAGS
  1324. ; History:
  1325. ;-----------------------------------------------------------------------;
  1326. ;------------------------------Pseudo-Code------------------------------;
  1327. ; {
  1328. ; }
  1329. ;-----------------------------------------------------------------------;
  1330. assumes ds,Data
  1331. assumes es,nothing
  1332. public ExtCom_FN1
  1333. ExtCom_FN1 proc near
  1334. or HSFlag[si],XOffReceived
  1335. ExtComDummy:
  1336. clc
  1337. ret
  1338. ExtCom_FN1 endp
  1339. page
  1340. ;----------------------------Private-Routine----------------------------;
  1341. ;
  1342. ; ExtCom_FN2 - Extended Function Clear X-Off
  1343. ;
  1344. ; Analagous to receiving an X-ON character. Buffered
  1345. ; transmission of characters is restarted.
  1346. ;
  1347. ; Entry:
  1348. ; interrupts disabled
  1349. ; dx = port base address
  1350. ; Returns:
  1351. ; None
  1352. ; Error Returns:
  1353. ; None
  1354. ; Registers Preserved:
  1355. ; SI,DI,DS
  1356. ; Registers Destroyed:
  1357. ; AX,BX,CX,DX,ES,FLAGS
  1358. ; History:
  1359. ;-----------------------------------------------------------------------;
  1360. ;------------------------------Pseudo-Code------------------------------;
  1361. ; {
  1362. ; }
  1363. ;-----------------------------------------------------------------------;
  1364. assumes ds,Data
  1365. assumes es,nothing
  1366. public ExtCom_FN2
  1367. ExtCom_FN2 proc near
  1368. and HSFlag[si],NOT XOffReceived
  1369. call KickTx ;Kick transmitter interrupts on
  1370. clc
  1371. ret
  1372. ExtCom_FN2 endp
  1373. page
  1374. ;----------------------------Private-Routine----------------------------;
  1375. ;
  1376. ; ExtCom_FN3 - Extended Function Set RTS
  1377. ;
  1378. ; Set the RTS signal active.
  1379. ;
  1380. ; Entry:
  1381. ; interrupts disabled
  1382. ; dx = port base address
  1383. ; Returns:
  1384. ; None
  1385. ; Error Returns:
  1386. ; None
  1387. ; Registers Preserved:
  1388. ; SI,DI,DS
  1389. ; Registers Destroyed:
  1390. ; AX,BX,CX,DX,ES,FLAGS
  1391. ; History:
  1392. ;-----------------------------------------------------------------------;
  1393. ;------------------------------Pseudo-Code------------------------------;
  1394. ; {
  1395. ; }
  1396. ;-----------------------------------------------------------------------;
  1397. assumes ds,Data
  1398. assumes es,nothing
  1399. public ExtCom_FN3
  1400. ExtCom_FN3 proc near
  1401. add dl,ACE_MCR ;Point at Modem Control Register
  1402. in al,dx ;Get current settings
  1403. or al,ACE_RTS ;Set RTS
  1404. iodelay
  1405. out dx,al ;And update
  1406. clc
  1407. ret
  1408. ExtCom_FN3 endp
  1409. page
  1410. ;----------------------------Private-Routine----------------------------;
  1411. ;
  1412. ; ExtCom_FN4 - Extended Function Clear RTS
  1413. ;
  1414. ; Set the RTS signal inactive.
  1415. ;
  1416. ; Entry:
  1417. ; interrupts disabled
  1418. ; dx = port base address
  1419. ; Returns:
  1420. ; None
  1421. ; Error Returns:
  1422. ; None
  1423. ; Registers Preserved:
  1424. ; SI,DI,DS
  1425. ; Registers Destroyed:
  1426. ; AX,BX,CX,DX,ES,FLAGS
  1427. ; History:
  1428. ;-----------------------------------------------------------------------;
  1429. ;------------------------------Pseudo-Code------------------------------;
  1430. ; {
  1431. ; }
  1432. ;-----------------------------------------------------------------------;
  1433. assumes ds,Data
  1434. assumes es,nothing
  1435. public ExtCom_FN4
  1436. ExtCom_FN4 proc near
  1437. add dl,ACE_MCR ;Point at Modem Control Register
  1438. in al,dx ;Get current settings
  1439. and al,NOT ACE_RTS ;Clear RTS
  1440. iodelay
  1441. out dx,al ;And update
  1442. clc
  1443. ret
  1444. ExtCom_FN4 endp
  1445. page
  1446. ;----------------------------Private-Routine----------------------------;
  1447. ;
  1448. ; ExtCom_FN5 - Extended Function Set DTR
  1449. ;
  1450. ; Set the DTR signal active.
  1451. ;
  1452. ; Entry:
  1453. ; interrupts disabled
  1454. ; dx = port base address
  1455. ; Returns:
  1456. ; None
  1457. ; Error Returns:
  1458. ; None
  1459. ; Registers Preserved:
  1460. ; SI,DI,DS
  1461. ; Registers Destroyed:
  1462. ; AX,BX,CX,DX,ES,FLAGS
  1463. ; History:
  1464. ;-----------------------------------------------------------------------;
  1465. ;------------------------------Pseudo-Code------------------------------;
  1466. ; {
  1467. ; }
  1468. ;-----------------------------------------------------------------------;
  1469. assumes ds,Data
  1470. assumes es,nothing
  1471. public ExtCom_FN5
  1472. ExtCom_FN5 proc near
  1473. add dl,ACE_MCR ;Point at Modem Control Register
  1474. in al,dx ;Get current settings
  1475. or al,ACE_DTR ;Set DTR
  1476. iodelay
  1477. out dx,al ;And update
  1478. clc
  1479. ret
  1480. ExtCom_FN5 endp
  1481. page
  1482. ;----------------------------Private-Routine----------------------------;
  1483. ;
  1484. ; ExtCom_FN6 - Extended Function Clear DTR
  1485. ;
  1486. ; Set the DTR signal inactive.
  1487. ;
  1488. ; Entry:
  1489. ; interrupts disabled
  1490. ; dx = port base address
  1491. ; Returns:
  1492. ; None
  1493. ; Error Returns:
  1494. ; None
  1495. ; Registers Preserved:
  1496. ; SI,DI,DS
  1497. ; Registers Destroyed:
  1498. ; AX,BX,CX,DX,ES,FLAGS
  1499. ; History:
  1500. ;-----------------------------------------------------------------------;
  1501. ;------------------------------Pseudo-Code------------------------------;
  1502. ; {
  1503. ; }
  1504. ;-----------------------------------------------------------------------;
  1505. assumes ds,Data
  1506. assumes es,nothing
  1507. public ExtCom_FN6
  1508. ExtCom_FN6 proc near
  1509. add dl,ACE_MCR ;Point at Modem Control Register
  1510. in al,dx ;Get current settings
  1511. and al,NOT ACE_DTR ;Clear DTR
  1512. iodelay
  1513. out dx,al ;And update
  1514. clc
  1515. ret
  1516. ExtCom_FN6 endp
  1517. page
  1518. ;----------------------------Private-Routine----------------------------;
  1519. ;
  1520. ; ExtCom_FN7 - Extended Function Reset Printer
  1521. ;
  1522. ; Assert the RESET line on an LPT port
  1523. ;
  1524. ; Entry:
  1525. ; interrupts disabled
  1526. ; dx = port base address
  1527. ; Returns:
  1528. ; None
  1529. ; Error Returns:
  1530. ; None
  1531. ; Registers Preserved:
  1532. ; SI,DI,DS
  1533. ; Registers Destroyed:
  1534. ; AX,BX,CX,DX,ES,FLAGS
  1535. ; History:
  1536. ;-----------------------------------------------------------------------;
  1537. ;------------------------------Pseudo-Code------------------------------;
  1538. ; {
  1539. ; }
  1540. ;-----------------------------------------------------------------------;
  1541. assumes ds,Data
  1542. assumes es,nothing
  1543. public ExtCom_FN7
  1544. ExtCom_FN7 proc near
  1545. call DOSTI ;Not called at interrupt time
  1546. mov ch,1 ;ROM BIOS Reset Port
  1547. call DoLPT ;Perform the function
  1548. clc
  1549. ret
  1550. ExtCom_FN7 endp
  1551. page
  1552. ;----------------------------Private-Routine----------------------------;
  1553. ;
  1554. ; ExtCom_FN8 - Get Num Ports
  1555. ;
  1556. ; Entry:
  1557. ; Returns:
  1558. ; AX = Max LPT port id
  1559. ; DX = 0
  1560. ; Error Returns:
  1561. ; None
  1562. ; Registers Preserved:
  1563. ; SI,DI,DS
  1564. ; Registers Destroyed:
  1565. ; AX,BX,CX,DX,ES,FLAGS
  1566. ; History:
  1567. ;-----------------------------------------------------------------------;
  1568. ;------------------------------Pseudo-Code------------------------------;
  1569. ; {
  1570. ; }
  1571. ;-----------------------------------------------------------------------;
  1572. assumes ds,Data
  1573. assumes es,nothing
  1574. public ExtCom_FN8
  1575. ExtCom_FN8 proc near
  1576. mov ax, MAXLPT + LPTx
  1577. xor dx, dx
  1578. stc
  1579. ret
  1580. ExtCom_FN8 endp
  1581. page
  1582. ;----------------------------Private-Routine----------------------------;
  1583. ;
  1584. ; ExtCom_FN9 - Get Max COM Port
  1585. ;
  1586. ; Entry:
  1587. ; Returns:
  1588. ; AX = Max COM port id
  1589. ; DX = 0
  1590. ; Error Returns:
  1591. ; None
  1592. ; Registers Preserved:
  1593. ; SI,DI,DS
  1594. ; Registers Destroyed:
  1595. ; AX,BX,CX,DX,ES,FLAGS
  1596. ; History:
  1597. ;-----------------------------------------------------------------------;
  1598. ;------------------------------Pseudo-Code------------------------------;
  1599. ; {
  1600. ; }
  1601. ;-----------------------------------------------------------------------;
  1602. assumes ds,Data
  1603. assumes es,nothing
  1604. public ExtCom_FN9
  1605. ExtCom_FN9 proc near
  1606. mov ax, MAXCOM
  1607. xor dx, dx
  1608. stc
  1609. ret
  1610. ExtCom_FN9 endp
  1611. page
  1612. ;----------------------------Private-Routine----------------------------;
  1613. ;
  1614. ; ExtCom_FN10 - Get COM Port Bas & IRQ
  1615. ;
  1616. ; Entry:
  1617. ; AH = com id
  1618. ; DS:SI -> DEB
  1619. ; Returns:
  1620. ; AX = base
  1621. ; DX = irq
  1622. ; Error Returns:
  1623. ; None
  1624. ; Registers Preserved:
  1625. ; DS
  1626. ; Registers Destroyed:
  1627. ; AX,BX,CX,DX,DI,ES,FLAGS
  1628. ; History:
  1629. ;-----------------------------------------------------------------------;
  1630. ;------------------------------Pseudo-Code------------------------------;
  1631. ; {
  1632. ; }
  1633. ;-----------------------------------------------------------------------;
  1634. assumes ds,Data
  1635. assumes es,nothing
  1636. public ExtCom_FN10
  1637. ExtCom_FN10 proc near
  1638. call FindCOMPort
  1639. stc
  1640. ret
  1641. ExtCom_FN10 endp
  1642. page
  1643. ifdef DEBUG
  1644. public RecCom40, RecCom50, RecCom60, RecCom70, RecCom80
  1645. public RecCom90, RecCom95, RecCom100
  1646. public SendImm10, SendImm20,
  1647. public SendCom10, SendCom20, SendCom30, SendCom40, SendCom50, SendCom60
  1648. public Flush10, Flush20, Flush30, Flush40
  1649. public KickTx10
  1650. public Evt10
  1651. public EvtGet10
  1652. public StaCom20, StaCom25, StaCom30
  1653. public ClrBrk10, ClrBrk20, ClrBrk30
  1654. public ExtCom10, ExtCom20, ExtCom30, ExtCom40, ExtComDummy
  1655. public MSRRestart, MSRWait10, MSRWait20, MSRWait30, MSRWait40
  1656. public MSRWait50, MSRWait60, MSRWait70, MSRWait80, MSRWait90
  1657. endif
  1658. DOSTI proc near
  1659. FSTI
  1660. ret
  1661. DOSTI endp
  1662. DOCLI proc near
  1663. FCLI
  1664. ret
  1665. DOCLI endp
  1666. sEnd code
  1667. End