initial code
This commit is contained in:
parent
e33c1db9b1
commit
5c04b293e1
|
@ -0,0 +1,11 @@
|
||||||
|
NAME=foxdos
|
||||||
|
|
||||||
|
rm $NAME
|
||||||
|
|
||||||
|
mkdir -p obj
|
||||||
|
|
||||||
|
# TODO this only works in root directory. might be good to just use a proper build system
|
||||||
|
nasm -I. -Isrc src/boot.s -o obj/boot
|
||||||
|
nasm -I. -Isrc src/kernel.s -o obj/kernel
|
||||||
|
|
||||||
|
cat obj/boot obj/kernel > $NAME
|
|
@ -0,0 +1,5 @@
|
||||||
|
NUMSEG equ 0 ; 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
|
|
@ -0,0 +1,45 @@
|
||||||
|
; mothdos boot sector. should load kernel into segment 0x50 at 0x00. max size
|
||||||
|
; would be 64k but i doubt a dos needs more than that. stack is placed at
|
||||||
|
; 0x10500. i would suggest changing this to load the kernel into extended
|
||||||
|
; a20-gate memory so as not to overwrite the boot sector with larger kernels
|
||||||
|
; but i will leave that for you to do. code is public domain as always. i
|
||||||
|
; have not tested any of this so your mileage using it may vary
|
||||||
|
|
||||||
|
%include "config.s"
|
||||||
|
|
||||||
|
[org 0x7C00]
|
||||||
|
[bits 16]
|
||||||
|
|
||||||
|
mov ax, K_ADDR << 4
|
||||||
|
push ax ; setup for ds
|
||||||
|
mov es, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov fs, ax
|
||||||
|
|
||||||
|
xor bx, bx
|
||||||
|
mov ds, bx
|
||||||
|
mov word [0x21*4], 2 ; see kernel_entry
|
||||||
|
mov word [0x21*4+2], ax
|
||||||
|
pop ds
|
||||||
|
|
||||||
|
mov ax, 0x200 | NUMSEG
|
||||||
|
mov cl, 2
|
||||||
|
xor dh, dh
|
||||||
|
int 13h
|
||||||
|
|
||||||
|
; 64kb stack
|
||||||
|
mov ax, STACK_SEG
|
||||||
|
mov ss, ax
|
||||||
|
xor sp, sp
|
||||||
|
mov ax, sp
|
||||||
|
not sp
|
||||||
|
|
||||||
|
; kernel time(?)
|
||||||
|
push ds
|
||||||
|
push ax
|
||||||
|
retf
|
||||||
|
|
||||||
|
; TODO we have lots of space for init code here
|
||||||
|
|
||||||
|
times 510 - ($-$$) db 0
|
||||||
|
dw 0xAA55
|
|
@ -0,0 +1,128 @@
|
||||||
|
int21:
|
||||||
|
push ds
|
||||||
|
push cs
|
||||||
|
pop ds
|
||||||
|
; your handler goes here
|
||||||
|
; you could maybe make a jump table that takes ah as input?
|
||||||
|
pop ds
|
||||||
|
iret
|
||||||
|
|
||||||
|
retcode: dw 0
|
||||||
|
verify: db 0
|
||||||
|
|
||||||
|
get_retcode:; ah=4dh
|
||||||
|
mov ax, [retcode]
|
||||||
|
retf
|
||||||
|
|
||||||
|
get_version:; ah=30h
|
||||||
|
mov ax, 8 ; if it is not zero indexed this indicates windows ME
|
||||||
|
xor bx, bx ; update: what does that comment mean
|
||||||
|
mov cx, bx
|
||||||
|
retf
|
||||||
|
|
||||||
|
getverify:; ah=54h
|
||||||
|
mov al, [verify]
|
||||||
|
retf
|
||||||
|
|
||||||
|
setverify:; ah=2eh
|
||||||
|
mov [verify], al
|
||||||
|
retf
|
||||||
|
|
||||||
|
getint:; ah=35h
|
||||||
|
push ds
|
||||||
|
push di
|
||||||
|
push ax
|
||||||
|
xor ah, ah
|
||||||
|
shl ax, 2
|
||||||
|
mov di, ax
|
||||||
|
xor ax, ax
|
||||||
|
mov ds, ax
|
||||||
|
pop ax
|
||||||
|
mov word bx, [di]
|
||||||
|
mov word es, [di+2]
|
||||||
|
pop di
|
||||||
|
pop ds
|
||||||
|
retf
|
||||||
|
|
||||||
|
setint:; ah=25h
|
||||||
|
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
|
||||||
|
popa
|
||||||
|
retf
|
||||||
|
|
||||||
|
rdcmos:; input in al. TODO handle bcd here to abstractt it from the kernel
|
||||||
|
cli
|
||||||
|
cmp al, 9 ; not rtc register, do not wait. if this function bugs out
|
||||||
|
jg .rd ; on a century boundary thats not on me. stop using dos
|
||||||
|
xchg al, ah
|
||||||
|
.wait: mov al, 0xA ; msb specifies if rtc update is in progress
|
||||||
|
out 0x70, al ; TODO https://wiki.osdev.org/CMOS#RTC_Update_In_Progress
|
||||||
|
in al, 0x71
|
||||||
|
shl al, 1
|
||||||
|
jc .wait
|
||||||
|
xchg al, ah
|
||||||
|
.rd: out 0x70, al
|
||||||
|
in al, 0x71
|
||||||
|
sti
|
||||||
|
ret
|
||||||
|
|
||||||
|
wrcmos:; register in bh, value in bl
|
||||||
|
cli
|
||||||
|
push ax
|
||||||
|
mov al, bh
|
||||||
|
or al, 0x80 ; nmi always on
|
||||||
|
out 0x70, al
|
||||||
|
mov al, bl
|
||||||
|
out 0x71, al
|
||||||
|
pop ax
|
||||||
|
sti
|
||||||
|
ret
|
||||||
|
|
||||||
|
gettime:; ah=2ch
|
||||||
|
push ax
|
||||||
|
xor dl, dl
|
||||||
|
|
||||||
|
mov al, dl ; seconds
|
||||||
|
call rdcmos
|
||||||
|
mov dh, al
|
||||||
|
|
||||||
|
mov al, 2h ; minutes
|
||||||
|
call rdcmos
|
||||||
|
mov cl, al
|
||||||
|
|
||||||
|
mov al, 4h ; hours
|
||||||
|
call rdcmos
|
||||||
|
mov ch, al
|
||||||
|
|
||||||
|
shl al, 1 ; adjust for 12 hour time
|
||||||
|
jnc .end
|
||||||
|
add ch, 12
|
||||||
|
|
||||||
|
.end: pop ax
|
||||||
|
retf
|
||||||
|
|
||||||
|
settime:; ah=2dh
|
||||||
|
push bx
|
||||||
|
mov bl, ch
|
||||||
|
mov bh, 0x4
|
||||||
|
call wrcmos
|
||||||
|
mov bl, cl
|
||||||
|
shr bh, 1
|
||||||
|
call wrcmos
|
||||||
|
mov bl, dh
|
||||||
|
cmp dl, 50 ; rtc cannot hold hundredths of a second so we round
|
||||||
|
jng .f
|
||||||
|
inc bl
|
||||||
|
.f: xor bh, bh
|
||||||
|
call wrcmos
|
||||||
|
xor al, al ; it probably succeeded, its fine. TODO am i missing return codes anywhere else
|
||||||
|
pop bx
|
||||||
|
iret
|
|
@ -0,0 +1,6 @@
|
||||||
|
%include "config.s"
|
||||||
|
[org K_ADDR]
|
||||||
|
kernel_entry: ; MUST be a short jump due to loader config
|
||||||
|
jmp $ ; TODO stub because os doesnt actually exist yet
|
||||||
|
|
||||||
|
%include "int21.s"
|
Loading…
Reference in New Issue