;---------------------------------------------------------------------
;Font editor for EGA 8x14 fonts
;---------------------------------------------------------------------
O equ <offset>
B equ <byte ptr>
W equ <word ptr>
.Model Tiny
.Code
.186
Org 100h
Start: call Main ;Call main procedure
mov ah,4Ch ;Exit to DOS
int 21h
;---------------------------------------------------------------------
FError$ db 'Error accessing file$'
Title$ db ' EGA 8x14 Font Editor -- by Selenium Software $'
INSTRUC_LEN equ 47 ;Length of Instruc... strings
Instruc1$ db ' Arrows(keypad or cursor)=Move around in grid $'
Instruc2$ db ' Shft-Arrows(keypad only),numbers 2468=Select $'
Instruc3$ db ' character [+]=Next char [-]=Prev. char $'
Instruc4$ db ' Q=Quit Space=Toggle pixel B=Copy BIOS char $'
Instruc5$ db ' S=Save C=Copy P=Paste M+Arrow=Move bitmap $'
Instruc6$ db ' T=Switch to typing mode(Esc returns to edit) $'
Shift$ db ' Enter direction to shift: $'
CharStr$ db ' Current Char: '
HexData db '?? " " $'
Ext$ db '.F14',0
CrossYList db 1,2,3,4,5,6,6,7,8,8,9,9,10,10
;---------------------------------------------------------------------
FileHandle dw 0 ;File handle
X_SIZE equ 32 ;Size of grid squares
Y_SIZE equ 24
CurFont dw 0 ;Current font
CurChar dw 0 ;Current character
XPos dw 0 ;X and Y position
YPos dw 0
;---------------------------------------------------------------------
; Main procedure
;---------------------------------------------------------------------
Main Proc
mov dx,O(BiosFont) ;DX = BIOS font buffer
call GetFont ;Copy font into buffer
mov CurFont,dx ;Set current font
mov cx,1 ;CX = length
add cl,[ds:80h]
mov di,81h ;DI = command line
mov al,20h ;Scan for non-space
repe scasb
lea si,[di-1] ;Save position
repne scasb ;Scan for space
mov byte ptr [di-1],0 ;Set to zero
sub di,si ;Copy to filename buffer
mov cx,di
mov di,O(FileName)
rep movsb
;-------------------------------------------------
mov si,O(FileName) ;SI = filename
m_LenOLoop: mov di,si ;DI = SI
mov cx,-1 ;CX = -1
m_LenLoop: inc cx ;Increment length
lodsb ;Load byte
cmp al,'\' ;If it's a '\', start over
je m_LenOLoop
test al,al ;Loop while not null
jnz m_LenLoop
mov al,'.' ;If there is already an extension,
repne scasb ;then do nothing
je m_NameOK
mov si,O(Ext$) ;DI now points to the null terminator
mov cx,5 ;Copy the extension '.FNT' onto the
rep movsb ;end of the filename
;-------------------------------------------------
m_NameOK: mov di,O(Buffer) ;Clear the buffer
mov cx,3584/2
xor ax,ax
rep stosw
mov ax,3D02h ;Open font file
mov dx,O(FileName)
int 21h
jnc m_FileOK ;If it does not exist, then
mov ah,3Ch ;create it (normal attr, etc.)
xor cx,cx
int 21h
jc m_FError
m_FileOK: mov FileHandle,ax ;Save file handle
xchg bx,ax ;BX = handle
mov ah,3Fh ;Read 3584 bytes
mov cx,3584
mov dx,O(Buffer)
int 21h
jc m_UseBios ;If an error occurred, then
test ax,ax
jnz m_Cont
m_UseBios: mov si,O(BiosFont) ;use the BIOS font
mov di,O(Buffer)
mov cx,3584
rep movsb
;-------------------------------------------------
m_Cont: call Initialize ;Initialize display & variables
call MainLoop ;Go into main loop
;-------------------------------------------------
m_Done: mov ax,3 ;Switch to text mode
int 10h
mov ax,4202h ;Seek to end of file
mov bx,FileHandle
xor cx,cx
xor dx,dx
int 21h
or dx,ax ;DX = empty flag
mov ah,3Eh ;Close the file
int 21h
test dx,dx ;If the file is still empty, then
jnz m_Exit
mov ah,41h ;delete it
mov dx,O(FileName)
int 21h
m_Exit: xor al,al ;Return with error code 0
ret
;-------------------------------------------------
m_FError: mov ah,9 ;Output error string
mov dx,O(FError$)
int 21h
mov al,1 ;Return with error code 1
ret
Main EndP
;---------------------------------------------------------------------
; MainLoop -- Main editing loop
;---------------------------------------------------------------------
MainLoop Proc
pusha ;Save all registers
x_KeyLoop: call PutCursor ;Show the cursor
xor ah,ah ;Wait for a key
int 16h
call PutCursor ;Hide the cursor
x_KeyChk1: cmp al,'a' ;Make it uppercase
jb $+4
add al,'A'-'a'
cmp al,'-' ;[-] - Char Select Left?
je x_CLeft
cmp al,'+' ;[+] - Char Select Right?
je x_CRight
cmp al,'4' ;4 - Char Select Left?
je x_CLeft
cmp al,'6' ;6 - Char Select Right?
je x_CRight
cmp al,'8' ;8 - Char Select Up?
je x_CUp
cmp al,'2' ;2 - Char Select Down?
je x_CDown
cmp al,' ' ;Space - Flip Pixel?
je x_Flip
cmp al,'B' ;B - Get BIOS char?
je x_Bios
cmp al,'C' ;C - Copy?
je x_Copy
cmp al,'P' ;P - Paste?
je x_Paste
cmp al,'Q' ;Q - Exit?
je x_ExitJmp
cmp al,'T' ;T - Typing mode?
je x_Type
cmp al,'M' ;M - Move bitmap?
je x_Move
cmp al,'S' ;S - Save?
je x_Save
jmp x_KeyChk2 ;Jump to second key block
x_ExitJmp: jmp x_Exit ;Jump to exit
;-------------------------------------------------
x_CLeft: mov al,-1 ;Moving back 1 character
jmp x_NewChar ;Display new character
;-------------------------------------------------
x_CRight: mov al,1 ;Moving forward 1 character
jmp x_NewChar ;Display new character
;-------------------------------------------------
x_CUp: mov al,-20h ;Moving up 1 row
jmp x_NewChar ;Display new character
;-------------------------------------------------
x_CDown: mov al,20h ;Moving down 1 row
;Fall through...
;-------------------------------------------------
x_NewChar: add al,B CurChar ;Add in current character
xchg al,B CurChar ;Show old character
call ShowChar
mov ax,CurChar ;Show new character
call ShowChar
jmp x_KeyLoop
;-------------------------------------------------
x_Flip: mov bx,XPos ;BX = X, CX = Y
mov cx,YPos
call FGetPixel ;Flip the pixel
xor al,1
call FPutPixel
jmp x_KeyLoop
;-------------------------------------------------
x_Bios: imul si,CurChar,14 ;SI = BIOS font char
add si,O(BiosFont)
jmp x_CopyShow ;Copy and show
;-------------------------------------------------
x_Copy: imul si,CurChar,14 ;SI = working font char
add si,O(Buffer) ;DI = clipboard
mov di,O(Clipboard)
mov cx,14 ;Copy 14 bytes
rep movsb
jmp x_KeyJmp
;-------------------------------------------------
x_Paste: mov si,O(Clipboard) ;SI = clipboard
;Fall through...
;-------------------------------------------------
x_CopyShow: mov ax,CurChar ;AX = current char
imul di,ax,14 ;DI = working font char
add di,O(Buffer)
mov cx,14 ;Copy 14 bytes
rep movsb
call ShowChar ;Redraw the character
jmp x_KeyJmp
;-------------------------------------------------
x_Type: call TypeMode ;Call typing-mode loop
jmp x_KeyJmp
;-------------------------------------------------
x_Move: call Shift ;Call shift-char procedure
jmp x_KeyJmp
;-------------------------------------------------
x_Save: mov bx,FileHandle ;BX = file handle
mov ax,4200h ;Seek to beginning of file
xor cx,cx
xor dx,dx
int 21h
mov ah,40h ;Write 3584 bytes to file
mov dx,O(Buffer)
mov cx,3584
int 21h
mov ah,40h ;Truncate file at 3584 bytes
xor cx,cx
int 21h
jmp x_KeyJmp
;-------------------------------------------------
x_KeyChk2: xchg al,ah ;Scan code in AL
cmp al,53h ;Del - Clear?
je x_Clear
cmp al,4Bh ;Left?
je x_Left
cmp al,4Dh ;Right?
je x_Right
cmp al,48h ;Up?
je x_Up
cmp al,50h ;Down?
je x_Down
x_KeyJmp: jmp x_KeyLoop ;Invalid, loop
;-------------------------------------------------
x_Clear: xor al,al ;AL = 0
imul di,CurChar,14 ;DI = working font char
add di,O(Buffer)
mov cx,14 ;Clear 14 bytes
rep stosb
mov ax,CurChar ;Redraw the character
call ShowChar
jmp x_KeyLoop
;-------------------------------------------------
x_Left: mov ax,XPos ;Decrement XPos
dec ax
js x_KeyJmp ;Don't save if < 0
mov XPos,ax
jmp x_KeyLoop
;-------------------------------------------------
x_Right: mov ax,XPos ;Increment XPos
inc ax
cmp al,7 ;Don't save if > 7
jg x_KeyJmp
mov XPos,ax
jmp x_KeyLoop
;-------------------------------------------------
x_Up: mov ax,YPos ;Decrement YPos
dec ax
js x_KeyJmp ;Don't save if < 0
mov YPos,ax
jmp x_KeyLoop
;-------------------------------------------------
x_Down: mov ax,YPos ;Increment XPos
inc ax
cmp al,13 ;Don't save if > 13
jg x_KeyJmp
mov YPos,ax
jmp x_KeyLoop
;-------------------------------------------------
x_Exit: popa ;Restore registers
ret ;Return
MainLoop EndP
;---------------------------------------------------------------------
; FillRect -- Draw a filled rectangle
;---------------------------------------------------------------------
; BX = X1, CX = Y1, SI = X2, DI = Y2, AL = color (0 or 1)
FillRect Proc
pusha ;Save all registers
cmp cx,di ;Put Y values in order
jle $+4
xchg cx,di
mov dx,cx ;BX = X1, CX = X2
mov cx,si ;DX = Y1
fr_loop: call PutRow ;Draw this row
inc dx ;Next row
cmp dx,di ;Loop while not done
jle fr_loop
popa ;Restore registers
ret ;Return
FillRect EndP
;---------------------------------------------------------------------
; FlipPixel -- Flip the value of a pixel
;---------------------------------------------------------------------
; BX = X, CX = Y
FlipPixel Proc
pusha ;Save all registers
push ds
push 0A000h ;DS = video memory
pop ds
mov dx,bx ;DX = X
imul bx,cx,80 ;BX = Y * 80 = row offset
mov cx,dx ;CX = X
shr dx,3 ;DX = byte offset within row
add bx,dx ;BX = offset
and cl,7 ;AL = bit mask
mov al,80h
shr al,cl
xor [bx],al ;Flip the pixel
pop ds ;Restore registers
popa
ret ;Return
FlipPixel EndP
;---------------------------------------------------------------------
; FGetPixel -- Read a pixel from the current character
;---------------------------------------------------------------------
; BX = X, CX = Y, returns AL = color (0 or 1)
FGetPixel Proc
push bx ;Save registers
push cx
push si
imul si,CurChar,14 ;SI = offset
add si,cx
mov cx,bx ;AL = bit mask
mov al,80h
shr al,cl
and al,Buffer[si] ;Read the pixel
inc cx ;AL = 0 if off, 1 if on
rol al,cl
pop si ;Restore registers
pop cx
pop bx
ret ;Return
FGetPixel EndP
;---------------------------------------------------------------------
; FPutPixel -- Write a pixel to the current character
;---------------------------------------------------------------------
; BX = X, CX = Y, AL = color (0 or 1)
FPutPixel Proc
pusha ;Save registers
mov si,bx ;SI = X, DI = Y
mov di,cx
cmp al,1 ;BP = color (0 or 1)
sbb bp,bp
inc bp
imul ax,CurChar,14 ;BX = offset
add cx,ax ;AL = bit mask
xchg cx,bx
mov al,80h
shr al,cl
test bp,bp ;Jump if turning off
jz fp_off
fp_on: or Buffer[bx],al ;Set the pixel
jmp fp_cont
fp_off: not al ;Clear the pixel
and Buffer[bx],al
;-------------------------------------------------
fp_cont: lea bx,[si+300] ;Get position in small char display
lea cx,[di+30]
mov ax,bp ;AX = color
call PutPixel ;Draw this pixel
mov bx,CurChar ;BX, CX = current char
mov cx,bx
and bx,1Fh ;BX = X position
imul bx,8 ;X = (ch MOD 16) * 8
shr cx,5 ;CX = Y position
imul cx,18 ;Y = (ch / 16) * 18
lea bx,[bx+si+8] ;Adjust for UL corner & pixel position
add cx,di ;now (BX, CX) is the position of the
add cx,32 ;pixel on the screen
call PutPixel ;Draw this pixel
imul si,X_SIZE ;(BX, CX)-(SI, DI) = position on screen
imul di,Y_SIZE ;of rectangle in large char display
lea bx,[si+380+1]
lea cx,[di+1]
add si,380+X_SIZE-1
add di,Y_SIZE-1
call FillRect ;Fill the rectangle
popa ;Restore registers
ret ;Return
FPutPixel EndP
;---------------------------------------------------------------------
; GetFont -- Copy BIOS 14-point font into buffer
;---------------------------------------------------------------------
; DX = offset of buffer
GetFont Proc
pusha ;Save all registers
push ds
push es
push dx ;Save DX
mov ax,1130h ;Get BIOS 14-point font
mov bh,02h
int 10h
push es ;DS = ES
pop ds
push cs ;ES = CS
pop es
mov dx,cx ;DX = extra bytes (needed if
sub dx,14 ; this isn't a real 14-point font)
mov bx,100h ;BX = char count
mov si,bp ;SI = BIOS font
pop di ;DI = buffer
gf_loop: mov cx,14 ;Copy 14 bytes
rep movsb
add si,dx ;Skip extra bytes
dec bx ;Loop back
jnz gf_loop
pop es ;Restore registers
pop ds
popa
ret ;Return
GetFont EndP
;---------------------------------------------------------------------
; GetPixel -- Read the value of a pixel
;---------------------------------------------------------------------
; BX = X, CX = Y, returns AL = color (0 or 1)
GetPixel Proc
push bx ;Save registers
push cx
push dx
push ds
push 0A000h ;DS = video memory
pop ds
mov dx,bx ;DX = X
imul bx,cx,80 ;BX = Y * 80 = row offset
mov cx,dx ;CX = X
shr dx,3 ;DX = byte offset within row
add bx,dx ;BX = offset
and cl,7 ;AL = bit mask
mov al,80h
shr al,cl
and al,[bx] ;Read the pixel
inc cx ;AL = 0 if off, 1 if on
rol al,cl
pop ds ;Restore registers
pop dx
pop cx
pop bx
ret ;Return
GetPixel EndP
;---------------------------------------------------------------------
; Initialize -- Initialize the display and variables
;---------------------------------------------------------------------
Initialize Proc
pusha ;Save all registers
mov ax,10h ;Switch to 640x350x16 EGA mode
int 10h
xor bx,bx ;Display the title
xor cx,cx
mov dx,O(Title$)
mov ah,0FFh
call PutStr
mov cx,250 ;Instructions box is at (0, 240)
mov si,6 ;6 instruction lines
mov dx,O(Instruc1$) ;DX = offset of first string
in_loop1: call PutStr ;Display the instructions
add dx,INSTRUC_LEN
add cx,14
dec si
jnz in_loop1
;-------------------------------------------------
mov al,1 ;Setting pixels here
mov di,14 ;14 lines in grid
xor cx,cx ;Y starts at 0
in_loop2: mov bx,380 ;X starts at 380
mov si,(8*X_SIZE)/2 ;Width is 8*X_SIZE
in_iloop2: call PutPixel ;Draw this pixel
add bx,2 ;Next pixel
dec si ;Loop back
jnl in_iloop2
add cx,Y_SIZE ;Next line
dec di ;Loop back
jnl in_loop2
mov si,8 ;8 columns in grid
mov bx,380 ;X starts at 380
in_loop3: xor cx,cx ;Y starts at 0
mov di,(14*Y_SIZE)/2 ;Height is 8*X_SIZE
in_iloop3: call PutPixel ;Draw this pixel
add cx,2 ;Next pixel
dec di ;Loop back
jnl in_iloop3
add bx,X_SIZE ;Next column
dec si ;Loop back
jnl in_loop3
;-------------------------------------------------
xor ax,ax ;Current character is 00
mov CurChar,ax
mov XPos,ax
mov YPos,ax
in_loop4: call ShowChar ;Display the characters
inc al
jnz in_loop4
popa ;Restore registers
ret ;Return
Initialize EndP
;---------------------------------------------------------------------
; PutChar -- Output a character to the screen
;---------------------------------------------------------------------
; BX = X, CX = Y, AL = char, AH = XOR mask (BX should be 0 mod 8)
PutChar Proc
pusha ;Save all registers
push es
push 0A000h ;ES = video memory
pop es
shr bx,3 ;DI = offset in video memory
imul di,cx,80
add di,bx
mov bl,al ;SI = offset in font buffer
imul si,bx,14 ;BH should be zero here
add si,CurFont
mov cx,14 ;14 rows
pc_loop: lodsb ;Get font char
xor al,ah ;XOR with mask
stosb ;Write to screen
add di,79 ;Move to next row
loop pc_loop ;Loop back
pop es ;Restore registers
popa
ret ;Return
PutChar EndP
;---------------------------------------------------------------------
; PutCursor -- Draw or erase the cross cursor
;---------------------------------------------------------------------
PutCursor Proc
pusha ;Save registers
imul di,XPos,X_SIZE ;(DI, BP) = center of rectangle
imul bp,YPos,Y_SIZE ;in large char display
add di,380+(X_SIZE/2)
add bp,(Y_SIZE/2)
mov bx,di ;Flip the center pixel
mov cx,bp
call FlipPixel
mov dx,(X_SIZE/2)-2 ;DX = distance from center to edge - 2
mov si,O(CrossYList) ;SI = Y position list
mov bx,1 ;X position = 1
xor cx,cx ;Zero CX
pcr_loop: lodsb ;CX = Y position
mov cl,al
neg bx ;Flip four pixels
call pcr_draw
neg cx
call pcr_draw
neg bx
call pcr_draw
neg cx
call pcr_draw
inc bx ;Next pixel
dec dx ;Loop back
jnz pcr_loop
popa ;Restore registers
ret ;Return
pcr_draw: add bx,di ;BX = X, CX = Y
add cx,bp
call FlipPixel ;Flip this pixel
sub bx,di ;Fix BX, CX
sub cx,bp
ret ;Return
PutCursor EndP
;---------------------------------------------------------------------
; PutPixel -- Set the value of a pixel
;---------------------------------------------------------------------
; BX = X, CX = Y, AL = color (0 or 1)
PutPixel Proc
pusha ;Save all registers
push ds
push 0A000h ;DS = video memory
pop ds
mov dx,bx ;DX = X
imul bx,cx,80 ;BX = Y * 80 = row offset
mov cx,dx ;CX = X
shr dx,3 ;DX = byte offset within row
add bx,dx ;BX = offset
and cl,7 ;AH = bit mask
mov ah,80h
shr ah,cl
test al,al ;Check pixel color
jz pp_off ;Jump if turning off
pp_on: or [bx],ah ;Turn pixel on
jmp pp_done
pp_off: not ah ;Turn pixel off
and [bx],ah
pp_done: pop ds ;Restore registers
popa
ret ;Return
PutPixel EndP
;---------------------------------------------------------------------
; PutRow -- Draw a row of pixels in the same color
;---------------------------------------------------------------------
; BX = X1, CX = X2, DX = Y, AL = color (0 or 1)
PutRow Proc
pusha ;Save all registers
push es
push 0A000h ;ES = video memory
pop es
cmp bx,cx ;Put them in order
jng $+4
xchg bx,cx
cmp al,1 ;BP = color
sbb bp,bp
not bp
;-------------------------------------------------
push dx cx dx bx ;Store parameters
xchg ax,cx ;If it's all on
shr ax,3 ;the same byte,
shr bx,3 ;like 00111110,
cmp ax,bx ;then use the
je pr_thin ;other routine.
pop cx bx ;CX = x1, BX = y
call pr_offs ;Get offsets
mov al,0FFh ;Translate to the
shr al,cl ;multiple-pixel value
call pr_partial ;Write pixels
mov dx,bx ;Save offset
pop cx bx ;CX = x2, BX = y
call pr_offs ;Get offsets
mov al,080h ;Translate to the
shr al,cl ;multiple-pixel value
neg al
call pr_partial ;Write pixels
inc dx ;Start at second byte
sub bx,dx ;Byte length in BX
jz pr_ret ;Zero, nothing to do
mov di,dx ;DI = offset
mov cx,bx ;CX = count
mov ax,bp ;AX = color
shr cx,1 ;Count in words
rep stosw ;Draw solid line
adc cl,ch ;Possible odd byte
rep stosb
pr_ret: pop es ;Restore registers
popa
ret ;Return
;-------------------------------------------------
pr_thin: pop cx di ;CX = x1, BX = y
mov bx,dx
call pr_offs ;Get offsets
mov ah,0FFh ;0FFh for multiple pixels
shr ah,cl ;Get value
pop cx di ;CX = x2
and cx,7
mov al,080h ;Translate to the
shr al,cl ;multiple-pixel value
neg al
and al,ah ;Combine values
push O(pr_ret) ;Set return offset
;-------------------------------------------------
pr_partial: test bp,bp ;Jump if turning on
jnz pr_pon
pr_poff: not al ;AL = AND mask
and es:[bx],al ;Turn pixels off
ret ;Return
pr_pon: or es:[bx],al ;Turn pixels on
ret ;Return
;-------------------------------------------------
pr_offs: imul bx,80 ;Get offset in BX,
ror cx,3 ;shift in CX
add bl,cl
adc bh,0
shr cx,13
ret
PutRow EndP
;---------------------------------------------------------------------
; PutStr -- Output a string to the screen (like INT 21/09)
;---------------------------------------------------------------------
; BX = X, CX = Y, DS:DX = string (BX should be 0 mod 8)
PutStr Proc
pusha ;Save all registers
mov si,dx ;DS:SI = string
ps_loop: lodsb ;Get a character
cmp al,'$' ;Exit if '$'
je ps_done
call PutChar ;Draw the character
add bx,8 ;Move right 8 pixels
jmp ps_loop ;Loop back
ps_done: popa
ret ;Return
PutStr EndP
;---------------------------------------------------------------------
; RestoreScr -- Restore the screen
;---------------------------------------------------------------------
RestoreScr Proc
pusha ;Save all registers
push ds
push es
push cs ;DS = CS
pop ds
push 0A000h ;ES = video memory
pop es
mov si,O(ScreenBuf) ;Copy ScreenBuf to the screen
xor di,di
mov cx,28000/2
rep movsw
pop es ;Restore registers
pop ds
popa
ret ;Return
RestoreScr EndP
;---------------------------------------------------------------------
; SaveScr -- Save & clear the screen
;---------------------------------------------------------------------
SaveScr Proc
pusha ;Save all registers
push ds
push es
push 0A000h ;DS = video memory
pop ds
push cs ;ES = CS
pop es
xor si,si ;Copy the screen to ScreenBuf
mov di,O(ScreenBuf)
mov cx,28000/2
rep movsw
push ds ;ES = video memory
pop es
xor di,di ;Clear the screen
xor ax,ax
mov cx,28000/2
rep stosw
pop es ;Restore registers
pop ds
popa
ret ;Return
SaveScr EndP
;---------------------------------------------------------------------
; Shift -- Shift the current character
;---------------------------------------------------------------------
Shift Proc
pusha ;Save all registers
xor bx,bx ;Display shift prompt
mov cx,336
mov dx,O(Shift$)
mov ah,0FFh ;Black on white
call PutStr
imul si,CurChar,14 ;SI = offset of char
add si,O(Buffer)
xor ah,ah ;Get a key
int 16h
mov al,ah ;AL = key
cmp al,4Bh ;Left?
je sh_left
cmp al,4Dh ;Right?
je sh_right
cmp al,48h ;Up?
je sh_up
cmp al,50h ;Down?
je sh_down
sh_done: mov ax,CurChar ;Re-display the character
call ShowChar
popa ;Restore registers
ret ;Return
;-------------------------------------------------
sh_left: mov cx,14 ;14 bytes
sh_lloop: shl B [si],1 ;Shift left
inc si ;Next byte
loop sh_lloop ;Loop back
jmp sh_done
;-------------------------------------------------
sh_right: mov cx,14 ;14 bytes
sh_rloop: shr B [si],1 ;Shift right
inc si ;Next byte
loop sh_rloop ;Loop back
jmp sh_done
;-------------------------------------------------
sh_up: mov di,si ;Shift 13 bytes up
inc si
mov cx,13
rep movsb
mov B [di],0 ;Clear the bottom line
jmp sh_done
;-------------------------------------------------
sh_down: mov bx,13 ;13 bytes
sh_dloop: mov al,[si+bx-1] ;Shift one byte down
mov [si+bx],al
dec bx ;Next byte
jnz sh_dloop ;Loop back
mov B [si],0 ;Clear the top line
jmp sh_done
Shift EndP
;---------------------------------------------------------------------
; ShowChar -- Display a font character on the screen
;---------------------------------------------------------------------
; AL = char
ShowChar Proc
pusha ;Save all registers
xor ah,ah ;Zero AH
mov bp,ax ;BP = char
mov CurFont,O(Buffer) ;Set working font
mov bx,ax ;BX = X position
and bx,1Fh ;X = (ch MOD 16) * 8
imul bx,8
mov cx,ax ;CX = Y position
shr cx,5 ;Y = (ch / 16) * 18
imul cx,18
add bx,8 ;Adjust for UL corner
add cx,30
lea si,[bx+7] ;SI, DI = LR corner of rectangle
mov di,cx
add di,17
xor al,al ;Clear the rectangle
call FillRect
mov ax,bp ;Display the char
add cx,2
call PutChar
mov CurFont,O(BiosFont) ;Set BIOS font
cmp bp,CurChar ;If it is the current char, then:
jne sc_done
;-------------------------------------------------
mov al,1 ;Color is white
mov dx,cx ;BX = X1, CX = X2, DX = Y
mov cx,si
sub dx,2 ;Draw the top line
call PutRow
add dx,17 ;Draw the bottom line
call PutRow
xor cx,cx ;Y = 0
sc_oloop: xor bx,bx ;X = 0
sc_iloop: call FGetPixel ;Read this pixel from the font
call FPutPixel ;Display it on screen
inc bx ;Next pixel
cmp bx,8 ;Loop while < 8
jb sc_iloop
inc cx ;Next row
cmp cx,14 ;Loop while < 14
jb sc_oloop
;-------------------------------------------------
mov ax,CurChar ;AH = first digit
mov ah,al ;AL = second digit
and al,0Fh
shr ah,4
cmp al,0Ah ;Convert AL to hex
sbb al,69h
das
xchg al,ah ;Switch AL, AH
cmp al,0Ah ;Convert AL to hex
sbb al,69h
das
mov W HexData,ax ;Set hex string
xor bx,bx ;Output the status string
mov cx,336
mov dx,O(CharStr$)
xor ah,ah
call PutStr
mov bx,168 ;Display the character
mov ax,CurChar
call PutChar
sc_done: popa ;Restore registers
ret ;Return
ShowChar EndP
;---------------------------------------------------------------------
; TypeMode -- Typing mode loop
;---------------------------------------------------------------------
TypeMode Proc
pusha ;Save all registers
call SaveScr ;Save & clear the screen
t_begin: mov CurFont,O(Buffer) ;Set working font
xor ax,ax ;Start with char 0
mov cx,238 ;Y starts at 238
t_yloop: mov bx,384 ;X starts at 384
t_xloop: call PutChar ;Display one character
add bx,8 ;Move right one char
inc ax ;Next character
test al,1Fh ;Loop until done 32 characters
jnz t_xloop
add cx,14 ;Move down one line
test ah,ah ;Loop until done 8 lines
jz t_yloop
xor bx,bx ;Start at (0, 0)
xor cx,cx
;-------------------------------------------------
t_keyloop: mov CurFont,O(BiosFont) ;Set BIOS font
mov ax,'_' ;Display a cursor
call PutChar
int 16h ;Wait for a key (AH = 0)
push ax ;Save AX
mov ax,' ' ;Remove the cursor
call PutChar
pop ax ;Restore AX
cmp al,20h ;Character?
jae t_char
cmp al,1Bh ;Escape?
je t_done
cmp al,0Dh ;Enter?
je t_enter
cmp al,08h ;Backspace?
je t_bksp
jmp t_keyloop ;Invalid, loop
;-------------------------------------------------
t_char: mov CurFont,O(Buffer) ;Set working font
xor ah,ah ;Display this character
call PutChar
add bx,8 ;Move right one char
cmp bx,640 ;Loop if not off the end
jb t_keyloop ;Otherwise, fall through...
t_enter: add cx,14 ;Move down one line
xor bx,bx ;Move to the far left
cmp cx,350 ;If we went off the bottom,
jae t_begin ;then restart typing mode
jmp t_keyloop
t_bksp: test bx,bx ;If not already at the left, then
jz t_keyloop
sub bx,8 ;move left one char
jmp t_keyloop
;-------------------------------------------------
t_done: call RestoreScr ;Restore the screen
popa ;Restore registers
ret ;Return
TypeMode EndP
;---------------------------------------------------------------------
FileName db 128 dup(?) ;File name
Clipboard db 14 dup(?) ;Clipboard
Buffer db 3584 dup(?) ;Buffer for font
BiosFont db 3584 dup(?) ;EGA BIOS font
ScreenBuf db 28000 dup(?) ;Screen save buffer
End Start