Source code of Windows XP (NT5)
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.

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