home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / ATCOM / ATMVDM.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  45KB  |  1,455 lines

  1. ;*DDK*************************************************************************/
  2. ;
  3. ; COPYRIGHT (C) Microsoft Corporation, 1989
  4. ; COPYRIGHT    Copyright (C) 1995 IBM Corporation
  5. ;
  6. ;    The following IBM OS/2 WARP source code is provided to you solely for
  7. ;    the purpose of assisting you in your development of OS/2 WARP device
  8. ;    drivers. You may use this code in accordance with the IBM License
  9. ;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
  10. ;    Copyright statement may not be removed.;
  11. ;*****************************************************************************/
  12. ;       SCCSID = @(#)atmvdm.asm 6.14 92/03/21
  13. ; ***************************************************************************
  14. ; *
  15. ; *
  16. ; *
  17. ; ***************************************************************************
  18.  
  19. ;;********************** START OF SPECIFICATIONS *********************
  20. ;;*
  21. ;;* SOURCE FILE NAME:  ATMVDM.ASM
  22. ;;*
  23. ;;* DESCRIPTIVE NAME:  PCOM MVDM support Routines
  24. ;;*
  25. ;;* STATUS: RELEASE 2  LEVEL 0
  26. ;;*
  27. ;;* FUNCTION: This module contains the main VCOM entry point for
  28. ;;*           the COM01.SYS.  Also included are the major subroutines that
  29. ;;*           handle the IOCTL and high speed read/write routines for VCOM
  30. ;;*           support.
  31. ;;*
  32. ;;*           For IOCTL support, a semaphore is used to assure the TX Q is
  33. ;;*           empty BEFORE allowing the IOCTL to proceed.  The main
  34. ;;*           strategy routine (Com_Strat) is called after setting up a
  35. ;;*           request packet and all registers.
  36. ;;*
  37. ;;*           This is the Asyncronous Communcications Device Driver for the
  38. ;;*           PS/2 systems.  It is based on the design put forth in DCR 29.
  39. ;;*           developed by IBM.
  40. ;;*
  41. ;;* NOTES:
  42. ;;*    DEPENDENCIES: ABIOS MUST BE PRESENT
  43. ;;*    RESTRICTIONS: Supports only COM1 and COM2 handles
  44. ;;*    PATCH LABEL:  0
  45. ;;*
  46. ;;* ENTRY POINTS:  PCOMEntryVDM, PCOMStackEntry
  47. ;;*
  48. ;;* EXTERNAL REFERENCES:
  49. ;;*
  50. ;;*
  51. ;;*********************** END OF SPECIFICATIONS **********************
  52. ;
  53. ;
  54. ;       Modification History
  55. ;
  56. ;       ACW     04/16/91        @PVW Added perfview counters/timers
  57. ;       YN      08/28/91        CP20PB726006
  58. ;       DJB     08/10/93        @DB70730 - Clear out packet status field before
  59. ;                               calling ComStrat on open call
  60. ;       WDM     04/21/94        82548 - pvwxport.inc now included in atcom.inc
  61. ;
  62.  
  63. ;
  64. ;  82548   include pvwxport.inc            ;@PVW
  65. include atcom.inc
  66. .xlist
  67. include devhlp.inc
  68. include devsym.inc
  69. include basemaca.inc
  70. include oldmaca.inc
  71. include error.inc
  72. include infoseg.inc
  73. include filemode.inc
  74. include gas.inc
  75. .list
  76.  
  77.         extrn   Com1:word
  78.         extrn   Com2:word
  79.         extrn   Rx_Notify:near
  80.         extrn   Tx_Notify:near
  81.         extrn   Ms_Notify:near
  82.         extrn   ProcBlock:near
  83.         extrn   CheckTX:near
  84.         extrn   ComputeWTO:near
  85.         extrn   ComputeRTO:near
  86.  
  87. EXTRN   Rx_Notify:NEAR
  88. EXTRN   Tx_Notify:NEAR
  89. EXTRN   Ms_Notify:NEAR
  90.  
  91. EXTRN   ProcBlock:NEAR
  92. EXTRN   CheckTX:NEAR
  93. EXTRN   ComputeWTO:NEAR
  94. EXTRN   ComputeRTO:NEAR
  95.  
  96. EXTRN   Com1Strat:FAR
  97. EXTRN   Com2Strat:FAR
  98. EXTRN   Com3Strat:FAR
  99. EXTRN   Com4Strat:FAR
  100.  
  101. EXTRN   Com1:WORD
  102. EXTRN   Com2:WORD
  103. EXTRN   Com3:WORD
  104. EXTRN   Com4:WORD
  105.  
  106. EXTRN   VCOMAddress:FAR
  107.  
  108. CSEG    SEGMENT
  109.         ASSUME cs:CSEG
  110. ;;********************** START OF SPECIFICATIONS *********************
  111. ;;*
  112. ;;* SUBROUTINE NAME: PCOMEntryVDM
  113. ;;*
  114. ;;* DESCRIPTIVE NAME: Communication Device Driver VCOM Service Entry Point
  115. ;;*
  116. ;;* FUNCTION:  This entry point is used by the VCOM to communicate with the
  117. ;;*      Async hardware via this device driver.  VCOM calls this entry point
  118. ;;*      to write data to the hardware, read data from the hardware and to
  119. ;;*      otherwise manipulate the hardware (setup, reset, etc.)
  120. ;;*
  121. ;;*      On entry to this routine, the command type is checked and a call
  122. ;;*      is made to either the service routine (VDMWriteByte or VDMReadByte) or the
  123. ;;*      main IOCTL entry point (ComStrat).
  124. ;;*
  125. ;;* NOTES:       ABIOS MUST BE PRESENT
  126. ;;*
  127. ;;* ENTRY POINTS:  PCOMEntryVDM
  128. ;;*
  129. ;;* LINKAGE:     Far 16:32
  130. ;;*
  131. ;;* INPUT:  AX    = command
  132. ;;*         Dl    = port number
  133. ;;*         Bx, Cx are defined on a per command basis
  134. ;;*         ES:Si = pointer to input data
  135. ;;*         ES:Di = pointer to output data
  136. ;;*
  137. ;;* OUTPUT: command based
  138. ;;*
  139. ;;*         if AX = 1    (Open Port)
  140. ;;*            Dl = port number
  141. ;;*            CX = 0    if normal open
  142. ;;*            CX = 1    if no IRQ open
  143. ;;*
  144. ;;*         returns:
  145. ;;*            AX = 0 if no error
  146. ;;*            AX = 1 if general error (Protect mode conflict)
  147. ;;*            AX = 2 if Com in use by a different DD (cannot get LID)
  148. ;;*            AX = 3 if Com not installed
  149. ;;*
  150. ;;*
  151. ;;*         if AX = 2    (Close Port)
  152. ;;*            Dl = port number
  153. ;;*
  154. ;;*         returns:
  155. ;;*            AX = error, if any (0 if no error)
  156. ;;*
  157. ;;*
  158. ;;*         if AX = 3    (Get Byte)
  159. ;;*            Dl = port number
  160. ;;*
  161. ;;*         returns:
  162. ;;*            Ah = character
  163. ;;*            Al = character's LSR
  164. ;;*            Cl = more data indicator (1 - MORE_TO_COME)
  165. ;;*
  166. ;;*
  167. ;;*         if AX = 4  (Put Byte)
  168. ;;*            Dl = port number
  169. ;;*            Bl = character
  170. ;;*
  171. ;;*         returns:
  172. ;;*            Cl = more room indicator
  173. ;;*                 Bit 0 : more room in TxQueue (1 - TRUE)
  174. ;;*                 Bit 1 - 7 Reserved, set to 0
  175. ;;*
  176. ;;*
  177. ;;*         if AX = 5    (Get DLL/DLM value)
  178. ;;*            Dl = port number
  179. ;;*
  180. ;;*         returns:
  181. ;;*            Cl = DLL value
  182. ;;*            Ch = DLM value
  183. ;;*
  184. ;;*
  185. ;;*         if AX = 6    (Put DLL/DLM value)
  186. ;;*            Dl = port number
  187. ;;*            Cl = DLL value
  188. ;;*            Ch = DLM value
  189. ;;*
  190. ;;*         returns:
  191. ;;*            none
  192. ;;*
  193. ;;*
  194. ;;*         if AX = 46h  (Set MCR)
  195. ;;*            Dl = port number
  196. ;;*         ES:Si = pointer to input data
  197. ;;*         ES:Di = pointer to output data
  198. ;;*
  199. ;;*         command specific input data:
  200. ;;*
  201. ;;*            DB        Mask on
  202. ;;*            DB        Mask off
  203. ;;*
  204. ;;*         returns:
  205. ;;*         (command specific output data)
  206. ;;*            DW        COM Error code
  207. ;;*
  208. ;;*
  209. ;;*         if AX = 42h  (Set LCR)
  210. ;;*            Dl = port number
  211. ;;*         ES:Si = pointer to input data
  212. ;;*         ES:Di = pointer to output data
  213. ;;*
  214. ;;*         command specific input data:
  215. ;;*            DW        Number of data bits
  216. ;;*                DW    Parity
  217. ;;*                     DW       Stop bits
  218. ;;*
  219. ;;*             returns:
  220. ;;*             (command specific output data)
  221. ;;*                     none
  222. ;;*
  223. ;;*
  224. ;;*             if AX = 4Bh  (Set Break ON)
  225. ;;*                     Dl = port number
  226. ;;*             ES:Si = pointer to input data
  227. ;;*             ES:Di = pointer to output data
  228. ;;*
  229. ;;*         command specific input data:
  230. ;;*            None
  231. ;;*
  232. ;;*         returns:
  233. ;;*         (command specific output data)
  234. ;;*            DW        COM Error code
  235. ;;*
  236. ;;*
  237. ;;*         if AX = 45h  (Set Break OFF)
  238. ;;*            Dl = port number
  239. ;;*         ES:Si = pointer to input data
  240. ;;*         ES:Di = pointer to output data
  241. ;;*
  242. ;;*         command specific input data:
  243. ;;*            None
  244. ;;*
  245. ;;*         returns:
  246. ;;*         (command specific output data)
  247. ;;*            DW        COM Error code
  248. ;;*
  249. ;;*
  250. ;;*         if AX = 62h  (Get LCR value)
  251. ;;*            Dl = port number
  252. ;;*         ES:Si = pointer to input data
  253. ;;*         ES:Di = pointer to output data
  254. ;;*
  255. ;;*         command specific input data:
  256. ;;*            none
  257. ;;*
  258. ;;*         returns:
  259. ;;*         (command specific output data)
  260. ;;*            DB        Data bits
  261. ;;*            DB        Parity
  262. ;;*            DB        Stop Bits
  263. ;;*            DB        Transmitting Break
  264. ;;*
  265. ;;*
  266. ;;*         if AX = 66h  (Get MCR value)
  267. ;;*            Dl = port number
  268. ;;*         ES:Si = pointer to input data
  269. ;;*         ES:Di = pointer to output data
  270. ;;*
  271. ;;*         command specific input data:
  272. ;;*            none
  273. ;;*
  274. ;;*         returns:
  275. ;;*         (command specific output data)
  276. ;;*            DB        MCR bits 0 and 1 (DTR and RTS)
  277. ;;*                      MCR bits 2 to 7 are undefined
  278. ;;*
  279. ;;*
  280. ;;*         if AX = 67h  (Get MSR value)
  281. ;;*            Dl = port number
  282. ;;*         ES:Si = pointer to input data
  283. ;;*         ES:Di = pointer to output data
  284. ;;*
  285. ;;*         command specific input data:
  286. ;;*            none
  287. ;;*
  288. ;;*         returns:
  289. ;;*         (command specific output data)
  290. ;;*            DB        MSR value
  291. ;;*                      Bits 0 to 3     undefined
  292. ;;*                      Bit 4           Clear to send (CTS)
  293. ;;*                      Bit 5           Data set ready (DSR)
  294. ;;*                      Bit 6           Ring indicator (RI)
  295. ;;*                      Bit 7           Data carrier detect (DCD)
  296. ;;*
  297. ;;*
  298. ;;* EXIT-NORMAL: AX = 0
  299. ;;*
  300. ;;* EXIT_ERROR:  AX = 1
  301. ;;*
  302. ;;* EFFECTS:
  303. ;;*      ComInfo - Data Structure for a Com port
  304. ;;*      Request Packet - Request packet for a Async Device Driver function
  305. ;;*
  306. ;;* INTERNAL REFERENCES:
  307. ;;*      Com1Strat and Com2Strat to process IOCTL commands
  308. ;;*      VDMWriteByte                           to write 1 character
  309. ;;*      VDMReadByte                           to read 1 character
  310. ;;*      VDMGetDLLDLM                    to return the DLL/DLM values
  311. ;;*      VDMSetDLLDLM                    to update the DLL/DLM values
  312. ;;*      Rx_Notify                       to see if an RX Interrupt should be
  313. ;;*                                      reflected at this time (was defered)
  314. ;;*      Tx_Notify                       to see if a TX Interrupt should be
  315. ;;*                                      reflected at this time (was defered)
  316. ;;*      INT_Notify              Macro to see if a TX or RX Interrupt should
  317. ;;*                                    be reflected at this time (was defered)
  318. ;;*
  319. ;;* EXTERNAL REFERENCES:
  320. ;;*      DevHlp_SemClear  - release the system semaphore
  321. ;*
  322. ;;*********************** END OF SPECIFICATIONS **********************
  323. ;
  324. ;
  325. ;PCOMEntryVDM:
  326. Procedure PCOMEntryVDM,FAR
  327. ;
  328. ;    Save all used registers (except AX)
  329.         .386
  330.         SaveReg <esi,edi,es,ds,ebx,edx,ebp>
  331.         .286
  332. ;
  333. ;    Get DS addressability
  334.         setDS   DSEG
  335. ;
  336. ;    Select (Command type)
  337. ;
  338. ;        Case (Get Byte - 3):
  339. pev060:
  340.         cmp     ax,3
  341.         jne     pev080
  342. ;            get correct ComInfo (DL = Port Number)
  343.         call    DLtoComInfo
  344. ifdef PERFVIEW
  345.         pvw_Read START                  ;@PVW start timer
  346. endif
  347. ;            call VDMReadByte           ; get byte and status from Rx queues
  348. ;       NOTE:   Exits with interrupts disabled to not cause reentrancy
  349. ;               problems in VCOM
  350.         call    VDMReadByte
  351. ifdef PERFVIEW
  352.         pvw_Read STOP,VDMCOUNTERS       ;@PVW stop timer, inc num_reads,
  353. endif
  354.                                         ;@PVW update bytes read
  355. ;            Break
  356.         jmp     pev200
  357. ;
  358. ;        Case (Put Byte - 4):
  359. pev080:
  360.         cmp     ax,4
  361.         jne     pev020
  362. ;            get correct ComInfo (DL = Port Number)
  363.         call    DLtoComInfo
  364. ifdef PERFVIEW
  365.         pvw_Write START                 ;@PVW start timer
  366. endif
  367. ;            call VDMWriteByte          ; put byte at end of Tx queue
  368.         call    VDMWriteByte
  369. ;            call Rx_Notify             ; see if Rx int should be reflected
  370.         call    Rx_Notify
  371. ifdef PERFVIEW
  372.         pvw_Write STOP,VDMCOUNTERS      ;@PVW stop timer, inc num_writes,
  373. endif
  374.                                         ;@PVW update bytes written
  375. ;            Break
  376.         jmp     pev200
  377. ;
  378. ;        Case (Open Port - 1):
  379. pev020:
  380.         cmp     ax,1
  381.         ljne    pev040
  382. ;            get correct ComInfo (DL = Port Number)
  383.         call    DLtoComInfo
  384. ;            IF (ComInfo != 0)
  385.         or      si,si
  386.         jz      pev033
  387. ;            THEN
  388. ;                IF (OpenCount != 0)     ; see if port already in use
  389. ;       cmp     [si].ci_nopens,0
  390. ;       je      pev030                   ;|----Fix for CP20PB726384
  391. ;                THEN                    ;|
  392. ;                    AX = 1              ; VDM-Protect mode app conflict
  393. ;       mov     ax,1                     ;|
  394. ;       jmp     pev035                   ;|----Fix for CP20PB726384
  395. ;                ELSE
  396. pev030:
  397. ;                    ComInfo.VDM_flag.InUse = TRUE
  398.         or      [si].ci_vdm_flag,VDM_Flag_InUse
  399.         cmp     cx,0
  400.         je      pev031
  401.         or      [si].ci_vdm_flag,VDM_Flag_No_IRQ_Open
  402. pev031:
  403. ;                    Fill in Request packet
  404.         mov     [si].ci_req_pack.IPcommand,Open_Command
  405.         mov     [si].ci_req_pack.IPlen,req_Header+2
  406.         mov     [si].ci_req_pack.PktStatus,0                    ; @DB70730 - Clear out the status field
  407. ;                    Set correct parameters for call (ES:BX -> Packet)
  408.         cli
  409.         push    ax
  410.         mov     al,[si].ci_dcb_flags1
  411.         and     al,NOT F1_OUT_DCD_FLOW  ; ODCD=OFF
  412.         mov     [si].ci_dcb_flags1,al
  413.         pop     ax
  414.         sti
  415.         push    ds
  416.         pop     es
  417.         lea     bx,[si].ci_req_pack
  418. ;                    call (FAR) ComStrat            ; call strategy routine
  419.         Call_Strat
  420. ;                    AX = 0                         ; set AX to NO ERROR
  421.         mov     ax,0
  422. ;                  IF Request_packet.status = error ; if an open error occurred
  423.         cmp     [si].ci_req_pack.IPstatus,0
  424.         jne      pev035
  425. ;                    THEN
  426. ;                        AX = ComInfo.VDM_OpenError  ; set the error code
  427.         mov     ax,[si].ci_vdm_OpenError
  428. ;                    ENDIF
  429. ;                ENDIF
  430.         jmp     short pev035
  431. ;            ELSE
  432. pev033:
  433. ;                AX = COMx_NOT_INSTALLED (3)
  434.         mov     ax,3                            ; COMx not installed
  435. ;            ENDIF
  436. pev035:
  437. ;
  438.         cmp     [si].ci_req_pack.IPstatus,STDON OR STERR OR ERROR_I24_GEN_FAILURE
  439.         jne     pev036
  440.         mov     ax,2
  441.  
  442. pev036:
  443.         cmp     [si].ci_req_pack.IPstatus,STDON OR STERR OR ERROR_I24_DEVICE_IN_USE
  444.         jne     pev037
  445.         mov     ax,2
  446.  
  447. pev037:
  448. ;            Break
  449.         jmp     pev200
  450. ;
  451. ;        Case (Close Port - 2):
  452. pev040:
  453.         cmp     ax,2
  454.         ljne     pev100
  455. ;            get correct ComInfo (DL = Port Number)
  456.         call    DLtoComInfo
  457. ;       set TX/RX to state 1 and enable transmit to empty TX buffer
  458.         mov     [si].ci_vdm_Tx_State,1
  459.         mov     [si].ci_vdm_Rx_State,1
  460.         cli                             ;@@ disable
  461.         call    CheckTX                 ; start Tx if conditions permit........
  462.  
  463. ;            Fill in IOCTL Request packet
  464.         lea     di,[si].ci_req_pack     ; make ES:DI -> req packet for block
  465.         mov     ax,ds
  466.         mov     es,ax
  467.         mov     es:[di].IPcommand,Close_Command
  468.         mov     es:[di].IPlen,req_Header+2
  469.         mov     cx,VDM_TERM_TIMEOUT     ; (dx:cx) = time out
  470.         xor     dx,dx
  471.  
  472. ;            IF (Tx Queue not empty)
  473.         cli
  474.         mov     ax,[si].ci_qout.ioq_count ; ax = size of output queue
  475.         cmp     ax,0
  476.         je      pev041                  ; user data in queue, request not done
  477. ;            THEN
  478. ;                Block this request
  479.         mov     [si].ci_vdm_Blocked_IOCTL._hi,es
  480.         mov     [si].ci_vdm_Blocked_IOCTL._lo,di
  481.         or      [si].ci_vdm_flag,VDM_Flag_Blocked_IOCTL
  482.         call    ProcBlock
  483. ;            ENDIF
  484. pev041:
  485.  
  486.         sti
  487. ;            Set correct parameters for call (ES:BX -> IOCTL Packet)
  488.         mov     bx,di
  489.  
  490. ;PB732220   force cleanup for this port
  491.         mov     [si].ci_nopens,1             ; Per request of Phil Doragh to
  492.                                              ; restore the line
  493. ;            call (FAR) ComStrat             ; call strategy routine
  494.         Call_Strat
  495. ;            ComInfo.vdm_flag.InUse = FALSE
  496.         and     [si].ci_vdm_flag,NOT VDM_Flag_InUse
  497.         and     [si].ci_vdm_flag,NOT VDM_Flag_No_IRQ_Open
  498. ;            IF Request_pack.status = error
  499.         cmp     [si].ci_req_pack.IPstatus,0
  500.         jne     pev058
  501. ;            THEN
  502. ;                AX = 1
  503.         mov     ax,1
  504.         jmp     short pev059
  505. ;            ELSE
  506. pev058:
  507. ;                AX = 0
  508.         mov     ax,0
  509. ;            ENDIF
  510. pev059:
  511. ;            Break
  512.         jmp     pev200
  513. ;
  514. ;        Case (Get DLL/DLM - 5):
  515. pev100:
  516.         cmp     ax,5
  517.         jne     pev120
  518. ;            get correct ComInfo (DL = Port Number)
  519.         call    DLtoComInfo
  520.  
  521.         call    WaitForOutPut           ; wait for TX queue to empty
  522.  
  523. ;            call VDMGetDLLDLM           ; get DLL/DLM from hardware
  524.         call    VDMGetDLLDLM
  525. ;            INT_Notify          ; Macro to see if any ints should be relected
  526.         INT_Notify
  527. ;            Break
  528.         jmp     pev200
  529. ;
  530. ;        Case (Set DLL/DLM - 6):
  531. pev120:
  532.         cmp     ax,6
  533.         jne     pev140
  534. ;            get correct ComInfo (DL = Port Number)
  535.         call    DLtoComInfo
  536.  
  537.         call    WaitForOutPut           ; wait for TX queue to empty
  538.  
  539. ;            call VDMSetDLLDLM           ; set DLL/DLM in hardware
  540.         call    VDMSetDLLDLM
  541. ;            INT_Notify          ; Macro to see if any ints should be relected
  542.         INT_Notify
  543. ;            Break
  544.         jmp     pev200
  545. ;
  546. pev140:
  547. ;            get correct ComInfo (DL = Port Number)
  548.         mov     bx,si
  549.         call    DLtoComInfo
  550. ;            Fill in IOCTL Request packet
  551. ;                    (Data Pointer, Parameter Pointer)
  552.         Fill_IOCTL      es,di,es,bx
  553. ;        Case (IOCTL Set LCR       - 42h):
  554.         cmp     ax,42h
  555.         jne      pev141
  556. ;            Set data pointer to NULL
  557.         Set_Data        NULL,NULL
  558.         jmp     pev160
  559. pev141:
  560. ;        Case (IOCTL Set Break OFF - 45h):
  561.         cmp     ax,45h
  562.         jne      pev142
  563. ;            Set parameter pointer to NULL
  564.         Set_Para        NULL,NULL
  565.         jmp     pev160
  566. pev142:
  567. ;        Case (IOCTL Set MCR       - 46h):
  568.         cmp     ax,46h
  569.         jne      pev143
  570.         jmp     pev170          ;BUGBUG don't worry about TX Q
  571. ;       jmp     pev160
  572. pev143:
  573. ;        Case (IOCTL Set Break ON  - 4Bh):
  574.         cmp     ax,4bh
  575.         jne      pev144
  576. ;            Set parameter pointer to NULL
  577.         Set_Para        NULL,NULL
  578.         jmp     pev160
  579. pev144:
  580. ;        Case (IOCTL Get LCR       - 62h):
  581.         cmp     ax,62h
  582.         jne      pev145
  583. ;            Set parameter pointer to NULL
  584.         Set_Para        NULL,NULL
  585.         jmp     short pev160
  586. pev145:
  587. ;        Case (IOCTL Get MCR       - 66h):
  588.         cmp     ax,66h
  589.         jne      pev146
  590. ;            Set parameter pointer to NULL
  591.         Set_Para        NULL,NULL
  592.         jmp     short pev160
  593. pev146:
  594. ;        Case (IOCTL Get MSR       - 67h):
  595.         cmp     ax,67h
  596.         ljne     pev180
  597. ;            Set parameter pointer to NULL
  598.         Set_Para        NULL,NULL
  599. pev160:
  600.         ; wait for TX queue to empty
  601.         call    WaitForOutPut
  602. pev170:
  603. ;            Set correct parameters for call (ES:BX -> IOCTL Packet)
  604.         mov     bx,ds
  605.         mov     es,bx
  606.         lea     bx,[si].ci_req_pack
  607. ;            call (FAR) ComStrat             ; call strategy routine
  608.         Call_Strat
  609. ;            IF Request_packet.status = error
  610.         cmp     [si].ci_req_pack.IPstatus,0
  611.         jne     pev178
  612. ;                AX = 1
  613.         mov     ax,1
  614.         jmp     short pev179
  615. ;            ELSE
  616. pev178:
  617. ;                AX = 0
  618.         mov     ax,0
  619. ;            ENDIF
  620. pev179:
  621. ;            INT_Notify          ; Macro to see if any ints should be relected
  622.         INT_Notify
  623. ;            Break
  624.         jmp     pev200
  625. ;
  626. ;        default:                                ; Invalid function
  627. pev180:
  628. ;            AX = 1
  629.         mov     ax,1
  630. ;            Break
  631. ;       jmp     pev200
  632. ;
  633. ;    ENDSelect
  634. pev200:
  635. ;
  636. ;    Restore all used registers (does not include AX)
  637.         .386
  638.         RestoreReg <ebp,edx,ebx,ds,es,edi,esi>
  639.         .286
  640. ;
  641. ;    RETURN
  642.         db      66h
  643.         ret
  644. ;
  645. ;END PCOMEntryVDM
  646. EndProc PCOMEntryVDM
  647. ;
  648. ;;********************** START OF SPECIFICATIONS *********************
  649. ;;*
  650. ;;*  SUBROUTINE NAME:    VDMWriteByte
  651. ;;*
  652. ;;*  DESCRIPTIVE NAME:   Fast VDM write byte routine
  653. ;;*
  654. ;;*  STATUS: RELEASE 2  LEVEL 0
  655. ;;*
  656. ;;*  FUNCTION:
  657. ;;*
  658. ;;*  NOTES:  none
  659. ;;*
  660. ;;*  ENTRY POINTS:   VDMWriteByte
  661. ;;*
  662. ;;*  LINKAGE:    NEAR
  663. ;;*
  664. ;;*  USES:
  665. ;;*
  666. ;;*  INPUT:      AX = 4,  DL = port number, BL = character, pointer to ComInfo
  667. ;;*
  668. ;;*  OUTPUT:     CL = more room indicator
  669. ;;*
  670. ;;*  EXIT-NORMAL:  NONE
  671. ;;*
  672. ;;*  EXIT_ERROR:   NONE
  673. ;;*
  674. ;;*  EFFECTS:
  675. ;;*
  676. ;;*  INTERNAL REFERENCES:
  677. ;;*
  678. ;;*  EXTERNAL REFERENCES:  none
  679. ;;*
  680. ;;*********************** END OF SPECIFICATIONS **********************
  681. ;
  682. ;VDMWriteByte:
  683. Procedure VDMWriteByte,near
  684. ;
  685.         cli
  686.  
  687. ; Do state updates
  688.  
  689. ;   IF (ComInfo.VDM_Rx_state == 3)       ; are we in receive state 3
  690.         cmp     [si].ci_vdm_Rx_State,3
  691.         jne     vwb020
  692. ;   THEN                                 ; yes, increment count
  693. ;       ComInfo.VDM_Tx_count = ComInfo.VDM_Tx_count + 1
  694.         inc     [si].ci_vdm_Tx_Count
  695. ;       IF (ComInfo.VDM_Tx_count == 16)
  696.         cmp     [si].ci_vdm_Tx_Count,VDM_Max_Tx_Count
  697.         jne     vwb020
  698. ;       THEN                             ; 16 chars sent, yes
  699. ;           ComInfo.VDM_Tx_count = 0     ; goto receive state 1
  700.         mov     [si].ci_vdm_Tx_Count,0
  701. ;           ComInfo.VDM_Rx_state = 1
  702.         mov     [si].ci_vdm_Rx_State,1
  703. ;       ENDIF
  704. ;   ENDIF
  705. vwb020:
  706. ;   IF (character == XOFF)               ; was this an XOFF?
  707.         cmp     cl,XOFFequ
  708.         jne     vwb030
  709. ;   THEN                                 ; yes - XOFF
  710. ;     IF (ComInfo.VDM_Tx_state != 3)     ; are we in state 3 ?
  711.         cmp     [si].ci_vdm_Tx_State,3
  712.         je      vwb040
  713. ;     THEN                               ; no
  714. ;       ComInfo.VDM_Tx_state = 2         ; goto transmit state 2
  715.         mov     [si].ci_vdm_Tx_State,2
  716.         jmp     vwb040
  717. ;     ENDIF
  718. ;   ELSE
  719. vwb030:                                  ; not XOFF
  720. ;   ComInfo.VDM_Tx_state = 1             ; set transmit state 1
  721.         mov     [si].ci_vdm_Tx_State,1
  722. ;   ComInfo.VDM_Rx_count = 0
  723.         mov     [si].ci_vdm_Rx_Count,0
  724. ;   ENDIF
  725. vwb040:
  726.  
  727. ; see if we can transmit character immediately
  728.  
  729.         jmp     SHORT vwb011
  730.  
  731.         ; The following block of code causes instablility and timing problem.
  732.  
  733.         cmp     [si].ci_qout.ioq_count,0
  734.         jnz     vwb011          ; if queue not empty, go queue
  735.  
  736.         ; check handshaking for busy
  737.         mov     cl,[si].ci_msrshadow    ; (al) = msrshadow
  738.         and     cl,[si].ci_outhhslines  ; mask bits of interest
  739.         cmp     cl,[si].ci_outhhslines
  740.         jne     vwb011                  ; modem lines down, go queue
  741.  
  742.         cmp     [si].ci_vdm_rx_state,1  ; are we in state 1?
  743.         jne     vwb011                  ; no, go queue
  744.  
  745.         push    ax              ; save current values
  746.         push    dx
  747.  
  748.         ; check at the hardware for busy
  749.         mov     dx,[si].ci_port ; get port address
  750.  
  751.         add     dx,R_INTEN      ; get to IER
  752.         in      al,dx
  753.         test    al,IE_TX
  754.         jnz     vwb010          ; if tx ints are on, go queue
  755.  
  756.         add     dx,R_LINES-R_INTEN ; get to LSR
  757.         in      al,dx
  758.         test    al,LS_THRE
  759.         jz      vwb010          ; if THRE not empty, go queue
  760.  
  761. ; The queue is empty, the lines are good and the chip is free so send the data.
  762.         add     dx,R_DATA-R_LINES ; get to RBR
  763.         mov     al,bl           ; get character
  764.         out     dx,al           ; its out-a-here!
  765.  
  766.         pop     dx
  767.         pop     ax
  768.  
  769.         jmp     vwb013          ; check for more room and return
  770.  
  771. vwb010:                         ; restore regs
  772.         pop     dx
  773.         pop     ax
  774. vwb011:
  775.  
  776. ;   Add character to end of Tx Queue
  777.  
  778.         mov     cl,bl
  779.         mov     bx,[si].ci_qout.ioq_in
  780.         inc     bx                              ; adjust in pointer
  781.         cmp     bx,[si].ci_qout.ioq_out
  782.         je      vwb050                          ; (in + 1) == out
  783.         dec     bx
  784.         mov     [bx],cl                         ; put byte in queue
  785.         inc     bx
  786.         cmp     bx,[si].ci_qout.ioq_end
  787.         jne     vwb012                          ; did not wrap
  788.  
  789.         mov     bx,[si].ci_qout.ioq_base        ; wrapped
  790.  
  791. vwb012:
  792.  
  793.         mov     [si].ci_qout.ioq_in,bx           ; update in pointer
  794.         inc     [si].ci_qout.ioq_count           ; adjust count
  795.  
  796.         call    CheckTX                 ; start Tx if conditions permit........
  797.         cli                             ;@@ disable
  798.  
  799. vwb013:
  800. ;   CL = 1                               ; more room
  801.         mov     cl,1
  802. ;   IF (ComInfo.VDM_Rx_state != 1) OR
  803.         cmp     [si].ci_vdm_Rx_State,1
  804.         jne     vwb050
  805. ;      (NO more room in TX QUEUE)
  806.         mov     ax,[si].ci_qout.ioq_count       ; ax = size of output queue
  807.         cmp     ax,QO_SIZE-VDM_Delta_QO_SIZE
  808.         jl      vwb060
  809. ;   THEN
  810. vwb050:
  811. ;       CL = 0                           ; NO more room
  812.         mov     cl,0
  813. ;       ComInfo.vdm_flag.notify_the_VCOM_Tx = TRUE
  814.         or      [si].ci_vdm_flag,VDM_Flag_notify_the_VCOM_TX
  815. ;   ENDIF
  816. vwb060:
  817. ;
  818. ;   RETURN                               ; to PCOMEntryVDM
  819.  
  820.         ret
  821. ;
  822. ;END  VDMWriteByte
  823. EndProc  VDMWriteByte
  824. ;
  825. ;;********************** START OF SPECIFICATIONS *********************
  826. ;;*
  827. ;;*  SUBROUTINE NAME:    VDMReadByte
  828. ;;*
  829. ;;*  DESCRIPTIVE NAME:   Fast VDM read byte routine
  830. ;;*
  831. ;;*  STATUS: RELEASE 2  LEVEL 0
  832. ;;*
  833. ;;*  FUNCTION:
  834. ;;*
  835. ;;*  NOTES:  none
  836. ;;*
  837. ;;*  ENTRY POINTS:   VDMReadByte
  838. ;;*
  839. ;;*  LINKAGE:    NEAR
  840. ;;*
  841. ;;*  USES:
  842. ;;*
  843. ;;*  INPUT:      AH = 3,  DL = port number, pointer to ComInfo
  844. ;;*
  845. ;;*  OUTPUT:     AH = character, AL = this character's LSR,
  846. ;;*              CL = more data indicator (bit 0 - physical, bit 1 - logical)
  847. ;;*
  848. ;;*  EXIT-NORMAL:  NONE
  849. ;;*
  850. ;;*  EXIT_ERROR:   NONE
  851. ;;*
  852. ;;*  EFFECTS:   Exits with interrupts disabled !!!!!!!!!
  853. ;;*
  854. ;;*  INTERNAL REFERENCES:
  855. ;;*
  856. ;;*  EXTERNAL REFERENCES:  none
  857. ;;*
  858. ;;*********************** END OF SPECIFICATIONS **********************
  859. ;
  860. ;VDMReadByte:
  861. Procedure VDMReadByte,near
  862. ;
  863. ;   Get character from front of Rx Queue into AH
  864.         cli
  865.         mov     bx,[si].ci_qin.ioq_out
  866.         cmp     bx,[si].ci_qin.ioq_in
  867. ;       stc                                     ; assume the queue is empty
  868.         push    ax                              ;PB73220
  869.         je      vrb040                          ; queue is empty (out == in)
  870.         pop     ax                              ;PB73220
  871.  
  872. vrb05:  mov     ah,[bx]                         ; (ah) = byte
  873.         push    bx                              ; save the addr
  874.         dec     [si].ci_qin.ioq_count           ; adjust count
  875.         jnz     vrb10                           ; didn't take last char
  876.  
  877. vrb10:  inc     bx                              ; adjust out pointer
  878.         cmp     [si].ci_qin.ioq_end,bx          ; clears carry (end >= bx)
  879.         jne     vrb20                           ; did not hit end of queue
  880.  
  881.          ; Hit the end of the queue, wrap out pointer (out == base).
  882.  
  883.         mov     bx,[si].ci_qin.ioq_base         ; (bx) = base of queue
  884. vrb20:  mov     [si].ci_qin.ioq_out,bx          ; reset the output pointer
  885.  
  886. ;   Get LSR from front of Rx Status Queue into AL
  887.         pop     bx
  888.         sub     bx,[si].ci_qin.ioq_base
  889.         mov     al,[si+bx].ci_qstat
  890.         sti
  891. ;   check for MS interrupts
  892.         push    ax
  893.         call    MS_notify
  894.         pop     ax
  895.         push    ax                       ; save data
  896. ;   IF (ComInfo.VDM_Rx_state == 2) AND   ; are we in receive state 2 and
  897.         cli                              ;CP20PB726006 Cannot have int while changing status
  898.         cmp     [si].ci_vdm_Rx_State,2
  899.         jne     vrb020
  900. ;      (Character == XOFF) AND           ; is this XOFF character and
  901.         cmp     ah,XOFFequ
  902.         jne     vrb020
  903. ;      (Character's LSR == 0) AND        ; is this character valid and
  904.         test    al,LS_OERR+LS_PERR+LS_FERR+LS_BI ;CP20PB726006
  905.         jnz     vrb020
  906. ;      (Tx queue not empty)              ; is the transmit Q not empty
  907.         mov     ax,[si].ci_qout.ioq_count       ; ax = size of output queue
  908.         cmp     ax,0
  909.         je      vrb015
  910. ;   THEN                                 ; yes
  911. ;       ComInfo.VDM_Rx_state = 3         ; goto receive state 3
  912.         mov     [si].ci_vdm_Rx_State,3
  913.         jmp     short   vrb020
  914. ;   ELSE
  915. vrb015:
  916. ;       ComInfo.VDM_Rx_state = 1         ; go back to receive state 1
  917.         mov     [si].ci_vdm_Rx_State,1
  918.         mov     [si].ci_vdm_Tx_Count,0
  919. ;   ENDIF
  920. vrb020:
  921. ;   IF (more data in Rx QUEUE) AND
  922.         cli                              ;CP20PB726006 Cannot have int while changing status
  923.         mov     ax,[si].ci_qin.ioq_count       ; ax = size of input queue
  924.         cmp     ax,0
  925.         jz      vrb040
  926. ;      (ComInfo.VDM_Tx_state == 1)
  927.         cmp     [si].ci_vdm_Tx_State,1
  928.         jne         vrb040
  929. ;   THEN
  930. ;       CL = 1                           ; queue not empty
  931.         mov     cl,1
  932.         jmp     short vrb060
  933. ;   ELSE
  934. vrb040:
  935. ;       CL = 0                           ; NO more data
  936.         mov     cl,0
  937. ;       ComInfo.vdm_flag.notify_the_VCOM_Rx = TRUE
  938.         or      [si].ci_vdm_flag,VDM_Flag_notify_the_VCOM_RX
  939. ;   ENDIF
  940. vrb060:
  941. ;
  942. ;   RETURN                                       ; to PCOMEntryVDM
  943.         pop     ax                      ; restore data
  944.         ret
  945. ;
  946. ;END  VDMReadByte
  947. EndProc  VDMReadByte
  948. ;
  949. ;;********************** START OF SPECIFICATIONS *********************
  950. ;;*
  951. ;;*  SUBROUTINE NAME:    VDMGetDLLDLM
  952. ;;*
  953. ;;*  DESCRIPTIVE NAME:        Get the DLL and DLM registers routine
  954. ;;*
  955. ;;*  STATUS: RELEASE 2  LEVEL 0
  956. ;;*
  957. ;;*  FUNCTION:
  958. ;;*
  959. ;;*  NOTES:  none
  960. ;;*
  961. ;;*  ENTRY POINTS:   VDMGetDLLDLM
  962. ;;*
  963. ;;*  LINKAGE:    NEAR
  964. ;;*
  965. ;;*  USES:
  966. ;;*
  967. ;;*  INPUT:      AH = 3,  DL = port number, pointer to ComInfo
  968. ;;*
  969. ;;*  OUTPUT:     CL = DLL, CH = DLM
  970. ;;*
  971. ;;*  EXIT-NORMAL:  NONE
  972. ;;*
  973. ;;*  EXIT_ERROR:   NONE
  974. ;;*
  975. ;;*  EFFECTS:
  976. ;;*
  977. ;;*  INTERNAL REFERENCES:
  978. ;;*
  979. ;;*  EXTERNAL REFERENCES:  none
  980. ;;*
  981. ;;*********************** END OF SPECIFICATIONS **********************
  982. ;
  983. ;VDMGetDLLDLM:
  984. Procedure VDMGetDLLDLM,near
  985. ;
  986. ;   read current DLL value into CL
  987. ;   read current DLM value into CH
  988.  
  989. ;** IBMIBM *** disable here to prevent interrupts while going direct to hw
  990.  
  991.         pushf                           ; save flags for later
  992.         cli                             ; DISABLE PROCESSOR INTERRUPTS
  993.         mov     dx,[si].ci_port
  994.         add     dx,R_LINEC              ; (dx) -> LCR
  995.         in      al,dx                   ; (al) = current value of LCR
  996.         mov     ah,al                   ; save original state of LCR
  997.         or      al,LC_DLAB              ; turn on DLAB
  998.         out     dx,al
  999.  
  1000. ; Set divisor-latch value.
  1001. ; (dx) -> R_LINEC
  1002.  
  1003.         add     dx,R_BAUDH-R_LINEC      ; (dx) -> MSB of baud latch
  1004.         in      al,dx                   ; get MSB of baud latch
  1005.         mov     ch,al                   ; (al) = divisor latch MSB
  1006.         dec     dx                      ; (dx) -> LSB of baud latch
  1007.         in      al,dx                   ; get LSB of baud latch
  1008.         mov     cl,al                   ; (al) = divisor latch LSB
  1009.  
  1010. ; Restore original state of LCR (turn off DLAB)
  1011. ; (dx) -> R_BAUDL
  1012.  
  1013.         add     dx,R_LINEC-R_BAUDL      ; (dx) -> LCR
  1014.         mov     al,ah                   ; (al) = original state of LCR
  1015.         out     dx,al
  1016.  
  1017. ;** IBMIBM *** time to re-enable
  1018.         popf                            ; restore flags
  1019.  
  1020. ;
  1021. ;   RETURN                                       ; to PCOMEntryVDM
  1022.         ret
  1023. ;
  1024. ;END  VDMGetDLLDLM
  1025. EndProc  VDMGetDLLDLM
  1026. ;
  1027. ;;********************** START OF SPECIFICATIONS *********************
  1028. ;;*
  1029. ;;*  SUBROUTINE NAME:    VDMSetDLLDLM
  1030. ;;*
  1031. ;;*  DESCRIPTIVE NAME:   Set the DLL and DLM registers routine
  1032. ;;*
  1033. ;;*  STATUS: RELEASE 2  LEVEL 0
  1034. ;;*
  1035. ;;*  FUNCTION:
  1036. ;;*
  1037. ;;*  NOTES:  none
  1038. ;;*
  1039. ;;*  ENTRY POINTS:   VDMSetDLLDLM
  1040. ;;*
  1041. ;;*  LINKAGE:    NEAR
  1042. ;;*
  1043. ;;*  USES:
  1044. ;;*
  1045. ;;*  INPUT:      AH = 3,  DL = port number, pointer to ComInfo
  1046. ;;*              CL = DLL, CH = DLM
  1047. ;;*
  1048. ;;*  OUTPUT:     NONE
  1049. ;;*
  1050. ;;*  EXIT-NORMAL:  NONE
  1051. ;;*
  1052. ;;*  EXIT_ERROR:   NONE
  1053. ;;*
  1054. ;;*  EFFECTS:
  1055. ;;*
  1056. ;;*  INTERNAL REFERENCES:
  1057. ;;*
  1058. ;;*  EXTERNAL REFERENCES:  none
  1059. ;;*
  1060. ;;*********************** END OF SPECIFICATIONS **********************
  1061. ;
  1062. ;VDMSetDLLDLM:
  1063. Procedure VDMSetDLLDLM,near
  1064. ;
  1065. ;   put CL into DLL
  1066. ;   put CH into DLM
  1067.                                         ; if CX is 0 or 1, then the baud rate
  1068.         cmp     cx,1                    ; is too high, unsupported.  It will
  1069.         jbe     setdd100                ; not fit in a word, and the DIV below
  1070.                                         ; will cause a TRAP 0
  1071.  
  1072. ;** IBMIBM *** disable here to prevent interrupts while going direct to hw
  1073.  
  1074.         call    DLtoComInfo
  1075.         pushf                           ; This did not exist here before
  1076.         cli                             ; DISABLE PROCESSOR INTERRUPTS
  1077.         mov     [si].ci_fifobaud,cx     ; store latch values in cominfo
  1078.  
  1079.         mov     dx,[si].ci_port
  1080.         add     dx,R_LINEC              ; (dx) -> LCR
  1081.         min     al,dx                   ; (al) = current value of LCR
  1082.         mov     ah,al                   ; save original state of LCR
  1083.         or      al,LC_DLAB              ; turn on DLAB
  1084.         mout    dx,al
  1085.  
  1086. ; Set divisor-latch value.
  1087. ; (dx) -> R_LINEC
  1088.  
  1089.         add     dx,R_BAUDH-R_LINEC      ; (dx) -> MSB of baud latch
  1090.         mov     al,ch                   ; (al) = divisor latch MSB
  1091.         mout    dx,al
  1092.         dec     dx                      ; (dx) -> LSB of baud latch
  1093.         mov     al,cl                   ; (al) = divisor latch LSB
  1094.         mout    dx,al                   ; set LSB of baud latch
  1095.  
  1096. ; Restore original state of LCR (turn off DLAB)
  1097. ; (dx) -> R_BAUDL
  1098.  
  1099.         add     dx,R_LINEC-R_BAUDL      ; (dx) -> LCR
  1100.         mov     al,ah                   ; (al) = original state of LCR
  1101.         mout    dx,al
  1102.  
  1103.         savereg <ax,dx>
  1104.         mov     dx,CLOCK_RATEHI         ; Get clock rate in dx:ax
  1105.         mov     ax,CLOCK_RATELO         ; 
  1106.         div     cx                      ; 
  1107.         mov     bx,ax                   ; bx = baud
  1108.         mov     [si].ci_baud,ax         ; ci_baud = baud
  1109.         restorereg <dx,ax>
  1110.  
  1111.         call    ComputeWTO              ; re-compute write timeout value
  1112.         call    ComputeRTO              ; re-compute read  timeout value
  1113.  
  1114. setdd90:
  1115.         popf                            ; used to be sti here
  1116. setdd100:
  1117. ;
  1118. ;   RETURN                              ; to PCOMEntryVDM
  1119.         ret
  1120. ;
  1121. ;END  VDMSetDLLDLM
  1122. EndProc  VDMSetDLLDLM
  1123. ;
  1124. ;;********************** START OF SPECIFICATIONS *********************
  1125. ;;*
  1126. ;;*  SUBROUTINE NAME:    DLtoComInfo
  1127. ;;*
  1128. ;;*  DESCRIPTIVE NAME:   Sets DS:SI to point to the correct ComInfo
  1129. ;;*                      based on DL (0, 1 or 2)
  1130. ;;*
  1131. ;;*  STATUS: RELEASE 2  LEVEL 0
  1132. ;;*
  1133. ;;*  FUNCTION:
  1134. ;;*
  1135. ;;*  NOTES:  none
  1136. ;;*
  1137. ;;*  ENTRY POINTS:   DLtoComInfo
  1138. ;;*
  1139. ;;*  LINKAGE:    NEAR
  1140. ;;*
  1141. ;;*  USES:
  1142. ;;*
  1143. ;;*  INPUT:      DL = port number
  1144. ;;*
  1145. ;;*  OUTPUT:     DS:SI -> ComInfo for this port
  1146. ;;*
  1147. ;;*  EXIT-NORMAL:  NONE
  1148. ;;*
  1149. ;;*  EXIT_ERROR:   NONE
  1150. ;;*
  1151. ;;*  EFFECTS:
  1152. ;;*
  1153. ;;*  INTERNAL REFERENCES:
  1154. ;;*
  1155. ;;*  EXTERNAL REFERENCES:  none
  1156. ;;*
  1157. ;;*********************** END OF SPECIFICATIONS **********************
  1158.  
  1159. Procedure DLtoComInfo,near
  1160.  
  1161.         cmp     dl,0                        ; if DL == 0, then SI -> Com1
  1162.         jne     DLtoComInfo2
  1163.         mov     si,Com1                     ; (DS:SI) -> COM1 info
  1164.         jmp     SHORT DLtoComInfo_ret
  1165.  
  1166. DLtoComInfo2:
  1167.         cmp     dl, 1                       ; if DL == 1, then SI -> Com2
  1168.         jne     DLtoComInfo3
  1169.         mov     si, Com2                    ; (DS:SI) -> COM2 info
  1170.         jmp     SHORT DLtoComInfo_ret
  1171.  
  1172. DLtoComInfo3:
  1173.         cmp     dl, 2                       ; if DL == 2, then SI -> Com3
  1174.         jne     DLtoComInfo4
  1175.         mov     si, Com3                    ; (DS:SI) -> COM3 info
  1176.         jmp     SHORT DLtoComInfo_ret
  1177.  
  1178. DLtoComInfo4:
  1179.         mov     si, Com4                    ; (DS:SI) -> COM4 info
  1180.  
  1181. DLtoComInfo_ret:
  1182.         ret
  1183.  
  1184. EndProc  DLtoComInfo
  1185.  
  1186. ;
  1187. ;;********************** START OF SPECIFICATIONS *********************
  1188. ;;*
  1189. ;;*  SUBROUTINE NAME:    WaitForOutPut
  1190. ;;*
  1191. ;;*  DESCRIPTIVE NAME:   Waits for TX queue to empty
  1192. ;;*
  1193. ;;*  STATUS: RELEASE 2  LEVEL 0
  1194. ;;*
  1195. ;;*  FUNCTION:
  1196. ;;*
  1197. ;;*  NOTES:  none
  1198. ;;*
  1199. ;;*  ENTRY POINTS:   WaitForOutPut
  1200. ;;*
  1201. ;;*  LINKAGE:    NEAR
  1202. ;;*
  1203. ;;*  USES:
  1204. ;;*
  1205. ;;*  INPUT:      DS:SI -> ComInfo for this port
  1206. ;;*              ES:DI = ID to block on
  1207. ;;*              dx:cx = time out value
  1208. ;;*
  1209. ;;*  OUTPUT:     None
  1210. ;;*
  1211. ;;*  EXIT-NORMAL:  NONE
  1212. ;;*
  1213. ;;*  EXIT_ERROR:   NONE
  1214. ;;*
  1215. ;;*  EFFECTS:
  1216. ;;*
  1217. ;;*  INTERNAL REFERENCES:
  1218. ;;*
  1219. ;;*  EXTERNAL REFERENCES:  none
  1220. ;;*
  1221. ;;*********************** END OF SPECIFICATIONS **********************
  1222.  
  1223. Procedure WaitForOutPut,near
  1224.  
  1225.         push    ax
  1226. ;            IF (Tx Queue not empty)
  1227.         cli
  1228.         mov     ax,[si].ci_qout.ioq_count ; ax = size of output queue
  1229.         cmp     ax,0
  1230.         jne     wfop001                 ; user data in queue, request not done
  1231.         sti
  1232.         pop     ax
  1233.         ret
  1234. wfop001:
  1235. ;            THEN
  1236. ;                Block this request
  1237.         push    cx
  1238.         push    dx
  1239.         push    di
  1240.         push    es
  1241.  
  1242.         lea     di,[si].ci_req_pack     ; make ES:DI -> req packet for block
  1243.         mov     ax,ds
  1244.         mov     es,ax
  1245.         mov     cx,-1                   ; (dx:cx) = infinite time out
  1246.         mov     dx,cx
  1247.         mov     [si].ci_vdm_Blocked_IOCTL._hi,es
  1248.         mov     [si].ci_vdm_Blocked_IOCTL._lo,di
  1249.         or      [si].ci_vdm_flag,VDM_Flag_Blocked_IOCTL
  1250.         call    ProcBlock
  1251.  
  1252.         sti
  1253.         pop     es
  1254.         pop     di
  1255.         pop     dx
  1256.         pop     cx
  1257.         pop     ax
  1258.         ret
  1259. ;            ENDIF
  1260.  
  1261. EndProc  WaitForOutPut
  1262.  
  1263. ;;********************** START OF SPECIFICATIONS *********************
  1264. ;;*
  1265. ;;* SUBROUTINE NAME: PCOMStackEntry
  1266. ;;*
  1267. ;;* DESCRIPTIVE NAME: Communication Device Driver Stack Based VDM Entry Point
  1268. ;;*
  1269. ;;* FUNCTION:  This entry point is used by the VDMM to tell PCOM when the VCOM
  1270. ;;*      does a VDHOpenPDD.  VCOM calls this entry point to get the stack based
  1271. ;;*      entry point (PCOMEntryVDM) and the structure of the ports to support.
  1272. ;;*
  1273. ;;*      On entry to this routine, the command type is checked and the correct
  1274. ;;*      data is stored and returned.
  1275. ;;*
  1276. ;;* NOTES:       ABIOS MUST BE PRESENT
  1277. ;;*
  1278. ;;* ENTRY POINTS:  PCOMStackEntry
  1279. ;;*
  1280. ;;* LINKAGE:     Far 16:32
  1281. ;;*
  1282. ;;* INPUT:  (on the stack)
  1283. ;;*         Func  = port number
  1284. ;;*         P1    = pointer 1
  1285. ;;*         P2    = pointer 2
  1286. ;;*
  1287. ;;* OUTPUT: command based
  1288. ;;*
  1289. ;;*         if Func = 0    (Register)
  1290. ;;*            P1.offset  = 0
  1291. ;;*            P1.segment = VDD's CS
  1292. ;;*            P2.offset  = low 16-bits of VDD EIP for entry point
  1293. ;;*            P2.segment = high 16-bits of VDD EIP for entry point
  1294. ;;*
  1295. ;;*         returns:
  1296. ;;*            AX = 1
  1297. ;;*
  1298. ;;*         if Func = 1    (Get Reg based entry point)
  1299. ;;*            P1 -> return area for reg based address
  1300. ;;*            P2 -> return area for structure of supported ports
  1301. ;;*
  1302. ;;*         returns:
  1303. ;;*            AX = 1
  1304. ;*
  1305. ;;*********************** END OF SPECIFICATIONS **********************
  1306. ;
  1307. ;PCOMStackEntry:
  1308. Procedure PCOMStackEntry,FAR
  1309.  
  1310. ;
  1311. ;       set up stack frame pointer
  1312.         SaveReg <bp>
  1313.         mov     bp,sp
  1314.         SaveReg <ds>
  1315. ;
  1316. ;    Get DS addressability
  1317.         setDS   DSEG
  1318. ;
  1319. ;    Select (Function type)
  1320. ;
  1321. ;        Case (Register - 0):
  1322. pse000:
  1323.         .386
  1324.         cmp     [bp].uFunc,0
  1325.         .286
  1326.         jne     pse020
  1327. ;            Save 16:32 pointer of VCOM notification entry point
  1328. ;                 in global (fixed) data (VCOMAddress)
  1329.         mov     ax,[bp].ul1._lo
  1330.         mov     [VCOMAddress].fp_sel,ax
  1331.         mov     ax,[bp].ul2._lo
  1332.         mov     [VCOMAddress].fp_offlo,ax
  1333.         mov     ax,[bp].ul2._hi
  1334.         mov     [VCOMAddress].fp_offhi,ax
  1335. ;            Break
  1336.         jmp     pse500
  1337. ;
  1338. ;        Case (Initialize PCOM-VCOM connection - 1):
  1339. pse020:
  1340.         .386
  1341.         cmp     [bp].uFunc,1
  1342.         .286
  1343.         ljne     pse200
  1344.  
  1345. ;
  1346. ;       Pass register based entry point to VCOM
  1347. ;
  1348.         SaveReg <es,di,si,cx>           ; save burned regs
  1349.  
  1350.         mov     es,[bp].ul1._hi         ; get pointer 1 selector
  1351.         mov     di,[bp].ul1._lo         ; get pointer 1 offset
  1352.         mov     es:[di].fp_sel,cs       ; set the far pointer selector
  1353.         mov     es:[di].fp_offhi,0      ; set the far pointer high offset
  1354.         lea     ax,cs:PCOMEntryVDM      ; get the far pointer low offset
  1355.         mov     es:[di].fp_offlo,ax     ; set the far pointer low offset
  1356.  
  1357. ;
  1358. ;       Set up device dependant structure for VCOM
  1359. ;
  1360. ;       struct {
  1361. ;       word ret_len;
  1362. ;       word num_com;
  1363. ;       word @com1,
  1364. ;            @com2,
  1365. ;            @com3,
  1366. ;            @com4
  1367. ;       word @cm1irq,
  1368. ;            @cm2irq,
  1369. ;            @cm3irq,
  1370. ;            @cm4irq
  1371. ;       };
  1372. ;
  1373.  
  1374.         mov     es,[bp].ul2._hi         ; get selector of pointer 2
  1375.         mov     di,[bp].ul2._lo         ; get offset of pointer 2
  1376.  
  1377.         mov     cx,es:[di].ret_len
  1378.         cmp     cx,size Device_dependant_VCOM_data
  1379.         ljne    pse070                  ; we're done
  1380.  
  1381.         push    di                      ; save current pointer
  1382.         mov     al,0                    ; what to store
  1383.         cld                             ; set direction flag to smaller->larger
  1384.         repnz   stosb                   ; zero out the passed structure
  1385.         pop     di                      ; restore pointer
  1386.  
  1387.         mov     es:[di].num_com,MAXCOMPORTS  ; set number of com ports supported
  1388.         xor     cx,cx
  1389.  
  1390.         mov     si,com1                 ; get ComInfo for com1
  1391.         or      si,si                   ; if not installed
  1392.         jz      pse040                  ; we're done with this one
  1393.         mov     ax,ds:[si].ci_port      ; get port address
  1394.         mov     es:[di].@com1,ax        ; set port address
  1395.         mov     cl,ds:[si].ci_irq       ; get irq level
  1396.         mov     es:[di].@cm1irq,cx      ; set irq level
  1397.  
  1398. pse040:                                 ; 
  1399.         mov     si,com2                 ; get ComInfo for com2
  1400.         or      si,si                   ; if not installed
  1401.         jz      pse050                  ; we're done with this one
  1402.         mov     ax,ds:[si].ci_port      ; get port address
  1403.         mov     es:[di].@com2,ax        ; set port address
  1404.         mov     cl,ds:[si].ci_irq       ; get irq level
  1405.         mov     es:[di].@cm2irq,cx        ; set irq level
  1406.  
  1407. pse050:                                 ; 
  1408.         mov     si,com3                 ; get ComInfo for com3
  1409.         or      si,si                   ; if not installed
  1410.         jz      pse060                  ; we're done with this one
  1411.         mov     ax,ds:[si].ci_port      ; get port address
  1412.         mov     es:[di].@com3,ax        ; set port address
  1413.         mov     cl,ds:[si].ci_irq       ; get irq level
  1414.         mov     es:[di].@cm3irq,cx        ; set irq level
  1415.  
  1416. pse060:                                 ; 
  1417.         mov     si,com4                 ; get ComInfo for com4
  1418.         or      si,si                   ; if not installed
  1419.         jz      pse070                  ; we're done with this one
  1420.         mov     ax,ds:[si].ci_port      ; get port address
  1421.         mov     es:[di].@com4,ax        ; set port address
  1422.         mov     cl,ds:[si].ci_irq       ; get irq level
  1423.         mov     es:[di].@cm4irq,cx      ; set irq level
  1424. pse070:                                 ; 
  1425.         RestoreReg <cx,si,di,es>        ; 
  1426. ;            Break
  1427. ;       jmp     pse500
  1428. ;
  1429. ;
  1430. ;       Default case (invalid parameter):
  1431. ;        set     return value
  1432. pse200:
  1433.          mov    ax,0
  1434.          jmp    pse600
  1435. ;    ENDSelect
  1436. pse500:                                 ; 
  1437. ;
  1438. ;       set good return value
  1439.         mov     ax,1
  1440. pse600:
  1441. ;
  1442. ;       restore frame pointer
  1443.         RestoreReg <ds,bp>
  1444. ;
  1445. ;    RETURN (32 bit)
  1446.         db      66h
  1447.         ret     12
  1448. ;
  1449. ;END PCOMStackEntry
  1450. EndProc PCOMStackEntry
  1451. ;
  1452. CSEG    ENDS
  1453.  
  1454.         END
  1455.