; =============================================================================
;
; Litos - Initialize graphics card, real mode
;
; =============================================================================
%ifdef DEBUG
;%define DEBUG_GRAPH ; uncomment this to display GRAPH info
%endif
CODE_SECTION 16
; ------------- Type of compatible videocard
VCARD_MDA EQU 0 ; MDA (Hercules)
VCARD_CGA EQU 1 ; CGA
VCARD_EGA EQU 2 ; EGA
VCARD_VGA EQU 3 ; VGA
; -----------------------------------------------------------------------------
; Call Int 10h interrupt with saving registers
; -----------------------------------------------------------------------------
; Notes: Some BIOSes destroy some registers, so we call it with saving them.
; -----------------------------------------------------------------------------
; ------------- Push registers
Int10: pushf ; push flags
push si ; push SI
push di ; push DI
push bp ; push BP
push ds ; push DS
push es ; push ES
; ------------- Call Int 10h
int 10h ; call int 10h
; ------------- Pop registers
pop es ; pop ES
pop ds ; pop DS
pop bp ; pop BP
pop di ; pop DI
pop si ; pop SI
popf ; pop flags
ret
; -----------------------------------------------------------------------------
; BIOS display character
; -----------------------------------------------------------------------------
; INPUT: AL = character to display
; -----------------------------------------------------------------------------
; ------------- Push registers
BIOSDispChar: push ax ; push AX
push bx ; push BX
push cx ; push CX
push dx ; push DX
; ------------- Display character
mov ah,0eh ; AH <- function code
mov bx,7 ; BL <- color of text, BH <- page 0
call Int10 ; display character
; ------------- Get new cursor position
call GetCursorPos ; get new cursor position
; ------------- Pop registers
pop dx ; pop DX
pop cx ; pop CX
pop bx ; pop BX
pop ax ; pop AX
BIOSDispText4: ret
; -----------------------------------------------------------------------------
; BIOS display text
; -----------------------------------------------------------------------------
; INPUT: DS:SI = text to display
; DESTROYS: AX, SI
; -----------------------------------------------------------------------------
BIOSDispText: cld ; direction up
lodsb ; AL <- character to display
or al,al ; end of text?
jz BIOSDispText4 ; end of text
call BIOSDispChar ; BIOS display character
jmp short BIOSDispText ; next character
; -----------------------------------------------------------------------------
; Initialize graphics card
; -----------------------------------------------------------------------------
; INPUT: DS = data segment
; [VideoCard] = VCARD_MDA
; [VideoSegm] = 0b000h
; [VideoRows] = 25
; DESTROYS: AX, BX, CX, DX
; -----------------------------------------------------------------------------
; ------------- Prepare BIOS data segment (-> ES)
InitCard: xor ax,ax ; AX <- 0
mov es,ax ; ES <- 0
; ------------- Check EGA videocard
mov ah,12h ; AH <- function code
mov bx,0ff10h ; BL <- function subcode
call Int10 ; check videocard type
cmp bh,1 ; check color mode flag
ja InitCard2 ; invalid EGA videocard
cmp bl,10h ; check memory size
je InitCard2 ; invalid EGA videocard
mov byte [VideoCard],VCARD_EGA ; set EGA type card
mov [VideoMemSize],bl ; store size of videomemory
; ------------- Number of video rows (only for EGA, VGA and MCGA)
mov al,[es:484h] ; AL <- number of rows-1
inc ax ; AL <- number of rows
cmp al,25 ; rows minimal
jb InitCard1 ; invalid number of rows
mov [VideoRows],al ; number of video rows
; ------------- Check VGA videocard
InitCard1: mov ax,1a00h ; AX <- function code
call Int10 ; check VGA card
cmp al,1ah ; check magic number
jne InitCard5 ; invalid VGA videocard
inc bx ; BL += 1
shr bl,1 ; BL /= 2
cmp bl,(7+1)/2 ; display combination 7 or 8?
je InitCard4 ; ok, VGA with bw/col display
cmp bl,(11+1)/2 ; display combination 11 or 12?
je InitCard4 ; ok, MCGA with bw/col display
jmp short InitCard5 ; no VGA card
; ------------- Check CGA videocard (checking control port address 3d4h/3b4h)
InitCard2: cmp byte [es:463h],0d4h ; is it MDA videocard?
jb InitCard5 ; it is MDA videocard (addr. 3b4h)
InitCard4: inc byte [VideoCard] ; set CGA type videocard
; ------------- Get current videomode
InitCard5: mov ah,0fh ; AH <- function code
call Int10 ; get initial videomode
and al,~B7 ; reset bit 7 (clear display flag)
; ------------- Check if it is valid text videomode
cmp al,3 ; 0 to 4: 40x25 or 80x25
jbe InitCard6 ; videomode is OK
cmp al,7 ; 7: monochrome 80x25
je InitCard6 ; videomode is OK
; ------------- Set standard videomode
mov ax,3 ; AH <- 0 function, AL <- 3 videomode
call Int10 ; set new videomode
; ------------- Store current videomode
mov ah,0fh ; AH <- function code
call Int10 ; get initial videomode
and al,~B7 ; reset bit 7 (clear display flag)
InitCard6: mov [VideoModeCols],ax ; store videomode and columns
; ------------- Segment of videomemory
cmp al,7 ; MDA (monochrome) videomode?
je InitCard8 ; MDA videomode
mov byte [VideoSegm+1],0b8h ; segment for color videomode
; ------------- Number of bytes per row
InitCard8: mov al,ah ; AL <- number of columns
mov ah,0 ; AX = number of columns
shl ax,1 ; AX <- number of bytes per row
mov [VideoBytes],ax ; number of bytes per row
; ------------- Select active page 0 (to set memory offset to 0)
mov ax,500h ; AH <- 5 function code, AL <- 0 page
call Int10 ; select active page 0
; ------------- Debug display graphics card info
%ifdef DEBUG_GRAPH
call DebInitGra ; debug display graphics card info
%endif
; ------------- Get cursor position (it is called as function, destroys AX-DX)
GetCursorPos: mov ah,3 ; AH <- 3 function code
mov bh,0 ; BH <- 0 page
call Int10 ; get cursor position
mov [VideoPosRow],dx ; store cursor position and row
ret
; -----------------------------------------------------------------------------
; Debug display graphics card info
; -----------------------------------------------------------------------------
%ifdef DEBUG_GRAPH
; ------------- Type of graphics card
DebInitGra: mov si,VideoCardMsg ; SI <- debug message
call BIOSDispText ; display text
mov bh,0 ; BH <- 0
mov bl,[VideoCard] ; BX <- type of videocard
mov al,[VideoCardsChar+bx] ; AL <- character (MDA is as MGA)
call BIOSDispChar ; display character
; ------------- Current videomode
mov si,VideoCardMsg2; SI <- debug text
call BIOSDispText ; display message
mov al,[VideoMode] ; AL <- current videomode
cbw ; convert to word
call BIOSDispNum ; display current videomode
; ------------- Dimension of current videomode
mov si,VideoCardMsg22; SI <- debug text
call BIOSDispText ; display message
mov al,[VideoCols] ; AL <- number of columns
call BIOSDispNum ; display number of columns
mov al,"x" ; AL <- "x" character
call BIOSDispChar ; display character
mov al,[VideoRows] ; AL <- number of rows
call BIOSDispNum ; display number of rows
; ------------- Installed graphics memory
mov si,VideoCardMsg23; SI <- debug text
call BIOSDispText ; display message
mov al,[VideoMemSize] ; AL <- size of videomemory
inc ax ; correction
mov ah,64 ; multiple (64 KB)
mul ah ; size of videomemory in KB
call BIOSDispNum ; display size of videomemory
; ------------- Segment of graphics memory
mov si,VideoCardMsg3; SI <- debug text
call BIOSDispText ; display message
mov ax,[VideoSegm] ; AX <- segment of videomemory
call BIOSDispHexWord ; display segment of videomemory
call BIOSDispNewLine ; display new line
ret
%endif
; -----------------------------------------------------------------------------
; Data
; -----------------------------------------------------------------------------
DATA_SECTION
; ------------- Videocard and current videomode
VideoCard: db VCARD_MDA ; type of compatible videocard
VideoMemSize: db 0 ; videomemory reported by BIOS
; (0=64K, 1=128K, 2=192K, 3=256K more)
align 2, db 0
VideoSegm: dw 0b000h ; current segment of videomemory
align 2, db 0
VideoModeCols:
VideoMode: db 3 ; current BIOS videomode
VideoCols: db 80 ; current number of columns
align 2, db 0
VideoBytes: dw 160 ; current number of bytes per row
VideoRows: db 25 ; current number of rows
VideoCol: db 7 ; current color
align 2, db 0
VideoPosRow:
VideoPos: db 0 ; currect cursor position
VideoRow: db 0 ; current cursor row
; ------------- Debug messages
%ifdef DEBUG_GRAPH
VideoCardMsg: db 13,10,'--- Graphics Card:',13,10
db 'Compatible graphics card: ',0
VideoCardsChar: db "M","C","E","V"
VideoCardMsg2: db 'GA',13,10,'Current videomode: ',0
VideoCardMsg22: db ' (',0
VideoCardMsg23: db ')',13,10,'Installed graphics memory: ',0
VideoCardMsg3: db ' KB',13,10,'Segment of graphics memory: ',0
%endif
|