home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / SCREENDD / SVGAID.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-04-14  |  232.5 KB  |  6,025 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. ;*
  14. ;* SOURCE FILE NAME = svgaid.asm
  15. ;*
  16. ;* DESCRIPTIVE NAME = Identify a super VGA adapter in the system, if one exsts.
  17. ;*
  18. ;*
  19. ;* VERSION      V2.0
  20. ;*
  21. ;* DATE
  22. ;*
  23. ;* DESCRIPTION  Identify a super VGA adapter in the system, if one exists.
  24. ;*
  25. ;*              extern void _IdentifySVGA (void);
  26. ;*
  27. ;*              Call from 'C' as:
  28. ;*
  29. ;*                      IdentifySVGA();
  30. ;*
  31. ;* FUNCTIONS
  32. ;*              UpperCaseSearch
  33. ;*              FindStringExpansion
  34. ;*              FindStringSomewhere
  35. ;*              FindStringPlanar
  36. ;*              FindString
  37. ;*              LookStringExpansion
  38. ;*              LookStringSomewhere
  39. ;*              LookStringPlanar
  40. ;*              LookString
  41. ;*              TextDelay
  42. ;*              OutpwDelay
  43. ;*              OutpDelay
  44. ;*              OutpData
  45. ;*              InpDelay
  46. ;*              InpwDelay
  47. ;*              InpData
  48. ;*              OutpInp
  49. ;*              OutpChk
  50. ;*              OutpIdxInpData
  51. ;*              SaveOutpChk
  52. ;*              OutpIdxXchgData
  53. ;*              OutpIdxChkXchgData
  54. ;*              OutpwChk
  55. ;*              SaveOutpwChk
  56. ;*              SaveXORChk
  57. ;*              SaveXORConst
  58. ;*              GetPortBase
  59. ;*              GetCrtcBase
  60. ;*              GetCrtcBaseSave1
  61. ;*              GetSave1
  62. ;*              GetSave2
  63. ;*              GetCrtcBaseSave2
  64. ;*              RestoreSave2
  65. ;*              RestoreSave1
  66. ;*              ATCOutpIdx
  67. ;*              IsNoCrtCWrap
  68. ;*              IsNOTISAAliased
  69. ;*              ATIWaitIdle
  70. ;*              ATIOutpChk
  71. ;*              ATIDestXOutpChk
  72. ;*              ATIAccelerator
  73. ;*              IsATI
  74. ;*              IsSpeedWay
  75. ;*              IsTrident
  76. ;*              IsTseng
  77. ;*              Video7EnableExt
  78. ;*              Video7DisableExt
  79. ;*              IsVideo7
  80. ;*              IsChips
  81. ;*              IsWeitek
  82. ;*              IsWeitekP9x00
  83. ;*              IsWesternDig
  84. ;*              WhichATI
  85. ;*              WhichTrident
  86. ;*              TsengSetATCMisc
  87. ;*              TsengLock
  88. ;*              TsengEnableExt
  89. ;*              TsengDisableExt
  90. ;*              WhichTseng
  91. ;*              WhichVideo7
  92. ;*              WhichWeitek
  93. ;*              WhichWeitekP9x00
  94. ;*              WhichWesternDig
  95. ;*              _IdentifySVGA
  96. ;*
  97. ;* NOTES        NONE
  98. ;*
  99. ;* STRUCTURES   NONE
  100. ;*
  101. ;* EXTERNAL REFERENCES
  102. ;*
  103. ;* EXTERNAL FUNCTIONS
  104. ;*
  105. ;****************************************************************************
  106.  
  107.         PAGE    58,132
  108.         TITLE   SVGA Idenfication Routines - (svgaid.asm)
  109.  
  110. INCL_16         EQU     1                                      ;/*          */
  111.  
  112. ifdef SVGAUTIL
  113.         .286
  114. ;!! Should this be imported somehow?                           ;/*          */
  115. DOSIODELAYCNT   EQU     10
  116. else ;/* SVGAUTIL */
  117.         .386p
  118.         include devhlp.inc              ;Define DevHlp functions
  119. endif ;/* SVGAUTIL */
  120.  
  121.  
  122. .xlist
  123.         include struc.inc                                      ;/*          */
  124.         include iodelay.inc                                    ;/*          */
  125.         UNDEFINE_SVGA   EQU     1       ; exclude various unwanted defs
  126.         include svgadefs.inc            ;          
  127. .list
  128.  
  129. ;!! How do we insure no one interrupts us while we do this?     /*          */
  130. ;* There is some chance of incorrect results here,              /*          */
  131. ;* due to an interrupting process which changes the contents of /*          */
  132. ;* of some VGA index register(s) between our setting them,      /*          */
  133. ;* and our reading or setting the associated data register.     /*          */
  134. ;* A screen saver program would be an example such process.     /*          */
  135.  
  136. ;/*
  137. ;**     Stuff which should be private
  138. ;*/
  139.  
  140. ;           all important indicies and values are saved on the stack
  141. ; STACK FRAME for identify routines
  142. ;Index/Value pairs must be in consecutive bytes for load by word.
  143. ;Reorder for easy loading                                       /*          */
  144. SaveValue1      EQU   <BYTE PTR [bp-1]>         ; BYTE
  145. SaveIndex1      EQU   <BYTE PTR [bp-2]>         ; BYTE
  146. SaveReg1        EQU   <WORD PTR [bp-4]>         ; WORD
  147. SaveValue2      EQU   <BYTE PTR [bp-5]>         ; BYTE
  148. SaveIndex2      EQU   <BYTE PTR [bp-6]>         ; BYTE
  149. SaveReg2        EQU   <WORD PTR [bp-8]>         ; WORD
  150. SaveValue3      EQU   <BYTE PTR [bp-9]>         ; BYTE
  151. SaveIndex3      EQU   <BYTE PTR [bp-10]>        ; BYTE
  152. SaveReg3        EQU   <WORD PTR [bp-12]>        ; WORD
  153. SaveValue4      EQU   <BYTE PTR [bp-13]>        ; BYTE
  154. SaveIndex4      EQU   <BYTE PTR [bp-14]>        ; BYTE
  155. SaveReg4        EQU   <BYTE PTR [bp-16]>        ; WORD
  156. STACKBLOCK      EQU   16
  157.  
  158. DGROUP  GROUP   BioData
  159.  
  160.         EXTRN   _sSVGA:DWORD            ;                       /*          */
  161.         EXTRN   _XGAInstance:WORD       ;                       /*          */
  162. ifndef SVGAUTIL
  163.         EXTRN  PCI_DeviceTbl:DWORD     ;@senja array of upto 8 (hw=Vendow ID, lw=Device ID)
  164.         EXTRN  PCI_Num:WORD            ;@senja number of PCI devices found
  165. endif
  166.  
  167. ifdef SVGAUTIL
  168. BioData SEGMENT WORD PUBLIC 'DATA'
  169. else
  170. BioData SEGMENT WORD PUBLIC 'DATA' USE16
  171. endif ;/* SVGAUTIL */
  172.  
  173.         ASSUME  DS:DGROUP
  174.  
  175.  
  176. ifdef SVGAUTIL
  177. else
  178.         EXTRN DevHelp: DWORD
  179. endif ;/* SVGAUTIL */
  180.  
  181. PUBLIC  SvgaOEMInfo
  182. PUBLIC  SvgaBaseAddr
  183. PUBLIC  DATA_END
  184.  
  185. SvgaOEMInfo     OEMINFO <SIZE OEMINFO,,>  ;@senja
  186. SvgaBaseAddr    DD      0
  187.  
  188. ;
  189. ; The following label defines the end of the Screen resident data.
  190. ;
  191. DATA_END LABEL  BYTE
  192.  
  193. ATISig          DB      ' 761295520'    ; 
  194. DiamondViperSig DB      'VIPER'         ;                       /*          */
  195. WDSig           DB      'VGA='          ; 
  196. WeitekSig       DB      'WEITEK'        ;                       /*          */
  197. ;                                                               /*          */
  198. ;       SEQ06 == Everybody's favorite lock register!            /*          */
  199. ;                                                               /*          */
  200. ;       But since WD and Video7 made the restore value          /*          */
  201. ;       not DIRECTLY readable, we cannot just read it           /*          */
  202. ;       while poking around looking for something else and      /*          */
  203. ;       restore what we read, expecting to preserve things!     /*          */
  204. ;                                                               /*          */
  205. ;       In fact, we CANNOT restore SEQ06 until after we know    /*          */
  206. ;       which adapter it is!                                    /*          */
  207. ;                                                               /*          */
  208. ;       But we CAN read enough without knowing which adapter    /*          */
  209. ;       to restore SEQ06 once we know which adapter!            /*          */
  210. ;                                                               /*          */
  211. ;       WD's SEQ06 restore value can be determined from         /*          */
  212. ;       how many bits the sequencer index preserves             /*          */
  213. ;       when you write to it: 6 unlocked, 3 locked.             /*          */
  214. ;                                                               /*          */
  215. ;       Video's SEQ06 restore value can be determined from      /*          */
  216. ;       the bit zero of what you read from SEQ06.               /*          */
  217. ;                                                               /*          */
  218. ;       Cirrus uses SEQ06 as a lock,                            /*          */
  219. ;       but at least you can read it! (Thank you!)              /*          */
  220. ;                                                               /*          */
  221. SEQ06           DB      ?               ;What we will restore!  /*          */
  222. SEQ06WD         DB      ?               ;Unless we are WD!      /*          */
  223.  
  224. BioData ends
  225.  
  226.  
  227.  
  228. ifdef SVGAUTIL
  229. BiosSeg SEGMENT WORD Public 'CODE'
  230. else
  231. BiosSeg SEGMENT WORD Public 'CODE' USE16
  232. endif ;/* SVGAUTIL */
  233.  
  234. BIOSSeg ends
  235.  
  236.  
  237.  
  238.  
  239. ;;endif ;endif svgautil
  240.  
  241. ; set opcodes back to normal
  242.  
  243. ifdef SVGAUTIL
  244.         .286
  245. else ;/* SVGAUTIL */
  246.         .386p
  247. endif ;/* SVGAUTIL */
  248.  
  249.  
  250. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end jwk18
  251.  
  252.  
  253.  
  254. ifdef SVGAUTIL
  255. BiosSeg SEGMENT WORD Public 'CODE'
  256. else
  257. BiosSeg SEGMENT WORD Public 'CODE' USE16
  258. endif ;/* SVGAUTIL */
  259.  
  260.         ASSUME  CS:BiosSeg
  261.  
  262. ;/****************************************************************************
  263. ;*
  264. ;* FUNCTION NAME = SVGAPhysToVirt
  265. ;*
  266. ;* DESCRIPTION   = Convert physical address to virtual.
  267. ;*
  268. ;* INPUT     =  AX = address high
  269. ;*              BX = address low
  270. ;*              CX = length
  271. ;* OUTPUT    =  DS:SI = selector/offset pair.
  272. ;*
  273. ;* RETURN-NORMAL = NC if no errors.
  274. ;* RETURN-ERROR  = CR if errors.
  275. ;*
  276. ;****************************************************************************/
  277.  
  278. SVGAPhysToVirt  PROC    Near
  279.                 PUBLIC  SVGAPhysToVirt
  280.  
  281. ifdef SVGAUTIL
  282.         mov     si, ax
  283.         ror     si, 4
  284.         and     si, 0f000h              ;Clears carry too!
  285.         mov     ds, si
  286.         mov     si, bx
  287. else
  288.         push    dx                      ;                       /*          */
  289.         mov     dh, 0                   ; 
  290.         mov     dl, DevHlp_PhysToVirt
  291.         call    DevHelp                 ;Leave result in DS:SI
  292.         pop     dx                      ;                       /*          */
  293. endif ;/* SVGAUTIL */
  294.  
  295.         ret
  296.  
  297. SVGAPhysToVirt  ENDP
  298.  
  299. ;/****************************************************************************
  300. ;*
  301. ;* FUNCTION NAME = SVGAUnPhysToVirt
  302. ;*
  303. ;* DESCRIPTION   = Unconvert physical address to virtual.
  304. ;*
  305. ;* INPUT     =  AX = address high
  306. ;*              BX = address low
  307. ;*              CX = length
  308. ;* OUTPUT    =  NONE
  309. ;*
  310. ;* RETURN-NORMAL = NONE
  311. ;* RETURN-ERROR  = NONE
  312. ;*
  313. ;****************************************************************************/
  314.  
  315. SVGAUnPhysToVirt PROC   Near
  316.                 PUBLIC  SVGAUnPhysToVirt
  317.  
  318. ifdef SVGAUTIL
  319.         clc                             ;Return NC.
  320. else
  321.         push    dx                      ;                       /*          */
  322.         mov     dl, DevHlp_UnPhysToVirt ;Let DevHlp know we're done
  323.         pushf                           ;Save results flags     /*          */
  324.         call    DevHelp                 ; using virtual addresses.
  325.         popf                            ;Restore results flags  /*          */
  326.         pop     dx                      ;                       /*          */
  327. endif ;/* SVGAUTIL */
  328.  
  329.         ret
  330.  
  331. SVGAUnPhysToVirt ENDP
  332.  
  333. ;*                                                             ;/*          */
  334. ;/****************************************************************************
  335. ;*
  336. ;* FUNCTION NAME = SVGAPhysToUVirt
  337. ;*
  338. ;* DESCRIPTION   = Convert physical address to virtual.
  339. ;*
  340. ;* INPUT     =  AX = address high
  341. ;*              BX = address low
  342. ;*              CX = length
  343. ;* OUTPUT    =  ES:BX = selector/offset pair.
  344. ;*
  345. ;* RETURN-NORMAL = NC if no errors.
  346. ;* RETURN-ERROR  = CR if errors.
  347. ;*
  348. ;****************************************************************************/
  349.  
  350. SVGAPhysToUVirt PROC    Near
  351.                 PUBLIC  SVGAPhysToUVirt
  352.  
  353. ifdef SVGAUTIL
  354. ;*
  355. ;*!!This is a non-working "safe"? dummy routine which points to ROM.
  356. ;*!!What we really need is an extension to the DOS XMS specification
  357. ;*!!or a ROM BIOS routine which handles 32-bit (not 24-bit) addresses,
  358. ;*!!which would provide a handle to physical memory         which do not
  359. ;*!!have RAM in them.
  360. ;*
  361.         mov     si, 0f000h              ;Point to ROM in case no carry check!
  362.         mov     es, si
  363.         mov     si, bx
  364.         stc                             ;Always an error for now!
  365. else
  366.         push    dx                      ;                       /*          */
  367.         mov     dh, 004h                ;Read/Write Segment&I/O Privilege
  368.         mov     dl, DevHlp_PhysToUVirt
  369.         call    DevHelp
  370.         pop     dx                      ;                       /*          */
  371. endif ;/* SVGAUTIL */
  372.  
  373.         ret
  374.  
  375. SVGAPhysToUVirt ENDP
  376.  
  377. ;*                                                             ;/*          */
  378. ;/****************************************************************************
  379. ;*
  380. ;* FUNCTION NAME = SVGAUnPhysToUVirt
  381. ;*
  382. ;* DESCRIPTION   = Unconvert physical address to virtual.
  383. ;*
  384. ;* INPUT     =  ES = selector to virtual address.
  385. ;* OUTPUT    =  NONE
  386. ;*
  387. ;* RETURN-NORMAL = NC if no errors.
  388. ;* RETURN-ERROR  = CR if errors.
  389. ;*
  390. ;****************************************************************************/
  391.  
  392. SVGAUnPhysToUVirt PROC   Near
  393.                 PUBLIC  SVGAUnPhysToUVirt
  394.  
  395. ifdef SVGAUTIL
  396.         clc                             ;Return NC.
  397. else
  398.         push    ax                      ;                       /*          */
  399.         mov     ax, es                  ;DevHelp Selector reg   /*          */
  400.         push    dx                      ;                       /*          */
  401.         mov     dh, 002h                ;UnMap
  402.         mov     dl, DevHlp_PhysToUVirt
  403.         pushf                           ;Save results flags     /*          */
  404.         call    DevHelp
  405.         popf                            ;Restore results flags  /*          */
  406.         pop     dx                      ;                       /*          */
  407.         pop     ax                      ;                       /*          */
  408. endif ;/* SVGAUTIL */
  409.  
  410.         ret
  411.  
  412. SVGAUnPhysToUVirt ENDP
  413.  
  414.  
  415. ;***    UpperCaseSearch
  416. ;          
  417. ;       Entry:  DS : SI Starting address of the string
  418. ;               CX = length of string
  419. ;               ES : DI ROM address to compare with
  420. ;
  421. ;       Capitalize the string at the location.
  422. ;       Restores all entry registers
  423. ;
  424. ;* RETURN-NORMAL = ZR if found.
  425. ;* RETURN-ERROR  = NZ if not found.
  426. ;
  427. UpperCaseSearch PROC    Near
  428.                 PUBLIC  UpperCaseSearch
  429.  
  430.         push    cx                      ;                       /*          */
  431.         jcxz    ExitUpperCase           ;Exit w/CX zero=success!/*          */
  432.         push    ax                      ;                       /*          */
  433.         push    si                      ;                       /*          */
  434.         push    di                      ;                       /*          */
  435. UpperCaseLoop:                          ;                       /*          */
  436.         mov     al, byte ptr ds:[si]
  437.         cmp     al, 'a'
  438.         jl      short @F
  439.         cmp     al, 'z'
  440.         jg      short @F
  441.         sub     al, 20h
  442. @@:
  443.         cmp     es:[di], al
  444.         jne     StringNotFound          ;Exit with CX non zero=failure!
  445.         inc     si
  446.         inc     di
  447.         loop    UpperCaseLoop           ;Loop or w/CX=success!  /*          */
  448. StringNotFound:                         ;                       /*          */
  449.         pop     di                      ;                       /*          */
  450.         pop     si                      ;                       /*          */
  451.         pop     ax                      ;                       /*          */
  452. ExitUpperCase:
  453.         and     cx, cx                  ;Success=no chars left  /*          */
  454.         pop     cx                      ;                       /*          */
  455.         ret
  456.  
  457. UpperCaseSearch ENDP
  458.  
  459. ;*                                                              /*          */
  460. ;/****************************************************************************
  461. ;*
  462. ;* FUNCTION NAME = FindStringExpansion
  463. ;*
  464. ;* DESCRIPTION   =
  465. ;*      Look for string at C000:xxxx ROM BIOS location to identify a SVGA card.
  466. ;*                 Capitalize the string searched as to make it case insensitive.
  467. ;*
  468. ;* INPUT     =  BX = ROM address (low)
  469. ;*              CX = length of string
  470. ;*              DS:DI -> string to compare (in DGROUP)
  471. ;*
  472. ;* OUTPUT    =  AX = 0000ch
  473. ;*
  474. ;* RETURN-NORMAL = ZR if found.
  475. ;* RETURN-ERROR  = NZ if not found.
  476. ;*
  477. ;****************************************************************************/
  478.  
  479. FindStringExpansion PROC    Near
  480.                 PUBLIC  FindStringExpansion
  481.  
  482.         mov     ax, 0000ch              ;                       /*          */
  483. ;       Now fall thru to (call and return):
  484.  
  485. ;*                                                              /*          */
  486. ;/****************************************************************************
  487. ;*
  488. ;* FUNCTION NAME = FindStringSomewhere
  489. ;*
  490. ;* DESCRIPTION   =
  491. ;*      Look for string at ROM BIOS location to identify a SVGA card.
  492. ;*                 Capitalize the string searched as to make it case insensitive.
  493. ;*
  494. ;* INPUT     =  AX = ROM address (high)
  495. ;*              BX = ROM address (low)
  496. ;*              CX = length of string
  497. ;*              DS:DI -> string to compare (in DGROUP)
  498. ;*
  499. ;* OUTPUT    =  NONE
  500. ;*
  501. ;* RETURN-NORMAL = ZR if found.
  502. ;* RETURN-ERROR  = NZ if not found.
  503. ;*
  504. ;****************************************************************************/
  505.  
  506. FindStringSomewhere PROC    Near
  507.                 PUBLIC  FindStringSomewhere
  508.  
  509.         push    es
  510.         push    ds
  511.         push    ds                      ;Move match string selector to ES.
  512.         pop     es
  513.         call    SVGAPhysToVirt          ;Get virtual address into DS:SI.
  514.  
  515.         ASSUME  DS:NOTHING, ES:DGROUP
  516.  
  517.         cld
  518. ;       xor     ax, ax                  ;                       /*          */
  519.         call    UpperCaseSearch
  520.         pop     ds                      ;Restore DEVHLP ptr selector!
  521.         pop     es
  522.  
  523.         ASSUME  DS:DGROUP, ES:NOTHING
  524.  
  525.         call    SVGAUnPhysToVirt        ;Unmap AX:BX.
  526.         ret
  527.  
  528. FindStringSomewhere     ENDP
  529.  
  530. FindStringExpansion     ENDP
  531.  
  532. ;*                                                              /*          */
  533. ;/****************************************************************************
  534. ;*
  535. ;* FUNCTION NAME = FindStringPlanar
  536. ;*
  537. ;* DESCRIPTION   =
  538. ;*      Look for string at E000:xxxx ROM BIOS location to identify a SVGA card.
  539. ;*                 Capitalize the string searched as to make it case insensitive.
  540. ;*
  541. ;* INPUT     =  BX = ROM address (low)
  542. ;*              CX = length of string
  543. ;*              DS:DI -> string to compare (in DGROUP)
  544. ;*
  545. ;* OUTPUT    =  AX = 0000eh
  546. ;*
  547. ;* RETURN-NORMAL = ZR if found.
  548. ;* RETURN-ERROR  = NZ if not found.
  549. ;*
  550. ;****************************************************************************/
  551.  
  552. FindStringPlanar PROC    Near
  553.                 PUBLIC  FindStringPlanar
  554.  
  555.         mov     ax, 0000eh              ;                       /*          */
  556.         call    FindStringSomewhere
  557.         ret
  558.  
  559. FindStringPlanar     ENDP
  560.  
  561. ;*                                                              /*          */
  562. ;/****************************************************************************
  563. ;*
  564. ;* FUNCTION NAME = FindString
  565. ;*
  566. ;* DESCRIPTION   =
  567. ;*      Look for string at ROM BIOS location to identify a SVGA card.
  568. ;*                 Capitalize the string searched as to make it case insensitive.
  569. ;*
  570. ;* INPUT     =  BX = ROM address (low)
  571. ;*              CX = length of string
  572. ;*              DS:DI -> string to compare (in DGROUP)
  573. ;*
  574. ;* OUTPUT    =  AX = ROM address (high)
  575. ;*
  576. ;* RETURN-NORMAL = ZR if found.
  577. ;* RETURN-ERROR  = NZ if not found.
  578. ;*
  579. ;****************************************************************************/
  580.  
  581. FindString      PROC    Near
  582.                 PUBLIC  FindString
  583.  
  584.         call    FindStringExpansion
  585.         .if     < nz >                  ;If not found on expansion card:
  586.             call    FindStringPlanar    ;Try planar ROM instead.
  587.         .endif
  588.         ret
  589.  
  590. FindString      ENDP
  591.  
  592. ;*                                                              /*          */
  593. ;/****************************************************************************
  594. ;*
  595. ;* FUNCTION NAME = LookStringExpansion
  596. ;*
  597. ;* DESCRIPTION   =
  598. ;*      Look for string at C000:0-200 ROM BIOS location to identify a SVGA card.
  599. ;*                 Capitalize the string searched as to make it case insensitive.
  600. ;*
  601. ;* INPUT     =  CX = length of string
  602. ;*              DS:DI -> string to compare (in DGROUP)
  603. ;*
  604. ;* OUTPUT    =  AX = 0000ch
  605. ;*
  606. ;* RETURN-NORMAL = ZR if found.
  607. ;* RETURN-ERROR  = NZ if not found.
  608. ;*
  609. ;****************************************************************************/
  610.  
  611. LookStringExpansion PROC    Near
  612.                 PUBLIC  LookStringExpansion
  613.  
  614.         mov     ax, 0000ch              ;                       /*          */
  615. ;       Now fall thru to (call and return):
  616.  
  617. ;*                                                              /*          */
  618. ;/****************************************************************************
  619. ;*
  620. ;* FUNCTION NAME = LookStringSomewhere
  621. ;*
  622. ;* DESCRIPTION   =
  623. ;*      Look for string at ROM BIOS offsets 0-200 to identify a SVGA card.
  624. ;*                 Capitalize the string searched as to make it case insensitive.
  625. ;*
  626. ;* INPUT     =  AX = ROM address (high)
  627. ;*              CX = length of string
  628. ;*              DS:DI -> string to compare (in DGROUP)
  629. ;*
  630. ;* OUTPUT    =  NONE
  631. ;*
  632. ;* RETURN-NORMAL = ZR if found.
  633. ;* RETURN-ERROR  = NZ if not found.
  634. ;*
  635. ;****************************************************************************/
  636.  
  637. LookStringSomewhere PROC    Near
  638.                 PUBLIC  LookStringSomewhere
  639.  
  640.         push    bx
  641.         push    es
  642.         push    ds
  643.         push    cx                      ;Save string length.
  644.         push    ds                      ;Move match string selector to ES.
  645.         pop     es
  646.         xor     bx, bx                  ;Low offset zero.
  647.         add     cx, 00200h              ;Limit search to first 200 bytes.
  648.         call    SVGAPhysToVirt          ;Get virtual address into DS:SI.
  649.         pop     cx                      ;Restore string length
  650.  
  651.         ASSUME  DS:NOTHING, ES:DGROUP
  652.  
  653.         cld
  654. ;       xor     ax, ax                  ;                       /*          */
  655.         .repeat
  656.             call    UpperCaseSearch
  657.         .until  <e> OR                  ;Until string found (z).
  658.             inc     si                  ;Check next location in ROM.
  659.         .until  <si a 00200h>           ;Until no more locations to check (nz).
  660.         pop     ds                      ;Restore DEVHLP ptr selector!
  661.         pop     es
  662.  
  663.         ASSUME  DS:DGROUP, ES:NOTHING
  664.  
  665.         call    SVGAUnPhysToVirt        ;Unmap AX:BX.
  666.         pop     bx
  667.         ret
  668.  
  669. LookStringSomewhere     ENDP
  670.  
  671. LookStringExpansion     ENDP
  672.  
  673. ;*                                                              /*          */
  674. ;/****************************************************************************
  675. ;*
  676. ;* FUNCTION NAME = LookStringPlanar
  677. ;*
  678. ;* DESCRIPTION   =
  679. ;*      Look for string at E000:0-200 ROM BIOS location to identify a SVGA card.
  680. ;*                 Capitalize the string searched as to make it case insensitive.
  681. ;*
  682. ;* INPUT     =  CX = length of string
  683. ;*              DS:DI -> string to compare (in DGROUP)
  684. ;*
  685. ;* OUTPUT    =  AX = 0000eh
  686. ;*
  687. ;* RETURN-NORMAL = ZR if found.
  688. ;* RETURN-ERROR  = NZ if not found.
  689. ;*
  690. ;****************************************************************************/
  691.  
  692. LookStringPlanar PROC    Near
  693.                 PUBLIC  LookStringPlanar
  694.  
  695.         mov     ax, 0000eh              ;                       /*          */
  696.         call    LookStringSomewhere
  697.         ret
  698.  
  699. LookStringPlanar     ENDP
  700.  
  701. ;*                                                              /*          */
  702. ;/****************************************************************************
  703. ;*
  704. ;* FUNCTION NAME = LookString
  705. ;*
  706. ;* DESCRIPTION   =
  707. ;*      Look for string at ROM BIOS offsets 0-200 to identify a SVGA card.
  708. ;*                 Capitalize the string searched as to make it case insensitive.
  709. ;*
  710. ;* INPUT     =  CX = length of string
  711. ;*              DS:DI -> string to compare (in DGROUP)
  712. ;*
  713. ;* OUTPUT    =  AX = ROM address (high)
  714. ;*
  715. ;* RETURN-NORMAL = ZR if found.
  716. ;* RETURN-ERROR  = NZ if not found.
  717. ;*
  718. ;****************************************************************************/
  719.  
  720. LookString      PROC    Near
  721.                 PUBLIC  LookString
  722.  
  723.         call    LookStringExpansion
  724.         .if     < nz >                  ;If not found on expansion card:
  725.             call    LookStringPlanar    ;Try planar ROM instead.
  726.         .endif
  727.         ret
  728.  
  729. LookString      ENDP
  730.  
  731. ;*
  732. ;*      All input and output instructions were deliberately put into
  733. ;*      separate subroutines to insure that a TextDelay preceeded each.
  734. ;*      Even though the chip being LOOKED FOR often does not need such
  735. ;*      delays, the chip being TESTED may need them!
  736. ;*
  737. ;*      We need to be able to minimize changes made to the chip being TESTED
  738. ;*      and restore it to its original state when we are done,
  739. ;*      so that we minimize the potential for annoying or damaging
  740. ;*      "special effects" on OTHER manufacturer's chips.
  741. ;*
  742.  
  743. ;/****************************************************************************
  744. ;*
  745. ;* FUNCTION NAME = TextDelay
  746. ;*
  747. ;* DESCRIPTION   = Instead of using the macro to save code space
  748. ;*
  749. ;* INPUT         = NONE
  750. ;* OUTPUT        = NONE
  751. ;*                 WARNING - trashes si
  752. ;*
  753. ;* RETURN-NORMAL = NONE
  754. ;* RETURN-ERROR  = NONE
  755. ;*
  756. ;* CALLED BY
  757. ;*      OutpwDelay
  758. ;*      OutpDelay
  759. ;*      InpDelay
  760. ;*      InpwDelay
  761. ;*
  762. ;****************************************************************************/
  763.  
  764. TextDelay       PROC    Near            ; 
  765.                 PUBLIC  TextDelay       ; 
  766.  
  767.         push       si                   ;                       ;JWK07
  768.         pushf                           ;Save flag register.    /*          */
  769.         DevIODelay si                   ; 
  770.         popf                            ;Restore flags.         /*          */
  771.         pop        si                   ;                       ;JWK07
  772.         ret                             ; 
  773.  
  774. TextDelay       ENDP                    ; 
  775.  
  776. ;/****************************************************************************
  777. ;*
  778. ;* FUNCTION NAME = _TextDelay
  779. ;*
  780. ;* DESCRIPTION   = Instead of using the macro to save code space
  781. ;*
  782. ;* INPUT         = NONE
  783. ;* OUTPUT        = NONE
  784. ;*
  785. ;* RETURN-NORMAL = NONE
  786. ;* RETURN-ERROR  = NONE
  787. ;*
  788. ;* CALLED BY
  789. ;*      InputDelay
  790. ;*      OutputDelay
  791. ;*
  792. ;****************************************************************************/
  793.  
  794. _TextDelay      PROC    Far             ;                       /*          */
  795.                 PUBLIC  _TextDelay      ; 
  796.  
  797.         call    TextDelay               ; 
  798.         ret
  799.  
  800. _TextDelay      ENDP                    ; 
  801.  
  802. ;*                                                              /*          */
  803. ;/****************************************************************************
  804. ;*
  805. ;* FUNCTION NAME = OutpwDelay
  806. ;*
  807. ;* DESCRIPTION   = Output to word port preceeded by I/O delay.
  808. ;*
  809. ;* INPUT         = DX = Output port.
  810. ;*                 AX = Value to output.
  811. ;* OUTPUT        = NONE
  812. ;*
  813. ;* RETURN-NORMAL = NONE
  814. ;* RETURN-ERROR  = NONE
  815. ;*
  816. ;* CALLED BY
  817. ;*
  818. ;****************************************************************************/
  819.  
  820. OutpwDelay      PROC    Near
  821.                 PUBLIC  OutpwDelay
  822.  
  823.         call    TextDelay               ;IMMEDIATELY before to minimize delay!
  824.         out     dx, ax                  ;Output to port.
  825.         ret
  826.  
  827. OutpwDelay       ENDP
  828.  
  829. ;*                                                              /*          */
  830. ;/****************************************************************************
  831. ;*
  832. ;* FUNCTION NAME = OutpDelay
  833. ;*
  834. ;* DESCRIPTION   = Output to byte port preceeded by I/O delay.
  835. ;*
  836. ;* INPUT         = DX = Output port.
  837. ;*                 AL = Value to output.
  838. ;* OUTPUT        = NONE
  839. ;*
  840. ;* RETURN-NORMAL = NONE
  841. ;* RETURN-ERROR  = NONE
  842. ;*
  843. ;* CALLED BY
  844. ;*
  845. ;****************************************************************************/
  846.  
  847. OutpDelay       PROC    Near
  848.                 PUBLIC  OutpDelay
  849.  
  850.         call    TextDelay               ;IMMEDIATELY before to minimize delay!
  851.         out     dx, al                  ;Output to port.
  852.         ret
  853.  
  854. OutpDelay        ENDP
  855.  
  856. ;*                                                              /*          */
  857. ;/****************************************************************************
  858. ;*
  859. ;* FUNCTION NAME = OutpData
  860. ;*
  861. ;* DESCRIPTION   = Output to byte port preceeded by I/O delay.
  862. ;*
  863. ;* INPUT         = DX = Output index port.
  864. ;*                 AL = Data value to output.
  865. ;* OUTPUT        = NONE
  866. ;*
  867. ;* RETURN-NORMAL = NONE
  868. ;* RETURN-ERROR  = NONE
  869. ;*
  870. ;* CALLED BY
  871. ;*
  872. ;****************************************************************************/
  873.  
  874. OutpData        PROC    Near
  875.                 PUBLIC  OutpData
  876.  
  877.         inc     dx                      ;Point to data register.
  878.         call    OutpDelay               ; 
  879.         dec     dx                      ;Point back to index register.
  880.         ret
  881.  
  882. OutpData        ENDP
  883.  
  884. ;*                                                              /*          */
  885. ;/****************************************************************************
  886. ;*
  887. ;* FUNCTION NAME = InpDelay
  888. ;*
  889. ;* DESCRIPTION   = Input from byte port preceeded by I/O delay.
  890. ;*
  891. ;* INPUT         = DX = Input port.
  892. ;* OUTPUT        = AL = Input value.
  893. ;*
  894. ;* RETURN-NORMAL = NONE
  895. ;* RETURN-ERROR  = NONE
  896. ;*
  897. ;* CALLED BY
  898. ;*
  899. ;****************************************************************************/
  900.  
  901. InpDelay        PROC    Near
  902.                 PUBLIC  InpDelay
  903.  
  904.         call    TextDelay               ;IMMEDIATELY before to minimize delay!
  905.         in      al, dx                  ;Input from port.
  906.         ret
  907.  
  908. InpDelay        ENDP
  909.  
  910. ;*                                                              /*          */
  911. ;/****************************************************************************
  912. ;*
  913. ;* FUNCTION NAME = InpwDelay
  914. ;*
  915. ;* DESCRIPTION   = Input from word port preceeded by I/O delay.
  916. ;*
  917. ;* INPUT         = DX = Input port.
  918. ;* OUTPUT        = AX = Input value.
  919. ;*
  920. ;* RETURN-NORMAL = NONE
  921. ;* RETURN-ERROR  = NONE
  922. ;*
  923. ;* CALLED BY
  924. ;*
  925. ;****************************************************************************/
  926.  
  927. InpwDelay       PROC    Near
  928.                 PUBLIC  InpwDelay
  929.  
  930.         call    TextDelay               ;IMMEDIATELY before to minimize delay!
  931.         in      ax, dx                  ;Input from port.
  932.         ret
  933.  
  934. InpwDelay       ENDP
  935.  
  936. ;*                                                              /*          */
  937. ;/****************************************************************************
  938. ;*
  939. ;* FUNCTION NAME = InpData
  940. ;*
  941. ;* DESCRIPTION   = Input from byte port preceeded by I/O delay.
  942. ;*
  943. ;* INPUT         = DX = Output index port.
  944. ;* OUTPUT        = AL = Data value input.
  945. ;*
  946. ;* RETURN-NORMAL = NONE
  947. ;* RETURN-ERROR  = NONE
  948. ;*
  949. ;* CALLED BY
  950. ;*      OutpIdxInpData
  951. ;*      IsTrident
  952. ;*      IsWeitek
  953. ;*      IsWeitekP9x00
  954. ;*      WhichWesternDig
  955. ;*
  956. ;****************************************************************************/
  957.  
  958. InpData         PROC    Near
  959.                 PUBLIC  InpData
  960.  
  961.         inc     dx                      ;Point to data register.
  962.         call    InpDelay                ; 
  963.         dec     dx                      ;Point back to index register.
  964.         ret
  965.  
  966. InpData         ENDP
  967.  
  968. ;*                                                              /*          */
  969. ;/****************************************************************************
  970. ;*
  971. ;* FUNCTION NAME = OutpInp
  972. ;*
  973. ;* DESCRIPTION   = Output to byte port and re-read it.
  974. ;*
  975. ;* INPUT         = DX = Input port.
  976. ;*                 AL = New value.
  977. ;* OUTPUT        = AL = Modified new value.
  978. ;*
  979. ;* RETURN-NORMAL = NONE
  980. ;* RETURN-ERROR  = NONE
  981. ;*
  982. ;* CALLED BY
  983. ;*      OutpChk
  984. ;*      SaveXORConst
  985. ;*      IsNotISAAliased
  986. ;*      IsCirrus
  987. ;*
  988. ;****************************************************************************/
  989.  
  990. OutpInp         PROC    Near
  991.                 PUBLIC  OutpInp
  992.  
  993.         call    OutpDelay               ;Write byte out.
  994.         call    InpDelay                ;Read modified byte back.
  995.         ret
  996.  
  997. OutpInp         ENDP
  998.  
  999. ;*                                                              /*          */
  1000. ;/****************************************************************************
  1001. ;*
  1002. ;* FUNCTION NAME = OutpChk
  1003. ;*
  1004. ;* DESCRIPTION   = Test for read/write register.
  1005. ;*
  1006. ;* INPUT         = DX = port address.
  1007. ;*                 AL = new value.
  1008. ;* OUTPUT        = NONE
  1009. ;*
  1010. ;* RETURN-NORMAL = ZR (reads match writes).
  1011. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1012. ;*
  1013. ;* CALLED BY
  1014. ;*      SaveOutpChk
  1015. ;*      OutpIdxXchgData
  1016. ;*      OutpIdxChkXchgData
  1017. ;*      OutpwChk
  1018. ;*      SaveXORChk
  1019. ;*      ATCOutpIdx
  1020. ;*      IsTseng
  1021. ;*      LastAttempt
  1022. ;*
  1023. ;****************************************************************************/
  1024.  
  1025. OutpChk         PROC    Near
  1026.                 PUBLIC  OutpChk
  1027.  
  1028.         push    ax
  1029.         mov     ah, al                  ;Save value written.
  1030.         call    OutpInp                 ;Write new & read modified value.
  1031.         cmp     al, ah                  ;Was read same as write?
  1032.         pop     ax
  1033.         ret
  1034.  
  1035. OutpChk         ENDP
  1036.  
  1037. ;*                                                              /*          */
  1038. ;/****************************************************************************
  1039. ;*
  1040. ;* FUNCTION NAME = OutpIdxInpData
  1041. ;*
  1042. ;* DESCRIPTION   = Read indexed register.
  1043. ;*
  1044. ;* INPUT         = DX = port address.
  1045. ;*                 AL = index.
  1046. ;* OUTPUT        = AL = value read.
  1047. ;*
  1048. ;* RETURN-NORMAL = NONE
  1049. ;* RETURN-ERROR  = NONE
  1050. ;*
  1051. ;* CALLED BY
  1052. ;*      OutpIdxXchgData
  1053. ;*      IsNoCrtcWrap
  1054. ;*      IsS3
  1055. ;*      TsengSetATCMisc
  1056. ;*      IsVideo7
  1057. ;*      WDRegPairString
  1058. ;*      IsWeitek
  1059. ;*      IsWeitekP9x00
  1060. ;*      LastAttempt
  1061. ;*      WhichATI
  1062. ;*      WhichCirrus
  1063. ;*      WhichS3
  1064. ;*      WhichTrident
  1065. ;*      WhichTseng
  1066. ;*      WhichVideo7
  1067. ;*      WhichWeitek
  1068. ;*      WhichWesternDig
  1069. ;*
  1070. ;****************************************************************************/
  1071.  
  1072. OutpIdxInpData  PROC    Near
  1073.                 PUBLIC  OutpIdxInpData
  1074.  
  1075.         call    OutpDelay               ;Write the new index value.
  1076.         call    InpData                 ;Read the data value.
  1077.         ret
  1078.  
  1079. OutpIdxInpData  ENDP
  1080.  
  1081. ;*                                                              /*          */
  1082. ;/****************************************************************************
  1083. ;*
  1084. ;* FUNCTION NAME = SaveOutpChk
  1085. ;*
  1086. ;* DESCRIPTION   = Test for read/write register.
  1087. ;*
  1088. ;* INPUT         = DX = port address.
  1089. ;*                 AL = new value.
  1090. ;* OUTPUT        = NONE
  1091. ;*                 original value restored.
  1092. ;*
  1093. ;* RETURN-NORMAL = ZR (reads match writes).
  1094. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1095. ;*
  1096. ;* CALLED BY
  1097. ;*      OutpIdxChkXchgData
  1098. ;*      OutpwChk
  1099. ;*      SaveOutpwChk
  1100. ;*      LastAttempt
  1101. ;*
  1102. ;****************************************************************************/
  1103.  
  1104. SaveOutpChk     PROC    Near
  1105.                 PUBLIC  SaveOutpChk
  1106.  
  1107.         push    ax
  1108.         mov     ah, al                  ;Save new value.
  1109.         call    InpDelay                ;Read the original value.
  1110.         xchg    ah, al                  ;Save original value, use new.
  1111.         call    OutpChk                 ;Write new value and compare.
  1112.         mov     al, ah                  ;Get back old value.
  1113.         call    OutpDelay               ;Restore old value if possible.
  1114.         .if     < z >                   ;If new value was the same,
  1115.             call    InpDelay            ;Read back the value.
  1116.             cmp     al, ah              ;Was read same as write?
  1117.         .endif
  1118.         pop     ax
  1119.         ret
  1120.  
  1121. SaveOutpChk     ENDP
  1122.  
  1123. ;*                                                              /*          */
  1124. ;/****************************************************************************
  1125. ;*
  1126. ;* FUNCTION NAME = OutpIdxXchgData
  1127. ;*
  1128. ;* DESCRIPTION   = Read and save indexed register, write with new value.
  1129. ;*
  1130. ;* INPUT         = DX = port address.
  1131. ;*                 AL = index.
  1132. ;*                 AH = new value to write.
  1133. ;* OUTPUT        = AL = value read.
  1134. ;*                 This value can be/must be "restored" to register addressed
  1135. ;*                 with the INPUT index.
  1136. ;*
  1137. ;* RETURN-NORMAL = NONE
  1138. ;* RETURN-ERROR  = NONE
  1139. ;*
  1140. ;* CALLED BY
  1141. ;*      IsCirrus
  1142. ;*      IsTrident
  1143. ;*      WhichS3
  1144. ;*
  1145. ;****************************************************************************/
  1146.  
  1147. OutpIdxXchgData PROC    Near
  1148.                 PUBLIC  OutpIdxXchgData
  1149.  
  1150.         call    OutpIdxInpData          ;Read the original value.
  1151.         xchg    al, ah                  ;Exchange old & new values.
  1152.         call    OutpData                ;Test for read/writable reg
  1153.         xchg    al, ah                  ;Exchange old & new values.
  1154.         ret
  1155.  
  1156. OutpIdxXchgData ENDP
  1157.  
  1158. ;*                                                              /*          */
  1159. ;/****************************************************************************
  1160. ;*
  1161. ;* FUNCTION NAME = OutpIdxChkXchgData
  1162. ;*
  1163. ;* DESCRIPTION   = Read and save indexed register, write with new value.
  1164. ;*
  1165. ;* INPUT         = DX = port address.
  1166. ;*                 AL = index.
  1167. ;*                 AH = new value to write.
  1168. ;* OUTPUT        = AL = value read.
  1169. ;*                 This value can be/must be "restored" to register addressed
  1170. ;*                 with the INPUT index, even when error (NZ) returned!
  1171. ;*
  1172. ;* RETURN-NORMAL = ZR (reads match writes).
  1173. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1174. ;*
  1175. ;* CALLED BY
  1176. ;*      GetCrtcBaseSave2
  1177. ;*      IsCirrus
  1178. ;*      Video7EnableExt
  1179. ;*      IsVideo7
  1180. ;*      WDEnableExt
  1181. ;*      WhichCirrus
  1182. ;*
  1183. ;****************************************************************************/
  1184.  
  1185. OutpIdxChkXchgData PROC    Near
  1186.                 PUBLIC  OutpIdxChkXchgData
  1187.  
  1188.         call    SaveOutpChk             ;Test for read/writeable index reg.
  1189.         pushf                           ;Save flags.
  1190.         call    OutpIdxInpData          ;Read the original value.
  1191.         popf                            ;Restore flags.
  1192.         .if     < z >                   ;If read/write index:
  1193.             xchg    al, ah              ;Exchange old & new values.
  1194.             push    dx
  1195.             inc     dx                  ;Point to the data register.
  1196.             call    OutpChk             ;Test for read/writable reg
  1197.             pop     dx
  1198.             xchg    al, ah              ;Exchange old & new values.
  1199.         .endif
  1200.         ret
  1201.  
  1202. OutpIdxChkXchgData ENDP
  1203.  
  1204. ;*                                                              /*          */
  1205. ;/****************************************************************************
  1206. ;*
  1207. ;* FUNCTION NAME = OutpwChk
  1208. ;*
  1209. ;* DESCRIPTION   = Test for read/write indexed/word register.
  1210. ;*
  1211. ;* INPUT         = DX = port address.
  1212. ;*                 AX = index (AL) and new value (AH).
  1213. ;* OUTPUT        = NONE
  1214. ;*
  1215. ;* RETURN-NORMAL = ZR (reads match writes).
  1216. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1217. ;*
  1218. ;* CALLED BY
  1219. ;*      WhichCirrus
  1220. ;*
  1221. ;****************************************************************************/
  1222.  
  1223. OutpwChk        PROC    Near
  1224.                 PUBLIC  OutpwChk
  1225.  
  1226.         call    SaveOutpChk             ;Check index set.
  1227.         .if     < z >                   ;If no error setting index:
  1228.             push    dx
  1229.             call    OutpDelay           ;Write the new index value.
  1230.             inc     dx                  ;Point to the data register.
  1231.             xchg    al, ah              ;Get new value.
  1232.             call    OutpChk
  1233.             xchg    al, ah
  1234.             pop     dx
  1235.         .endif
  1236.         ret
  1237.  
  1238. OutpwChk          ENDP
  1239.  
  1240. ;*                                                              /*          */
  1241. ;/****************************************************************************
  1242. ;*
  1243. ;* FUNCTION NAME = SaveOutpwChk
  1244. ;*
  1245. ;* DESCRIPTION   = Test indexed register for read/write register.
  1246. ;*
  1247. ;* INPUT         = DX = port address.
  1248. ;*                 AL = index register number.
  1249. ;*                 AH = new value.
  1250. ;* OUTPUT        = original value restored.
  1251. ;*
  1252. ;* RETURN-NORMAL = ZR (reads match writes).
  1253. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1254. ;*
  1255. ;* CALLED BY
  1256. ;*
  1257. ;****************************************************************************/
  1258.  
  1259. SaveOutpwChk    PROC    Near
  1260.                 PUBLIC  SaveOutpwChk
  1261.  
  1262.         call    SaveOutpChk             ;Check index set.
  1263.         .if     < z >                   ;If no error and can set index:
  1264.             push    dx
  1265.             call    OutpDelay           ;Write the new index value.
  1266.             inc     dx                  ;Point to the data register.
  1267.             xchg    al, ah              ;Get new value.
  1268.             call    SaveOutpChk
  1269.             xchg    al, ah
  1270.             pop     dx
  1271.         .endif
  1272.         ret
  1273.  
  1274. SaveOutpwChk          ENDP
  1275.  
  1276. ;*                                                              /*          */
  1277. ;/****************************************************************************
  1278. ;*
  1279. ;* FUNCTION NAME = SaveXORChk
  1280. ;*
  1281. ;* DESCRIPTION   = Test for read write register.
  1282. ;*
  1283. ;* INPUT         = DX = port address.
  1284. ;*                 AL = value to XOR with.
  1285. ;* OUTPUT        = original value restored.
  1286. ;*
  1287. ;* RETURN-NORMAL = ZR (reads match writes).
  1288. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1289. ;*
  1290. ;* CALLED BY
  1291. ;*
  1292. ;****************************************************************************/
  1293.  
  1294. SaveXORChk      PROC    Near
  1295.                 PUBLIC  SaveXORChk
  1296.  
  1297.         push    ax
  1298.         mov     ah, al                  ;Save bits to modify.
  1299.         call    InpDelay                ;Read the original value.
  1300.         xchg    ah, al                  ;Save original value, restore mask.
  1301.         xor     al, ah                  ;XOR in changable bits.
  1302.         call    OutpChk                 ;Write new value and compare.
  1303.         mov     al, ah                  ;Get back old value.
  1304.         call    OutpDelay               ;Restore old value if possible.
  1305.         .if     < z >                   ;If new value was the same,
  1306.             call    InpDelay            ;Read back the value.
  1307.             cmp     al, ah              ;Was read same as write?
  1308.         .endif
  1309.         pop     ax
  1310.         ret
  1311.  
  1312. SaveXORChk      ENDP
  1313.  
  1314. ;*                                                              /*          */
  1315. ;/****************************************************************************
  1316. ;*
  1317. ;* FUNCTION NAME = SaveXORConst
  1318. ;*
  1319. ;* DESCRIPTION   = Test for unwritable (constant) bits in register.
  1320. ;*
  1321. ;* INPUT         = DX = port address.
  1322. ;*                 AL = value to XOR with.
  1323. ;* OUTPUT        = original value restored.
  1324. ;*
  1325. ;* RETURN-NORMAL = ZR (no bits changed).
  1326. ;* RETURN-ERROR  = NZ (some bits changed).
  1327. ;*
  1328. ;* CALLED BY
  1329. ;*
  1330. ;****************************************************************************/
  1331.  
  1332. SaveXORConst    PROC    Near
  1333.                 PUBLIC  SaveXORConst
  1334.  
  1335.         push    ax
  1336.         mov     ah, al                  ;Save bits to modify.
  1337.         call    InpDelay                ;Get original value.
  1338.         xchg    ah, al                  ;Save original value, restore mask.
  1339.         xor     al, ah                  ;XOR in presumed constant bits.
  1340.         call    OutpInp                 ;Write new & read modified values.
  1341.         xor     al, ah                  ;Did bits stay same? Return success!
  1342.         mov     al, ah                  ;Get original value.
  1343.         call    OutpDelay               ;Restore original value.
  1344.         pop     ax
  1345.         ret
  1346.  
  1347. SaveXORConst     ENDP
  1348.  
  1349. ;/****************************************************************************
  1350. ;*
  1351. ;* FUNCTION NAME = GetPortBase
  1352. ;*
  1353. ;* DESCRIPTION   = Return port base address in DX (3b0 or 3d0)
  1354. ;*                 depending on mono/colour mode.
  1355. ;*
  1356. ;* INPUT         = NONE
  1357. ;* OUTPUT        = DX = 3x0 (3b0 or 3d0) port base address.
  1358. ;*
  1359. ;* RETURN-NORMAL = NONE
  1360. ;* RETURN-ERROR  = NONE
  1361. ;*
  1362. ;* CALLED BY
  1363. ;*      GetCrtcBase
  1364. ;*      ATCOutpIdx
  1365. ;*      TsengLock
  1366. ;*      TsengEnableExt
  1367. ;*
  1368. ;****************************************************************************/
  1369.  
  1370. GetPortBase     PROC    Near
  1371.                 PUBLIC  GetPortBase
  1372.  
  1373.         push    ax                      ;                       /*          */
  1374.         mov     dx, 03cch               ;Misc Output Read addr
  1375.         call    InpDelay                ;Input from port.
  1376.         mov     dl, 0b0h                ; assume mono           /*          */
  1377.         and     al, 001h                ;                       /*          */
  1378.         shl     al, 5                   ;                       /*          */
  1379.         add     dl, al                  ;Bump up to color maybe /*          */
  1380.         pop     ax                      ;                       /*          */
  1381.         ret                             ;                       /*          */
  1382.  
  1383. GetPortBase     ENDP
  1384.  
  1385. ;*                                                              /*          */
  1386. ;/****************************************************************************
  1387. ;*
  1388. ;* FUNCTION NAME = GetCrtcBase
  1389. ;*
  1390. ;* DESCRIPTION   = Return port base address in DX (3b0 or 3d0)
  1391. ;*                 depending on mono/colour mode.
  1392. ;*
  1393. ;* INPUT         = NONE
  1394. ;* OUTPUT        = DX = 3x4 port base address.
  1395. ;*                 CX = 3x0 base address.
  1396. ;*
  1397. ;* RETURN-NORMAL = NONE
  1398. ;* RETURN-ERROR  = NONE
  1399. ;*
  1400. ;* CALLED BY
  1401. ;*      GetCrtcBaseSave1
  1402. ;*      WhichCirrus
  1403. ;*      WhichTrident
  1404. ;*      WhichTseng
  1405. ;*
  1406. ;****************************************************************************/
  1407.  
  1408. GetCrtcBase     PROC    Near
  1409.                 PUBLIC  GetCrtcBase
  1410.  
  1411.         call    GetPortBase             ;Depends on mono/color  /*          */
  1412.         mov     cx, dx                  ; 
  1413.         add     dl, 0004h               ;Crtc index address.
  1414.         ret
  1415.  
  1416. GetCrtcBase     ENDP
  1417.  
  1418. ;*                                                              /*          */
  1419. ;/****************************************************************************
  1420. ;*
  1421. ;* FUNCTION NAME = GetCrtcBaseSave1
  1422. ;*
  1423. ;* DESCRIPTION   = Return port base address in DX (3b0 or 3d0)
  1424. ;*                 depending on mono/colour mode.
  1425. ;*
  1426. ;* INPUT         = AX = index register to save and new value.
  1427. ;*                 BP = stack frame pointer.
  1428. ;* OUTPUT        = DX = 3x4 port base address.
  1429. ;*                 CX = 3x0 base address.
  1430. ;*
  1431. ;* RETURN-NORMAL = NONE
  1432. ;* RETURN-ERROR  = NONE
  1433. ;*
  1434. ;* CALLED BY
  1435. ;*
  1436. ;****************************************************************************/
  1437.  
  1438. GetCrtcBaseSave1 PROC    Near
  1439.                 PUBLIC  GetCrtcBaseSave1
  1440.  
  1441.         call    GetCrtcBase             ;(3d4)                  /*          */
  1442. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  1443. ;       Now fall thru to (call and return):
  1444.  
  1445. ;*                                                              /*          */
  1446. ;/****************************************************************************
  1447. ;*
  1448. ;* FUNCTION NAME = GetSave1
  1449. ;*
  1450. ;* DESCRIPTION   = Input from byte port preceeded by I/O delay.
  1451. ;*                 Save into SaveReg1/SaveIndex1 pair.
  1452. ;*
  1453. ;* INPUT         = DX = Input port.
  1454. ;*                 BP = Stack frame pointer.
  1455. ;* OUTPUT        = NONE
  1456. ;*
  1457. ;* RETURN-NORMAL = NONE
  1458. ;* RETURN-ERROR  = NONE
  1459. ;*
  1460. ;* CALLED BY
  1461. ;*      GetCrtcBaseSave1
  1462. ;*      IsCirrus
  1463. ;*      IsTrident
  1464. ;*      IsWeitek
  1465. ;*      IsWeitekP9x00
  1466. ;*      WhichCirrus
  1467. ;*      WhichTseng
  1468. ;*      WhichWeitek
  1469. ;*
  1470. ;****************************************************************************/
  1471.  
  1472. GetSave1        PROC    Near
  1473.                 PUBLIC  GetSave1
  1474.  
  1475.         mov     [SaveReg1], dx
  1476.         push    ax
  1477.         call    InpDelay                ;Read the original value.
  1478.         mov     [SaveIndex1], al        ;Save it.
  1479.         pop     ax
  1480.         ret
  1481.  
  1482. GetSave1        ENDP
  1483.  
  1484. GetCrtcBaseSave1 ENDP
  1485.  
  1486. ;*                                                              /*          */
  1487. ;/****************************************************************************
  1488. ;*
  1489. ;* FUNCTION NAME = GetSave2
  1490. ;*
  1491. ;* DESCRIPTION   = Input from byte port preceeded by I/O delay.
  1492. ;*                 Save into SaveReg2/SaveIndex2 pair.
  1493. ;*
  1494. ;* INPUT         = DX = Input port.
  1495. ;*                 BP = Stack frame pointer.
  1496. ;* OUTPUT        = NONE
  1497. ;*
  1498. ;* RETURN-NORMAL = NONE
  1499. ;* RETURN-ERROR  = NONE
  1500. ;*
  1501. ;* CALLED BY
  1502. ;*      TsengEnableExt
  1503. ;*      Video7EnableExt
  1504. ;*      LastAttempt
  1505. ;*
  1506. ;****************************************************************************/
  1507.  
  1508. GetSave2        PROC    Near
  1509.                 PUBLIC  GetSave2
  1510.  
  1511.         mov     [SaveReg2], dx
  1512.         push    ax
  1513.         call    InpDelay                ;Read the original value.
  1514.         mov     [SaveIndex2], al        ;Save it.
  1515.         pop     ax
  1516.         ret
  1517.  
  1518. GetSave2        ENDP
  1519.  
  1520. ;*                                                              /*          */
  1521. ;/****************************************************************************
  1522. ;*
  1523. ;* FUNCTION NAME = GetCrtcBaseSave2
  1524. ;*
  1525. ;* DESCRIPTION   = Return port base address in DX (3b0 or 3d0)
  1526. ;*                 depending on mono/colour mode.
  1527. ;*
  1528. ;* INPUT         = AX = index register to save and new value.
  1529. ;*                 BP = stack frame pointer.
  1530. ;* OUTPUT        = DX = 3x4 port base address.
  1531. ;*                 CX = 3x0 base address.
  1532. ;*
  1533. ;* RETURN-NORMAL = ZR (reads match writes).
  1534. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1535. ;*
  1536. ;* CALLED BY
  1537. ;*
  1538. ;****************************************************************************/
  1539.  
  1540. GetCrtcBaseSave2 PROC    Near
  1541.                 PUBLIC  GetCrtcBaseSave2
  1542.  
  1543.         call    GetCrtcBaseSave1        ;(3d4)                  /*          */
  1544. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  1545.         mov     [SaveReg2], dx          ;Save register address.
  1546.         mov     [SaveIndex2], al        ;Save index register.
  1547.         push    ax                      ;Save index register and value.
  1548.         call    OutpIdxChkXchgData      ;Read original value, write new.
  1549.         mov     [SaveValue2], al        ;Save original value for restore.
  1550.         pop     ax                      ;Restore index register and value.
  1551.         ret
  1552.  
  1553. GetCrtcBaseSave2 ENDP
  1554.  
  1555. ;*                                                              /*          */
  1556. ;/****************************************************************************
  1557. ;*
  1558. ;* FUNCTION NAME = RestoreSave2
  1559. ;*
  1560. ;* DESCRIPTION   = Restore indexed register and index value.
  1561. ;*
  1562. ;* INPUT         = BP = Stack frame pointer.
  1563. ;* OUTPUT        = NONE
  1564. ;*
  1565. ;* RETURN-NORMAL = NONE
  1566. ;* RETURN-ERROR  = NONE
  1567. ;*
  1568. ;* CALLED BY
  1569. ;*      IsCirrus
  1570. ;*      WDDisableExt
  1571. ;*      WhichCirrus
  1572. ;*      WhichS3
  1573. ;*
  1574. ;****************************************************************************/
  1575.  
  1576. RestoreSave2    PROC    Near
  1577.                 PUBLIC  RestoreSave2
  1578.  
  1579.         mov     dx, [SaveReg2]
  1580.         push    ax
  1581.         mov     ax, word ptr [SaveIndex2]   ;Get the original value.
  1582.         call    OutpwDelay              ;Write the original value.
  1583.         pop     ax
  1584. ;       Now fall thru to (call and return):
  1585.  
  1586. ;*                                                              /*          */
  1587. ;/****************************************************************************
  1588. ;*
  1589. ;* FUNCTION NAME = RestoreSave1
  1590. ;*
  1591. ;* DESCRIPTION   = Restore original index register value.
  1592. ;*
  1593. ;* INPUT         = BP = Stack frame pointer.
  1594. ;* OUTPUT        = NONE
  1595. ;*
  1596. ;* RETURN-NORMAL = NONE
  1597. ;* RETURN-ERROR  = NONE
  1598. ;*
  1599. ;* CALLED BY
  1600. ;*      RestoreSave2
  1601. ;*      IsTrident
  1602. ;*      IsTseng
  1603. ;*      IsVideo7
  1604. ;*      IsWeitek
  1605. ;*      IsWeitekP9x00
  1606. ;*      LastAttempt
  1607. ;*      WhichTseng
  1608. ;*      WhichWeitek
  1609. ;*
  1610. ;****************************************************************************/
  1611.  
  1612. RestoreSave1    PROC    Near
  1613.                 PUBLIC  RestoreSave1
  1614.  
  1615.         mov     dx, [SaveReg1]
  1616.         push    ax
  1617.         mov     al, [SaveIndex1]        ;Get the original value.
  1618.         call    OutpDelay               ;Write the original value.
  1619.         pop     ax
  1620.         ret
  1621.  
  1622. RestoreSave1     ENDP
  1623.  
  1624. RestoreSave2     ENDP
  1625.  
  1626. ;*                                                                /*          */
  1627. ;/****************************************************************************
  1628. ;*
  1629. ;* FUNCTION NAME = ATCOutpIdx
  1630. ;*
  1631. ;* DESCRIPTION   = Reset ATC Flip flop and set ATC index.
  1632. ;*
  1633. ;* INPUT         = AL = New index value to set.
  1634. ;* OUTPUT        = DX = 3c0 = ATC Index address
  1635. ;*                 CX = 3x0 base address
  1636. ;* CLOBBERS      = AH
  1637. ;*
  1638. ;* RETURN-NORMAL = ZR (reads match writes).
  1639. ;* RETURN-ERROR  = NZ (reads do not match writes).
  1640. ;*
  1641. ;* CALLED BY
  1642. ;*      IsTseng
  1643. ;*
  1644. ;****************************************************************************/
  1645.  
  1646. ATCOutpIdx      PROC    Near
  1647.                 PUBLIC  ATCOutpIdx
  1648.  
  1649.         call    GetPortBase             ;Get port base address
  1650.         add     dx, 00ah
  1651.         push    ax                      ;Save new index to set.
  1652.         call    InpDelay                ;Dummy read to set to index write.
  1653.         pop     ax                      ;Restore new index to set.
  1654.         mov     dl, 0c0h                ;ATC address (3c0)
  1655.         call    OutpChk                 ;Write new ATC index value.
  1656.         ret
  1657.  
  1658. ATCOutpIdx      ENDP
  1659.  
  1660. ;*                                                              /*          */
  1661. ;/****************************************************************************
  1662. ;*
  1663. ;* FUNCTION NAME = IsNoCrtcWrap
  1664. ;*
  1665. ;* DESCRIPTION   = Check for CTRC Wrap at 020h
  1666. ;*
  1667. ;* INPUT         = BP = Stack frame pointer.
  1668. ;*                 DX = 3x4 port base address.
  1669. ;* OUTPUT        = NONE
  1670. ;*
  1671. ;* RETURN-NORMAL = ZR (if no wrap).
  1672. ;* RETURN-ERROR  = NZ (if wrap).
  1673. ;*
  1674. ;* CALLED BY
  1675. ;*      WDEnableExt
  1676. ;*      IsS3
  1677. ;*      IsTseng
  1678. ;*
  1679. ;****************************************************************************/
  1680.  
  1681. IsNoCrtcWrap    PROC    Near
  1682.                 PUBLIC  IsNoCrtcWrap
  1683.  
  1684.         mov     al, 00fh + 020h         ;Use safe reg: cur addr low
  1685.         call    OutpIdxInpData          ;Get current value
  1686.         mov     ah, al                  ; 
  1687.         mov     al, 00fh                ;Point to cur addr low reg
  1688.         call    OutpIdxInpData          ; 
  1689.         .if     <al e ah>               ;If regs are same:
  1690.             not     al                  ;Get ones complement.
  1691.             call    OutpData            ; 
  1692.             mov     al, 00fh + 020h     ;Point past wrapping
  1693.             call    OutpIdxInpData      ; 
  1694.             not     al                  ;Get ones complement.
  1695.             cmp     al, ah              ;See if regs are still the same.
  1696.             mov     al, 00fh            ;Point to row offset reg
  1697.             call    OutpwDelay          ;Restore cur addr low.
  1698.         .endif
  1699.         lahf                            ;Get flags into AH.
  1700.         and     ah, 040h                ;Complement zero flag!
  1701.         ret
  1702.  
  1703. IsNoCrtcWrap    ENDP
  1704.  
  1705. ;*                                                              /*          */
  1706. ;/****************************************************************************
  1707. ;*
  1708. ;* FUNCTION NAME = IsNotISAAliased
  1709. ;*
  1710. ;* DESCRIPTION   = Test for register NOT ISA aliased.
  1711. ;*
  1712. ;* INPUT         = DX = port address.
  1713. ;*                 AL = SAFE new mask to XOR test.
  1714. ;* OUTPUT        = NONE
  1715. ;*
  1716. ;* RETURN-NORMAL = ZR (reads do not match writes).  Is NOT Aliased!
  1717. ;* RETURN-ERROR  = NZ (reads match writes).  Is Aliased!
  1718. ;*
  1719. ;* CALLED BY
  1720. ;*      IsSpeedWay
  1721. ;*
  1722. ;****************************************************************************/
  1723.  
  1724. IsNotISAAliased PROC    Near
  1725.                 PUBLIC  IsNotISAAliased
  1726.  
  1727.         push    ax                      ;Save original & test values.
  1728.         push    bx
  1729.         push    cx
  1730.         mov     bl, al                  ;Save test mask to XOR.
  1731.         mov     cx, dx                  ;Save original port.
  1732.         call    InpDelay                ;Get value at original port.
  1733.         mov     bh, al                  ;Save value at original port.
  1734. ;
  1735. ;               003ffh mask should be similarly effective.      /*          */
  1736. ;
  1737.         and     dx, 00fffh              ;Get alias port address.
  1738.         call    InpDelay                ;Get value at alias port.
  1739.         xchg    dx, cx                  ;Get back original port.
  1740.         .if     <al e bh>               ;Can only be alias if same now first!
  1741.             mov     al, bh              ;Restore original value.
  1742.             xor     al, bl              ;XOR with test mask to force changes.
  1743.             call    OutpInp             ;Write new & read modified values.
  1744.             mov     ah, al              ;Save modified test value.
  1745.             xchg    dx, cx              ;Get back alias port.
  1746.             call    InpDelay            ;Read back the value.
  1747.             cmp     al, ah              ;Was alias read same as write?
  1748.             xchg    dx, cx              ;Get back original port.
  1749.             mov     al, bh              ;Get original value.
  1750.             call    OutpDelay           ;Restore original value.
  1751.         .endif
  1752.         lahf                            ;Get flags.
  1753.         and     ah, 040h                ;Complement ZR, now NOT aliased!
  1754.         pop     cx
  1755.         pop     bx
  1756.         pop     ax
  1757.         ret
  1758.  
  1759. IsNotISAAliased    ENDP
  1760.  
  1761. ;*****************************************************************************
  1762. ;
  1763. ;
  1764. ;
  1765. ;*****************************************************************************
  1766.  
  1767. ;*                                                              /*          */
  1768. ;/****************************************************************************
  1769. ;*
  1770. ;* FUNCTION NAME = ATIWaitIdle
  1771. ;*
  1772. ;* DESCRIPTION   = Wait for ATI accelerator to be idle.
  1773. ;*
  1774. ;* INPUT         = NONE
  1775. ;* OUTPUT        = NONE
  1776. ;*
  1777. ;* RETURN-NORMAL = ZR (now idle)
  1778. ;* RETURN-ERROR  = NZ (timeout)
  1779. ;*
  1780. ;* CALLED BY
  1781. ;*
  1782. ;****************************************************************************/
  1783.  
  1784. ATIWaitIdle     PROC    near                                    ;          
  1785.                 PUBLIC  ATIWaitIdle
  1786.  
  1787.         xor     cx, cx                  ;Initialize timeout.
  1788.         push    dx
  1789.         mov     dx, 09aeeh              ;EXT_FIFO_STATUS reg.
  1790.         .repeat
  1791.             call    InpwDelay           ;Read EXT_FIFO_STATUS reg.
  1792.             test    ax, 00001h          ;16 free FIFOs?
  1793.         .loop   < nz >                  ;Wait until timeout or YES.
  1794.         .if     < z >                   ;If no failure:
  1795.             xor     cx, cx              ;Initialize timeout.
  1796.             mov     dx, 09ae8h          ;GP_STAT reg.
  1797.             .repeat
  1798.                 call    InpwDelay       ;Read GP_STAT reg.
  1799.                 test    ax, 00200h      ;GP_BUSY?
  1800.             .loop   < nz >              ;Wait until timeout or NO.
  1801.         .endif
  1802.         pop dx
  1803.         ret
  1804.  
  1805. ATIWaitIdle ENDP
  1806.  
  1807. ;*                                                              /*          */
  1808. ;/****************************************************************************
  1809. ;*
  1810. ;* FUNCTION NAME = ATIOutpChk
  1811. ;*
  1812. ;* DESCRIPTION   = Test ATI chip for register writable.
  1813. ;*
  1814. ;* INPUT         = AX - value to write.
  1815. ;*                 DX - register address to write to and read from.
  1816. ;* OUTPUT        = NONE
  1817. ;*
  1818. ;* RETURN-NORMAL = ZR (now idle and same)
  1819. ;* RETURN-ERROR  = NZ (timeout or different)
  1820. ;*
  1821. ;* CALLED BY
  1822. ;*
  1823. ;****************************************************************************/
  1824.  
  1825. ATIOutpChk      PROC    near                                     ;          
  1826.                 PUBLIC  ATIOutpChk
  1827.  
  1828.         mov     bx, ax                      ;Save original value to write.
  1829.         call    OutpwDelay                  ;Write register value.
  1830.         call    ATIWaitIdle
  1831.         .if     < z >                       ;If idle and OK so far:
  1832.             call    InpwDelay               ;Read the register again.
  1833.             cmp     ax, bx                  ;Compare with original written value.
  1834.         .endif                              ;Else failure.
  1835.         ret
  1836.  
  1837. ATIOutpChk      ENDP
  1838.  
  1839. ;*                                                              /*          */
  1840. ;/****************************************************************************
  1841. ;*
  1842. ;* FUNCTION NAME = ATIDestXOutpChk
  1843. ;*
  1844. ;* DESCRIPTION   = Test ATI chip for DESTX_DIASTP set effecting READ_SRC_X.
  1845. ;*
  1846. ;* INPUT         = AX - value to write.
  1847. ;* OUTPUT        = NONE
  1848. ;*
  1849. ;* RETURN-NORMAL = ZR (now idle and same)
  1850. ;* RETURN-ERROR  = NZ (timeout or different)
  1851. ;*
  1852. ;* CALLED BY
  1853. ;*
  1854. ;****************************************************************************/
  1855.  
  1856. ATIDestXOutpChk PROC    Near
  1857.                 PUBLIC  ATIDestXOutpChk
  1858.  
  1859.         mov     bx, ax              ;Save original value to write.
  1860.         mov     dx, 08ee8h          ;Get DESTX_DIASTP reg address.
  1861.         call    OutpwDelay          ;Write the new value.
  1862.         call    ATIWaitIdle
  1863.         .if     < z >               ;If idle and OK so far:
  1864.             mov     dx,0daeeh       ;Get READ_SRC_X reg address.
  1865.             call    InpwDelay       ;Read the value.
  1866.             cmp     ax,bx           ;Compare with original written value.
  1867.         .endif                      ;Else failure.
  1868.         ret
  1869.  
  1870. ATIDestXOutpChk ENDP
  1871.  
  1872. ;*                                                              /*          */
  1873. ;/****************************************************************************
  1874. ;*
  1875. ;* FUNCTION NAME = ATI8514
  1876. ;*
  1877. ;* DESCRIPTION   = Test ATI chip for 8514 Accelerator.
  1878. ;*
  1879. ;* INPUT         = NONE
  1880. ;* OUTPUT        = NONE
  1881. ;*
  1882. ;* RETURN-NORMAL = ZR (has 8514 Accelerator)
  1883. ;* RETURN-ERROR  = NZ (timeout or other failure)
  1884. ;*
  1885. ;* CALLED BY
  1886. ;*
  1887. ;****************************************************************************/
  1888.  
  1889. ATI8514         PROC    near            ;                       /*          */
  1890.                 PUBLIC  ATI8514         ;                       /*          */
  1891.  
  1892. ;*
  1893. ;*  Test for 8514 first.
  1894. ;*
  1895.         mov     dx, 042e8h              ;SUBSYS_CNTL reg.
  1896.         mov     ax, 0900fh
  1897.         call    OutpwDelay              ;Write the new value.
  1898.         mov     ax, 0400fh
  1899.         call    OutpwDelay              ;Write the new value.
  1900.         mov     dx, 002ebh              ;DAC_R_INDEX reg.
  1901.         mov     al, 0a4h
  1902.         call    OutpDelay               ;Write the new value.
  1903.         xor     cx, cx
  1904.         .repeat                         ;Wait fixed amount of time.
  1905.         .loop
  1906.         mov     dx, 002ech              ;DAC_W_INDEX reg
  1907.         call    InpDelay                ;Input from port.
  1908.         .if     <al e 0a5h>             ;Always one more!       /*          */
  1909.             mov     dx, 092e8h          ;ERR_TERM reg address.
  1910.             call    InpwDelay           ;Read the value.
  1911.             push    ax                  ;Save original value.
  1912.             not     ax                  ;Change all the bits.   /*          */
  1913.             call    ATIOutpChk          ;See if they all change./*          */
  1914.             pop     ax                  ;                       /*          */
  1915.             call    OutpwDelay          ;Restore original value./*          */
  1916.         .endif                          ;Else success! 8514!
  1917. ;*
  1918. ;*  Test for ATI Accelerator:
  1919. ;*
  1920.         .if     < z >                   ;If some type of 8514:
  1921.             mov     dx, 052eeh          ;ROM_ADDR_1 reg address.
  1922.             call    InpwDelay           ;Read the value.
  1923.             push    ax                  ; 
  1924.             not     ax                  ;Change all the bits.   /*          */
  1925.             call    ATIOutpChk          ;See if they all change.
  1926.             pop     ax                  ; 
  1927.             call    OutpwDelay          ;Restore original value.
  1928.         .endif                          ;Else failure.
  1929.         ret                             ; 
  1930.  
  1931. ATI8514         ENDP                    ;                       /*          */
  1932.  
  1933. ;*                                                              /*          */
  1934. ;/****************************************************************************
  1935. ;*
  1936. ;* FUNCTION NAME = ATIMach64
  1937. ;*
  1938. ;* DESCRIPTION   = Test ATI chip for Mach64 Accelerator.
  1939. ;*
  1940. ;* INPUT         = NONE
  1941. ;* OUTPUT        = NONE
  1942. ;*
  1943. ;* RETURN-NORMAL = ZR (has Mach64 Accelerator)
  1944. ;* RETURN-ERROR  = NZ (timeout or other failure)
  1945. ;*
  1946. ;* CALLED BY
  1947. ;*
  1948. ;****************************************************************************/
  1949.  
  1950. ATIMach64       PROC    near            ;                       /*          */
  1951.                 PUBLIC  ATIMach64
  1952.  
  1953.         mov     dx, 01eeeh              ;CRTC_GEN_CTRL addr.
  1954.         call    InpwDelay               ;Read the current value.
  1955.         push    ax                      ;Save current value.
  1956.         and     ah, not 001h            ;Disable VGA passthru.
  1957.         call    OutpwDelay              ;Write the new value.
  1958.         mov     dx, 066eeh              ;GEN_TEST_CTRL reg.
  1959.         call    InpwDelay               ;Read the current value.
  1960.         push    ax                      ;Save gen_test_ctrl.
  1961.         and     al, not 070h            ;Turn off test mode.
  1962.         call    OutpwDelay              ;Write the new value.
  1963.         mov     dx, 066ech              ;GEN_TEST_CTRL reg.
  1964.         call    InpwDelay               ;Read the current value.
  1965.         push    ax                      ;Save gen_test_ctrl.
  1966.         and     ah, not 001h            ;Reset GUI engine.
  1967.         call    OutpwDelay              ;Write the new value.
  1968.         pop     ax                      ;Restore gen_test_ctrl.
  1969.         call    OutpwDelay              ;Restore original value.
  1970.         mov     dx, 01ceh               ;ATI Extended regs index/*          */
  1971.         mov     ah, 0a0h                ;ATI20 index value      /*          */
  1972.         mov     al, ah                  ;                       /*          */
  1973.         call    OutpIdxInpData          ;Get current DAC RS[3:2]/*          */
  1974.         push    ax                      ;Save ATI20 data        /*          */
  1975.         and     al, not 060h            ;Clear DAC RS[3:2]      /*          */
  1976.         xchg    ah, al                  ;Restore index,save data/*          */
  1977.         call    OutpwDelay              ;                       /*          */
  1978.         mov     dx, 05eefh              ;DAC_R_INDEX reg.
  1979.         mov     al, 0a4h                ; 
  1980.         call    OutpDelay               ;Write the new value.
  1981.         xor     cx, cx                  ; 
  1982.         .repeat                         ;Wait fixed amount of time.
  1983.         .loop                           ; 
  1984.         mov     dx, 05eech              ;DAC_W_INDEX reg
  1985.         call    InpDelay                ;Input from port.
  1986.         .if     <al e 0a5h>             ;Always one more!
  1987.             mov     dx, 042ech          ;SCRATCH_REG0 reg addr.
  1988.             call    InpwDelay           ;Read the value.
  1989.             push    ax                  ; 
  1990.             not     ax                  ;Change all the bits.
  1991.             call    OutpwChk            ;See if it changes.
  1992.             pop     ax                  ; 
  1993.             call    OutpwDelay          ;Restore original value.
  1994.         .endif                          ;Else failure.
  1995.         mov     dx, 01ceh               ;ATI Extended regs index/*          */
  1996.         pop     ax                      ;Restore ATI20 data     /*          */
  1997.         call    OutpwDelay              ;Restore original value./*          */
  1998.         pop     ax                      ;Restore gen_test_ctrl.
  1999.         mov     dx, 066eeh              ;GEN_TEST_CTRL reg.
  2000.         call    OutpwDelay              ;Restore original value.
  2001.         pop     ax                      ;Restore Crtc ctrl.
  2002.         mov     dx, 01eeeh              ;CRTC_GEN_CTRL addr.
  2003.         call    OutpwDelay              ;Restore original value.
  2004.         ret
  2005.  
  2006. ATIMach64       ENDP
  2007.  
  2008. ;/****************************************************************************
  2009. ;*
  2010. ;* FUNCTION NAME = IsATI
  2011. ;*
  2012. ;* DESCRIPTION   = Look for an ATI Wonder.
  2013. ;*
  2014. ;*                 Check for product signature string at C000:30
  2015. ;*                 which should read '761295520'
  2016. ;*
  2017. ;*                 Assume DS -> DGROUP on entry
  2018. ;*
  2019. ;* INPUT         = NONE
  2020. ;* OUTPUT        = NONE
  2021. ;*
  2022. ;* RETURN-NORMAL = NONE
  2023. ;* RETURN-ERROR  = NONE
  2024. ;*
  2025. ;* CALLED BY
  2026. ;*
  2027. ;****************************************************************************/
  2028.  
  2029. IsATI           PROC    Near
  2030.                 PUBLIC  IsATI
  2031.  
  2032.         push    di
  2033.         mov     bx, 00030h              ;Search target offset.
  2034.         mov     cx, 10                  ;Search string length.
  2035.         mov     di, OFFSET DGROUP :ATISig ;Search string value.
  2036. ;@V3.0JLO01  call    FindString              ;See if string is there in ROM.
  2037.         call    LookString              ;See if string is there in ROM.
  2038.         pop     di
  2039.         ret
  2040.  
  2041. IsATI           ENDP
  2042.  
  2043. ;/****************************************************************************
  2044. ;*
  2045. ;* FUNCTION NAME = IsCirrus
  2046. ;*
  2047. ;* DESCRIPTION   = Graphics Cursor X position register (3c5, index 10,30,50...F0)
  2048. ;*                 uses both index and data for position value. Bits 7-5 of
  2049. ;*                 the index are bits 0-2 of the cursor position.  Data value
  2050. ;*                 represents bits 3-10 of the cursor position.
  2051. ;*                 If 3c4 loaded with a value and then read without
  2052. ;*                 writing data to 3c5, it returns 3 bits of the
  2053. ;*                 previously set cursor position.
  2054. ;*
  2055. ;* INPUT         = NONE
  2056. ;* OUTPUT        = NONE
  2057. ;*
  2058. ;* RETURN-NORMAL = ZR if found.
  2059. ;* RETURN-ERROR  = NZ if not found.
  2060. ;*
  2061. ;* CALLED BY
  2062. ;*
  2063. ;****************************************************************************/
  2064. ;          
  2065.  
  2066. IsCirrus        PROC    Near
  2067.                 PUBLIC  IsCirrus
  2068.  
  2069.         enter   STACKBLOCK, 0           ;          
  2070.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  2071.         call    GetSave1                ;Read original index & save it.
  2072.         mov     ax, 01206h              ; sr6 register index and unlock.
  2073. ;       Current SEQ06 value now saved globally!                 /*          */
  2074. ;       But at least TRY to restore it as soon as possible!     /*          */
  2075.         mov     [SaveReg2], dx          ;                       /*          */
  2076.         mov     [SaveIndex2], al        ;                       /*          */
  2077. ;                                                               /*          */
  2078. ;       Cannot call OutpIdxChkXchgData here                     /*          */
  2079. ;       since GD5401 has no SEQ SR6!                            /*          */
  2080. ;                                                               /*          */
  2081.         call    OutpIdxXchgData         ;Try setting SEQ SR6.   /*          */
  2082.         mov     [SaveValue2], al        ;Save old value.        /*          */
  2083.         mov     al, 010h                ;SEQ SR10 index.
  2084.         call    OutpInp                 ;Write new & read modified values.
  2085. ;                                       ;Read value is first 3 bits, shifted by 5
  2086.         cmp     al, 010h                ;Test for read/writable /*          */
  2087.         jb      IsCirrusExit            ;Exit if not.           /*          */
  2088.         test    al, 00fh                ;Test for read/writable /*          */
  2089.         jnz     IsCirrusExit            ;Exit if not.           /*          */
  2090.         mov     [SaveIndex3], al        ;Read/writable index?   /*          */
  2091. ;       mov     ah, 000h                ;Any data at all!       /*          */
  2092.         call    OutpIdxChkXchgData      ;Test for read/writable /*          */
  2093.                                         ;Read value is bits 3-10 of the current position
  2094.         mov     [SaveValue3], al        ;                       /*          */
  2095.         .if     < z >                   ;If read/write:         /*          */
  2096.             mov     ax, 02850h          ;Set cursor to position 322. This value chosen in
  2097.             mov     bl, al              ;Save index.            /*          */
  2098. ;                                                               /*          */
  2099. ;           Cannot call OutpIdxChkXchgData here                 /*          */
  2100. ;           since index register has extra "data" bits.         /*          */
  2101. ;                                                               /*          */
  2102.             call    OutpIdxXchgData     ;No index check!        /*          */
  2103.             mov     bh, al              ;Save data.             /*          */
  2104.             mov     al, 070h            ; write the index only
  2105.             call    OutpInp             ;Write new & read modified values.
  2106. ;                                       ;Read value should be 50h
  2107.             cmp     al, bl              ; if 0 it is Cirrus, else not
  2108.             mov     ax, bx              ;Restore index & data   /*          */
  2109.             call    OutpwDelay          ;Restore the old value. /*          */
  2110.         .endif                          ;Else not read/write    /*          */
  2111.         mov     ax, word ptr [SaveIndex3]
  2112.         call    OutpwDelay              ;Restore the old value.
  2113. IsCirrusExit:
  2114.         call    RestoreSave2            ;Restore original values/*          */
  2115.         leave                           ;          
  2116.         ret
  2117.  
  2118. IsCirrus     ENDP
  2119.  
  2120. ;/*****************************************************************            ;          
  2121. ;*
  2122. ;* FUNCTION NAME = IsS3                                     
  2123. ;*
  2124. ;* DESCRIPTION   =
  2125. ;*
  2126. ;* INPUT         = NONE
  2127. ;* OUTPUT        = NONE
  2128. ;*
  2129. ;* RETURN-NORMAL = ZR if found.
  2130. ;* RETURN-ERROR  = NZ if not found.
  2131. ;*
  2132. ;* CALLED BY
  2133. ;*
  2134. ;****************************************************************************/
  2135.  
  2136. IsS3            PROC    Near            ;                       /*          */
  2137.                 PUBLIC  IsS3
  2138.  
  2139.         enter   STACKBLOCK, 0           ;                       /*          */
  2140. ;*                                                              /*          */
  2141. ;*      Weitek VGA used to pass the following test!
  2142. ;*      so it was clearly not specific enough!
  2143. ;*
  2144.         mov     ax, 04838h              ;Unlock extensions.
  2145.         call    GetCrtcBaseSave2        ;(3d4)                  /*          */
  2146. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  2147. ;*                                                              /*          */
  2148. ;*      Cannot check return since                               /*          */
  2149. ;*      not all the S3 bits are writable!                       /*          */
  2150. ;*                                                              /*          */
  2151. ;*      .if     <z> AND                 ;Exit if not R/W!       /*          */
  2152. ;*                                                              /*          */
  2153.             mov     al, 0cch            ;                       /*          */
  2154.             inc     dx                  ;Point to data register /*          */
  2155.             call    SaveXORChk          ;                       /*          */
  2156.         .if     <z> AND                 ;Exit if not R/W!
  2157.             dec     dx                  ;Point back to index reg/*          */
  2158. ;*                                                              /*          */
  2159. ;*          We must eliminate this possibility
  2160. ;*          to reject the Weitek VGA!
  2161. ;*
  2162.             call    IsNoCrtcWrap        ;(3d4)                  /*          */
  2163.         .if     <z> AND                 ;Exit if wraps!         /*          */
  2164. ;*
  2165.             mov     al, 030h            ;Chip-ID/Rev index      /*          */
  2166.             call    OutpDelay           ;                       /*          */
  2167.             inc     dx                  ;Point to data register /*          */
  2168.             mov     al, 0ffh            ;                       /*          */
  2169.             call    SaveXORConst        ;Must be read only!     /*          */
  2170.         .if     <z> AND                 ;Exit if R/W!           /*          */
  2171.             dec     dx                  ;Point back to index reg/*          */
  2172.             mov     al, 030h            ; 
  2173.             call    OutpIdxInpData      ;Read indexed reg       /*          */
  2174.             and     al, 0f0h            ;mask out lower nibble  /*          */
  2175.         .if     <al be 0d0h>            ;Vision964              /*@V3.0YEE01*/
  2176. ;           cmp     al, 0a0h            ;801/805 family
  2177. ;           je      S3Exit
  2178. ;           cmp     al, 080h            ;80 is 911/924          /*          */
  2179. ;           je      S3Exit
  2180. ;           cmp     al, 090h            ;928 family
  2181. ;           je      S3Exit
  2182. ;           cmp     al, 0b0h            ;928 PCI                /*          */
  2183.             cmp     al, al              ;Always success here!   /*          */
  2184.         .endif                                                  /*@V2.1MNH13*/
  2185. S3Exit:                                 ;                       /*          */
  2186.         call    RestoreSave2            ;Restore original values
  2187.         leave                           ;                       /*          */
  2188.         ret
  2189.  
  2190. IsS3            ENDP
  2191.  
  2192. ;/****************************************************************************
  2193. ;*
  2194. ;* FUNCTION NAME = IsSpeedWay
  2195. ;*
  2196. ;* DESCRIPTION   = Look for IBM 'SVGA'
  2197. ;*
  2198. ;* INPUT         = NONE
  2199. ;* OUTPUT        = NONE
  2200. ;*
  2201. ;* RETURN-NORMAL = NONE
  2202. ;* RETURN-ERROR  = NONE
  2203. ;*
  2204. ;* CALLED BY
  2205. ;*
  2206. ;****************************************************************************/
  2207.  
  2208. IsSpeedWay      PROC    Near
  2209.                 PUBLIC  IsSpeedWay
  2210.  
  2211.         mov     dx, 02170h              ;Start from 8th instance OpMode Reg.
  2212.         .repeat
  2213.             call    InpDelay            ;Read the OpMode setting.
  2214.             test    al, 0eah            ;Any of these bits on?
  2215.             .if     < z > AND           ;Valid value?
  2216.                 mov     al, 0ffh        ;Test all of the bits.
  2217.                 call    IsNotISAAliased
  2218.             .if     < z > AND           ;If not aliased
  2219. ;
  2220. ;               This should be INSIDE the loop & not AFTER!     /*          */
  2221. ;               If both XGA and Speedway
  2222. ;               (a real but maybe dumb possibility),
  2223. ;               then keep looking until we find the speedway address!
  2224. ;
  2225.                 mov     al, 0eah
  2226.                 call    SaveXORConst
  2227.             .if     < z > AND           ;If no changes:
  2228.                 mov     al, 00fh
  2229.                 or      dl, 008h        ;VRAM Index
  2230.                 call    SaveXORChk
  2231.             .if     < z > AND           ;If reads match writes:
  2232.                 mov     al, 0f4h
  2233.                 or      dl, 009h        ;Setup Memory Access    /*          */
  2234.                 call    SaveXORConst
  2235.             .if     < z >               ;Exit with success!
  2236.                 and dx, not 0000fh
  2237.                 mov [_XGAInstance], dx  ;Remember XGA instance  /*          */
  2238.                 cmp     al, al          ;Return success
  2239.                 jmp short @F
  2240.             .endif
  2241. SWayNextPort:
  2242.             sub     dx, 00010h          ;Next configuration
  2243.         .until  <dx b 02100h>           ;Still more ports to check
  2244. @@:
  2245.         ret
  2246.  
  2247. IsSpeedWay      ENDP
  2248.  
  2249. ;/****************************************************************************
  2250. ;*
  2251. ;* FUNCTION NAME = _GetXGAInstance
  2252. ;*
  2253. ;* DESCRIPTION   = Get XGAInstance value
  2254. ;*
  2255. ;* INPUT         = NONE
  2256. ;* OUTPUT        = NONE
  2257. ;*
  2258. ;* RETURN-NORMAL = NONE
  2259. ;* RETURN-ERROR  = NONE
  2260. ;*
  2261. ;* CALLED BY
  2262. ;*
  2263. ;****************************************************************************/
  2264.  
  2265. _GetXGAInstance PROC    Far             ;                       /*          */
  2266.                 PUBLIC  _GetXGAInstance ;                       /*          */
  2267.  
  2268.         call    IsSpeedWay
  2269.         ret
  2270.  
  2271. _GetXGAInstance ENDP                    ;                       /*          */
  2272.  
  2273. ;/****************************************************************************
  2274. ;*
  2275. ;* FUNCTION NAME = IsTrident
  2276. ;*
  2277. ;* DESCRIPTION   = Look for Trident chip set
  2278. ;*                 check for presence of inverting bit field in
  2279. ;*                 Mode Control register 1
  2280. ;*
  2281. ;* INPUT         = NONE
  2282. ;* OUTPUT        = NONE
  2283. ;*
  2284. ;* RETURN-NORMAL = NONE
  2285. ;* RETURN-ERROR  = NONE
  2286. ;*
  2287. ;* CALLED BY
  2288. ;*
  2289. ;****************************************************************************/
  2290.  
  2291. IsTrident       PROC    Near
  2292.                 PUBLIC  IsTrident
  2293.  
  2294.         enter   STACKBLOCK, 0           ;          
  2295.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  2296.         call    GetSave1                ;Read value & save it.  /*          */
  2297.         call    OutpChk
  2298.         mov     ax, 0000eh              ;Write all zeroes       /*          */
  2299. ;                                                               /*          */
  2300. ;       Need to check for index wrap so we do not clobber       /*          */
  2301. ;       TSeng Tsequencer 0x0e&0x07==0x06! (Tsix!)               /*          */
  2302. ;       Which we may not be able to restore TsucceTsTsfully!    /*          */
  2303. ;                                                               /*          */
  2304.         call    OutpChk                 ;Check index for wrap   /*          */
  2305.         .if     <z>                     ;If R/W: Else Tskip!    /*          */
  2306. ;                                                               /*          */
  2307. ;           Cannot call OutpIdxChkXchgData here                 /*          */
  2308. ;           since read value changes!                           /*          */
  2309. ;                                                               /*          */
  2310.             call    OutpIdxXchgData     ;Read indexed reg       /*          */
  2311.             mov     ah, al              ;Save old value         /*          */
  2312.             call    InpData             ;Read value 2nd time!
  2313.             and     al, 00fh            ; 
  2314.             xchg    al, ah              ;get old value back
  2315.             xor     al, 002h            ;flip bit
  2316.             call    OutpData            ;Write the new value, restore.
  2317.             cmp     ah, 002h            ;ZR => Trident, NZ => not
  2318.         .endif                          ;                       /*          */
  2319.         call    RestoreSave1            ;Restore the original index.
  2320.         leave                           ;          
  2321.         ret
  2322.  
  2323. IsTrident       ENDP
  2324.  
  2325. ;*                                                              /*          */
  2326. ;/****************************************************************************
  2327. ;*
  2328. ;* FUNCTION NAME = TsengSetATCMisc
  2329. ;*
  2330. ;* DESCRIPTION   = Point to Tseng ATC Misc and set the value.
  2331. ;*
  2332. ;* INPUT         = CX = 3x0 CrtcBase
  2333. ;*               = AL = New Tseng ATC Misc Reg value
  2334. ;* OUTPUT        = DX = 3c0 = ATC Index address
  2335. ;* CLOBBERS      = AX
  2336. ;*
  2337. ;* RETURN-NORMAL = ZR (reads match writes).
  2338. ;* RETURN-ERROR  = NZ (reads do not match writes).
  2339. ;*
  2340. ;* CALLED BY
  2341. ;*      IsTseng
  2342. ;*
  2343. ;****************************************************************************/
  2344.  
  2345. TsengSetATCMisc PROC    Near
  2346.                 PUBLIC  TsengSetATCMisc
  2347.  
  2348.         mov     ah, al                  ;Save new ATC Misc value.
  2349.         mov     al, 016h                ;Tseng ATC Misc index.
  2350.         call    ATCOutpIdx              ;Set index & test for read/writeable.
  2351.         .if     < z >                   ;If NO errors setting index:
  2352.             mov     al, ah              ;Restore new ATC Misc value.
  2353.             call    OutpIdxInpData      ;Write new ATC Misc value & reread it.
  2354.             cmp     al, ah
  2355.         .endif
  2356.         ret
  2357.  
  2358. TsengSetATCMisc    ENDP
  2359.  
  2360.  
  2361. ;*                                                              /*          */
  2362. ;/****************************************************************************
  2363. ;*
  2364. ;* FUNCTION NAME = TsengEnableExt
  2365. ;*
  2366. ;* DESCRIPTION   =
  2367. ;*
  2368. ;* INPUT         = BP = Stack Frame Pointer
  2369. ;* OUTPUT        = DX = 03c4 = SEQ index address
  2370. ;*
  2371. ;* RETURN-NORMAL = NONE
  2372. ;* RETURN-ERROR  = NONE
  2373. ;*
  2374. ;* CALLED BY
  2375. ;*
  2376. ;****************************************************************************/
  2377.  
  2378. TsengEnableExt  PROC    Near
  2379.                 PUBLIC  TsengEnableExt
  2380.  
  2381.         call    GetPortBase             ;Depends on mono/color  /*          */
  2382.         add     dl, 008h                ;Mode Ctrl (3b8/3d8)    /*          */
  2383.         call    GetSave2                ;           
  2384. ;;JWK07        mov     ax, 02901h              ;Unlock values.
  2385.                mov     ax, 0a003h       ;JWK07 ;Correct Unlock values.
  2386. ;       Now fall thru to (call and return):
  2387.  
  2388. ;*                                                              /*          */
  2389. ;/****************************************************************************
  2390. ;*
  2391. ;* FUNCTION NAME = TsengLock
  2392. ;*
  2393. ;* DESCRIPTION   = Lock or Unlock Tseng extended registers.
  2394. ;*
  2395. ;* INPUT         = AX = Lock 0a003h or Unlock 02901h
  2396. ;*                 DX = Mode Ctrl (3b8/3d8)
  2397. ;*
  2398. ;* OUTPUT        = NONE
  2399. ;*
  2400. ;* RETURN-NORMAL = NONE
  2401. ;* RETURN-ERROR  = NONE
  2402. ;*
  2403. ;* CALLED BY
  2404. ;*
  2405. ;****************************************************************************/
  2406.  
  2407. TsengLock       PROC    Near
  2408.                 PUBLIC  TsengLock
  2409.  
  2410.         push    dx
  2411.         mov     dl, 0bfh                ;Lock/Unlock extended regs
  2412.         call    OutpDelay               ;Write the new value.
  2413.         pop     dx
  2414.         mov     al, ah                  ; 
  2415.         call    OutpDelay               ;Write the new value.
  2416.         ret
  2417.  
  2418. TsengLock       ENDP
  2419.  
  2420. TsengEnableExt  ENDP
  2421.  
  2422. ;*                                                              /*          */
  2423. ;/****************************************************************************
  2424. ;*
  2425. ;* FUNCTION NAME = TsengDisableExt
  2426. ;*
  2427. ;* DESCRIPTION   =
  2428. ;*
  2429. ;* INPUT         = BP = Stack Frame Pointer
  2430. ;* OUTPUT        = DX = 03c4 = SEQ index address
  2431. ;*
  2432. ;* RETURN-NORMAL = NONE
  2433. ;* RETURN-ERROR  = NONE
  2434. ;*
  2435. ;* CALLED BY
  2436. ;*
  2437. ;****************************************************************************/
  2438.  
  2439. TsengDisableExt PROC    Near
  2440.                 PUBLIC  TsengDisableExt
  2441.  
  2442.         mov     dx, [SaveReg2]          ;Mode Ctrl (3b8/3d8)    /*          */
  2443.         push    ax
  2444.         mov     al, [SaveValue2]        ; 
  2445.         mov     ah, al                  ; 
  2446.         and     al, 040h                ; 
  2447.         rol     al, 3                   ; 
  2448.         or      al, 001h                ; 
  2449.         call    TsengLock               ;Restore lock state     /*          */
  2450.         pop     ax
  2451.         ret
  2452.  
  2453. TsengDisableExt ENDP
  2454.  
  2455. ;*                                                                /*          */
  2456. ;/****************************************************************************
  2457. ;*
  2458. ;* FUNCTION NAME = IsTseng
  2459. ;*
  2460. ;* DESCRIPTION   = Look for Tseng chip
  2461. ;*
  2462. ;*                 Use:
  2463. ;*
  2464. ;*                 read old reg value
  2465. ;*                 write a new value
  2466. ;*                 read the new value
  2467. ;*                 write old value back
  2468. ;*                 if new value written equals value read, chip is Tseng
  2469. ;*
  2470. ;* INPUT         = NONE
  2471. ;* OUTPUT        = NONE
  2472. ;*
  2473. ;* RETURN-NORMAL = NONE
  2474. ;* RETURN-ERROR  = NONE
  2475. ;*
  2476. ;* USES:   AX, BX, DX
  2477. ;*
  2478. ;* CALLED BY
  2479. ;*
  2480. ;****************************************************************************/
  2481.  
  2482. IsTseng         PROC    Near
  2483.                 PUBLIC  IsTseng
  2484.  
  2485.         enter   STACKBLOCK, 0           ;                       /*          */
  2486.         mov     dx, 003cdh              ;Tseng Tsegment Tselect /*          */
  2487.         mov     al, 0ffh                ;Test all bits for R/W  /*          */
  2488.         call    SaveXORChk              ;                       /*          */
  2489.         .if     <z>                     ;If R/W                 /*          */
  2490.             call    GetCrtcBaseSave1    ;(3d4)                  /*          */
  2491. ;*          OUTPUT   = DX = 003x4 (CRTC index address)
  2492. ;*                                                              /*          */
  2493. ;*          We must eliminate this possibility to reject the Weitek VGA!
  2494. ;*
  2495.             call    IsNoCrtcWrap        ;(3d4)                  /*          */
  2496. ;*          OUTPUT   = DX = 003x4 (CRTC index address)
  2497.             .if     < z >               ;If no wrap:            /*          */
  2498.                 mov     al, 033h        ;Point to extended start/*          */
  2499.                 call    OutpChk         ;Extra sanity check for L40
  2500.                                         ; which ignores index set,
  2501.             .if     < z >               ; so check it worked:   /*          */
  2502.                 inc     dl              ; 
  2503.                 mov     al, 00fh        ;                       /*          */
  2504.                 call    SaveXORChk      ;Test for read/writable./*          */
  2505.             .if     < z >               ;If read/write:         /*          */
  2506. ;*                                                              /*          */
  2507. ;*              We must eliminate this possibility to reject the WD90C24!
  2508. ;*
  2509.                 mov     dl, 0cdh        ;GDC Segment Select 1   /*          */
  2510.                 mov     al, 0ffh        ;Test all bits          /*          */
  2511.                 call    SaveXORChk      ;Test for read/writable./*          */
  2512.             .endif
  2513.             .endif
  2514.             .endif
  2515.             .if     < nz >              ;If NOT ET4000+:        /*          */
  2516. IsTsengExit:                            ;could be ET3000
  2517. ;!!             Trident TR8900 passes ET3000 test!              /*          */
  2518. ;!!             Can we TStrENGthen it somehow?
  2519.                 mov     al, 016h        ;Tseng ATC Misc index.
  2520.                 call    ATCOutpIdx      ;Set index & test for read/writeable.
  2521.                 inc     dx
  2522.                 call    InpDelay        ;Read the value.
  2523.                 mov     bl, al          ;Save original value in bl
  2524.                 xor     al, 10h         ;Toggle bit             /*          */
  2525.                 call    TsengSetATCMisc ;Write new ATC Misc val /*          */
  2526.                 .if     < z >           ;If read/writeable:     /*          */
  2527.                     mov     al, bl      ;Get original value
  2528.                     call    TsengSetATCMisc ;Restore ATC Misc   /*          */
  2529.                 .endif
  2530.             .endif
  2531. MustBeTseng:
  2532.             pushf                       ;Save flags
  2533.             mov     al, 20h             ;Turn palette back on
  2534.             call    ATCOutpIdx          ;Set ATC index reg      /*          */
  2535.             popf                        ;restore flags
  2536.             call    RestoreSave1        ;Restore the original index.
  2537.         .endif                          ;                       /*          */
  2538.         leave                           ;                       /*          */
  2539.         ret                             ; 
  2540.  
  2541. IsTseng         ENDP
  2542.  
  2543. ;/****************************************************************************
  2544. ;*
  2545. ;* FUNCTION NAME = Video7EnableExt
  2546. ;*
  2547. ;* DESCRIPTION   =
  2548. ;*
  2549. ;* INPUT         = BP = Stack Frame Pointer
  2550. ;* OUTPUT        = DX = 03c4 = SEQ index address
  2551. ;*
  2552. ;* RETURN-NORMAL = ZR (reads do not match writes).
  2553. ;* RETURN-ERROR  = NZ (reads match writes).
  2554. ;*
  2555. ;* CALLED BY
  2556. ;*
  2557. ;****************************************************************************/
  2558.  
  2559. Video7EnableExt PROC    Near
  2560.                 PUBLIC  Video7EnableExt
  2561.  
  2562.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  2563.         call    GetSave2                ;           
  2564.         mov     ax, 0ea06h              ;write 0eah to reg 6    /*          */
  2565. ;       Don't check index, since we want failure for output chk!/*          */
  2566.         call    OutpIdxChkXchgData      ;Read indexed reg       /*          */
  2567. ;       Current SEQ06 value now saved globally!                 /*          */
  2568. ;       But at least TRY to restore it as soon as possible!     /*          */
  2569. ;       mov     [SaveValue2], al        ;In case NOT Video7!    /*          */
  2570.         lahf                            ;Did reads match writes?/*          */
  2571.         test    ah,040h                 ;NZ=>Z, Z=>NZ           /*          */
  2572.         ret
  2573.  
  2574. Video7EnableExt ENDP
  2575.  
  2576. ;/****************************************************************************
  2577. ;*
  2578. ;* FUNCTION NAME = Video7DisableExt
  2579. ;*
  2580. ;* DESCRIPTION   =
  2581. ;*
  2582. ;* INPUT         = BP = Stack Frame Pointer
  2583. ;*                 FL = ZR = Video7, NZ = not Video7
  2584. ;* OUTPUT        = DX = 03c4 = SEQ index address
  2585. ;*
  2586. ;* RETURN-NORMAL = NONE
  2587. ;* RETURN-ERROR  = NONE
  2588. ;*
  2589. ;* CALLED BY
  2590. ;*
  2591. ;****************************************************************************/
  2592.  
  2593. Video7DisableExt PROC   Near
  2594.                 PUBLIC  Video7DisableExt
  2595.  
  2596.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  2597. ;We do not want to lock it now, we want to restore the lock state!
  2598. ;       mov     ax, 0ae06h              ;write 0aeh to reg 6    /*          */
  2599. ;       call    OutpwDelay              ;Write the new value.   /*          */
  2600. ;       mov     dx, [SaveReg2]          ;                       /*          */
  2601. ;       Current SEQ06 value now saved globally!                 /*          */
  2602. ;       But at least TRY to restore it as soon as possible!     /*          */
  2603.         mov     al, 006h                ;                       /*          */
  2604.         mov     ah, [SEQ06]             ;Use global lock restore/*          */
  2605.         call    OutpwDelay              ;Restore original lock  /*          */
  2606.         mov     al, [SaveIndex2]        ;           
  2607.         call    OutpDelay               ;Restore the index.
  2608.         ret
  2609.  
  2610. Video7DisableExt ENDP
  2611.  
  2612. ;/****************************************************************************
  2613. ;*
  2614. ;* FUNCTION NAME = IsVideo7
  2615. ;*
  2616. ;* DESCRIPTION   = Look for Headland chip (Video7)
  2617. ;*
  2618. ;*                 read value of Start Address High (SAH) register
  2619. ;*                 read Identification register (ID field)
  2620. ;*                 if (SAH ^ 0EAH == ID reg) its a Video7 chip
  2621. ;*
  2622. ;* INPUT         = NONE
  2623. ;* OUTPUT        = NONE
  2624. ;*
  2625. ;* RETURN-NORMAL = NONE
  2626. ;* RETURN-ERROR  = NONE
  2627. ;*
  2628. ;* CALLED BY
  2629. ;*
  2630. ;****************************************************************************/
  2631.  
  2632. IsVideo7        PROC    Near
  2633.                 PUBLIC  IsVideo7
  2634.  
  2635.         enter   STACKBLOCK, 0           ;          
  2636.         call    Video7EnableExt         ;enable extended registers
  2637.         jnz     IsVideo7Exit            ;Exit if read/write     /*          */
  2638.         call    GetCrtcBaseSave1        ;(3d4)                  /*          */
  2639. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  2640. ;       mov     bx, dx                  ;save copy              /*          */
  2641.         xor     bh, bh                  ;Default value          /*          */
  2642.         mov     ax, 0550ch              ;select Start Address High reg
  2643.         call    OutpIdxChkXchgData      ;Read indexed reg       /*          */
  2644.         mov     bl, al                  ;Save previous value
  2645.         .if     < z >                   ;If read/write:         /*          */
  2646. ;           call    InpDelay            ;Read the value back.   /*          */
  2647.             mov     al, 01fh            ;select ID register
  2648.             call    OutpIdxInpData      ;Read indexed reg       /*          */
  2649.  
  2650.             mov     bh, al              ;                       /*          */
  2651.         .endif                          ;Else not read/write    /*          */
  2652.         mov     al, 00ch                ;select SAH register
  2653.         mov     ah, bl                  ;Get back old value     /*          */
  2654.         call    OutpwDelay              ;Write old value back
  2655.         cmp     bh, 055h xor 0eah       ;ZR => Video7, NZ => not/*          */
  2656.         call    RestoreSave1            ;Restore the original index.
  2657. IsVideo7Exit:                           ;                       /*          */
  2658.         call    Video7DisableExt        ;disable extended regs
  2659.         leave                           ;          
  2660.         ret
  2661.  
  2662. IsVideo7        ENDP
  2663.  
  2664. ;*                                                              /*          */
  2665. ;/****************************************************************************
  2666. ;*
  2667. ;* FUNCTION NAME = WDDisableExt
  2668. ;*
  2669. ;* DESCRIPTION   = Relock WD private registers.
  2670. ;*                 Maintain Z/NZ
  2671. ;*
  2672. ;* INPUT         = BP = Stack frame pointer.
  2673. ;*                 DX = 3x4 port base address.
  2674. ;*
  2675. ;* RETURN-NORMAL = NONE
  2676. ;* RETURN-ERROR  = NONE
  2677. ;*
  2678. ;* CALLED BY
  2679. ;*      IsWesternDig
  2680. ;*      WhichWesternDig
  2681. ;*
  2682. ;****************************************************************************/
  2683.  
  2684. WDDisableExt    PROC    near
  2685.                 PUBLIC  WDDisableExt
  2686.  
  2687.         pushf                           ;Save results flags.    /*          */
  2688.         call    GetCrtcBase             ;(3d4)                  /*          */
  2689. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  2690.         call    IsNoCrtcWrap            ;(3d4)                  /*          */
  2691. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  2692.         .if     < z >                   ;If no wrap:            /*          */
  2693.             mov     al, 035h            ;PR30/Mapping RAM Unlock/*          */
  2694.             mov     ah, [SaveValue3]    ;                       /*          */
  2695.             call    OutpwDelay          ;Restore lock/unlock    /*          */
  2696.             mov     al, 034h            ;PR1B/Flat Panel Unlock /*          */
  2697.             mov     ah, [SaveIndex3]    ;                       /*          */
  2698.             call    OutpwDelay          ;Restore lock/unlock    /*          */
  2699.         .endif                                                  /*@V2.1MNH01*/
  2700.         popf                            ;Restore results flags  /*          */
  2701.         call    RestoreSave2
  2702.         mov     al, 000h                ;Lock extensions        /*          */
  2703. ;       Now fall thru to (call and return):
  2704.  
  2705. ;*                                                              /*          */
  2706. ;/****************************************************************************
  2707. ;*
  2708. ;* FUNCTION NAME = WDLock
  2709. ;*
  2710. ;* DESCRIPTION   = Lock/Unlock WD private registers.
  2711. ;*
  2712. ;* INPUT         = AL = Lock (000h)/Unlock(080h) bit.
  2713. ;* OUTPUT        = NONE
  2714. ;*
  2715. ;* RETURN-NORMAL = NONE
  2716. ;* RETURN-ERROR  = NONE
  2717. ;*
  2718. ;* CALLED BY
  2719. ;*
  2720. ;****************************************************************************/
  2721.  
  2722. WDLock          PROC    Near
  2723.                 PUBLIC  WDLock
  2724. ;
  2725. ;       Which adapter needs this lock/unlock?                   /*          */
  2726. ;       And does this code really work?                         /*          */
  2727. ;       Shouldn't this be 001h->0102h instead of 080h->0103h?   /*          */
  2728. ;
  2729. ;       This routine must be removed since the WD90C24A2B       /*          */
  2730. ;       & WD90C24A2C have a     which causes all output to      /*          */
  2731. ;       003c3 to put the chip to sleep.                         /*          */
  2732. ;
  2733. ;       Since historically this routine has output to the       /*          */
  2734. ;       address and the       bit, it is effectively a nop      /*          */
  2735. ;       anyway.  So it should not be missed.                    /*          */
  2736. ;
  2737. ;       mov     ah, al                  ;Save lock/unlock bit
  2738. ;       mov     dx, 003c3h              ;Same as 046e8h!
  2739. ;       push    dx                      ;
  2740. ;       call    InpDelay                ;
  2741. ;       push    ax                      ;Save Subsys Enable
  2742. ;       or      al, 010h                ;Add Setup bit
  2743. ;       call    OutpDelay               ;Write new value, enter setup mode.
  2744. ;       mov     dx, 00103h              ;!!What is this addr?!  (102?)
  2745. ;       call    InpDelay                ;
  2746. ;       pushf                           ;Save results flags.
  2747. ;       or      al, ah                  ;Add in lock/unlock bit
  2748. ;       popf                            ;Restore results flags
  2749. ;       call    OutpDelay               ;Write new value, unlock extensions.
  2750. ;       pop     ax                      ;Restore Subsys Enable
  2751. ;       pop     dx                      ;(003c3h)
  2752. ;       call    OutpDelay               ;Write new value, exit setup mode.
  2753.         ret
  2754.  
  2755. WDLock          ENDP
  2756.  
  2757. WDDisableExt    ENDP
  2758.  
  2759. ;*                                                              /*          */
  2760. ;/****************************************************************************
  2761. ;*
  2762. ;* FUNCTION NAME = WDEnableExt
  2763. ;*
  2764. ;* DESCRIPTION   = Unlock WD private registers.
  2765. ;*
  2766. ;* INPUT         = BP = Stack frame pointer.
  2767. ;* OUTPUT        = DX = 003x4 (CRTC index address)
  2768. ;*
  2769. ;* RETURN-NORMAL = NONE
  2770. ;* RETURN-ERROR  = NONE
  2771. ;*
  2772. ;* CALLED BY
  2773. ;*
  2774. ;****************************************************************************/
  2775.  
  2776. WDEnableExt     PROC    near
  2777.                 PUBLIC  WDEnableExt
  2778.  
  2779. ;!!     mov     al, 080h                ;Unlock extensions      /*          */
  2780. ;!!     call    WDLock                  ;Is this the right bit? /*          */
  2781.         mov     ax, 08529h              ;Set PR10, RW enable PR11-PR1A  /*          */
  2782.         call    GetCrtcBaseSave2        ;(3d4)                  /*          */
  2783. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  2784. ;*                                      ;Write the new value, RW enable PR11-PR1A.
  2785. ;                                                               /*          */
  2786. ;       Cannot check the following because PVGA1A only has      /*          */
  2787. ;       PR0-PR5, and the 029h index is not read/writable!       /*          */
  2788. ;                                                               /*          */
  2789. ;       jnz     WDEnableExtExit         ;Exit if not read/write./*          */
  2790. ;                                                               /*          */
  2791. ;*                                                              /*          */
  2792. ;*      We must eliminate this possibility to reject the Weitek VGA!
  2793. ;*
  2794.         call    IsNoCrtcWrap            ;(3d4)                  /*          */
  2795.         jnz     WDEnableExtExit         ;Exit if wraps!         /*          */
  2796.         mov     ax, 05934h              ;Set PR1B/Flat Panel Unlock
  2797.         call    OutpIdxChkXchgData      ;Write new value, lock for read ID!
  2798.         mov     [SaveIndex3],al         ;Save for non-WDs!      /*          */
  2799.         mov     ax, 04335h              ;Set PR30/Mapping RAM Unlock
  2800.         call    OutpIdxChkXchgData      ;Write new value, lock for read ID!
  2801.         mov     [SaveValue3],al         ;Save for non-WDs!      /*          */
  2802.         cmp     al, al                  ;WD's MAY not read!     /*          */
  2803. WDEnableExtExit:
  2804.         ret
  2805.  
  2806. WDEnableExt     ENDP
  2807.  
  2808. ;*                                                              /*          */
  2809. ;/****************************************************************************
  2810. ;*
  2811. ;* FUNCTION NAME = WDRegPairString
  2812. ;*
  2813. ;* DESCRIPTION   = Test for WD string presence at CRTC reg pair.
  2814. ;*
  2815. ;* INPUT         = AL = index of first CRTC reg in pair.
  2816. ;*               = DX = 003x4 (CRTC index address)
  2817. ;* OUTPUT        = AL = First reg
  2818. ;*                 AH = Second reg
  2819. ;*
  2820. ;* RETURN-NORMAL = (zr if WD string found)
  2821. ;* RETURN-ERROR  = (nz if WD string NOT found)
  2822. ;*
  2823. ;* CALLED BY
  2824. ;*
  2825. ;****************************************************************************/
  2826.  
  2827. WDRegPairString PROC    Near
  2828.                 PUBLIC  WDRegPairString
  2829.  
  2830.         mov     ah, al                  ;Save register index.
  2831.         call    OutpIdxInpData          ;Read high byte of chip 90cxx
  2832.         xchg    ah, al                  ;Save high byte, restore index.
  2833.         inc     al                      ;Get next index.
  2834.         call    OutpIdxInpData          ;Read low byte of chip 90cxx
  2835.         cmp     ax, 05744h              ;"WD"
  2836.         ret
  2837.  
  2838. WDRegPairString ENDP
  2839.  
  2840. ;/****************************************************************************
  2841. ;*
  2842. ;* FUNCTION NAME = IsWesternDig
  2843. ;*
  2844. ;* DESCRIPTION   =
  2845. ;*      At index 30 thru 3f, the WD90cxx chips have an encoded device id.
  2846. ;*      Certain unlocks must be done to allow it to be read.
  2847. ;*      This is NOT documented in ALL of their data books.
  2848. ;*      It IS documented in the data book for the WD90C26.
  2849. ;*      It IS hinted at ("reserved") in other data books.
  2850. ;*
  2851. ;*                  3333333333333333
  2852. ;*                  0123456789ABCDEF
  2853. ;*      PVGA1A    ->################ #=0ffh or 000h
  2854. ;*      WD90c00   ->COPYRIGHT1989WDC
  2855. ;*      WD90c24   ->#WD90C24REVC0892 #=varies        Toshiba T4700CT
  2856. ;*      WD90c24a2a->#WD90C24AREVA293 #=varies z=000h WD90C24 Demo Board
  2857. ;*      WD90c24a2b->#WD90C24AREVB293 #=varies z=000h IBM ThinkPad
  2858. ;*      WD90c24a2c->#WD90C24AREVC### #=varies        WD program checks this!
  2859. ;*      WD90c26   ->#WD90C26REV#199# #=varies        WD ref documents this!
  2860. ;*      WD90c31   ->#WD90C310200zzzz #=varies z=000h WD program checks this!
  2861. ;*      WD90c31A  ->#WD90C31050zzzzz #=varies z=000h WD program checks this!
  2862. ;*      WD90c33   ->#WD90C33######## #=varies z=000h WD program checks this!
  2863. ;*      WD90c34   ->#WD90C34######## #=varies z=000h WD program checks this!
  2864. ;*      WD90cxx   ->#WD90Cxx######## #=varies x=chip
  2865. ;*
  2866. ;*      So for PVGA1A, Look for string 'VGA=' at BIOS location C000:007D
  2867. ;*      Physical address = C007D or E007D
  2868. ;*      For the other adapters, look for a 'WD' at either possible port pair.
  2869. ;*
  2870. ;* INPUT         = NONE
  2871. ;* OUTPUT        = NONE
  2872. ;*
  2873. ;* RETURN-NORMAL = ZR if found.
  2874. ;* RETURN-ERROR  = NZ if not found.
  2875. ;*
  2876. ;* CALLED BY
  2877. ;*
  2878. ;****************************************************************************/
  2879.  
  2880. IsWesternDig    PROC    Near
  2881.                 PUBLIC  IsWesternDig
  2882.  
  2883.         enter   STACKBLOCK, 0           ;          
  2884.         call    WDEnableExt             ;Unlock needed registers.
  2885. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  2886.         jnz     ExitWD                  ;Exit if wraps!         /*          */
  2887.         mov     al, 03dh                ;                       /*          */
  2888.         call    WDRegPairString         ;Test reg pair for "WD" /*          */
  2889.         jz      ExitWD                  ;Yes, it's a WD!        /*          */
  2890.         mov     al, 031h                ;                       /*          */
  2891.         call    WDRegPairString         ;Test reg pair for "WD" /*          */
  2892.         jz      ExitWD                  ;Yes, it's a WD!        /*          */
  2893. ;*
  2894. ;*      Now test for PVGA1A:            ;                       /*          */
  2895. ;*              WD test program suggests the following for all WD chips:
  2896. ;*                      and 3cf.e, 0fd
  2897. ;*                      and 3cf.c, not 040 to reset out of NON-VGA mode
  2898. ;*                      lock 3cf.f=000
  2899. ;*                      test 3cf.9 NOT writable==>next test
  2900. ;*                      unlock 3cf.f=005
  2901. ;*                      test 3cf.9 writable==>WD chip!
  2902. ;*                      restore all regs
  2903. ;*
  2904.         push    di
  2905.         mov     bx, 0007dh              ;Search target offset.
  2906.         mov     cx, 4                   ;Search string length.
  2907.         mov     di, OFFSET DGROUP :WDSig ;Search string value.
  2908.         call    FindString              ;See if string is there in ROM.
  2909.         pop     di
  2910. ExitWD:
  2911.         call    WDDisableExt
  2912.         leave                           ;          
  2913.         ret
  2914.  
  2915. IsWesternDig    ENDP
  2916.  
  2917. ;*                                                              /*          */
  2918. ;/****************************************************************************
  2919. ;*
  2920. ;* FUNCTION NAME = IsChips
  2921. ;*
  2922. ;* DESCRIPTION   = Read value of XR00 register. If value is NOT 00 or FF,
  2923. ;*                 then C&T SVGA exists.
  2924. ;*                 Some non-C&T adapters may carry over the last value set
  2925. ;*                 from a previous instruction when querying 3c6, so use
  2926. ;*                 the cursor reg for test.   s3 964 did this.
  2927. ;*
  2928. ;* INPUT         = NONE
  2929. ;* OUTPUT        = NONE
  2930. ;*
  2931. ;* RETURN-NORMAL = ZR if found.
  2932. ;* RETURN-ERROR  = NZ if not found.
  2933. ;*
  2934. ;* CALLED BY
  2935. ;*
  2936. ;****************************************************************************/
  2937.  
  2938. IsChips         PROC    Near
  2939.                 PUBLIC  IsChips
  2940.  
  2941.         enter   STACKBLOCK, 0
  2942.  
  2943.         mov     ax, 0000fh              ;Write 00 to cursor reg               
  2944.         call    GetCrtcBaseSave2        ;(3d4)                                
  2945.  
  2946.         mov     dx, 03d6h               ;XR extension index register (3d6)
  2947.         call    GetSave1                ;Read original index & save it.
  2948.  
  2949.         mov     al, 00h                 ;XR00
  2950.         call    OutpIdxInpData          ;Read indexed reg
  2951.  
  2952.         cmp     al,00h                  ;          
  2953.         je      NotChips                ;          
  2954.         cmp     al,0FFh
  2955.         je      NotChips                ;          
  2956.         cmp     al,al                   ;found one!!!
  2957.         jz      @F
  2958. NotChips:
  2959.         cmp     al,01h                  ;set nz flag              
  2960. @@:
  2961.         call    RestoreSave1            ;Restore the original values.
  2962.         call    RestoreSave2            ;Restore the original values.           
  2963.         leave
  2964.         ret
  2965.  
  2966. IsChips         ENDP
  2967.  
  2968. ;*                                                              /*          */
  2969. ;/****************************************************************************
  2970. ;*
  2971. ;* FUNCTION NAME = IsWeitek
  2972. ;*
  2973. ;* DESCRIPTION   =
  2974. ;*                      Setting the index at 3c4, or setting the 3c5.11 20 bit
  2975. ;*                      (a second time) locks (reads as zero)
  2976. ;*                      3c5.11 when the 3c5.11 20 bit is already set.
  2977. ;*                      Two outputs to 3c5.11 (of any value) when the hidden
  2978. ;*                      3c5.11 20 bit is set unlock 3c5.11.
  2979. ;*                      Setting the 3c5.11 20 bit also locks (reads as zero)
  2980. ;*                      3c5.12.  In spite of documentation, ALL bits in the
  2981. ;*                      3c5.12 register are writable when unlocked.
  2982. ;*
  2983. ;* INPUT         = NONE
  2984. ;* OUTPUT        = NONE
  2985. ;*
  2986. ;* RETURN-NORMAL = ZR if found.
  2987. ;* RETURN-ERROR  = NZ if not found.
  2988. ;*
  2989. ;* CALLED BY
  2990. ;*
  2991. ;****************************************************************************/
  2992.  
  2993. IsWeitek        PROC    Near
  2994.                 PUBLIC  IsWeitek
  2995.  
  2996.         enter   STACKBLOCK, 0
  2997.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  2998.         call    GetSave1                ;Read original index & save it.
  2999.         mov     al, 011h                ;SEQ misc index.
  3000.         call    OutpIdxInpData          ;Read POSSIBLY locked value.
  3001.         test    al, 020h                ;Test SEQ Misc CRLOCK.
  3002.         .if     < z >                   ;Only W5x86 if zero!
  3003.             call    OutpData            ;Output twice to unlock.
  3004.             call    OutpData            ; 
  3005.             call    InpData             ;Read UNlocked original value.
  3006.             mov     ah, al              ;Save value to restore.
  3007.             and     al, not 020h        ;Unlock Output register.
  3008.             call    OutpData            ; 
  3009.             mov     al, 010h            ;SEQ W5x86 ID Register.
  3010.             call    OutpIdxInpData      ; 
  3011.             and     al, 0f0h            ;Extract W5x86 ID bits.
  3012.             cmp     al, 050h            ;Only W5x86 if equal!
  3013.             mov     al, 011h            ;SEQ misc index.
  3014.             call    OutpwDelay          ;Restore original lock/unlock.
  3015.         .endif
  3016.         call    RestoreSave1            ;Restore the original values.
  3017.         leave
  3018.         ret
  3019.  
  3020. IsWeitek        ENDP
  3021.  
  3022. ;*                                                              /*          */
  3023. ;/****************************************************************************
  3024. ;*
  3025. ;* FUNCTION NAME = WeitekP9000Chk
  3026. ;*
  3027. ;* DESCRIPTION   = Check physical memory addresses for Weitek 9000
  3028. ;*
  3029. ;*                 ONLY 9000 PASSES THIS TEST, NOT 9100!
  3030. ;*
  3031. ;*                 INTERRUPT REG @ ADDR 00100008+xxx00000 (xxx=top 10 bits)
  3032. ;*                 xxx usually C00,D00,E00,F00 in Weitek implementation
  3033. ;*                 xxx usually 800,A00,200 for Diamond Viper
  3034. ;*                        Bits 31-6 always zero.
  3035. ;*                        Bit pairs 5-4,3-2,1-0 must set high bit to chg low.
  3036. ;*                        Safe to change other bits momentarily in text modes
  3037. ;*                        for testing existence.
  3038. ;*                        Works strangely enough to be a reasonable test.
  3039. ;*                 SYS CONFIG REG @ ADDR 00100004+xxx00000 (xxx=top 10 bits)
  3040. ;*                        Bits 31-26,8-3 always zero.
  3041. ;*                        Bits 2-0 are chip version
  3042. ;*                        Safe to change other bits momentarily in text modes
  3043. ;*                        for testing existence.
  3044. ;*                        Decent redundancy check for first test.
  3045. ;*
  3046. ;* INPUT         = DI == high word of address to check
  3047. ;* OUTPUT        = NONE
  3048. ;*
  3049. ;* RETURN-NORMAL = ZR if found.
  3050. ;* RETURN-ERROR  = NZ if not found.
  3051. ;*
  3052. ;* CALLED BY
  3053. ;*      IsWeitek9x00
  3054. ;*
  3055. ;****************************************************************************/
  3056.  
  3057. ifndef SVGAUTIL
  3058.  
  3059. WeitekP9000Chk  PROC    Near            ;                       /*@V3.0MNH04*/
  3060.                 PUBLIC  WeitekP9000Chk  ;                       /*@V3.0MNH04*/
  3061.  
  3062.         xor     bx, bx                  ;Low word of physical address.
  3063.         mov     cx, WEITEK_P9000_REGLENGTH  ;Length of area selected
  3064.         push    es
  3065.         mov     ax, di                  ;High word of physical address.
  3066.         call    SVGAPhysToUVirt
  3067.         mov     ax, 000h                ;Convert nc to z, c to nz
  3068.         rcl     ax, 001h                ; 
  3069.         .if     < z >                   ;If selector returned:
  3070.             mov     ax, word ptr es:[bx][WEITEK_P9000_SYSCONFIG][word]
  3071.             and     ax, 0fe80h
  3072.             .if     < z >
  3073.             mov     ax, word ptr es:[bx][WEITEK_P9000_SYSCONFIG]
  3074.             and     ax, 001f8h
  3075.             .if     < z >
  3076.             mov     ax, word ptr es:[bx][WEITEK_P9000_ENABLE][word]
  3077.             and     ax, ax
  3078.             .if     < z >
  3079.             mov     ax, word ptr es:[bx][WEITEK_P9000_ENABLE]
  3080.             and     ax, 0ffaah
  3081.             .if     <ax e 000aah>
  3082.             mov     ax, word ptr es:[bx][WEITEK_P9000_INTERRUPT][word]
  3083.             and     ax, ax
  3084.             .if     < z >
  3085.             cli
  3086.             mov     ax, word ptr es:[bx][WEITEK_P9000_INTERRUPT]
  3087.             mov     dx, ax              ;Save a copy for restore.
  3088.             and     ax, 0ffeah
  3089.             .if     <ax e 0002ah>
  3090. ;
  3091. ;                   These XOR'd bits should be read only!
  3092. ;
  3093.                 xor     word ptr es:[bx][WEITEK_P9000_INTERRUPT], 0ffffh
  3094.                 .if     <dx e es:[bx][WEITEK_P9000_INTERRUPT]>  ;Same?
  3095.                     mov     ax, 00015h  ;Only these bits should change!
  3096.                     xor     word ptr es:[bx][WEITEK_P9000_INTERRUPT], ax
  3097.                     xor     ax, dx
  3098.                     cmp     ax, es:[bx][WEITEK_P9000_INTERRUPT]  ;Same?
  3099.                 .endif
  3100.                 mov     es:[bx][WEITEK_P9000_INTERRUPT], dx  ;Restore non-WEITEK_P9000!
  3101.             .endif                      ;Else already nz for not found.
  3102.             .endif                      ;Else already nz for not found.
  3103.             .endif                      ;Else already nz for not found.
  3104.             .endif                      ;Else already nz for not found.
  3105.             .endif                      ;Else already nz for not found.
  3106.             .endif                      ;Else already nz for not found.
  3107.             sti
  3108.             call    SVGAUnPhysToUVirt   ;ES=selector to free.
  3109.         .endif                          ;Else already nz for not found.
  3110.         pop     es
  3111.         ret
  3112.  
  3113. WeitekP9000Chk  ENDP                    ;                       /*@V3.0MNH04*/
  3114.  
  3115. endif ;/* SVGAUTIL */
  3116.  
  3117. ;*                                                              /*          */
  3118. ;/****************************************************************************
  3119. ;*
  3120. ;* FUNCTION NAME = IsWeitekP9x00
  3121. ;*
  3122. ;* DESCRIPTION   = Hunt thru physical memory addresses for Weitek
  3123. ;*                 INTERRUPT REG @ ADDR 00100008+xxx00000 (xxx=top 10 bits)
  3124. ;*                 xxx usually C00,D00,E00,F00 in Weitek implementation
  3125. ;*                 xxx usually 800,A00,200 for Diamond Viper
  3126. ;*                        Bits 31-6 always zero.
  3127. ;*                        Bit pairs 5-4,3-2,1-0 must set high bit to chg low.
  3128. ;*                        Safe to change other bits momentarily in text modes
  3129. ;*                        for testing existence.
  3130. ;*                        Works strangely enough to be a reasonable test.
  3131. ;*                 SYS CONFIG REG @ ADDR 00100004+xxx00000 (xxx=top 10 bits)
  3132. ;*                        Bits 31-26,8-3 always zero.
  3133. ;*                        Bits 2-0 are chip version
  3134. ;*                        Safe to change other bits momentarily in text modes
  3135. ;*                        for testing existence.
  3136. ;*                        Decent redundancy check for first test.
  3137. ;*
  3138. ;*                      For Diamond Viper, the P9x00 chip must first be
  3139. ;*                      mapped into the address space.
  3140. ;*                      Setting the index at 3c4, or setting the 3c5.11 20 bit
  3141. ;*                      (a second time) locks (reads as zero)
  3142. ;*                      3c5.11 when the 3c5.11 20 bit is already set.
  3143. ;*                      Two outputs to 3c5.11 (of any value) when the hidden
  3144. ;*                      3c5.11 20 bit is set unlock 3c5.11.
  3145. ;*                      Setting the 3c5.11 20 bit also locks (reads as zero)
  3146. ;*                      3c5.12.  In spite of documentation, ALL bits in the
  3147. ;*                      3c5.12 register are writable when unlocked.
  3148. ;*
  3149. ;* INPUT         = NONE
  3150. ;* OUTPUT        = NONE
  3151. ;*
  3152. ;* RETURN-NORMAL = ZR if found.
  3153. ;* RETURN-ERROR  = NZ if not found.
  3154. ;*
  3155. ;* CALLED BY
  3156. ;*
  3157. ;****************************************************************************/
  3158.  
  3159. IsWeitekP9x00   PROC    Near            ;                       /*@V3.0MNH04*/
  3160.                 PUBLIC  IsWeitekP9x00   ;                       /*@V3.0MNH04*/
  3161.  
  3162.         enter   STACKBLOCK, 0
  3163.         push    di
  3164.         mov     bx, 00037h              ;Search target offset.
  3165.         mov     cx, 5                   ;Search string length.
  3166.         mov     di, OFFSET DGROUP :DiamondViperSig ;Search string value.
  3167.         call    FindString              ;See if string is there in ROM.
  3168.         .if     < z >                   ;If Diamond Viper.
  3169. ;*
  3170. ;*              Diamond Viper does not map the P9x00 into memory
  3171. ;*              until you indicate where by outputting where to (locked)
  3172. ;*              SEQ register 012.  One bit value means unmapped.
  3173. ;*              So we cannot just hunt thru memory for the P9x00!
  3174. ;*              This test works for both real DOS and OS/2.
  3175. ;*
  3176.             mov     dx, 03c4h           ;SEQ index address (3c4)/*          */
  3177.             call    GetSave1            ;Read original index & save it.
  3178.             mov     al, 011h            ;SEQ misc index.
  3179.             call    OutpIdxInpData      ;Read POSSIBLY locked value.
  3180.             test    al, 020h            ;Test SEQ Misc CRLOCK.
  3181.             .if     < z >               ;Only Diamond Viper if zero!
  3182.                 mov     [SvgaOEMInfo.Manufacturer], DIAMOND_MANUFACTURER ; 1 ;
  3183.                 call    OutpData        ;Output twice to unlock.
  3184.                 call    OutpData        ; 
  3185.                 call    InpData         ;Read UNlocked original value.
  3186.                 mov     ah, al          ;Save value to restore.
  3187.                 and     al, not 020h    ;Unlock Output register.
  3188.                 call    OutpData        ; 
  3189.                 mov     al, 012h        ;SEQ Output index.
  3190.                 call    OutpIdxInpData  ; 
  3191.                 or      al, 003h        ;Set base address to 80000000.
  3192.                 call    OutpData        ;So following test works!
  3193.                 mov     al, 011h        ;SEQ misc index.
  3194.                 call    OutpwDelay      ;Restore original lock/unlock.
  3195.                 mov     di, 08000h+WEITEK_P9000_REGISTERS ;Indicate base address.
  3196.                 xor     ax, ax          ;Always successful here!
  3197.             .endif
  3198.             call    RestoreSave1        ;Restore the original values.
  3199.         .endif                          ;Endif Diamond Viper.
  3200.         .if     < nz >                  ;If NOT Diamond Viper.
  3201. ;*
  3202. ;*              Since unextended real DOS cannot peek and poke the P9x00,
  3203. ;*              we need a reasonable facsimile.
  3204. ;*              Also since poking in memory can be dangerous,
  3205. ;*              it would be helpful to have some hints that we will find it,
  3206. ;*              before we go off and poke into a possible NMI handler.
  3207. ;*              Besides checking for the "WEITEK" string,
  3208. ;*              Another possibility would be to also check for a Weitek VGA!
  3209. ;*              Weitek VGA existence could also justify P9x00 memory search or
  3210. ;*              could also presumably "imply" P9x00 existence (for real DOS).
  3211. ;*              For WPOS, we might not have a BIOS, so we should just
  3212. ;*              do the hunt or require a Weitek VGA.
  3213. ;*
  3214.             .if     <[_sSVGA.AdapterType] ne WEITEK_ADAPTER>
  3215.                 mov     cx, 6           ;Search string length.
  3216.                 mov     di, OFFSET DGROUP:WeitekSig ;Search string value.
  3217.                 call    LookString      ;See if string is anywhere in ROM.
  3218.             .endif
  3219. ;                                       ;Indicate presumed addr./*@V3.0MNH04*/
  3220.              mov     di, 0c000h+WEITEK_P9000_REGISTERS ;        /*@V3.0MNH04*/
  3221.         .endif                          ;Endif NOT Diamond Viper.
  3222.         .if     < z >                   ;If we found a Weitek P9000:
  3223.             mov word ptr [SvgaBaseAddr][word], di ;Save addr.   /*@V3.0MNH04*/
  3224.         .endif
  3225.         pop     di
  3226.         leave
  3227.         ret
  3228.  
  3229. IsWeitekP9x00   ENDP                    ;                       /*@V3.0MNH04*/
  3230.  
  3231. ;/****************************************************************************
  3232. ;*
  3233. ;* FUNCTION NAME = LastAttempt
  3234. ;*
  3235. ;* DESCRIPTION   = This function attempts to detect chipsets of the
  3236. ;*                 manufacturers which we don't successfuly identify
  3237. ;*                 in "IsAdapter" functions. For example:
  3238. ;*                 WD adapters are identified depending on the presence
  3239. ;*                 of VGA= string in the BIOS. For many OEM implementations,
  3240. ;*                 this test would fail. The code must not trash VGA registers.
  3241. ;*
  3242. ;* INPUT         = NONE
  3243. ;* OUTPUT        = AX = usAdapterType
  3244. ;*                 BX = ChipType
  3245. ;*
  3246. ;* RETURN-NORMAL = non zero AX
  3247. ;* RETURN-ERROR  = AX zero
  3248. ;*
  3249. ;* CALLED BY
  3250. ;*
  3251. ;****************************************************************************/
  3252.  
  3253. LastAttempt     PROC    Near
  3254.                 PUBLIC  LastAttempt
  3255.  
  3256.         enter   STACKBLOCK, 0           ;          
  3257. ;       I doubt that the WD code is necessary any longer!       /*          */
  3258.         xor     ax, ax                  ;No identifiable VGA.   /*          */
  3259.         leave                           ;          
  3260.         ret
  3261.  
  3262. LastAttempt     ENDP
  3263.  
  3264. ;*****************************************************************************
  3265. ;
  3266. ;
  3267. ;
  3268. ;*****************************************************************************
  3269.  
  3270. ;*                                                              /*          */
  3271. ;/****************************************************************************
  3272. ;*
  3273. ;* FUNCTION NAME = WhichATIUnaccelerated
  3274. ;*
  3275. ;* DESCRIPTION   = Test ATI chip for Unaccelerated.
  3276. ;*
  3277. ;* INPUT         = NONE
  3278. ;* OUTPUT        = NONE
  3279. ;*
  3280. ;* RETURN-NORMAL = 1 - ATI18800-x chip
  3281. ;*                 2 - ATI28800-x chip
  3282. ;* RETURN-ERROR  = NONE
  3283. ;*
  3284. ;* CALLED BY
  3285. ;*      WhichATI
  3286. ;*
  3287. ;****************************************************************************/
  3288.  
  3289. WhichATIUnaccelerated   PROC    near    ;                       /*          */
  3290.         PUBLIC  WhichATIUnaccelerated
  3291.  
  3292.         push    ds              ; 
  3293.         mov     ax, 0ch         ; ROM Address high
  3294.         xor     bx, bx          ; ROM Address low
  3295.         mov     cx, 100h        ; 
  3296.         call    SVGAPhysToVirt  ; 
  3297.  
  3298.         ASSUME  DS:NOTHING
  3299.  
  3300.         xor     ah, ah          ; 
  3301.         mov     al, ds:[si+43h] ; Chip version number
  3302.         sub     al, '0'         ; 
  3303.         pop     ds              ; 
  3304.  
  3305.         ASSUME  DS:DGROUP
  3306.  
  3307.         call    SVGAUnPhysToVirt        ; 
  3308.         mov     dx, 01ceh               ;ATI Extended regs index
  3309.         mov     ah, al                  ;Save version number
  3310.         call    InpDelay                ;Get current index reg  /*          */
  3311.         or      al, 080h                ;This bit not readable  /*          */
  3312.         push    ax                      ;Save index & version
  3313.         .if     <ah be 2>               ;Not Ver 3 or higher    /*          */
  3314.             mov     al, 0bbh            ;                       /*          */
  3315.             call    OutpIdxInpData      ;Read indexed reg       /*          */
  3316.             mov     cx, 4               ;assume 256k            /*          */
  3317.             test    al, 20h             ; 
  3318.             .if     < nz >              ;                       /*          */
  3319.                 shl     cx, 1           ;                       /*          */
  3320.             .endif                      ;                       /*          */
  3321.         .else                                                   /*@V2.1MNH13*/
  3322. ATIV3:
  3323.             mov     al, 0b0h            ;                       /*          */
  3324.             call    OutpIdxInpData      ;Read indexed reg       /*          */
  3325.             mov     cx, 4               ;assume 256k            /*          */
  3326.             test    al, 18h             ; 
  3327.             .if     < nz >              ;                       /*          */
  3328.                 shl     cx, 1           ;make it 512k           /*          */
  3329.                 test    al, 10h         ; 
  3330.                 .if     < z >           ;                       /*          */
  3331.                     shl     cx, 1       ;make it 1M             /*          */
  3332.                 .endif                  ;                       /*          */
  3333.             .endif                      ;                       /*          */
  3334.         .endif                          ;                       /*          */
  3335. ATIMEM:                                 ;                       /*          */
  3336.         mov     word ptr [_sSVGA.Memory][1*word], cx ;          /*          */
  3337. ;                                                                ;           start
  3338.         pop     ax                      ;Restore index & ver.
  3339.         call    OutpDelay               ;Restore original index /*          */
  3340. ;!!     .if < ah b 5 >                  ;Was this in SVGAROUT but not SVGAID!
  3341.         .if < ah b 3 >                  ;Was this in SVGAID but not SVGAROUT!
  3342.             mov     ax, ATI_18800_CHIP  ; 
  3343.         .else                           ; 
  3344.             mov     ax, ATI_28800_CHIP  ; 
  3345.         .endif                          ; 
  3346. ATIExit:                                ; 
  3347.         ret
  3348.  
  3349. WhichATIUnaccelerated   ENDP
  3350.  
  3351. ;/****************************************************************************
  3352. ;*
  3353. ;* FUNCTION NAME = WhichATI
  3354. ;*
  3355. ;* DESCRIPTION   = ATI Wonder boards V3, V4, V5 use ATI18800-x chips
  3356. ;*                                   V6, +, XL  use ATI28800-x chips
  3357. ;*                 ATI "Ultra" boards use Mach 8 == ATI38800-x chips
  3358. ;*                 ATI "Graphics Ultra" uses Mach 32 == ATI68800-x chips
  3359. ;*
  3360. ;* INPUT         = NONE
  3361. ;* OUTPUT        = NONE
  3362. ;*
  3363. ;* RETURN-NORMAL = 1 - ATI18800-x chip
  3364. ;*                 2 - ATI28800-x chip
  3365. ;*                 3 - ATI38800-x chip                          /*          */
  3366. ;*                 4 - ATI68800-x chip                          /*          */
  3367. ;*                 5 - ATI88800-x chip                          /*          */
  3368. ;* RETURN-ERROR  = NONE
  3369. ;*
  3370. ;* CALLED BY
  3371. ;*
  3372. ;****************************************************************************/
  3373.  
  3374. WhichATI        PROC    Near            ; 
  3375.                 PUBLIC  WhichATI        ; 
  3376.  
  3377.         call    ATI8514                 ;Test for ATI 8514      /*          */
  3378.         .if     < z >                   ;If ATI 8154:
  3379.             mov     ax,0aaaah AND 003ffh;Must limit to 11 bits!
  3380.             call    ATIDestXOutpChk     ; 
  3381.             .if     < z >               ;If OK so far:
  3382.                 mov     ax,05555h AND 003ffh ;Must limit to 11 bits!
  3383.                 call    ATIDestXOutpChk ; 
  3384.             .endif                      ; 
  3385.             .if     < z >               ;If 68800 (Mach 32)
  3386.                 mov     dx, 036eeh      ;Misc_Options           /*          */
  3387.                 mov     cl, 002h        ;Get shift count        /*          */
  3388.                 mov     bx, ATI_68800_CHIP ;                    /*          */
  3389.             .else                       ;Else 38800 (Mach 8)
  3390.                 mov     dx, 012eeh      ;Config_Status_1        /*          */
  3391.                 mov     cl, 005h        ;Get shift count        /*          */
  3392.                 mov     bx, ATI_38800_CHIP ;                    /*          */
  3393.             .endif                      ; 
  3394.             call    InpwDelay           ;                       /*          */
  3395.             shr     al, cl              ;Shift to low bits      /*          */
  3396.             and     al, 003h            ;Get memory size bits.  /*          */
  3397.             mov     cl, al              ;Use as shift count     /*          */
  3398.             mov     ax, 00008h          ;Start with 64K*8=512K  /*          */
  3399.             shl     ax, cl              ;                       /*          */
  3400.             mov     word ptr [_sSVGA.Memory][1*word], ax ;      /*          */
  3401.             mov     ax, bx              ;Set chiptype           /*          */
  3402.         .else                           ;If NOT ATI 8514:
  3403. ;                                                               /*          */
  3404. ;           Check for Mach64 AFTER Mach8/32:                    /*          */
  3405. ;               ValuePoint AMBRA system has Mach32 which        /*          */
  3406. ;               responds to 0x02ec + ? * 0x0400                 /*          */
  3407. ;               when it should not.                             /*          */
  3408. ;               Problem is that it hangs the system when you    /*          */
  3409. ;               write to such an address!                       /*          */
  3410. ;                                                               /*          */
  3411. ;               Since it did not happen with all Mach32s        /*          */
  3412. ;               it is probably a hardware problem.              /*          */
  3413. ;                                                               /*          */
  3414. ;               Changing the Mach64 test itself would probably  /*          */
  3415. ;               not help get past this problem, since           /*          */
  3416. ;               we would still have to write to SOME port!      /*          */
  3417. ;                                                               /*          */
  3418. ;               Fortunately, we already know that the Mach64    /*          */
  3419. ;               does not pass the test for a Mach32 or Mach8!   /*          */
  3420. ;                                                               /*          */
  3421.             call    ATIMach64           ;Is it a Mach 64?
  3422.             .if     < z >               ;If ATI Mach 64:
  3423.                 mov     dx, 052ech      ;MEM_CTRL reg addr.
  3424.                 call    InpwDelay       ;Read the current value.
  3425.                 and     ax, 007h        ;Get memory size bits.
  3426.                 test    al, 004h
  3427.                 .if     < nz >          ;If below boundary:
  3428.                     mov     cl, al      ; 
  3429.                     mov     ax, 00008h  ;Set for 64K*8=512K.
  3430.                     shl     ax, cl      ;Shift to actual size.
  3431.                 .else                   ;Else above boundary:
  3432.                     dec     ax          ;Get count of 2M units.
  3433.                     shl     ax, 005h    ;Shift to 64K units.
  3434.                 .endif                  ; 
  3435.                 mov     word ptr [_sSVGA.Memory][1*word], ax ; 
  3436.                 mov     ax, ATI_88800_CHIP ; 
  3437.             .else                       ;Else NOT ATI Mach 64:
  3438.                 call    WhichATIUnaccelerated ;                 /*          */
  3439.             .endif                      ; 
  3440.         .endif                          ; 
  3441.         ret
  3442. ;                                                                ;           end
  3443. WhichATI        ENDP                    ; 
  3444.  
  3445. ;/****************************************************************************
  3446. ;*
  3447. ;* FUNCTION NAME = WhichCirrus
  3448. ;*
  3449. ;* DESCRIPTION   =  Cirrus chips: GD5422, GD5424, GD5426, GD5428, etc.
  3450. ;*
  3451. ;* INPUT         = NONE
  3452. ;* OUTPUT        = NONE
  3453. ;*
  3454. ;* RETURN-NORMAL = 0 - any other Cirrus chip, not supported by SVGA
  3455. ;*                 1 - GD5420 chip                                          
  3456. ;*                 2 - GD5422 chip
  3457. ;*                 3 - GD5424 chip
  3458. ;*                 4 - GD5426 chip
  3459. ;*                 5 - GD5428 chip                                          
  3460. ;*                 6 - GD5429 chip                                          
  3461. ;*                 7 - GD543X chip                                          
  3462. ;*                 8 - GD5434 chip                                          
  3463. ;*
  3464. ;* RETURN-ERROR  = NONE
  3465. ;*
  3466. ;* CALLED BY
  3467. ;*
  3468. ;****************************************************************************/
  3469. ;          
  3470. WhichCirrus     PROC    Near
  3471.                 PUBLIC  WhichCirrus
  3472.  
  3473.         enter   STACKBLOCK, 0           ;          
  3474.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  3475.         call    GetSave1                ;Read original index & save it.
  3476.         mov     ax, 01206h              ; sr6 register index and unlock.
  3477.         mov     [SaveReg2], dx          ;                       /*          */
  3478.         mov     [SaveIndex2], al
  3479.         call    OutpIdxChkXchgData      ;Try setting SEQ SR6.   /*          */
  3480.         mov     [SaveValue2], al        ;Save old value.        /*          */
  3481.         mov     ah, 0                   ; set return to 0
  3482.         jne     cirrus_exit             ; Unable to unlock, assume GD5401
  3483.         call    GetCrtcBase             ;(3d4)                  /*          */
  3484. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  3485.         mov     al, 27h                 ; Chip ID register index
  3486.         call    OutpIdxInpData          ;Read indexed reg       /*          */
  3487.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  3488. ;           mov     ah, 0                   ; asuume one of the older ones
  3489. ;           cmp     al, 8ah                 ; GD5420
  3490. ;           je  cirrus_exit
  3491.         shr     al, 1
  3492.         shr     al, 1
  3493.         mov     ah, CIRRUS_5420_CHIP    ; 1                                  
  3494.         cmp     al, 022h                ; GD5420                             
  3495.         je      Mem2x                   ;                                    
  3496.         mov     ah, CIRRUS_5422_CHIP ;2                         /*          */
  3497.         cmp     al, 23h                 ; GD5422
  3498.         je      Mem2x                   ;                                    
  3499.         mov     ah, CIRRUS_5424_CHIP ;3                         /*          */
  3500.         cmp     al, 25h                 ; GD5424
  3501.         je      Mem2x                   ;                                    
  3502.         mov     ah, CIRRUS_5426_CHIP ;4                         /*          */
  3503.         cmp     al, 24h                 ; GD5426
  3504.         je      Mem2x                   ;                                    
  3505.         mov     ah, CIRRUS_5428_CHIP ;5 ;            ;           *          */
  3506.         cmp     al, 26h                 ; GD5428                             
  3507.         je      Mem2x                   ;                                    
  3508.         mov     ah, CIRRUS_5429_CHIP    ; 6                                  
  3509.         cmp     al, 027h                ; GD5429                             
  3510.         je      Mem2x                   ;                                    
  3511.         mov     ah, CIRRUS_5434_CHIP    ; 8                                  
  3512.         cmp     al, 02Ah                ; GD5434                             
  3513.         je      Mem3x                   ;                                    
  3514.         mov     ah, CIRRUS_543X_CHIP    ; 7                                  
  3515.         cmp     al, 028h                ; GD5430                             
  3516.         je      Mem3x                   ;                                    
  3517.         cmp     al, 029h                ; GD5430-like                        
  3518.         je      Mem3x                   ;                                    
  3519.         mov     ah, 0                   ; none of the above
  3520.         jmp     short cirrus_exit       ; exit                               
  3521. Mem2x:                                  ;                                    
  3522.         mov     al, 0ah                 ; memory reg for 2x                  
  3523.         call    OutpIdxInpData          ; get memory value                   
  3524.         shr     al, 03h                 ; shift bits 3,4 to end              
  3525.         and     al, 03h                 ; only look at bits 3,4              
  3526.         jmp     short GetCirrusMem      ; get memory                         
  3527. Mem3x:                                  ;                                    
  3528.         mov     al, 015h                ; memory reg for 3x                  
  3529.         call    OutpIdxInpData          ; get memory value                   
  3530.         and     al, 00fh                ; mask lower nibble                  
  3531. GetCirrusMem:                           ;                                    
  3532.         .if     <al ne 002h>            ;1 Meg ?                             
  3533.             mov     dx, 010h            ;Get default mem size=1M             
  3534.             .if     <al e 001h>         ;512K ?                              
  3535.                 shr     dx, 1           ;adjust mem to 512k                  
  3536.             .endif                      ;                                    
  3537.             .if     <al e 003h>         ;2 Meg ?                             
  3538.                 shl     dx, 1           ;adjust mem to 2 Meg                 
  3539.             .endif                      ;                                    
  3540.             .if     <al e 004h>         ;4 Meg ?                             
  3541.                 shl     dx, 2           ;adjust mem to 4 Meg                 
  3542.             .endif                      ;                                    
  3543.             mov     word ptr [_sSVGA.Memory][1*word], dx  ;save it           
  3544.         .endif                          ;                                    
  3545. cirrus_exit:
  3546.         mov     al, ah
  3547.         cbw
  3548.         call    RestoreSave2            ;Restore the original values.
  3549.         leave                           ;          
  3550.         ret
  3551.  
  3552. WhichCirrus        ENDP
  3553.  
  3554. ;/*****************************************************************             ;          
  3555. ;*
  3556. ;* FUNCTION NAME = WhichS3                                  
  3557. ;*
  3558. ;* DESCRIPTION   =  S3: xxxxxx, xxxxxx, xxxxxx
  3559. ;*
  3560. ;* INPUT         = NONE
  3561. ;* OUTPUT        = NONE
  3562. ;*
  3563. ;* RETURN-NORMAL = 0 - any other S3 chip, not supported by SVGA
  3564. ;*                 1 - xxxxxx chip
  3565. ;*                 2 - xxxxxx chip
  3566. ;*                 3 - xxxxxx chip
  3567. ;*
  3568. ;* RETURN-ERROR  = NONE
  3569. ;*
  3570. ;* CALLED BY
  3571. ;*
  3572. ;****************************************************************************/
  3573. WhichS3         PROC    Near            ;          
  3574.                 PUBLIC  WhichS3
  3575.  
  3576. ;!!Need to adjust memory sizes!
  3577.         enter   STACKBLOCK, 0           ;          
  3578.         mov     ax, 04838h              ;Unlock extensions.
  3579.         call    GetCrtcBaseSave2        ;(3d4)                  /*          */
  3580. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  3581. ;       mov     ax, 0a039h              ;unlock r39             /*          */
  3582. ;       call    OutpIdxXchgData         ;Not needed for reads!  /*          */
  3583. ;       mov     ah, al                  ;                       /*          */
  3584. ;       push    ax                      ;Save original lock     /*          */
  3585.         mov     al, 030h                ;Chip ID/Rev index      /*          */
  3586.         call    OutpIdxInpData          ;Read indexed reg       /*          */
  3587.         and     al, 0f0h                ;mask out lower nibble  /*          */
  3588.         mov     cl, al                  ;Save chip id           /*          */
  3589.         mov     al, 036h                ;Configuration Reg 1 index
  3590.         call    OutpIdxInpData          ;Read indexed reg       /*          */
  3591.         and     al, 0e0h
  3592.         .if     <cl e 080h>             ;If 911/924:            /*          */
  3593.             or  al, 0c0h                ;Insure high bits set   /*          */
  3594.         .endif                          ;                       /*          */
  3595.         .if     <al ne 0c0h>            ;1 Meg ?                /*          */
  3596.             mov     dx, 010h            ;Get default mem size=1M/*          */
  3597.             .if     <al e 0e0h>         ;512K ?                 /*          */
  3598.                 shr     dx, 1           ;adjust mem to 512k
  3599.             .endif                                              /*@V2.1MNH13*/
  3600.             .if     <al e 080h>         ;2 Meg ?                /*          */
  3601.                 shl     dx, 1           ;adjust mem to 2 Meg
  3602.             .endif                                              /*@V2.1MNH13*/
  3603.             .if     <al e 040h>         ;3 Meg ?                /*          */
  3604.                 mov     bx, dx          ;adjust mem to 3 Meg
  3605.                 shl     dx, 1
  3606.                 or      dx, bx
  3607.             .endif                                              /*@V2.1MNH13*/
  3608.             .if     <zero al>           ;4 Meg ?                /*          */
  3609.                 shl     dx, 2           ;adjust mem to 4 Meg
  3610.             .endif                                              /*@V2.1MNH13*/
  3611. ;                                       ;Save mem size:         /*          */
  3612.             mov     word ptr [_sSVGA.Memory][1*word], dx ;      /*          */
  3613.         .endif                                                  /*@V2.1MNH13*/
  3614. determine_S3:
  3615.         mov     al, S3_86C805_CHIP      ;                       /*          */
  3616.         cmp     cl, 0a0h                ;801/805
  3617.         je      S3_exit                 ;                       /*          */
  3618.         mov     al, S3_86C911_CHIP      ;                       /*          */
  3619.         cmp     cl, 080h                ;          
  3620.         je      S3_exit                 ;                       /*          */
  3621.         mov     al, S3_86C928_CHIP      ;                       /*          */
  3622.         cmp     cl, 090h                ;928
  3623.         je      S3_exit                 ;                       /*          */
  3624.         cmp     cl, 0b0h                ;928 PCI                            
  3625.         je      S3_exit                 ;                       /*          */
  3626.         mov     al, S3_86C864_CHIP      ;                       /*          */
  3627.         cmp     cl, 0c0h                ;Vision 864                         
  3628.         je      S3_exit                 ;                       /*          */
  3629.         mov     al, S3_86C964_CHIP      ;                       /*@V3.0YEE01*/
  3630.         cmp     cl, 0d0h                ;Vision 964               @V3.0YEE01
  3631.         je      S3_exit                 ;                       /*@V3.0YEE01*/
  3632.         xor     al, al                  ;                       /*          */
  3633. S3_exit:
  3634.         cbw
  3635. S3found:
  3636. ;       mov     cx, ax                  ;                       /*          */
  3637. ;       pop     ax                      ;Restore original lock. /*          */
  3638. ;       mov     al, 039h                ;Not needed for reads!  /*          */
  3639. ;       call    OutpwDelay              ;Write the new value.   /*          */
  3640.         call    RestoreSave2            ;Restore original value.
  3641. ;       mov     ax, cx                  ;                       /*          */
  3642.         leave                           ;          
  3643.         ret
  3644.  
  3645. WhichS3            ENDP
  3646.  
  3647. ;/****************************************************************************
  3648. ;*
  3649. ;* FUNCTION NAME = WhichTrident
  3650. ;*
  3651. ;* DESCRIPTION   =
  3652. ;*
  3653. ;*         read Chip Version Register
  3654. ;*         value in AL >= 3   8900 chip version
  3655. ;*
  3656. ;*         convert AL to:  AL = 1 => 8800
  3657. ;*                         AL = 2 => 8900
  3658. ;*
  3659. ;*         Check memory on 8900 from 'Software Programming' register
  3660. ;*
  3661. ;* INPUT         = NONE
  3662. ;* OUTPUT        = NONE
  3663. ;*
  3664. ;* RETURN-NORMAL = NONE
  3665. ;* RETURN-ERROR  = NONE
  3666. ;*
  3667. ;* CALLED BY
  3668. ;*
  3669. ;****************************************************************************/
  3670.  
  3671. WhichTrident    PROC    Near
  3672.                 PUBLIC  WhichTrident
  3673.  
  3674.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  3675.         mov     ax, 0bh                 ;write 0 to version reg (0bh)
  3676.         call    OutpIdxInpData          ;Read indexed reg       /*          */
  3677.         cmp     al, 003h                ;                       /*          */
  3678.         mov     ax, TRIDENT_8800_CHIP   ;assume 8800            /*          */
  3679.         jl      short @F                ;                       /*          */
  3680.         call    GetCrtcBase             ;(3d4)                  /*          */
  3681. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  3682.         mov     al, 01fh                ;Set up to read 'software programming'
  3683.                                         ; reg w/two bits w/amount of video memory.
  3684.         call    OutpIdxInpData          ;Read indexed reg       /*          */
  3685.         and     al, 003h                ;Isolate # 256K blks - 1/*          */
  3686.         inc     al                      ;al = # 256K blks       /*          */
  3687.         shl     al, 002h                ;al = # 64K blks        /*          */
  3688.         mov     byte ptr [_sSVGA.Memory][1*word], al ;          /*          */
  3689.         mov     ax, TRIDENT_8900_CHIP   ;make it 8900           /*          */
  3690. @@:     ret
  3691.  
  3692. WhichTrident    ENDP
  3693.  
  3694. ;/****************************************************************************
  3695. ;*
  3696. ;* FUNCTION NAME = _IdentifyCPU
  3697. ;*
  3698. ;* DESCRIPTION   =   figure out what type of Intel 80x8x is in use
  3699. ;*
  3700. ;*
  3701. ;*
  3702. ;* ENTRY POINT:  _IdentifyProcessorType
  3703. ;*    LINKAGE:   Call Far
  3704. ;*
  3705. ;* INPUT:
  3706. ;*       DS = DGROUP
  3707. ;*
  3708. ;* EXIT-NORMAL: AX = processor type
  3709. ;* EXIT-ERROR:  NONE
  3710. ;*
  3711. ;* EFFECTS:
  3712. ;*       AX
  3713. ;*
  3714. ;* USES ROUTINES:
  3715. ;*
  3716. ;* CALLED BY ROUTINES:
  3717. ;*             INIT
  3718. ;*
  3719. ;* INPUT         = NONE
  3720. ;* OUTPUT        = NONE
  3721. ;*
  3722. ;* RETURN-NORMAL = ax = processor type
  3723. ;* RETURN-ERROR  = NONE
  3724. ;*
  3725. ;* CALLED BY
  3726. ;*
  3727. ;****************************************************************************/
  3728.  
  3729.  
  3730.  
  3731. ;JWK22
  3732.  
  3733. ; The following procedure determines the type of processor present in the
  3734. ; system it is running on.  This procedure was documented by INTEL in an
  3735. ; APPLICATION NOTE (AP-485) as the 'official' way to determine processor
  3736. ; type. Additionally note that if processor is not made by Intel, or by a
  3737. ; vendor licensed to used Intel's masks, the results may not be valid.
  3738. ;
  3739. ; Returns:
  3740. ;  10h - 8088 processor    \ the code to distinguish 8086 from 8088
  3741. ;  11h - 8086 processor    / is NOT from Intel
  3742. ;  20h - Intel 286 processor
  3743. ;  30h - Intel386(TM) processor
  3744. ;  40h - Intel486(TM) processor
  3745. ;  50h - Pentium(TM) processor
  3746. ;
  3747.  
  3748.  
  3749. NULPROC         equ      0h
  3750. PROCV20         equ      8h
  3751. PROC808x        equ     10h
  3752. PROC8088        equ     10h
  3753. PROC8086        equ     11h
  3754. PROC8018x       equ     18h
  3755. PROC80188       equ     18h
  3756. PROC80186       equ     19h
  3757. PROC80286       equ     20h
  3758. PROC80386       equ     30h
  3759. PROC80386SX     equ     38h
  3760. PROC80386SLC    equ     39h
  3761. PROC80386SL     equ     3ah
  3762. PROC80486       equ     40h
  3763. PROC80486DX     equ     40h
  3764. PROC80486DX2    equ     41h
  3765. PROC80486DX3    equ     42h
  3766. PROC80486SX     equ     45h
  3767. PROC80486SX2    equ     46h
  3768. PROC80486SX3    equ     47h
  3769. PROC80486SL     equ     49h
  3770. PROC80486SLC    equ     4ah
  3771. PROC80486SLC2   equ     4bh
  3772. PROC80486SLC3   equ     4ch
  3773. PROC80486BL2    equ     4dh
  3774. PROC80486BL3    equ     4eh
  3775. PROCPentium     equ     50h
  3776. PROCCYRIXDR2    equ    0c6h
  3777.  
  3778. CPUID   MACRO
  3779.         db      0fh                     ; opcode for CPUID instruction
  3780.         db      0a2h
  3781.         ENDM
  3782.  
  3783. MPUSHFD MACRO
  3784.         db      066h                    ; opcode for pushfd instruction
  3785.         db      09ch
  3786.         ENDM
  3787.  
  3788. MPOPFD  MACRO
  3789.         db      066h                    ; opcode for popfd instruction
  3790.         db      09dh
  3791.         ENDM
  3792.  
  3793. MPUSHEAX MACRO
  3794.         db      066h                    ; opcode for pusheax instruction
  3795.         db      050h
  3796.         ENDM
  3797.  
  3798. MPOPEAX MACRO
  3799.         db      066h                    ; opcode for pusheax instruction
  3800.         db      058h
  3801.         ENDM
  3802.  
  3803.  
  3804. FAMILY_MASK     equ     0f00h
  3805. FAMILY_SHIFT    equ     8
  3806. MODEL_MASK      equ     0f0h
  3807. MODEL_SHIFT     equ     4
  3808. STEPPING_MASK   equ     0fh
  3809.  
  3810.  
  3811. cpuid_step         EQU   <BYTE PTR [bp-06h]>       ; byte
  3812. cpuid_model        EQU   <BYTE PTR [bp-08h]>       ; byte
  3813. cpuid_type         EQU   <BYTE PTR [bp-0ah]>       ; byte
  3814. IDENTIFYCPUSTACKBLOCK EQU 0ah
  3815.  
  3816.  
  3817.  
  3818.  
  3819. IdentifyCPU   PROC                 ;JWK22
  3820.  
  3821.         enter   IDENTIFYCPUSTACKBLOCK,0
  3822.         push    ds
  3823.  
  3824.         push    dx
  3825.         push    cx
  3826.         push    bx
  3827.  
  3828.  
  3829.  
  3830.         pushf                           ; save flags
  3831.         xor     ax,ax                   ; clear AX
  3832.         push    ax                      ; push it on the stack
  3833.         popf                            ; zero the flags
  3834.         pushf                           ; try to zero flag bits 12-15
  3835.         pop     ax                      ; recover flags
  3836.         and     ax,0f000h               ; if flag bits 12-15 are 1
  3837.         cmp     ax,0f000h               ;  then processor is
  3838.         jz      is_0_1                  ;   8018x or 808x
  3839.         mov     ax,07000h               ; try to set flag bits 12-14
  3840.         push    ax
  3841.         popf
  3842.         pushf
  3843.         pop     ax
  3844.         mov     dx,PROC80386            ; load 386 value
  3845.         and     ax,07000h               ; if 12-14 are 0
  3846.         jz      is_80286                ;  processor is 80286
  3847.  
  3848.    ; allow 386 instructions
  3849.         .386
  3850.  
  3851.         ;;pushfd                        ; save all flags
  3852.         MPUSHFD
  3853.  
  3854.         mov     ax,0000fh               ; turn all upper bits on
  3855.         push    ax                      ; of EFLAGS.
  3856.         xor     ax,ax                   ; turn off all lower bits of EFLAGS.
  3857.         push    ax                      ; put flags on stack
  3858.  
  3859.         ;;popfd                         ; pop back into flags
  3860.         MPOPFD
  3861.  
  3862.         ;;pushfd                        ; push flags back to stack
  3863.         MPUSHFD
  3864.  
  3865.         pop     ax                      ; throw away lower part
  3866.         pop     ax                      ; we can see results in AX
  3867.         cmp     ax,0                    ; if AX == 0 then we have a 386
  3868.         jz      SHORT finishpop         ; otherwise we have a 486 or higher
  3869.  
  3870.         mov     dx,PROC80486            ; store a 486 value
  3871.  
  3872.         ;;pushfd                        ; push original EFLAGS
  3873.         MPUSHFD
  3874.  
  3875.         ;;pop     eax                   ; get original EFLAGS in EAX
  3876.         MPOPEAX
  3877.  
  3878.         mov     ecx,eax                 ; save original EFLAGS in ECX
  3879.         xor     eax,200000h             ; flip ID bit in EFLAGS
  3880.  
  3881.         ;;push    eax                   ; save for EFLAGS
  3882.         MPUSHEAX
  3883.  
  3884.         ;;popfd                         ; copy to EFLAGS
  3885.         MPOPFD
  3886.  
  3887.         ;;pushfd                        ; push EFLAGS
  3888.         MPUSHFD
  3889.  
  3890.         ;;pop     eax                   ; get new EFLAGS value
  3891.         MPOPEAX
  3892.  
  3893.         xor     eax,ecx
  3894.         jz      SHORT finishpop         ; if ID bit cannot be changed,
  3895.                                         ;   CPU = Intel486 without CPUID
  3896.                                         ;   instruction functionality
  3897. ;
  3898. ;    Otherwise, execute CPUID instruction to determine family.
  3899. ;
  3900. cpuid_data:
  3901.         mov     eax,1
  3902.         CPUID
  3903.         mov     cpuid_step,al          ; isolate stepping info
  3904.         and     cpuid_step,STEPPING_MASK
  3905.  
  3906.         and     al,MODEL_MASK           ; isolate model info
  3907.         shr     al,MODEL_SHIFT
  3908.         mov     cpuid_model,al
  3909.  
  3910.         and     ax,FAMILY_MASK          ; mask everything but family
  3911.         shr     ax,FAMILY_SHIFT
  3912.         mov     cpuid_type,al
  3913.         mov     cx,16                   ; move 16 to CX
  3914.         mul     cx                      ; multiply AX by 16
  3915.         mov     dx,ax                   ; set cpu_type with family
  3916.  
  3917. finishpop:
  3918.         mov     ax, dx                  ; get return value
  3919.  
  3920.         ;;popfd                         ; restore extended flags
  3921.         MPOPFD
  3922.  
  3923.  
  3924.   ; restore processor instructions allowed
  3925.  
  3926.         ifdef SVGAUTIL
  3927.            .286
  3928.         else ;/* SVGAUTIL */
  3929.            .386p
  3930.         endif ;/* SVGAUTIL */
  3931.  
  3932.  
  3933.         mov     dx,ax                   ; 
  3934.         jmp     short IdentifyCPUdone
  3935.  
  3936. is_80286:
  3937.         mov     dx,PROC80286            ; point to processor id string
  3938.         jmp     short IdentifyCPUdone
  3939.  
  3940. is_0_1:
  3941.         push    cx                      ; save CX for test of shift
  3942.         mov     ax,0ffffh               ; set all AX bits
  3943.         mov     cl,33                   ; will shift only once on 80186
  3944.         shl     ax,cl                   ;  or 33 times on 8086
  3945.         pop     cx                      ; restore CX
  3946.         jnz     is_80186                ; non-zero means 80186
  3947.  
  3948. is_8086:
  3949. ; Is it an 8086?
  3950. ; Returns ax == 0 for 8088, ax == 1 for 8086
  3951. ; Code takes advantage of the 8088's 4-byte prefetch queues and 8086's
  3952. ; 6-byte prefetch queues. By self-modifying the code at location exactly
  3953. ; 5 bytes away from IP, and determining if the modification took effect,
  3954. ; you can differentiate between 8088s and 8086s.
  3955. ; Note this code was taken from Dr. Dobb's Journal, June 1993.
  3956.         mov     ax,cs                   ; ES == code segment
  3957.         mov     es,ax
  3958.  
  3959.         std                             ; cause stosb to count backwards
  3960.  
  3961.         mov     dx,1                    ; DX is flag and we'll start at 1
  3962.         mov     di,OFFSET IdentifyCPUEndLabel      ; DI == offset of code tail to modify
  3963.         mov     al,090h                 ; AL == nop instruction opcode
  3964.         mov     cx,3                    ; set for 3 repetitions
  3965.         REP     stosb                   ; store the bytes
  3966.  
  3967.         cld                             ; clear the direction flag
  3968.         nop                             ; three nops in a row
  3969.         nop                             ; provide dummy instructions
  3970.         nop
  3971.         dec     dx                      ; decrement flag (only with 8088)
  3972.         nop                             ; dummy instruction--6 bytes
  3973. IdentifyCPUEndLabel:
  3974.         nop
  3975.  
  3976.         mov     ax,dx                   ; get value in AX
  3977.         mov     dx,PROC8088             ; indicate 8088
  3978.         cmp     ax,0                    ; if AX == 0 then we have a 8088
  3979.         jz      is_8086_done            ; otherwise we have a 8086
  3980.         mov     dx,PROC8086             ; indicate 8086
  3981.  
  3982. is_8086_done:
  3983.         jmp     short IdentifyCPUdone
  3984.  
  3985. is_80186:
  3986.         mov     dx,PROC8018x
  3987.  
  3988. IdentifyCPUdone:
  3989.         popf                            ; restore original flags
  3990.         mov     ax,dx                   ; put processor type into AX
  3991.         pop     bx
  3992.         pop     cx
  3993.         pop     dx
  3994.         pop     ds
  3995.         leave
  3996.         ret
  3997.  
  3998. IdentifyCPU   ENDP                ; JWK22
  3999.  
  4000.  
  4001. _IdentifyCPU   PROC    far          ;JWK22
  4002.                PUBLIC  _IdentifyCPU
  4003.  
  4004.         call IdentifyCPU
  4005.         ret
  4006.  
  4007. _IdentifyCPU   ENDP                ; JWK22
  4008.  
  4009.  
  4010. ;/****************************************************************************
  4011. ;*
  4012. ;* FUNCTION NAME = TsengGetVRAMSize                     /*          */
  4013. ;*                                   ;;JWK07 replace entire routine to use
  4014. ;*                                   ;;      iodelay, correct unlock, use write to flush cache
  4015. ;*                                   ;;      needed for PCI and VLB
  4016. ;* DESCRIPTION   = Determine how much VRAM is installed by read/write of VRAM
  4017. ;*
  4018. ;* INPUT         = AX = chiptype
  4019. ;*                 DX = CRTC index (3c4 or 3b4)
  4020. ;* OUTPUT        = AX = number of VRAM 64k blocks
  4021. ;*                      all other registers restored
  4022. ;* RETURN-NORMAL = AX = number of VRAM 64k blocks
  4023. ;* RETURN-ERROR  = AX = 0
  4024. ;*
  4025. ;* CALLED BY     WhichTseng
  4026. ;*
  4027. ;* ASSUMPTIONS  1) tseng already 'found'
  4028. ;*              2) extended registers enabled
  4029. ;*
  4030. ;****************************************************************************/
  4031.  
  4032. TTESTA  equ 00000h
  4033. TTESTB  equ 0aaaah
  4034. TTESTC  equ 0f0f0h
  4035. TTESTD  equ 00707h
  4036.  
  4037. WBINVD  MACRO            ; JWK22
  4038.   local skiplabel
  4039.         cmp     Tcpu_id, PROC80486      ; invalid opcode if < 486
  4040.         jl      short skiplabel
  4041.         db      0fh      ; write back and invalidate cache command
  4042.         db      09h      ; 
  4043.   skiplabel:
  4044.         ENDM
  4045.  
  4046. Tsave0              EQU   <WORD PTR [bp-02h]>       ; WORD
  4047. Tsave1              EQU   <WORD PTR [bp-04h]>       ; WORD
  4048. Tsave2              EQU   <WORD PTR [bp-06h]>       ; WORD
  4049. Tsave3              EQU   <WORD PTR [bp-08h]>       ; WORD
  4050. Ttest0              EQU   <WORD PTR [bp-0ah]>       ; WORD
  4051. Ttest1              EQU   <WORD PTR [bp-0ch]>       ; WORD
  4052. Ttest2              EQU   <WORD PTR [bp-0eh]>       ; WORD
  4053. Ttest3              EQU   <WORD PTR [bp-10h]>       ; WORD
  4054. Tpeek0              EQU   <WORD PTR [bp-12h]>       ; WORD
  4055. Tpeek1              EQU   <WORD PTR [bp-14h]>       ; WORD
  4056. Tpeek2              EQU   <WORD PTR [bp-16h]>       ; WORD
  4057. Tpeek3              EQU   <WORD PTR [bp-18h]>       ; WORD
  4058. Tchiptype           EQU   <WORD PTR [bp-1ah]>       ; WORD
  4059. TCRTCIndex          EQU   <WORD PTR [bp-1ch]>       ; WORD
  4060. Tseg                EQU   <WORD PTR [bp-1eh]>       ; WORD
  4061. Tseg_3cd            EQU   <WORD PTR [bp-20h]>       ; WORD
  4062. Tseg_3cb            EQU   <WORD PTR [bp-22h]>       ; WORD
  4063. Tcpu_id             EQU   <WORD PTR [bp-24h]>       ; WORD
  4064. Tmap                EQU   <BYTE PTR [bp-26h]>       ; BYTE
  4065. Tsave_3cb           EQU   <BYTE PTR [bp-28h]>       ; BYTE
  4066. Tsave_3cd           EQU   <BYTE PTR [bp-2ah]>       ; BYTE
  4067. TSENGSTACKBLOCK     EQU   2ah
  4068.  
  4069.  
  4070. TsengGetVRAMSize  PROC    Near
  4071.                   PUBLIC  TsengGetVRAMSize
  4072.  
  4073.  
  4074.     enter   TSENGSTACKBLOCK, 0
  4075.  
  4076.     push  si
  4077.     push  bx
  4078.     push  cx
  4079.     push  es
  4080.     push  ds
  4081.  
  4082.     mov Ttest0, TTESTA
  4083.     mov Ttest1, TTESTB
  4084.     mov Ttest2, TTESTC
  4085.     mov Ttest3, TTESTD
  4086.     mov Tchiptype, ax
  4087.     mov TCRTCIndex,dx
  4088.     mov Tseg, 0                     ; preset return value
  4089.     mov Tcpu_id, 0                  ; clear cpu id
  4090.  
  4091.  
  4092.     call  IdentifyCPU               ; get cpu type in AX
  4093.  
  4094.     mov Tcpu_id, ax                 ; save cpu type
  4095.  
  4096.  
  4097.     ; Set the 'key' (ie, unlock)
  4098.     mov    dx, 03bfh
  4099.     mov    al, 03h
  4100.     call   OutpDelay
  4101.     mov    dx, 03b8h
  4102.     mov    al, 0a0h
  4103.     call   OutpDelay
  4104.     mov    dx, 03d8h
  4105.     mov    al, 0a0h
  4106.     call   OutpDelay
  4107.  
  4108.  
  4109. ;   Save the state of the TS GDC and CRTC36 registers so we can restore after
  4110. ;   setting up linear mapping.
  4111. ;
  4112. ;  just push save on stack
  4113.  
  4114.     mov    cx, 1
  4115. SaveTS:
  4116.     mov    dx, 03C4h
  4117.     mov    ax, cx
  4118.     call   OutpIdxInpData
  4119.     push   ax
  4120.     inc    cx
  4121.     cmp    cx, 6
  4122.     jle    SaveTS
  4123.  
  4124.     mov    cx, 0
  4125. SaveGDC:
  4126.     mov    dx, 03CEh
  4127.     mov    ax, cx
  4128.     call   OutpIdxInpData
  4129.     push   ax
  4130.     inc    cx
  4131.     cmp    cx, 8
  4132.     jle    SaveGDC
  4133.  
  4134. SaveCRTC36:
  4135.     mov    dx, 03D4h
  4136.     mov    ax, 036h
  4137.     call   OutpIdxInpData
  4138.     push   ax
  4139. SaveCRTC34:
  4140.     mov    dx, 03D4h
  4141.     mov    ax, 034h
  4142.     call   OutpIdxInpData
  4143.     push   ax
  4144.  
  4145.  
  4146. ;   Set up for linear access.
  4147. ;   Enable writes to all planes.
  4148.  
  4149.     mov   dx, 03C4h
  4150.     mov   al, 02h
  4151.     call  OutpIdxInpData ;;out   dx, al
  4152.      or   al, 0fh
  4153.     inc   dx
  4154.     call  OutpDelay ;;out   dx, al
  4155.  
  4156.  
  4157. ;   blank the screen to enable fast host VRAM access
  4158.  
  4159.     mov   dx, 03C4h
  4160.     mov   al, 01h
  4161.     call  OutpIdxInpData
  4162.     or    al, 20h
  4163.     inc   dx
  4164.     call  OutpDelay
  4165.  
  4166.  
  4167. ;   set write plane mask for all planes
  4168.  
  4169.     mov   dx, 03C4h
  4170.     mov   al, 02h
  4171.     call  OutpIdxInpData
  4172.      or   al, 0fh
  4173.     inc   dx
  4174.     call  OutpDelay
  4175.  
  4176.  
  4177. ;   set Chain 4 mode, disable font selection
  4178.  
  4179.     mov   dx, 03C4h
  4180.     mov   al, 04h
  4181.     call  OutpIdxInpData
  4182.     or    al, 0ch
  4183.     and   al, 0fdh
  4184.     inc   dx
  4185.     call  OutpDelay
  4186.  
  4187. ;   make sure fast r/w disabled
  4188.                                                                   ;JWK11
  4189.     mov   dx, 03C4h                                               ;JWK11
  4190.     mov   al, 06h                                                 ;JWK11
  4191.     call  OutpIdxInpData                                          ;JWK11
  4192.     and   al, 0cfh                ; disable 'early address info'  ;JWK11
  4193.      or   al, 040h                ;  disable zero wait state      ;JWK11
  4194.     inc   dx                                                      ;JWK11
  4195.     call  OutpDelay                                               ;JWK11
  4196.  
  4197. ;   Disable set/reset
  4198.  
  4199.     mov   dx, 03CEh
  4200.     mov   al, 01h
  4201.     call  OutpIdxInpData
  4202.     and   al, 0f0h
  4203.     inc   dx
  4204.     call  OutpDelay
  4205.  
  4206.  
  4207. ;   No rop or rotate.
  4208.  
  4209.     mov   dx, 03CEh
  4210.     mov   al, 03h
  4211.     call  OutpIdxInpData
  4212.     and   al, 0e0h
  4213.     inc   dx
  4214.  
  4215. ;   select plane 0
  4216.  
  4217.     mov   dx, 03CEh
  4218.     mov   al, 04h
  4219.     call  OutpIdxInpData
  4220.     and   al, 0fch
  4221.     inc   dx
  4222.     call  OutpDelay
  4223.  
  4224. ;   Normal read/write modes
  4225.  
  4226.     mov   dx, 03CEh
  4227.     mov   al, 05h
  4228.     call  OutpIdxInpData
  4229.     and   al, 0e4h
  4230.     inc   dx
  4231.     call  OutpDelay
  4232.  
  4233.  
  4234.  
  4235. ;   disable PCI Memory Burst
  4236.  
  4237.     mov   dx, 03D4h         ;jwk11
  4238.     mov   al, 34h           ;jwk11
  4239.     call  OutpIdxInpData    ;jwk11
  4240.     and   al, 0efh          ;jwk11
  4241.     inc   dx                ;jwk11
  4242.     call  OutpDelay         ;jwk11
  4243.  
  4244. ;   disable MMU and linear flat addressing
  4245.  
  4246.     mov   dx, 03D4h
  4247.     mov   al, 36h
  4248.     call  OutpIdxInpData
  4249.     and   al, 0c7h          ;jwk11 was c3 WRONG
  4250.     inc   dx
  4251.     call  OutpDelay
  4252.  
  4253.  
  4254. ;   Use existing mapping
  4255. ;   Disable odd/even
  4256.  
  4257.     mov   dx, 03CEh
  4258.     mov   al, 06h
  4259.     call  OutpIdxInpData
  4260.     mov   Tmap, al
  4261.     and   al, 0fdh
  4262.     inc   dx
  4263.     call  OutpDelay
  4264.  
  4265.  
  4266. ;   Enable all bits
  4267.  
  4268.     mov   dx, 03CEh
  4269.     mov   al, 08h
  4270.     call  OutpIdxInpData
  4271.     mov   al, 0ffh
  4272.     inc   dx
  4273.     call  OutpDelay
  4274.  
  4275.  
  4276. ;   Address where the VGA memory happens to be mapped
  4277.  
  4278.     mov  al, Tmap
  4279.     shr  al, 2
  4280.     and  al, 03h
  4281.  
  4282.     cmp  al, 03h
  4283.     jnz  @f
  4284.     mov  ax, 000Bh
  4285.     mov  bx, 8000h
  4286.     jmp  SHORT BreakMapSwitch
  4287. @@:
  4288.     cmp  al, 02
  4289.     jnz  @f
  4290.     mov  ax, 000Bh
  4291.     mov  bx, 0000h
  4292.     jmp SHORT BreakMapSwitch
  4293. @@:                                     ;; must be 0 or 1
  4294.     mov  ax, 000Ah
  4295.     mov  bx, 0000h
  4296.  
  4297. BreakMapSwitch:
  4298.  
  4299.     mov cx, 16*1024    ; request 16k memory
  4300.  
  4301.     push    ds
  4302.     pop     es
  4303.     ASSUME  DS:NOTHING, ES:DGROUP
  4304.  
  4305.     push    ds                      ;save values for unphystovirt
  4306.     push    ax                      ;save values for unphystovirt
  4307.     push    bx
  4308.     push    cx
  4309.     call    SVGAPhysToVirt          ;Get virtual address into DS:SI.
  4310.     jnc     @f
  4311.     jmp     breaktestloop
  4312. @@:
  4313.  
  4314.  
  4315. ;   Save the GDC segment select registers
  4316.  
  4317.     mov  dx, 03CBh
  4318.     in   al, dx
  4319.     mov  Tsave_3cb, al
  4320.     mov  dx, 03CDh
  4321.     in   al, dx
  4322.     mov  Tsave_3cd, al
  4323.  
  4324. ;   Select the first segment and save what we find there
  4325.  
  4326.     ;flush cach
  4327.     WBINVD            ;WBINVD write-back and invalidate cach
  4328.  
  4329.     xor  al, al
  4330.     mov  dx, 03CBh
  4331.     call OutpDelay
  4332.     mov  dx, 03CDh
  4333.     xor  al, al
  4334.     call OutpDelay
  4335.  
  4336.  
  4337.     ;flush cach
  4338.     WBINVD            ;WBINVD write-back and invalidate cach   ;JWK22
  4339.  
  4340.  
  4341. ;   force fifo empty read                       ;JWK08
  4342. ;   force fifo empty read                       ;JWK08
  4343.                                                 ;JWK08
  4344.         push  cx                                ;JWK08
  4345.                                                 ;JWK08
  4346.         mov   cx, 512                           ;JWK08
  4347.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4348.    loopa1:                                      ;JWK08
  4349.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4350.         add   bx, 2                             ;JWK08
  4351.         loop  loopa1                            ;JWK08
  4352.                                                 ;JWK08
  4353.                                                 ;JWK08
  4354.         pop   cx                                ;JWK08
  4355.                                                 ;JWK08
  4356.  
  4357. ; read inital values to be restored later
  4358.  
  4359.     mov  ax, WORD PTR ds:[si+0]
  4360.     mov  Tsave0, ax
  4361.     mov  ax, WORD PTR ds:[si+2]
  4362.     mov  Tsave1, ax
  4363.     mov  ax, WORD PTR ds:[si+4]
  4364.     mov  Tsave2, ax
  4365.     mov  ax, WORD PTR ds:[si+6]
  4366.     mov  Tsave3, ax
  4367.  
  4368. ;   set the initial values of the first segment
  4369. ;   these should not change unless a wrap occurred
  4370.  
  4371.     mov ax, Ttest0
  4372.     mov WORD PTR ds:[si+0], ax
  4373.     mov ax, Ttest1
  4374.     mov WORD PTR ds:[si+2], ax
  4375.     mov ax, Ttest2
  4376.     mov WORD PTR ds:[si+4], ax
  4377.     mov ax, Ttest3
  4378.     mov WORD PTR ds:[si+6], ax
  4379.  
  4380.     ;flush cach
  4381.     WBINVD            ;WBINVD write-back and invalidate cach   ;JWK22
  4382.  
  4383.  
  4384. ;   force fifo empty read                       ;JWK08
  4385.                                                 ;JWK08
  4386.         push  cx                                ;JWK08
  4387.                                                 ;JWK08
  4388.         mov   cx, 512                           ;JWK08
  4389.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4390.    loopb1:                                      ;JWK08
  4391.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4392.         add   bx, 2                             ;JWK08
  4393.         loop  loopb1                            ;JWK08
  4394.                                                 ;JWK08
  4395.                                                 ;JWK08
  4396.         pop   cx                                ;JWK08
  4397.  
  4398.  
  4399.  
  4400. ;   Probe memory in 128k increments
  4401.  
  4402.     xor    cx, cx
  4403. ForSegLoop:
  4404.  
  4405. ;
  4406. ;   Construct the GDC segment selector values for the segment
  4407. ;       seg_3cd = seg & 0x0F;
  4408. ;       seg_3cd |= seg_3cd << 4;
  4409. ;       seg_3cb = seg & 0x30;
  4410. ;       seg_3cb |= seg_3cb >> 4;
  4411.  
  4412.    mov  bx, cx                    ; cx has current segment
  4413.    and  bx, 0fh
  4414.    mov  ax, bx
  4415.    shl  bx, 4
  4416.    or   ax, bx
  4417.    mov  Tseg_3cd, ax
  4418.  
  4419.    mov  bx, cx
  4420.    and  bx, 30h
  4421.    mov  ax, bx
  4422.    shr  bx, 4
  4423.    or   ax, bx
  4424.    mov  Tseg_3cb, ax
  4425.  
  4426.  
  4427.     ;flush cach
  4428.     WBINVD            ;WBINVD write-back and invalidate cach   ;JWK22
  4429.  
  4430.  
  4431. ;   force fifo empty read                       ;JWK08
  4432.                                                 ;JWK08
  4433.         push  cx                                ;JWK08
  4434.                                                 ;JWK08
  4435.         mov   cx, 512                           ;JWK08
  4436.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4437.    loopc1:                                      ;JWK08
  4438.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4439.         add   bx, 2                             ;JWK08
  4440.         loop  loopc1                            ;JWK08
  4441.                                                 ;JWK08
  4442.                                                 ;JWK08
  4443.         pop   cx                                ;JWK08
  4444.  
  4445. ;  Select the 64k segment to test
  4446.  
  4447.    mov  dx, 03CDh
  4448.    mov  ax, Tseg_3cd
  4449.    call OutpDelay
  4450.  
  4451.    mov  dx, 03CBh
  4452.    mov  ax, Tseg_3cb
  4453.    call OutpDelay
  4454.  
  4455.     ;flush cach
  4456.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4457.  
  4458.  
  4459. ;   force fifo empty read                       ;JWK08
  4460.                                                 ;JWK08
  4461.         push  cx                                ;JWK08
  4462.                                                 ;JWK08
  4463.         mov   cx, 512                           ;JWK08
  4464.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4465.    loopd1:                                      ;JWK08
  4466.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4467.         add   bx, 2                             ;JWK08
  4468.         loop  loopd1                            ;JWK08
  4469.                                                 ;JWK08
  4470.                                                 ;JWK08
  4471.         pop   cx                                ;JWK08
  4472.                                              ;JWK08
  4473.                                              ;JWK08
  4474. ; read current VRAM values so we can restore
  4475.  
  4476.    mov ax, WORD PTR ds:[si+0]
  4477.    mov Tpeek0, ax
  4478.    mov ax, WORD PTR ds:[si+2]
  4479.    mov Tpeek1, ax
  4480.    mov ax, WORD PTR ds:[si+4]
  4481.    mov Tpeek2, ax
  4482.    mov ax, WORD PTR ds:[si+6]
  4483.    mov Tpeek3, ax
  4484.  
  4485.  
  4486. ;  Write the test values
  4487.  
  4488.    mov ax, Ttest0
  4489.    mov WORD PTR ds:[si+0], ax
  4490.    mov ax, Ttest1
  4491.    mov WORD PTR ds:[si+2], ax
  4492.    mov ax, Ttest2
  4493.    mov WORD PTR ds:[si+4], ax
  4494.    mov ax, Ttest3
  4495.    mov WORD PTR ds:[si+6], ax
  4496.  
  4497.     ;flush cach
  4498.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4499.  
  4500.  
  4501. ;   force fifo empty read                       ;JWK08
  4502.                                                 ;JWK08
  4503.         push  cx                                ;JWK08
  4504.                                                 ;JWK08
  4505.         mov   cx, 512                           ;JWK08
  4506.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4507.    loope1:                                      ;JWK08
  4508.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4509.         add   bx, 2                             ;JWK08
  4510.         loop  loope1                            ;JWK08
  4511.                                                 ;JWK08
  4512.                                                 ;JWK08
  4513.         pop   cx                                ;JWK08
  4514.  
  4515.  
  4516. ;  Make sure data in segment 0 is still valid (no wrap)
  4517.  
  4518.     xor  al, al
  4519.     mov  dx, 03CBh
  4520.     call OutpDelay
  4521.     mov  dx, 03CDh
  4522.     xor  al, al
  4523.     call OutpDelay
  4524.  
  4525.     ;flush cach
  4526.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4527.  
  4528.  
  4529. ;   force fifo empty read                       ;JWK08
  4530.                                                 ;JWK08
  4531.         push  cx                                ;JWK08
  4532.                                                 ;JWK08
  4533.         mov   cx, 512                           ;JWK08
  4534.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4535.    loopf1:                                      ;JWK08
  4536.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4537.         add   bx, 2                             ;JWK08
  4538.         loop  loopf1                            ;JWK08
  4539.                                                 ;JWK08
  4540.                                                 ;JWK08
  4541.         pop   cx                                ;JWK08
  4542.  
  4543. ;  check test values
  4544.  
  4545.    mov ax, WORD PTR ds:[si+0]
  4546.    cmp ax, TTESTA
  4547.    jz  @f
  4548.    jmp  breaktestloop
  4549. @@:
  4550.    mov ax, WORD PTR ds:[si+2]
  4551.    cmp ax, TTESTB
  4552.    jz  @f
  4553.    jmp  breaktestloop
  4554. @@:
  4555.    mov ax, WORD PTR ds:[si+4]
  4556.    cmp ax, TTESTC
  4557.    jz  @f
  4558.    jmp breaktestloop                    ;short fails on screendd
  4559. @@:
  4560.    mov ax, WORD PTR ds:[si+6]
  4561.    cmp ax, TTESTD
  4562.    jz  @f
  4563.    jmp breaktestloop                    ;short fails on screendd
  4564. @@:
  4565.  
  4566.  
  4567. ;  Try to read back the test values in the test segment
  4568.  
  4569.     ;flush cach
  4570.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4571.  
  4572.  
  4573. ;   force fifo empty read                       ;JWK08
  4574.                                                 ;JWK08
  4575.         push  cx                                ;JWK08
  4576.                                                 ;JWK08
  4577.         mov   cx, 512                           ;JWK08
  4578.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4579.    loopg1:                                      ;JWK08
  4580.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4581.         add   bx, 2                             ;JWK08
  4582.         loop  loopg1                            ;JWK08
  4583.                                                 ;JWK08
  4584.                                                 ;JWK08
  4585.         pop   cx                                ;JWK08
  4586.  
  4587.    mov  dx, 03CDh
  4588.    mov  ax, Tseg_3cd
  4589.    ;;out  dx, al
  4590.    call OutpDelay
  4591.  
  4592.    mov  dx, 03CBh
  4593.    mov  ax, Tseg_3cb
  4594.    ;;out  dx, al
  4595.    call OutpDelay
  4596.  
  4597.     ;flush cach
  4598.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4599.  
  4600.  
  4601. ;   force fifo empty read                       ;JWK08
  4602.                                                 ;JWK08
  4603.         push  cx                                ;JWK08
  4604.                                                 ;JWK08
  4605.         mov   cx, 512                           ;JWK08
  4606.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4607.    looph1:                                      ;JWK08
  4608.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4609.         add   bx, 2                             ;JWK08
  4610.         loop  looph1                            ;JWK08
  4611.                                                 ;JWK08
  4612.                                                 ;JWK08
  4613.         pop   cx                                ;JWK08
  4614.  
  4615. ;  test the new values (end if not same as written)
  4616.  
  4617.    mov ax, WORD PTR ds:[si+0]
  4618.    cmp ax, Ttest0
  4619.    jnz  breaktestloop
  4620.    mov ax, WORD PTR ds:[si+2]
  4621.    cmp ax, Ttest1
  4622.    jnz  breaktestloop
  4623.  
  4624.    mov ax, WORD PTR ds:[si+4]
  4625.    cmp ax, Ttest2
  4626.    jnz  breaktestloop
  4627.    mov ax, WORD PTR ds:[si+6]
  4628.    cmp ax, Ttest3
  4629.    jnz  breaktestloop
  4630.  
  4631.  
  4632. ; restore peeked values since we altered them
  4633.  
  4634.    mov ax, Tpeek0
  4635.    mov WORD PTR ds:[si+0], ax
  4636.    mov ax, Tpeek1
  4637.    mov WORD PTR ds:[si+2], ax
  4638.    mov ax, Tpeek2
  4639.    mov WORD PTR ds:[si+4], ax
  4640.    mov ax, Tpeek3
  4641.    mov WORD PTR ds:[si+6], ax
  4642.  
  4643.     ;flush cach
  4644.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4645.  
  4646.  
  4647. ;   force fifo empty read                       ;JWK08
  4648.                                                 ;JWK08
  4649.         push  cx                                ;JWK08
  4650.                                                 ;JWK08
  4651.         mov   cx, 512                           ;JWK08
  4652.         mov   bx, 100  ;offset 100 bytes so we flush 'elsewhere'
  4653.    loopi1:                                      ;JWK08
  4654.         mov   ax, WORD PTR ds:[si+bx]           ;JWK08
  4655.         add   bx, 2                             ;JWK08
  4656.         loop  loopi1                            ;JWK08
  4657.                                                 ;JWK08
  4658.                                                 ;JWK08
  4659.         pop   cx                                ;JWK08
  4660.  
  4661. ;  Use a new test pattern for the next location.
  4662.  
  4663.  
  4664.    mov ax, Ttest2
  4665.    add ax, 03h
  4666.    mov Ttest2, ax
  4667.  
  4668.    mov ax, Ttest3
  4669.    add ax, 07h
  4670.    mov Ttest3, ax
  4671.  
  4672.    add  cx, 4                  ; 256k increments
  4673.    mov Ttest0, cx              ; low order word = segment number
  4674.    mov   Tseg, cx              ; update successful block count
  4675.  
  4676.    cmp  cx, 64                 ; support up to 4 meg
  4677.    jg   @f
  4678.    jmp  ForSegLoop
  4679. @@:
  4680. breaktestloop:                  ; seg has last valid value
  4681.  
  4682. ;  Restore the values in the first segment
  4683.  
  4684.     ;flush cach
  4685.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4686.  
  4687.     xor  al ,al
  4688.     mov  dx, 03CBh
  4689.     call OutpDelay
  4690.     xor  al ,al
  4691.     mov  dx, 03CDh
  4692.     call OutpDelay
  4693.  
  4694.  
  4695.     mov  ax, Tsave0
  4696.     mov  WORD ptr ds:[si+0], ax
  4697.     mov  ax, Tsave1
  4698.     mov  WORD ptr ds:[si+2], ax
  4699.     mov  ax, Tsave2
  4700.     mov  WORD ptr ds:[si+4], ax
  4701.     mov  ax, Tsave3
  4702.     mov  WORD ptr ds:[si+6], ax
  4703.  
  4704.     ;flush cach
  4705.     WBINVD            ;WBINVD write-back and invalidate cach  ;JWK22
  4706.  
  4707.  
  4708. ;   Restore the segment selector values
  4709.  
  4710.     mov  dx, 03CBh
  4711.     mov  al, Tsave_3cb
  4712.     ;;out  dx, al
  4713.     call OutpDelay
  4714.     mov  dx, 03CDh
  4715.     mov  al, Tsave_3cd
  4716.     ;;out  dx, al
  4717.     call OutpDelay
  4718.  
  4719.     pop     cx                      ; restore virttophys registers
  4720.     pop     bx
  4721.     pop     ax
  4722.     pop     ds
  4723.     ASSUME  DS:DGROUP, ES:NOTHING
  4724.  
  4725.     call    SVGAUnPhysToVirt        ;Unmap AX:BX.
  4726.  
  4727.  
  4728. ;   Restore CR0
  4729. ;   pop  eax
  4730. ;   mov  CR0, eax
  4731.  
  4732.  
  4733. ;   Restore the state of the TS CRTC36 and GDC registers
  4734. ;   just pop off the stack and write in reverse order of how we saved
  4735.  
  4736.  
  4737. RestoreCRTC34:
  4738.     mov    dx, 03D4h
  4739.     mov    ax, 034h
  4740.     call   OutpDelay
  4741.     pop    ax
  4742.     inc    dx
  4743.     call   OutpDelay
  4744.  
  4745. RestoreCRTC36:
  4746.     mov    dx, 03D4h
  4747.     mov    ax, 036h
  4748.     call   OutpDelay
  4749.     pop    ax
  4750.     inc    dx
  4751.     call   OutpDelay
  4752.  
  4753.     mov    cx, 8
  4754. RestoreGDC:
  4755.     mov    dx, 03CEh
  4756.     mov    ax, cx
  4757.     ;;out    dx, al
  4758.     call OutpDelay
  4759.     pop    ax
  4760.     ;;out    dx, al
  4761.     inc    dx
  4762.     call OutpDelay
  4763.     dec    cx
  4764.     cmp    cx, 0
  4765.     jge    RestoreGDC
  4766.  
  4767.     mov    cx, 6
  4768. RestoreTS:
  4769.     mov    dx, 03C4h
  4770.     mov    ax, cx
  4771.     ;;out    dx, al
  4772.     call OutpDelay
  4773.     pop    ax
  4774.     ;;out    dx, al
  4775.     inc    dx
  4776.     call OutpDelay
  4777.     dec    cx
  4778.     cmp    cx, 1
  4779.     jge    RestoreTS
  4780.  
  4781. ;   Return the size based on the last segment write/read passed
  4782.  
  4783.     mov  ax, Tseg
  4784.  
  4785. ;   Restore calling register values
  4786.  
  4787.     pop  ds
  4788.     pop  es
  4789.     pop  cx
  4790.     pop  bx
  4791.     pop  si
  4792.  
  4793.     leave
  4794.     ret
  4795.  
  4796.  
  4797. TsengGetVRAMSize  ENDP
  4798.  
  4799.  
  4800. ;/****************************************************************************
  4801. ;*
  4802. ;* FUNCTION NAME = WhichTseng
  4803. ;*
  4804. ;* DESCRIPTION   = Determine which Tseng chip we're using ET3000/ET4000
  4805. ;*                 Distinguish the two by availability of Extended Start Addr.
  4806. ;*                 Register (CRTC index 33h) which only exists on ET4000.
  4807. ;*
  4808. ;* INPUT         = NONE
  4809. ;* OUTPUT        = NONE
  4810. ;*
  4811. ;* RETURN-NORMAL = NONE
  4812. ;* RETURN-ERROR  = NONE
  4813. ;*
  4814. ;* CALLED BY
  4815. ;*
  4816. ;****************************************************************************/
  4817.  
  4818. ;!! Actually, this should be 0210ah + IOD<2:0>*010h:
  4819. TSENG_CRTCB_ADDRESS     equ     0217ah  ;Index port for W32 CRTCB regs
  4820. TSENG_CRTCB_ROW_OFF_HI  equ     0ech    ;CRTCB/Sprite Row Offset High Reg
  4821.  
  4822. WhichTseng      PROC    Near
  4823.                 PUBLIC  WhichTseng
  4824.  
  4825.         enter   STACKBLOCK, 0           ;                       /*          */
  4826.         call    TsengEnableExt          ;enable extended regs   /*          */
  4827.         call    GetCrtcBase             ;(3d4)                  /*          */
  4828. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  4829. ;       mov     bx, dx                  ;keep copy              /*          */
  4830.         mov     al, 037h                ;Video System Config 2
  4831.         call    OutpIdxInpData          ;Read indexed reg       /*          */
  4832. ;                                       ;Can determine mem size /*          */
  4833. ;                                       ;only AFTER know chip   /*          */
  4834.         mov     bl, al                  ;Save memory config     /*          */
  4835.         mov     al, 033h                ;CRTC reg index 33h
  4836.         call    OutpDelay               ;Write the new index value.
  4837.         inc     dx                      ;Point to the data register.
  4838.         mov     al, 0ffh                ;All bits first.        /*          */
  4839.         call    SaveXORChk              ;Test for read/writable./*          */
  4840.         .if     < z >                   ;If read/writable:      /*          */
  4841.             mov     dx, TSENG_CRTCB_ADDRESS ;                   /*          */
  4842.             call    GetSave1            ;                       /*          */
  4843.             mov     al, TSENG_CRTCB_ROW_OFF_HI  ;               /*          */
  4844.             call    OutpIdxInpData      ;                       /*          */
  4845.             and     al, 0f0h            ;Extract Chip revision  /*          */
  4846.             .if     < z >               ;                       /*          */
  4847.                 mov     ax, TSENG_ET4000W32_CHIP   ;            /*          */
  4848.             .elseif     <al eq 010h>,short ;                    /*          */
  4849.                 mov     ax, TSENG_ET4000W32I_CHIP  ;            /*          */
  4850.             .elseif     <al eq 020h>,short ;                    /*          */
  4851.                 mov     ax, TSENG_ET4000W32PA_CHIP ;            /*          */
  4852.             .elseif     <al eq 030h>,short ;                    /*          */
  4853.                 mov     ax, TSENG_ET4000W32IB_CHIP ;            /*          */
  4854.             .elseif     <al eq 050h>,short ;                    /*          */
  4855.                 mov     ax, TSENG_ET4000W32PB_CHIP ;            /*          */
  4856.             .elseif     <al eq 060h>,short ;                    /*          */
  4857.                 mov     ax, TSENG_ET4000W32PD_CHIP ;            /*          */
  4858.             .elseif     <al eq 070h>,short ;                    /*          */
  4859.                 mov     ax, TSENG_ET4000W32PC_CHIP ;            /*          */
  4860.             .elseif     <al eq 0B0h>,short ;                    /*          */
  4861.                 mov     ax, TSENG_ET4000W32IC_CHIP ;            /*          */
  4862.             .else                   ,short ;                    /*          */
  4863. ;;JWK23 Tseng has assured us that there will be no new W32I chips
  4864. ;;JWK23 and that all future revisions will be W32P Rev C compatable.
  4865. ;;JWK23 Handle Unknown chips as W32Pc.  No need to identify new revisions
  4866. ;;JWK23 accept to support some new function.
  4867. ;;JWK23
  4868. ;;JWK23         mov     ax, UNKNOWN_CHIP;             JWK07     /*          */
  4869.                 mov     ax, TSENG_ET4000W32PX_CHIP;   JWK23
  4870.             .endif                      ;                       /*          */
  4871.             call    RestoreSave1        ;                       /*          */
  4872.         .else                           ;                       /*          */
  4873.             mov     al, 00fh            ;Low 4 bits next.       /*          */
  4874.             call    SaveXORChk          ;Test for read/writable./*          */
  4875.             .if     < z >               ;If read/writable:      /*          */
  4876.                 mov ax, TSENG_ET4000_CHIP ;                     /*          */
  4877.             .else                       ;                       /*          */
  4878.                 mov ax, TSENG_ET3000_CHIP ;                     /*          */
  4879. WT3000:                                 ; 
  4880.                 pushf                   ; 
  4881.                 push    ax              ; 
  4882.                 mov     al, 6           ;set up index port to zoom reg
  4883.                 mov     dl, 0c4h        ;SEQ index address (3c4)/*          */
  4884.                 call    OutpIdxInpData  ;Read indexed reg       /*          */
  4885.                 and     al, 01111111B   ; 
  4886.                 call    OutpData        ;Turn off zoom enable bit.
  4887.                 pop     ax              ; 
  4888.                 popf                    ; 
  4889.             .endif                      ;                       /*          */
  4890.         .endif                          ;                       /*          */
  4891. WTExit:                                 ; 
  4892. ;                                       ;Can determine mem size /*          */
  4893. ;                                       ;only AFTER know chip   /*          */
  4894.  
  4895.         push  ax                                          ;     /*          */
  4896.         call TsengGetVRAMSize           ;Try VRAM Search  ;     /*          */
  4897.         .if <ax ne 0>                   ;if value, use it ;     /*          */
  4898.             mov     word ptr [_sSVGA.Memory][word], ax    ;     /*          */
  4899.             pop     ax                                    ;     /*          */
  4900.         .else                           ;else try old method    /*          */
  4901.             pop     ax                                    ;     /*          */
  4902.             .if <ax b TSENG_ET4000W32_CHIP> ;ET4000/3000            /*          */
  4903.                 test    bl, 081h            ;VRAM=1/DRAM=0 :7,1M :0./*          */
  4904.                 .if     < z >               ;If can determine memory/*          */
  4905. ;                                           ;Adjust mem to 512k     /*          */
  4906.                     shr     word ptr [_sSVGA.Memory][word], 1 ;     /*          */
  4907.                 .endif                      ;                       /*          */
  4908.             .elseif < e >                   ;ET4000W32              /*          */
  4909.                 test    bl, 001h            ;No VRAM/DRAM bit       /*          */
  4910.                 .if < z >                   ;Bus width?             /*          */
  4911. ;                                           ;Adjust mem to 512k     /*          */
  4912.                     shr     word ptr [_sSVGA.Memory][word], 1 ;     /*          */
  4913.                 .endif                                              /*@V2.1JWK01*/
  4914.             .else                           ;< a > ET4000W32I/W32P  /*          */
  4915.                 test    bl, 008h            ;Ram length 1M or 256K  /*          */
  4916.                 .if < z >                   ;If 1M:                 /*          */
  4917.                     shl  word ptr [_sSVGA.Memory][word], 001h ;     /*          */
  4918.                 .endif                      ;                       /*          */
  4919.                 test    bl, 001h            ;Bus width 16 or 32?    /*          */
  4920.                 .if < nz >                  ;If 32:                 /*          */
  4921.                     shl  word ptr [_sSVGA.Memory][word], 001h ;     /*          */
  4922.                 .endif                      ;                       /*          */
  4923.             .endif                          ; 
  4924.         .endif                              ;end if ax          /*          */
  4925.         call    TsengDisableExt         ;disable extended regs  /*          */
  4926.         leave                           ;                       /*          */
  4927.         ret
  4928.  
  4929. WhichTseng      ENDP
  4930.  
  4931. ;/****************************************************************************
  4932. ;*
  4933. ;* FUNCTION NAME = WhichVideo7
  4934. ;*
  4935. ;* DESCRIPTION   =
  4936. ;*     Determine which chip we're using
  4937. ;*
  4938. ;*     Chip Revision Register contents
  4939. ;*             HT205   71H                     up to 800x600x16
  4940. ;*             HT208   42H     0111xxxxB       up to 1024x768x16
  4941. ;*             HT209   52H/51H 0101xxxxB       up to 1024x768x256 (1Meg memory)
  4942. ;*
  4943. ;*     Determining amount of video memory on Video7 adapter.
  4944. ;*     Requires the folllowing procedure:
  4945. ;*
  4946. ;*             o Set card into a planar mode.
  4947. ;*             o Ensure all planes enabled
  4948. ;*             o Force card into 32-bit memory width (ext reg 0xcc)
  4949. ;*             o Write pattern to %%A0000 (say 5Ah)
  4950. ;*             o Enable read from plane 3 (reg 03ceh)
  4951. ;*             o Read back value
  4952. ;*             o If value is same, we have 1Meg Memory
  4953. ;*             o Otherwise set 16-bit memory width
  4954. ;*             o Read back same value
  4955. ;*             o If value is same, we have 512k Memory
  4956. ;*             o Otherwise default to 256k
  4957. ;*
  4958. ;* INPUT         = NONE
  4959. ;* OUTPUT        = NONE
  4960. ;*
  4961. ;* RETURN-NORMAL = NONE
  4962. ;* RETURN-ERROR  = NONE
  4963. ;*
  4964. ;* CALLED BY
  4965. ;*
  4966. ;****************************************************************************/
  4967.  
  4968. WhichVideo7     PROC    Near
  4969.                 PUBLIC  WhichVideo7
  4970.  
  4971.         enter   STACKBLOCK, 0           ;                       /*          */
  4972.         mov     al, [SEQ06]             ;Use Video7 lock restore/*          */
  4973. ;       Since bit 0 goes on when unlocked, reread != ea!        /*          */
  4974.         and     al, 001h                ;0=locked, 1=unlocked   /*          */
  4975.         mov     al, 0eah                ;Assume unlocked        /*          */
  4976.         .if     < z >                                           /*@V2.1MNH21*/
  4977.             mov     al, 0aeh            ;Locked instead         /*          */
  4978.         .endif                          ;0aeh=lock, 0eah=unlock /*          */
  4979.         mov     [SEQ06], al             ;Instead of value read  /*          */
  4980.         call    Video7EnableExt         ;enable extended registers
  4981.         mov     al, 08eh                ; 
  4982. ;       mov     dl, 0c4h                ;SEQ index address (3c4)/*          */
  4983.         call    OutpIdxInpData          ;Read indexed reg       /*          */
  4984.         shr     al, 4                   ;has value 04h to 0fh
  4985.         mov     bl, al                  ; 
  4986.         mov     ax, VIDEO7_HT205_CHIP   ;AX = 1  (HT205)            label miss.
  4987.         cmp     bl, 7                   ; 
  4988.         je      WhichV7Exit             ; 
  4989.         inc     ax                      ;AX = 2  (HT208)
  4990.         cmp     bl, 4                   ; 
  4991.         je      WhichV7Exit             ; 
  4992.         inc     ax                      ;AX = 3  (HT209)
  4993.         cmp     bl, 5                   ; 
  4994.         je      WhichV7Exit             ; 
  4995. ;       inc     ax                      ;AX = 4  (HT216)        /*          */
  4996. ;       cmp     bl, 6                   ;
  4997. ;       je      WhichV7Exit             ;
  4998.         xor     ax, ax                  ;AX = 0 (don't know)
  4999. WhichV7Exit:
  5000.         mov     dx, 2                   ; 
  5001.         mov     cl, al                  ; 
  5002.         shl     dx, cl                  ; 
  5003.         mov     word ptr [_sSVGA.Memory][1*word], dx ;          /*          */
  5004.         push    ax
  5005.         cmp     al, al                  ;Indicate IS Video7     /*          */
  5006.         call    Video7DisableExt        ;disable extended registers
  5007.         pop     ax
  5008.         leave                           ;                       /*          */
  5009.         ret
  5010.  
  5011. WhichVideo7     ENDP
  5012.  
  5013. ;*                                                              /*          */
  5014. ;/****************************************************************************
  5015. ;*
  5016. ;* FUNCTION NAME = WhichWeitek
  5017. ;*
  5018. ;* DESCRIPTION   = Determine which Weitek SVGA chip we're using.
  5019. ;*
  5020. ;* INPUT         = NONE
  5021. ;* OUTPUT        = NONE
  5022. ;*
  5023. ;* RETURN-NORMAL = NONE
  5024. ;* RETURN-ERROR  = NONE
  5025. ;*
  5026. ;* CALLED BY
  5027. ;*
  5028. ;****************************************************************************/
  5029.  
  5030. WhichWeitek     PROC    Near
  5031.                 PUBLIC  WhichWeitek
  5032.  
  5033.         enter   STACKBLOCK, 0
  5034.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  5035.         call    GetSave1                ;Read original index & save it.
  5036.         mov     al, 007h                ;SEQ W5x86 Revision Reg
  5037.         call    OutpIdxInpData          ;Read W5x86 Revision Reg.
  5038.         shr     al, 5                   ;Get Device ID bits low.
  5039.         and     al, 007h                ;Extract just Device ID bits.
  5040.         .if     < nz > AND
  5041.         .if     <al be 002h>
  5042.             inc     al
  5043.         .else                           ;Else W5086 or unknown W5x86.
  5044.             xor     al, al
  5045.         .endif
  5046.         cbw                             ;Extend to word.
  5047.         call    RestoreSave1            ;Restore the original values.
  5048.         leave
  5049.         ret
  5050.  
  5051. WhichWeitek     ENDP
  5052.  
  5053.  
  5054. ifndef SVGAUTIL
  5055.  
  5056. ;*                                                              /*          */
  5057. ;/****************************************************************************
  5058. ;*
  5059. ;* FUNCTION NAME = WeitekMemConfig
  5060. ;*
  5061. ;* DESCRIPTION   = Set Weitek MemConfig register.
  5062. ;*                      Currently just determine the memory size.
  5063. ;*
  5064. ;* INPUT         = AX = new MemConfig register value.
  5065. ;* OUTPUT        = AX = old MemConfig register value.
  5066. ;*
  5067. ;* RETURN-NORMAL = NONE
  5068. ;* RETURN-ERROR  = NONE
  5069. ;*
  5070. ;* CALLED BY
  5071. ;*
  5072. ;****************************************************************************/
  5073.  
  5074. WeitekMemConfig PROC    Near
  5075.                 PUBLIC  WeitekMemConfig
  5076.  
  5077.         push    es
  5078.         push    bx
  5079.         push    cx
  5080.         push    ax
  5081.         mov     ax, word ptr [SvgaBaseAddr][word] ;Get base address.
  5082.         add     ax, WEITEK_P9000_REGISTERS  ;High word of physical addr.
  5083.         xor     bx, bx                  ;Low word of physical address.
  5084.         mov     cx, WEITEK_P9000_REGLENGTH  ;Length of area selected
  5085.         call    SVGAPhysToUVirt
  5086.         pop     ax                      ;Get back new value.
  5087.         .if     < nc >                  ;If selector returned:
  5088.             xchg    ax, word ptr es:[bx][WEITEK_P9000_MEMCONFIG]
  5089.             call    SVGAUnPhysToUVirt   ;ES=selector to free.
  5090.         .endif                          ;Endif selector returned.
  5091.         pop     cx
  5092.         pop     bx
  5093.         pop     es
  5094.         ret
  5095.  
  5096. WeitekMemConfig ENDP
  5097.  
  5098. ;*                                                              /*          */
  5099. ;/****************************************************************************
  5100. ;*
  5101. ;* FUNCTION NAME = WeitekVRAMMap
  5102. ;*
  5103. ;* DESCRIPTION   = Map first word at selected address.
  5104. ;*
  5105. ;* INPUT         = AX = selected frame buffer offset high bits.
  5106. ;*               = BX = selected frame buffer offset low bits.
  5107. ;* OUTPUT        = ES:BX = pointer to frame buffer word.
  5108. ;*
  5109. ;* RETURN-NORMAL = NC if no errors.
  5110. ;* RETURN-ERROR  = CR if errors.
  5111. ;*
  5112. ;* CALLED BY
  5113. ;*
  5114. ;****************************************************************************/
  5115.  
  5116. WeitekVRAMMap   PROC    Near
  5117.                 PUBLIC  WeitekVRAMMap
  5118.  
  5119.         push    ax                      ;Save offset high.
  5120.         add     ax, word ptr [SvgaBaseAddr][word] ;Get base address.
  5121.         add     ax, WEITEK_P9000_VRAM   ;High word of physical addr.
  5122.         push    cx
  5123.         xor     cx, cx                  ;Whole segment.
  5124.         sub     cx, bx                  ;Less low bits.
  5125.         call    SVGAPhysToUVirt
  5126.         pop     cx
  5127.         pop     ax                      ;Restore offset high.
  5128.         ret
  5129.  
  5130. WeitekVRAMMap    ENDP
  5131.  
  5132. ;*                                                              /*          */
  5133. ;/****************************************************************************
  5134. ;*
  5135. ;* FUNCTION NAME = WeitekGetSelWord
  5136. ;*
  5137. ;* DESCRIPTION   = Get word at selected address.
  5138. ;*
  5139. ;* INPUT         = AX = selected frame buffer offset high bits.
  5140. ;*               = BX = selected frame buffer offset low bits.
  5141. ;* OUTPUT        = DX = word at selected address.
  5142. ;*
  5143. ;* RETURN-NORMAL = NC if no errors.
  5144. ;* RETURN-ERROR  = CR if errors.
  5145. ;*
  5146. ;* CALLED BY
  5147. ;*
  5148. ;****************************************************************************/
  5149.  
  5150. WeitekGetSelWord PROC    Near
  5151.                 PUBLIC  WeitekGetSelWord
  5152.  
  5153.         push    es
  5154.         push    bx
  5155.         call    WeitekVRAMMap           ;Map the word.
  5156.         .if     < nc >                  ;If selector returned:
  5157.             mov     dx, word ptr es:[bx]
  5158.             call    SVGAUnPhysToUVirt   ;ES=selector to free.
  5159.         .endif                          ;Endif selector returned.
  5160.         pop     bx
  5161.         pop     es
  5162.         ret
  5163.  
  5164. WeitekGetSelWord ENDP
  5165.  
  5166. ;*                                                              /*          */
  5167. ;/****************************************************************************
  5168. ;*
  5169. ;* FUNCTION NAME = WeitekSetSelWord
  5170. ;*
  5171. ;* DESCRIPTION   = Set word at selected address.
  5172. ;*
  5173. ;* INPUT         = AX = selected frame buffer offset high bits.
  5174. ;*               = BX = selected frame buffer offset low bits.
  5175. ;*                 DX = word to set at selected address.
  5176. ;* OUTPUT        = NONE
  5177. ;*
  5178. ;* RETURN-NORMAL = NC if no errors.
  5179. ;* RETURN-ERROR  = CR if errors.
  5180. ;*
  5181. ;* CALLED BY
  5182. ;*
  5183. ;****************************************************************************/
  5184.  
  5185. WeitekSetSelWord PROC    Near
  5186.                 PUBLIC  WeitekSetSelWord
  5187.  
  5188.         push    es
  5189.         push    bx
  5190.         call    WeitekVRAMMap           ;Map the word.
  5191.         .if     < nc >                  ;If selector returned:
  5192.             mov     word ptr es:[bx], dx
  5193.             call    SVGAUnPhysToUVirt   ;ES=selector to free.
  5194.         .endif                          ;Endif selector returned.
  5195.         pop     bx
  5196.         pop     es
  5197.         ret
  5198.  
  5199. WeitekSetSelWord ENDP
  5200.  
  5201. ;*                                                              /*          */
  5202. ;/****************************************************************************
  5203. ;*
  5204. ;* FUNCTION NAME = WeitekGet1stWord
  5205. ;*
  5206. ;* DESCRIPTION   = Get first word from frame buffer.
  5207. ;*
  5208. ;* INPUT         = NONE
  5209. ;* OUTPUT        = DX = word at selected address.
  5210. ;*
  5211. ;* RETURN-NORMAL = NC if no errors.
  5212. ;* RETURN-ERROR  = CR if errors.
  5213. ;*
  5214. ;* CALLED BY
  5215. ;*
  5216. ;****************************************************************************/
  5217.  
  5218. WeitekGet1stWord PROC    Near
  5219.                 PUBLIC  WeitekGet1stWord
  5220.  
  5221.         push    ax
  5222.         push    bx
  5223.         xor     ax, ax                  ;Get buffer start selector.
  5224.         xor     bx, bx                  ;Get buffer first word.
  5225.         call    WeitekGetSelWord
  5226.         pop     bx
  5227.         pop     ax
  5228.         ret
  5229.  
  5230. WeitekGet1stWord ENDP
  5231.  
  5232. ;*                                                              /*          */
  5233. ;/****************************************************************************
  5234. ;*
  5235. ;* FUNCTION NAME = WeitekChkSelWord
  5236. ;*
  5237. ;* DESCRIPTION   = Check read/writability of word at selected address.
  5238. ;*
  5239. ;* INPUT         = AX = selected frame buffer offset high bits.
  5240. ;*               = BX = selected frame buffer offset low bits.
  5241. ;* OUTPUT        = NONE
  5242. ;*
  5243. ;* RETURN-NORMAL = (zr if reads match writes)
  5244. ;* RETURN-ERROR  = (nz if reads do NOT match writes)
  5245. ;*
  5246. ;* CALLED BY
  5247. ;*
  5248. ;****************************************************************************/
  5249.  
  5250. WeitekChkSelWord PROC    Near
  5251.                 PUBLIC  WeitekChkSelWord
  5252.  
  5253.         call    WeitekGetSelWord        ;Get word original value.
  5254.         push    dx                      ;Save original value.
  5255.         .if     <nc> AND                ;If no mapping errors:
  5256.             call    WeitekGet1stWord
  5257.         .if     <nc> AND                ;If no mapping errors:
  5258.             xor     dx, 0aaaah          ;Toggle half the bits.
  5259.             mov     cx, dx              ;Save new value.
  5260.             call    WeitekSetSelWord
  5261.             call    WeitekGet1stWord    ;Force actual memory read.
  5262.         .if     <dx ne cx>              ;If starting word did not change:
  5263.             call    WeitekGetSelWord    ;See if word changed as set.
  5264.             cmp     dx, cx              ;Not floating, high, or low.
  5265.         .else                           ;Else wrap occured!
  5266.             or      cx, 00001h          ;Set NZ for failure.
  5267.         .endif
  5268.         pop     dx                      ;Restore original value.
  5269.         pushf                           ;Save success indicator.
  5270.         call    WeitekSetSelWord
  5271.         popf                            ;Restore success indicator.
  5272.         ret
  5273.  
  5274. WeitekChkSelWord ENDP
  5275.  
  5276. endif ;/* SVGAUTIL */
  5277.  
  5278. ;*                                                              /*          */
  5279. ;/****************************************************************************
  5280. ;*
  5281. ;* FUNCTION NAME = WhichWeitekP9x00
  5282. ;*
  5283. ;* DESCRIPTION   = Determine which Weitek chip were using.
  5284. ;*                      Currently just determine the memory size.
  5285. ;*
  5286. ;* INPUT         = NONE
  5287. ;* OUTPUT        = NONE
  5288. ;*
  5289. ;* RETURN-NORMAL = NONE
  5290. ;* RETURN-ERROR  = NONE
  5291. ;*
  5292. ;* CALLED BY
  5293. ;*
  5294. ;****************************************************************************/
  5295.  
  5296. WhichWeitekP9x00 PROC    Near
  5297.                 PUBLIC  WhichWeitekP9x00
  5298.  
  5299.         enter   STACKBLOCK, 0           ;                       /*          */
  5300.  
  5301. ifdef   TSU02                           ;          
  5302.  
  5303. ifndef SVGAUTIL
  5304.         mov     ax, 00002h              ;Set for 2 banks.
  5305.         call    WeitekMemConfig
  5306.         push    ax                      ;Save original memory configuration.
  5307. ;*
  5308. ;*      Now find chip length by testing for
  5309. ;*      address wrap or end of chip at high addresses.
  5310. ;*      Assume chips are at least 64K/4=16K bits long.
  5311. ;!!Should there be an assumed length for REAL DOS? =256K? =1M?  /*          */
  5312. ;*      Starting value here determines "default" size given under real DOS
  5313. ;*      Size will be 1/2 of first test, since first (and any) test fails.
  5314. ;*
  5315.         mov     ax, 00008h              ;Start with 128K bits long=512K buffer.
  5316.         xor     bx, bx                  ;Offset low is always zero.
  5317.         .repeat
  5318.             push    ax
  5319.             shr     ax, 1               ;Test wrap after previous chip size.
  5320.             call    WeitekChkSelWord    ;Check for word read/writable.
  5321.             pop     ax
  5322.         .until  < nz > or               ;Until memory test fails or...
  5323.             shl     ax, 1               ;Get next chip size.
  5324.         .until  <ax a 00010h>           ;Until > largest possible length=256K.
  5325.         shr     ax, 1                   ;Failed at this size, but not prev=1/2!
  5326.         mov     word ptr [_sSVGA.Memory][1*word], ax ;          /*          */
  5327. ;*
  5328. ;*      Now find out how many banks by testing
  5329. ;*      bank bits (2:3) in addresses in 4 bank mode.
  5330. ;*
  5331.         mov     ax, 00004h              ;Set for 4 banks.
  5332.         call    WeitekMemConfig
  5333.         xor     ax, ax                  ;High word of physical address.
  5334.         mov     bx, dword               ;Check second bank.
  5335.         call    WeitekChkSelWord        ;Check for word read/writable.
  5336.         .if     < z >                   ;If at least two banks:
  5337.             shl     word ptr [_sSVGA.Memory][word], 1 ;         /*          */
  5338.             shl     bx, 1               ;Check third bank.
  5339.             call    WeitekChkSelWord    ;Check for word read/writable.
  5340.             .if     < z >               ;If at least three(&four) banks:
  5341.                 shl     word ptr [_sSVGA.Memory][word], 1 ;     /*          */
  5342.             .endif
  5343.         .endif
  5344. ;*
  5345.         pop     ax                      ;Restore original memory configuration.
  5346.         call    WeitekMemConfig
  5347.  
  5348. else ;/* SVGAUTIL */
  5349. ;*      Leave default memory size at 1M
  5350. endif ;/* SVGAUTIL */
  5351.  
  5352. endif                                   ;          
  5353.  
  5354.         mov di, word ptr [SvgaBaseAddr][word] ;Get presumed base address.
  5355.  
  5356. ifndef SVGAUTIL                         ;                       /*@V3.0MNH04*/
  5357.         call    WeitekP9000Chk          ;                       /*@V3.0MNH04*/
  5358.         .if     < nz >                  ;If not P9000 base:     /*@V3.0MNH04*/
  5359.             mov     di, 00000h+WEITEK_P9000_REGISTERS ;Hunt!    /*@V3.0MNH04*/
  5360.             .repeat                     ;                       /*@V3.0MNH04*/
  5361.                 call    WeitekP9000Chk  ;                       /*@V3.0MNH04*/
  5362.             .leave  < z >               ;                       /*@V3.0MNH04*/
  5363.                 add     di, WEITEK_P9000_INCREMENT ;Leaves nz!  /*@V3.0MNH04*/
  5364.             .until  < c >               ;Until addr hi word wrap/*@V3.0MNH04*/
  5365.         .endif                          ;                       /*@V3.0MNH04*/
  5366.         mov     ax, WEITEK_P9000_CHIP   ; 1                     /*          */
  5367.         .if     < nz >                  ;No 9000 found:         /*@V3.0MNH04*/
  5368.             mov     ax, WEITEK_P9100_CHIP   ; 4                 /*@V3.0MNH04*/
  5369.         .endif                          ;                       /*@V3.0MNH04*/
  5370. else ;/* SVGAUTIL */                    ;                       /*@V3.0MNH04*/
  5371. ;*                                                              /*@V3.0MNH04*/
  5372. ;*      We do not have a way to use 32 bit addr's in real DOS!  /*@V3.0MNH04*/
  5373. ;*      So we can only guess...                                 /*@V3.0MNH04*/
  5374. ;*                                                              /*@V3.0MNH04*/
  5375.         mov     ax, WEITEK_P9000_CHIP   ; 1                     /*          */
  5376. endif ;/* SVGAUTIL */                   ;                       /*@V3.0MNH04*/
  5377.  
  5378.         and di, not WEITEK_P9000_REGISTERS ;Remove register part, leave base.
  5379.         mov word ptr [SvgaBaseAddr][word], di ;Save base address.
  5380.  
  5381.         leave                           ;                       /*          */
  5382.         ret
  5383.  
  5384. WhichWeitekP9x00 ENDP
  5385.  
  5386. ;/****************************************************************************
  5387. ;*
  5388. ;* FUNCTION NAME = WhichWesternDig
  5389. ;*
  5390. ;* DESCRIPTION   =
  5391. ;*      At index 30 thru 3f, the WD90cxx chips have an encoded device id.
  5392. ;*      Certain unlocks must be done to allow it to be read.
  5393. ;*      This is NOT documented in ALL of their data books.
  5394. ;*      It IS documented in the data book for the WD90C26.
  5395. ;*      It IS hinted at ("reserved") in other data books.
  5396. ;*
  5397. ;*                  3333333333333333
  5398. ;*                  0123456789ABCDEF
  5399. ;*      PVGA1A    ->################ #=0ffh or 000h
  5400. ;*      WD90c00   ->COPYRIGHT1989WDC
  5401. ;*      WD90c24   ->#WD90C24REVC0892 #=varies        Toshiba T4700CT
  5402. ;*      WD90c24a2a->#WD90C24AREVA293 #=varies z=000h WD90C24 Demo Board
  5403. ;*      WD90c24a2b->#WD90C24AREVB293 #=varies z=000h IBM ThinkPad
  5404. ;*      WD90c24a2c->#WD90C24AREVC### #=varies        WD program checks this!
  5405. ;*      WD90c26   ->#WD90C26REV#199# #=varies        WD ref documents this!
  5406. ;*      WD90c31   ->#WD90C310200zzzz #=varies z=000h WD program checks this!
  5407. ;*      WD90c31A  ->#WD90C31050zzzzz #=varies z=000h WD program checks this!
  5408. ;*      WD90c33   ->#WD90C33######## #=varies z=000h WD program checks this!
  5409. ;*      WD90c34   ->#WD90C34######## #=varies z=000h WD program checks this!
  5410. ;*      WD90cxx   ->#WD90Cxx######## #=varies x=chip
  5411. ;*
  5412. ;* INPUT         = NONE
  5413. ;* OUTPUT        = NONE
  5414. ;*
  5415. ;* RETURN-NORMAL = NONE
  5416. ;* RETURN-ERROR  = NONE
  5417. ;*
  5418. ;* CALLED BY
  5419. ;*
  5420. ;****************************************************************************/
  5421.  
  5422. WhichWesternDig PROC    Near
  5423.                 PUBLIC  WhichWesternDig
  5424.  
  5425.         enter   STACKBLOCK, 0           ;                       /*          */
  5426.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  5427.         call    InpDelay                ;Read original index    /*          */
  5428.         push    ax                      ;Save original index    /*          */
  5429.         mov     ax, 04806h              ;Everyone's fav lock!   /*          */
  5430.         call    OutpwDelay              ;Unlock                 /*          */
  5431.         call    WDEnableExt             ;Unlock needed registers.
  5432. ;*      OUTPUT   = DX = 003x4 (CRTC index address)
  5433.         mov     al, 036h
  5434.         call    WDRegPairString         ;Read chip id char pair for 90cxx
  5435.         mov     bx, WESTERNDIG_PVGA1A_CHIP ;BX has value to return
  5436.         cmp     ax, 0ffffh              ;Registers do not exist!
  5437.         jz      WhichWDEasy             ;It's a PVGA1A
  5438.         cmp     ax, 00000h              ;Registers do not exist!
  5439.         jz      WhichWDEasy             ;It's a PVGA1A
  5440.         inc     bx                      ;Assume WD90c00
  5441.         cmp     ax, 04748h              ;"GH"
  5442.         jz      WhichWDEasy             ;It's a WD90c00
  5443.         and     ax, 00f0fh
  5444.         mov     cl, 004h
  5445.         shl     ah, cl
  5446.         or      al, ah
  5447.         cmp     al, 000h
  5448.         jz      WhichWDEasy             ;It's a WD90c00
  5449.         cmp     al, 020h
  5450.         jz      WhichWDEasy             ;It's a WD90c00
  5451.         cmp     al, 022h
  5452.         jz      WhichWDEasy             ;It's a WD90c00
  5453.         inc     bx                      ;Assume WD90c11
  5454.         cmp     al, 011h
  5455.         jz      WhichWDEasy             ;It's a WD90c11
  5456.         inc     bx                      ;Assume WD90c30
  5457.         cmp     al, 030h
  5458.         jz      WhichWDEasy             ;It's a WD90c30
  5459.         inc     bx                      ;Assume WD90c26
  5460.         cmp     al, 026h
  5461.         jz      WhichWDEasy             ;It's a WD90c26
  5462.         inc     bx                      ;Assume WD90c27
  5463.         cmp     al, 027h
  5464.         jz      WhichWDEasy             ;It's a WD90c27
  5465.         inc     bx                      ;Assume WD90c31
  5466.         cmp     al, 031h
  5467.         jz      WhichWDEasy             ;It's a WD90c31
  5468.         inc     bx                      ;Assume WD90c24
  5469.         cmp     al, 024h
  5470.         jz      WhichWDEasy             ;It's a WD90c24
  5471.         inc     bx                      ;Assume WD90c33
  5472.         cmp     al, 033h
  5473.         jz      WhichWDEasy             ;It's a WD90c33
  5474.         jmp     short @F
  5475. WhichWDEasy:
  5476. ifdef SVGAUTIL
  5477.         jmp     short WhichWDExit1
  5478. else ;/* SVGAUTIL */
  5479.         jmp     WhichWDExit1
  5480. endif ;/* SVGAUTIL */
  5481. @@:
  5482. ;!! I doubt that the following tests will remain necessary!     /*          */
  5483. ;       mov     bx, WESTERNDIG_WD9000_CHIP ;Assume WD90c00
  5484. ;       mov     dl, 0c4h                ;SEQ index address (3c4)/*          */
  5485. ;       mov     [SaveReg4], dx
  5486. ;       call    InpDelay                ;Read the original index.
  5487. ;       mov     [SaveIndex4], al
  5488. ;       mov     ax, 04806h              ;extended sequencers.
  5489. ;       call    OutpwDelay              ;Write the new value.
  5490. ;                                       ;Distinguish between
  5491. ;       mov     al, 012h                ; WD90c00 and WD90c11 & later
  5492. ;       call    OutpIdxInpData          ;Read indexed reg       /*          */
  5493. ;                                       ; by using bit 6 of Misc Control Reg
  5494. ;                                       ;If chip doesn't respond to changes
  5495. ;                                       ; in the bit, its a WD90c00
  5496. ;       mov     ah, al                  ;
  5497. ;       and     al, NOT 01000000B       ;
  5498. ;       call    OutpData                ;Replace with bit 6 set to 0.
  5499. ;       call    InpData                 ;Read the value back.
  5500. ;       xchg    al, ah                  ;
  5501. ;       call    OutpData                ;Write the original value.
  5502. ;       xchg    ah, al                  ;
  5503. ;       test    al, 01000000B           ;if bit IS NOT zero,
  5504. ;       jnz     WhichWDExit2            ; its a 90c00
  5505. ;       or      al, 01000000B           ;
  5506. ;       call    OutpData                ;Replace with bit 6 set to 1.
  5507. ;       call    InpData                 ;Read the value back.
  5508. ;       xchg    al, ah                  ;
  5509. ;       call    OutpData                ;Write back the original value.
  5510. ;       xchg    ah, al                  ;
  5511. ;       test    al, 01000000B           ;if bit IS zero,
  5512. ;       jz      WhichWDExit2            ; its a 90c00
  5513. ;       inc     bx                      ;Assume WD90c11
  5514. ;       mov     dl, 0c4h                ;SEQ index address (3c4)/*          */
  5515. ;                                       ;Look for scratch pad reg
  5516. ;       mov     ax, 0aa09h              ; at index 09h, found on
  5517. ;       call    SaveOutpwChk            ; 90c30, not 90c11
  5518. ;       jnz     WhichWDExit2            ;Its probably a 90c11
  5519. ;       inc     bx                      ;Call it at least a WD90c30...
  5520. ;       mov     dx, 023c0h              ;Check for extended index control reg
  5521. ;       mov     al, 0ffh                ;Value to XOR with for test.
  5522. ;       call    SaveXORChk              ;
  5523. ;       jnz     WhichWDExit2            ;Its probably a 90c30.
  5524. ;       mov     bx, WESTERNDIG_WD9031_CHIP ;Call it at least a WD90c31.
  5525. WhichWDExit2:
  5526. ;       mov     dx, [SaveReg4]
  5527. ;       mov     al, [SaveIndex4]
  5528. ;       out     dx, al
  5529. WhichWDExit1:
  5530.         .if     <bx e WESTERNDIG_WD9024_CHIP> ;                 /*          */
  5531.             mov     al, 03ch            ;Id string byte         /*          */
  5532.             call    OutpIdxInpData      ;Read indexed reg       /*          */
  5533. ;                                                               /*          */
  5534. ;           Because of STN displays only capable of using 1/2M  /*          */
  5535. ;           even on the newer chips, memory path is a better    /*          */
  5536. ;           indication of usable display memory.                /*          */
  5537. ;                                                               /*          */
  5538. ;           .if     <al ae 'C'>         ;                       /*          */
  5539. ;               mov     al, 02ah        ;PR11 EGA Switches      /*          */
  5540. ;           .else                       ;Else not WD90C24C:     /*          */
  5541. ;                                                               /*          */
  5542. ;               Yes, strangely 32 bit path implies 1/2M!        /*          */
  5543. ;               And 16 bit path implies 1M!                     /*          */
  5544. ;                                                               /*          */
  5545.                 mov     dl, 0c4h        ;SEQ index address (3c4)/*          */
  5546.                 mov     al, 010h        ;                       /*          */
  5547. ;           .endif                      ;                       /*          */
  5548.             call    OutpIdxInpData      ;Read indexed reg       /*          */
  5549.             not     al                  ;Extra mem if bit 5 OFF /*          */
  5550.             and     al, 020h            ;Was bit 5 OFF? now ON? /*          */
  5551.             shr     al, 2               ;512K Extra (1M Total)  /*          */
  5552.             add     al, 008h            ;512K Otherwise         /*          */
  5553.         .else                           ;Else not WD90C24:      /*          */
  5554.             xor     al, al              ;Assume size not found  /*          */
  5555. ;*
  5556. ;*          WARNING:                                            /*          */
  5557. ;*              PR18 for LCD/FLAT PANELS is 3x5.31 Flat Panel Status (C24)
  5558. ;*              PR18 for desktops is 3x5.3e Vertical Timing Overflow  (C31/C33)
  5559. ;*              PR18A for LCD/FLAT PANELS is 3x5.3d Vertical Timing Overflow (C24)
  5560. ;*
  5561. ;*          WARNING:                                            /*          */
  5562. ;*              3x5.3e is PR18 Vertical Timing Overflow for desktops (C31/C33)
  5563. ;*              3x5.3e is PR39 Flat Panel Blinking for LCD/FLAT PANELS (C24)
  5564. ;*
  5565. ;*          So we cannot just read 3x5.3e and expect the Vertical
  5566. ;*          Timing Overflow, without knowing which chip we have!
  5567. ;*
  5568.             .if     <bx e WESTERNDIG_WD9033_CHIP> ;             /*          */
  5569.                 mov     al, 03eh        ;PR18 Vert Timing Ovrflw/*          */
  5570.                 call    OutpIdxInpData  ;Read indexed reg       /*          */
  5571.                 and     al, 080h        ;Get 90C33 2M bit       /*          */
  5572.                 shr     al, 2           ;Shift to 2M position   /*          */
  5573.             .endif                      ;Else not WD90C33:      /*          */
  5574.             .if     <zero al>           ;If not 2M then what?   /*          */
  5575.                 mov     dl, 0ceh        ;Determine on-board memory
  5576.                 mov     al, 00bh        ;Memory size
  5577.                 call    OutpIdxInpData  ;Read indexed reg       /*          */
  5578.                 shr     al, 006h        ;top 2 bits have mem size;           
  5579.                 .if     < nz >          ;zero means 256k        /*          */
  5580.                     dec     al          ;make count zero-based  /*          */
  5581.                 .endif                                          /*@V2.1MNH01*/
  5582.                 mov     cl, al          ;                       /*          */
  5583.                 mov     al, 0100B       ;256KB with no shift    /*          */
  5584.                 shl     al, cl          ;Shift to correct size. /*          */
  5585.             .endif                      ;Endif not 2M.          /*          */
  5586.         .endif                          ;Endif not WD90C24      /*          */
  5587.         cbw                             ;Extend to fullword     /*          */
  5588.         mov     word ptr [_sSVGA.Memory][word], ax ;            /*          */
  5589.         mov     al, 006h                ;Everyone's fav lock!   /*          */
  5590.         mov     ah, [SEQ06WD]           ;Use WD lock restore    /*          */
  5591.         mov     [SEQ06], ah             ;Instead of value read  /*          */
  5592.         mov     dl, 0c4h                ;SEQ index address (3c4)/*          */
  5593.         call    OutpwDelay              ;Restore original lock  /*          */
  5594.         pop     ax                      ;Restore original index /*          */
  5595.         call    OutpDelay               ;Restore original index /*          */
  5596.         push    bx                      ;Save return code       /*          */
  5597.         call    WDDisableExt            ;                       /*          */
  5598.         pop     ax                      ;Get return code        /*          */
  5599.         leave                           ;                       /*          */
  5600.         ret
  5601.  
  5602. WhichWesternDig ENDP
  5603.  
  5604. ifndef SVGAUTIL
  5605.  
  5606. ;/****************************************************************************
  5607. ;*
  5608. ;* FUNCTION NAME = IdentifyPCIAdapter
  5609. ;*
  5610. ;* DESCRIPTION   =
  5611. ;*      Process the array of identified PCI video devices and find the preffered
  5612. ;*      one (supported) and assign it our private device id. If none found, return
  5613. ;*      generic_pci_adapter as the SVGA type.
  5614. ;*
  5615. ;*
  5616. ;* INPUT         = NONE
  5617. ;* OUTPUT        = NONE
  5618. ;*
  5619. ;* RETURN-NORMAL = _sSVGA and SvgaOEMInfo structures are set.
  5620. ;* RETURN-ERROR  = NONE
  5621. ;*
  5622. ;* CALLED BY    IdentifyAdapter
  5623. ;*
  5624. ;****************************************************************************/
  5625.  
  5626. IdentifyPCIAdapter   PROC    near
  5627.      mov     [_sSVGA.AdapterType], UNKNOWN_ADAPTER ; 0 ;     /*          */
  5628.      mov     [_sSVGA.ChipType], UNKNOWN_CHIP ; 0 ;           /*          */
  5629.      mov     word ptr [_sSVGA.Memory][0*word], 0 ;           /*          */
  5630.      mov     word ptr [_sSVGA.Memory][1*word], 0010h ;       /*          */
  5631.      mov     [SvgaOEMInfo.Manufacturer], UNKNOWN_MANUFACTURER ; 0 ;
  5632.      mov        cx, PCI_Num
  5633. device_loop:
  5634.      dec     cx
  5635.      mov     si, offset PCI_DeviceTbl           ;ulong hw: Vendor ID, lw Device ID
  5636.      mov     ax, cx
  5637.      shl     ax, 2
  5638.      add     si, ax
  5639.      mov     ax, word ptr ds:[si]
  5640.      cmp     ax, 01002h                      ;ATI
  5641.      jnz     short @F
  5642.      call    IsATI                           ;           
  5643.      jnz     BadDetection                    ;           
  5644.      mov     [_sSVGA.AdapterType], ATI_ADAPTER ; 
  5645.      call    WhichATI
  5646.      jmp     DonePCI
  5647.  
  5648. @@:
  5649.      cmp     ax, 0100ch                      ;TSENG
  5650.      jnz     short @F
  5651.      call    IsTseng                         ;           
  5652.      jnz     BadDetection                    ;           
  5653.      mov     [_sSVGA.AdapterType], TSENG_ADAPTER ; 
  5654.      call    WhichTseng
  5655.      jmp     DonePCI
  5656.  
  5657. @@:
  5658.      cmp     ax, 010beh                      ;TSENG
  5659.      jnz     short @F
  5660.      call    IsTseng                         ;           
  5661.      jnz     BadDetection                    ;           
  5662.      mov     [_sSVGA.AdapterType], TSENG_ADAPTER ; 
  5663.      call    WhichTseng
  5664.      jmp     DonePCI
  5665.  
  5666. @@:
  5667.      cmp     ax, 0100eh                      ;WEITEK
  5668.      jnz     short @F
  5669. ;     call    IsWeitek                                  
  5670. ;     jnz     BadDetection                              
  5671.      mov     [_sSVGA.AdapterType], WEITEK_ADAPTER ; 
  5672.      mov     si, offset PCI_DeviceTbl           ;ulong hw: Vendor ID, lw Device ID
  5673.      mov     ax, cx
  5674.      shl     ax, 2
  5675.      add     ax, 2
  5676.      add     si, ax
  5677.      mov     ax, word ptr ds:[si]
  5678.      cmp     ax, 09100h                ; device ID for 9100
  5679.      jnz     NextWTChip
  5680.      mov     ax, WEITEK_P9100_CHIP
  5681.      jmp     DonePCI
  5682. NextWTChip:
  5683.      cmp     ax, 09001h                ; device ID for 9000
  5684.      jnz     NextDevice
  5685.      mov     ax, WEITEK_P9000_CHIP
  5686.      jmp     SHORT DonePCI
  5687.  
  5688. @@:
  5689.      cmp     ax, 0101ch                      ;WD
  5690.      jnz     short @F
  5691.      call    IsWesternDig                    ;           
  5692.      jnz     short BadDetection              ;           
  5693.      mov     [_sSVGA.AdapterType], WESTERNDIG_ADAPTER ; 
  5694.      call    WhichWesternDig         ; 
  5695.      jmp     SHORT DonePCI
  5696.  
  5697. @@:
  5698.      cmp     ax, 01013h                      ;Cirrus
  5699.      jnz     short @F
  5700.      call    IsCirrus                        ;           
  5701.      jnz     short BadDetection              ;           
  5702.      mov     [_sSVGA.AdapterType], CIRRUS_ADAPTER ; 
  5703.      call    WhichCirrus             ; 
  5704.      jmp     SHORT DonePCI
  5705.  
  5706. @@:
  5707.      cmp     ax, 05333h                      ;S3
  5708.      jnz     short @F
  5709.      call    IsS3                            ;           
  5710.      jnz     short BadDetection              ;           
  5711.      mov     [_sSVGA.AdapterType], S3_ADAPTER ; 
  5712.      call    WhichS3                 ; 
  5713.      jmp     SHORT DonePCI
  5714.  
  5715. @@:
  5716.      cmp     ax, 01023h                      ;TRIDENT
  5717.      jnz     short @F
  5718.      call    IsTrident                       ;           
  5719.      jnz     short BadDetection              ;           
  5720.      mov     [_sSVGA.AdapterType], TRIDENT_ADAPTER ; 
  5721.      call    WhichTrident            ; 
  5722.      jmp     SHORT NextDevice
  5723.  
  5724. @@:
  5725.      cmp     ax, 01005h                      ;AVANCE
  5726.      jnz     short @F
  5727. ;     mov     [_sSVGA.AdapterType], GENERIC_PCISVGA_ADAPTER            
  5728.      mov     [_sSVGA.AdapterType],  UNKNOWN_ADAPTER         ;          
  5729.      mov     ax, 02301h
  5730.      jmp     SHORT NextDevice
  5731.  
  5732. @@:
  5733.      cmp     ax, 0102ch                      ;C&T
  5734.      jnz     short @F
  5735.      mov     [_sSVGA.AdapterType], CHIPS_ADAPTER ; 
  5736.      mov     ax, CHIPS_FIRST_CHIP    ; return a chiptype
  5737.  
  5738. @@:
  5739. NextDevice:
  5740.      jcxz    DonePCI
  5741.      jmp     device_loop
  5742. DonePCI:
  5743.      mov     [_sSVGA.ChipType], ax
  5744.      ret
  5745. BadDetection:                             ;           
  5746.      mov     ax, 0ffh                     ;           
  5747.      ret                                  ;           
  5748. IdentifyPCIAdapter ENDP
  5749.  
  5750. endif
  5751.  
  5752. ;/****************************************************************************
  5753. ;*
  5754. ;* FUNCTION NAME = _IdentifySVGA
  5755. ;*
  5756. ;* DESCRIPTION   =
  5757. ;*
  5758. ;*      Identify SVGA and its VRAM size from:
  5759. ;*
  5760. ;*                                            Return in AH    AL
  5761. ;*        o Indeterminate chip set                       0     0
  5762. ;*
  5763. ;*        o Headland/Video 7     HT205                   1     1
  5764. ;*                               HT208                   1     2
  5765. ;*                               HT209                   1     3
  5766. ;*
  5767. ;*        o Trident Microsystems 8800                    2     1
  5768. ;*                               8900                    2     2
  5769. ;*
  5770. ;*        o Tseng                ET3000                  3     1
  5771. ;*                               ET4000                  3     2
  5772. ;*                               ET4000/W32              3     3
  5773. ;*                               ET4000/W32i             3     4/*          */
  5774. ;*                               ET4000/W32p             3     5/*          */
  5775. ;*
  5776. ;*        o Western Digital      PVGA1A                  4     1
  5777. ;*                               WD90c00                 4     2
  5778. ;*                               WD90c11                 4     3
  5779. ;*                               WD90c30                 4     4
  5780. ;*                               WD90c26                 4     5/*          */
  5781. ;*                               WD90c27                 4     6/*          */
  5782. ;*                               WD90c31                 4     7/*          */
  5783. ;*                               WD90c24                 4     8/*          */
  5784. ;*                               WD90c33                 4     9/*          */
  5785. ;*
  5786. ;*        o ATI                  ATI18800                5     1
  5787. ;*                               ATI28800                5     2
  5788. ;*                               ATI38800==MACH8         5     3/*          */
  5789. ;*                               ATI68800==MACH32        5     4/*          */
  5790. ;*                               ATI68800AX              5     5/*          */
  5791. ;*                               ATI68800GX              5     6/*          */
  5792. ;*
  5793. ;*        o IBM Speedway         VGA-256C                6     1
  5794. ;*
  5795. ;*
  5796. ;*        o CIRRUS               GD5422                  7     1
  5797. ;*                               GD5424                  7     2
  5798. ;*                               GD5426                  7     3
  5799. ;*                               GD5428                  7     4/*          */
  5800. ;*
  5801. ;*        o S3                   801, 805                8     1
  5802. ;*                               928                     8     2
  5803. ;*                               864                     8     3/*          */
  5804. ;*                               964                     8     4/*          */
  5805. ;*                               911                     8     5/*          */
  5806. ;*
  5807. ;*        o CHIPS&TECHNOLOGY                             9      /*          */
  5808. ;*
  5809. ;*        o WEITEK               P9000                  10     1/*          */
  5810. ;*                               W5186                  10     2/*          */
  5811. ;*                               W5286                  10     3/*          */
  5812. ;*
  5813. ;* ENTRY POINT:  _IdentifySVGA
  5814. ;*    LINKAGE:   Call Far
  5815. ;*
  5816. ;* INPUT:
  5817. ;*       ES:BX = request packet address
  5818. ;*       DS = DGROUP
  5819. ;*
  5820. ;* EXIT-NORMAL: AX = Status to return to OS
  5821. ;* EXIT-ERROR:  NONE
  5822. ;*
  5823. ;* EFFECTS:
  5824. ;*       AX
  5825. ;*
  5826. ;* USES ROUTINES:
  5827. ;*
  5828. ;* CALLED BY ROUTINES:
  5829. ;*             INIT
  5830. ;*
  5831. ;* INPUT         = NONE
  5832. ;* OUTPUT        = NONE
  5833. ;*
  5834. ;* RETURN-NORMAL = adapter type and chip type.
  5835. ;* RETURN-ERROR  = NONE
  5836. ;*
  5837. ;* CALLED BY
  5838. ;*
  5839. ;****************************************************************************/
  5840.  
  5841. _IdentifySVGA   PROC    far             ;to far                 /*          */
  5842.                 PUBLIC  _IdentifySVGA   ;                       /*          */
  5843.  
  5844.         enter   0,0                     ;                       /*          */
  5845.         pusha                           ;                       /*          */
  5846.         push    ds                      ;                       /*          */
  5847. ifndef SVGAUTIL
  5848.         cmp     word ptr PCI_Num, 0     ;@senja
  5849.         jz      short @F                ;@senja
  5850.         call    IdentifyPCIAdapter      ;will set both _sSVGA and SvgaOEMInfo structures
  5851.         cmp     ax, 0ffh                ;           
  5852.         jnz     IdentifyExit            ;           
  5853. @@:
  5854. endif
  5855.         mov     [_sSVGA.AdapterType], UNKNOWN_ADAPTER ; 0 ;     /*          */
  5856.         mov     [_sSVGA.ChipType], UNKNOWN_CHIP ; 0 ;           /*          */
  5857.         mov     word ptr [_sSVGA.Memory][0*word], 0 ;           /*          */
  5858.         mov     word ptr [_sSVGA.Memory][1*word], 0010h ;       /*          */
  5859.         mov     [SvgaOEMInfo.Manufacturer], UNKNOWN_MANUFACTURER ; 0 ;
  5860.         mov     dx, 03c4h               ;SEQ index address (3c4)/*          */
  5861.         call    InpDelay                ;Read original index    /*          */
  5862.         push    ax                      ;Save original index    /*          */
  5863.         mov     al, 048h                ;                       /*          */
  5864.         call    OutpInp                 ;Test WD PR20 lock state/*          */
  5865.         or      al, 040h                ;Create WD lock restore /*          */
  5866.         mov     [SEQ06WD], al           ;Save just in case WD!  /*          */
  5867.         mov     al, 006h                ;Everyone's fav lock!   /*          */
  5868.         call    OutpIdxInpData          ;Read original value.   /*          */
  5869.         mov     [SEQ06], al             ;Save in case not WD!   /*          */
  5870.         pop     ax                      ;Restore original index /*          */
  5871.         call    OutpDelay               ;Restore original index /*          */
  5872. @@:                                     ;                       /*          */
  5873.         call    IsSpeedWay
  5874.         jnz     @F
  5875.         mov     [_sSVGA.AdapterType], IBM_ADAPTER ; 6           /*          */
  5876.         mov     ax, IBM_SVGA_CHIP ;1    ;                       /*          */
  5877.         jmp     SetChipType             ;                       /*          */
  5878.  
  5879. @@:     call    IsVideo7                ; 
  5880.         jnz     short @F                ; 
  5881.         mov     [_sSVGA.AdapterType], VIDEO7_ADAPTER ;1         /*          */
  5882.         call    WhichVideo7             ; 
  5883.         jmp     SetChipType
  5884.  
  5885. @@:     call    IsTrident               ; 
  5886.         jnz     short @F                ; 
  5887.         mov     [_sSVGA.AdapterType], TRIDENT_ADAPTER ;2        /*          */
  5888.         call    WhichTrident            ; 
  5889.         jmp     short SetChipType
  5890.  
  5891. @@:     call    IsTseng                 ; 
  5892.         jnz     short @F                ; 
  5893.         mov     [_sSVGA.AdapterType], TSENG_ADAPTER ;3          /*          */
  5894.         call    WhichTseng              ; 
  5895.         jmp     short SetChipType
  5896.  
  5897. @@:     call    IsWesternDig            ; 
  5898.         jnz     short @F                ; 
  5899.         mov     [_sSVGA.AdapterType], WESTERNDIG_ADAPTER ;4     /*          */
  5900.         call    WhichWesternDig         ; 
  5901.         jmp     short SetChipType
  5902.  
  5903. @@:     call    IsATI                   ; 
  5904.         jnz     short @F                ; 
  5905.         mov     [_sSVGA.AdapterType], ATI_ADAPTER ;5            /*          */
  5906.         call    WhichATI                ; 
  5907.         jmp     short SetChipType
  5908.  
  5909. @@:     call    IsCirrus                ;                       /*          */
  5910.         jnz     short @F                ; 
  5911.         mov     [_sSVGA.AdapterType], CIRRUS_ADAPTER ;7         /*          */
  5912.         call    WhichCirrus             ; 
  5913.         jmp     short SetChipType
  5914.  
  5915. @@:     call    IsS3                    ;                       /*          */
  5916.         jnz     short @F                ; 
  5917.         mov     [_sSVGA.AdapterType], S3_ADAPTER ;8             /*          */
  5918.         call    WhichS3                 ; 
  5919.         jmp     short SetChipType
  5920.  
  5921. @@:     call    IsChips                 ;                       /*          */
  5922.         jnz     short @F                ; 
  5923.         mov     [_sSVGA.AdapterType], CHIPS_ADAPTER ;9
  5924.         mov     ax, CHIPS_FIRST_CHIP    ; return a chiptype
  5925.         jmp     short SetChipType
  5926.  
  5927. @@:     call    IsWeitek                ;                       /*          */
  5928.         jnz     short @F                ;                       /*          */
  5929.         mov     [_sSVGA.AdapterType], WEITEK_ADAPTER ; 10       /*          */
  5930.         call    WhichWeitek             ;                       /*          */
  5931.         jmp     short SetChipType       ;                       /*          */
  5932.  
  5933. @@:     call    LastAttempt             ;                       /*          */
  5934.         or      ax, ax
  5935.         jz      SVGAExit                ;AX is 0 if adapter not identified.
  5936.                                         ;if successful ax= adapter, bx=chiptype.
  5937.         mov     [_sSVGA.AdapterType], ax ;                      /*          */
  5938.         mov     ax, bx
  5939. SetChipType:                            ;                       /*          */
  5940.         mov     [_sSVGA.ChipType], ax   ;                       /*          */
  5941. SVGAExit:
  5942. ;*                                                              /*          */
  5943. ;*      Since WEITEK P9000 can be married to any VGA,
  5944. ;*      we test for it last and if we find it,
  5945. ;*      we move the current adapter and chip type to SvgaOEMInfo
  5946. ;*
  5947. @@:     call    IsWeitekP9x00           ;                       /*@V3.0MNH04*/
  5948.         jnz     short IdentifyExit      ;@senja
  5949.         mov     ax, [_sSVGA.AdapterType] ;                      /*          */
  5950.         mov     word ptr [SvgaOEMInfo.ManufacturerData][0*word], ax  ; 
  5951.         mov     ax, [_sSVGA.ChipType]   ;                       /*          */
  5952.         mov     word ptr [SvgaOEMInfo.ManufacturerData][1*word], ax ; 
  5953.         mov     [_sSVGA.AdapterType], WEITEK_ADAPTER ; 10       /*          */
  5954.         call    WhichWeitekP9x00        ;                       /*@V3.0MNH04*/
  5955.         mov     [_sSVGA.ChipType], ax   ;                       /*          */
  5956. IdentifyExit:
  5957.         pop     ds                      ;                       /*          */
  5958.         popa                            ;                       /*          */
  5959.         leave                           ;                       /*          */
  5960.         ret                             ;                       /*          */
  5961.  
  5962. _IdentifySVGA   ENDP                    ;                       /*          */
  5963.  
  5964. BiosSeg ends
  5965.  
  5966.         end
  5967. ;*
  5968. ;* CHANGE ACTIVITY =
  5969. ;*   DATE      FLAG       APAR    CHANGE DESCRIPTION
  5970. ;*   --------  ---------- -----   --------------------------------------
  5971. ;*   mm/dd/yy  @Vr.mpppxx xxxxx   xxxxxxx
  5972. ;*   11/12/92                     Dale  More specific Speedway detection.
  5973. ;*   12/28/92                     Senja Cirrus Logic support.
  5974. ;*   01/20/93                     Senja WD detection logic enhanced.
  5975. ;*   01/21/93                     XGA doesn't boot because Aperture Index gets trashed.
  5976. ;*   02/10/93                     Manufacturer info IOCTL.
  5977. ;*   02/18/93                     UpdateMemoryInfo IOCTL.
  5978. ;*   03/05/93                     Do not identify XGA as Speedway.
  5979. ;*   03/10/93                     Identification of MC Orchid.
  5980. ;*   03/12/93                     Changed BANK packet interface to be more consistent.
  5981. ;*   03/16/93                     Making SCREENDD more consistent.
  5982. ;*   03/23/93                     Fixing bank packet validation.
  5983. ;*   04/03/93                     Attach to OEMHLP.
  5984. ;*   04/14/92                     If XGA detected, do not proceed with the detection.
  5985. ;*   05/02/93              68723  Improve Speedway checks
  5986. ;*   06/03/93              69461  Lock the extended sequencer before exit
  5987. ;*   06/03/93              63910  ACER M3125 SVGA fix
  5988. ;*   06/04/93             F69306  Add support for S3
  5989. ;*   08/12/93              72760  Enhance S3 chip detection
  5990. ;*   08/30/93              73465  Only need 1 manufacturer value for Diamond
  5991. ;*   08/31/93                     Recognize Cirrus Logic GD5428 chip
  5992. ;*   10/06/93              72687  Support Number Nine adapters with S3
  5993. ;*   10/13/93              74175  Fix SVGA conflict on Gateway VLB
  5994. ;*   11/01/93             D75458  Merge r206v, r205, r206, r207 S3 code
  5995. ;*   11/19/93             D74047  Add support for S3 911/924
  5996. ;*   02/24/94             D79562  Recognize additional WD chipsets
  5997. ;*   03/17/94             D80921  Fix WD DOS started in background
  5998. ;*   03/18/94             D       Fix WD DOS started in background
  5999. ;*   04/26/94             D82003  WD90C24 preserve locks for BIOS setmodes
  6000. ;*   05/13/94             F74819  ATI Mach8/32 check in files
  6001. ;*   05/14/94                     Support more Cirrus chipsets
  6002. ;*   05/17/94                     Support S3 Vision 864/964
  6003. ;*   06/14/94                     Make Video7 lock check not affect Cirrus
  6004. ;*   06/15/94                     Add ATI Mach 64 Identification
  6005. ;*   07/15/94                     enhance Tseng VRAM size determination
  6006. ;*   07/16/94                     ATI Mach64 detection clear RS2 & restore
  6007. ;*   07/16/94             D89152  WD/Video7/Cirrus SEQ06 lock preservation
  6008. ;*   07/28/94              88172  Detect Chips and Technologies adapter
  6009. ;*   08/04/94              92358  Set zero flag off if CHIPS not found
  6010. ;*   08/12/94              92809  Tseng MemorySize determination not always correct (VLB, PCI)
  6011. ;*   08/16/94             D93790  Fix WD C24 memory detection
  6012. ;*   08/18/94              82945  Enable TSENGW32 with Diamond
  6013. ;*   08/26/94             D93217  Fix ATI Mach32 memory detection
  6014. ;*   08/25/94             D       Add PCI detection via a BIOS call.
  6015. ;*   09/19/94              92593  Actix S3864 returns       vender ID
  6016. ;*   09/22/94              99400  Avance card causes trap in DOS full screen
  6017. ;*   09/22/94                     Strengthen CHIPS test
  6018. ;*   09/23/94                     Detect memory size for Cirrus
  6019. ;*   09/25/94              99760  Compudyne w/ Weitek IPE during installation
  6020. ;*   10/20/94                     Add write back invalidate cache commands
  6021. ;*   10/25/94             103192  TSENG Rev D wont install
  6022. ;*   11/16/94  @V3.0JLO01 104565  ATI Mach32 microchannel version not recognized
  6023. ;*   11/30/94  @V3.0YEE01 105950  Support S3 964
  6024. ;*   01/12/95  @V3.0MNH04 102314  Put back Weitek Hunt to id 9000 vs 9100
  6025.