home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Informática Multimedia Fácil 56
/
INF1297.iso
/
SOFCAS
/
EDUCA
/
EVSIM11.ZIP
/
EV-SYS.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-04-27
|
78KB
|
1,798 lines
;┌───────────────────────────────────────────────────────────────────┐
;│ │
;│ RUTINAS EN ENSAMBLADOR PARA EV │
;│ │
;│ Incluir en un fichero de proyecto con EV.C │
;│ El modelo de memoria debe ser necesariamente LARGE │
;│ │
;└───────────────────────────────────────────────────────────────────┘
PUBLIC _VGAModeX ; inicializar modo X
PUBLIC _setpix ; trazar puntos
PUBLIC _set16pix ; trazar bloques de 16 puntos
PUBLIC _set4pix ; trazar bloques de 4 puntos
PUBLIC _getpix ; obtener color de un punto
PUBLIC _recta ; trazado de una recta
PUBLIC _lineahoriz ; trazar línea horizontal
PUBLIC _showpage ; elegir página a mostrar
PUBLIC _setpage ; página para setpix y getpix
PUBLIC _FuenteInfo ; puntero juego caracteres 8*16
PUBLIC _segvideo ; segmento de vídeo activo
PUBLIC _Xprcar ; escribir carácter en modo X
PUBLIC _prcar ; escribir carácter en 16 colores
PUBLIC _PintaBitMap ; imprimir mapa de bits
PUBLIC _MoveVram ; copiar un área de vídeo
PUBLIC _MoveMem ; copiar una zona de memoria a otra
PUBLIC _prbios ; imprimir con la BIOS
PUBLIC _set80x30 ; modo texto VGA 80x30 (font 8x16)
PUBLIC _ResetVideo ; Reset del modo de vídeo
PUBLIC _NuevaInt24 ; nuevo gestor errores críticos
PUBLIC _NoHayTecla ; indicar si no hay tecla en el buffer
_TEXT SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:_TEXT, DS:_DATA
; ------------ Establecer cualquier modo X no soportado por la BIOS.
; Declaración: void VGAModeX (int hvertical);
;
; Modo X Valor de hvertical
; ----------- ------------------
; 320x200x256 200
; 320x240x256 240
; 320x400x256 400
; 320x480x256 480
;
; Basado en una rutina original de:
; Pedro Gimeno Fortea (Fido 2:346/207.62)
hvertical EQU WORD PTR [BP+6] ; para modelo LARGE
_VGAModeX PROC FAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH DS
MOV AX,40h
MOV DS,AX
MOV AL,DS:[10h]
AND AL,0CFh ; por si estamos en modo 7...
OR AL,20h
MOV DS:[10h],AL ; ...forzar modo de color
POP DS
MOV AX,12h ; Modo estándar 640x480x16 (480/240)
CMP hvertical,480
JE vini_ok
CMP hvertical,240
JE vini_ok
MOV AX,0Eh ; Modo estándar 640x200x16 (400/200)
vini_ok: INT 10h
MOV DX,3CEh ; Graphics Controller
MOV AX,4005h ; bit de 256c en Mode Register
CLI
OUT DX,AX
MOV DX,3DAh ; Asegurar que el Attribute Controller
IN AL,DX ; está en modo Registro, no en modo Dato
MOV DX,3C0h ; Attribute Controller
MOV AL,0 ; desactivar acceso de VGA; reg. paleta 0
MOV CX,16 ; Programaremos 16 registros en total
SetPalReg: JMP SHORT $+2
JMP SHORT $+2
OUT DX,AL ; Meter en el registro N-ésimo...
JMP SHORT $+2
JMP SHORT $+2
OUT DX,AL ; ... el valor N
INC AL ; Siguiente registro / valor
LOOP SetPalReg
MOV AL,30h ; Registro 10h (de modo), bit de acceso
OUT DX,AL ; de VGA activado
MOV AL,41h ; Activar el modo de 256 colores
OUT DX,AL
CMP hvertical,200
JE dup_ok ; ya se partía con Scanline duplicado
CMP hvertical,480
JE dup_ok ; ya se partía con Scanline sin duplicar
MOV DX,3D4h ; CRT controller
MOV AL,09h
OUT DX,AL
INC DX
IN AL,DX
AND AL,7Fh ; desactivar duplicación (400)
CMP hvertical,400
JE set_dup
OR AL,80h ; Duplicar tamaño de Scanline (240)
set_dup: OUT DX,AL
dup_ok: STI
PUSH DS
MOV AX,40h
MOV DS,AX
MOV BYTE PTR DS:[49h],13h ; simular modo 13h
POP DS
POP DI
POP SI
POP BP
RET
_VGAModeX ENDP
; ------------ Pintar un punto en modo X.
; Declaración: void setpix (int x, int y, int color);
x0 EQU [BP+6] ; para modelo LARGE
y0 EQU [BP+8]
color EQU [BP+10]
_setpix PROC FAR
PUSH BP
MOV BP,SP
PUSH DS
PUSH DI
MOV AX,320/4 ; calcular offset en VRAM
MUL WORD PTR y0
MOV CX,x0
MOV DI,CX
SHR DI,1
SHR DI,1
ADD DI,AX ; offset en DI
AND CL,3 ; calcular máscara para el
MOV AH,1 ; mapa a direccionar en AH
SHL AH,CL
MOV AL,2 ; a AL el número de registro
MOV DX,3C4h
OUT DX,AX ; cargar registro de máscara
MOV AL,color
MOV DS,_segvideo ; DS -> VRAM
MOV [DI],AL ; trazar punto
POP DI
POP DS
POP BP
RET
_setpix ENDP
; ------------ Pintar un cuadrado de 4x4 en modo X (coords. multiplo de 4).
; Declaración: void set16pix (int x, int y, int color);
x16 EQU [BP+6] ; para modelo LARGE
y16 EQU [BP+8]
color16 EQU [BP+10]
_set16pix PROC FAR
PUSH BP
MOV BP,SP
PUSH DS
PUSH DI
MOV AX,320/4 ; calcular offset en VRAM
MUL WORD PTR y16
MOV DI,x16
SHR DI,1
SHR DI,1
ADD DI,AX ; offset en DI
MOV AX,1111b*256+2 ; direccionar 4 mapas en AH
MOV DX,3C4h ; (AL el número de registro)
OUT DX,AX ; cargar registro de máscara
MOV AL,color16
MOV DS,_segvideo ; DS -> VRAM
MOV [DI],AL ; trazar puntos
MOV [DI+80],AL ; trazar puntos
ADD DI,160
MOV [DI],AL ; trazar puntos
MOV [DI+80],AL ; trazar puntos
POP DI
POP DS
POP BP
RET
_set16pix ENDP
; ------------ Pintar un cuadrado de 2x2 en modo X (coords. multiplo de 2).
; Declaración: void set4pix (int x, int y, int color);
x4 EQU [BP+6] ; para modelo LARGE
y4 EQU [BP+8]
color4 EQU [BP+10]
_set4pix PROC FAR
PUSH BP
MOV BP,SP
PUSH DS
PUSH DI
MOV AX,320/4 ; calcular offset en VRAM
MUL WORD PTR y4
MOV CX,x4
MOV DI,CX
SHR DI,1
SHR DI,1
ADD DI,AX ; offset en DI
TEST CL,2
MOV AX,0011b*256+2 ; direccionar 2 mapas en AH
JZ m4pix_ok
MOV AH,1100b
m4pix_ok: MOV DX,3C4h ; (AL el número de registro)
OUT DX,AX ; cargar registro de máscara
MOV AL,color4
MOV DS,_segvideo ; DS -> VRAM
MOV [DI],AL ; trazar puntos
MOV [DI+80],AL ; trazar puntos
POP DI
POP DS
POP BP
RET
_set4pix ENDP
; ------------ Obtener el color de un punto en modo X.
; (Se suponen 80 columnas en el eje X).
; Declaración:
; int lineahoriz (int x, int y, int largo, int color);
x_h EQU [BP+6] ; para modelo LARGE
y_h EQU [BP+8]
l_h EQU [BP+10]
c_h EQU [BP+12]
_lineahoriz PROC FAR
PUSH BP
MOV BP,SP
PUSH ES
PUSH DI
MOV AX,320/4 ; calcular offset en VRAM
MUL WORD PTR y_h
MOV DI,x_h
ADD DI,AX ; offset en DI
MOV AH,00001111b ; direccionar 4 mapas en AH
MOV AL,2 ; a AL el número de registro
MOV DX,3C4h
OUT DX,AX ; cargar registro de máscara
MOV CX,l_h
MOV AL,c_h
MOV ES,_segvideo ; DS -> VRAM
REP STOSB ; trazar línea
POP DI
POP ES
POP BP
RET
_lineahoriz ENDP
; ------------ Trazar línea horizontal en modo X.
; Declaración: int getpix (int x, int y);
x1 EQU [BP+6] ; para modelo LARGE
y1 EQU [BP+8]
_getpix PROC FAR
PUSH BP
MOV BP,SP
PUSH DS
PUSH SI
MOV AX,320/4 ; calcular offset en VRAM
MUL WORD PTR y1
MOV SI,x1
MOV CX,SI
SHR SI,1
SHR SI,1
ADD SI,AX
AND CL,3 ; calcular máscara para el
MOV AH,CL ; mapa a direccionar en AH
MOV AL,4
MOV DX,3CEh
OUT DX,AX ; cargar registro Read-Map
MOV DS,_segvideo ; DS -> VRAM
MOV AL,[SI] ; obtener color del punto
MOV AH,0 ; (int)
POP SI
POP DS
POP BP
RET
_getpix ENDP
; ------------ Trazar una recta a través del algoritmo de Bresenham.
; Declaración: void recta (int x1, int y1, x2, y2, color, modo);
; Si modo es 0, utiliza la BIOS; si no, asume modo de 16 colores.
rx1 EQU [BP+6] ; para modelo LARGE
ry1 EQU [BP+8]
rx2 EQU [BP+10]
ry2 EQU [BP+12]
rcolor EQU [BP+14]
rmodo EQU [BP+16]
_recta PROC FAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
CMP WORD PTR rmodo,0
JE rm_ok1
MOV DX,3CEh
MOV AX,205h ; modo read 0 y write 2
OUT DX,AX
rm_ok1: MOV CX,rx1
MOV DX,ry1
MOV SI,rx2
MOV DI,ry2 ; de (CX,DX) a (SI,DI)
PUSH DS
MOV AL,BYTE PTR rcolor
MOV AH,BYTE PTR rmodo
MOV DS,AX ; pocos registros tiene el 8086 :-)
PUSH BP
CMP CX,SI
JNE tst_ok
CMP DX,DI
JNE tst_ok
MOV AX,DS
CALL rpunto ; línea de un solo punto
JMP fin
tst_ok: MOV AX,SI
SUB AX,CX ; AX = X2-X1
JNC absx2x1
NEG AX
XCHG CX,SI
XCHG DX,DI
absx2x1: MOV BX,DI ; AX = ABS(X2-X1) = «dx»
SUB BX,DX
MOV BP,1 ; BP = 1 = «yincr» si Y2>Y1
JNC absy2y1
NEG BP ; BP = -1 = «yincr» si Y2<=Y1
NEG BX
absy2y1: CMP AX,BX ; BX = ABS(Y2-Y1) = «dy»
PUSHF
JA noswap ; ABS(pendiente) menor de 1
XCHG AX,BX
noswap: SHL BX,1 ; BX = «dy» * 2
MOV SI,BX
SUB SI,AX ; SI = «dy» * 2 - «dx» = «d»
MOV DI,BX
SUB DI,AX
SUB DI,AX ; DI = «dy»*2-«dx»*2 = «incr2»
POPF
JBE penmay1 ; pendiente mayor de 1
penmen1: PUSH AX
MOV AX,DS
CALL rpunto ; en (CX, DX) = («x», «y»)
POP AX
INC CX ; «x»++
AND SI,SI ; (SI>0) ? -> «d» > 0 ?
JS noincy
ADD SI,DI ; «d» > 0 : «d» = «d» + «incr2»
ADD DX,BP ; «y» = «y» + «yincr»
DEC AX ; «dx»--
JNZ penmen1
JMP fin
noincy: ADD SI,BX ; «d» < 0 : «d» = «d» + «incr1»
DEC AX
JNZ penmen1
JMP fin
penmay1: PUSH AX
MOV AX,DS
CALL rpunto ; en (CX, DX) = («x», «y»)
POP AX
ADD DX,BP ; «y» = «y» + «yincr»
AND SI,SI ; (SI>0) ? -> «d» > 0 ?
JS noincx
ADD SI,DI ; «d» > 0 : «d» = «d» + «incr2»
INC CX ; «x»++
DEC AX ; «dx»--
JNZ penmay1
JMP fin
noincx: ADD SI,BX ; «d» = «d» + «incr1»
DEC AX ; «dx»--
JNZ penmay1
fin: POP BP
POP DS ;-)
CMP WORD PTR rmodo,0
JE rm_ok2
MOV DX,3CEh
MOV AX,5
OUT DX,AX ; modo read 0 y write 0 de la BIOS
MOV AX,0FF08h
OUT DX,AX ; registro máscara de bit a 0xFF
rm_ok2: POP DI
POP SI
POP BP
RET
_recta ENDP
rpunto PROC
AND AH,AH
JZ rpuntobios
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH AX
MOV AX,80
MUL DX
MOV BX,CX
MOV DX,CX
MOV CL,3
SHR BX,CL
ADD BX,AX
MOV AX,0A000h
MOV DS,AX ; DS:BX -> VRAM
AND DL,00000111b
MOV CL,DL
MOV DX,3CEh
MOV AH,10000000b
SHR AH,CL
MOV AL,8
OUT DX,AX ; actualizar registro de máscara
POP AX
MOV AH,[BX] ; cargar latches
MOV [BX],AL ; trazar punto
POP DS
POP DX
POP CX
POP BX
RET
rpuntobios: PUSH BX ; preservar registros (salvo AX)
PUSH CX
PUSH DX
PUSH BP
PUSH SI
PUSH DI
MOV AH,0Ch ; trazar punto usando BIOS
XOR BX,BX
INT 10h
POP DI
POP SI
POP BP
POP DX
POP CX
POP BX
RET
rpunto ENDP
; ------------ Selecciona la página de trabajo para setpix/getpix
; en los modos que admiten varias.
; Declaración: void setpage (int pagina);
pags EQU [BP+6] ; para modelo LARGE
_setpage PROC FAR
PUSH BP
MOV BP,SP
MOV AX,0A000h
CMP WORD PTR pags,0
JE sp_ok
MOV AX,0A800h
sp_ok: MOV _segvideo,AX ; nueva dirección de vídeo
POP BP
RET
_setpage ENDP
; ------------ Selecciona la página de trabajo visualizada en los
; modos que admiten varias.
; Declaración: void showpage (int pagina);
pagv EQU [BP+6] ; para modelo LARGE
_showpage PROC FAR
PUSH BP
MOV BP,SP
MOV DX,3DAh
PUSH DS
MOV AX,40h
MOV DS,AX
MOV CX,9 ; timeout de 0.5 segundos
MOV AH,DS:[6Ch]
frt_vert: CMP AH,DS:[6Ch]
JNE frt_nvert
IN AL,DX ; esperar primero final del
TEST AL,8 ; retrazado vertical
JNZ frt_vert
JMP irt_vert
frt_nvert: MOV AH,DS:[6Ch]
LOOP frt_vert
JMP fin_shw ; no llega el retrazo
irt_vert: CMP AH,DS:[6Ch]
JNE irt_nvert
IN AL,DX ; esperar inicio del
TEST AL,8 ; retrazado vertical
JZ irt_vert
JMP fin_shw
irt_nvert: MOV AH,DS:[6Ch]
LOOP irt_vert
fin_shw: MOV AX,pagv
AND AL,AL ; ¿página 0?
JZ wp_ok ; así es
MOV AL,80h ; página 1, con offset 8000h
wp_ok: MOV DX,3D4h ; direccionar CRT
MOV AH,AL ; byte alto del offset a AH
MOV AL,0Ch
OUT DX,AX
POP DS
POP BP
RET
_showpage ENDP
; ------------ Imprimir carácter de la fuente en modo X.
; Declaración: void Xprcar (int car, int x, int y, int largo,
; int alto, int tinta, int papel, int pitch);
car EQU [BP+6] ; para modelo LARGE
c_x EQU [BP+8]
c_y EQU [BP+10]
largo EQU [BP+12]
alto EQU [BP+14]
tinta EQU [BP+16]
papel EQU [BP+18]
pitch EQU [BP+20]
_Xprcar PROC FAR
PUSH BP
MOV BP,SP
PUSH ES
PUSH SI
PUSH DI
MOV AX,320/4 ; calcular offset en VRAM
MUL WORD PTR c_y
MOV DI,c_x
SHR DI,1
SHR DI,1
ADD DI,AX
MOV ES,_segvideo ; ES:DI -> VRAM
MOV AL,car
MOV AH,0
MOV CL,4
SHL AX,CL ; carácter * 16
ADD AX,OFFSET _FuenteInfo
MOV SI,AX ; SI -> fuente
MOV CX,c_x
AND CL,3 ; calcular máscara para el
MOV BH,00010001b ; mapa a direccionar en BH
ROL BH,CL
MOV BL,10000000b ; pixel en curso en BL
MOV CX,8
pr_horiz: PUSH CX
MOV CX,largo
pr_duphoriz: PUSH CX
PUSH SI
PUSH DI
MOV AL,2 ; a AL el número de registro
MOV AH,BH
MOV DX,3C4h
OUT DX,AX ; cargar registro de máscara
MOV AH,tinta ; tinta inicial
MOV DX,16
pr_vert:
MOV AL,AH ; tinta en curso
TEST [SI],BL
JNZ pr_tin
MOV AL,papel
CMP AL,0FFh
JNE pr_pap
MOV CX,alto
PUSH BX
MOV BL,AH
SHL BX,1
pr_nulvert: ADD DI,80 ; siguiente línea
ADD BX,pitch
LOOP pr_nulvert
SHR BX,1
MOV AH,BL
POP BX
JMP pr_otrop
pr_pap: MOV CX,alto
PUSH BX
MOV BL,AH
SHL BX,1
pr_papvert: MOV ES:[DI],AL ; trazar punto de papel
ADD DI,80 ; siguiente línea
ADD BX,pitch
LOOP pr_papvert
SHR BX,1
MOV AH,BL
POP BX
JMP pr_otrop
pr_tin: MOV CX,alto
PUSH BX
MOV BL,AL
SHL BX,1
pr_tinvert: MOV ES:[DI],AL ; trazar punto de tinta
ADD DI,80 ; siguiente línea
ADD BX,pitch
MOV AX,BX
SHR AX,1
LOOP pr_tinvert
MOV AH,AL
POP BX
pr_otrop: INC SI ; siguiente scan
DEC DX
JNZ pr_vert
POP DI
POP SI
ROL BH,1 ; siguiente mapa de bits
JNC pr_np
INC DI ; siguiente dirección VRAM
pr_np:
POP CX
LOOP pr_duphoriz
ROR BL,1 ; siguiente pixel
POP CX
DEC CX
JZ pr_ex
JMP pr_horiz
pr_ex: POP DI
POP SI
POP ES
POP BP
RET
_Xprcar ENDP
; ------------ Imprimir carácter 8 ó 9x16 de la VGA en modo de 16 colores.
; Declaración: int prcar (int car, int x, int y,
; int tinta, int papel);
; Devuelve la anchura efectiva usada (8 ó 9, según carácter).
chr EQU [BP+6] ; para modelo LARGE
chr_x EQU [BP+8]
chr_y EQU [BP+10]
chr_tinta EQU [BP+12]
chr_papel EQU [BP+14]
_prcar PROC FAR
PUSH BP
MOV BP,SP
PUSH ES
PUSH DS
PUSH SI
PUSH DI
CMP f8x16_seg,0
JNE pr_rapido ; punteros a fuentes ya inicializados
MOV AX,1130h
MOV BH,6
PUSH ES ; *
PUSH BP ; **
INT 10h
MOV BX,BP
MOV AX,ES ; AX:BX -> juego 8x16
POP BP ; **
POP ES ; *
MOV f8x16_off,BX
MOV f8x16_seg,AX
MOV AX,1130h
MOV BH,7
PUSH ES ; *
PUSH BP ; **
INT 10h
MOV BX,BP
MOV AX,ES ; AX:BX -> caracteres 9x16
POP BP ; **
POP ES ; *
MOV fix9x16_off,BX
MOV fix9x16_seg,AX
pr_rapido: MOV DX,_segvideo ; DX -> VRAM
MOV AH,chr
PUSH ES
MOV DI,fix9x16_off
MOV ES,fix9x16_seg
MOV CX,256 ; «timeout»
busca9: MOV AL,ES:[DI]
CMP AL,AH
JNE fin9?
ADD SP,2 ; "POP ES"
MOV CH,1 ; anchura = 9 pixels (8+1)
JMP pfuente_ok ; fuente en ES:DI+1
fin9?: AND AL,AL
JZ usar8
ADD DI,17
LOOP busca9
usar8: POP ES
MOV AL,chr
MOV AH,0
MOV BL,AL
MOV CL,4
SHL AX,CL
MOV DI,f8x16_off
MOV ES,f8x16_seg
ADD DI,AX
DEC DI
MOV CH,0 ; anchura = 8 pixels (8+0)
CMP BL,255
JNE pfuente_ok ; código 255: 9 pixels de ancho
INC CH
pfuente_ok: INC DI ; fuente en ES:DI
MOV DS,DX ; DS -> VRAM
MOV SI,chr_x
MOV BX,SI
MOV CL,3
SHR SI,CL ; SI = chr_x / 8
MOV AX,80 ; bytes por línea
MUL WORD PTR chr_y
ADD SI,AX ; DS:SI -> VRAM carácter
AND BL,00000111b
MOV CL,BL ; CL = bits a respetar por la izda
MOV DX,3CEh
MOV AX,205h ; modo read 0 y write 2
OUT DX,AX
MOV BL,16 ; altura de la fuente
pr_print8: MOV AX,0FF08h
SHR AH,CL ; AH = máscara de papel rotada
OUT DX,AX ; actualizar registro máscara
MOV AH,[SI] ; actualizar latches
MOV BH,chr_papel
MOV [SI],BH ; escribir VRAM con color fondo izdo
MOV AH,[SI] ; cargar latches con color de fondo
MOV AH,ES:[DI] ; trama del carácter
SHR AH,CL ; rotada a su sitio
OUT DX,AX ; registro máscara de bit con trama
MOV BH,chr_tinta
MOV [SI],BH ; pintar izda carácter (color tinta)
AND CH,CH
JNZ no_skip_b2
AND CL,CL
JZ skip_b2
no_skip_b2: INC SI ; parte derecha
PUSH CX
SUB CL,8
NEG CL ; bits a correr a la izda
SUB CL,CH ; 8/9
MOV AX,0FF08h
SHL AH,CL ; AH = máscara de papel rotada
OUT DX,AX ; actualizar registro máscara
MOV AH,[SI] ; actualizar latches
MOV BH,chr_papel
MOV [SI],BH ; escribir VRAM con color fondo dcho
MOV AH,[SI] ; cargar latches con color de fondo
ADD CL,CH ; 8/9
MOV AH,ES:[DI] ; trama del carácter
SHL AH,CL ; rotada a su sitio
OUT DX,AX ; registro máscara de bit con trama
MOV BH,chr_tinta
MOV [SI],BH ; pintar dcha carácter (color tinta)
POP CX
DEC SI
skip_b2: INC DI ; preparar para siguiente scan
ADD SI,80 ; siguiente línea en pantalla
DEC BL
JNZ pr_print8
MOV AX,5
OUT DX,AX ; modo read 0 y write 0 de la BIOS
MOV AX,0FF08h
OUT DX,AX ; registro máscara de bit a 0xFF
POP DI
POP SI
POP DS
POP ES
POP BP
MOV AL,CH
ADD AL,8
MOV AH,0 ; retornar anchura carácter
RET
_prcar ENDP
; ------------ Imprimir mapa de bits en modo X.
; Declaración: void PintaBitMap (char *bitmap, int ancho,
; int relx, int rely, int lx,
; int ly, int x, int y, int modo);
bitmap EQU [BP+6] ; para modelo LARGE
ancho EQU [BP+10]
relx EQU [BP+12] ; coordenadas relativas sobre
rely EQU [BP+14] ; el propio bitmap
lx EQU [BP+16]
ly EQU [BP+18]
p_x EQU [BP+20]
p_y EQU [BP+22]
modo EQU [BP+24]
_PintaBitMap PROC FAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH DS
PUSH ES
MOV ES,_segvideo
LDS SI,bitmap
MOV BX,320/4
CMP WORD PTR modo,0
JE bm_ini_ok
NEG BX
MOV AX,lx ; empezar por el final
DEC AX
ADD p_x,AX
MOV AX,ly
DEC AX
ADD p_y,AX
bm_ini_ok: MOV AX,rely
MUL WORD PTR ancho
ADD AX,relx
ADD SI,AX ; DS:SI -> bitmap
MOV AX,320/4 ; calcular offset en VRAM
MUL WORD PTR p_y
MOV CX,p_x
MOV DI,CX
SHR DI,1
SHR DI,1
ADD DI,AX ; offset en DI
AND CL,3 ; calcular máscara para el
MOV AH,00010001b ; mapa a direccionar en AH
ROL AH,CL
MOV AL,2 ; a AL el número de registro
MOV DX,3C4h
OUT DX,AX ; cargar registro de máscara
MOV CX,lx
bm_horiz: PUSH CX
PUSH SI
PUSH DI
PUSH DS
MOV CX,ly
bm_vert: MOV AL,[SI]
MOV ES:[DI],AL ; trazar punto
ADD DI,BX ; siguiente scan
ADD SI,ancho ; siguiente punto vertical
JNC si_ok1
PUSH AX ; desbordamiento de segmento
MOV AX,DS
ADD AX,1000h
MOV DS,AX
POP AX
si_ok1: LOOP bm_vert
POP DS
POP DI
POP SI
INC SI ; siguiente punto horizontal
JNZ si_ok2
PUSH AX ; desbordamiento de segmento
MOV AX,DS
ADD AX,1000h
MOV DS,AX
POP AX
si_ok2: AND BX,BX
JNS bm_derecho
ROR AH,1 ; impresión al revés
JNC bm_np
DEC DI
JMP bm_np
bm_derecho: ROL AH,1 ; siguiente mapa de bits
JNC bm_np
INC DI ; siguiente dirección VRAM
bm_np: MOV AL,2
OUT DX,AX
POP CX
LOOP bm_horiz
POP ES
POP DS
POP DI
POP SI
POP BP
RET
_PintaBitMap ENDP
; ------------ Copiar bloque de una zona de vídeo a otra en modo X.
; Declaración: void MoveVram (void *fuente, void *destino,
; unsigned numbytes);
fuente EQU [BP+6] ; para modelo LARGE
destino EQU [BP+10]
numbytes EQU [BP+14]
_MoveVram PROC FAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH DS
PUSH ES
LDS SI,fuente
LES DI,destino
MOV CX,numbytes
MOV BH,0001b ; para registro de máscara
MOV BL,0 ; para registro Read-Map
CLD
copia_plano: PUSH SI
PUSH DI
PUSH CX
MOV AL,2
MOV AH,BH
MOV DX,3C4h ; registro de máscara
OUT DX,AX
MOV AL,4
MOV AH,BL
MOV DX,3CEh ; registro Read-Map
OUT DX,AX
REP MOVSB ; copiar plano de bits
POP CX
POP DI
POP SI
SHL BH,1 ; siguiente plano escritura
INC BL ; siguiente plano lectura
CMP BL,4
JB copia_plano ; completar los 4 planos
POP ES
POP DS
POP DI
POP SI
POP BP
RET
_MoveVram ENDP
; ------------ Copiar un bloque de memoria a otro sitio. El compilador
; tiene media docena de funciones o mas pero ni una sola
; que funcione bien. Requiere punteros huge.
;
; Declaración:
; void MoveMem (char huge *fuente, char huge *destino,
; unsigned numbytes);
fuente EQU [BP+6] ; para modelo LARGE
destino EQU [BP+10]
numbytes EQU [BP+14]
_MoveMem PROC FAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH DS
PUSH ES
LDS SI,fuente
LES DI,destino
MOV CX,numbytes
SHR CX,1
CLD
PUSHF
REP MOVSW
POPF
JNC fin_mv
MOVSB
fin_mv: POP ES
POP DS
POP DI
POP SI
POP BP
RET
_MoveMem ENDP
; ------------ Impresión en pantalla en color usando la BIOS. Al hacer
; scroll se intenta respetar el posible color global de fondo.
;
; 0 -> final de cadena
; 1 -> inicializar rutina (necesario si cambia el modo
; de pantalla): automático la primera vez
; 2 -> el siguiente carácter indica la tinta (BIOS)
; 3 -> el siguiente carácter indica el papel (BIOS)
; 4 -> el siguiente carácter indica el nº de veces que
; se imprimirá el que viene detrás
; 5 -> avanzar cursor a la derecha
; 10 -> retorno de carro y salto de línea estilo UNIX
;
; Declaración: void prbios (char *cadena);
cadena EQU [BP+6] ; para modelo LARGE
_prbios PROC FAR
PUSH BP
MOV BP,SP
PUSH SI
PUSH DI
PUSH DS
PUSH ES
LES BX,cadena
CMP pr_pagina,-1 ; ¿primera vez?
JNE pr_otro
CALL prbios_init
pr_otro: MOV AL,ES:[BX]
PUSH BX
CMP AL,' '
JAE pr_ASCII ; no es un código de control
AND AL,AL
JZ pr_exit ; código de control 0: final
CMP AL,1
JE pr_init ; código de control 1: reset
CMP AL,2
JE pr_settinta ; código de control 2: tinta
CMP AL,3
JE pr_setpapel ; código de control 3: papel
CMP AL,4
JE pr_setveces ; código de control 4: repetir
pr_ASCII: CALL pr_AL_bios
POP BX
INC BX
JMP pr_otro
pr_settinta: MOV AL,ES:[BX+1]
AND AL,15
AND pr_color,240
OR pr_color,AL ; actualizar color tinta
POP BX
ADD BX,2
JMP pr_otro
pr_setpapel: MOV AL,ES:[BX+1]
AND AL,240
AND pr_color,15
OR pr_color,AL ; actualizar color papel
POP BX
ADD BX,2
JMP pr_otro
pr_setveces: MOV AL,ES:[BX+1]
MOV pr_veces,AL ; actualizar repeticiones
POP BX
ADD BX,2
JMP pr_otro
pr_init: CALL prbios_init
POP BX
INC BX
JMP pr_otro
pr_exit: POP BX
POP ES
POP DS
POP DI
POP SI
POP BP
RET
_prbios ENDP
pr_AL_bios PROC ; imprimir en color usando BIOS
PUSH AX
MOV AH,3
MOV BH,pr_pagina
INT 10h ; DX = coordenadas del cursor
POP AX
CMP AL,5
JE pr_derecha ; código de control 3: avanzar
CMP AL,10
JE pr_crlf ; código de control 10: CR & LF
MOV AH,9
MOV BH,pr_pagina
MOV BL,pr_color
MOV CL,pr_veces
XOR CH,CH
PUSH DX
INT 10h ; imprimir carácter
POP DX
pr_derecha: ADD DL,pr_veces
MOV pr_veces,1
CMP DL,pr_maxX
JBE pr_av
pr_crlf: XOR DL,DL ; volver al inicio de línea
INC DH ; salto a la siguiente
PUSH DS
MOV AX,40h
MOV DS,AX
CMP DH,DS:[84h] ; variable de nº líneas - 1
POP DS
JBE pr_av
DEC DH
PUSH DX ; es preciso hacer scroll
PUSH DS
MOV AX,40h
MOV DS,AX
MOV DH,DS:[84h]
POP DS
MOV AX,601h
MOV BH,pr_colorb ; color por defecto
XOR CX,CX
MOV DL,pr_maxX
INT 10h ; hacer scroll usando BIOS
POP DX
pr_av: MOV BH,pr_pagina
MOV AH,2
INT 10h ; posicionar cursor
RET
pr_AL_bios ENDP
prbios_init PROC
PUSH BX
MOV AH,15
INT 10h
MOV pr_pagina,BH
MOV AH,8
INT 10h ; obtener color por defecto
MOV pr_color,AH
MOV pr_colorb,AH
PUSH DS
MOV AX,40h
MOV DS,AX
MOV AX,DS:[4Ah]
CMP BYTE PTR DS:[84h],24 ; variable de nº líneas - 1
JAE pr_ln_ok
MOV BYTE PTR DS:[82h],24 ; inicializar esta variable
pr_ln_ok: POP DS
MOV pr_maxX,AL
POP BX
RET
prbios_init ENDP
pr_pagina DB -1 ; página de visualización activa
pr_veces DB 1 ; veces que se imprime cada carácter
pr_color DB ? ; color BIOS para imprimir
pr_colorb DB ? ; color por defecto en pantalla
pr_maxX DB ? ; máxima coordenada X en pantalla
; ------------ Establecer el modo 80x30 en la VGA (fuente 8x16).
; Declaración: int set80x30 (void);
; Devuelve 1 si funciona y 0 si falla (no hay VGA o
; no estaba en modo texto de color) además de asignar
; en ese caso el nº de líneas a 25 (por si la variable
; de la BIOS está indefinida).
_set80x30 PROC FAR
PUSH SI
PUSH DI
MOV AX,1A00h
INT 10h
CMP AL,1Ah
JNE set80err ; no es VGA
CMP BL,7
JE es_vga
CMP BL,8
JE es_vga
CMP BL,9
JE es_vga
CMP BL,12
JBE set80err ; no es VGA
es_vga: MOV AH,0Fh
INT 10h
CMP AL,3
JA set80err ; no es modo texto de color
set30: MOV DX,3D4h ; Dirección base del CRTC
CLI
MOV AX,00C11h ; Vertical Display End (desproteger regs. 0-7)
OUT DX,AX
MOV AX,00D06h ; Vertical Total
OUT DX,AX
MOV AX,03E07h ; Overflow
OUT DX,AX
MOV AX,0EA10h ; Vertical Retrace Start
OUT DX,AX
MOV AX,08C11h ; Vertical Retrace End (y proteger regs. 0-7)
OUT DX,AX
MOV AX,0DF12h ; Vertical Display Enable End
OUT DX,AX
MOV AX,0E715h ; Start Vertical Blanking
OUT DX,AX
MOV AX,00616h ; End Vertical Blanking
OUT DX,AX
MOV DX,3CCh ; Miscellaneous Output
IN AL,DX
AND AL,00110011b ; Cambiamos sólo el clock mode a 1
OR AL,11000100b ; y la VSP a negativa.
MOV DX,3C2h
OUT DX,AL
STI
PUSH DS
MOV AX,0040h ; área de la BIOS
MOV DS,AX
MOV WORD PTR DS:[004Ch],8192 ; nuevo tamaño de página en bytes
MOV BYTE PTR DS:[0084h],29 ; número de líneas-1
POP DS
MOV AX,1 ; función con éxito
POP DI
POP SI
RET
set80err: PUSH DS
MOV AX,0040h ; área de la BIOS
MOV DS,AX
MOV BYTE PTR DS:[0084h],24 ; número de líneas-1
POP DS
MOV AX,0 ; función con fallo
POP DI
POP SI
RET
_set80x30 ENDP
; ------------ Restablecer el modo de vídeo normal.
; Declaración: void ResetVideo (void);
_ResetVideo PROC FAR
PUSH SI
PUSH DI
PUSH DS
MOV DI,40h
MOV DS,DI
MOV AL,DS:[49h]
POP DS
XOR AH,AH
INT 10h ; reponer modo en curso
POP DI
POP SI
RET
_ResetVideo ENDP
; ------------ Gestor de errores críticos para mejorar presentación.
_NuevaInt24 PROC
MOV AL,3 ; error en la función DOS invocada.
IRET
_NuevaInt24 ENDP
; ------------ Indicar con gran rapidez si no hay una tecla pulsada.
; Declaración: int NoHayTecla (void);
_NoHayTecla PROC FAR
PUSH DS
MOV AX,40h
MOV DS,AX
MOV AX,DS:[1Ah]
CMP AX,DS:[1Ch]
MOV AX,1
JE condtec_ok
MOV AX,0
condtec_ok: POP DS
RET
_NoHayTecla ENDP
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_segvideo DW 0A000h ; puede variar con la página
_fuente8x16 LABEL DWORD ; puntero a fuente VGA 8x16
f8x16_off DW 0
f8x16_seg DW 0
_fix9x16 LABEL DWORD ; puntero a caracteres VGA 9x16
fix9x16_off DW 0
fix9x16_seg DW 0
; ------------ Juego de caracteres 8x16 con estilo informático.
_FuenteInfo EQU THIS BYTE
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 60, 66, 129, 165, 129
DB 189, 153, 129, 66, 60, 0, 0, 0
DB 0, 0, 0, 60, 126, 255, 219, 255
DB 195, 231, 255, 126, 60, 0, 0, 0
DB 0, 0, 0, 0, 108, 254, 254, 254
DB 254, 124, 56, 16, 0, 0, 0, 0
DB 0, 0, 0, 0, 16, 56, 124, 254
DB 124, 56, 16, 0, 0, 0, 0, 0
DB 0, 0, 0, 24, 60, 24, 102, 255
DB 102, 24, 24, 60, 0, 0, 0, 0
DB 0, 0, 0, 24, 60, 126, 255, 255
DB 126, 24, 24, 60, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 24, 60
DB 60, 24, 0, 0, 0, 0, 0, 0
DB 255, 255, 255, 255, 255, 255, 231, 195
DB 195, 231, 255, 255, 255, 255, 255, 255
DB 0, 0, 0, 0, 0, 60, 102, 66
DB 66, 102, 60, 0, 0, 0, 0, 0
DB 255, 255, 255, 255, 255, 195, 153, 189
DB 189, 153, 195, 255, 255, 255, 255, 255
DB 0, 0, 30, 14, 26, 50, 120, 204
DB 204, 204, 204, 120, 0, 0, 0, 0
DB 0, 0, 60, 102, 102, 102, 102, 60
DB 24, 126, 24, 24, 0, 0, 0, 0
DB 0, 0, 0, 62, 51, 62, 51, 48
DB 48, 112, 240, 224, 0, 0, 0, 0
DB 0, 0, 0, 63, 51, 63, 51, 51
DB 51, 119, 255, 238, 0, 0, 0, 0
DB 0, 0, 24, 24, 24, 219, 60, 231
DB 60, 219, 24, 24, 24, 0, 0, 0
DB 0, 128, 192, 224, 240, 248, 254, 248
DB 240, 224, 192, 128, 0, 0, 0, 0
DB 0, 2, 6, 14, 30, 62, 254, 62
DB 30, 14, 6, 2, 0, 0, 0, 0
DB 0, 0, 24, 60, 126, 24, 24, 24
DB 126, 60, 24, 0, 0, 0, 0, 0
DB 0, 0, 102, 102, 102, 102, 102, 102
DB 102, 0, 102, 102, 0, 0, 0, 0
DB 0, 0, 127, 219, 219, 219, 123, 27
DB 27, 27, 27, 27, 0, 0, 0, 0
DB 0, 124, 198, 96, 56, 108, 198, 198
DB 108, 56, 12, 198, 124, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 254, 254, 254, 254, 0, 0, 0, 0
DB 0, 0, 24, 60, 126, 24, 24, 24
DB 126, 60, 24, 126, 0, 0, 0, 0
DB 0, 0, 24, 60, 126, 24, 24, 24
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 0, 24, 24, 24, 24, 24, 24
DB 24, 126, 60, 24, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 24, 12, 254
DB 12, 24, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 48, 96, 254
DB 96, 48, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 192, 192
DB 192, 254, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 36, 102, 255
DB 102, 36, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 16, 16, 16, 16, 56
DB 56, 56, 124, 124, 124, 254, 254, 0
DB 0, 254, 254, 124, 124, 124, 56, 56
DB 56, 16, 16, 16, 16, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 48, 48, 48, 48, 56
DB 56, 56, 0, 56, 0, 0, 0, 0
DB 0, 0, 0, 238, 238, 34, 34, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 36, 36, 126, 36, 36
DB 126, 36, 36, 0, 0, 0, 0, 0
DB 0, 0, 0, 24, 126, 98, 96, 126
DB 14, 78, 126, 24, 0, 0, 0, 0
DB 0, 0, 0, 226, 226, 2, 2, 254
DB 224, 224, 238, 238, 0, 0, 0, 0
DB 0, 0, 0, 120, 96, 100, 254, 228
DB 228, 228, 228, 252, 0, 0, 0, 0
DB 0, 0, 0, 56, 56, 8, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 14, 24, 24, 24, 24, 28
DB 28, 28, 28, 28, 14, 0, 0, 0
DB 0, 0, 112, 24, 24, 24, 24, 56
DB 56, 56, 56, 56, 112, 0, 0, 0
DB 0, 0, 0, 0, 0, 214, 214, 124
DB 214, 214, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 24, 24
DB 126, 24, 24, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 56, 56, 8, 8, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 126, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 56, 56, 0, 0, 0, 0
; DB 0, 0, 0, 2, 2, 2, 2, 254 ; / orig.
; DB 224, 224, 224, 224, 0, 0, 0, 0
DB 0, 0, 0, 0, 2, 6, 12, 24 ; / modif.
DB 48, 96, 64, 0, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 134, 142, 142
DB 142, 142, 142, 254, 0, 0, 0, 0
DB 0, 0, 0, 24, 24, 24, 56, 56
DB 56, 56, 56, 56, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 6, 6, 6
DB 254, 224, 226, 254, 0, 0, 0, 0
DB 0, 0, 0, 252, 140, 12, 14, 62
DB 14, 14, 142, 254, 0, 0, 0, 0
DB 0, 0, 0, 140, 140, 140, 140, 140
DB 254, 28, 28, 28, 0, 0, 0, 0
DB 0, 0, 0, 254, 192, 192, 254, 14
DB 14, 14, 142, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 128, 254, 142
DB 142, 142, 142, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 6, 14, 14
DB 14, 14, 14, 14, 0, 0, 0, 0
DB 0, 0, 0, 124, 76, 76, 254, 142
DB 142, 142, 142, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 134, 134, 134
DB 254, 14, 14, 14, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 56, 56
DB 0, 0, 56, 56, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 56, 56
DB 0, 0, 56, 56, 8, 8, 0, 0
DB 0, 0, 0, 0, 6, 12, 24, 48
DB 112, 56, 28, 14, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 126, 126
DB 0, 126, 126, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 96, 48, 24, 12
DB 14, 28, 56, 112, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 6, 126, 112
DB 112, 0, 112, 112, 0, 0, 0, 0
DB 0, 0, 0, 254, 130, 186, 170, 170
DB 190, 128, 254, 0, 0, 0, 0, 0
DB 0, 0, 0, 124, 100, 100, 254, 226
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 0, 0, 0, 252, 196, 196, 254, 226
DB 226, 226, 226, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 194, 192, 192, 224
DB 224, 224, 226, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 194, 194, 226, 226
DB 226, 226, 226, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 192, 192, 192, 254
DB 224, 224, 224, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 192, 192, 192, 248
DB 224, 224, 224, 224, 0, 0, 0, 0
DB 0, 0, 0, 254, 194, 192, 192, 238
DB 226, 226, 226, 254, 0, 0, 0, 0
DB 0, 0, 0, 194, 194, 194, 194, 254
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 0, 0, 0, 48, 48, 48, 48, 56
DB 56, 56, 56, 56, 0, 0, 0, 0
DB 0, 0, 0, 12, 12, 12, 14, 14
DB 14, 142, 142, 254, 0, 0, 0, 0
DB 0, 0, 0, 196, 196, 196, 254, 226
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 0, 0, 0, 192, 192, 192, 224, 224
DB 224, 224, 224, 254, 0, 0, 0, 0
; DB 0, 0, 0, 238, 214, 214, 214, 214 ; M orig.
; DB 230, 230, 230, 226, 0, 0, 0, 0
DB 0, 0, 0, 198, 238, 254, 254, 214 ; M modif.
DB 198, 198, 198, 198, 0, 0, 0, 0
DB 0, 0, 0, 254, 194, 194, 226, 226
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 0, 0, 0, 254, 142, 134, 134, 134
DB 134, 134, 134, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 194, 194, 254, 224
DB 224, 224, 224, 224, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 134, 134, 134
DB 134, 158, 158, 254, 0, 0, 0, 0
DB 0, 0, 0, 252, 196, 196, 254, 226
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 0, 0, 0, 254, 194, 192, 254, 14
DB 14, 14, 142, 254, 0, 0, 0, 0
DB 0, 0, 0, 254, 48, 48, 56, 56
DB 56, 56, 56, 56, 0, 0, 0, 0
DB 0, 0, 0, 194, 194, 194, 226, 226
DB 226, 226, 226, 254, 0, 0, 0, 0
DB 0, 0, 0, 226, 226, 226, 226, 226
DB 226, 102, 100, 124, 0, 0, 0, 0
; DB 0, 0, 0, 230, 230, 230, 214, 214 ; W orig.
; DB 214, 214, 214, 238, 0, 0, 0, 0
DB 0, 0, 0, 198, 198, 198, 214, 214 ; W modif.
DB 214, 214, 214, 238, 0, 0, 0, 0
DB 0, 0, 0, 194, 194, 194, 124, 226
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 0, 0, 0, 130, 130, 130, 254, 56
DB 56, 56, 56, 56, 0, 0, 0, 0
DB 0, 0, 0, 254, 134, 6, 254, 224
DB 224, 224, 226, 254, 0, 0, 0, 0
DB 0, 0, 14, 8, 8, 8, 8, 8
DB 8, 8, 8, 8, 14, 0, 0, 0
DB 0, 0, 0, 128, 128, 128, 128, 254
DB 14, 14, 14, 14, 0, 0, 0, 0
DB 0, 0, 112, 16, 16, 16, 16, 16
DB 16, 16, 16, 16, 112, 0, 0, 0
DB 0, 0, 60, 36, 36, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 255, 0, 0
DB 0, 0, 32, 56, 56, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 124, 68, 4
DB 126, 102, 102, 126, 0, 0, 0, 0
DB 0, 0, 0, 96, 96, 126, 98, 98
DB 98, 114, 114, 126, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 96
DB 112, 112, 114, 126, 0, 0, 0, 0
DB 0, 0, 0, 6, 6, 126, 70, 70
DB 78, 78, 78, 126, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 98
DB 126, 112, 114, 126, 0, 0, 0, 0
DB 0, 0, 0, 28, 16, 60, 24, 24
DB 28, 28, 28, 28, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 98
DB 114, 114, 114, 126, 2, 2, 126, 0
DB 0, 0, 0, 96, 96, 126, 98, 98
DB 114, 114, 114, 114, 0, 0, 0, 0
DB 0, 0, 0, 24, 24, 0, 16, 16
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 0, 0, 24, 24, 0, 16, 16
DB 24, 24, 24, 24, 8, 8, 24, 0
DB 0, 0, 0, 96, 96, 100, 100, 100
DB 126, 114, 114, 114, 0, 0, 0, 0
DB 0, 0, 0, 48, 48, 48, 48, 48
DB 56, 56, 56, 56, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 254, 146, 146
DB 218, 218, 218, 218, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 98
DB 114, 114, 114, 114, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 98
DB 114, 114, 114, 126, 64, 64, 64, 0
DB 0, 0, 0, 0, 0, 126, 98, 98
DB 114, 114, 114, 126, 2, 2, 2, 0
DB 0, 0, 0, 0, 0, 126, 96, 96
DB 112, 112, 112, 112, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 96
DB 126, 14, 78, 126, 0, 0, 0, 0
DB 0, 0, 0, 16, 16, 60, 24, 24
DB 28, 28, 28, 28, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 98, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 114, 114, 114
DB 114, 54, 52, 60, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 146, 146, 146
DB 218, 218, 218, 238, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 98, 98, 98
DB 60, 114, 114, 114, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 114, 114, 114
DB 114, 98, 98, 126, 2, 2, 126, 0
DB 0, 0, 0, 0, 0, 126, 70, 6
DB 126, 112, 114, 126, 0, 0, 0, 0
DB 0, 0, 30, 24, 24, 12, 8, 48
DB 8, 12, 24, 24, 30, 0, 0, 0
DB 0, 0, 24, 24, 24, 24, 24, 0
DB 24, 24, 24, 24, 24, 0, 0, 0
DB 0, 0, 120, 24, 24, 48, 16, 12
DB 16, 48, 24, 24, 120, 0, 0, 0
DB 0, 0, 0, 0, 0, 118, 220, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 16, 56, 108
DB 198, 198, 254, 0, 0, 0, 0, 0
DB 0, 0, 0, 254, 194, 192, 192, 224
DB 224, 224, 226, 254, 8, 14, 98, 126
DB 0, 0, 102, 0, 0, 98, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 12, 8, 16, 0, 126, 98, 98
DB 126, 112, 114, 126, 0, 0, 0, 0
DB 0, 16, 56, 100, 0, 124, 68, 4
DB 126, 102, 102, 126, 0, 0, 0, 0
DB 0, 0, 102, 0, 0, 124, 68, 4
DB 126, 102, 102, 126, 0, 0, 0, 0
DB 0, 48, 16, 8, 0, 124, 68, 4
DB 126, 102, 102, 126, 0, 0, 0, 0
DB 0, 124, 100, 124, 0, 124, 68, 4
DB 126, 102, 102, 126, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 126, 98, 96
DB 112, 112, 114, 126, 8, 14, 98, 126
DB 0, 16, 56, 100, 0, 126, 98, 98
DB 126, 112, 114, 126, 0, 0, 0, 0
DB 0, 0, 102, 0, 0, 126, 98, 98
DB 126, 112, 114, 126, 0, 0, 0, 0
DB 0, 48, 16, 8, 0, 126, 98, 98
DB 126, 112, 114, 126, 0, 0, 0, 0
DB 0, 0, 102, 0, 0, 0, 16, 16
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 16, 56, 100, 0, 0, 16, 16
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 48, 16, 8, 0, 0, 16, 16
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 204, 0, 124, 100, 100, 254, 226
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 124, 100, 124, 0, 124, 100, 100, 254
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 12, 8, 16, 254, 192, 192, 192, 254
DB 224, 224, 224, 254, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 255, 153, 25
DB 255, 220, 221, 255, 0, 0, 0, 0
DB 0, 0, 0, 127, 72, 72, 252, 207
DB 204, 204, 204, 207, 0, 0, 0, 0
DB 0, 16, 56, 100, 0, 126, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 0, 102, 0, 0, 126, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 48, 16, 8, 0, 126, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 16, 56, 100, 0, 98, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 48, 16, 8, 0, 98, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 0, 102, 0, 0, 114, 114, 114
DB 114, 98, 98, 126, 2, 2, 126, 0
DB 0, 204, 0, 254, 142, 134, 134, 134
DB 134, 134, 134, 254, 0, 0, 0, 0
DB 0, 102, 0, 194, 194, 194, 226, 226
DB 226, 226, 226, 254, 0, 0, 0, 0
DB 0, 0, 24, 24, 24, 126, 98, 112
DB 114, 126, 24, 24, 24, 0, 0, 0
DB 0, 0, 0, 28, 54, 48, 48, 124
DB 48, 48, 102, 252, 0, 0, 0, 0
DB 0, 0, 0, 102, 102, 60, 24, 126
DB 24, 126, 24, 24, 0, 0, 0, 0
DB 0, 0, 0, 252, 196, 196, 252, 228
DB 238, 228, 230, 230, 0, 0, 0, 0
DB 0, 14, 27, 24, 24, 24, 24, 126
DB 24, 24, 24, 24, 24, 216, 112, 0
DB 0, 12, 8, 16, 0, 124, 68, 4
DB 126, 102, 102, 126, 0, 0, 0, 0
DB 0, 12, 8, 16, 0, 0, 16, 16
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 12, 8, 16, 0, 126, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 12, 8, 16, 0, 98, 98, 98
DB 114, 114, 114, 126, 0, 0, 0, 0
DB 0, 0, 118, 220, 0, 126, 98, 98
DB 114, 114, 114, 114, 0, 0, 0, 0
DB 118, 220, 0, 254, 194, 194, 226, 226
DB 226, 226, 226, 226, 0, 0, 0, 0
DB 0, 124, 68, 4, 126, 102, 126, 0
DB 126, 0, 0, 0, 0, 0, 0, 0
DB 0, 126, 98, 98, 114, 114, 126, 0
DB 126, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 28, 28, 0, 28, 28
DB 252, 192, 194, 254, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 254
DB 192, 192, 192, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 254
DB 6, 6, 6, 0, 0, 0, 0, 0
DB 0, 48, 49, 113, 113, 113, 1, 255
DB 224, 239, 227, 239, 236, 15, 0, 0
DB 0, 48, 49, 113, 113, 113, 1, 255
DB 224, 235, 235, 235, 239, 3, 0, 0
DB 0, 0, 0, 56, 0, 56, 56, 56
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 51, 102, 204
DB 102, 51, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 204, 102, 51
DB 102, 204, 0, 0, 0, 0, 0, 0
DB 68, 17, 68, 17, 68, 17, 68, 17
DB 68, 17, 68, 17, 68, 17, 68, 17
DB 170, 85, 170, 85, 170, 85, 170, 85
DB 170, 85, 170, 85, 170, 85, 170, 85
DB 119, 221, 119, 221, 119, 221, 119, 221
DB 119, 221, 119, 221, 119, 221, 119, 221
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 24, 248
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 248, 24
DB 248, 24, 24, 24, 24, 24, 24, 24
DB 54, 54, 54, 54, 54, 54, 54, 246
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 0, 0, 0, 0, 0, 0, 0, 254
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 0, 0, 0, 0, 0, 0, 248, 24
DB 248, 24, 24, 24, 24, 24, 24, 24
DB 54, 54, 54, 54, 54, 54, 246, 6
DB 246, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 0, 0, 0, 0, 0, 0, 254, 6
DB 246, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 246, 6
DB 254, 0, 0, 0, 0, 0, 0, 0
DB 54, 54, 54, 54, 54, 54, 54, 254
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 24, 24, 24, 24, 24, 24, 248, 24
DB 248, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 248
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 24, 31
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 24, 24, 24, 24, 24, 24, 24, 255
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 255
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 24, 31
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 0, 0, 0, 0, 0, 0, 0, 255
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 24, 24, 24, 24, 24, 24, 24, 255
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 31, 24
DB 31, 24, 24, 24, 24, 24, 24, 24
DB 54, 54, 54, 54, 54, 54, 54, 55
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 55, 48
DB 63, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 63, 48
DB 55, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 247, 0
DB 255, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 255, 0
DB 247, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 55, 48
DB 55, 54, 54, 54, 54, 54, 54, 54
DB 0, 0, 0, 0, 0, 0, 255, 0
DB 255, 0, 0, 0, 0, 0, 0, 0
DB 54, 54, 54, 54, 54, 54, 247, 0
DB 247, 54, 54, 54, 54, 54, 54, 54
DB 24, 24, 24, 24, 24, 24, 255, 0
DB 255, 0, 0, 0, 0, 0, 0, 0
DB 54, 54, 54, 54, 54, 54, 54, 255
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 255, 0
DB 255, 24, 24, 24, 24, 24, 24, 24
DB 0, 0, 0, 0, 0, 0, 0, 255
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 54, 63
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 24, 24, 24, 24, 24, 24, 31, 24
DB 31, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 31, 24
DB 31, 24, 24, 24, 24, 24, 24, 24
DB 0, 0, 0, 0, 0, 0, 0, 63
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 54, 54, 54, 54, 54, 54, 54, 255
DB 54, 54, 54, 54, 54, 54, 54, 54
DB 24, 24, 24, 24, 24, 24, 255, 24
DB 255, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 24, 248
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 31
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 255, 255, 255, 255, 255, 255, 255, 255
DB 255, 255, 255, 255, 255, 255, 255, 255
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 255, 255, 255, 255, 255, 255, 255, 255
DB 240, 240, 240, 240, 240, 240, 240, 240
DB 240, 240, 240, 240, 240, 240, 240, 240
DB 15, 15, 15, 15, 15, 15, 15, 15
DB 15, 15, 15, 15, 15, 15, 15, 15
DB 255, 255, 255, 255, 255, 255, 255, 255
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 115, 222
DB 204, 204, 222, 115, 0, 0, 0, 0
DB 0, 0, 0, 252, 196, 196, 206, 226
DB 226, 226, 234, 238, 128, 128, 128, 0
DB 0, 0, 0, 126, 102, 96, 96, 96
DB 96, 96, 96, 96, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 254, 108, 108
DB 108, 108, 108, 108, 0, 0, 0, 0
DB 0, 0, 0, 126, 102, 48, 24, 12
DB 24, 48, 102, 126, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 126, 216
DB 216, 216, 216, 112, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 102, 102, 102
DB 102, 124, 96, 96, 96, 192, 0, 0
DB 0, 0, 0, 0, 0, 118, 220, 24
DB 24, 24, 24, 24, 0, 0, 0, 0
DB 0, 0, 0, 126, 24, 60, 102, 102
DB 102, 60, 24, 126, 0, 0, 0, 0
DB 0, 0, 0, 60, 102, 102, 102, 126
DB 102, 102, 102, 60, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 56, 108, 198
DB 198, 108, 108, 238, 0, 0, 0, 0
DB 0, 0, 0, 30, 48, 24, 12, 62
DB 102, 102, 102, 60, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 110, 219
DB 219, 118, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 12, 56, 108
DB 124, 108, 56, 96, 0, 0, 0, 0
DB 0, 0, 0, 28, 48, 96, 96, 120
DB 96, 96, 48, 28, 0, 0, 0, 0
DB 0, 0, 0, 0, 60, 102, 102, 102
DB 102, 102, 102, 102, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 126, 0
DB 126, 0, 126, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 24, 24, 126
DB 24, 24, 0, 126, 0, 0, 0, 0
DB 0, 0, 0, 48, 24, 12, 6, 12
DB 24, 48, 0, 126, 0, 0, 0, 0
DB 0, 0, 0, 12, 24, 48, 96, 48
DB 24, 12, 0, 126, 0, 0, 0, 0
DB 0, 0, 0, 14, 27, 27, 24, 24
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 24, 24, 24, 24, 24, 24, 24
DB 24, 216, 216, 112, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 24, 0, 0
DB 126, 0, 0, 24, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 118, 220
DB 0, 118, 220, 0, 0, 0, 0, 0
DB 0, 0, 56, 108, 108, 56, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 24
DB 24, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 24, 0, 0, 0, 0, 0, 0, 0
DB 0, 15, 12, 12, 12, 12, 12, 204
DB 108, 60, 28, 12, 0, 0, 0, 0
DB 0, 126, 98, 98, 114, 114, 114, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 126, 70, 6, 126, 112, 126, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 60, 60
DB 60, 60, 60, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
DB 0, 0, 0, 0, 0, 0, 0, 0
_DATA ENDS
END