home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / ATCOM / ATEISAI.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  33KB  |  780 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 = @(#)ateisai.asm        6.3 91/04/22
  13. ; ***************************************************************************
  14. ; *
  15. ; *
  16. ; *
  17. ; ***************************************************************************
  18.  
  19.         PAGE ,132
  20.         .286c
  21.  
  22.         TITLE   com01.sys - Asynchronous Communication Device Driver
  23.         NAME com01
  24.  
  25. ;***    ateisai.asm - Parse EISA configuration for COM port
  26. ;                     information.  This information will be used
  27. ;                     to intitialize the driver's data structures.
  28. ;
  29. ;   EisaInit - Entry point for EISA init. code
  30. ;
  31. ;       Modification History
  32. ;
  33. ;       ACW     04/16/91        @PVW Added perfview counters/timers
  34. ;
  35. ;       WDM     04/21/94        82548 - pvwxport.inc now included in atcom.inc
  36. ;
  37.  
  38.  
  39. .xlist
  40. ; 82548 include pvwxport.inc            ;@PVW
  41. include basemaca.inc                    ; various macro's (break, ljc, etc.)
  42. include devsym.inc
  43. include devhlp.inc                      ; definition of device help calls.
  44. include infoseg.inc                     ; structures defining the infoseg.
  45. include filemode.inc                    ; file system file mode equates.
  46. include struc.inc                       ; structured macros
  47. .list
  48. include atcom.inc
  49. include ateisa.inc                      ; equates for eisa COM code
  50. include eisa.inc
  51.  
  52.         EXTRN   DOSDEVIOCTL:far
  53.         EXTRN   DOSOPEN:far
  54.  
  55. HSEG    SEGMENT
  56.  
  57.         PUBLIC  IsEISA
  58.         PUBLIC  SystemCOMs
  59.  
  60.  
  61. oemhlp_name     db      "OEMHLP$ ",0    ; OEMHLP$ name
  62. dev_str         db      "COM"           ; device id
  63. LEN_DEV_STR     equ     $-dev_str       ; string length
  64. type_str        db      "ASY"           ; device type
  65. LEN_TYP_STR     equ     $-type_str      ; string length
  66. sub_str         db      "COM"           ; device subtype
  67. LEN_SUB_STR     equ     $-sub_str       ; string length
  68. semi_str        db      ";"             ; subtype delimiter
  69. LEN_SEMI_STR    equ     $-semi_str      ; string length
  70. Slot            EisaSlotInfo <>         ; Slot info.
  71. Function        EisaFuncInfo <>         ; Function info.
  72. EisaCall        EisaCallParameters <>   ; EISA call info.
  73. COMsFound       db      LEN_EISACOM_STRUC * MAXECOMPORTS DUP (0)   ; array for EISA info.
  74. SystemCOMs      db      LEN_EISACOM_STRUC * MAXECOMPORTS DUP (0)   ; array for all system COM ports
  75. com_index       db      0               ; offset in to COMsFound array
  76. bios_found      dw      MAXISACOMPORTS DUP (0) ; match found in EISA config. info
  77. Temp_COMFound   EISACom <>              ; temp variable for sorting
  78. IsEISA          db      0               ; flag indicating valid EISA info.
  79. oemhlp_handle   dw      0               ; handle for file access
  80. action          dw      0               ; DOSOPEN parameter
  81.  
  82. HSEG    ENDS
  83.  
  84. FA_SYSTEM       equ     4               ; system file attribute
  85. OEMHLP_CAT      equ     80h             ; DOSDEVIOCTL category
  86. OPN_EXIST       equ     0001h           ; open an existing file/create a file
  87. OPN_RDWRACC     equ     0042h           ; read/write access
  88.  
  89.  
  90. RSEG    SEGMENT PUBLIC  'RESCODE'
  91.         ASSUME  CS:RSEG,DS:HSEG,ES:NOTHING,SS:NOTHING
  92.  
  93. ;**     EisaInit - entry point for EISA init. processing.
  94. ;
  95. ;       This subroutine will get called from ComInit to check
  96. ;       for the presence of an EISA system.  If
  97. ;       running on an EISA system, then this routine will
  98. ;       parse the EISA system's non-volatile configuration CMOS,
  99. ;       looking for COM port information.  This information will be
  100. ;       stored in a table, for use during ComInit's set-up of the 'ComN'
  101. ;       data structures.
  102. ;
  103. ;       ENTRY   None
  104. ;
  105. ;       EXIT    IsEISA flag = 1 if EISA COM ports found
  106. ;                           = 0 otherwise
  107. ;
  108. ;       USES    flags, all other regs. restored
  109.  
  110.         PUBLIC EisaInit
  111. Procedure EisaInit
  112.         ASSUME  CS:RSEG,DS:HSEG,ES:NOTHING,SS:NOTHING
  113.  
  114.         pusha                           ; save all regs.
  115.         push    es                      ; and ES, too
  116.         call    OpenOEMHLP              ; get access to OEMHLP$ driver,
  117.         .if     < c >                   ; error?
  118.             jmp     exit_eisai          ;  Y: exit
  119.         .endif
  120.         mov     cl, 0                   ; first slot #
  121.  
  122.         push    ds                      ; set ES to our DGROUP
  123.         pop     es
  124.  
  125. slot_loop:
  126.         call    GetSlotInfo             ; get info. for first slot
  127.         .if     < ah ne 0 >             ; error?
  128.             .if     < ah e EISA_ERROR_EMPTY_SLOT > ; empty slot?
  129.                 inc     cl              ;  Y: go to next slot number,
  130.                 jmp     slot_loop       ;     and process next slot
  131.             .elseif < ah e EISA_INVALID_SLOT >  ; invalid slot?
  132.                 jmp     reconcile       ;  Y: reconcile info. found
  133.             .else                       ; not invalid or empty, so error exit
  134.                 jmp     exit_eisai      ; then exit
  135.             .endif
  136.         .else                           ; Valid slot, check for I/O ports
  137.             .if < bit Slot.esi_fbFunc and EISA_HAS_IO_ENTRIES > I/O ports on this slot?
  138.                 mov     ch, Slot.esi_cbFunc    ; Y: get number of functions
  139.                 dec     ch              ; make it relative to 0
  140.  
  141. function_loop:
  142.                 call    GetFuncInfo     ; get 320 byte record for this func.
  143.                 .if     < ah ne 0 >     ; Error?
  144.                     stc                 ;  Y: indicate error, then
  145.                     jmp     exit_eisai  ;  error exit
  146.                 .endif
  147.  
  148.                 lea     si, Function.efi_achType   ; point to device string
  149.                 lea     di,  dev_str    ; device string to look for
  150.                 mov     ax, LEN_DEV_STR ; string length
  151.                 call    strncmp         ; is this function a COM device?
  152.                 .if     < z > and       ;  Y: also check to see if it's enabled
  153.                 .if     < bit Function.efi_fbFunction z EISA_FUNC_ENABLED > ; if enabled
  154.                     lea     si, Function.efi_achType    ; point to dev. string
  155.                     add     si, LEN_DEV_STR             ; point to the comma
  156.                     inc     si          ; point to the type string
  157.                     lea     di, type_str ; type string to look for
  158.                     mov     ax, LEN_TYP_STR ; string length
  159.                     call    strncmp     ; is this an asynchronous port?
  160.                     .if     < z >
  161.                         call    RecordFunc  ;  Y: store the information
  162.                     .endif
  163.                 .endif
  164.                 .if     < com_index e MAXECOMPORTS >  ; Just found eighth COM port?
  165.                     jmp     reconcile   ;  Y: no need to search further
  166.                 .endif
  167.                 dec     ch              ; next function to check
  168.                 .if     < ch ge 0 >     ; More functions to check?
  169.                     jmp     function_loop       ;  Y: check next function
  170.                 .endif
  171.             .endif                      ; I/O ports
  172.         .endif                          ; No error on slot call
  173.         inc     cl                      ; next slot to check
  174.         jmp     slot_loop               ; check next slot
  175.  
  176. reconcile:
  177.         .if     < com_index g 0 >       ; if any COM info. found, then
  178.             call    CompareBIOS         ;  compare results to BIOS data area
  179.             call    AddEISA             ;  then add in any EISA only COM ports
  180.             mov     IsEISA, 1           ;  indicate valid data
  181.         .endif
  182.  
  183. exit_eisai:
  184.         pop     es                      ; restore regs.
  185.         popa
  186.         ret
  187. EndProc EisaInit
  188.  
  189. ;**     AddEISA - Add in EISA COM ports.
  190. ;
  191. ;       This routine fills in the data structure used to init. the driver
  192. ;       with any information that was found on non-ISA compatible
  193. ;       COM ports.  These are COM ports that do not begin
  194. ;       at the ISA compatible port addresses.
  195. ;
  196. ;       ENTRY   None.
  197. ;
  198. ;       EXIT    None.
  199. ;
  200. ;       USES    All registers destroyed.
  201. ;
  202.  
  203. public  AddEISA
  204. AddEISA         proc    near
  205.  
  206.         .if     < com_index e 0 >       ; already matched up all the
  207.             ret                         ;  EISA COM ports, so just exit
  208.         .endif
  209.  
  210.         .if     < com_index g 1 >       ; if more than one un-matched
  211.                                         ;  EISA COM port remaining
  212.             ; bubble sort the EISA COM ports
  213.  
  214. bubble_sort:
  215.             xor     dx, dx              ; assume sort is finished
  216.             mov     cx, MAXECOMPORTS    ; number of array items
  217.             dec     cx                  ; adjust to loop count
  218.             mov     si, OFFSET COMsFound ; start of EISA array
  219.  
  220. scan_array:
  221.             mov     al, [si].COMport_number     ; unit number
  222.             mov     di, si
  223.             add     di, LEN_EISACOM_STRUC       ; point to next entry
  224.             .if     < al g [di].COMport_number > ; if these aren't in order
  225.                 mov     dx, 1           ; not through sorting yet
  226.                 push    si              ; save current offset
  227.                 push    cx              ; save loop count
  228.                 push    di              ; save current+1 offset
  229.                 push    si              ; save current offset
  230.                 mov     di, OFFSET Temp_COMFound ; temp buffer
  231.                 mov     cx, LEN_EISACOM_STRUC / 2  ; prepare for word move
  232.                 rep     movsw           ; copy current array entry to temp.
  233.                 pop     di              ; get current offset back
  234.                 pop     si              ; get current+1 offset back
  235.                 push    si              ; save current+1 offset
  236.                 mov     cx, LEN_EISACOM_STRUC / 2  ; prepare for word move
  237.                 rep     movsw           ; copy current+1 to current
  238.                 pop     di              ; get current+1 offset back
  239.                 mov     si, OFFSET Temp_COMFound ; temp buffer
  240.                 mov     cx, LEN_EISACOM_STRUC / 2  ; prepare for word move
  241.                 rep     movsw           ; copy from tmp to current+1
  242.                 pop     cx              ; get loop count back
  243.                 pop     si              ; get current offset back
  244.             .endif
  245.  
  246.             add     si, LEN_EISACOM_STRUC  ; point to next array element
  247.             loop    scan_array          ; check next two items
  248.             .if     < dx e 1 >          ; is the array sorted yet?
  249.                 jmp     bubble_sort     ;  N: try again
  250.             .endif
  251.         .endif
  252.  
  253.         ; Now scan the sorted array, looking for un-used EISA COM ports.
  254.  
  255.         mov     al, MAXISACOMPORTS      ; offset to first available EISA slot
  256.         xor     ah, ah
  257.         mov     bx, LEN_EISACOM_STRUC
  258.         mul     bx                      ; construct an offset in to the
  259.                                         ;  driver's data structure
  260.         mov     di, OFFSET SystemCOMs   ; beginning of driver's data structure
  261.         add     di, ax                  ; first empty entry in driver's data
  262.         mov     cx, MAXECOMPORTS        ; max. number of EISA COM ports
  263.         mov     si, OFFSET COMsFound    ; first entry in EISA array
  264.         mov     dl, MAXISACOMPORTS      ; to keep track of total
  265.         mov     bl, dl                  ; use as an index into int. routines
  266.         xor     bh, bh
  267.         shl     bx, 1                   ; X 2 to create an offset
  268.  
  269. scan_eisa:
  270.         .if     < [si].COMport_number g 0 > and  ; if valid data
  271.         .if     < [si].In_use e 0 > and ; and this COM port is not in use
  272.         .if     < [si].base_addr ne COM1_PORT > and ; and it's not ISA COM1
  273.         .if     < [si].base_addr ne COM2_PORT >     ; or ISA COM2
  274.  
  275.             ; fill in the device driver's data structure with the
  276.             ; EISA config. information
  277.             mov     ax, [si].base_addr  ; get base addr from EISA
  278.             mov     [di].base_addr, ax  ; have the driver use it
  279.             mov     al, [si].IRQ_number ; get IRQ level from EISA
  280.             mov     [di].IRQ_number, al ; have the driver use it
  281.             mov     al, [si].sharable_IRQ  ; get IRQ sharing info. from EISA
  282.             mov     [di].sharable_IRQ, al  ; have the driver use it
  283.  
  284.             add     di, LEN_EISACOM_STRUC  ; point to next free entry
  285.             inc     bx
  286.             inc     bx                  ; point to next int. routine
  287.             inc     dl                  ; add another COM port
  288.             .if     < dl e MAXECOMPORTS > ; max reached?
  289.                 jmp     exit_add        ;  Y: exit
  290.             .endif
  291.         .endif
  292.  
  293.         add     si, LEN_EISACOM_STRUC   ; point to next EISA COM port
  294.         loop    scan_eisa               ; process all EISA COM ports
  295.  
  296. exit_add:
  297.         ret
  298.  
  299. AddEISA         endp
  300.  
  301. ;**     atoi
  302. ;
  303. ;       Converts the string at DS:SI in to an integer value.  Does
  304. ;       not assume NULL termination - searches for the first
  305. ;       non-ASCII digit instead.
  306. ;
  307. ;       ENTRY   (ds:si) -> String to convert
  308. ;
  309. ;       EXIT    if 'C' clear
  310. ;                       AX = integer value
  311. ;               else
  312. ;                       invalid input
  313. ;
  314. ;       USES    Flags, all other registers restored.
  315. ;
  316.  
  317. public  atoi
  318. atoi proc near
  319.  
  320.         push    si                      ; save regs.
  321.         push    bx
  322.         push    cx
  323.         push    dx
  324.  
  325.         xor     ah, ah                  ; clear high order byte
  326.         mov     bx, 1                   ; initial power of ten multiplier
  327.         xor     cx, cx                  ; initial string size
  328.         xor     dx, dx                  ; eventual result
  329.  
  330.         cld                             ; go forward to find the end
  331.  
  332. find_end_digits:
  333.         lodsb                           ; get a char
  334.         .if     < al ge '0' >  and      ; if in range
  335.         .if     < al le '9' >           ;  then
  336.             inc     cx                  ;  increment string size
  337.             jmp     find_end_digits     ;  and keep looking
  338.         .endif
  339.  
  340.         .if     < cx e 0 >              ; no digits found?
  341.             stc                         ;  indicate error
  342.             jmp     exit_atoi           ;  then exit
  343.         .endif
  344.  
  345.         dec     si                      ; back up to non-digit char.
  346.         dec     si                      ; back up to least significant digit
  347.         std                             ; go backwards from least to most sig.
  348.  
  349. convert:
  350.         lodsb                           ; get a digit
  351.         sub     al, '0'                 ; strip off the ASCII portion
  352.         push    dx                      ; save the work in progress
  353.         mul     bx                      ; calculate this position
  354.         pop     dx                      ; retrieve work done so far
  355.         add     dx, ax                  ; accumulate this new position
  356.         .if     < bx e 1 >              ; special case for first time
  357.             mov     bx, 10              ; initial powers of ten value
  358.         .else
  359.             mov     ax, 10              ; to create next power of ten
  360.             push    dx                  ; save work in progress
  361.             mul     bx                  ; create next power of ten
  362.             pop     dx                  ; restore work in progress
  363.             mov     bx, ax              ; put back in powers of 10 reg.
  364.         .endif
  365.         loop    convert                 ; loop until all are converted
  366.  
  367.         mov     ax, dx                  ; move result to return value
  368.         clc                             ; indicate no error
  369.  
  370. exit_atoi:
  371.         pop     dx                      ; restore regs
  372.         pop     cx
  373.         pop     bx
  374.         pop     si
  375.  
  376.         ret
  377.  
  378. atoi    endp
  379.  
  380. ;**     CompareBIOS
  381. ;
  382. ;       This function reconciles the data found in the EISA
  383. ;       config. information with the BIOS data area's COM
  384. ;       base address array.  The purpose of this routine is to
  385. ;       ensure ISA/DOS compatibility.  By looking at the BIOS
  386. ;       data area first, we can handle the possiblity of an ISA
  387. ;       card being plugged in to an EISA machine without a
  388. ;       corresponding EISA config. file.
  389. ;
  390. ;       To accomplish this, two things are done.  First, the EISA
  391. ;       config. information is compared to the BIOS data area.
  392. ;       For each match between the two, an entry is initialized
  393. ;       in the data structure that is used to initialize the driver.
  394. ;       After this is done, the result is checked against the
  395. ;       BIOS data area.  If there are any BIOS data area entries
  396. ;       that do not have a corresponding entry in the data structure used to
  397. ;       initialize the driver, then the driver data structure is filled
  398. ;       in with ISA defaults.
  399. ;
  400. ;       ENTRY   None
  401. ;
  402. ;       EXIT    None
  403. ;
  404. ;       USES    All registers destroyed.
  405. ;
  406.  
  407. public  CompareBIOS
  408. CompareBIOS     proc    near
  409.  
  410.         push    es                      ; save our data selector
  411.         mov     ax, COM_SEG             ; get selector for BIOS data area
  412.         mov     es, ax
  413.         xor     bx, bx                  ; create offset to BIOS data area
  414.  
  415.         mov     cl, com_index           ; number of COM ports in EISA info.
  416.         xor     ch, ch                  ; clear high byte
  417.         mov     di, OFFSET COMsFound    ; beginning of EISA array
  418.  
  419. check_all_EISA_COMs:
  420.         push    cx                      ; save # of EISA COM ports loop count
  421.         mov     cl, MAXISACOMPORTS      ; max. number of BIOS found COM ports
  422.                                         ;  supported
  423.         xor     dx, dx                  ; array index
  424.         push    bx                      ; save beginning index
  425.  
  426. check_all_BIOS_entries:
  427.         mov     ax, [di].base_addr      ; EISA base addr.
  428.         .if     < <word ptr es:[bx]> g 0 > and     ; if there is a BIOS data entry
  429.         .if     < es:[bx] ge ax >       ;  and it could be in range
  430.             mov     ax, [di].end_addr   ; get the end of the range
  431.             .if     < es:[bx] le ax > and ; if in range
  432.             .if     < [di].In_use e 0 > ; and this EISA info. hasn't been used
  433.                 mov     [di].In_use, 1  ; a match has been found, mark this
  434.                                         ;  entry as being in use.
  435.                 push    dx              ; save array index
  436.                 push    bx              ; save offset to BIOS data area
  437.                 mov     ax, dx          ; get array index
  438.                 mov     bx, LEN_EISACOM_STRUC
  439.                 mul     bx              ; create an offset
  440.                 mov     bx, ax          ; set up an index
  441.  
  442.                 ; fill in the device driver's data structure with the
  443.                 ; EISA config. information
  444.                 mov     ax, [di].base_addr      ; get base addr from EISA
  445.                 mov     SystemCOMs[bx].base_addr, ax ; save for use by the driver
  446.                 mov     al, [di].IRQ_number     ; get IRQ level from EISA
  447.                 mov     SystemCOMs[bx].IRQ_number, al  ; save for use by the driver
  448.                 mov     al, [di].sharable_IRQ   ; get IRQ sharing info. from EISA
  449.                 mov     SystemCOMs[bx].sharable_IRQ, al ; save for use by the driver
  450.  
  451.                 pop     bx              ; restore offset to BIOS data area
  452.                 pop     dx              ; restore array index
  453.                 push    bx              ; save offset to BIOS data area
  454.                 mov     bx, dx          ; get the array index
  455.                 shl     bx, 1           ; adjust to word offset
  456.                 mov     bios_found[bx], 1  ; indicate valid info.
  457.                 pop     bx              ; restore offset to BIOS data area
  458.                 dec     com_index       ; keep track of how many EISA LPTs used
  459.             .endif
  460.         .endif
  461.  
  462.         inc     bx
  463.         inc     bx                      ; point to the next BIOS data entry
  464.         inc     dx                      ; next array index
  465.         loop    check_all_BIOS_entries  ; process each valid BIOS entry
  466.  
  467.         pop     bx                      ; restore initial offset to BIOS
  468.         pop     cx                      ; restore EISA loop count
  469.         add     di, LEN_EISACOM_STRUC   ; point to next array entry
  470.         loop    check_all_EISA_COMs     ; process all EISA COM ports found
  471.  
  472.         mov     cx, MAXISACOMPORTS      ; loop counter
  473.         xor     bx, bx                  ; offset into BIOS data area
  474.         mov     di, OFFSET SystemCOMs   ; "save" array
  475.  
  476. fill_in_ISA_values:
  477.         .if     < <word ptr es:[bx]> ne 0 > and    ; if there is a COM port
  478.         .if     < bios_found[bx] e 0 >  ; and no EISA info. was found
  479.  
  480.             ; Fill in the total system COM port array with ISA defaults,
  481.             ; since no EISA config. information was found.
  482.             mov     [di].sharable_IRQ, 0    ; no IRQ sharing
  483.             mov     ax, es:[bx]         ; port addr.
  484.             mov     [di].base_addr, ax  ; have device driver use it
  485.             .if     < ax e COM1_PORT >  ; COM1 base address?
  486.                 mov     [di].IRQ_number, COM1_VEC       ; use IRQ4
  487.             .else                       ; use IRQ3
  488.                 mov     [di].IRQ_number, COM2_VEC
  489.             .endif
  490.         .endif
  491.         inc     bx
  492.         inc     bx                      ; next BIOS data area entry
  493.         add     di, LEN_EISACOM_STRUC   ; next detice driver entry
  494.         loop    fill_in_ISA_values      ; process all BIOS data area COM ports
  495.  
  496.         pop     es                      ; get our data selector back
  497.         ret
  498. CompareBIOS     endp
  499.  
  500. ;**     GetFuncInfo
  501. ;
  502. ;       Set up an IOCTL structure to call OEMHLP for EISA
  503. ;       function information.
  504. ;
  505. ;       ENTRY   <cl> = Slot number requested
  506. ;               <ch> = Function number requested
  507. ;
  508. ;       EXIT    if <ah> = 0
  509. ;                       Variable 'Function' contains result
  510. ;               else
  511. ;                       <ah> contains error code
  512. ;
  513. ;       USES    ax
  514. ;
  515.  
  516. public  GetFuncInfo
  517. GetFuncInfo     proc    near
  518.  
  519.         mov     EisaCall.ecp_SubFunction, EISA_FUNCTION_REQUEST   ; tell OEMHLP$ "get function info."
  520.         mov     EisaCall.ecp_SlotNumber, cl  ; requested slot number
  521.         mov     EisaCall.ecp_FunctionNumber, ch ; requested function number
  522.  
  523.         push    ds
  524.         push    OFFSET Function         ; returned data structure
  525.         push    ds
  526.         push    OFFSET EisaCall         ; parm. list
  527.         push    EISA_FNNUMBER           ; request code for EISA BIOS call
  528.         push    OEMHLP_CAT              ; IOCTL category code
  529.         push    [oemhlp_handle]         ; file handle
  530.         call    DOSDEVIOCTL             ; make call to OEMHLP$
  531.         .if     < ax ne 0 >             ; error?
  532.             mov ah, EISA_INVALID_BIOS_CALL      ;  Y: Indicate not EISA machine
  533.         .else
  534.             mov ah, Function.efi_bReturn      ;  N: Use the EISA return code
  535.         .endif
  536.  
  537.         ret
  538.  
  539. GetFuncInfo     endp
  540.  
  541.  
  542. ;**     GetSlotInfo
  543. ;
  544. ;       Set up an IOCTL structure to call OEMHLP for EISA
  545. ;       slot information.
  546. ;
  547. ;       ENTRY   <cl> = Slot number requested
  548. ;
  549. ;       EXIT    if <ah> = 0
  550. ;                       Variable 'Slot' contains result
  551. ;               else
  552. ;                       <ah> contains error code
  553. ;
  554. ;       USES    ax
  555. ;
  556.  
  557. public GetSlotInfo
  558. GetSlotInfo     proc    near
  559.  
  560.         mov     EisaCall.ecp_SubFunction, EISA_SLOT_REQUEST  ; tell OEMHLP$ "get slot info."
  561.         mov     EisaCall.ecp_SlotNumber, cl  ; requested slot number
  562.  
  563.         push    ds
  564.         push    OFFSET Slot             ; returned data structure
  565.         push    ds
  566.         push    OFFSET EisaCall         ; parm. list
  567.         push    EISA_FNNUMBER           ; request code for EISA BIOS call
  568.         push    OEMHLP_CAT              ; IOCTL category code
  569.         push    [oemhlp_handle]         ; file handle
  570.         call    DOSDEVIOCTL             ; make call to OEMHLP$
  571.         .if     < ax ne 0 >             ; error?
  572.             mov ah, EISA_INVALID_BIOS_CALL      ;  Y: Indicate not EISA machine
  573.         .else
  574.             mov ah, Slot.esi_bReturn  ;  N: Use the EISA return code
  575.         .endif
  576.  
  577.         ret
  578.  
  579. GetSlotInfo     endp
  580.  
  581. ;**     OpenOEMHLP
  582. ;
  583. ;       Uses DOSOPEN to get a handle for access to OEMHLP$
  584. ;
  585. ;       ENTRY   None
  586. ;
  587. ;       EXIT    if 'C' clear
  588. ;                       OEMHLP_handle set
  589. ;               else
  590. ;                       error
  591. ;
  592. ;       USES    AX
  593. ;
  594.  
  595. public OpenOEMHLP
  596. OpenOEMHLP    proc    near
  597.  
  598.         push    ds
  599.         push    OFFSET oemhlp_name      ; device name
  600.         push    ds
  601.         push    OFFSET oemhlp_handle    ; file handle
  602.         push    ds
  603.         push    OFFSET action           ; action taken
  604.         push    0                       ; high order half of file size
  605.         push    0                       ; low order half of file size
  606.         push    FA_SYSTEM               ; file attribute
  607.         push    OPN_EXIST               ; fail if it does not exist
  608.         push    OPN_RDWRACC             ; get read/write access
  609.         push    0                       ; reserved
  610.         push    0                       ; reserved
  611.         call    DOSOPEN                 ; get a handle for OEMHLP$
  612.         .if     < ax e 0 >              ; error?
  613.             clc                         ;  N: indicate no error
  614.         .else
  615.             stc                         ;  Y: indicate error
  616.         .endif
  617.  
  618.         ret
  619.  
  620. OpenOEMHLP    endp
  621.  
  622. ;**     RecordFunc
  623. ;
  624. ;       After a function has been found that is an asynchronous COM device,
  625. ;       this routine is called to save the configuration
  626. ;       of the device.
  627. ;
  628. ;       ENTRY   Function - contains information on a COM device
  629. ;
  630. ;       EXIT    COMs - updated
  631. ;
  632. ;       USES    All registers restored.
  633. ;
  634.  
  635. public  RecordFunc
  636. RecordFunc proc near
  637.  
  638.         pusha                           ; save regs.
  639.         lea     si, Function.efi_achType   ; device type string
  640.         mov     di, OFFSET semi_str     ; delimiter string to look for
  641.         mov     bx, LEN_SEMI_STR        ; length of delimiter string
  642.         mov     ax, EISA_DEVICE_TYPE_LEN ; size of type ASCII string field
  643.         call    ScanString              ; is there a subtype delimiter?
  644.         .if     < nz >                  ;  N: return to caller
  645.             jmp     record_exit
  646.         .endif
  647.  
  648.         mov     di, OFFSET sub_str      ; beginning of subtype string
  649.         mov     bx, LEN_SUB_STR         ; length of subtye string
  650.         inc     si                      ; first char. after subtype delim.
  651.         mov     ax, OFFSET Function     ; beginning of structure
  652.         add     ax, OFFSET efi_achType  ; adjusted to beginning of ASCII
  653.         add     ax, EISA_DEVICE_TYPE_LEN  ; add max. offset
  654.         sub     ax, si                  ; subtract current offset for len.
  655.         call    ScanString              ; is the subtype string 'COM'?
  656.         .if     < nz >                  ;  N: return to caller
  657.             jmp     record_exit
  658.         .endif
  659.  
  660.         dec     si                      ; check to make sure 'COM' is alone:
  661.         cld                             ; make sure we're going forward
  662.         lodsb                           ; get char. right before 'COM'
  663.         .if     < al e ';' > or         ; semicolon?
  664.         .if     < al e ' ' > or         ; or a space?
  665.         .if     < al e TAB >            ; or a TAB?
  666.             nop                         ;  Y: then it's OK, keep going
  667.         .else
  668.             jmp     record_exit         ;  N: something in front of 'COM', exit
  669.         .endif
  670.  
  671.         add     si, LEN_SUB_STR         ; point to unit number
  672.         call    atoi                    ; attempt to convert to integer
  673.         .if     < c >                   ; valid integer?
  674.             jmp     record_exit         ;  N: so exit
  675.         .endif
  676.  
  677.         push    ax                      ; save the integer value
  678.         mov     ax, LEN_EISACOM_STRUC   ; struc. size
  679.         mul     com_index               ;  multiplied by current index
  680.         mov     bx, ax                  ;  yields an offset.
  681.         inc     com_index               ; increment for next time
  682.         pop     ax                      ; get integer back
  683.         mov     COMsFound[bx].COMport_number, al  ; store the unit number
  684.         lea     si, Function.efi_eiri
  685.         lodsb                           ; get IRQ info.
  686.         .if     < bit al and EISA_IRQ_SHARABLE > and      ; is the IRQ sharable?
  687.         .if     < bit al and EISA_IRQ_LEVEL >             ; AND level triggered?
  688.             mov     COMsFound[bx].sharable_IRQ, INT_SHARING   ; it is sharable
  689.         .else
  690.             mov     COMsFound[bx].sharable_IRQ, 0   ; not sharable
  691.         .endif
  692.         and     al, 0Fh                 ; mask off all but IRQ number
  693.         mov     COMsFound[bx].IRQ_number, al    ; store IRQ number
  694.         lea     si, Function.efi_epi    ; port info.
  695.         cld                             ; go forward
  696.         lodsb                           ; get I/O port information
  697.         and     al, EISA_NUMBER_PORTS   ; mask off all but number of ports
  698.         mov     cx, ax                  ; save the number of ports
  699.         lodsw                           ; get base port addr
  700.         mov     COMsFound[bx].base_addr, ax     ; store base addr
  701.         add     ax, cx                  ; calculate last port addr
  702.         mov     COMsFound[bx].end_addr, ax      ; store end addr
  703.  
  704. record_exit:
  705.         popa                            ; restore regs.
  706.         ret
  707. RecordFunc endp
  708.  
  709. ;**     ScanString
  710. ;
  711. ;       Searches the string at DS:SI for an occurrence of the string
  712. ;       at ES:DI.  Updates DS:SI.
  713. ;
  714. ;       ENTRY   <ax> = length of string to be scanned
  715. ;               <bx> = pattern length
  716. ;               <ds:si> - String to search
  717. ;               <es:di> - Pattern to match
  718. ;
  719. ;       EXIT    if 'Z' = 1
  720. ;                       search pattern was found, <si> -> offset
  721. ;               else
  722. ;                       search pattern not found
  723. ;
  724. ;       USES    SI
  725. ;
  726.  
  727. public  ScanString
  728. ScanString proc near
  729.  
  730.         push    cx                      ; save count register
  731.         mov     cx, ax                  ; get the string length
  732.         mov     ax, bx                  ; get the pattern length
  733.         dec     si                      ; pre-decrement for loop
  734.  
  735. search_string:
  736.         inc     si                      ; point to next attempt
  737.         call    strncmp                 ; compare the strings
  738.         loopnz  search_string           ; keep trying
  739.  
  740.         pop     cx                      ; restore the count register
  741.         ret                             ; and exit
  742.  
  743. ScanString endp
  744.  
  745. ;**     strncmp
  746. ;
  747. ;       Compares two strings for a given length; ignores null
  748. ;
  749. ;       ENTRY   <ax> = string length
  750. ;               <ds:si> - string 1
  751. ;               <es:di> - string 2
  752. ;
  753. ;       EXIT    if 'Z' = 1
  754. ;                       the strings did compare
  755. ;               else
  756. ;                       the strings did not compare
  757. ;
  758. ;       USES    All registers restored
  759. ;
  760.  
  761. strncmp proc near
  762.  
  763.         push    cx                      ; save regs.
  764.         push    si
  765.         push    di
  766.  
  767.         mov     cx, ax                  ; get the string length
  768.         cld                             ; go forward
  769.         repe    cmpsb                   ; compare the strings
  770.  
  771.         pop     di                      ; restore regs.
  772.         pop     si
  773.         pop     cx
  774.         ret                             ; and exit
  775.  
  776. strncmp endp
  777.  
  778. RSEG    ENDS
  779.         END
  780.