12 EXTRN TimeCount:WORD ; incremented every 70th of a second
\r
13 EXTRN linewidth:WORD
\r
19 ;===========================================================================
\r
24 ; VL_WaitVBL ******** NEW *********
\r
26 ; Wait for the vertical retrace (returns before the actual vertical sync)
\r
30 PROC VL_WaitVBL num:WORD
\r
34 mov dx,STATUS_REGISTER_1
\r
38 ; wait for a display signal to make sure the raster isn't in the middle
\r
59 ;===========================================================================
\r
67 PROC VL_SetCRTC crtc:WORD
\r
71 ; wait for a display signal to make sure the raster isn't in the middle
\r
76 mov dx,STATUS_REGISTER_1
\r
80 test al,1 ;1 = display is disabled (HBL / VBL)
\r
87 ; for some reason, my XT's EGA card doesn't like word outs to the CRTC
\r
92 mov al,0ch ;start address high register
\r
98 mov al,0dh ;start address low register
\r
113 ;===========================================================================
\r
121 PROC VL_SetScreen crtc:WORD, pel:WORD
\r
122 PUBLIC VL_SetScreen
\r
125 mov cx,[timecount] ; if timecount goes up by two, the retrace
\r
126 add cx,2 ; period was missed (an interrupt covered it)
\r
128 mov dx,STATUS_REGISTER_1
\r
131 ; wait for a display signal to make sure the raster isn't in the middle
\r
136 test al,1 ;1 = display is disabled (HBL / VBL)
\r
145 cmp [timecount],cx ; will only happen if an interrupt is
\r
146 jae @@setcrtc ; straddling the entire retrace period
\r
149 ; when several succesive display not enableds occur,
\r
150 ; the bottom of the screen has been hit
\r
190 ; for some reason, my XT's EGA card doesn't like word outs to the CRTC
\r
195 mov al,0ch ;start address high register
\r
201 mov al,0dh ;start address low register
\r
208 ; set horizontal panning
\r
211 mov al,ATR_PELPAN or 20h
\r
214 mov al,[BYTE pel] ;pel pan value
\r
224 ;===========================================================================
\r
227 ;============================================================================
\r
229 ; VL_ScreenToScreen
\r
231 ; Basic block copy routine. Copies one block of screen memory to another,
\r
232 ; using write mode 1 (sets it and returns with write mode 0). bufferofs is
\r
233 ; NOT accounted for.
\r
235 ;============================================================================
\r
237 PROC VL_ScreenToScreen source:WORD, dest:WORD, wide:WORD, height:WORD
\r
238 PUBLIC VL_ScreenToScreen
\r
245 mov ax,SC_MAPMASK+15*256
\r
266 mov di,[dest] ;start at same place in all planes
\r
267 mov dx,[height] ;scan lines to draw
\r
285 mov ds,ax ;restore turbo's data segment
\r
292 ;===========================================================================
\r
296 ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
\r
300 ; Function: Detects the presence of various video subsystems
\r
304 ; Subsystem ID values:
\r
313 ; 82h = Hercules InColor
\r
315 ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
\r
317 ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
\r
321 ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
\r
322 VIDstruct STRUC ; corresponds to C data structure
\r
324 Video0Type DB ? ; first subsystem type
\r
325 Display0Type DB ? ; display attached to first subsystem
\r
327 Video1Type DB ? ; second subsystem type
\r
328 Display1Type DB ? ; display attached to second subsystem
\r
333 Device0 EQU word ptr Video0Type[di]
\r
334 Device1 EQU word ptr Video1Type[di]
\r
337 MDA EQU 1 ; subsystem types
\r
346 MDADisplay EQU 1 ; display types
\r
348 EGAColorDisplay EQU 3
\r
349 PS2MonoDisplay EQU 4
\r
350 PS2ColorDisplay EQU 5
\r
355 ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
\r
359 ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
\r
361 Results VIDstruct <> ;results go here!
\r
363 EGADisplays DB CGADisplay ; 0000b, 0001b (EGA switch values)
\r
364 DB EGAColorDisplay ; 0010b, 0011b
\r
365 DB MDADisplay ; 0100b, 0101b
\r
366 DB CGADisplay ; 0110b, 0111b
\r
367 DB EGAColorDisplay ; 1000b, 1001b
\r
368 DB MDADisplay ; 1010b, 1011b
\r
370 DCCtable DB 0,0 ; translate table for INT 10h func 1Ah
\r
374 DB EGA,EGAColorDisplay
\r
377 DB VGA,PS2MonoDisplay
\r
378 DB VGA,PS2ColorDisplay
\r
380 DB MCGA,EGAColorDisplay
\r
381 DB MCGA,PS2MonoDisplay
\r
382 DB MCGA,PS2ColorDisplay
\r
384 TestSequence DB TRUE ; this list of flags and addresses
\r
385 DW FindPS2 ; determines the order in which this
\r
386 ; program looks for the various
\r
387 EGAflag DB ? ; subsystems
\r
396 NumberOfTests EQU ($-TestSequence)/3
\r
402 push bp ; preserve caller registers
\r
412 ; initialize the data structure that will contain the results
\r
414 lea di,Results ; DS:DI -> start of data structure
\r
416 mov Device0,0 ; zero these variables
\r
419 ; look for the various subsystems using the subroutines whose addresses are
\r
420 ; tabulated in TestSequence; each subroutine sets flags in TestSequence
\r
421 ; to indicate whether subsequent subroutines need to be called
\r
423 mov byte ptr CGAflag,TRUE
\r
424 mov byte ptr EGAflag,TRUE
\r
425 mov byte ptr Monoflag,TRUE
\r
427 mov cx,NumberOfTests
\r
428 mov si,offset TestSequence
\r
430 @@L01: lodsb ; AL := flag
\r
432 lodsw ; AX := subroutine address
\r
433 jz @@L02 ; skip subroutine if flag is false
\r
437 call ax ; call subroutine to detect subsystem
\r
443 ; determine which subsystem is active
\r
447 mov al,Results.Video0Type
\r
448 mov ah,0 ; was: Results.Display0Type
\r
450 pop di ; restore caller registers and return
\r
463 ; This subroutine uses INT 10H function 1Ah to determine the video BIOS
\r
464 ; Display Combination Code (DCC) for each video subsystem present.
\r
470 int 10h ; call video BIOS for info
\r
473 jne @@L13 ; exit if function not supported (i.e.,
\r
474 ; no MCGA or VGA in system)
\r
476 ; convert BIOS DCCs into specific subsystems & displays
\r
479 xor bh,bh ; BX := DCC for active subsystem
\r
482 jz @@L11 ; jump if only one subsystem present
\r
484 mov bl,ch ; BX := inactive DCC
\r
486 mov ax,[bx+offset DCCtable]
\r
491 xor bh,bh ; BX := active DCC
\r
494 mov ax,[bx+offset DCCtable]
\r
498 ; reset flags for subsystems that have been ruled out
\r
500 mov byte ptr CGAflag,FALSE
\r
501 mov byte ptr EGAflag,FALSE
\r
502 mov byte ptr Monoflag,FALSE
\r
504 lea bx,Video0Type[di] ; if the BIOS reported an MDA ...
\r
505 cmp byte ptr [bx],MDA
\r
508 lea bx,Video1Type[di]
\r
509 cmp byte ptr [bx],MDA
\r
512 @@L12: mov word ptr [bx],0 ; ... Hercules can't be ruled out
\r
513 mov byte ptr Monoflag,TRUE
\r
523 ; Look for an EGA. This is done by making a call to an EGA BIOS function
\r
524 ; which doesn't exist in the default (MDA, CGA) BIOS.
\r
526 FindEGA PROC near ; Caller: AH = flags
\r
527 ; Returns: AH = flags
\r
529 ; Display0Type updated
\r
531 mov bl,10h ; BL := 10h (return EGA info)
\r
532 mov ah,12h ; AH := INT 10H function number
\r
533 int 10h ; call EGA BIOS for info
\r
534 ; if EGA BIOS is present,
\r
536 ; CL = switch setting
\r
538 je @@L22 ; jump if EGA BIOS not present
\r
541 shr al,1 ; AL := switches/2
\r
542 mov bx,offset EGADisplays
\r
543 xlat ; determine display type from switches
\r
544 mov ah,al ; AH := display type
\r
545 mov al,EGA ; AL := subystem type
\r
549 je @@L21 ; jump if EGA has a monochrome display
\r
551 mov CGAflag,FALSE ; no CGA if EGA has color display
\r
554 @@L21: mov Monoflag,FALSE ; EGA has a mono display, so MDA and
\r
555 ; Hercules are ruled out
\r
563 ; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
\r
565 FindCGA PROC near ; Returns: VIDstruct updated
\r
567 mov dx,3D4h ; DX := CRTC address port
\r
569 jc @@L31 ; jump if not present
\r
582 ; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H. If
\r
583 ; a 6845 is found, the subroutine distinguishes between an MDA
\r
584 ; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
\r
585 ; This bit changes on Hercules adapters but does not change on an MDA.
\r
587 ; The various Hercules adapters are identified by bits 4 through 6 of
\r
588 ; the CRT Status value:
\r
592 ; 101b = InColor card
\r
595 FindMono PROC near ; Returns: VIDstruct updated
\r
597 mov dx,3B4h ; DX := CRTC address port
\r
599 jc @@L44 ; jump if not present
\r
601 mov dl,0BAh ; DX := 3BAh (status port)
\r
604 mov ah,al ; AH := bit 7 (vertical sync on HGC)
\r
606 mov cx,8000h ; do this 32768 times
\r
608 and al,80h ; isolate bit 7
\r
610 loope @@L41 ; wait for bit 7 to change
\r
611 jne @@L42 ; if bit 7 changed, it's a Hercules
\r
613 mov al,MDA ; if bit 7 didn't change, it's an MDA
\r
619 mov dl,al ; DL := value from status port
\r
620 and dl,01110000b ; mask bits 4 thru 6
\r
622 mov ah,MDADisplay ; assume it's a monochrome display
\r
624 mov al,HGCPlus ; look for an HGC+
\r
626 je @@L43 ; jump if it's an HGC+
\r
628 mov al,HGC ; look for an InColor card or HGC
\r
630 jne @@L43 ; jump if it's not an InColor card
\r
632 mov al,InColor ; it's an InColor card
\r
633 mov ah,EGAColorDisplay
\r
635 @@L43: call FoundDevice
\r
644 ; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
\r
645 ; The technique is to write and read register 0Fh of the chip (cursor
\r
646 ; low). If the same value is read as written, assume the chip is
\r
647 ; present at the specified port addr.
\r
650 Find6845 PROC near ; Caller: DX = port addr
\r
651 ; Returns: cf set if not present
\r
653 out dx,al ; select 6845 reg 0Fh (Cursor Low)
\r
655 in al,dx ; AL := current Cursor Low value
\r
656 mov ah,al ; preserve in AH
\r
657 mov al,66h ; AL := arbitrary value
\r
658 out dx,al ; try to write to 6845
\r
661 @@L51: loop @@L51 ; wait for 6845 to respond
\r
664 xchg ah,al ; AH := returned value
\r
665 ; AL := original value
\r
666 out dx,al ; restore original value
\r
668 cmp ah,66h ; test whether 6845 responded
\r
669 je @@L52 ; jump if it did (cf is reset)
\r
671 stc ; set carry flag if no 6845 present
\r
681 ; This subroutine stores the currently active device as Device0. The
\r
682 ; current video mode determines which subsystem is active.
\r
685 FindActive PROC near
\r
687 cmp word ptr Device1,0
\r
688 je @@L63 ; exit if only one subsystem
\r
690 cmp Video0Type[di],4 ; exit if MCGA or VGA present
\r
691 jge @@L63 ; (INT 10H function 1AH
\r
692 cmp Video1Type[di],4 ; already did the work)
\r
696 int 10h ; AL := current BIOS video mode
\r
699 cmp al,7 ; jump if monochrome
\r
700 je @@L61 ; (mode 7 or 0Fh)
\r
702 cmp Display0Type[di],MDADisplay
\r
703 jne @@L63 ; exit if Display0 is color
\r
706 @@L61: cmp Display0Type[di],MDADisplay
\r
707 je @@L63 ; exit if Display0 is monochrome
\r
709 @@L62: mov ax,Device0 ; make Device0 currently active
\r
721 ; This routine updates the list of subsystems.
\r
724 FoundDevice PROC near ; Caller: AH = display #
\r
727 lea bx,Video0Type[di]
\r
728 cmp byte ptr [bx],0
\r
729 je @@L71 ; jump if 1st subsystem
\r
731 lea bx,Video1Type[di] ; must be 2nd subsystem
\r
733 @@L71: mov [bx],ax ; update list entry
\r