User:Johnburger/Demo/Boot/VGA
With the vast number of video adapters on the market, all with their proprietary (and often secret!) access methods, video drivers are the biggest problem for PC system developers. There are certain industry-standard modes and conventions, but the really clever stuff needs drivers provided by the video card manufacturers.
Before leaving Real Mode, now would be the perfect time to set the desired Video Mode using the BIOS. All VGAs support 80x50 mode, so that will be the lowest common denominator for this Demonstrator. Some systems support 90x60 too - VMware is a perfect example! That gives me more experimenting room; but I need a way to disable it in the source code. The easiest is to use %define BIOS.VGA.90x60
.
Note though that the 90x60 code takes up a fair bit of space. That will probably be the second code against The Wall if I run out of room...
Oh, and set the cursor to invisible too.
Demo/Boot/VGA.inc
; ; Boot/VGA.inc ; ; Use the BIOS to set the desired video mode (80x50 by default: 90x60 if enabled) VGA.Set80x25 EQU (BIOS.VGA.SetMode.Fn << 8) | BIOS.VGA.SetMode.80x25 VGA.Ext80x50 EQU (BIOS.VGA.ExtMode.Fn << 8) | BIOS.VGA.ExtMode.80x50 ; Note: DS and ES are 0000h Boot.VGA: MOV AX,VGA.Set80x25 ; Set 80x25 mode, 8x16 font INT BIOS.VGA.Int MOV AX,VGA.Ext80x50 ; Ext 80x50 mode, 8x8 font MOV BL,0 INT BIOS.VGA.Int %ifndef BIOS.VGA.90x60 VGA.Rows EQU 50 VGA.Cols EQU 80 MOV AH,BIOS.VGA.Cursor.Fn ; Set cursor size MOV CX,BIOS.VGA.Cursor.None ; To invisible INT BIOS.VGA.Int %else ; BIOS.VGA.90x60 VGA.Rows EQU 60 VGA.Cols EQU 90 ;------------------------------------------------------------------------------- ; I know I said I don't like "magic numbers", but the following is esoteric! MOV AL,0E7h MOV DX,Dev.VGA.Misc.Port OUT DX,AL CLD ; Work forwards MOV SI,Boot.VGA.Seq MOV CX,.Seq.Num ; This many Seq registers MOV DX,Dev.VGA.Seq.Base CALL Boot.VGA.Write MOV AL,017h ; Enable regs 0-7 MOV DX,Dev.VGA.CRTC.Base OUT DX,AL INC DX ; Go to Data port IN AL,DX AND AL,~80h ; Enable registers OUT DX,AL DEC DX ; Back to Index port MOV AL,003h ; Enable vertical retrace OUT DX,AL INC DX ; Go to Data port IN AL,DX OR AL,80h ; Enable registers OUT DX,AL DEC DX ; Back to Index port MOV CX,.CRTC.Num ; This many CRTC registers PUSH Boot.VGA.End ; Fake a call from .End ;------------------------------------------------------------------------------- .Write: MOV AH,0 ; Start with register 0 .Write.Loop: CS ; Load from Code Segment! LODSB XCHG AL,AH ; Make sure Index is in AL OUT DX,AX ; 16-bit write MOV AH,AL ; But need AL for LODSB INC AH ; Next index LOOP .Write.Loop RET .Seq DB 003h, 001h, 003h, 000h, 002h ; Sequence registers .Seq.Num EQU $-.Seq .CRTC DB 06Bh, 059h, 05Ah, 082h, 060h, 08Dh, 00Bh, 03Eh DB 000h, 047h, 020h, 000h, 000h, 000h, 000h, 000h DB 0EAh, 00Ch, 0DFh, 02Dh, 008h, 0E8h, 005h, 0A3h DB 0FFh ; CRTC registers .CRTC.Num EQU $-.CRTC %endif ; BIOS.VGA.90x60 .End: