home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / PRINTER / PRTEISAI.ASM < prev    next >
Assembly Source File  |  1995-04-14  |  54KB  |  993 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.  
  13. ; SCCSID = @(#)prteisai.asm     6.3 90/12/10
  14. ;/**********************************************************************
  15. ;/*                                                                    *
  16. ;/*                                                                    *
  17. ;/*                                                                    *
  18. ;/**********************************************************************
  19.  TITLE PRINTDD - PRINTER DEVICE DRIVER EISA INIT. TIME ROUTINE
  20.  NAME PRINTDD
  21. PAGE ,132
  22. .286C
  23.  
  24. ;***********************************************************************
  25. ; CODING CONVENTIONS
  26. ; all psuedo-ops, equates, documentation, publics,and externs are in uppercase.
  27. ; all code and data names are in lowercase.
  28. ;
  29. ; ROUTINES IN THIS MODULE:
  30. ;       EISAINIT
  31. ;***********************************************************************
  32.  
  33.         .XCREF
  34.         .XLIST
  35.         INCLUDE basemaca.inc            ; VARIOUS MACRO'S (BREAK, LJC, ETC.)
  36.         INCLUDE osmaca.inc
  37.         INCLUDE devsym.inc
  38.         INCLUDE devhlp.inc              ; DEFINITION OF DEVICE HELP CALLS.
  39.         INCLUDE infoseg.inc             ; STRUCTURES DEFINING THE INFOSEG.
  40.         INCLUDE filemode.inc            ; FILE SYSTEM FILE MODE EQUATES.
  41.         INCLUDE struc.inc               ; STRUCTURED MACROS
  42.         .LIST
  43.         .CREF
  44.         INCLUDE prtdd.inc               ; PRINTER DEVICE DRIVER INCLUDE FILE
  45.         INCLUDE prtdd1.inc              ; PRINTER DEVICE DRIVER INCLUDE FILE
  46.         INCLUDE prteisa.inc             ; EQUATES FOR EISA CODE
  47.         INCLUDE eisa.inc
  48.  
  49. BREAK <DATA FOR THE PRINTER DEVICE DRIVER>
  50. ;/********************** START OF SPECIFICATIONS ***********************/
  51. ;/*                                                                    */
  52. ;/* SUBROUTINE NAME: PRTDATA                                           */
  53. ;/*                                                                    */
  54. ;/* DESCRIPTIVE NAME: PRINTER DEVICE DRIVER DATA DECLARATIONS          */
  55. ;/*                                                                    */
  56. ;/*********************** END OF SPECIFICATIONS ************************/
  57. DSEG    SEGMENT PUBLIC  'data'
  58.  
  59.         EXTRN   device_help:DWORD
  60.         EXTRN   irq5index:WORD
  61.         EXTRN   irq7owner:WORD
  62.         EXTRN   numofprts:BYTE
  63.         EXTRN   perprtarea:BYTE
  64.  
  65. o_name          db      "OEMHLP$ "      ; OEMHLP$ name
  66. par_str         db      "PAR"           ; device id
  67. LEN_PAR_STR     equ     $-par_str       ; string length
  68. lpt_str         db      "LPT"           ; device subtype
  69. LEN_LPT_STR     equ     $-lpt_str       ; string length
  70. semi_str        db      ";"             ; subtype delimiter
  71. LEN_SEMI_STR    equ     $-semi_str      ; string length
  72. OEMinfo         AttachDDstr     <>      ; attachDD return info
  73. OEMpkt          Packet  <>              ; IOCTL packet for OEMHLP$
  74. Slot            EisaSlotInfo <>         ; Slot info.
  75. Function        EisaFuncInfo <>         ; Function info.
  76. EisaCall        EisaCallParameters <>   ; EISA call info.
  77. LPTsFound       db      SIZE EISALpt * MAXPRINTERS DUP (0)   ; array for info. found
  78. lpt_index       db      0               ; offset in to LPTsFound array
  79. bios_found      dw      3 DUP (0)       ; match found in EISA config. info
  80. Temp_LPTFound   EISALpt <>              ; temp variable for sorting
  81.  
  82. Eisa_int_routines       LABEL   WORD
  83.                 dw      OFFSET  eInt_1  ; interrupt routine for LPT1
  84.                 dw      OFFSET  eInt_2  ; interrupt routine for LPT2
  85.                 dw      OFFSET  eInt_3  ; interrupt routine for LPT3
  86.  
  87. DSEG    ENDS
  88.  
  89.         EXTRNFAR initialprt
  90.  
  91. CSEG    SEGMENT PUBLIC  'code'
  92.         ASSUME  CS:CSEG,DS:DSEG,ES:NOTHING,SS:NOTHING
  93.  
  94.         EXTRN   prtint07:NEAR
  95.         EXTRN   prtint05:NEAR
  96.         EXTRN   eInt_1:NEAR
  97.         EXTRN   eInt_2:NEAR
  98.         EXTRN   eInt_3:NEAR
  99.  
  100. BREAK <EISA INITIALIZATION ROUTINE>
  101. ;/*********************** END OF SPECIFICATIONS ************************/
  102. ;/*                                                                    */
  103. ;/* SUBROUTINE NAME: EISAINIT                                          */
  104. ;/*                                                                    */
  105. ;/* DESCRIPTIVE NAME: PRINT DEVICE DRIVER EISA INIT. ROUTINE.          */
  106. ;/*                                                                    */
  107. ;/* FUNCTION: This subroutine will get called from PRTINIT to check    */
  108. ;/*           for the presence of an EISA system.  If                  */
  109. ;/*           running on an EISA system, then this routine will        */
  110. ;/*           perform the intitialization of the printer device        */
  111. ;/*           driver's data structures.  This routine will use the     */
  112. ;/*           EISA system's non-volatile configuration CMOS to         */
  113. ;/*           determine the port address and IRQ line for each printer */
  114. ;/*           attached to the system.  If not running on an EISA       */
  115. ;/*           system, this routine will set CY, indicating to PRTINIT  */
  116. ;/*           that it should initialize the data structures, with      */
  117. ;/*           the default ISA values.                                  */
  118. ;/*                                                                    */
  119. ;/* ENTRY POINT: EISAINIT                                              */
  120. ;/*    LINKAGE : CALL NEAR                                             */
  121. ;/*                                                                    */
  122. ;/* INPUT:     ES = SELECTOR TO BIOS DATA AREA                         */
  123. ;/*            BX = OFFSET TO BIOS DATA AREA                           */
  124. ;/*            NUMOFPRTS = NUMBER OF PRINTERS ATTACHED                 */
  125. ;/*                                                                    */
  126. ;/* REGISTERS USED: NONE                                               */
  127. ;/*                                                                    */
  128. ;/* EXIT-NORMAL:   CY = 0, EISA System                                 */
  129. ;/*                                                                    */
  130. ;/* EXIT-ERROR:    CY = 1, Non-EISA system                             */
  131. ;/*                                                                    */
  132. ;/* INTERNAL REFERENCES: NONE                                          */
  133. ;/*    ROUTINES:                                                       */
  134. ;/*                                                                    */
  135. ;/* EXTERNAL REFERENCES:                                               */
  136. ;/*                                                                    */
  137. ;/*********************** END OF SPECIFICATIONS ************************/
  138.         PUBLIC eisainit
  139. Procedure eisainit
  140.  
  141.         pusha                           ; save all regs.
  142.         push    es                      ; and ES, too
  143.         call    AttachOEMHLP            ; get access to OEMHLP$ driver,
  144.         .if     < c >                   ; error?
  145.             jmp     exit_eisai          ;  Y: exit
  146.         .endif
  147.         mov     cl, 0                   ; first slot #
  148.  
  149.         push    ds                      ; set ES to our DGROUP
  150.         pop     es
  151.  
  152. slot_loop:
  153.         call    GetSlotInfo             ; get info. for first slot
  154.         .if     < ah ne 0 >             ; error?
  155.             .if     < ah e EISA_ERROR_EMPTY_SLOT > ; empty slot?
  156.                 inc     cl              ;  Y: go to next slot number,
  157.                 jmp     slot_loop       ;     and process next slot
  158.             .elseif < ah e EISA_INVALID_SLOT >  ; invalid slot?
  159.                 jmp     reconcile       ;  Y: reconcile info. found
  160.             .else                       ; not invalid or empty, so error exit
  161.                 stc                     ; indicate error
  162.                 jmp     exit_eisai      ; then exit
  163.             .endif
  164.         .else                           ; Valid slot, check for I/O ports
  165.             .if < bit Slot.esi_fbFunc and EISA_HAS_IO_ENTRIES > I/O ports on this slot?
  166.                 mov     ch, Slot.esi_cbFunc    ; Y: get number of functions
  167.                 dec     ch              ; make it relative to 0
  168.  
  169. function_loop:
  170.                 call    GetFuncInfo     ; get 320 byte record for this func.
  171.                 .if     < ah ne 0 >     ; Error?
  172.                     stc                 ;  Y: indicate error, then
  173.                     jmp     exit_eisai  ;  error exit
  174.                 .endif
  175.  
  176.                 lea     si, Function.efi_achType   ; point to device string
  177.                 lea     di,  par_str    ; device string to look for
  178.                 mov     ax, LEN_PAR_STR ; string length
  179.                 call    strncmp         ; is this function a PAR device?
  180.                 .if     < z > and       ;  Y: also check to see if it's enabled
  181.                 .if     < bit Function.efi_fbFunction z EISA_FUNC_ENABLED > ; if enabled
  182.                     call    RecordFunc  ;  Y: store the information
  183.                 .endif
  184.                 .if     < lpt_index e MAXPRINTERS >  ; Just found third printer?
  185.                     jmp     reconcile   ;  Y: no need to search further
  186.                 .endif
  187.                 dec     ch              ; next function to check
  188.                 .if     < ch ge 0 >     ; More functions to check?
  189.                     jmp     function_loop       ;  Y: check next function
  190.                 .endif
  191.             .endif                      ; I/O ports
  192.         .endif                          ; No error on slot call
  193.         inc     cl                      ; next slot to check
  194.         jmp     slot_loop               ; check next slot
  195.  
  196. reconcile:
  197.         .if     < lpt_index g 0 >       ; if any LPT info. found, then
  198.             call    CompareBIOS         ;  compare results to BIOS data area
  199.             call    AddEISA             ;  then add in any EISA only printers
  200.             clc                         ; indicate no error
  201.         .else                           ; otherwise,
  202.             stc                         ;  treat it like an ISA machine
  203.         .endif
  204.  
  205. exit_eisai:
  206.         pop     es                      ; restore regs.
  207.         popa
  208.         ret
  209. EndProc eisainit
  210.  
  211. ;****************************************************************************
  212. ;                                                                           *
  213. ; SUBROUTINE NAME:  AddEISA                                                 *
  214. ;                                                                           *
  215. ; DESCRIPTIVE NAME: Add EISA printers to device driver data structure.      *
  216. ;                                                                           *
  217. ; FUNCTION:     This routine fills in the device driver's data structure    *
  218. ;               with any information that was found on non-ISA compatible   *
  219. ;               printer ports.  These are printer ports that do not begin   *
  220. ;               at the ISA compatible port addresses.  If all three         *
  221. ;               ISA compatible printers were found by the BIOS at POST      *
  222. ;               time, then this routine will do nothing.  Also, if          *
  223. ;               all the printers found in EISA config. were already         *
  224. ;               matched up with ISA compatible printers found by the BIOS,  *
  225. ;               then this routine will do nothing.  If neither of the two   *
  226. ;               conditions above were true, then this routine will "left    *
  227. ;               justify" the EISA printers, and fill them in to the         *
  228. ;               driver's data structure.                                    *
  229. ;                                                                           *
  230. ; ENTRY POINT:  AddEISA                                                     *
  231. ;     LINKAGE:  Call near (local and discarded after init)                  *
  232. ;                                                                           *
  233. ; EXIT-NORMAL:  None.                                                       *
  234. ;                                                                           *
  235. ; EXIT-ERROR:   None.                                                       *
  236. ;                                                                           *
  237. ; EFFECTS:      All registers destroyed.                                    *
  238. ;                                                                           *
  239. ;****************************************************************************
  240.  
  241. public  AddEISA
  242. AddEISA         proc    near
  243.  
  244.         .if     < numofprts e MAXPRINTERS >     ; 3 ISA compatible printers,
  245.             ret                         ; so just exit
  246.         .endif
  247.  
  248.         .if     < lpt_index e 0 >       ; already matched up all the
  249.             ret                         ;  EISA printers, so just exit
  250.         .endif
  251.  
  252.         .if     < lpt_index g 1 >       ; if more than one EISA printer
  253.                                         ;  remaining
  254.             ; bubble sort the EISA printers
  255.  
  256. bubble_sort:
  257.             xor     dx, dx              ; assume sort is finished
  258.             mov     cx, MAXPRINTERS     ; number of array items
  259.             dec     cx                  ; adjust to loop count
  260.             mov     si, OFFSET LPTsFound ; start of EISA array
  261.  
  262. scan_array:
  263.             mov     al, [si].printer_number     ; unit number
  264.             mov     di, si
  265.             add     di, LEN_EISALPT_STRUC       ; point to next entry
  266.             .if     < al g [di].printer_number > ; if these aren't in order
  267.                 mov     dx, 1           ; not through sorting yet
  268.                 push    si              ; save current offset
  269.                 push    cx              ; save loop count
  270.                 push    di              ; save current+1 offset
  271.                 push    si              ; save current offset
  272.                 mov     di, OFFSET Temp_LPTFound ; temp buffer
  273.                 mov     cx, LEN_EISALPT_STRUC / 2  ; prepare for word move
  274.                 rep     movsw           ; copy current array entry to temp.
  275.                 pop     di              ; get current offset back
  276.                 pop     si              ; get current+1 offset back
  277.                 push    si              ; save current+1 offset
  278.                 mov     cx, LEN_EISALPT_STRUC / 2  ; prepare for word move
  279.                 rep     movsw           ; copy current+1 to current
  280.                 pop     di              ; get current+1 offset back
  281.                 mov     si, OFFSET Temp_LPTFound ; temp buffer
  282.                 mov     cx, LEN_EISALPT_STRUC / 2  ; prepare for word move
  283.                 rep     movsw           ; copy from tmp to current+1
  284.                 pop     cx              ; get loop count back
  285.                 pop     si              ; get current offset back
  286.             .endif
  287.  
  288.             add     si, LEN_EISALPT_STRUC  ; point to next array element
  289.             loop    scan_array          ; check next two items
  290.             .if     < dx e 1 >          ; is the array sorted yet?
  291.                 jmp     bubble_sort     ;  N: try again
  292.             .endif
  293.         .endif
  294.  
  295.         ; Now scan the sorted array, looking for un-used EISA printers.
  296.         ; The variable "numofprts" tells us how many printers the BIOS
  297.         ; found, which by this time is also the number of printers
  298.         ; we've initialized the driver for, since we give the ISA
  299.         ; printers top priority for initializing the driver's data
  300.         ; structures.  Therefore, the number of EISA printers we
  301.         ; can add now is: MAXPRINTERS - numofprts
  302.  
  303.         mov     al, numofprts           ; number of printers BIOS found
  304.         xor     ah, ah
  305.         mov     bx, SIZE printer_database
  306.         mul     bx                      ; construct an offset in to the
  307.                                         ;  driver's data structure
  308.         mov     di, OFFSET perprtarea   ; beginning of driver's data structure
  309.         add     di, ax                  ; first empty entry in driver's data
  310.         mov     cx, MAXPRINTERS         ; max. number of EISA printers
  311.         mov     si, OFFSET LPTsFound    ; first entry in EISA array
  312.         mov     dl, numofprts           ; to keep track of total
  313.         mov     bl, dl                  ; use as an index into int. routines
  314.         xor     bh, bh
  315.         shl     bx, 1                   ; X 2 to create an offset
  316.  
  317. scan_eisa:
  318.         .if     < [si].printer_number g 0 > and  ; if valid data
  319.         .if     < [si].In_use e 0 >     ; and this printer is not in use
  320.  
  321.             ; fill in the device driver's data structure with the
  322.             ; EISA config. information
  323.             mov     ax, [si].base_addr  ; get base addr from EISA
  324.             mov     [di].deviceaddr, ax ; have the driver use it
  325.             mov     al, [si].IRQ_number ; get IRQ level from EISA
  326.             mov     [di].intlevel, al   ; have the driver use it
  327.             mov     al, [si].sharable_IRQ  ; get IRQ sharing info. from EISA
  328.             mov     [di].share_interrupt, al  ; have the driver use it
  329.             mov     ax, Eisa_Int_routines[bx]  ; get offset of int hdl.
  330.             mov     [di].introutine, ax ; have the driver use it
  331.             inc     numofprts           ; increase global counter
  332.  
  333.             push    ax                  ; save interrupt handler addr
  334.             or      [di].commonflags1, BOOTINIT ; indicate boot time
  335.             CALLFAR initialprt          ; initialize the printer
  336.             and     [di].commonflags1, NOT BOOTINIT ; clear boot flag
  337.             pop     ax                  ; get interrupt handler addr
  338.  
  339.             ; if we're going to share this interrupt line, grab it
  340.             ; now and then we won't have to keep hooking it and un-hooking
  341.             ; for each file printed.
  342.             .if     < [di].share_interrupt e INT_SHARING >
  343.                 push    bx              ; save offset to int. routine
  344.                 push    dx              ; save printer count
  345.                 xor     bh, bh          ; clear high byte
  346.                 mov     bl, [di].intlevel  ; IRQ number
  347.                 mov     dh, INT_SHARING ; request the IRQ shared
  348.                 mov     dl, DevHlp_SetIRQ ; request code
  349.                 call    DWORD PTR [device_help] ; request the IRQ line
  350.                 .if     < c >           ; if CY set, the request failed
  351.                     mov     [di].share_interrupt, 0  ; no sharing
  352.                 .endif
  353.                 pop     dx              ; get printer count back
  354.                 pop     bx              ; get offset to int. routines
  355.             .endif
  356.  
  357.             add     di, SIZE printer_database   ; point to next free entry
  358.             inc     bx
  359.             inc     bx                  ; point to next int. routine
  360.             inc     dl                  ; add another printer
  361.             .if     < dl e MAXPRINTERS > ; max reached?
  362.                 jmp     exit_add        ;  Y: exit
  363.             .endif
  364.         .endif
  365.  
  366.         add     si, LEN_EISALPT_STRUC   ; point to next EISA printer
  367.         loop    scan_eisa               ; process all EISA printers
  368.  
  369. exit_add:
  370.         ret
  371.  
  372. AddEISA         endp
  373.  
  374. ;****************************************************************************
  375. ;                                                                           *
  376. ; SUBROUTINE NAME:  atoi                                                    *
  377. ;                                                                           *
  378. ; FUNCTION: Converts the string at DS:SI in to an integer value.  Does      *
  379. ;           not assume NULL termination - searches for the first            *
  380. ;           non-ASCII digit instead.                                        *
  381. ;                                                                           *
  382. ; ENTRY POINT:  atoi                                                        *
  383. ;     LINKAGE:  Call near (local and discarded after init)                  *
  384. ;               DS:SI - String to convert                                   *
  385. ;                                                                           *
  386. ; EXIT-NORMAL:  AX = integer value.                                         *
  387. ;               CY clear                                                    *
  388. ;                                                                           *
  389. ; EXIT-ERROR:   CY set indicates invalid input                              *
  390. ;                                                                           *
  391. ; EFFECTS:      Flags, all other registers restored.                        *
  392. ;                                                                           *
  393. ;****************************************************************************
  394.  
  395. public  atoi
  396. atoi proc near
  397.  
  398.         push    si                      ; save regs.
  399.         push    bx
  400.         push    cx
  401.         push    dx
  402.  
  403.         xor     ah, ah                  ; clear high order byte
  404.         mov     bx, 1                   ; initial power of ten multiplier
  405.         xor     cx, cx                  ; initial string size
  406.         xor     dx, dx                  ; eventual result
  407.  
  408.         cld                             ; go forward to find the end
  409.  
  410. find_end_digits:
  411.         lodsb                           ; get a char
  412.         .if     < al ge '0' >  and      ; if in range
  413.         .if     < al le '9' >           ;  then
  414.             inc     cx                  ;  increment string size
  415.             jmp     find_end_digits     ;  and keep looking
  416.         .endif
  417.  
  418.         .if     < cx e 0 >              ; no digits found?
  419.             stc                         ;  indicate error
  420.             jmp     exit_atoi           ;  then exit
  421.         .endif
  422.  
  423.         dec     si                      ; back up to non-digit char.
  424.         dec     si                      ; back up to least significant digit
  425.         std                             ; go backwards from least to most sig.
  426.  
  427. convert:
  428.         lodsb                           ; get a digit
  429.         sub     al, '0'                 ; strip off the ASCII portion
  430.         push    dx                      ; save the work in progress
  431.         mul     bx                      ; calculate this position
  432.         pop     dx                      ; retrieve work done so far
  433.         add     dx, ax                  ; accumulate this new position
  434.         .if     < bx e 1 >              ; special case for first time
  435.             mov     bx, 10              ; initial powers of ten value
  436.         .else
  437.             mov     ax, 10              ; to create next power of ten
  438.             push    dx                  ; save work in progress
  439.             mul     bx                  ; create next power of ten
  440.             pop     dx                  ; restore work in progress
  441.             mov     bx, ax              ; put back in powers of 10 reg.
  442.         .endif
  443.         loop    convert                 ; loop until all are converted
  444.  
  445.         mov     ax, dx                  ; move result to return value
  446.         clc                             ; indicate no error
  447.  
  448. exit_atoi:
  449.         pop     dx                      ; restore regs
  450.         pop     cx
  451.         pop     bx
  452.         pop     si
  453.  
  454.         ret
  455.  
  456. atoi    endp
  457.  
  458. ;****************************************************************************
  459. ;                                                                           *
  460. ; SUBROUTINE NAME:  AttachOEMHLP                                            *
  461. ;                                                                           *
  462. ; DESCRIPTIVE NAME: Perform an attachDD call so that we may do IOCTLs to    *
  463. ;                   OEMHLP$ to get EISA config. information.                *
  464. ;                                                                           *
  465. ; FUNCTION:     Set up AttachDD data structure so that calls may be made to *
  466. ;               OEMHLP$ during printer driver init.                         *
  467. ;                                                                           *
  468. ; ENTRY POINT:  AttachOEMHLP                                                *
  469. ;     LINKAGE:  Call near (local and discarded after init)                  *
  470. ;                                                                           *
  471. ;                                                                           *
  472. ; EXIT-NORMAL:  CY = 0                                                      *
  473. ;                                                                           *
  474. ; EXIT-ERROR:   CY = 1                                                      *
  475. ;                                                                           *
  476. ; EFFECTS:      DX destroyed.                                               *
  477. ;                                                                           *
  478. ;****************************************************************************
  479.  
  480. public AttachOEMHLP
  481. AttachOEMHLP    proc    near
  482.  
  483.         push    bx
  484.         push    di
  485.         mov     bx, OFFSET o_name       ; get the OEMHLP$ name
  486.         mov     di ,OFFSET OEMinfo      ; point to the data area for info
  487.         mov     dl, DevHlp_AttachDD     ; request code
  488.         call    DWORD PTR [device_help] ; perform the devhlp to attach
  489.         pop     di
  490.         pop     bx
  491.         ret
  492.  
  493. AttachOEMHLP    endp
  494.  
  495. ;****************************************************************************
  496. ;                                                                           *
  497. ; SUBROUTINE NAME:  CompareBIOS                                             *
  498. ;                                                                           *
  499. ; DESCRIPTIVE NAME: Compare EISA config. information to the BIOS data area. *
  500. ;                                                                           *
  501. ; FUNCTION:     This function reconciles the data found in the EISA         *
  502. ;               config. information with the BIOS data area's printer       *
  503. ;               base address array.  The purpose of this routine is to      *
  504. ;               ensure ISA/DOS compatibility.  By looking at the BIOS       *
  505. ;               data area first, we can handle the possiblity of an ISA     *
  506. ;               card being plugged in to an EISA machine without a          *
  507. ;               corresponding EISA config. file.                            *
  508. ;                                                                           *
  509. ;               To accomplish this, two things are done.  First, the EISA   *
  510. ;               config. information is compared to the BIOS data area.      *
  511. ;               For each match between the two, an entry is initialized     *
  512. ;               in the driver's database.  After this is done, the          *
  513. ;               resulting database for the driver is checked against the    *
  514. ;               BIOS data area.  If there are any BIOS data area entries    *
  515. ;               that do not have a corresponding entry in the driver's      *
  516. ;               database, then the driver's database is filled in with the  *
  517. ;               ISA defaults.                                               *
  518. ;                                                                           *
  519. ; ENTRY POINT:  CompareBIOS                                                 *
  520. ;     LINKAGE:  Call near (local and discarded after init)                  *
  521. ;                                                                           *
  522. ; EXIT-NORMAL:  None.                                                       *
  523. ;                                                                           *
  524. ; EXIT-ERROR:   None.                                                       *
  525. ;                                                                           *
  526. ; EFFECTS:      All registers destroyed.                                    *
  527. ;                                                                           *
  528. ;****************************************************************************
  529.  
  530. public  CompareBIOS
  531. CompareBIOS     proc    near
  532.  
  533.         push    es                      ; save our data selector
  534.         mov     ax, BIOSROMDATA         ; get selector for BIOS data area
  535.         mov     es, ax
  536.         xor     bx, bx                  ; create offset to BIOS data area
  537.         xor     si, si                  ; index in to BIOS data area
  538.  
  539.         mov     cl, lpt_index           ; number of printers in EISA info.
  540.         xor     ch, ch                  ; clear high byte
  541.         mov     di, OFFSET LPTsFound    ; beginning of EISA array
  542.  
  543. check_all_EISA_printers:
  544.         push    cx                      ; save # of EISA printers loop count
  545.         mov     cl, numofprts           ; number of printers the BIOS found
  546.                                         ;  during POST
  547.         jncxz   compbios_0              ; if ports, continue.
  548.         ; got here when EISA info exists and no BIOS info.  User needs to
  549.         ; run EISA configuration to remove EISA info.  Nothing to initialize.
  550.         pop     cx                      ; restore # of EISA printers loop count
  551.         jmp     compbios_1              ; if no ports, exit.
  552. compbios_0:
  553.         xor     dx, dx                  ; array index
  554.         push    si                      ; save beginning index
  555.  
  556. check_all_BIOS_entries:
  557.         mov     ax, [di].base_addr      ; EISA base addr.
  558.         .if     < biosdata.printer_adapt[si] ge ax > near ; could be in range
  559.             mov     ax, [di].end_addr   ; get the end of the range
  560.             .if     < biosdata.printer_adapt[si] le ax > near and ; if in range
  561.             .if     < [di].In_use e 0 > near ; and this EISA info. hasn't been used
  562.                 mov     [di].In_use, 1  ; a match has been found, mark this
  563.                                         ;  entry as being in use.
  564.                 push    bx              ; save offset to BIOS data area
  565.                 push    dx              ; save array index
  566.                 mov     ax, dx          ; get array index
  567.                 mov     bx, SIZE printer_database
  568.                 mul     bx              ; create an offset
  569.                 mov     bx, ax          ; set up an index
  570.  
  571.                 ; fill in the device driver's data structure with the
  572.                 ; EISA config. information
  573.                 mov     ax, [di].base_addr      ; get base addr from EISA
  574.                 mov     perprtarea[bx].deviceaddr, ax ; have the driver use it
  575.                 mov     al, [di].IRQ_number     ; get IRQ level from EISA
  576.                 mov     perprtarea[bx].intlevel, al  ; have the driver use it
  577.                 mov     al, [di].sharable_IRQ   ; get IRQ sharing info. from EISA
  578.                 mov     perprtarea[bx].share_interrupt, al ; have the driver use it
  579.                 mov     ax, Eisa_Int_routines[si]    ; get offset of int hdl.
  580.                 mov     perprtarea[bx].introutine, ax ; have the driver use it
  581.  
  582.                 or      perprtarea[bx].commonflags1, BOOTINIT ; indicate boot time
  583.                 push    ax              ; save interrupt handler addr
  584.                 push    di              ; save EISA array pointer
  585.                 mov     di, OFFSET perprtarea
  586.                 add     di, bx          ; point to current driver structure
  587.  
  588.                 CALLFAR initialprt      ; initialize the printer
  589.                 pop     di              ; get EISA array pointer back
  590.                 and     perprtarea[bx].commonflags1, NOT BOOTINIT ; clear boot flag
  591.                 pop     ax              ; get interrupt handler addr
  592.  
  593.                 ; if we're going to share this interrupt line, grab it
  594.                 ; now and then we won't have to keep hooking it and un-hooking
  595.                 ; it for each file printed.
  596.  
  597.                 .if     < perprtarea[bx].share_interrupt e INT_SHARING >
  598.                     push    bx                  ; save offset to perprtarea
  599.                     mov     bl, perprtarea[bx].intlevel ; IRQ number
  600.                     xor     bh, bh                      ; clear high byte
  601.                     mov     dh, INT_SHARING             ; request the IRQ shared
  602.                     mov     dl, DevHlp_SetIRQ           ; request code
  603.                     call    DWORD PTR [device_help]     ; request the IRQ line
  604.                     pop     bx                          ; offset to perprtarea
  605.                     .if     < c >                       ; if CY set, req failed
  606.                         mov     perprtarea[bx].share_interrupt, 0  ; no sharing
  607.                     .endif
  608.                 .endif
  609.  
  610.                 pop     dx              ; restore array index
  611.  
  612.                 ; now that the interrupt sharing issue has been sorted out,
  613.                 ; check for interrupt sharing again.  If it is not going to
  614.                 ; be done for this printer, then use the standard ISA
  615.                 ; entry points in to the interrupt service routine, if
  616.                 ; the printer is configured for IRQ7 or IRQ5.
  617.                 .if     < perprtarea[bx].share_interrupt ne INT_SHARING >
  618.                     .if     < perprtarea[bx].intlevel e LEVEL5 >
  619.                         mov     perprtarea[bx].introutine, OFFSET prtint05
  620.                         mov     irq5index, dx   ; save index into driver str.
  621.                     .elseif < perprtarea[bx].intlevel e LEVEL7 >
  622.                         mov     perprtarea[bx].introutine, OFFSET prtint07
  623.                     .endif
  624.                 .endif
  625.  
  626.                 mov     bios_found[si], 1  ; indicate valid info.
  627.                 dec     lpt_index       ; keep track of how many EISA LPTs used
  628.                 pop     bx              ; restore offset to BIOS data area
  629.             .endif
  630.         .endif
  631.  
  632.         inc     si
  633.         inc     si                      ; point to the next BIOS data entry
  634.         inc     dx                      ; next array index
  635.         dec     cx                      ; too much code for loop inst.
  636.         jz      next_eisa               ; process next EISA printer
  637.         jmp     check_all_BIOS_entries  ; process each valid BIOS entry
  638.  
  639. next_eisa:
  640.         pop     si                      ; restore initial offset to BIOS
  641.         pop     cx                      ; restore EISA loop count
  642.         add     di, LEN_EISALPT_STRUC   ; point to next array entry
  643.         dec     cx                      ; too much code for loop inst.
  644.         jz      use_ISA_values          ; revert to ISA defaults
  645.         jmp     check_all_EISA_printers ; process all EISA printers found
  646.  
  647. use_ISA_values:
  648.         mov     cx, MAXPRINTERS         ; loop counter
  649.         xor     si, si                  ; offset into BIOS data area
  650.         xor     dx, dx                  ; array index
  651.         mov     di, OFFSET perprtarea   ; device driver's array
  652.  
  653. fill_in_ISA_values:
  654.         .if     < biosdata.printer_adapt[si] ne 0 > and ; if there is a printer,
  655.         .if     < bios_found[si] e 0 >            ; and no EISA info. was found
  656.  
  657.             ; Fill in the device driver's data structure with ISA defaults,
  658.             ; since no EISA config. information was found.
  659.  
  660.             mov     [di].share_interrupt, 0             ; no IRQ sharing
  661.             mov     ax, biosdata.printer_adapt[si]      ; port addr.
  662.             mov     [di].deviceaddr, ax                 ; have device driver use it
  663.             .if     < ax e PORT278H >                   ; LPT3 base address?
  664.                 mov     [di].introutine, OFFSET prtint05 ; use IRQ5
  665.                 mov     [di].intlevel, LEVEL5
  666.                 mov     irq5index, dx
  667.             .else                                       ; use IRQ7
  668.                 mov     [di].introutine, OFFSET prtint07
  669.                 mov     [di].intlevel, LEVEL7
  670.             .endif
  671.             or      [di].commonflags1, BOOTINIT         ; indicate boot time
  672.             CALLFAR initialprt                          ; initialize the printer
  673.             and     [di].commonflags1, NOT BOOTINIT     ; clear boot flag
  674.         .endif
  675.         inc     dx                                      ; array index
  676.         inc     si
  677.         inc     si                              ; next BIOS data area entry
  678.         add     di, SIZE printer_database       ; next detice driver entry
  679.         loop    fill_in_ISA_values              ; process all BIOS data area LPTs
  680.  
  681. compbios_1:
  682.         pop     es                      ; get our data selector back
  683.         ret
  684. CompareBIOS     endp
  685.  
  686. ;****************************************************************************
  687. ;                                                                           *
  688. ; SUBROUTINE NAME:  GetFuncInfo                                             *
  689. ;                                                                           *
  690. ; DESCRIPTIVE NAME: Call OEMHLP to get EISA function information.           *
  691. ;                                                                           *
  692. ; FUNCTION:     Set up an IOCTL structure to call OEMHLP for EISA           *
  693. ;               function information.                                       *
  694. ;                                                                           *
  695. ; ENTRY POINT:  GetFuncInfo                                                 *
  696. ;     LINKAGE:  Call near (local and discarded after init)                  *
  697. ;               CL = Slot number requested                                  *
  698. ;               CH = Function number requested                              *
  699. ;                                                                           *
  700. ; EXIT-NORMAL:  AH = 0                                                      *
  701. ;               Variable 'Function' contains result                         *
  702. ;                                                                           *
  703. ; EXIT-ERROR:   AH = Error code.                                            *
  704. ;                                                                           *
  705. ; EFFECTS:      AX destroyed.                                               *
  706. ;                                                                           *
  707. ;****************************************************************************
  708.  
  709. public  GetFuncInfo
  710. GetFuncInfo     proc    near
  711.  
  712.         push    bx                      ; Save the work registers
  713.         push    bp
  714.         push    es
  715.  
  716.         mov     EisaCall.ecp_SubFunction, EISA_FUNCTION_REQUEST   ; tell OEMHLP$ "get function info."
  717.         mov     EisaCall.ecp_SlotNumber, cl  ; requested slot number
  718.         mov     EisaCall.ecp_FunctionNumber, ch ; requested function number
  719.  
  720.         mov     bx,OFFSET OEMpkt        ; point es:bx to IOCTL packet
  721.         mov     es:[bx].PktLen,LenGenIOCTL ; get length
  722.         mov     es:[bx].PktCmd,CMDGenIOCTL ; get ioctl cmd
  723.         mov     es:[bx].GIOCategory,0    ; get category for base drivers
  724.         mov     es:[bx].GIOFunction,EISA_FNNUMBER ; get function for EISA info.
  725.         mov     word ptr es:[bx].GIODataPack+2,ds       ; get data addr
  726.         mov     word ptr es:[bx].GIODataPack,OFFSET Function ; get data addr
  727.         mov     word ptr es:[bx].GIOParaPack+2,ds       ; get parm addr
  728.         mov     word ptr es:[bx].GIOParaPack,OFFSET EisaCall
  729.  
  730.         push    word ptr [OEMinfo].pcs  ; setup pointer to function
  731.         push    word ptr [OEMinfo].poffset
  732.         mov     bp, sp
  733.         call    dword ptr [bp]          ; call external OEMHLP IOCTL routine
  734.         mov     di, ax                  ; save success state
  735.  
  736.         pop     ax                      ; remove call address from stack
  737.         pop     ax
  738.  
  739.         and     es:[bx].PktStatus, NOT STDON ; remove init. time flag
  740.         .if     < es:[bx].PktStatus ne 0 > ; OEMHLP error?
  741.             mov ah, EISA_INVALID_BIOS_CALL ;  Y: Indicate not EISA machine
  742.         .else
  743.             mov ah, Function.efi_bReturn    ;  N: Use the EISA return code
  744.         .endif
  745.  
  746.         pop     es                      ; restore work regs.
  747.         pop     bp
  748.         pop     bx
  749.  
  750.         ret
  751.  
  752. GetFuncInfo     endp
  753.  
  754. ;****************************************************************************
  755. ;                                                                           *
  756. ; SUBROUTINE NAME:  GetSlotInfo                                             *
  757. ;                                                                           *
  758. ; DESCRIPTIVE NAME: Call OEMHLP to get EISA slot information.               *
  759. ;                                                                           *
  760. ; FUNCTION:     Set up an IOCTL structure to call OEMHLP for EISA slot      *
  761. ;               information.                                                *
  762. ;                                                                           *
  763. ; ENTRY POINT:  GetSlotInfo                                                 *
  764. ;     LINKAGE:  Call near (local and discarded after init)                  *
  765. ;               CL = Slot number requested                                  *
  766. ;                                                                           *
  767. ; EXIT-NORMAL:  AH = 0                                                      *
  768. ;               Variable 'Slot' contains result                             *
  769. ;                                                                           *
  770. ; EXIT-ERROR:   AH = Error code.                                            *
  771. ;                                                                           *
  772. ; EFFECTS:      AX destroyed.                                               *
  773. ;                                                                           *
  774. ;****************************************************************************
  775.  
  776. public GetSlotInfo
  777. GetSlotInfo     proc    near
  778.  
  779.         push    bx                      ; Save the work registers
  780.         push    bp
  781.         push    es
  782.  
  783.         mov     EisaCall.ecp_SubFunction, EISA_SLOT_REQUEST  ; tell OEMHLP$ "get slot info."
  784.         mov     EisaCall.ecp_SlotNumber, cl  ; requested slot number
  785.  
  786.         mov     bx,OFFSET OEMpkt        ; point es:bx to IOCTL packet
  787.         mov     es:[bx].PktLen,LenGenIOCTL ; get length
  788.         mov     es:[bx].PktCmd,CMDGenIOCTL ; get ioctl cmd
  789.         mov     es:[bx].GIOCategory,0    ; get category for base drivers
  790.         mov     es:[bx].GIOFunction,EISA_FNNUMBER ; get function for EISA info.
  791.         mov     word ptr es:[bx].GIODataPack+2,ds       ; get data addr
  792.         mov     word ptr es:[bx].GIODataPack,OFFSET Slot ; get data addr
  793.         mov     word ptr es:[bx].GIOParaPack+2,ds       ; get parm addr
  794.         mov     word ptr es:[bx].GIOParaPack,OFFSET EisaCall
  795.  
  796.         push    word ptr [OEMinfo].pcs  ; setup pointer to function
  797.         push    word ptr [OEMinfo].poffset
  798.         mov     bp, sp
  799.         call    dword ptr [bp]          ; call external OEMHLP IOCTL routine
  800.  
  801.         pop     ax                      ; remove call address from stack
  802.         pop     ax
  803.  
  804.         and     es:[bx].PktStatus, NOT STDON ; remove init. time flag
  805.         .if     < es:[bx].PktStatus ne 0 > ; OEMHLP error?
  806.             mov ah, EISA_INVALID_BIOS_CALL ;  Y: Indicate not EISA machine
  807.         .else
  808.             mov ah, Slot.esi_bReturn    ;  N: Use the EISA return code
  809.         .endif
  810.  
  811.         pop     es                      ; restore work regs.
  812.         pop     bp
  813.         pop     bx
  814.  
  815.         ret
  816.  
  817. GetSlotInfo     endp
  818.  
  819. ;****************************************************************************
  820. ;                                                                           *
  821. ; SUBROUTINE NAME:  RecordFunc                                              *
  822. ;                                                                           *
  823. ; DESCRIPTIVE NAME: Record EISA function information.                       *
  824. ;                                                                           *
  825. ; FUNCTION:     After a function has been found that is a parallel device,  *
  826. ;               this routine is called to save the configuration            *
  827. ;               of the device, if it is a line printer (LPT).               *
  828. ;                                                                           *
  829. ; ENTRY POINT:  RecordFunc                                                  *
  830. ;     LINKAGE:  Call near (local and discarded after init)                  *
  831. ;               Function - contains information on a PAR device             *
  832. ;                                                                           *
  833. ; EXIT-NORMAL:  Lpts - updated                                              *
  834. ;                                                                           *
  835. ; EXIT-ERROR:   None.                                                       *
  836. ;                                                                           *
  837. ; EFFECTS:      None. All registers restored.                               *
  838. ;                                                                           *
  839. ;****************************************************************************
  840. public  RecordFunc
  841. RecordFunc proc near
  842.  
  843.         pusha                           ; save regs.
  844.         lea     si, Function.efi_achType   ; device type string
  845.         mov     di, OFFSET semi_str     ; delimiter string to look for
  846.         mov     bx, LEN_SEMI_STR        ; length of delimiter string
  847.         mov     ax, EISA_DEVICE_TYPE_LEN ; size of type ASCII string field
  848.         call    ScanString              ; is there a subtype delimiter?
  849.         .if     < nz >                  ;  N: return to caller
  850.             jmp     record_exit
  851.         .endif
  852.  
  853.         mov     di, OFFSET lpt_str      ; beginning of subtype string
  854.         mov     bx, LEN_LPT_STR         ; length of subtye string
  855.         inc     si                      ; first char. after subtype delim.
  856.         mov     ax, OFFSET Function     ; beginning of structure
  857.         add     ax, OFFSET efi_achType  ; adjusted to beginning of ASCII
  858.         add     ax, EISA_DEVICE_TYPE_LEN  ; add max. offset
  859.         sub     ax, si                  ; subtract current offset for len.
  860.         call    ScanString              ; is the subtype string 'LPT'?
  861.         .if     < nz >                  ;  N: return to caller
  862.             jmp     record_exit
  863.         .endif
  864.  
  865.         dec     si                      ; check to make sure 'LPT' is alone:
  866.         cld                             ; make sure we're going forward
  867.         lodsb                           ; get char. right before 'LPT'
  868.         .if     < al e ';' > or         ; is it a semicolon?
  869.         .if     < al e ' ' > or         ; or a space?
  870.         .if     < al e TAB >            ; or a TAB?
  871.             nop                         ;  Y: then it's OK, keep going
  872.         .else
  873.             jmp     record_exit         ;  N: something in front of 'LPT', exit
  874.         .endif
  875.  
  876.         add     si, LEN_LPT_STR         ; point to unit number
  877.         call    atoi                    ; attempt to convert to integer
  878.         .if     < c >                   ; valid integer?
  879.             jmp     record_exit         ;  N: so exit
  880.         .endif
  881.  
  882.         push    ax                      ; save the integer value
  883.         mov     ax, LEN_EISALPT_STRUC   ; struc. size
  884.         mul     lpt_index               ;  multiplied by current index
  885.         mov     bx, ax                  ;  yields an offset.
  886.         inc     lpt_index               ; increment for next time
  887.         pop     ax                      ; get integer back
  888.         mov     LPTsFound[bx].printer_number, al  ; store the unit number
  889.         lea     si, Function.efi_eiri
  890.         lodsb                           ; get IRQ info.
  891.         .if     < bit al and EISA_IRQ_SHARABLE > and      ; is the IRQ sharable?
  892.         .if     < bit al and EISA_IRQ_LEVEL >             ; AND level triggered?
  893.             mov     LPTsFound[bx].sharable_IRQ, INT_SHARING   ; it is sharable
  894.         .else
  895.             mov     LPTsFound[bx].sharable_IRQ, 0   ; not sharable
  896.         .endif
  897.         and     al, 0Fh                 ; mask off all but IRQ number
  898.         mov     LPTsFound[bx].IRQ_number, al    ; store IRQ number
  899.         lea     si, Function.efi_epi    ; port info.
  900.         cld                             ; go forward
  901.         lodsb                           ; get I/O port information
  902.         and     al, EISA_NUMBER_PORTS   ; mask off all but number of ports
  903.         mov     cx, ax                  ; save the number of ports
  904.         lodsw                           ; get base port addr
  905.         mov     LPTsFound[bx].base_addr, ax     ; store base addr
  906.         add     ax, cx                  ; calculate last port addr
  907.         mov     LPTsFound[bx].end_addr, ax      ; store end addr
  908.  
  909. record_exit:
  910.         popa                            ; restore regs.
  911.         ret
  912. RecordFunc endp
  913.  
  914. ;****************************************************************************
  915. ;                                                                           *
  916. ; SUBROUTINE NAME:  ScanString                                              *
  917. ;                                                                           *
  918. ; FUNCTION: Searches the string at DS:SI for an occurrence of the string    *
  919. ;           at ES:DI.  Updates DS:SI.                                       *
  920. ;                                                                           *
  921. ; ENTRY POINT:  ScanString                                                  *
  922. ;     LINKAGE:  Call near (local and discarded after init)                  *
  923. ;               AX = length of string to be scanned                         *
  924. ;               BX = pattern length                                         *
  925. ;               DS:SI - String to search                                    *
  926. ;               ES:DI - Pattern to match                                    *
  927. ;                                                                           *
  928. ; EXIT-NORMAL:  Z = 1; search pattern was found, SI points to offset        *
  929. ;                                                                           *
  930. ; EXIT-ERROR:   Z = 0; the strings did not compare                          *
  931. ;                                                                           *
  932. ; EFFECTS:      SI                                                          *
  933. ;                                                                           *
  934. ;****************************************************************************
  935.  
  936. public  ScanString
  937. ScanString proc near
  938.  
  939.         push    cx                      ; save count register
  940.         mov     cx, ax                  ; get the string length
  941.         mov     ax, bx                  ; get the pattern length
  942.         dec     si                      ; pre-decrement for loop
  943.  
  944. search_string:
  945.         inc     si                      ; point to next attempt
  946.         call    strncmp                 ; compare the strings
  947.         loopnz  search_string           ; keep trying
  948.  
  949.         pop     cx                      ; restore the count register
  950.         ret                             ; and exit
  951.  
  952. ScanString endp
  953.  
  954. ;****************************************************************************
  955. ;                                                                           *
  956. ; SUBROUTINE NAME:  strncmp                                                 *
  957. ;                                                                           *
  958. ; FUNCTION: Compares two strings for a given length; ignores null           *
  959. ;                                                                           *
  960. ; ENTRY POINT:  strncmp                                                     *
  961. ;     LINKAGE:  Call near (local and discarded after init)                  *
  962. ;               AX = string length                                          *
  963. ;               DS:SI - string 1                                            *
  964. ;               ES:DI - string 2                                            *
  965. ;                                                                           *
  966. ; EXIT-NORMAL:  Z = 1; the strings did compare                              *
  967. ;                                                                           *
  968. ; EXIT-ERROR:   Z = 0; the strings did not compare                          *
  969. ;                                                                           *
  970. ; EFFECTS:      none, all registers restored                                *
  971. ;                                                                           *
  972. ;****************************************************************************
  973.  
  974. strncmp proc near
  975.  
  976.         push    cx                      ; save regs.
  977.         push    si
  978.         push    di
  979.  
  980.         mov     cx, ax                  ; get the string length
  981.         cld                             ; go forward
  982.         repe    cmpsb                   ; compare the strings
  983.  
  984.         pop     di                      ; restore regs.
  985.         pop     si
  986.         pop     cx
  987.         ret                             ; and exit
  988.  
  989. strncmp endp
  990.  
  991. CSEG    ENDS
  992.         END
  993.