Updating Character Generator RAM
After you create a table of character definitions, you must make the table accessible to the hardware character generator by properly locating it in the video buffer.
To copy a character definition table into video memory map 2, you must program both the Sequencer's Memory Mode register and its Map Mask register, as well as the Graphics Controller's Mode and Miscellaneous registers, to make memory map 2 directly addressable. You can then copy character definitions to any of the available table locations in map 2. After you update map 2, restore the Sequencer and Graphics Controller registers to values appropriate for the alphanumeric video mode you are using.
Listing A demonstrates how the Sequencer and Graphics Controller are programmed on both the EGA and the VGA to make character generator RAM in map 2 accessible. Listing B is the converse routine; it restores the Sequencer and Graphics Controller registers to their alphanumeric mode default values.
Код:
;Listing A
DGROUP GROUP _DATA
_TEXT SEGMENT byte public 'CODE'
ASSUME cs:_TEXT, ds:DGROUP
_CGenModeSet PROC near
push bp ; preserve caller registers
mov bp,sp
push si
; Program the Sequencer
cli ; disable interrupts
mov dx,3C4h ; Sequencer port address
mov si,offset DGROUP:SeqParms
mov cx,4
L01: lodsw ; AH := value for Sequencer register AL := register number
out dx,ax ; program the register
loop L01
sti ; enable interrupts
; Program the Graphics Controller
mov dl,0CEh ; DX := 3CEH (Graphics Controller port address)
mov si,offset DGROUP:GCParms
mov cx,3
L02: lodsw ; program the Graphics Controller
out dx,ax
loop L02
pop si
pop bp
ret
_CGenModeSet ENDP
_TEXT ENDS
_DATA SEGMENT word public 'DATA'
; Format of the parameters is: Lo-order byte: Register number Hi-order byte: Value for reg
SeqParms DW 0100h ; synchronous reset
DW 0402h ; CPU writes only to map 2
DW 0704h ; sequential addressing
DW 0300h ; clear synchronous reset
GCParms DW 0204h ; select map 2 for CPU reads
DW 0005h ; disable odd-even addressing
DW 0006h ; map starts at A000:0000
_DATA ENDS
END
;Listing B
DGROUP GROUP _DATA
_TEXT SEGMENT byte public 'CODE'
ASSUME cs:_TEXT,ds:DGROUP
_CGenModeClear PROC near
push bp ; preserve caller registers
mov bp,sp
push si
; Program the Sequencer
cli ; disable interrupts
mov dx,3C4h ; Sequencer port address
mov si,offset DGROUP:SeqParms
mov cx,4
L01: lodsw ; AH := value for Sequencer register AL := register number
out dx,ax ; program the register
loop L01
sti ; enable interrupts
; Program the Graphics Controller
mov dl,0CEh ; DX := 3CEH (Graphics Controller port address)
mov si,offset DGROUP:GCParms
mov cx,3
L02: lodsw ; program the Graphics Controller
out dx,ax
loop L02
mov ah,0Fh ; AH := INT 10H function number
int 10h ; get video mode
cmp al,7
jne L03 ; jump if not monochrome mode
mov ax,0806h; program Graphics Controller
out dx,ax ; to start map at B000:0000
L03: pop si
pop bp
ret
_CGenModeClear ENDP
_TEXT ENDS
_DATA SEGMENT word public 'DATA'
; Format of the parameters is: Lo-order byte: Register number Hi-order byte: Value for reg
SeqParms DW 0100h ; synchronous reset
DW 0302h ; CPU writes to maps 0 and 1
DW 0304h ; odd-even addressing
DW 0300h ; clear synchronous reset
GCParms DW 0004h ; select map 0 for CPU reads
DW 1005h ; enable odd-even addressing
DW 0E06h ; map starts at B800:0000
_DATA ENDS
END