home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / window / miscutil / 87dtec / perpropc.asm next >
Encoding:
Assembly Source File  |  1985-07-12  |  18.2 KB  |  621 lines

  1.  
  2.         title   LISTING 3  ;DETERMINING CPU TYPE
  3.  
  4. ; Cputest.asm is the Lattice C-callable assembly language routine that determines
  5. ; the machine's processor type.
  6.  
  7. ; Copyright (c) 1986 Dan Jacobs and Joel Rosenblum 
  8.  
  9.         name    cputest  ;determine CPU type
  10.  
  11.         include dos.mac         ; Lattice C memory model configuration macro
  12.                                 ; In this case it is a copy of dm8086.mac
  13.         
  14. ; processor type equates
  15. CPU_88    equ 01H       ; Intel 8088 - 8086
  16. CPU_186   equ 02H       ; Intel 80188 - 80186
  17. CPU_286   equ 04H       ; Intel 80286
  18. CPU_V20   equ 08H       ; NEC V20 - V30
  19.  
  20.         PSEG
  21.  
  22. comment\**********************************************************************
  23.  
  24. NAME
  25.         cputest
  26.  
  27. SYNOPSIS
  28.  
  29.         unsigned int cputest (features)
  30.         unsigned int features;          see definition of machine type
  31.  
  32. DESCRIPTION
  33.  
  34.         returns features with the proper active CPU type or'ed in
  35.  
  36. *****************************************************************************\
  37.  
  38.                 public  cputest
  39. cputest         proc    near
  40.  
  41.                 push    BP              ; save the frame pointer (if called from C)
  42.                 mov     BP, SP
  43.  
  44.                 ; next, save the passed existing features 
  45.  
  46.                 mov     AX, 4[BP]
  47.                 push    AX
  48.  
  49.         ; check for  8088 or 8086  by using the  SHR instruction  since the 
  50.         ; 8088 and 8086 do not mask cl with 07H before executing the shift. 
  51.  
  52.                 mov     CL, 20H         
  53.                 mov     AX, 1
  54.                 shr     AX, CL
  55.                 test    AX, AX          ; if after the shift AX is the same  
  56.                                         ; as before, it's a 8088 - 8086 or V20 - V30
  57.                 jnz     check_80186     ; else, continue checking other Intel CPUs
  58.  
  59.         ; check for V20 or V30 by detecting if PUSHA is a valid instruction 
  60.         ; on the NEC CPUs
  61.  
  62.                 mov     BX, SP          ; save SP
  63.                 pusha
  64.                 cmp     BX, SP          ; if SP has not been decremented, then 
  65.                 je      is_88           ; it's an 8088 - 8086
  66.                 popa                    ; else, we restore registers
  67.                 mov     AX, CPU_V20
  68.                 jmp     return
  69.  
  70. is_88:          mov     AX, CPU_88
  71.                 jmp     return
  72.  
  73. check_80186:
  74.  
  75.         ; check for the 80188 or 80186 by detecting if SP is updated
  76.         ; before or after it is pushed.
  77.         
  78.                 push    SP
  79.                 pop     BX
  80.                 cmp     BX, SP
  81.                 je      is_286          ; if updated after, it's a 80286
  82.  
  83.                 mov     AX, CPU_186     ; else, it's a 80186 or 80188
  84.                 jmp     short return            
  85.  
  86. is_286:         mov     AX, CPU_286
  87.  
  88. return:         pop     BX              ; recall saved features 
  89.                 or      AX, BX          ; and or cputype into other features bits
  90.                 pop     BP
  91.                 ret
  92.  
  93. cputest         endp
  94.  
  95.                 ENDPS
  96.                 end
  97.  
  98. -------------------------------------------------------------------------------
  99.  
  100.         title   LISTING 4  ;DETECTING MATH CO-PROCESSOR
  101.  
  102. ; testndp.asm is the Lattice C-callable assembly language routine that
  103. ; determines the presence of an 8087 or 80287 math  co-processer chip.
  104.  
  105. ; assembeled using Microsoft MASM v4.0
  106.  
  107. ; Copyright (c) 1986 Dan Jacobs and Joel Rosenblum 
  108.  
  109. ; portions copyrighted by MicroWay, Inc. 
  110.  
  111.         name    test_ndp
  112.  
  113.         include dos.mac         ; Lattice C memory model configuration macro
  114.                                 ; In this case it is a copy of dm8086.mac
  115.  
  116. ; We have to code the instructions for the NDP as dbs as the assembler
  117. ; generates an unwanted WAIT instruction
  118.  
  119. FINIT_MAC       MACRO
  120.                 db      0DBH, 0E3H
  121.                 ENDM
  122.  
  123. FSTCW_MAC       MACRO   address
  124.                 db      0D9H, 03EH
  125.                 dw      offset DGROUP:address
  126.                 ENDM
  127.  
  128.  
  129.  
  130. ; bit mask for coprocessor in FEATURES
  131. NDP             equ     0010H   ; a coprocessor is present
  132.  
  133.         DSEG
  134. ndp_word        dw      0       ; a storage location for the ndp to use for test
  135.         ENDDS
  136.  
  137.         PSEG
  138.  
  139. comment\**********************************************************************
  140.  
  141. NAME
  142.           testndp
  143.  
  144. SYNOPSIS
  145.           Check to see if a  8087 or 80287  numeric data processor is
  146.           present in the machine.  Here, we present two methods which
  147.           you may select based  upon how you set  CHOOSE in the  code:
  148.           First,  IBM's  recommended  procedure  which does an  int 11 
  149.           (equipment determination)  BIOS call.  The problem with this
  150.           method is that it only  works on IBMs and  100% compatibles.
  151.           Note that in the PC and XT the returned value is  determined 
  152.           by reading the  switch setting.    Unfortunately, all of the
  153.           early "guide to operations" manuals  informed you to set the 
  154.           switch  the  coprocessor the wrong way, rendering it usless.
  155.           Second,   MicroWay's  recommended  procedure  checks for the 
  156.           coprocessor directly.  We believe that this method should be 
  157.           used since it is more universal.  We leave the choice to you
  158.           depending how you set the equ for CHOOSE  below:
  159.  
  160.             1 to use int 11
  161.           or
  162.             0 for direct check
  163.  
  164. SYNOPSIS
  165.           unsigned int test_ndp (features);
  166.           unsigned features;              see definition of machine type
  167.  
  168. RETURN VALUE
  169.           the passed features variable with the NDP bit or'ed in
  170.  
  171. *****************************************************************************\
  172.  
  173. CHOOSE  equ     0       ; 0 = direct ndp check, 1 = IBM int 11 bios call
  174.  
  175.                 public  test_ndp
  176.  
  177. test_ndp        proc    near
  178.  
  179.         assume  ds:DGROUP
  180.  
  181.         push    bp              ; save the frame pointer (if called from C)
  182.         mov     bp, sp
  183.  
  184.         ; next, save the passed existing features
  185.         mov     ax, 4[bp]
  186.         push    ax
  187.         
  188. if CHOOSE ; use bios int check
  189.         int     11H                     ; equipment determination call
  190.         and     ax, 2                   ; coprocessor present
  191.         jz      no_ndp
  192. else ; use direct ndp check ala MicroWay
  193.         FINIT_MAC                       ; initilize the coprocessor
  194.         mov     ndp_word, 0
  195.         FSTCW_MAC <ndp_word>            ; fstcw ndp_word
  196.                                         ; move control word to ndp_word
  197.         mov     cx, 064H                ; count for wait loop
  198. l1:     push    dx
  199.         pop     dx
  200.         loop    l1
  201.         and     ndp_word, 03BFH         ; mask to bits we want
  202.         cmp     ndp_word, 03BFH         ; all the correct bits set
  203.         jne     no_ndp
  204.  
  205.         mov     ndp_word, 0             
  206.         FSTCW_MAC <ndp_word>            ; fstcw ndp_word
  207.                                         ; move control word to ndp_word
  208.         mov     cx, 064H                ; count for wait loop
  209. l2:     push    dx
  210.         pop     dx
  211.         loop    l2
  212.         and     ndp_word, 1F3FH         ; mask to bits we want
  213.         cmp     ndp_word, 033FH         ; all the correct bits set
  214.         jne     no_ndp
  215.  
  216. endif
  217.         mov     bx, NDP                 ; mask to turn on coprocessor bit
  218.         jmp     short ndp_exit
  219.  
  220. no_ndp: mov     bx, 0                   ; nothing to mask in
  221.  
  222. ndp_exit:
  223.         pop     ax                      ; get saved passed features
  224.         or      ax, bx                  ; and or in bit for ndp 
  225.  
  226.         pop     bp                      ; restore frame pointer to return to C caller
  227.  
  228.         ret
  229.  
  230. test_ndp        endp
  231.  
  232.         ENDPS
  233.         end
  234.  
  235. _______________________________________________________________________________
  236.  
  237.     title    Listing 5a  ;Calculating Timing Loops
  238.  
  239. ; Cal.asm is an assembly language routine that provides a standard
  240. ; delay independent of clock speed.   It may be  called  from  a C
  241. ; routine in your software as illustrated in listing 5b.
  242.  
  243. ; Note: The PC's timer interrupt is assumed set to the standard ~18.2Hz
  244.  
  245. ; Copyright (c) 1986 Howie Marshall, Applied Reasoning Corp. 
  246.  
  247. pgroup    group    prog
  248. dgroup    group    data
  249.  
  250. bios_data    segment    at 40H
  251.         org    06cH
  252. low_time    dw    ?
  253. bios_data    ends
  254.  
  255. data        segment    public 'data'
  256.         extrn    us500:word, ms2:word
  257. dummy        dw    0        ; a dummy to compare against
  258. data        ends
  259.  
  260. prog    segment    byte public 'prog'
  261. ;
  262. ; delaycal - calibrate the delay loop
  263. ;
  264. ; temp = delaycal(delay_time) from C.  Returns delay_count
  265. ;
  266.     assume    cs:pgroup
  267.     public    delaycal
  268. delaycal proc    near
  269.     assume    ds:dgroup
  270.     push    bp
  271.     push    ds
  272.     mov    bp,sp
  273.     mov    ax,bios_data
  274.     mov    ds,ax
  275.     assume    ds:bios_data
  276. ;
  277. ; wait for the timer to tick over
  278. ;
  279.     mov    di,low_time
  280. timwait:
  281.     cmp    di,low_time
  282.     je    timwait
  283. ;
  284.     xor    ax,ax
  285.     xor    dx,dx
  286.     add    di,6        ; wait for 5 more ticks
  287. ;*************************************************************
  288. timloop:
  289.     add    ax,1
  290.     adc    dx,0
  291.     cmp    di,low_time    ; have 5 ticks occurred yet?
  292.     ja    timloop        ; no, continue looping
  293. ;*************************************************************
  294. ;
  295. ;  5 ticks @ 18.2 ticks/sec => 270272 microseconds in 5 ticks
  296. ;
  297. ;  270272 = 16 * 16892
  298. ;
  299.     mov    bx,16
  300.     div    bx        ; cut down to single word
  301.     mov    bx,6[bp]    ; get desired delay time
  302.     mul    bx
  303.     mov    bx,16892
  304.     div    bx        ; finish divide-by-270272
  305.     or    ax,ax
  306.     jnz    timok
  307.     inc    ax        ; do at least one loop
  308. timok:
  309.     mov    sp,bp
  310.     pop    ds
  311.     assume    ds:dgroup
  312.     pop    bp
  313.     ret
  314. delaycal endp
  315. ;
  316. ;  DELAY SUBROUTINES:
  317. ;
  318. ;  This routine delays for 500 microseconds.
  319. ;
  320.     public    del500u
  321. del500u    proc    near
  322.     assume    ds:dgroup
  323.     mov    ax,us500
  324.     neg    ax
  325. ;
  326. ;  This loop contains the same instructions as the calibration loop
  327. ;  in delaycal above, but in a different order.  The first two are
  328. ;  do not actually affect the loop, other than taking the same number
  329. ;  of cycles as the corresponding portion of the loop in delaycal.
  330. ;
  331. ;  Note that both loops consist of:
  332. ;    ADD, ADC, CMP, Jcond
  333. ;
  334. ;*************************************************************
  335. loop1:
  336.     adc    dx,0        ; kill some time
  337.     cmp    dx,dummy    ; and some more
  338.     add    ax,1        ; increment our count
  339.     jnz    loop1        ; no, continue looping
  340. ;*************************************************************
  341.     ret
  342. del500u    endp
  343. ;
  344. ;  This is essentially the same as del500u, except that a different
  345. ;  count value is used to delay for 2 milliseconds.
  346. ;
  347.     public    del2m
  348. del2m    proc    near
  349.     assume    ds:dgroup
  350.     mov    ax,ms2
  351.     neg    ax
  352. ;*************************************************************
  353. loop2:
  354.     adc    dx,0        ; kill some time
  355.     cmp    dx,dummy    ; and some more
  356.     add    ax,1        ; increment our count
  357.     jnz    loop2        ; no, continue looping
  358. ;*************************************************************
  359.     ret
  360. del2m    endp
  361. prog    ends
  362.     end
  363.  
  364. -------------------------------------------------------------------------------
  365.  
  366.     title    LISTING 6  ;DETECTING VIDEO TYPE
  367.  
  368. ; Video.asm is the Lattice C-callable assembly language routine that determines
  369. ; the presence of video screen adapter cards and displays in an  IBM compatible
  370. ; system.
  371. ; *NOTE* The timing loops have only been validated on 6 Mhz. AT
  372.  
  373. ; Copyright (c) 1986 Dan Jacobs and Joel Rosenblum 
  374.  
  375. ; portions copyrighted by Hercules Corp. and International Business Machines Corp. 
  376.  
  377. ; For a more complete test of the EGA adapter card see IBM Seminar Proceedings 
  378. ; Vol. 2, No. 11-1
  379.  
  380.     name    video_test      ;determine video adapter card
  381.  
  382.     include    dos.mac        ; Lattice C memory model configuration macro
  383.                 ; In this case it is a copy of dm8086.mac
  384.  
  385. ; *NOTE* all the below equates must be the same as list1.c
  386.  
  387. ; video mode equates   
  388. CGA        equ    01H    ; IBM Color graphics adapter (CGA)
  389. MONO        equ    02H    ; IBM Monochrome card
  390. HERCULES    equ    04H    ; Hercules monochrome graphics card
  391. PGA        equ    08H    ; Professional graphics controller (PGA)
  392. EGA_MONO    equ    10H    ; IBM Enhanced graphics adapter (EGA) w/monochrome display
  393. EGA_COLOR    equ    20H    ; EGA w/color display
  394. EGA_HIGH    equ    40H    ; EGA w/high resolution color display
  395. UNKNOWN        equ    80H    ; Unknown board type
  396.  
  397. ; machine type equates
  398. IBMCOMPAT    equ    0100H
  399. IBMPC        equ    0200H
  400. IBMPCAT        equ    0400H
  401. IBM_CONVERT    equ    0800H
  402.  
  403. ; global equates
  404. VIDEO_IO    equ    10H    ; BIOS video i/o interrupt number
  405. GET_MODE    equ    0FH    ; video i/o get mode function
  406.  
  407.     DSEG
  408.  
  409. video_type    db    ?    ; place to accumulate the video type
  410. t_features    dw    ?    ; machine discriptor passed to function
  411.  
  412.     ENDDS
  413.  
  414.     PSEG
  415.  
  416. comment\**********************************************************************
  417.  
  418. NAME
  419.     Video_test - checks to see which video adapter and display are used
  420.  
  421. SYNOPSIS
  422.     unsigned int Video_test (features);
  423.     unsigned features;            see definition of machine type
  424.  
  425. RETURN VALUE
  426.     type of video board used
  427.         01H = Color graphics adapter
  428.         02H = Monochrome card
  429.         04H = Hercules card
  430.         08H = Professional graphics adapter
  431.         10H = EGA w/monocrome display
  432.         20H = EGA w/color display
  433.         40H = EGA w/high resolution color display
  434.         80H = Unknown video card
  435.  
  436. *****************************************************************************\
  437.  
  438.         public    video_test
  439.  
  440. video_test    proc    near
  441.  
  442.     push    bp        ; save the frame pointer (if called from C)
  443.     mov    bp, sp
  444.  
  445.     ; next, save the passed existing features
  446.     mov    ax, 4[bp]
  447.     mov    t_features, ax
  448.     
  449. check_ega:
  450.     ; Unfortunately this method of checking the EGA requires the use of
  451.     ; BIOS routines.  Therefore, it can only be used on compatible 
  452.     ; machines. We first, however, determine if we can make the BIOS call.
  453.  
  454.     ; We use FEATURES to check if the BIOS int 10
  455.     ; is available for use.
  456.           
  457.     test    t_features, IBMCOMPAT + IBMPC + IBMPCAT
  458.     jz    ega_done        ; can only do this test on compatible
  459.  
  460.     mov    ax, 1200H        ; video alternate select
  461.     mov    bl, 10H            ; return EGA info
  462.     mov    bh, 0FFH        ; invalid data for test
  463.     mov    cl, 0FH            ; reserved switch setting
  464.     int    VIDEO_IO        ; returns with bh = color or mono mode
  465.                     ;            bl = memory value
  466.                     ;            ch = feature bits
  467.                     ;            cl = switch setting            
  468.         
  469.     cmp    cl, 0CH            ; test switch setting
  470.     jge    ega_done        ; above max setting
  471.     cmp    bh, 01H            ; test range 0 - 1
  472.     jg    ega_done        ; above range
  473.     cmp    bl, 03H            ; check memory value for 0 - 3 range
  474.     jg    ega_done        ; above range
  475.  
  476.     ; if it gets here, there is a EGA card present
  477.     ; now test for the attached monitor
  478.  
  479.     and    cl, 0EH            ; trim the switch to the bits we need
  480.     cmp    cl, 1010B        ; monochrome monitor attached ?
  481.     je    is_m
  482.     cmp    cl, 0100B        ; secondary mono setting ?
  483.     jne    color            ; nope check color display
  484. is_m:    or    video_type, EGA_MONO    ; set EGA card with monochrome display
  485.     jmp    short ega_done
  486. color:    cmp    cl, 1000B        ; primary color display    ?
  487.     je    is_c
  488.     cmp    cl, 1110B        ; secondary color ?
  489.     jne    enh_d            ; check for high resolution display
  490. is_c:    or    video_type, EGA_COLOR    ; EGA card with color display
  491.     jmp    short ega_done
  492. enh_d:    cmp    cl, 1100B        ; primary high resolution display ?
  493.     je    is_enh
  494.     cmp    cl, 0110B        ; secondary high resolution display ?
  495.     jne    ega_done
  496. is_enh:    or    video_type, EGA_HIGH    ; EGA card with high resolution color display
  497.  
  498. ega_done:
  499.  
  500.     ; check for Hercules card is present by checking the status port
  501.     ; at 3BAH for the vertical retrace bit.
  502.     ; **NOTE** you can also tell the mode the card is in and set the card
  503.     ; mode.  For more information, contact Hercules technical support. 
  504.  
  505.     mov    dx,3BAH            ; address of status port
  506.     in    al,dx
  507.     and    al,80h            ; vertical retrace bit
  508.     mov    ah,al            ; Save bit 7 for test
  509.  
  510.     mov    cx,8000h        ; count for delay loop
  511. examine:
  512.     in    al,dx            ; Take another reading
  513.     and    al,80h            ; Isolate bit 7
  514.     cmp    al,ah
  515.     jne    is_hercules        ; If bit 7 changes then it
  516.     loop    examine            ; is a Hercules Graphics Card
  517.  
  518.     jmp    check_color        ; After this long, it must be
  519.                     ; something else.
  520. is_hercules:
  521.     or    video_type, HERCULES
  522.     jmp    short check_pga        ; don't check for mono or color
  523.                     ; board if Hercules present
  524.                     
  525. check_color:
  526.     test    video_type, EGA_COLOR + EGA_HIGH
  527.     jnz    check_mono        ; can't have a color card with
  528.                     ; EGA in color mode
  529.  
  530.     ; next check for a Color Graphics Adapter by the checking for the
  531.     ; presence of the cursor register at 0x3D4
  532.     mov    dx, 03D4H
  533.     call    cursor_reg        ; carry flag set if not there
  534.     jc    check_mono
  535.     or    video_type, CGA        ; there is a color graphics adapter
  536.  
  537. check_mono:
  538.     test    video_type, EGA_MONO    ; can't have mono card in machine
  539.     jnz    check_pga        ; with EGA in mono
  540.  
  541.     ; first check for a monochrome board by checking for the
  542.     ; presence of the cursor register at 0x3B4
  543.     mov    dx, 03B4H
  544.     call    cursor_reg        ; carry flag set if not there
  545.     jc    check_pga
  546.     or     video_type, MONO    ; there is a monochrome adapter card
  547.     
  548. check_pga:
  549.     ; now test for a Professional Graphics Adapter by checking the cursor
  550.     ; status register which is memory mapped to address C600:03DB
  551.  
  552.     push    es
  553.     mov    ax, 0C600H        ; load segment
  554.     mov    es, ax
  555.     mov    di, 03DBH        ; load offset
  556.     mov    ah, es:[di]        ; save the original value
  557.     mov    byte ptr es:[di], 5AH    ; test value
  558.     mov    al, byte ptr es:[di]    ; read it back
  559.     mov    byte ptr es:[di], ah    ; restore original
  560.         cmp    al, 5AH
  561.     pop    es            ; clear stack
  562.     jne    check_done        ; no PGA adapter
  563.     or    video_type, PGA        ; yes, it's there
  564.  
  565. check_done:
  566.     cmp    video_type, 0        ; When all else fails...
  567.     jne    exit            ; can't recognize any card
  568.     mov    video_type, UNKNOWN
  569.  
  570. exit:    xor    ax, ax            ; clear ah
  571.     mov    al, video_type
  572.  
  573.     pop    bp                  ; restore frame pointer    to return to C caller
  574.  
  575.     ret
  576.  
  577. video_test    endp
  578.  
  579.  
  580. comment\**********************************************************************
  581.  
  582. NAME
  583.     cursor_reg
  584.  
  585. SYNOPSIS
  586.     checks to see if there is a cursor register at the
  587.     address passed in dx    
  588.  
  589. RETURN VALUE
  590.     carry clear - if cursor register present
  591.     carry set   - no cursor register here
  592.  
  593. *****************************************************************************\
  594. cursor_reg    proc    near
  595.  
  596.     mov    al, 0FH        ; set the index to the cursor register    
  597.      out    dx, al
  598.     inc    dx        ; increment to data register
  599.     in    al, dx        ; get the original value
  600.     xchg    al, ah        ; save it for later
  601.     mov    al, 5AH        ; test value
  602.     out    dx, al        ; set cursor control register
  603.         jmp     $+2             ; waste some time
  604.         jmp     $+2
  605.         jmp     $+2
  606.     in    al, dx
  607.     cmp    al, 5AH        ; same as written ?
  608.     xchg    al, ah        ; restore saved value
  609.     out    dx, al
  610.     je    yup        ; it was the control register
  611.     stc            ; no cursor return code
  612.     ret
  613. yup:    clc            ; is there return code
  614.     ret
  615.  
  616. cursor_reg    endp
  617.  
  618.     ENDPS
  619.     end
  620.  
  621.