在 fasm 汇编中编写视频系统
write videosystem in fasm assembly
我正在用 fasm 汇编编写 os 并遇到问题 - bios videos 服务工作速度太慢。我已经发布了类似的问题,但更多的问题类型是“如何将像素写入视频内存”,现在我必须绘制一些几何图元。我对如何实现它没有任何想法。求助,请
代码
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
通常gpus有一个共享内存。直接写入而不是 bioses 调用。几年前,视频内存是 0A000h。你也有
__putpix。它应该比 bios 调用快得多
在PaintRectangle代码中,我在中给你的代码中,SI
寄存器是width 并且 DI
寄存器是 高度 。我的代码工作正常,但在今天的问题中,您正在为这些寄存器加载右下角外的点的另一个 (X,Y)!
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
}
并且 pix 宏将颜色加载到错误的寄存器中!您必须使用 CL
.
macro pix c, x, y {
pusha
mov dl, c <<<<< WRONG, use `CL`
mov ax, x
mov bx, y
call __putpix
popa
}
想要更多几何基元吗?
PaintRectangle代码可以绘制水平线。只需在 DI
.
中指定高度 1
PaintRectangle 代码可以绘制垂直线。只需在 SI
.
中指定宽度为 1
从我的 81-variations-of-the-rounded-rectangle 最近的代码审查 post 中,您可以学习如何绘制任何您喜欢的矩形。您甚至可以让该代码画一个圆圈!毕竟,一个完整的圆圈只不过是将所有 4 个凸角聚在一起。 (提示:使用矩形即正方形)
结论
停止使用宏。你使事情复杂化,你还没有完成任务。目前你制作了太多 call
并且你对 pusha
和 popa
指令过于自由。
这段代码的其余大部分都在使用 BIOS——您一开始就不想使用它!坚持使用 PutPixel 和 PaintRectangle 这两个代码,仔细研究 how 它们的工作原理,然后推导出你自己的代码他们的代码。
我正在用 fasm 汇编编写 os 并遇到问题 - bios videos 服务工作速度太慢。我已经发布了类似的问题,但更多的问题类型是“如何将像素写入视频内存”,现在我必须绘制一些几何图元。我对如何实现它没有任何想法。求助,请
代码
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
通常gpus有一个共享内存。直接写入而不是 bioses 调用。几年前,视频内存是 0A000h。你也有 __putpix。它应该比 bios 调用快得多
在PaintRectangle代码中,我在SI
寄存器是width 并且 DI
寄存器是 高度 。我的代码工作正常,但在今天的问题中,您正在为这些寄存器加载右下角外的点的另一个 (X,Y)!
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 }
并且 pix 宏将颜色加载到错误的寄存器中!您必须使用 CL
.
macro pix c, x, y { pusha mov dl, c <<<<< WRONG, use `CL` mov ax, x mov bx, y call __putpix popa }
想要更多几何基元吗?
PaintRectangle代码可以绘制水平线。只需在 DI
.
中指定高度 1
PaintRectangle 代码可以绘制垂直线。只需在 SI
.
中指定宽度为 1
从我的 81-variations-of-the-rounded-rectangle 最近的代码审查 post 中,您可以学习如何绘制任何您喜欢的矩形。您甚至可以让该代码画一个圆圈!毕竟,一个完整的圆圈只不过是将所有 4 个凸角聚在一起。 (提示:使用矩形即正方形)
结论
停止使用宏。你使事情复杂化,你还没有完成任务。目前你制作了太多 call
并且你对 pusha
和 popa
指令过于自由。
这段代码的其余大部分都在使用 BIOS——您一开始就不想使用它!坚持使用 PutPixel 和 PaintRectangle 这两个代码,仔细研究 how 它们的工作原理,然后推导出你自己的代码他们的代码。