Moved stuff around and added a makefile also got a custom bootloader

based on the JazzOS bootloader (modified a bit)
This commit is contained in:
2025-10-20 10:52:03 +01:00
parent 07932e2ce0
commit d38a233b62
33 changed files with 1248 additions and 890 deletions

View File

90
source/kernel/features/cli.asm Executable file
View File

@@ -0,0 +1,90 @@
os_start_cli:
pusha
call os_print_newline
mov si, prompt
call os_print_string
mov ax, 20
mov di, user_input
call os_display_input
; ------------------------------------------------
os_read_cli:
pusha
.output_the_user_input:
call os_print_newline
.check_matches: ; Check if the user input matches any internal commands
mov si, user_input
mov di, help_string
call os_compare_strings
cmp cl, 1
je help
mov si, user_input
mov di, clear_string
call os_compare_strings
cmp cl, 1
je clear
mov si, user_input
mov di, pong_string
call os_compare_strings
cmp cl, 1
je pong
mov si, user_input
mov di, snake_string
call os_compare_strings
cmp cl, 1
je snake
jmp .unkown
.unkown:
mov si, unknown_command
call os_print_string
mov si, user_input
call os_print_string_nl
jmp .finish
.finish:
popa
call os_start_cli
clear:
call os_set_text_mode
call os_read_cli.finish
help:
mov si, help_text
call os_print_string_nl
call os_read_cli.finish
pong:
call game_pong
call os_read_cli.finish
snake:
call game_snake
call os_read_cli.finish
section .data
welcome_text db 'Welcome to CrawOS, the Cool, Real and AWsome Operating System', 0
user_input times 20 db 0
prompt_length db 20
prompt db 'CrawOS sh> ', 0
help_string db 'HELP', 0
clear_string db 'CLEAR', 0
pong_string db 'PONG', 0
snake_string db 'SNAKE', 0
help_text db 'This is for Cowards: "HELP" for this help text, "CLEAR" to clear the screen, esc to reboot', 0
command_result_text db 'You typed: ', 0
unknown_command db 'Error: Unkown Command.. ', 0

View File

View File

@@ -0,0 +1,53 @@
os_set_graphics_mode:
pusha
mov ah, 00h
mov al, 13h
int 10h
popa
ret
; --------------------------------------
; x_end
; y_end
; x_start
; y_start
; colour
os_draw_graphical_rectangle:
; Tell BIOS we're changing 'da pixels!
mov ah, 0Ch
mov al, 1100b
mov cx, [x_start]
mov dx, [y_start]
jmp .x_loop
.x_loop:
int 10h
cmp cx, [x_end]
je .next_row
inc cx
call .x_loop
.next_row:
mov cx, [x_start]
cmp dx, [y_end]
je .finish
inc dx ; Increase Row
call .x_loop
.finish:
ret
section .data
x_start dw 0
y_start dw 0
x_end dw 0
y_end dw 0
colour db 1111b

View File

@@ -0,0 +1,77 @@
; AX = key pressed
os_read_input:
mov ah, 11h ; BIOS call to check for key
int 16h ; Interrupt
jnz .key_pressed ; Jump if input isn't 0
hlt
jmp os_read_input
.key_pressed:
mov ah, 10h
int 16h
ret
; -------------------------------------------
os_display_input:
pusha
mov cx, [prompt_length]
.loop:
call .check_key_pressed
jmp .loop
.check_key_pressed:
call os_read_input
cmp al, 08h
je .backspace
cmp al, 0Dh
je .enter_key
cmp al, 1Bh
je .esc_key
cmp cx, 0
jb .check_key_pressed
call .print_current_input
dec cx
jmp .check_key_pressed
.esc_key:
call os_reboot
.enter_key:
mov al, 0
stosb
popa
call os_read_cli
.backspace:
call .move_cursor_back ; then .move_cursor_back
call .loop ; Else .loop
.move_cursor_back:
mov ah, 0Eh
mov al, 08h
int 10h
mov al, 20h
int 10h
mov al, 08h
int 10h
dec di
jmp os_display_input
.print_current_input:
stosb
mov ah, 0Eh
int 10h
ret

View File

View File

