diff --git a/config.s b/config.s index 511d33f..051360c 100644 --- a/config.s +++ b/config.s @@ -1,5 +1,5 @@ -NUMSEG equ 1 ; TODO build system should calculate this value +NUMSEG equ 4; TODO build system should calculate this value ; might be good to move one of these into the high memory area -K_ADDR equ 0x500 ; kernel load address -STACK_SEG equ 0x1050 +KERNEL_SEG equ 0x50 +STACK_SEG equ 0x1050 diff --git a/src/boot.s b/src/boot.s index 974e70e..ace3604 100644 --- a/src/boot.s +++ b/src/boot.s @@ -5,7 +5,7 @@ [org 0x7C00] [bits 16] -mov ax, K_ADDR >> 4 +mov ax, KERNEL_SEG push ax ; setup for ds mov es, ax mov gs, ax @@ -13,7 +13,7 @@ mov fs, ax xor cx, cx mov ds, cx -mov word [0x21*4], 2 ; see kernel_entry +mov word [0x21*4], 2 ; see kjmp in kernel.s mov word [0x21*4+2], ax mov ax, 0x200 | NUMSEG @@ -34,7 +34,7 @@ push ds push ax retf -; TODO we have lots of space for init code here +; TODO filesystem and reserve space for mbr partition table times 510 - ($-$$) db 0 dw 0xAA55 diff --git a/src/int21.s b/src/int21.s index 4538e74..c26d717 100644 --- a/src/int21.s +++ b/src/int21.s @@ -45,7 +45,13 @@ tmp: dw 0 retcode: dw 0 verify: db 0 -rdin_echo:; ah=01h +; AH = 01h +; read a character from stdin and print it to stdout +; inputs: +; none +; outputs: +; AL: character read from stdin +rdin_echo: push ax mov ah, 8 int 0x21 @@ -55,10 +61,10 @@ rdin_echo:; ah=01h ; AH = 4dh ; get return code ; inputs: -; none +; none ; outputs: -; AH: termination type (0 = normal, 1 = control-C abort, 2 = critical error abort, 3 = terminate and stay resident) -; AL: return code +; AH: termination type (0 = normal, 1 = control-C abort, 2 = critical error abort, 3 = terminate and stay resident) +; AL: return code getret: xor ax, ax xchg [retcode], ax @@ -67,10 +73,10 @@ getret: ; AH = 30h ; get the DOS version number ; inputs: -; none +; none ; outputs: -; AL: major version -; AH: minor version +; AL: major version +; AH: minor version getver: mov ax, 8 ; if it is not zero indexed this indicates windows ME xor bx, bx ; update: what does that comment mean @@ -81,9 +87,9 @@ getver: ; AH = 54h ; get disk verify flag ; inputs: -; none +; none ; outputs: -; AL: 0 if off, 1 if on +; AL: 0 if off, 1 if on getverify: mov al, [verify] ret @@ -91,9 +97,9 @@ getverify: ; AH = 2eh ; set disk verify flag ; inputs: -; AL: 0 if off, 1 if on +; AL: 0 if off, 1 if on ; outputs: -; none +; none setverify: mov [verify], al ret @@ -101,9 +107,9 @@ setverify: ; AH = 35h ; get interrupt vector ; inputs: -; AL: interrupt number +; AL: interrupt number ; outputs: -; ES:BX: current interrupt handler +; ES:BX: current interrupt handler getint: push ds push di @@ -123,29 +129,29 @@ getint: ; AH = 25h ; set interrupt vector ; inputs: -; AL: interrupt number -; DS:DX: new interrupt handler +; AL: interrupt number +; DS:DX: new interrupt handler ; outputs: -; none +; none setint: pusha xor ah, ah shl ax, 2 mov di, ax xor ax, ax - push ds - mov ds, ax - mov word [di], dx - mov word [di+2], ds - pop ds + push es + mov es, ax + mov word es:[di], dx + mov word es:[di+2], ds + pop es popa ret ; read from CMOS register ; inputs: -; AL: register +; AL: register ; outputs: -; AL: value +; AL: value ; TODO: handle bcd here to abstract it from the kernel rdcmos: cli @@ -165,10 +171,10 @@ rdcmos: ; write to CMOS register ; inputs: -; BL: value -; BH: register +; BL: value +; BH: register ; outputs: -; none +; none wrcmos: cli push ax @@ -184,11 +190,11 @@ wrcmos: ; AH = 2ch ; read system time from the CMOS ; inputs: -; none +; none ; outputs: -; CH: hours -; CL: minutes -; DH: seconds +; CH: hours +; CL: minutes +; DH: seconds gettime: push ax xor dl, dl @@ -215,11 +221,11 @@ gettime: ; AH = 2dh ; set system time in the CMOS ; inputs: -; CH: hours -; CL: minutes -; DH: seconds +; CH: hours +; CL: minutes +; DH: seconds ; outputs: -; none +; none settime: push bx mov bl, ch diff --git a/src/kernel.s b/src/kernel.s index ebf0418..f70633c 100644 --- a/src/kernel.s +++ b/src/kernel.s @@ -1,6 +1,10 @@ %include "config.s" -kernel_entry: ; MUST be a short jump due to loader config +kjmp: ; MUST be a short jump due to loader config + jmp kernel_entry +%include "int21.s" + +kernel_entry: mov si, hello_string mov bl, 0x70 call print_string @@ -8,5 +12,4 @@ kernel_entry: ; MUST be a short jump due to loader config hello_string: db "hello world!", 13, 10, '$' -%include "int21.s" %include "vga.s" diff --git a/src/vga.s b/src/vga.s index fbf1559..32aa442 100644 --- a/src/vga.s +++ b/src/vga.s @@ -1,15 +1,11 @@ ; print a string to the screen ; inputs: -; DS:SI: pointer to '$'-terminated string -; BL: attribute +; DS:SI: pointer to '$'-terminated string +; BL: attribute ; outputs: -; none +; none print_string: - push ax - push bx - push cx - push dx - push bp + pusha push es ; get cursor position in DX @@ -20,27 +16,22 @@ print_string: ; calculate string length by iterating over it until we reach '$' ; this sucks but we have to do it because the bios expects to be passed the string length directly xor cx, cx - push si + mov bp, si + jmp .start_loop .size_loop: inc cx inc si +.start_loop: cmp byte [si], '$' jnz .size_loop - pop si - mov bp, si ; print string and update cursor position mov ax, ds mov es, ax - mov ah, 0x13 - mov al, 0x01 + mov ax, 0x1301 mov bh, 0x00 int 0x10 pop es - pop bp - pop dx - pop cx - pop bx - pop ax + popa ret