Під час інтервалу RETRACE луч повинен бути відключен, щоб запобігти погіршення зображення на екрані (тому HORIZONTAL RETRACE називають також HORIZONTAL BLANKING). Але між відключенням луча та початком RETRACE (а також між включенням луча та кінцем RETRACE) проходить деякий час, поки луч ще включен, а активна область екрану вже скінчилася. Цей інтервал називають OVERSCAN. За його допомогою створюється “рамка” екрану.
Аналогічні інтервали виникають при русі луча угору. Інтервал часу, коли луч іде угору, називають VERTICAL RETRACE. Час відключеного луча в RETRACE називають RETRACE BLANKING. Час включеного луча, що знаходиться у VERTICAL RETRACE, називають VERTICAL OVERSCAN. VERTICAL OVERSCAN може бути унизу (коли почався RETRACE, але луч ще не відключен), або угорі (коли RETRACE ще не скінчився, але луч вже включен).
Адреса відео BIOS CGA, EGA, VGA
Відео BIOS CGA знаходиться на материнській платі. При включенні комп'ютера, вектор переривання 10h ініциалізується так, щоб вказувати на відеопрограми BIOS в ROM. Ці програми починаються в адресному просторі CPU з адреси F000:E000.
В EGA знаходиться своя множина відеопрограм в RAM. Вони розміщуються з адреси C000:0000. Програма початкового завантаження (POST) ініциалізує вектор переривання 10h так, щоб він вказував на власні відеопрограми EGA. Адрес програми відео BIOS на материнській платі зберігається у векторі переривання 42h.
У VGA програми відео BIOS розміщуються за адресою C000:0000
У доданку наводиться текст програми на мові Borland Pascal 7.0 з вставками на мові Assembler. Програма демонструє можливості керування зображенням за допомогою прямої адресації відеопам’яти.
Доданок. Лістінг програми, яка демонструє можливості керування відеопам’ятью.
PROGRAM VideoMem_Demo; {Written by Kovalyov Serhii as attachment}
{to report "Video Memory"}
USES
CRT;
VAR
Cols:WORD;
Rows:BYTE;
PageSize:WORD;
ActivePage:BYTE;
VOffset:WORD;
ChOff:WORD;
J:BYTE;
Dir:BOOLEAN;
PROCEDURE ReadScreenProp; ASSEMBLER;
ASM
{Reading properties of Video Mode}
PUSH DS
MOV AX,0040h
MOV DS,AX
MOV AX,DS:[004Ah]
XOR BX,BX
MOV BL,DS:[0084h]
INC BL
MOV DL,DS:[0062h]
POP DS
MOV Cols,AX
MOV Rows,BL
MUL BX
MOV PageSize,AX
MOV ActivePage,DL
END;
PROCEDURE ClearScreen; ASSEMBLER;
{Set cursor position}
MOV BX,0050h
XOR DH,DH
MOV DL,ActivePage
ADD BX,DX
MOV WORD PTR DS:[BX],0
{Clearing active page}
MOV CX,PageSize
XOR AX,AX
MOV AL,ActivePage
MOV BX,PageSize
MOV VOffset,AX
MOV BX,VOffset
MOV AX,0B800h
@loop_label2:
MOV WORD PTR DS:[BX],0000h
INC BX
MOV WORD PTR DS:[BX],000Fh
LOOP @loop_label2
PROCEDURE PutSymbol(Character:CHAR;Attr:BYTE;PosX,PosY:BYTE); ASSEMBLER;
MOV CH,Attr
MOV CL,Character
MOV AL,PosY
MOV BX,Cols
ADD BX,BX
MOV BL,PosX
ADD BL,PosX
ADD AX,BX
MOV ChOff,AX
ADD BX,ChOff
MOV WORD PTR DS:BX,CX
BEGIN
Dir:=TRUE;
ReadScreenProp;
ClearScreen;
{WriteLn(PageSize,' ',VOffset,' ',ActivePage,' ',Cols,' ',Rows,' ',ChOff);}
PutSymbol(' ',$0000,0,0);
PutSymbol('V',$1E,3,1);
PutSymbol('I',$1E,3,2);
PutSymbol('D',$1E,3,3);
PutSymbol('E',$1E,3,4);
PutSymbol('O',$1E,3,5);
PutSymbol('M',$70,2,4);
PutSymbol('E',$02,3,4);
PutSymbol('M',$70,4,4);
PutSymbol('O',$70,5,4);
PutSymbol('R',$70,6,4);
PutSymbol('Y',$70,7,4);
J:=0;
REPEAT
IF Dir THEN PutSymbol(' ',$00,J-1,11)
ELSE PutSymbol(' ',$00,J+6,11);
PutSymbol('D',$0E,J,11);
PutSymbol('C',$0E,J+1,11);
PutSymbol('S',$0E,J+2,11);
PutSymbol('S',$0E,J+3,11);
PutSymbol('-',$0E,J+4,11);
PutSymbol('1',$0E,J+5,11);
IF (J<Cols-6) AND Dir THEN INC(J)
ELSE IF (NOT Dir) AND (J>0)
THEN DEC(J)
ELSE BEGIN
Dir:=NOT Dir;
Delay(120);
UNTIL KeyPressed;
END.