I am writing an OS in fasm assembly and I faced with problem. I was trying to draw font pixel-by-pixel, but it is too hard and strange. I want to make bitmap pixel-by-pixel font and save it on hdd, and in kernel code make function, that can load it to video memory. I tried to google it, but without success. Help, please
Code of kernel:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Macroses
macro rect c, x, y, w, h {
pusha
mov bx, c
mov cx, x
mov dx, y
mov si, w
mov di, h
call __rect
popa
}
macro pixel c, x, y {rect c, x, y, 1, 1}
macro __video__init {
pusha
;mov ax, 0x4F02
;mov bx, 0x101
;int 0x10
mov ah, 0x00
mov al, 0x13
int 0x10
rect 0x00, 0, 0, 640*2, 480*2
popa
}
macro sym c, x, y, s {
pusha
xor bx, bx
mov bx, c
mov cx, x
mov dx, y
mov al, s
call __sym
popa
}
macro image x, y, w, h, addr {
pusha
mov si, x
mov di, y
mov [reg0], w
mov [reg8], h
mov bp, addr
popa
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Cosmetics
macro return value {
mov eax, value
ret
}
macro far a {
mov ax, a/16
mov ds, ax
mov es, ax
mul ax, 16
mov sp, ax
div ax, 16
jmp ax:0x0000
}
macro rint trr {
pusha
mov bp, trr
cmp bp, 0x10
popa
je __r10h
}
macro retn {ret}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Tests
macro __video__test {
sym 0x0F, 0x00, 0x00, '!'
sym 0x0F, 0x0F, 0x00, '"'
sym 0x0F, 0x20, 0x00, '#'
sym 0x0F, 0x30, 0x00, '$'
sym 0x0F, 0x40, 0x00, '%'
sym 0x0F, 0x50, 0x00, '&'
sym 0x0F, 0x60, 0x00, "'"
sym 0x0F, 0x70, 0x00, '('
sym 0x0F, 0x80, 0x00, ')'
sym 0x0F, 0x90, 0x00, '*'
sym 0x0F, 0xA0, 0x00, '+'
sym 0x0F, 0xB0, 0x00, ','
sym 0x0F, 0xC0, 0x00, '-'
sym 0x0F, 0xD0, 0x00, '.'
sym 0x0F, 0xE0, 0x00, '/'
sym 0x0F, 0xF0, 0x00, '0'
sym 0x0F, 0x100,0x00, '1'
image 0, 0, 320, 200, 0
call __frame
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Kernel
__kernel:
org 0x7E00
mov [bootdev], dl
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Grafic Core
__video__init
;rect 0x01, 0x00, 0x00, 0x280, 0x190
__video__test
jmp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Bss
buffer db 1024 dup (?)
bootdev db 0x00
reg0 db 0x0000
reg1 db 0x0000
hexstr db '0x0000', 0x00
rstr db "Talisman's R-OS 0.0.1a", 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Funcs
;;;;;;;;;;;;;;;;;;;;;; Bitmap font func
__sym:
cmp al, '!'
je .!
cmp al, '"'
je ."
cmp al, '#'
je .sharp
cmp al, '$'
je .dollar
cmp al, '%'
je .%
cmp al, '&'
je .et
cmp al, "'"
je .'
cmp al, '('
je .brt
cmp al, ')'
je .brt2
cmp al, '*'
je .star
cmp al, '+'
je .plus
cmp al, ','
je .comma
cmp al, '-'
je .menos
cmp al, '.'
je .point
cmp al, '/'
je .slash
cmp al, '0'
je .0
cmp al, '1'
je .1
retn
.!:
add cx, 3
add dx, 4
rect bx, cx, dx, 2, 5
add dx, 7
rect bx, cx, dx, 2, 2
retn
.":
add cx, 2
add dx, 3
rect bx, cx, dx, 2, 3
add cx, 3
rect bx, cx, dx, 2, 3
retn
.sharp:
add cx, 2
add dx, 4
rect bx, cx, dx, 2, 8
add cx, 3
rect bx, cx, dx, 2, 8
sub cx, 4
inc dx
rect bx, cx, dx, 7, 1
add dx, 4
rect bx, cx, dx, 7, 1
retn
.dollar:
add cx, 3
add dx, 2
rect bx, cx, dx, 2, 2
dec cx
add dx, 2
rect bx, cx, dx, 4, 1
dec cx
inc dx
rect bx, cx, dx, 2, 2
add cx, 4
rect bx, cx, dx, 2, 2
sub cx, 3
add dx, 2
rect bx, cx, dx, 2, 1
add cx, 2
add dx, 1
rect bx, cx, dx, 2, 1
inc cx
inc dx
rect bx, cx, dx, 2, 2
sub cx, 4
rect bx, cx, dx, 2, 2
inc cx
add dx, 2
rect bx, cx, dx, 4, 1
inc cx
inc dx
rect bx, cx, dx, 2, 2
retn
.%:
inc cx
inc dx
rect bx, cx, dx, 2, 1
dec cx
inc dx
rect bx, cx, dx, 1, 2
add cx, 3
rect bx, cx, dx, 1, 2
sub cx, 2
add dx, 2
rect bx, cx, dx, 2, 1
dec cx
add dx, 5
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
sub cx, 2
add dx, 7
rect bx, cx, dx, 2, 1
dec cx
inc dx
rect bx, cx, dx, 1, 2
add cx, 3
rect bx, cx, dx, 1, 2
sub cx, 2
add dx, 2
rect bx, cx, dx, 2, 1
retn
.et:
add cx, 2
add dx, 3
rect bx, cx, dx, 3, 1
dec cx
inc dx
rect bx, cx, dx, 2 ,2
add cx, 3
rect bx, cx, dx, 2, 2
sub cx, 2
add dx, 2
rect bx, cx, dx, 3, 1
dec cx
inc dx
rect bx, cx, dx, 2, 4
add cx, 3
inc dx
rect bx, cx, dx, 4, 1
inc cx
inc dx
rect bx, cx, dx, 2, 2
sub cx, 3
add dx, 2
rect bx, cx, dx, 3, 1
add cx, 4
rect bx, cx, dx, 2, 1
retn
.':
add cx, 3
add dx, 2
rect bx, cx, dx, 2, 3
retn
.brt:
add cx, 5
add dx, 2
pixel bx, cx, dx
dec cx
inc dx
rect bx, cx, dx, 2, 1
dec cx
inc dx
rect bx, cx, dx, 2, 1
inc dx
rect bx, cx, dx, 2, 1
dec cx
inc dx
rect bx, cx, dx, 2, 1
inc dx
rect bx, cx, dx, 2, 1
inc cx
inc dx
rect bx, cx, dx, 2, 1
inc dx
rect bx, cx, dx, 2, 1
inc cx
inc dx
rect bx, cx, dx, 2, 1
inc cx
inc dx
pixel bx, cx, dx
retn
.brt2:
add cx, 3
add dx, 2
rect bx, cx, dx, 1, 2
;inc cx
;inc dx
;rect bx, cx, dx, 1, 2
inc cx
inc dx
pixel bx, cx, dx
inc dx
rect bx, cx, dx, 2, 2
inc cx
add dx, 2
rect bx, cx, dx, 2, 2
dec cx
add dx, 2
rect bx, cx, dx, 2, 2
;dec cx
inc dx
;rect bx, cx, dx, 2, 1
dec cx
inc dx
rect bx, cx, dx, 2, 1
inc dx
pixel bx, cx, dx
retn
.star:
add cx, 3
add dx, 3
pixel bx, cx, dx
sub cx, 2
inc dx
rect bx, cx, dx, 5, 1
inc cx
inc dx
rect bx, cx, dx, 3, 1
inc dx
pixel bx, cx, dx
add cx, 2
pixel bx, cx, dx
retn
.plus:
add cx, 3
add dx, 5
rect bx, cx, dx, 2, 5
sub cx, 2
add dx, 2
rect bx, cx, dx, 6, 1
retn
.comma:
add cx, 3
add dx, 10
rect bx, cx, dx, 2, 2
inc cx
add dx, 2
pixel bx, cx, dx
retn
.menos:
inc cx
add dx, 7
rect bx, cx, dx, 6, 1
retn
.point:
add cx, 3
add dx, 10
rect bx, cx, dx, 2, 2
retn
.slash:
add dx, 9
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
inc cx
dec dx
rect bx, cx, dx, 1, 3
retn
.0:
inc cx
add dx, 3
rect bx, cx, dx, 2, 10
add cx, 4
rect bx, cx, dx, 2, 10
dec cx
inc dx
rect bx, cx, dx, 1, 3
dec cx
add dx, 5
rect bx, cx, dx, 1, 3
dec cx
sub dx, 7
rect bx, cx, dx, 4, 1
add dx, 11
rect bx, cx, dx, 4, 1
retn
.1:
add cx, 4
add dx, 2
rect bx, cx, dx, 2, 10
sub cx, 2
add dx, 2
rect bx, cx, dx, 3, 2
add dx, 6
rect bx, cx, dx, 6, 2
retn
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; fast putpix func
__rect:
push ds dx di
imul dx, 320
add dx, cx
mov ax, 0xA000
mov ds, ax
jmp ._o
._o:
push si
jmp ._i
._i:
dec si
mov byte [edx+esi], bl;bx
jnz ._i
pop si
add dx, 320
dec di
jnz ._o
pop di dx ds
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Image func
__image:
mov ah, 0x00
int 0x13
mov ah, 0x02
mov al, [reg8]
imul al, 320
add al, 0x8700
add al, [reg0]
idiv al, 512
mov bx, 0x8700+si+320*di
mov es, 0x00
mov ch, 0x00
mov cl, (bp+512+0x7FFF-64000)/512
mov dh, 0x00
mov dl, [bootdev]
int 0x13
ret
__frame:
mov ebx, 0x00000000
._l:
mov byte [ebx+0xA000], [ebx+0x8700]
cmp ebx, 6400
je ._r
jmp ._l
._r:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; R interrupts
__r10h:
sym bx, cx, dx, al
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Footer
__footer:
cli
hlt
jmp $-2
times 0x7FFF-64000-$+$$ db 0x00
I hope my code will be more optimized in the future.
I can't make head nor tails about your __image code! You have thrown together a bunch of instructions that FASM wouldn't even be able to assemble.
And why would you load a font, or image, or any other file from disk when you don't have a file system that you can use? For now, all you can do is embed the character set in the kernel that your 1st stage bootloader has loaded into memory.
This is wrong: In your __video__init macro, where you setup the 320x200 256-color video mode, the black filled rectangle (rect 0x00, 0, 0, 640*2, 480*2
) that you draw is much too large, and frankly you don't need it since setting the video mode will already have blackend the screen.
To start using a bitmapped font, you'll have to define a character set in your program. Below is a very incomplete example of a character set where each character is 8 pixels wide and 12 pixels height. I have included the bit patterns for the digit "0" and the capitals "A" and "B".
CharSet12:
times (48 * 12) db 0 ; 0 -> 47
db 0, 124, 198, 198, 198, 214, 214, 198, 198, 198, 124, 0 ; 48 = Char "0"
times (16 * 12) db 0 ; 49 -> 64
db 0, 16, 56, 108, 198, 198, 254, 198, 198, 198, 198, 0 ; 65 = Char "A"
db 0, 252, 102, 102, 102, 124, 102, 102, 102, 102, 252, 0 ; 66 = Char "B"
times (189 * 12) db 0 ; 67 -> 255
You can design your own fonts this way and select any width and height that you like.
In transparent text, you only plot pixels that have the foreground color. The background shines through. Next code does that:
; IN (al,bl,cx,dx) OUT () MOD (ax)
DrawTransparentCharacter:
push es cx si di
mov ah, 12 ; OffsetInCharacterSet = CharacterHeight * ASCII
mul al
mov si, ax
imul di, dx, 320 ; OffsetInVideoMemory = (Y * 320) + X
add di, cx
mov ax, 0xA000
mov es, ax
mov ch, 12 ; CharacterHeight
.OuterLoop:
mov cl, 8 ; CharacterWidth
mov al, [CharSet12 + si]
.InnerLoop:
shl al, 1
jnc .Skip
mov [es:di], bl ; Plot pixel
.Skip:
inc di
dec cl
jnz .InnerLoop
inc si ; To next font byte
add di, 320 - 8 ; To next scanline
dec ch
jnz .OuterLoop
pop di si cx es
ret
Now you can output a character anywhere on the screen based on the pixel position of its upperleft corner.
; This draws a light green "A" in the middle of the screen
mov dx, 94 ; Y
mov cx, 156 ; X
mov bl, 10 ; Color LightGreen
mov al, 65 ; "A"
call DrawTransparentCharacter
In opaque text, you not only plot pixels that have the foreground color, but also those that make up the background rectangle. Next code does that:
; IN (al,bx,cx,dx) OUT () MOD (ax)
DrawOpaqueCharacter:
push es cx dx si di
mov ah, 12 ; OffsetInCharacterSet = CharacterHeight * ASCII
mul al
mov si, ax
imul di, dx, 320 ; OffsetInVideoMemory = (Y * 320) + X
add di, cx
mov ax, 0xA000
mov es, ax
mov ch, 12 ; CharacterHeight
.OuterLoop:
mov cl, 8 ; CharacterWidth
mov al, [CharSet12 + si]
.InnerLoop:
mov dl, bl ; Foreground color
shl al, 1
jc .Plot
mov dl, bh ; Background color
.Plot:
mov [es:di], dl ; Plot pixel
inc di
dec cl
jnz .InnerLoop
inc si ; To next font byte
add di, 320 - 8 ; To next scanline
dec ch
jnz .OuterLoop
pop di si dx cx es
ret
Now you can output a character anywhere on the screen based on the pixel position of its upperleft corner.
; This draws a green on bright white "B" in the bottom right corner of the screen
mov dx, 188 ; Y
mov cx, 312 ; X
mov bx, 0x0F02 ; Colors GreenOnBrightWhite
mov al, 66 ; "B"
call DrawOpaqueCharacter