home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / ATCOM / ATIOCTL.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  43KB  |  1,222 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 = @(#)atioctl.asm        6.6 91/11/11
  13. ; ***************************************************************************
  14. ; *
  15. ; *
  16. ; *
  17. ; ***************************************************************************
  18.  
  19.         PAGE    80,132
  20.         .286p
  21.  
  22.         TITLE   com01.sys - Asynchronous Communication Device Driver
  23.         NAME com01
  24.  
  25. ;       Bryan Diehl
  26. ;       David Gilman
  27.  
  28. ;***    atioctl.asm - IOCTL Routines
  29. ;
  30. ;       Support routines for generic IOCTLs.
  31. ;
  32. ;       LoadGIODataPack - Put a byte or word into the IOCTL data packet
  33. ;       GetGIOParaPack  - Get a byte or word from the IOCTL parameter packet
  34. ;       VerifyAddr      - Verify an IOCTL packet pointers
  35. ;       VerifyNull      - Verify a NULL IOCTL packet pointer
  36. ;       ComIoctl        - IOCTL dispatcher
  37. ;
  38. ;       Modification History
  39. ;
  40. ;       BD      01/18/87        Re-written to conform to MS standard for
  41. ;                               style, clarity and efficiency.
  42. ;                               New queue structure.
  43. ;       JGT     05/10/88        Add enhanced baud rate support
  44. ;       YN      05/25/89        MVDM Support - @VDM
  45. ;       YN      10/06/89        PTR 707056 - @@1
  46. ;       ACW     04/16/91        @PVW Added perfview counters/timers
  47. ;       YN      08/13/91        CP20D1390 - Bulletin Board Support
  48. ;       WDM     04/21/94        82548 - pvwxport.inc now included in atcom.inc
  49. ;       PMS     07/27/94        89343 - Only call CheckAPO when FIFO flags change
  50. ;
  51.  
  52. .xlist
  53. include devhlp.inc
  54. include devsym.inc
  55. include basemaca.inc
  56. include realmac.inc
  57. include ioctl.inc
  58. include seldesc.inc
  59. include atcom.inc               ; local include
  60. include atesp.inc
  61. .list
  62.  
  63.         extrn   DevHlp:dword
  64.         extrn   ComInit:near
  65.         extrn   CheckTX:near
  66.         extrn   CmxDone:near
  67.         extrn   CmxGenFail:near
  68.         extrn   CmxInvalidParameter:near
  69.         extrn   CmxInUse:near
  70.         extrn   CmxMonitor:near
  71.         extrn   CmxUnknown:near
  72.         extrn   DisableRemoteTX:near
  73.         extrn   EnableRemoteTXXO:near
  74.         extrn   Get_OCI_Sem:near
  75.         extrn   CheckLCR:near
  76.         extrn   ComputeAPO:near
  77.         extrn   ComputeHHS:near
  78.         extrn   ComputeRTO:near
  79.         extrn   ComputeWTO:near
  80.         extrn   EnableRemoteTX:near
  81.         extrn   MxInt:near
  82.         extrn   SetLineC:near
  83.         extrn   SetBaud:near
  84.  
  85.  
  86. DSEG SEGMENT
  87.  
  88. ;* IoctlTab - dispatch table for IOCTLs
  89. ;
  90.         EVEN
  91.         PUBLIC  IoctlTab
  92. IoctlTab LABEL WORD
  93.         DW      OFFSET ioc_bad          ; 40
  94.         DW      OFFSET ioc_sbaud        ; 41 set baud rate
  95.         DW      OFFSET ioc_slinec       ; 42 set line control
  96.         DW      OFFSET ioc_sbaudenh     ; 43 set extended bit baud
  97.         DW      OFFSET ioc_tximmed      ; 44 trans immed
  98.         DW      OFFSET ioc_break0       ; 45 break off
  99.         DW      OFFSET ioc_smodemc      ; 46 set modem control
  100.         DW      OFFSET ioc_rxoff        ; 47 as if XOFF received
  101.         DW      OFFSET ioc_rxon         ; 48 as if XON  received
  102.         DW      OFFSET ioc_bad          ; 49
  103.         DW      OFFSET ioc_bad          ; 4A
  104.         DW      OFFSET ioc_break1       ; 4B break on
  105.         DW      OFFSET ioc_bad          ; 4C
  106.         DW      OFFSET ioc_bad          ; 4D
  107.         DW      OFFSET ioc_bad          ; 4E
  108.         DW      OFFSET ioc_bad          ; 4F
  109.         DW      OFFSET ioc_bad          ; 50
  110.         DW      OFFSET ioc_bad          ; 51
  111.         DW      OFFSET ioc_bad          ; 52
  112.         DW      OFFSET ioc_sdcb         ; 53 set device control block
  113.         DW      OFFSET ioc_senh         ; 54 set enhanced parms
  114.         DW      OFFSET ioc_bad          ; 55
  115.         DW      OFFSET ioc_bad          ; 56
  116.         DW      OFFSET ioc_bad          ; 57
  117.         DW      OFFSET ioc_bad          ; 58
  118.         DW      OFFSET ioc_bad          ; 59
  119.         DW      OFFSET ioc_bad          ; 5A
  120.         DW      OFFSET ioc_bad          ; 5B
  121.         DW      OFFSET ioc_bad          ; 5C
  122.         DW      OFFSET ioc_bad          ; 5D
  123.         DW      OFFSET ioc_bad          ; 5E
  124.         DW      OFFSET ioc_bad          ; 5F
  125.         DW      OFFSET ioc_bad          ; 60
  126.         DW      OFFSET ioc_gbaud        ; 61 get baud rate
  127.         DW      OFFSET ioc_glinec       ; 62 get line control
  128.         DW      OFFSET ioc_gbaudenh     ; 63 get baud enhanced
  129.         DW      OFFSET ioc_gcomstat     ; 64 get com status
  130.         DW      OFFSET ioc_gtxstat      ; 65 get tx status
  131.         DW      OFFSET ioc_gmodemc      ; 66 get modem control output signals
  132.         DW      OFFSET ioc_gmodems      ; 67 get modem control input  signals
  133.         DW      OFFSET ioc_gistat       ; 68 input queue status
  134.         DW      OFFSET ioc_gostat       ; 69 output queue status
  135.         DW      OFFSET ioc_bad          ; 6A
  136.         DW      OFFSET ioc_bad          ; 6B
  137.         DW      OFFSET ioc_bad          ; 6C
  138.         DW      OFFSET ioc_gcomerr      ; 6D get com error word
  139.         DW      OFFSET ioc_bad          ; 6E
  140.         DW      OFFSET ioc_bad          ; 6F
  141.         DW      OFFSET ioc_bad          ; 70
  142.         DW      OFFSET ioc_bad          ; 71
  143.         DW      OFFSET ioc_gevent       ; 72 get comm event word
  144.         DW      OFFSET ioc_gdcb         ; 73 get device control block
  145.         DW      OFFSET ioc_genh         ; 74 get enhanced parms
  146. MAXIOCTL = (($ - IoctlTab)/2) - 1
  147.  
  148. DSEG    ENDS
  149.  
  150.  
  151. CSEG    SEGMENT
  152.         ASSUME cs:CSEG,ds:DSEG,es:NOTHING,ss:NOTHING
  153.  
  154. ;**     LoadGIODataPackB - load a byte into the data packet
  155. ;**     LoadGIODataPackW - load a word into the data packet
  156. ;
  157. ;       ENTRY   (es:di) -> request packet
  158. ;               al      =  byte to put in GIODataPack
  159. ;               ax      =  word to put in GIODataPack
  160. ;
  161. ;       EXIT
  162. ;
  163. ;       USES    cx es di
  164. ;
  165. ;       WARNING will not return if IOCTL data packet pointer is bad.
  166. ;               See VerifyAddrD
  167. ;
  168. ;       NOTE    IOCTL packet pointers are virtual addresses.
  169.  
  170. Procedure LoadGIODataPackB,NEAR
  171.         ASSUME cs:CSEG,ds:DSEG,es:NOTHING,ss:NOTHING
  172.  
  173.         ChkRPPtr
  174.  
  175.         mov     cx,1                    ; byte
  176.         call    VerifyAddrD             ; verify data address
  177.         SaveReg         <es,di>
  178.         les     di,es:[di].GIODataPack  ; (ds:si) -> IOCTL data packet
  179.         stosb                           ; Put al into the data packet
  180.         RestoreReg      <di,es>
  181.         ASSUME  es:NOTHING
  182.         ret
  183.  
  184. Entry LoadGIODataPackW
  185.  
  186.         ChkRPPtr
  187.  
  188.         mov     cx,2                    ; word
  189.         call    VerifyAddrD             ; verify data address
  190.         SaveReg         <es,di>
  191.         les     di,es:[di].GIODataPack  ; (ds:si) -> IOCTL data packet
  192.         stosw                           ; Put ax into the data packet
  193.         RestoreReg      <di,es>
  194.         ASSUME  es:NOTHING
  195.         ret
  196.  
  197. EndProc LoadGIODataPackB
  198.  
  199.  
  200. ;**     GetGIOParaPackB - get a byte from the parameter packet
  201. ;**     GetGIOParaPackW - get a word from the parameter packet
  202. ;
  203. ;       ENTRY   (es:di) -> request packet
  204. ;
  205. ;       EXIT    al      =  byte from GIOParaPack
  206. ;               ax      =  word from GIOParaPack
  207. ;
  208. ;       USES    cx es di
  209. ;
  210. ;       WARNING will not return if IOCTL parameter packet pointer is bad.
  211. ;               See VerifyAddrP
  212. ;
  213. ;       NOTE    IOCTL packet pointers are virtual addresses.
  214.  
  215. Procedure GetGIOParaPackB,NEAR
  216.         ASSUME cs:CSEG,ds:DSEG,es:NOTHING,ss:NOTHING
  217.  
  218.         mov     cx,1
  219.         jmp     short GetGIOx
  220.  
  221.  
  222. Entry GetGIOParaPackW
  223.         mov     cx,2
  224.  
  225. GetGIOx:
  226.         ChkRPPtr
  227.  
  228.         call    VerifyAddrP             ; verify parameter address, cx = size
  229.  
  230.         SaveReg         <es,di>
  231.  
  232.         les     di,es:[di].GIOParaPack  ; (ds:si) -> IOCTL paramaters
  233.         cmp     cx,1
  234.         je      GetPack10               ; load a byte
  235.  
  236.         mov     ax,es:[di]              ; load a word
  237.         jmp     short GetPack99
  238.  
  239. GetPack10:
  240.         mov     al,es:[di]              ; load a byte
  241.  
  242. GetPack99:
  243.         RestoreReg      <di,es>
  244.  
  245.         ret
  246.  
  247. EndProc GetGIOParaPackB
  248.  
  249.  
  250. ;**     VerifyAddrP - Verify IOCTL Parameter pointer
  251. ;**     VerifyAddrD - Verify IOCTL Data      pointer
  252. ;
  253. ;       ENTRY   (es:di) -> request packet
  254. ;               cx         length to verify
  255. ;
  256. ;       EXIT    will not return if invalid address
  257. ;
  258. ;       USES    none
  259. ;
  260. ;       WARNING cx == 0 => 65536
  261. ;       WARNING will not return if IOCTL parameter/data packet pointer is bad
  262. ;               jumps indirectly to CmxGenFail (general failure)
  263. ;               process will terminate when it returns from the kernel
  264.  
  265. Procedure VerifyAddrD,NEAR
  266.         ASSUME cs:CSEG,ds:DSEG,es:NOTHING,ss:NOTHING
  267.  
  268.         push    ax
  269.         push    dx
  270.         push    di
  271.         mov     ax,es:[di].GIODataPack._hi
  272.         mov     di,es:[di].GIODataPack._lo
  273.         mov     dx,(0100h OR DevHlp_VerifyAccess)       ; read/write
  274.         jmp     short VerifyAddr10
  275.  
  276. Entry VerifyAddrP
  277.         push    ax
  278.         push    dx
  279.         push    di
  280.         mov     ax,es:[di].GIOParaPack._hi
  281.         mov     di,es:[di].GIOParaPack._lo
  282.         mov     dx,(0000h OR DevHlp_VerifyAccess)       ; read only
  283.  
  284. VerifyAddr10:
  285.         test    [si].ci_vdm_flag,VDM_Flag_InUse ; @VDM if in use by VDM
  286.         jnz     ver99                           ; @VDM no check for pointer
  287.  
  288.         devhelp
  289.         jc      ioc_99          ;      address
  290.  
  291. ver99:  pop     di
  292.         pop     dx
  293.         pop     ax
  294.  
  295.         ret
  296.  
  297. EndProc VerifyAddrD
  298.  
  299.  
  300. ;**     VerifyNullP - verify IOCTL parameter packet pointer is null
  301. ;**     VerifyNullD - verify IOCTL data      packet pointer is null
  302. ;
  303. ;       ENTRY   (es:di) -> request packet
  304. ;
  305. ;       EXIT    none
  306. ;
  307. ;       USES    none
  308. ;
  309. ;       WARNING will NOT return if IOCTL parameter/data packet pointer
  310. ;               is not null.
  311. ;               jumps indirectly to CmxGenFail (general failure)
  312.  
  313. Procedure VerifyNullD,NEAR
  314.         ASSUME cs:CSEG,ds:DSEG,es:NOTHING,ss:NOTHING
  315.  
  316.         push    bx
  317.         mov     bx,GIODataPack          ; offset of data packet
  318.         jmp     short vn10
  319.  
  320. Entry VerifyNullP
  321.  
  322.         push    bx
  323.         mov     bx,GIOParaPack          ; offset of parameter packet
  324.  
  325. vn10:   ChkRPPtr
  326.         test    es:[di+bx]._hi,SELECTOR_MASK
  327.         jnz     ioc_99                  ; not a null selector
  328.         cmp     es:[di+bx]._lo,0
  329.         jnz     ioc_99                  ; not a null offset
  330.  
  331.         pop     bx
  332.         ret
  333.  
  334. EndProc VerifyNullD
  335.  
  336.  
  337. ;**     ComIoctl - Generic IOCTL Function Dispatcher
  338. ;
  339. ;       ENTRY   (ds:si) -> ComInfo
  340. ;               (es:di) -> Request packet
  341. ;
  342. ;       EXIT    none
  343. ;
  344. ;       USES    ax bx
  345. ;
  346. ;       Each IOCTL subroutine is called with:
  347. ;               (ds:si) -> ComInfo
  348. ;               (es:di) -> Request packet
  349. ;               ah      =  major code (category)
  350. ;               al      =  minor code (subfunction)
  351. ;               df      =  direction flag cleared for auto increment
  352. ;
  353. ;       IOCTL subroutines can use any register except bp.
  354.  
  355. Procedure ComIoctl,NEAR
  356.         ASSUME cs:CSEG,ds:DSEG,es:NOTHING,ss:NOTHING
  357.  
  358.         ChkComInfoPtr
  359.         ChkRPPtr
  360.  
  361. ; We need to insure mutual exclusion between opens, closes and ioctls.
  362.  
  363.         call    Get_OCI_Sem                     ; will not return if error
  364.  
  365.         mov     ah,es:[di].GIOCategory  ; ah = category
  366.         mov     al,es:[di].GIOFunction  ; al = function
  367.  
  368. ;       We must handle monitor IOCTLs separately since they have
  369. ;       a specific error code.
  370.  
  371.         cmp     ah,IOC_MO
  372.         je      ioc_monitor             ; monitor category not supported
  373.  
  374. ;       Sort out which IOCTL function we have.
  375.  
  376.         cmp     ah,IOC_SE
  377.         jne     ioc_unknown             ; not serial device category
  378.  
  379.         mov     bl,al                   ; function in bx for table index
  380.         and     bx,IOMIN_SUBFUNC OR IOMIN_READ ; subfunction and read bits only
  381.         cmp     bx,MAXIOCTL
  382.         ja      ioc_bad                 ; function out of range
  383.  
  384.         shl     bx,1                    ; word offset for dispatch table
  385.         cld                             ; clear direction flag (auto increment)
  386.  
  387. ; If an IOCTL completes successfully, it does a RET or a jump to CmxDone.
  388. ; If it errs (like "invalid baud rate"), it can jump to ioc_99 or
  389. ; Cmx* instead no matter what stack depth it is at, as long
  390. ; as it hasn't modified bp (bp is used to restore the stack).
  391.  
  392.         call    IoctlTab[bx]
  393.         jmp     CmxDone                 ; done and no error.
  394.  
  395. ioc_99: jmp     CmxGenFail              ; "general failure"
  396.  
  397.  
  398. ;**     ioc_bad - unknown ioctl category and/or function
  399. ;       don't return error if they don't want to see it
  400. ;
  401. ;       ENTRY   (es:di) -> request packet
  402. ;
  403. ;       EXIT    jumps to CmxDone or CmxUnknown
  404. ;
  405. ;       USES    none
  406.  
  407. ioc_bad:
  408.         test    es:[di].GIOFunction,IOMIN_IGNERR
  409.         jz      ioc_unknown             ; don't ignore error
  410.  
  411.         jmp     CmxDone                 ; ignore error
  412.  
  413. ioc_unknown:
  414.         jmp     CmxUnknown              ; return 'unknown command'
  415.  
  416. ioc_monitor:
  417.         jmp     CmxMonitor              ; return 'monitors not supported'
  418.  
  419.  
  420. ;**     IOCTL #41 - set baud rate
  421. ;
  422. ioc_sbaud:
  423.         call    VerifyNullD             ; verify null data pointer
  424.         call    GetGIOParaPackW         ; (ax) = baud requested
  425.  
  426.         call    SetBaud                 ; set baud rate if legal
  427.         jnc     ioc_sbx                 ; ok
  428.  
  429.         jmp     CmxInvalidParameter     ;     baud
  430.  
  431. ioc_sbx:
  432.         ret                             ; return normally.
  433.  
  434.  
  435. ;**     IOCTL #42 - set line control (byte size, parity, stop bits)
  436. ;
  437. ; Parmlist contains three bytes: al = ByteSize, ah = Parity, ch = StopBits
  438. ;
  439. ioc_slinec:
  440.         call    VerifyNullD             ; verify null data pointer
  441.         mov     cx,3                    ; number of bytes in the LCR structure
  442.         call    VerifyAddrP             ; verify address
  443.         les     di,es:[di].GIOParaPack  ; es:di -> Data Buffer.
  444.         mov     ax,es:[di]              ; get byte size and parity
  445.         mov     ch,es:[di]+2            ; get stopbits
  446.         SaveReg         <ax,cx>         ; save LCR bytes
  447.         call    CheckLCR                ; verify input values
  448.         jnc     ioc_linec10             ; "General Failure" err w/LCR input
  449.  
  450.         jmp     CmxGenFail              ;     line control, general failure
  451.  
  452. ioc_linec10:
  453.         RestoreReg      <cx,dx>         ; restore byte size and parity
  454.         mov     [si].ci_bytesize,dl     ; No error: put input into ComInfo.
  455.         mov     [si].ci_parity,dh       ; 
  456.         mov     [si].ci_stopbits,ch     ; 
  457.         call    SetLineC                ; Set [si].ci_linec, .ci_cmask
  458.         ret
  459.  
  460.  
  461. ;**     IOCTL #46 - set modem control output signals (DTR and RTS only)
  462. ;
  463. ; uses masks of signals to turn off and on:
  464. ;
  465. ;   WORD where high byte = mask of bits to turn OFF.
  466. ;               low byte = mask of bits to turn ON.
  467. ;
  468. ; Examples:             input              high     low        result
  469. ;  Set    RTS:  WORD = (NOT 0 shl 8 + 2) = 11111111 00000010 ; bit 2 ON
  470. ;  Clear  RTS:  WORD = (NOT 2 shl 8 + 0) = 11111101 00000000 ; bit 2 OFF
  471. ;  Set    DTR:  WORD = (NOT 0 shl 8 + 1) = 11111111 00000001 ; bit 1 ON
  472. ;  Clear  DTR:  WORD = (NOT 1 shl 8 + 0) = 11111110 00000000 ; bit 1 OFF
  473. ;  Set    both: WORD = (NOT 0 shl 8 + 3) = 11111111 00000011 ; bits 1+2 ON
  474. ;  Clear  both: WORD = (NOT 3 shl 8 + 0) = 11111100 00000000 ; bits 1+2 OFF
  475. ;
  476. ; return general failure if the app tries to modify a signal that is being
  477. ;        controled automatically by the drvice driver.
  478. ;
  479. ; return ComErr
  480. ;
  481. ioc_smodemc:
  482.         ; load up return value now in case of     pointer
  483.         mov     ax,[si].ci_comerr
  484.         call    LoadGIODataPackW        ; return ComErr word
  485.  
  486.         call    GetGIOParaPackW         ; ax = control masks
  487.         mov     bx,ax                   ; save in bx
  488.  
  489.         ; verify not trying to modify a signal being used for handshaking
  490.         not     ah                      ; bits being turned off
  491.         or      al,ah                   ; bits being modified
  492.         test    al,NOT (MC_DTR OR MC_RTS OR MC_LOOP)    ; trying to set
  493.                                                         ; reserved fields?
  494.         jnz     ioc_99                  ;  yes, error
  495.  
  496.         test    al,MC_DTR
  497.         jz      ioc_smodemc10           ; not modifying DTR
  498.  
  499.         ; don't have to mask because only DTR_FLOW has bit 10b on
  500.         .errnz  F1_DTR_FLOW    - 00000010b
  501.         .errnz  F1_DTR_INVALID - 00000011b
  502.         test    [si].ci_dcb_flags1,F1_DTR_FLOW
  503.         jnz     ioc_99                          ; DTR handshake - error
  504.  
  505. ioc_smodemc10:
  506.         test    al,MC_RTS
  507.         jz      ioc_smodemc15           ; not modifying RTS
  508.  
  509.         ; don't have to mask because both auto modes have bit 10000000b on
  510.         .errnz  F2_RTS_FLOW   - 10000000b
  511.         .errnz  F2_RTS_TOGGLE - 11000000b
  512.         test    [si].ci_dcb_flags2,F2_RTS_FLOW
  513.         jnz     ioc_99                  ; RTS handshake or toggle - error
  514.  
  515. ioc_smodemc15:
  516.  
  517.         ; Set MCR for standard port. (bx) = control masks
  518.         mov     dx,[si].ci_port         ; need port address for in/out
  519.         add     dx,R_MODMC              ; MCR port
  520.         min     al,dx                   ; Get old MCR value.
  521.         and     al,bh                   ; Turn OFF desired bits.
  522.         or      al,bl                   ; Turn ON desired bits.
  523.         mout    dx,al                   ; Output new MCR value.
  524.  
  525. ioc_smodemcx:
  526.         ret
  527.  
  528. ;**     IOCTL #61 - get baud rate
  529. ioc_gbaud:
  530.         call    VerifyNullP             ; verify null parameter pointer
  531.         mov     ax,[si].ci_baud
  532.         call    LoadGIODataPackW        ; load baud rate
  533.         ret
  534.  
  535.  
  536. ;**     IOCTL #62 - get line control (byte size, parity, stop bits)
  537. ioc_glinec:
  538.         call    VerifyNullP             ; verify null parameter pointer
  539.         mov     cx,4                    ; verify a write of four bytes
  540.         call    VerifyAddrD             ; verify a data address
  541.         les     di,es:[di].GIODataPack  ; es:di -> Data Buffer.
  542.         mov     al,[si].ci_bytesize     ; Data buffer:  byte 0 = bytesize
  543.         mov     ah,[si].ci_parity       ;               byte 1 = parity
  544.         stosw
  545.         mov     al,[si].ci_stopbits     ;               byte 2 = stopbits
  546.         mov     ah,[si].ci_linec        ;               byte 3 = Tx break
  547.         rol     ah,2                    ; roll break bit to bit 0
  548.         and     ah,1                    ; break bit only
  549.         stosw
  550.         ret
  551.  
  552.  
  553. ;**     IOCTL #65 - return tx status
  554. ;
  555. ; Bit   Description
  556. ; 0     queued write requests
  557. ; 1     data in DD tx queue
  558. ; 2     data in holding/shift register
  559. ; 3     character to tx immed
  560. ; 4     xon pending
  561. ; 5     xoff pending
  562. ; 6     reserved
  563. ; 7     reserved
  564. ;
  565. ioc_gtxstat:
  566.         call    VerifyNullP             ; verify null parameter pointer
  567.         xor     ah,ah                   ; clear ah
  568.  
  569.         ; Queued write requests?
  570.         cmp     [si].ci_w_rp._hi,0
  571.         je      short ioc_gtx10         ;  no
  572.         or      ah,1 shl 0              ;  yes
  573. ioc_gtx10:
  574.  
  575.         ; Data in driver transmit queue?
  576.         cmp     [si].ci_qout.ioq_count,0
  577.         je      short ioc_gtx20         ;  no
  578.         or      ah,1 shl 1              ;  yes
  579.  
  580. ioc_gtx20:
  581.  
  582.         ; If standard port, look at LSR to see if data in tx hardware.
  583.         cli
  584.         ReadLSR                         ; (al) = LSR
  585.         sti
  586.         and     al,LS_THRE OR LS_TSRE
  587.         cmp     al,LS_THRE OR LS_TSRE   ; data in tx hardware?
  588.         je      ioc_gtx30               ;  no
  589.         or      ah,1 shl 2              ;  yes
  590.  
  591. ioc_gtx30:
  592.  
  593.         test    [si].ci_hsflag,HS_TX_IMMED ; character waiting to tx immed?
  594.         jz      short ioc_gtx40         ;       no
  595.         or      ah,1 shl 3              ;  yes
  596. ioc_gtx40:
  597.  
  598.         test    [si].ci_hsflag,HS_XON_PENDING ; XON pending?
  599.         jz      short ioc_gtx50         ;  no
  600.         or      ah,1 shl 4              ;  yes
  601. ioc_gtx50:
  602.  
  603.         test    [si].ci_hsflag,HS_XOFF_PENDING ; XOFF pending?
  604.         jz      short ioc_gtx60         ;  no
  605.         or      ah,1 shl 5              ;  yes
  606. ioc_gtx60:
  607.  
  608.         xchg    ah,al
  609.         call    LoadGIODataPackB        ; load tx status
  610.         ret
  611.  
  612.  
  613. ;**     IOCTL #66 - get modem control output signals (DTR and RTS only)
  614. ioc_gmodemc:
  615.         call    VerifyNullP             ; verify null parameter pointer
  616.  
  617. ioc_gmc20:
  618.         ; If standard port, just read MCR.
  619.         mov     dx,[si].ci_port         ; need port address for in/out
  620.         add     dx,R_MODMC              ; Get Modem Control Reg value.
  621.         min     al,dx
  622.  
  623. ioc_gmcx:
  624.         ; (al) = MCR.
  625.         and     al,MC_DTR OR MC_RTS     ; mask reserved bits
  626.         call    LoadGIODataPackB        ; Put AL in the Req Packet data buffer.
  627.         ret
  628.  
  629.  
  630. ;**     IOCTL #67 - get control input signals (from shadow)
  631. ioc_gmodems:                            ; PTR B708056 @@1
  632.         call    VerifyNullP             ; verify null parameter pointer
  633.  
  634.  
  635. gms50:
  636.         ; If standard port, just read MSR.
  637.         mov     dx,[si].ci_port         ; @@1
  638.         add     dx,R_MODMS              ; (dx) -> modem status reg @@1
  639.         cli                             ; @@1
  640.         min     al,dx                   ; (al) = modem status    @@1
  641.         test    al,MS_DCTS OR MS_DDSR OR MS_TERI OR MS_DDCD       ; @@1
  642.         jz      gms90                   ; no MSR changes (interrupt)  @@1
  643.         jmp     SHORT gms80
  644.  
  645. gms80:  call    MxInt                   ; process modem status interrupt @@1
  646.         mov     al,[si].ci_msrshadow
  647.  
  648. gms90:  sti
  649.         call    LoadGIODataPackB        ; Put AL in the Req Packet data buffer.
  650.         ret
  651.  
  652.  
  653. ;**     IOCTL #44 - transmit immediate
  654. ioc_tximmed:
  655.         test    [si].ci_vdm_flag,VDM_Flag_InUse ;CP20D1390 If the port is opened
  656.         jz      tximm_normal_req                ; with special vdm access,
  657.         cmp     [si].ci_nvdmopens,0             ; Transmit Imm is not allowed.
  658.         ljg     CmxInUse                        ;+yn error General Failure
  659.  
  660. tximm_normal_req:
  661.         call    VerifyNullD                     ; verify null data pointer
  662.         call    GetGIOParaPackB                 ; get byte to Tx
  663.         cli
  664.         test    [si].ci_hsflag,HS_TX_IMMED ; already one pending?
  665.         jz      txim10                          ;  no, were cool
  666.         sti
  667.         jmp     CmxGenFail                      ;  yes, general failure
  668.  
  669. txim10: mov     [si].ci_tximm,al             ; save char
  670.         or      [si].ci_hsflag,HS_TX_IMMED      ; flag TxImm char pending
  671.  
  672. txim20:
  673.         ;NOTE interrupts are still off for CheckTX
  674.         call    CheckTX                         ; kick transmitter into action.
  675.  
  676. tximmx: sti
  677.         ret
  678.  
  679.  
  680. ;**     IOCTL #47 - as if XOFF received
  681. ioc_rxoff:
  682.         call    VerifyNullP             ; verify null parameter pointer
  683.         call    VerifyNullD             ; verify null data pointer
  684.  
  685. off20:
  686.         cli
  687.         or      [si].ci_HSFlag,HS_XOFF_RECEIVED
  688.         call    CheckTX
  689.  
  690.         sti
  691. offx:   ret
  692.  
  693.  
  694. ;**     IOCTL #48 - as if XON received
  695. ioc_rxon:
  696.         call    VerifyNullP             ; verify null parameter pointer
  697.         call    VerifyNullD             ; verify null data pointer
  698.  
  699. on20:
  700.         cli
  701.         and     [si].ci_HSFlag,NOT HS_XOFF_RECEIVED ; Show XOff NOT received
  702.         call    CheckTX
  703.         sti
  704.  
  705. onx:    ret
  706.  
  707.  
  708. ;**     IOCTL #4B - tx break on (stop transmitting)
  709. ioc_break1:
  710.         call    VerifyNullP             ; verify null parameter pointer
  711.         call    LoadGIODataPackW        ; verify valid data parameter
  712.         cli                             ; See ioctl 45
  713.  
  714.         or      [si].ci_HSFlag,LC_BREAK ; set the break bit
  715.         .errnz  HS_BREAK_SET-LC_BREAK
  716.  
  717. brk110:
  718.         mov     al,[si].ci_linec        ; get line control
  719.         or      al,LC_BREAK             ; set break bit
  720.         call    SetLineC
  721.         call    CheckTX
  722.  
  723. brk1x:  sti
  724.         mov     ax,[si].ci_comerr
  725.         call    LoadGIODataPackW        ; Return ComErr word, w/o clearing it.
  726.         ret
  727.  
  728.  
  729. ;**     IOCTL #45 - tx break off (resume tranmitting)
  730. ioc_break0:
  731.         call    VerifyNullP             ; verify null parameter pointer
  732.         call    LoadGIODataPackW        ; verify valid data parameter
  733.         cli
  734.         and     [si].ci_HSFlag,not LC_BREAK     ; clear the break bit
  735.         .errnz  HS_BREAK_SET-LC_BREAK
  736.  
  737. brk010:
  738.         mov     al,[si].ci_linec                ; get line control
  739.         and     al,not LC_BREAK                 ; clear break bit
  740.         call    SetLineC
  741.         call    CheckTX                         ; restart transmission
  742.  
  743. brkx:   sti
  744.         mov     ax,[si].ci_comerr
  745.         call    LoadGIODataPackW        ; Return ComErr word, w/o clearing it.
  746.         ret
  747.  
  748.  
  749. ;**     IOCTL #68 - return # of characters in and size of receive queue
  750. ;
  751. ;       NOTE    Usable size of queue is one less than declared (QI_SIZE - 1).
  752.  
  753. ioc_gistat:
  754.         lea     bx,[si].ci_qin          ; get pointer to input queue
  755.         mov     dx,QI_SIZE - 1
  756.         jmp     SHORT ioc_giostat
  757.  
  758.  
  759. ;**     IOCTL #69 - return # of characters in and size of transmit queue
  760. ;
  761. ;       NOTE    Usable size of queue is one less than declared (QO_SIZE - 1).
  762.  
  763. ioc_gostat:
  764.         lea     bx,[si].ci_qout         ; get pointer to queue
  765.         mov     dx,QO_SIZE - 1
  766.  
  767. ioc_giostat:
  768.         call    VerifyNullP             ; verify null parameter pointer
  769.         mov     cx,4                    ; verify a write of four bytes
  770.         call    VerifyAddrD             ; verify a data address
  771.         les     di,es:[di].GIODataPack  ; es:di -> Data Buffer.
  772.         mov     ax,[bx].ioq_count       ; # of chars in Queue
  773.         stosw
  774.         mov     ax,dx                   ; size
  775.         stosw
  776.         ret
  777.  
  778.  
  779. ;**     IOCTL #72 - get (and clear) com event word
  780. ioc_gevent:
  781.         call    VerifyNullP             ; verify null parameter pointer
  782.         xor     ax,ax                   ; ax = 0
  783.         xchg    ax,[si].ci_event        ; Get the current event word
  784.         call    LoadGIODataPackW        ; Return the event
  785.         ret
  786.  
  787.  
  788. ;**     IOCTL #64 - return com status
  789. ;
  790. ; the ComStatus byte is defined as follows:
  791. ;
  792. ;   CST_CTS_HOLD    = 01h  Tx waiting for CTS
  793. ;   CST_DSR_HOLD    = 02h  Tx waiting for DSR
  794. ;   CST_DCD_HOLD    = 04h  Tx waiting for DCD
  795. ;   CST_XOFF_HOLD   = 08h  Tx waiting because XOFF received
  796. ;   CST_XOFF_SENT   = 10h  Tx waiting because XOFF transmitted
  797. ;   CST_BREAK_HOLD  = 20h  Tx waiting because break being xmitted
  798. ;   CST_TX_IMMED    = 40h  Character waiting to transmitt immediate
  799. ;   CST_RX_DSR_HOLD = 80h  Receive waiting for DSR
  800. ;
  801. ; Need to get the status for a com port.  Since not all the status is
  802. ; contained within ci_status, it has to be assembled.
  803. ; Note: MSR has active low values (0 = on, 1 = off)
  804.  
  805. ioc_gcomstat:
  806.         call    VerifyNullP             ; verify null parameter pointer
  807.         xor     ah,ah
  808.  
  809.         ; get DSR CTS DCD
  810.         mov     al,[si].ci_msrshadow    ; (al) = msrshadow
  811.  
  812.         ; (al) = MSR
  813. gcs03:  not     al                      ; (al) = NOT msrshadow - which are down
  814.         mov     bl,al                   ; (bl) = NOT msrshadow - which are down
  815.         and     al,[si].ci_outhhslines  ; only bits being used for handshaking
  816.         shl     ax,1                    ; shift DCD into ah
  817.         shl     al,1                    ; shift DSR and CTS next to DCD
  818.         shr     ax,6                    ; shift into position
  819.         .errnz        MS_CTS-00010000b
  820.         .errnz        MS_DSR-00100000b
  821.         .errnz        MS_DCD-10000000b
  822.         .errnz  CST_CTS_HOLD-00000001b
  823.         .errnz  CST_DSR_HOLD-00000010b
  824.         .errnz  CST_DCD_HOLD-00000100b
  825.  
  826.  
  827.         ; Standard port:
  828.         cli
  829.         mov     ah,[si].ci_HSFlag                       ; handshake flag
  830.         and     ah,HS_XOFF_RECEIVED OR HS_XOFF_SENT     ; xoff rx/txed flags
  831.         or      al,ah                                   ;Fix
  832.         sti
  833.         test    [si].ci_dcb_flags2,F2_FULL_DUP
  834.         jz      gcs09                           ; full dup NOT on
  835.         and     ah,NOT HS_XOFF_SENT             ; full dup ON, tx doesn't wait
  836. gcs05:  or      al,ah
  837.         .errnz  HS_XOFF_RECEIVED-00001000b
  838.         .errnz     CST_XOFF_HOLD-00001000b
  839.         .errnz      HS_XOFF_SENT-00010000b
  840.         .errnz     CST_XOFF_SENT-00010000b
  841.  
  842.  
  843. gcs09:
  844.         ; Get BreakHold
  845.         test    [si].ci_hsflag,HS_BREAK_SET     ; handshake flag
  846.         jz      gcs10
  847.         or      al,CST_BREAK_HOLD
  848. gcs10:
  849.  
  850.         ; Get TxImmed
  851.         test    [si].ci_hsflag,HS_TX_IMMED
  852.         jz      gcs20
  853.         or      al,CST_TX_IMMED         ; show TX_IMMED pending
  854. gcs20:
  855.  
  856.         ; Get F1_IN_DSR_SENSE
  857.         test    [si].ci_dcb_flags1,F1_IN_DSR_SENSE ; input sensitivity to DSR?
  858.         jz      ioc_comstatx            ;  no, can't be waiting for it
  859.         and     bl,MS_DSR               ; mask off DSR from MSR above
  860.         shl     bl,2                    ; shift into position
  861.         or      al,bl
  862.         .errnz           MS_DSR-00100000b
  863.         .errnz          CST_RX_DSR_HOLD-10000000b
  864.  
  865. ioc_comstatx:
  866.         call    LoadGIODataPackB        ; load status
  867.         ret
  868.  
  869.  
  870. ;**     IOCTL #6D - return (and clear) com error word
  871. ioc_gcomerr:
  872.         call    VerifyNullP             ; verify null parameter pointer
  873.         xor     ax,ax
  874.         xchg    ax,[si].ci_comerr
  875.         call    LoadGIODataPackW
  876.         ret
  877.  
  878.  
  879. ;**     IOCTL #53 - set device control block (DCB)
  880. ;
  881. ; see spec and include files for definitions of the DCB structure
  882. ;
  883. ioc_sdcb:
  884.         call    VerifyNullD             ; verify null data pointer
  885.         mov     cx,DCB_SIZE             ; # bytes in the DCB structure
  886.         .errnz  DCB_SIZE - 11
  887.         call    VerifyAddrP             ; verify address
  888.  
  889.         xchg    si,di                   ; (ds:di) -> ComInfo
  890.                                         ; (es:si) -> request packet
  891.         SaveReg         <ds>
  892.         lds     si,es:[si].GIOParaPack  ; (ds:si) -> new DCB parameters
  893.         RestoreReg      <es>            ; (es:di) -> ComInfo struc
  894.  
  895.         ; check for invalid values in the DCB request
  896.  
  897.         mov     al,[si].ci_dcb_flags1           ; al = new flags1
  898.         mov     bl,[si].ci_dcb_flags3           ; bl = new flags3
  899.  
  900.         test    al,F1_RESERVED
  901.         ljnz    ioc_genfail                     ; reserved bits on
  902.  
  903.         .errnz  F3_READ_TO_MASK - 00000110b
  904.         .errnz  F3_READ_TO_BAD  - 00000000b
  905.         test    bl,F3_READ_TO_MASK
  906.         jz      ioc_genfail                     ;     read timeout
  907.  
  908. ; if (new flags3 fifo mode is zero)
  909. ;   use old flags3 fifo bits and new flags3 other bits
  910. ; else if (new flags3 is non-zero)
  911. ;   if (fifo not available)
  912. ;     general failure
  913. ; set flags3 after copying to dd memory (can't change user memory)
  914.  
  915.         mov     bh,es:[di].ci_dcb_flags3        ; bh = old f3
  916.         test    bl,F3_FIFO_MASK
  917.         jnz     sdcb2                           ; setting fifo mode, go verify
  918.  
  919. ; the FIFO mode is zero, ignore all the fifo flags (use old values)
  920.         and     bh,F3_FIFO_ALL                  ; bh = old f3 with fifo only
  921.         and     bl,NOT F3_FIFO_ALL              ; bl = new f3 with no fifo
  922.         or      bl,bh                           ; bl = new f3 with old fifo
  923.         jmp     SHORT sdcb4
  924.  
  925. ; user is attempting to set the FIFO mode.  Fail if no FIFO available.
  926. sdcb2:  test    bh,F3_FIFO_MASK
  927.         jz      ioc_genfail                     ; fifo not available
  928.  
  929.         ; RTS mode cannot be invalid
  930.  
  931.         ; check DTR modes
  932.         .errnz  F1_DTR_ENABLE - 00000001b
  933.         .errnz  F1_DTR_FLOW   - 00000010b
  934.  
  935. sdcb4:  and     al,F1_DTR_MASK          ; only the DTR bits
  936.         cmp     al,F1_DTR_INVALID
  937.         je      ioc_genfail             ; invalid DRT mode
  938.  
  939.  
  940.         ; all values are valid - put values into ComInfo
  941.  
  942.         ; save old flags1 and flags2 for ComputeHHS
  943.         mov     al,es:[di].ci_dcb_flags1        ; al = old flags1
  944.         mov     ah,es:[di].ci_dcb_flags2        ; ah = old flags2
  945.         SaveReg         <ax>                    ; save old flags 1 and 2
  946.  
  947.         ; all values are valid - put values into ComInfo
  948.         SaveReg         <di>                    ; save ComInfo pointer
  949.         .errnz  ci_dcb_writeto
  950.         mov     cx,DCB_SIZE
  951.         .errnz  DCB_SIZE - 11
  952.  
  953.         cli     ; no interrupts while we set up the new modes
  954.  
  955.         rep movsb                               ; copy DCB structure
  956.  
  957.         RestoreReg      <si>                    ; ComInfo pointer
  958.  
  959.         push    es
  960.         pop     ds                              ; (ds:si) -> ComInfo struc
  961.         ChkComInfoPtr
  962.  
  963.         mov     [si].ci_dcb_flags3,bl           ; save valid flags3
  964.  
  965. ; ComputeAPO MUST be called before ComputeXTO because the timeouts
  966. ; are based on the number of characters per interrupt.
  967.  
  968. ;@89343 Because some applications may wish to modify the Read T/O or
  969. ;       the Write T/O and these values are part of the Function #53,
  970. ;       we do not want to be changing the FIFO unless the FIFO flags
  971. ;       have been changed.  This is especially important because of
  972. ;       the SMC patches applied in ComputeAPO.  Also remember that
  973. ;       ComputeAPO will be called at ComOpen if a FIFO exists so the
  974. ;       initial values will be set at least one time.  This fix is to
  975. ;       handle the function 53 calls made while actively reading /
  976. ;       writing to the port.
  977. ;
  978.                                         ; @89343 start
  979.         cmp         bh,bl               ; bh = old, bl = new
  980.         je          sdcb10              ; No change, then skip FIFO
  981.  
  982.         SaveReg     <bx>                ; Save register
  983.         and         bh,F3_FIFO_ALL      ; mask bits 0 - 2
  984.         and         bl,F3_FIFO_ALL      ; mask bits 0 - 2
  985.         cmp         bh,bl               ; bh,bl masked off
  986.         RestoreReg  <bx>                ; Restore Register Back
  987.         je          sdcb10              ; No Status Change in Flags.
  988.                                         ; @89343 end
  989.  
  990.         call    ComputeAPO              ; compute FIFO modes
  991.  
  992. sdcb10:
  993. ; always recalc read/write timeouts as timeout, RX trig or TX count
  994. ; may have changed.  Easier to always recalc than to check.
  995.         call    ComputeRTO              ; calculate new read  timeout values
  996.         call    ComputeWTO              ; calculate new write timeout values
  997.  
  998.         RestoreReg      <bx>            ; bl = old flags1, bh = old flags2
  999.         ; set DTR/RTS according to old/new DTR/RTS modes
  1000.         call    ComputeHHS                      ; calculate new hs masks
  1001.  
  1002.  
  1003. ;Port is standard:
  1004. ;if buffer full
  1005. ;  call DisableRemoteTX
  1006. ;else
  1007. ;  call EnableRemoteTX.  (This call is necessary to get DTR and RTS
  1008. ;  raised when we are transitioning from DTR and RTS off to input HS.
  1009. ;endif
  1010.  
  1011.         cmp     [si].ci_qin.ioq_count,RX_HIGH_HS ;cj test to see if it's
  1012.                                                  ;cj above HW mark
  1013.         jle     sdcb12                  ;cj jump if RXQ is below high water mark
  1014.         call    DisableRemoteTX         ;cj go drop input HS lines or
  1015.                                         ;cj send XOFF as appropriate
  1016.         jmp     SHORT sdcb14            ;cj
  1017.  
  1018. sdcb12:
  1019.         call    EnableRemoteTX          ;cj go raise HS lines or
  1020.                                         ;cj send XON as appropriate
  1021.  
  1022. ;Port is standard:
  1023. ;if ATF disabled
  1024. ;  reset XOFF_RECEIVED flag
  1025. ;endif
  1026.  
  1027. sdcb14:
  1028.         test    [si].ci_dcb_flags2,F2_OUT_XO  ;cj test if ATF enabled
  1029.         jnz     sdcb16                        ;cj jump if yes
  1030.         and     [si].ci_hsflag,NOT HS_XOFF_RECEIVED
  1031.                                               ;cj else turn off XOFF_Received
  1032.                                               ;cj flag
  1033.  
  1034. ;Port is standard:
  1035. ;if ARF disabled
  1036. ;  call EnableRemoteTXXO.  We may have to send an XON, and we would
  1037. ;  have to do this regardless of the status of the receive buffer.
  1038. ;  We can't call EnableRemoteTX because EnableRemoteTX only works
  1039. ;  when ARF is enabled.
  1040. ;endif
  1041.  
  1042. sdcb16:
  1043.         test    [si].ci_dcb_flags2,F2_IN_XO  ;cj test if ARF is enabled
  1044.         jnz     sdcb18                       ;cj jump if yes
  1045.         call    EnableRemoteTXXO             ;cj else go send XON
  1046.  
  1047. ;if input HS was disabled, then the HS lines would have been set
  1048. ;appropriately when ComputeHHS was called above.
  1049. ;
  1050.  
  1051. sdcb18:
  1052.         call    CheckTX                 ;cj
  1053.  
  1054. sdcb20:
  1055.         ; call MxInt to set FX_IN_DSR_OK in case F1_IN_DSR_SENSE mode changed
  1056.         mov     al,[si].ci_msrshadow    ; (al) =  modem status register shadow
  1057.         call    MxInt                   ; calls CheckTX
  1058.  
  1059. sdcbx:  sti                     ; all modes set, ok for interrupts again
  1060.  
  1061.         ret
  1062.  
  1063. ioc_genfail:                            ; intermediate jump point
  1064.         jmp     CmxGenFail              ; general failure
  1065.  
  1066.  
  1067. ;**     IOCTL #73 - get device control block
  1068. ioc_gdcb:
  1069.         call    VerifyNullP             ; verify null parameter pointer
  1070.         mov     cx,DCB_SIZE             ; # bytes in the DCB structure
  1071.         call    VerifyAddrD             ; verify data address
  1072.  
  1073.         .errnz  DCB_SIZE - 11
  1074.  
  1075.         lea     si,[si].ci_dcb_writeto          ; (ds:si) -> DCB in ComInfo
  1076.         les     di,es:[di].GIODataPack          ; (es:di) -> Data Buffer.
  1077.  
  1078.         rep movsb                               ; copy DCB structure
  1079.  
  1080.         ret
  1081.  
  1082. ;************************************************************************
  1083. ;* IOCTL #74   ioc_gENH
  1084. ;*
  1085. ;*   Return Com Enhanced parameters  Information (74h)
  1086. ;*
  1087. ;* FUNCTION:    Retrieves the Enhanced Mode information from ComInfo.
  1088. ;
  1089. ; Bit           Description
  1090. ;
  1091. ; 0             Enhanced mode supported by haardware
  1092. ; 1             Enhanced mode enabled
  1093. ; 2,3           DMA Recieve Operation Request
  1094. ;       00      DMA Receive Disabled
  1095. ;       01      DMA Receive Auto
  1096. ;       10      DMA Receive Dedicated
  1097. ;       11      Reserved
  1098. ; 4,5           DMA Transmit Operation Request
  1099. ;       00      DMA Transmit Disabled
  1100. ;       01      DMA Transmit Auto
  1101. ;       10      DMA Transmit Dedicated
  1102. ;       11      Reserved
  1103. ; 6             Last receive used DMA
  1104. ; 7             Last transmit used DMA
  1105. ioc_genh:
  1106.  
  1107.         call    VerifyNullP             ; make sure param pkt pointer is NULL
  1108.         mov      cx,1
  1109.         call    VerifyAddrD             ; make sure data buffer addr is valid
  1110.  
  1111.         ; (AL) = enhanced flags
  1112.         ; set bits 0,1,6,7
  1113.         mov     al,[si].ci_eflags
  1114.         and     al,11000011b
  1115.  
  1116.         ; set bits 2,3
  1117.         mov     ah,[si].ci_tx_request
  1118.         shl     ah,2
  1119.         or      al,ah
  1120.         ; set bits 4,5
  1121.         mov     ah,[si].ci_rx_request
  1122.         shl     ah,4
  1123.         or      al,ah
  1124.  
  1125.         call    LoadGIODataPackB
  1126.  
  1127.        ret                              ; return through ComIoctl
  1128.  
  1129. ;************************************************************************
  1130. ;* IOCTL #54   ioc_sENH
  1131. ;*
  1132. ;*   Set Enhanced Mode Parameters (54h)
  1133. ;*
  1134. ;* FUNCTION:    Verifies that all Flags passed in are valid.
  1135. ;*              Updates the Enhanced flags in ComInfo.
  1136. ;*
  1137.  
  1138. ioc_sENH:
  1139.         jmp     CmxGenFail              ; hardware doesn't support enhanced
  1140.  
  1141. ;************************************************************************
  1142. ;* IOCTL #63  ioc_gbaudENH
  1143. ;*
  1144. ;*  Get Extended Baud Rate (63h)
  1145. ;*
  1146. ;*  Returns port Data Transfer Rate (in ComInfo) to user.
  1147. ;*
  1148.  
  1149. ioc_gbaudenh:
  1150.  
  1151.      call    VerifyNullP                ; make sure null parm pkt pointer
  1152.      mov     cx,15                      ; length of packet
  1153.      call    VerifyAddrD                ; verify data address
  1154.      ; put baud rate into RP Data Area
  1155.      SaveReg         <si>
  1156.      .386p
  1157.      les     di,es:[di].GIODataPack     ; (es:di) -> IOCTL data packet
  1158.  
  1159.      movzx   eax,[si].ci_baud           ; ax = baud data
  1160.                                         ; high part of eax = 0
  1161.      stosd                              ; Baud
  1162.      xor     al,al
  1163.      stosb                              ; Baud Frac
  1164.  
  1165.      mov     ax,MINBAUD
  1166.      stosd                              ; Baud Min
  1167.      xor     al,al
  1168.      stosb                              ; Min Frac
  1169.  
  1170.      mov     ax,MAX_EBAUD
  1171.      stosd                              ; Baud Max
  1172.      xor     al,al
  1173.      stosb                              ; Max Frac
  1174.  
  1175.    .286p
  1176.      RestoreReg      <si>
  1177.      ret
  1178.  
  1179. ;************************************************************************
  1180. ;* IOCtl #43 ioc_sbaudENH
  1181. ;*
  1182. ;* Set Extended (bit) Baud Rate  (43h)
  1183. ;*
  1184. ;*   Calls SetBaud to validate and set the Baud Rate.
  1185. ;*   Calls ComputeTPC to compute the new tick per char
  1186. ;*   value.
  1187. ;*
  1188.  
  1189. ioc_sbaudenh:
  1190.  
  1191.         call    VerifyNullD            ; verify null data pointer
  1192.         mov     cx,5                   ; parameter packet is 5 bytes long
  1193.         call    VerifyAddrP            ; verify parameter address, cx = size
  1194.         push    bx
  1195.         SaveReg <es,di>
  1196.         les     di,es:[di].GIOParaPack ; (ds:si) -> IOCTL paramaters
  1197.         .386p
  1198.         mov     eax,es:[di]            ; load double word baud rate
  1199.         .286p
  1200.         xor     bx,bx
  1201.         mov     bl,es:[di]+4           ; fraction
  1202.         RestoreReg <di,es>
  1203.         call    SetBaud                ; set baud rate if legal
  1204.                                        ; (only uses ax so no problem)
  1205.         pop     bx
  1206.         jnc     ioc_sbex
  1207.  
  1208.         jmp     CmxInvalidParameter    ;     baud
  1209.  
  1210. ioc_sbex:
  1211.         ret                            ; return normally.
  1212.  
  1213.  
  1214. ;##MAF end
  1215.  
  1216. EndProc ComIoctl
  1217.  
  1218. CSEG ENDS
  1219.  
  1220. END
  1221.  
  1222.