@@ -0,0 +1,6 @@
os_reboot:
mov ax, 0x5307
mov bx, 0x0001
mov cx, 0x0003
int 0x19

View File

View File

@@ -0,0 +1,26 @@
; How string comparison works
; DI => scasb compares value stored in DI which is 's' with 's' stored in AX register
; and then increments DI if DF is 0
; v
; memory address 1: |s|n|a|t|0|
; memory address 2: |s|n|a|k|e|0|
; ^
; SI => lodsb loads value stored at SI to AX and then increments SI if DF is 0
os_compare_strings:
cld
.compare:
lodsb
scasb ; Compare di to si
jne .unequal ; If they are no equal, jump to .unequal
cmp al, 0 ; Check if string is finished
je .equal ; If it has, return true
jmp .compare ; Finally, repeat
.unequal:
mov cl, 0 ; Change to 0 if unquality is proven
ret
.equal:
mov cl, 1
ret

70
source/kernel/features/text.asm Executable file
View File

@@ -0,0 +1,70 @@
; SI = pointer to start of string to be printed
os_print_string:
pusha
mov ah, 0Eh ; int 10h teletype function, we're telling the BIOS we will print something
.repeat:
lodsb ; Get char from si into al
cmp al, 0 ; Compare al to 0
je .done ; If char is zero, end of string
int 10h ; Otherwise, print it
jmp .repeat ; And move on to next char
.done:
popa
ret
; Exact same as the above procedure, but this adds a newline
; after priting, similar to the difference between Rust's print! and println!
os_print_string_nl:
pusha
mov ah, 0Eh ; int 10h teletype function, we're telling the BIOS we will print something
.repeat:
lodsb ; Get char from si into al
cmp al, 0 ; Compare al to 0
je .done ; If char is zero, end of string
int 10h ; Otherwise, print it
jmp .repeat ; And move on to next char
.done:
call os_print_newline
popa
ret
; --------------------------------------------
os_print_newline:
pusha
mov ah, 0Eh
mov al, 13
int 10h
mov al, 10
int 10h
popa
ret
; -------------------------------------------
os_set_text_mode:
pusha
; Set mode = 80x25 (text mode)
mov ah, 00h
mov al, 03h
int 10h
; Move cursor to the top left
mov ah, 02h
mov dh, 0
mov dl, 0
int 10h
popa
ret

View File

