;**********************************************************************;
;* C G A / E G A G R A P H I C R A M F O N T *;
;*--------------------------------------------------------------------*;
;* doel : Maakt het mogelijk om tekst af te drukken in *;
;* de grafische mode van een kleuren-kaart; het *;
;* ramfont kan van disk geladen worden. *;
;*--------------------------------------------------------------------*;
;* opm : De routine PIXEL uit de file EGA.INC moet *;
;* vanuit het hoofdprogramma mee geassembleerd en *;
;* beschikbaar zijn. *;
;*--------------------------------------------------------------------*;
;* auteur : Roland Leurs *;
;* ontwikkeld : 29-1-92 *;
;*--------------------------------------------------------------------*;
;* gebruik : Als include-file meenemen in het programma; de *;
;* functies kunnen als subroutines aangeroepen *;
;* worden. *;
;**********************************************************************;
;***********************************************************************
; Opslag van data:
;***********************************************************************
SCALE_X DW 1 ; HORIZONTALE SCHAAL FACTOR
SCALE_Y DW 1 ; VERTIKALE SCHAAL FACTOR
SCALE_X8 DW ? ; HOR. SCHAAL FACTOR * 8
TEKEN_HALF DB ? ; TEKENHOOGTE / 2
TEKENATTR DB 00 ; ATTRIBUUT VOOR GRAFISCH TEKEN
;***********************************************************************
; Font inladen. Aanroepen met het adres van de filenaam van het font in
; het registerpaar DS:DX.
; Uitvoer : carry = 0 -> font geladen
; carry = 1 -> error, foutcode in AX
;***********************************************************************
LOADFONT PROC NEAR
MOV AX,3D00H ; DOS FUNCTIE: BESTAND OPENEN
INT 21H
JC ENDLOAD ; SPRING INDIEN FOUT OPGETREDEN
MOV BX,AX ; ZET HANDLE IN BX
MOV AX,3F00H ; DOS FUNCTIE: BESTAND LEZEN
MOV CX,4096 ; AANTAL TE LEZEN BYTES
LEA DX,RAMFONT ; LAADT ADRES VAN DE BUFFER
INT 21H
MOV AX,3E00H ; DOS FUNCTIE: BESTAND SLUITEN
INT 21H
ENDLOAD: RET ; EINDE ROUTINE
LOADFONT ENDP
;***********************************************************************
; Karakter op het scherm schrijven. De coordinaten staan in de registers
; BX,DX. Het karakter zelf staat in AX. Voor het plotten van een pixel
; wordt de routine PIXEL uit EGA.INC aangeroepen.
; De registers BX,DX geven na afloop de coordinaten voor een volgend
; karakter. AX blijft ongewijzigd; de overige registers kunnen veranderen.
; Vanaf versie 4.23 worden diverse attributen ondersteund voor de weer-
; gave van de karakters. Deze attributen zijn in onderstaande tabel
; weergegeven:
; bit 7 : Halve tekenhoogte (8 ipv 16 beeldschermregels)
; bit 6 : --niet gebruikt--
; bit 5 : Double height
; bit 4 : Greyscale
; bit 3 : Invert
; bit 2 : Underline
; bit 1 : Italic
; bit 0 : Bold
; De opslag in de fonttabel blijft 16 bytes, ook als bit 7 gezet is.
;***********************************************************************
WRITE PROC NEAR
PUSH AX ; SAVE GEBRUIKTE REGISTERS
PUSH DX
MOV CL,KLEUR ; SAVE HUIDIGE KLEUR
PUSH CX
MOV CL,TEKENATTR ; TEST OP GRIJS TEKEN
AND CL,00010000B
JE WRITE_NGRIJS ; SPRING INDIEN NIET GRIJS
MOV KLEUR,7 ; ZET KLEUR 'GRIJS'
WRITE_NGRIJS: MOV CL,4 ; VERMENIGVULDIG KARAKTER MET 16
SHL AX,CL
MOV SI,AX ; ZET WEG ALS INDEX
DEC CL ; VERLAAG VERM.FACTOR
MOV AX,SCALE_X ; BEREKEN X-SCHAAL * 8
SHL AX,CL
MOV SCALE_X8,AX ; BERG OP IN WERKRUIMTE
XOR BP,BP ; WERK IN SCHERMPAGINA 0
MOV CL,16 ; LAADT AANTAL REGELS PER KARAKTER
MOV CH,TEKENATTR ; LAADT ATTRIBUUT
AND CH,10000000B ; TEST OP HALVE TEKENHOOGTE
JZ WRITE_NHALF ; SPRING INDIEN NIET HALVE HOOGTE
SHR CL,1 ; HALVEER DE TEKENHOOGTE
WRITE_NHALF: XOR CH,CH ; CX BEVAT NU AANTAL REGELS PER TEKEN
MOV TEKEN_HALF,CL ; ZET HOOGTE IN WERKRUIMTE
SHR TEKEN_HALF,1 ; DEEL DOOR 2
DEC SI
WRITE_TEKEN: INC SI ; VERLAAG TABELINDEX
MOV AH,RAMFONT[SI] ; LEES REGEL VAN KARAKTER
MOV AL,TEKENATTR ; LEES ATTRIBUUT
AND AL,00000001B ; TEST OP VET
JZ WRITE_NVET ; SPRING ALS NIET VET
MOV AL,AH ; KOPIEER DATA IN AL
SHR AL,1 ; SCHUIF EENMAAL RECHTS
OR AH,AL ; OR MET OORSPRONKELIJKE DATA
WRITE_NVET: MOV AL,TEKENATTR ; LEES ATTRIBUUT
TEST AL,00000100B ; TEST OP ONDERSTREPEN
JZ WRITE_NSTREEP ; SPRING BIJ NIET ONDERSTREPEN
CMP CX,1 ; TEST OP LAATSTE KARAKTERREGEL
JNE WRITE_NSTREEP ; SPRING ALS NIET LAATSTE REGEL
MOV AH,0FFH ; LAADT STREEPJE
WRITE_NSTREEP: TEST AL,00000010B ; TEST OP CURSIEF
JZ WRITE_NCURS ; SPRING ALS NIET CURSIEF
CMP CL,TEKEN_HALF ; TEST OP HELFT VAN TEKEN
JL WRITE_NCURS ; SPRING INDIEN NIET OP DE HELFT
SHR AH,1 ; SCHUIF EEN POSITIE NAAR RECHTS
WRITE_NCURS: TEST AL,00001000B ; TEST OP INVERTEREN
JZ WRITE_NINV ; SPRING ALS NIET INVERTEREN
XOR AH,0FFH ; INVERTEER DATA
WRITE_NINV: PUSH CX ; BEWAAR REGELTELLER
MOV CX,8 ; LAADT AANTAL BITS PER REGEL
REGEL: MOV AL,KLEUR ; LAADT PIXEL BEWERKING (zet pixel)
SHL AH,1 ; SCHUIF KARAKTER PIXEL IN CARRY
JC WRITE1 ; SPRING INDIEN PIXEL ZETTEN
MOV AL,0FFH ; ANDERS LAADT PIXEL WISSEN OPDRACHT
WRITE1: PUSH CX ; BEWAAR BITTELLER
MOV CX,SCALE_Y ; LAADT VERTIKALE SCHAAL
KOLOM: PUSH CX ; BEWAAR VERTIKALE TELLER
MOV CX,SCALE_X ; LAADT HORIZONTALE SCHAAL
PLOTPIXEL: PUSH AX
PUSH BX ; SAVE REGISTERS
PUSH CX
PUSH DX
PUSH SI
MOV CX,BX ; JUISTE REGISTERS ZETTEN
CMP AL,0FFH ; ALS ER GEEN PIXEL GEZET WORDT
JE WRITE2 ; DAN NIETS PLOTTEN
CALL PUTPIX ; PIXEL ZETTEN
WRITE2: POP SI
POP DX ; REGISTERS TERUGHALEN
POP CX
POP BX
POP AX
INC BX ; VERHOOG X-COORDINAAT
LOOP PLOTPIXEL ; HERHAAL TOT SCHAAL FACTOR X BEREIKT
POP CX ; HAAL VERTIKALE TELLER TERUG
SUB BX,SCALE_X ; VERLAAG X-COORDINAAT
INC DX ; VERHOOG Y-COORDINAAT
LOOP KOLOM ; HERHAAL TOT SCHAAL FACTOR Y BEREIKT
SUB DX,SCALE_Y ; VERLAAG Y-COORDINAAT
ADD BX,SCALE_X ; X-COORDINAAT VOOR VOLGEND KAR.PIXEL
POP CX ; HAAL BITTELLER TERUG
LOOP REGEL ; HERHAAL TOT EEN KARAKTERREGEL AF IS
SUB BX,SCALE_X8 ; ZET X NAAR BEGIN VAN KARAKTER
ADD DX,SCALE_Y ; ZET Y EEN KARAKTERREGEL OMHOOG
POP CX ; HAAL REGELTELLER TERUG
LOOP WRITE_TEKEN ; HERHAAL TOT KARAKTER GETEKEND IS
ADD BX,SCALE_X8 ; ZET X AAN BEGIN VAN VOLGEND KARAKTER
INC BX
POP CX ; KLEUR HERSTELLEN
MOV KLEUR,CL
POP DX ; ZET Y AAN BEGIN VAN VOLGEND KARAKTER
POP AX ; HAAL KARAKTER TERUG VAN STACK
RET ; EINDE ROUTINE
WRITE ENDP
;***********************************************************************
; De volgende routine drukt een gehele string af in grafische mode. Dit
; gebeurt door het herhaald aanroepen van de voorgaande routine. Het adres
; van de af te drukken string dient in DS:DI gegeven te worden. De string
; eindigt met de code 00.
; Hierbij worden geen registers gewijzigd.
;***********************************************************************
WRITELN PROC NEAR
PUSHF ; SAVE VLAGGETJES
PUSH AX ; SAVE ALLE REGISTERS
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
MOV AH,00H ; AH MOET STEEDS 0 ZIJN
WRITELN1: MOV AL,[DI] ; LAADT KARAKTER
CMP AL,00H ; TEST OP EINDE STRING
JE WRITELN2 ; SPRING INDIEN EINDE STRING
PUSH DI ; SAVE DI
CALL WRITE ; DRUK KARAKTER AF
POP DI ; HERSTEL DI
INC DI ; VERHOOG INDEX
JMP SHORT WRITELN1 ; SPRING VOOR VOLGEND KARAKTER
WRITELN2: POP SI ; HERSTEL GEBRUIKTE REGISTERS
POP DI
POP DX
POP CX
POP BX
POP AX
POPF ; HERSTEL VLAGGEN
RET ; EINDE ROUTINE
WRITELN ENDP
;***********************************************************************
; Tenslotte nog enkele macro's om fonts te laden, de schaalfactoren in
; te stellen en een karakter resp. string af te drukken.
;***********************************************************************
H_SIZE MACRO X
MOV SCALE_X,X ; ZET HORIZONTALE SCHAAL FACTOR
ENDM
V_SIZE MACRO Y
MOV SCALE_Y,Y ; ZET VERTIKALE SCHAAL FACTOR
ENDM
GPRINTC MACRO T
MOV AX,T ; LAADT AF TE DRUKKEN TEKEN
CALL WRITE ; PRINT KARAKTER
ENDM
GPRINT MACRO STR
LEA DI,STR ; LAADT ADRES VAN STRING
CALL WRITELN ; PRINT STRING
ENDM
INITFONT MACRO FONTNAAM
LEA DX,FONTNAAM ; ZET ADRES VAN FNAAM IN DX
CALL LOADFONT ; LAADT HET FONT
ENDM
MOVETO MACRO KOLOM,REGEL
IFNB <KOLOM>
MOV BX,KOLOM
ENDIF
IFNB <REGEL>
MOV DX,REGEL
ENDIF