i am writing an os in fasm assembly and faced with problem - bios videoservices works too slow. i already published similar question, but it is more that questin type as "how to write pixel to videomemory", now i have to draw some geometrical primitives. and i dunt have any ideas about how i can realise it. help, plz
code
boot.asm:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TEXT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x7C00
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00
cld
mov ax, 0x03
int 0x10
mov si, boot_msg
call printf
mov al, 8704/512 ; sector to read
mov bx, 0x7E00 ; destination
mov cx, 0x0002 ; cylinder:sector
mov dh, 0x00 ; head
call disk_read
mov ax, 0x7E0
mov ds, ax
mov es, ax
mov sp, 0x7E00
jmp 0x7E0:0x0000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include 'disk.asm'
include 'printh.asm'
boot_msg db 'R-OS bootloader ',\
'R-OS kernel CHS: 0x00/0x00/0x02 ',\
"Testing first MB of ROM... Fine, All that need free. kernel loading to 0x7E00 ", 0x00
disk_err db 'Disk error, errcode ', 0x00
times 510-$+$$ db 0x00
dw 0xAA55
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TEXT 0x200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include 'kernel.asm'
include 'fs.asm'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 65024-$+$$ db 0x00
kernel.asm:
org 0x7E00
mov [bootdev], dl
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Macroses
macro pixel c, x, y {
pusha
mov al, c
mov cx, x
mov dx, y
call __pixel
popa
}
macro pix c, x, y {
pusha
mov dl, c
mov ax, x
mov bx, y
call __putpix
popa
}
macro zone c, x, y, w, h {
pusha
mov al, c
mov cx, x
mov dx, y
mov si, w
mov di, h
call __zone2
popa
}
macro rect c, x, y, w, h {
mov cl, c
mov ax, x
mov bx, y
mov si, w+x
mov di, h+y
call __rect
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Kernel
mov ah, 0x00
mov al, 0x13
int 0x10
zone 0x09, 0, 0, 32, 20
int 0x10
pix 0x01, 33, 21
rect 0x0C, 10, 10, 10, 10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Text core
jmp __footer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Bss
buffer db 1024 dup (?)
bootdev db 0x00
reg0 dw 0x0000
reg8 dw 0x0000
hexstr db '0x0000', 0x00
rstr db 'R-OS Kernel', 0x00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Funcs
__pixel:
mov ah, 0x0C
int 0x10
ret
__fill:
mov ah, 0x0C
mov cx, 0x00
mov dx, 0x00
.__:
inc dx
cmp dx, 200-1
int 0x10
call ._
jmp .__
._:
inc cx
cmp cx, 320-1
int 0x10
cmp di, 0
je ._g
cmp di, 0
jne ._l
je ._onemore
jmp ._
._onemore:
cmp dx, 200-1
je ._end
jmp .__
._end:
ret
._g:
inc al
cmp al, 0x0F
jge ._21
ret
._l:
dec al
cmp al, 0x00
jle ._20
ret
._21:
mov di, 0x01
ret
._20:
mov di, 0x00
ret
;;;;;;;;;;;;;;;;;;;;;; Bitmap font func
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Fill func
__zone2:
mov ah, 0x0C
int 0x10
mov bx, cx
mov bp, dx
jmp ._x
._x:
mov dx, bp
cmp cx, si
je ._e
inc cx
cmp cx, [si+1]
jne ._y
._y:
cmp dx, di
je ._x
inc dx
pusha
dec cx
dec dx
;int 0x10
pix al, cx, dx
popa
jmp ._y
._e:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; putpix func
__putpix:
push ds bx
imul bx, 320
add bx, ax
mov ax, 0xA000
mov ds, ax
mov byte [bx], cl
pop bx ds
ret
__rect:
push ds bx di
imul bx, 320
add bx, ax
mov ax, 0xA000
mov ds, ax
.__:
push si
jmp ._
._:
dec si
mov [bx+si], cl
jnz ._
pop si
add bx, 320
dec di
jnz .__
pop di bx ds
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Footer
__footer:
cli
hlt
jmp $-2
times 8704-$+$$ db 0x00
In the PaintRectangle code that I gave to you in a previous answer, the SI
register is the width and the DI
register is the height. My code works correct, but in todays question you are loading these registers with another (X,Y) for the point just outside of the LowerRight corner!
macro rect c, x, y, w, h { mov cl, c mov ax, x mov bx, y mov si, w+x <<<<< WRONG, don't add +x mov di, h+y <<<<< WRONG, don't add +y call __rect }
And the pix macro loads the color into the wrong register! You must use CL
.
macro pix c, x, y { pusha mov dl, c <<<<< WRONG, use `CL` mov ax, x mov bx, y call __putpix popa }
The PaintRectangle code can draw an horizontal line. Just specify a height of 1 in DI
.
The PaintRectangle code can draw a vertical line. Just specify a width of 1 in SI
.
From a recent codereview post of mine 81-variations-of-the-rounded-rectangle you can learn how to draw any rectangle you like. You can even make that code draw a circle! After all, a full circle is nothing more than all 4 convex corners coming together. (Tip: use a rectangle that is a square)
Stop using macros. You're complicating matters and you're not yet up to the task. Currently you're making too many call
s and you're too liberal with pusha
and popa
instructions.
Much of the rest of this code is using BIOS - that you didn't want to use in the first place! Stick with the 2 codes PutPixel and PaintRectangle, study carefully how they work, and then derive your own code from them.