@@ -0,0 +1,134 @@
game_pong:
call .draw_screen
call .detect_input
; Clears screen and draws both players and ball
.draw_screen:
call os_set_graphics_mode ; Clear screen
.draw_p1:
; Player 1
mov ax, [p1_x]
mov [x_start], ax
mov [x_end], ax
mov bx, [p1_y]
mov [y_start], bx
add bx, [bat_height]
mov [y_end], bx
call os_draw_graphical_rectangle ; Draw player 1
.draw_p2:
; Player 2
mov ax, [p2_x]
mov [x_start], ax
mov [x_end], ax
mov bx, [p2_y]
mov [y_start], bx
add bx, [bat_height]
mov [y_end], bx
call os_draw_graphical_rectangle ; Draw player 1
.draw_ball:
; The ball
mov ax, [ball_x]
mov [x_start], ax
mov [x_end], ax
mov bx, [ball_y]
mov [y_start], bx
mov [y_end], bx
call os_draw_graphical_rectangle ; Draw the ball
ret
; Player 1 movements
.p1_up:
mov dx, [p1_y]
sub dx, 5
mov [p1_y], dx
jmp .detect_input
.p1_down:
mov dx, [p1_y]
add dx, 5
mov [p1_y], dx
jmp .detect_input
; Player 2 movements
.p2_up:
mov dx, [p2_y]
sub dx, 5
mov [p2_y], dx
jmp .detect_input
.p2_down:
mov dx, [p2_y]
add dx, 5
mov [p2_y], dx
jmp .detect_input
; Ball bouncing
; This should move the ball along one frame
; The ball moves 1 pixel per frame, however this is usually
; at an angle, so we need sin and cos
.bounce_ball:
; Change the x coords
fld dword [ball_angle]
fcos
fld dword [precise_ball_x]
faddp
frndint
fstp dword [ball_x]
; Change the y coords
fld dword [ball_angle]
fsin
fld dword [precise_ball_y]
faddp
frndint
fstp dword [ball_y]
ret
.detect_input:
call os_read_input
cmp al, 08h
je .finish
; Player 1
cmp al, 77h ; Pressed 'w' (player 1 up)
je .p1_up
cmp al, 73h ; Pressed 's' (player 1 down)
je .p1_down
; Player 2
cmp al, 5bh ; Pressed '[' (player 2 up)
je .p2_up
cmp al, 27h ; Pressed ''' (player 2 down)
je .p2_down
call .bounce_ball
call .draw_screen
jmp .detect_input
.finish:
call os_set_text_mode
call os_start_cli
section .data
ball_x dw 100
ball_y dw 100
precise_ball_x dw 100
precise_ball_y dw 100
ball_angle dw 1 ; In radians
cos_ball_angle dw 0
sin_ball_angle dw 0
p1_x dw 5
p1_y dw 5
p2_x dw 315
p2_y dw 5
bat_height dw 20

View File

@@ -0,0 +1,94 @@
game_snake:
call .draw_screen
call .detect_input
.draw_screen:
call os_set_graphics_mode ; Clear screen
.draw_snake_loop:
mov ax, [snake_x]
mov [x_start], ax
mov [x_end], ax
mov bx, [snake_y]
mov [y_start], bx
mov [y_end], bx
call os_draw_graphical_rectangle
ret
; Player 1 movements
.up:
mov dword [snake_direction], 0
jmp .end_detect_input
.down:
mov dword [snake_direction], 2
jmp .end_detect_input
.left:
mov dword [snake_direction], 3
jmp .end_detect_input
.right:
mov dword [snake_direction], 1
jmp .end_detect_input
.move_up:
mov dx, [snake_y]
sub dx, 1
mov [snake_y], dx
ret
.move_down:
mov dx, [snake_y]
add dx, 1
mov [snake_y], dx
ret
.move_left:
mov dx, [snake_x]
sub dx, 1
mov [snake_x], dx
ret
.move_right:
mov dx, [snake_x]
add dx, 1
mov [snake_x], dx
ret
.move_snake:
cmp dword [snake_direction], 0
je .move_up
cmp dword [snake_direction], 1
je .move_right
cmp dword [snake_direction], 2
je .move_down
; Else it must be left
jmp .move_left
.detect_input:
call os_read_input
cmp al, 08h
je .finish
; Player 1
cmp al, 77h ; Pressed 'w' up
je .up
cmp al, 61h ; Pressed 'a' left
je .left
cmp al, 73h ; Pressed 's' down
je .down
cmp al, 64h ; Pressed 'd' right
je .right
.end_detect_input:
call .move_snake
call .draw_screen
jmp .detect_input
.finish:
call os_set_text_mode
call os_start_cli
section .data:
snake_x: dw 5
snake_y: dw 5
snake_direction: dw 1 ; 0=up, 1=right, 2=down, 3=left
snake_length: dw 1

32
source/kernel/kernel.asm Normal file
View File

@@ -0,0 +1,32 @@
ORG 0h
BITS 16
start:
mov si, boot_message
call os_print_string_nl
mov si, help_text
call os_print_string_nl
call os_start_cli
hlt
halt:
jmp halt
boot_message: db 0Dh, 'Welcome to CrawOS!', 0Dh, 0
; ------------------------------------------------------------------
; FEATURES -- Code to pull into the kernel
%INCLUDE "source/kernel/features/text.asm"
%INCLUDE "source/kernel/features/keyboard.asm"
%INCLUDE "source/kernel/features/cli.asm"
%INCLUDE "source/kernel/features/power.asm"
%INCLUDE "source/kernel/features/strings.asm"
%INCLUDE "source/kernel/features/graphics.asm"
%INCLUDE "source/kernel/features/sound.asm"
%INCLUDE "source/kernel/features/basic.asm"
%INCLUDE "source/kernel/features/math.asm"
; GAMES -- Games that I wrote for it
%INCLUDE "source/kernel/games/pong.asm"
%INCLUDE "source/kernel/games/snake.asm"