Compare commits

...

10 commits

10 changed files with 321 additions and 29 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.bin
gfx/venv
gfx/*.asm

View file

@ -7,7 +7,7 @@ OS_SEGMENT equ 0x100
boot:
; Load from disk
mov ah, 0x02 ; read
mov al, 0x01 ; No of sectors (1)
mov al, 0x02 ; No of sectors (2)
mov cl, 0x02 ; Sector start (1 = boot sector, 2 = OS)
mov ch, 0x00 ; Cylinder 0
mov dh, 0x00 ; Head 0
@ -18,7 +18,7 @@ boot:
int 0x13 ; Send read interrupt
jc disk_error
; Now that the OS is loaded in 0x1000, let's call main!
jmp 0x100:0x0

BIN
gfx/cursor.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

18
gfx/cvbmp.py Normal file
View file

@ -0,0 +1,18 @@
from PIL import Image
im = Image.open('cursor.bmp')
pixels = list(im.getdata())
w, h = im.size
with open('gfxd_cursor.asm', 'w') as f:
f.write(f'gfxd_cursor_dim: db {w}, {h}\n')
f.write('gfxd_cursor: db ')
for px in pixels:
if px == (255, 255, 255, 255):
c = '0x0F'
elif px == (0, 0, 0, 255):
c = '0x00'
else:
c = '0xFF'
f.write(f'{c}, ')

View file

@ -0,0 +1,124 @@
; Constants
VMEM equ 0xA000
; Initializes 320x200 8-bit/256-color (13h) video graphics mode
gfx_init_vga13:
push ax
mov ax, 0x0013
int 0x10
pop ax
ret
; di = y*32+x
; ax = width
; bl = height
; bh = color
; ax/bl = 0 is undefined behavior. Don't do it.
; (To be clear, in the current implementation it just halts)
_gfx_rect0:
pusha
push VMEM
pop es
mov dl, 0 ; row counter
.row:
add dl, 1
mov cx, 0 ; col counter
.col:
add cx, 1
mov [es:di], bh
add di, 1
cmp cx, ax
jnz .col
sub di, ax ; di - width + 320. == x=x1; y++
add di, 320
cmp dl, bl
jnz .row
popa
ret
; cx = x
; al = y
; dx = width
; bl = height
; bh = color
gfx_rect:
pusha
; Set di to y*320+x
push bx
push dx ; Don't forget, mul clobbers dx!
mov ah, 0
mov bx, 320
mul bx
add ax, cx
mov di, ax
pop dx
pop bx
; AX CLOBBERED
mov ax, dx
call _gfx_rect0
popa
ret
; di = y*320+x
; si = source color data
; ax = width
; bl = height
; ax/bl = 0 is undefined behavior. Don't do it.
; (To be clear, in the current implementation it just halts)
_gfx_blit0:
pusha
push VMEM
pop es
mov dl, 0 ; row counter
.row:
add dl, 1
mov cx, 0 ; col counter
.col:
add cx, 1
mov dh, [si]
cmp dh, 0xFF
jz .ncp
mov [es:di], dh
.ncp:
add di, 1
add si, 1
cmp cx, ax
jnz .col
sub di, ax ; di - width + 320. == x=x1; y++
add di, 320
cmp dl, bl
jnz .row
popa
ret

117
main.asm
View file

@ -4,38 +4,111 @@
section KERNEL follows=BOOTSECTOR vstart=1000h
%macro mod 2
push ax
push cx
mov cx, %2
xor dx, dx
mov ax, %1
div cx
pop cx
pop ax
%endmacro
main:
mov ax, 0x0013
int 0x10
call gfx_init_vga13
; Important for mouse stuff definitely
jmp 0x000:.setcs
.setcs:
push es
push 0xa000
pop es
call mouse_initialize
call mouse_enable
mov di, 0
lp:
mov bx, 0
.c:
add bl, 1
.f:
mov byte [es:di], bl
add di, 1
cmp di, 0xFFFF
jnz .f
push bx
mov bx, 100
call sleep
pop bx
jmp .c
call update_mouse
pop es
jmp lp
jmp $ ; Halt
update_mouse:
cli
mov bx, [mouseX]
mov ax, [mouseY]
sti
mov cx, [lastMouseX]
mov dx, [lastMouseY]
push bx
push ax
xor bx, cx
jnz .update
xor ax, dx
jnz .update
pop ax
pop bx
ret
.update:
pop ax
pop bx
call clear_last_mouse
call render_mouse
mov [lastMouseX], bx
mov [lastMouseY], ax
ret
; cx = lastMouseX
; dx = lastMouseY
clear_last_mouse:
pusha
mov al, dl
mov dx, 11
mov bl, 18
mov bh, 0
call gfx_rect
popa
ret
; bx = mouseX
; ax = mouseY
render_mouse:
pusha
mov dx, 0
mov cx, 320
mul cx
add ax, bx
mov di, ax
mov si, gfxd_cursor
mov ax, 11
mov bl, 18
call _gfx_blit0
popa
ret
; Libs
%include "print_util.asm"
%include "time_util.asm"
%include "mouse_util.asm"
;%include "time_util.asm"
%include "gfx_util.asm"
; Data
HELLO_WORLD:
db 'Hello, world! :D', 0
db 'Hello, world! :D', 0
No:
db 'No.', 0
lastMouseX: dw 0
lastMouseY: dw 0
%include "gfx/gfxd_cursor.asm"

BIN
main.bin

Binary file not shown.

View file

@ -98,6 +98,42 @@ mouse_disable:
pop es
ret
clamp_mouse_bounds:
pusha
cli
mov ax, [mouseX]
mov bx, [mouseY]
sti
test ax, 0x8000
jnz .x0
mov ax, 0
.x0:
test bx, 0x8000
jnz .y0
mov bx, 0
.y0:
cmp bx, 320
jle .x1
mov bx, 320
.x1:
cmp ax, 200
jle .y1
mov ax, 200
.y1:
cli
mov [mouseX], ax
mov [mouseY], bx
sti
popa
ret
; Function: mouse_callback (FAR)
; called by the interrupt handler to process a mouse data packet
; All registers that are modified must be saved and restored
@ -143,6 +179,28 @@ mouse_callback:
mov cx, [mouseX]
add ax, cx ; AX = new mouse X_coord
; clamp values
test ax, 0x8000
jz .x0
mov ax, 0
.x0:
test dx, 0x8000
jz .y0
mov dx, 0
.y0:
cmp ax, 320
jle .x1
mov ax, 320
.x1:
cmp dx, 200
jle .y1
mov dx, 200
.y1:
; Status
mov [curStatus], bl ; Update the current status with the new bits
mov [mouseX], ax ; Update current virtual mouseX coord

View file

@ -1,8 +1,13 @@
%macro print_ch 1
push ax
push bx
mov bx, 0x000F
mov al, %1
mov ah, 0x0e
int 0x10
pop bx
pop ax
%endmacro
@ -14,14 +19,15 @@
int 0x10 ; Graphics services
%endmacro
; bx = string to print
print:
pusha
.loop:
mov al, [bx]
cmp al, 0
je .end ; go to end if char == 0
mov ah, 0x0e
int 0x10
@ -74,8 +80,11 @@ print_hex_digit:
.skip_alpha:
add al, 0x30 ; Add ASCII '0'
push bx
mov bx, 0x000F
mov ah, 0x0e
int 0x10
pop bx
popa
ret
@ -135,7 +144,8 @@ print_bin:
popa
ret
; bx = number to print
print_uint:
pusha
@ -160,8 +170,11 @@ print_uint:
pop ax ; 16-bit value
mov ah, 0x0e
;add al, 0x30
push bx
mov bx, 0x000F
int 0x10
pop bx
cmp bx, 0
jnz .print_loop

5
run.sh
View file

@ -1,2 +1,5 @@
nasm -f bin main.asm -o main.bin
qemu-system-x86_64 main.bin
qemu-system-x86_64 main.bin
dfkjjgodifjgodifj