home *** CD-ROM | disk | FTP | other *** search
/ 100 af Verdens Bedste Spil / 100Spil.iso / dos / wolf3d / source / wolfsrc.1 / ID_VL_A.ASM < prev    next >
Assembly Source File  |  1993-02-04  |  14KB  |  743 lines

  1. ; ID_VL.ASM
  2.  
  3.     IDEAL
  4.     MODEL    MEDIUM,C
  5.  
  6.     INCLUDE    'ID_VL.EQU'
  7.  
  8. SCREENSEG    =    0a000h
  9.  
  10.     DATASEG
  11.  
  12.     EXTRN    TimeCount:WORD        ; incremented every 70th of a second
  13.     EXTRN    linewidth:WORD
  14.  
  15. starttime    dw    ?
  16.  
  17.     CODESEG
  18.  
  19. ;===========================================================================
  20.  
  21.  
  22. ;==============
  23. ;
  24. ; VL_WaitVBL            ******** NEW *********
  25. ;
  26. ; Wait for the vertical retrace (returns before the actual vertical sync)
  27. ;
  28. ;==============
  29.  
  30. PROC    VL_WaitVBL  num:WORD
  31. PUBLIC    VL_WaitVBL
  32. @@wait:
  33.  
  34.     mov    dx,STATUS_REGISTER_1
  35.  
  36.     mov    cx,[num]
  37. ;
  38. ; wait for a display signal to make sure the raster isn't in the middle
  39. ; of a sync
  40. ;
  41. @@waitnosync:
  42.     in    al,dx
  43.     test    al,8
  44.     jnz    @@waitnosync
  45.  
  46.  
  47. @@waitsync:
  48.     in    al,dx
  49.     test    al,8
  50.     jz    @@waitsync
  51.  
  52.     loop    @@waitnosync
  53.  
  54.     ret
  55.  
  56. ENDP
  57.  
  58.  
  59. ;===========================================================================
  60.  
  61. ;==============
  62. ;
  63. ; VL_SetCRTC
  64. ;
  65. ;==============
  66.  
  67. PROC    VL_SetCRTC  crtc:WORD
  68. PUBLIC    VL_SetCRTC
  69.  
  70. ;
  71. ; wait for a display signal to make sure the raster isn't in the middle
  72. ; of a sync
  73. ;
  74.     cli
  75.  
  76.     mov    dx,STATUS_REGISTER_1
  77.  
  78. @@waitdisplay:
  79.     in    al,dx
  80.     test    al,1    ;1 = display is disabled (HBL / VBL)
  81.     jnz    @@waitdisplay
  82.  
  83.  
  84. ;
  85. ; set CRTC start
  86. ;
  87. ; for some reason, my XT's EGA card doesn't like word outs to the CRTC
  88. ; index...
  89. ;
  90.     mov    cx,[crtc]
  91.     mov    dx,CRTC_INDEX
  92.     mov    al,0ch        ;start address high register
  93.     out    dx,al
  94.     inc    dx
  95.     mov    al,ch
  96.     out    dx,al
  97.     dec    dx
  98.     mov    al,0dh        ;start address low register
  99.     out    dx,al
  100.     mov    al,cl
  101.     inc    dx
  102.     out    dx,al
  103.  
  104.  
  105.     sti
  106.  
  107.     ret
  108.  
  109. ENDP
  110.  
  111.  
  112.  
  113. ;===========================================================================
  114.  
  115. ;==============
  116. ;
  117. ; VL_SetScreen
  118. ;
  119. ;==============
  120.  
  121. PROC    VL_SetScreen  crtc:WORD, pel:WORD
  122. PUBLIC    VL_SetScreen
  123.  
  124.  
  125.     mov    cx,[timecount]        ; if timecount goes up by two, the retrace
  126.     add    cx,2                ; period was missed (an interrupt covered it)
  127.  
  128.     mov    dx,STATUS_REGISTER_1
  129.  
  130. ;
  131. ; wait for a display signal to make sure the raster isn't in the middle
  132. ; of a sync
  133. ;
  134. @@waitdisplay:
  135.     in    al,dx
  136.     test    al,1    ;1 = display is disabled (HBL / VBL)
  137.     jnz    @@waitdisplay
  138.  
  139.  
  140. @@loop:
  141.     sti
  142.     jmp    $+2
  143.     cli
  144.  
  145.     cmp    [timecount],cx        ; will only happen if an interrupt is
  146.     jae    @@setcrtc            ; straddling the entire retrace period
  147.  
  148. ;
  149. ; when several succesive display not enableds occur,
  150. ; the bottom of the screen has been hit
  151. ;
  152.  
  153.     in    al,dx
  154.     test    al,8
  155.     jnz    @@waitdisplay
  156.     test    al,1
  157.     jz    @@loop
  158.  
  159.     in    al,dx
  160.     test    al,8
  161.     jnz    @@waitdisplay
  162.     test    al,1
  163.     jz    @@loop
  164.  
  165.     in    al,dx
  166.     test    al,8
  167.     jnz    @@waitdisplay
  168.     test    al,1
  169.     jz    @@loop
  170.  
  171.     in    al,dx
  172.     test    al,8
  173.     jnz    @@waitdisplay
  174.     test    al,1
  175.     jz    @@loop
  176.  
  177.     in    al,dx
  178.     test    al,8
  179.     jnz    @@waitdisplay
  180.     test    al,1
  181.     jz    @@loop
  182.  
  183.  
  184. @@setcrtc:
  185.  
  186.  
  187. ;
  188. ; set CRTC start
  189. ;
  190. ; for some reason, my XT's EGA card doesn't like word outs to the CRTC
  191. ; index...
  192. ;
  193.     mov    cx,[crtc]
  194.     mov    dx,CRTC_INDEX
  195.     mov    al,0ch        ;start address high register
  196.     out    dx,al
  197.     inc    dx
  198.     mov    al,ch
  199.     out    dx,al
  200.     dec    dx
  201.     mov    al,0dh        ;start address low register
  202.     out    dx,al
  203.     mov    al,cl
  204.     inc    dx
  205.     out    dx,al
  206.  
  207. ;
  208. ; set horizontal panning
  209. ;
  210.     mov    dx,ATR_INDEX
  211.     mov    al,ATR_PELPAN or 20h
  212.     out    dx,al
  213.     jmp    $+2
  214.     mov    al,[BYTE pel]        ;pel pan value
  215.     out    dx,al
  216.  
  217.     sti
  218.  
  219.     ret
  220.  
  221. ENDP
  222.  
  223.  
  224. ;===========================================================================
  225.  
  226.  
  227. ;============================================================================
  228. ;
  229. ; VL_ScreenToScreen
  230. ;
  231. ; Basic block copy routine.  Copies one block of screen memory to another,
  232. ; using write mode 1 (sets it and returns with write mode 0).  bufferofs is
  233. ; NOT accounted for.
  234. ;
  235. ;============================================================================
  236.  
  237. PROC    VL_ScreenToScreen    source:WORD, dest:WORD, wide:WORD, height:WORD
  238. PUBLIC    VL_ScreenToScreen
  239. USES    SI,DI
  240.  
  241.     pushf
  242.     cli
  243.  
  244.     mov    dx,SC_INDEX
  245.     mov    ax,SC_MAPMASK+15*256
  246.     out    dx,ax
  247.     mov    dx,GC_INDEX
  248.     mov    al,GC_MODE
  249.     out    dx,al
  250.     inc    dx
  251.     in    al,dx
  252.     and    al,NOT 3
  253.     or    al,1
  254.     out    dx,al
  255.  
  256.     popf
  257.  
  258.     mov    bx,[linewidth]
  259.     sub    bx,[wide]
  260.  
  261.     mov    ax,SCREENSEG
  262.     mov    es,ax
  263.     mov    ds,ax
  264.  
  265.     mov    si,[source]
  266.     mov    di,[dest]                ;start at same place in all planes
  267.     mov    dx,[height]                ;scan lines to draw
  268.     mov    ax,[wide]
  269.  
  270. @@lineloop:
  271.     mov    cx,ax
  272.     rep    movsb
  273.     add    si,bx
  274.     add    di,bx
  275.  
  276.     dec    dx
  277.     jnz    @@lineloop
  278.  
  279.     mov    dx,GC_INDEX+1
  280.     in    al,dx
  281.     and    al,NOT 3
  282.     out    dx,al
  283.  
  284.     mov    ax,ss
  285.     mov    ds,ax                    ;restore turbo's data segment
  286.  
  287.     ret
  288.  
  289. ENDP
  290.  
  291.  
  292. ;===========================================================================
  293.  
  294.  
  295.     MASM
  296. ;═════════════════════════════════════════════════════════
  297. ;
  298. ; Name:    VL_VideoID
  299. ;
  300. ; Function:    Detects the presence of various video subsystems
  301. ;
  302. ; int VideoID;
  303. ;
  304. ; Subsystem ID values:
  305. ;      0  = (none)
  306. ;      1  = MDA
  307. ;      2  = CGA
  308. ;      3  = EGA
  309. ;      4  = MCGA
  310. ;      5  = VGA
  311. ;     80h = HGC
  312. ;     81h = HGC+
  313. ;     82h = Hercules InColor
  314. ;
  315. ;═════════════════════════════════════════════════════════
  316.  
  317. ;═════════════════════════════════════════════════════════
  318. ;
  319. ; Equates
  320. ;
  321. ;═════════════════════════════════════════════════════════
  322. VIDstruct    STRUC        ; corresponds to C data structure
  323.  
  324. Video0Type    DB    ?    ; first subsystem type
  325. Display0Type    DB    ?     ; display attached to first subsystem
  326.  
  327. Video1Type    DB    ?    ; second subsystem type
  328. Display1Type    DB    ?    ; display attached to second subsystem
  329.  
  330. VIDstruct    ENDS
  331.  
  332.  
  333. Device0    EQU    word ptr Video0Type[di]
  334. Device1    EQU    word ptr Video1Type[di]
  335.  
  336.  
  337. MDA    EQU    1    ; subsystem types
  338. CGA    EQU    2
  339. EGA    EQU    3
  340. MCGA    EQU    4
  341. VGA    EQU    5
  342. HGC    EQU    80h
  343. HGCPlus    EQU    81h
  344. InColor    EQU    82h
  345.  
  346. MDADisplay    EQU    1    ; display types
  347. CGADisplay    EQU    2
  348. EGAColorDisplay    EQU    3
  349. PS2MonoDisplay    EQU    4
  350. PS2ColorDisplay    EQU    5
  351.  
  352. TRUE    EQU    1
  353. FALSE    EQU    0
  354.  
  355. ;═════════════════════════════════════════════════════════
  356. ;
  357. ; Program
  358. ;
  359. ;═════════════════════════════════════════════════════════
  360.  
  361. Results    VIDstruct <>    ;results go here!
  362.  
  363. EGADisplays    DB    CGADisplay    ; 0000b, 0001b    (EGA switch values)
  364.     DB    EGAColorDisplay    ; 0010b, 0011b
  365.     DB    MDADisplay    ; 0100b, 0101b
  366.     DB    CGADisplay    ; 0110b, 0111b
  367.     DB    EGAColorDisplay    ; 1000b, 1001b
  368.     DB    MDADisplay    ; 1010b, 1011b
  369.  
  370. DCCtable    DB    0,0    ; translate table for INT 10h func 1Ah
  371.     DB    MDA,MDADisplay
  372.     DB    CGA,CGADisplay
  373.     DB    0,0
  374.     DB    EGA,EGAColorDisplay
  375.     DB    EGA,MDADisplay
  376.     DB    0,0
  377.     DB    VGA,PS2MonoDisplay
  378.     DB    VGA,PS2ColorDisplay
  379.     DB    0,0
  380.     DB    MCGA,EGAColorDisplay
  381.     DB    MCGA,PS2MonoDisplay
  382.     DB    MCGA,PS2ColorDisplay
  383.  
  384. TestSequence    DB    TRUE    ; this list of flags and addresses
  385.     DW    FindPS2    ;  determines the order in which this
  386.             ;  program looks for the various
  387. EGAflag    DB    ?    ;  subsystems
  388.     DW    FindEGA
  389.  
  390. CGAflag    DB    ?
  391.     DW    FindCGA
  392.  
  393. Monoflag    DB    ?
  394.     DW    FindMono
  395.  
  396. NumberOfTests    EQU    ($-TestSequence)/3
  397.  
  398.  
  399. PUBLIC    VL_VideoID
  400. VL_VideoID    PROC
  401.  
  402.     push    bp    ; preserve caller registers
  403.     mov    bp,sp
  404.     push    ds
  405.     push    si
  406.     push    di
  407.  
  408.     push    cs
  409.     pop    ds
  410.     ASSUME    DS:@Code
  411.  
  412. ; initialize the data structure that will contain the results
  413.  
  414.     lea    di,Results    ; DS:DI -> start of data structure
  415.  
  416.     mov    Device0,0    ; zero these variables
  417.     mov    Device1,0
  418.  
  419. ; look for the various subsystems using the subroutines whose addresses are
  420. ; tabulated in TestSequence; each subroutine sets flags in TestSequence
  421. ; to indicate whether subsequent subroutines need to be called
  422.  
  423.     mov    byte ptr CGAflag,TRUE
  424.     mov    byte ptr EGAflag,TRUE
  425.     mov    byte ptr Monoflag,TRUE
  426.  
  427.     mov    cx,NumberOfTests
  428.     mov    si,offset TestSequence
  429.  
  430. @@L01:    lodsb        ; AL := flag
  431.     test    al,al
  432.     lodsw        ; AX := subroutine address
  433.     jz    @@L02    ; skip subroutine if flag is false
  434.  
  435.     push    si
  436.     push    cx
  437.     call    ax    ; call subroutine to detect subsystem
  438.     pop    cx
  439.     pop    si
  440.  
  441. @@L02:    loop    @@L01
  442.  
  443. ; determine which subsystem is active
  444.  
  445.     call    FindActive
  446.  
  447.     mov    al,Results.Video0Type
  448.     mov    ah,0    ; was:  Results.Display0Type
  449.  
  450.     pop    di    ; restore caller registers and return
  451.     pop    si
  452.     pop    ds
  453.     mov    sp,bp
  454.     pop    bp
  455.     ret
  456.  
  457. VL_VideoID    ENDP
  458.  
  459.  
  460. ;
  461. ; FindPS2
  462. ;
  463. ; This subroutine uses INT 10H function 1Ah to determine the video BIOS
  464. ; Display Combination Code (DCC) for each video subsystem present.
  465. ;
  466.  
  467. FindPS2    PROC    near
  468.  
  469.     mov    ax,1A00h
  470.     int    10h    ; call video BIOS for info
  471.  
  472.     cmp    al,1Ah
  473.     jne    @@L13    ; exit if function not supported (i.e.,
  474.             ;  no MCGA or VGA in system)
  475.  
  476. ; convert BIOS DCCs into specific subsystems & displays
  477.  
  478.     mov    cx,bx
  479.     xor    bh,bh    ; BX := DCC for active subsystem
  480.  
  481.     or    ch,ch
  482.     jz    @@L11    ; jump if only one subsystem present
  483.  
  484.     mov    bl,ch    ; BX := inactive DCC
  485.     add    bx,bx
  486.     mov    ax,[bx+offset DCCtable]
  487.  
  488.     mov    Device1,ax
  489.  
  490.     mov    bl,cl
  491.     xor    bh,bh    ; BX := active DCC
  492.  
  493. @@L11:    add    bx,bx
  494.     mov    ax,[bx+offset DCCtable]
  495.  
  496.     mov    Device0,ax
  497.  
  498. ; reset flags for subsystems that have been ruled out
  499.  
  500.     mov    byte ptr CGAflag,FALSE
  501.     mov    byte ptr EGAflag,FALSE
  502.     mov    byte ptr Monoflag,FALSE
  503.  
  504.     lea    bx,Video0Type[di]  ; if the BIOS reported an MDA ...
  505.     cmp    byte ptr [bx],MDA
  506.     je    @@L12
  507.  
  508.     lea    bx,Video1Type[di]
  509.     cmp    byte ptr [bx],MDA
  510.     jne    @@L13
  511.  
  512. @@L12:    mov    word ptr [bx],0    ; ... Hercules can't be ruled out
  513.     mov    byte ptr Monoflag,TRUE
  514.  
  515. @@L13:    ret
  516.  
  517. FindPS2    ENDP
  518.  
  519.  
  520. ;
  521. ; FindEGA
  522. ;
  523. ; Look for an EGA.  This is done by making a call to an EGA BIOS function
  524. ;  which doesn't exist in the default (MDA, CGA) BIOS.
  525.  
  526. FindEGA    PROC    near    ; Caller:    AH = flags
  527.             ; Returns:    AH = flags
  528.             ;        Video0Type and
  529.             ;         Display0Type updated
  530.  
  531.     mov    bl,10h    ; BL := 10h (return EGA info)
  532.     mov    ah,12h    ; AH := INT 10H function number
  533.     int    10h    ; call EGA BIOS for info
  534.             ; if EGA BIOS is present,
  535.             ;  BL <> 10H
  536.             ;  CL = switch setting
  537.     cmp    bl,10h
  538.     je    @@L22    ; jump if EGA BIOS not present
  539.  
  540.     mov    al,cl
  541.     shr    al,1    ; AL := switches/2
  542.     mov    bx,offset EGADisplays
  543.     xlat        ; determine display type from switches
  544.     mov    ah,al    ; AH := display type
  545.     mov    al,EGA    ; AL := subystem type
  546.     call    FoundDevice
  547.  
  548.     cmp    ah,MDADisplay
  549.     je    @@L21    ; jump if EGA has a monochrome display
  550.  
  551.     mov    CGAflag,FALSE    ; no CGA if EGA has color display
  552.     jmp    short @@L22
  553.  
  554. @@L21:    mov    Monoflag,FALSE    ; EGA has a mono display, so MDA and
  555.             ;  Hercules are ruled out
  556. @@L22:    ret
  557.  
  558. FindEGA    ENDP
  559.  
  560. ;
  561. ; FindCGA
  562. ;
  563. ; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
  564. ;
  565. FindCGA    PROC    near    ; Returns:    VIDstruct updated
  566.  
  567.     mov    dx,3D4h    ; DX := CRTC address port
  568.     call    Find6845
  569.     jc    @@L31    ; jump if not present
  570.  
  571.     mov    al,CGA
  572.     mov    ah,CGADisplay
  573.     call    FoundDevice
  574.  
  575. @@L31:    ret
  576.  
  577. FindCGA    ENDP
  578.  
  579. ;
  580. ; FindMono
  581. ;
  582. ; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H.  If
  583. ; a 6845 is found, the subroutine distinguishes between an MDA
  584. ; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
  585. ; This bit changes on Hercules adapters but does not change on an MDA.
  586. ;
  587. ; The various Hercules adapters are identified by bits 4 through 6 of
  588. ; the CRT Status value:
  589. ;
  590. ; 000b = HGC
  591. ; 001b = HGC+
  592. ; 101b = InColor card
  593. ;
  594.  
  595. FindMono    PROC    near    ; Returns:    VIDstruct updated
  596.  
  597.     mov    dx,3B4h    ; DX := CRTC address port
  598.     call    Find6845
  599.     jc    @@L44    ; jump if not present
  600.  
  601.     mov    dl,0BAh    ; DX := 3BAh (status port)
  602.     in    al,dx
  603.     and    al,80h
  604.     mov    ah,al    ; AH := bit 7 (vertical sync on HGC)
  605.  
  606.     mov    cx,8000h    ; do this 32768 times
  607. @@L41:    in    al,dx
  608.     and    al,80h    ; isolate bit 7
  609.     cmp    ah,al
  610.     loope    @@L41    ; wait for bit 7 to change
  611.     jne    @@L42    ; if bit 7 changed, it's a Hercules
  612.  
  613.     mov    al,MDA    ; if bit 7 didn't change, it's an MDA
  614.     mov    ah,MDADisplay
  615.     call    FoundDevice
  616.     jmp    short @@L44
  617.  
  618. @@L42:    in    al,dx
  619.     mov    dl,al    ; DL := value from status port
  620.     and    dl,01110000b    ; mask bits 4 thru 6
  621.  
  622.     mov    ah,MDADisplay    ; assume it's a monochrome display
  623.  
  624.     mov    al,HGCPlus    ; look for an HGC+
  625.     cmp    dl,00010000b
  626.     je    @@L43    ; jump if it's an HGC+
  627.  
  628.     mov    al,HGC    ; look for an InColor card or HGC
  629.     cmp    dl,01010000b
  630.     jne    @@L43    ; jump if it's not an InColor card
  631.  
  632.     mov    al,InColor    ; it's an InColor card
  633.     mov    ah,EGAColorDisplay
  634.  
  635. @@L43:    call    FoundDevice
  636.  
  637. @@L44:    ret
  638.  
  639. FindMono    ENDP
  640.  
  641. ;
  642. ; Find6845
  643. ;
  644. ; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
  645. ; The technique is to write and read register 0Fh of the chip (cursor
  646. ; low).  If the same value is read as written, assume the chip is
  647. ; present at the specified port addr.
  648. ;
  649.  
  650. Find6845    PROC    near    ; Caller:  DX = port addr
  651.             ; Returns: cf set if not present
  652.     mov    al,0Fh
  653.     out    dx,al    ; select 6845 reg 0Fh (Cursor Low)
  654.     inc    dx
  655.     in    al,dx    ; AL := current Cursor Low value
  656.     mov    ah,al    ; preserve in AH
  657.     mov    al,66h    ; AL := arbitrary value
  658.     out    dx,al    ; try to write to 6845
  659.  
  660.     mov    cx,100h
  661. @@L51:    loop    @@L51    ; wait for 6845 to respond
  662.  
  663.     in    al,dx
  664.     xchg    ah,al    ; AH := returned value
  665.             ; AL := original value
  666.     out    dx,al    ; restore original value
  667.  
  668.     cmp    ah,66h    ; test whether 6845 responded
  669.     je    @@L52    ; jump if it did (cf is reset)
  670.  
  671.     stc        ; set carry flag if no 6845 present
  672.  
  673. @@L52:    ret
  674.  
  675. Find6845    ENDP
  676.  
  677.  
  678. ;
  679. ; FindActive
  680. ;
  681. ; This subroutine stores the currently active device as Device0.  The
  682. ; current video mode determines which subsystem is active.
  683. ;
  684.  
  685. FindActive    PROC    near
  686.  
  687.     cmp    word ptr Device1,0
  688.     je    @@L63    ; exit if only one subsystem
  689.  
  690.     cmp    Video0Type[di],4    ; exit if MCGA or VGA present
  691.     jge    @@L63    ;  (INT 10H function 1AH
  692.     cmp    Video1Type[di],4    ;  already did the work)
  693.     jge    @@L63
  694.  
  695.     mov    ah,0Fh
  696.     int    10h    ; AL := current BIOS video mode
  697.  
  698.     and    al,7
  699.     cmp    al,7    ; jump if monochrome
  700.     je    @@L61    ;  (mode 7 or 0Fh)
  701.  
  702.     cmp    Display0Type[di],MDADisplay
  703.     jne    @@L63    ; exit if Display0 is color
  704.     jmp    short @@L62
  705.  
  706. @@L61:    cmp    Display0Type[di],MDADisplay
  707.     je    @@L63    ; exit if Display0 is monochrome
  708.  
  709. @@L62:    mov    ax,Device0    ; make Device0 currently active
  710.     xchg    ax,Device1
  711.     mov    Device0,ax
  712.  
  713. @@L63:    ret
  714.  
  715. FindActive    ENDP
  716.  
  717.  
  718. ;
  719. ; FoundDevice
  720. ;
  721. ; This routine updates the list of subsystems.
  722. ;
  723.  
  724. FoundDevice    PROC    near    ; Caller:    AH = display #
  725.             ;         AL = subsystem #
  726.             ; Destroys:  BX
  727.     lea    bx,Video0Type[di]
  728.     cmp    byte ptr [bx],0
  729.     je    @@L71    ; jump if 1st subsystem
  730.  
  731.     lea    bx,Video1Type[di]    ; must be 2nd subsystem
  732.  
  733. @@L71:    mov    [bx],ax    ; update list entry
  734.     ret
  735.  
  736. FoundDevice    ENDP
  737.  
  738. IDEAL
  739.  
  740.  
  741.  
  742. END
  743.