diff --git a/Makefile b/Makefile index 89f18d5..7e33878 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,8 @@ TARGET = foxdos FILES = config.s \ - src/int21.s \ - src/kernel.s \ - src/vga.s + $(wildcard src/*.s) \ + $(wildcard src/int21/*.s) .PHONY: all qemu clean all: obj/boot.o obj/kernel.o $(TARGET) diff --git a/src/int21/0.s b/src/int21/0.s new file mode 100644 index 0000000..e3a2ba6 --- /dev/null +++ b/src/int21/0.s @@ -0,0 +1,15 @@ +; 0x00 - 0x0F + +; 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 + ; TODO does echo go to stdout or to screen? + pop ax + ret diff --git a/src/int21/2.s b/src/int21/2.s new file mode 100644 index 0000000..13b501a --- /dev/null +++ b/src/int21/2.s @@ -0,0 +1,89 @@ +; 0x20 - 0x2F + +; AH = 25h +; set interrupt vector +; inputs: +; AL: interrupt number +; DS:DX: new interrupt handler +; outputs: +; none +setint: + pusha + xor ah, ah + shl ax, 2 + mov di, ax + xor ax, ax + push es + mov es, ax + mov word es:[di], dx + mov word es:[di+2], ds + pop es + popa + ret + +; AH = 2ch +; read system time from the CMOS +; inputs: +; none +; outputs: +; CH: hours +; CL: minutes +; DH: seconds +gettime: + 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 + ret + +; AH = 2dh +; set system time in the CMOS +; inputs: +; CH: hours +; CL: minutes +; DH: seconds +; outputs: +; none +settime: + 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 + ret + +; AH = 2eh +; set disk verify flag +; inputs: +; AL: 0 if off, 1 if on +; outputs: +; none +setverify: + mov [verify], al + ret diff --git a/src/int21/3.s b/src/int21/3.s new file mode 100644 index 0000000..9f013e5 --- /dev/null +++ b/src/int21/3.s @@ -0,0 +1,36 @@ +; 0x30 - 0x3F + +; AH = 30h +; get the DOS version number +; inputs: +; none +; outputs: +; 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 + mov cx, bx + ret + +; AH = 35h +; get interrupt vector +; inputs: +; AL: interrupt number +; outputs: +; ES:BX: current interrupt handler +getint: + 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 + ret diff --git a/src/int21/4.s b/src/int21/4.s new file mode 100644 index 0000000..a421405 --- /dev/null +++ b/src/int21/4.s @@ -0,0 +1,13 @@ +; 0x40 - 0x4F + +; AH = 4dh +; get return code +; inputs: +; none +; outputs: +; 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 + ret diff --git a/src/int21/5.s b/src/int21/5.s new file mode 100644 index 0000000..645c438 --- /dev/null +++ b/src/int21/5.s @@ -0,0 +1,11 @@ +; 0x50 - 0x5F + +; AH = 54h +; get disk verify flag +; inputs: +; none +; outputs: +; AL: 0 if off, 1 if on +getverify: + mov al, [verify] + ret diff --git a/src/int21.s b/src/int21/int21.s similarity index 54% rename from src/int21.s rename to src/int21/int21.s index c26d717..c5b9657 100644 --- a/src/int21.s +++ b/src/int21/int21.s @@ -45,107 +45,11 @@ tmp: dw 0 retcode: dw 0 verify: db 0 -; 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 - ; TODO does echo go to stdout or to screen? - pop ax - -; AH = 4dh -; get return code -; inputs: -; none -; outputs: -; 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 - ret - -; AH = 30h -; get the DOS version number -; inputs: -; none -; outputs: -; 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 - mov cx, bx - ret - - -; AH = 54h -; get disk verify flag -; inputs: -; none -; outputs: -; AL: 0 if off, 1 if on -getverify: - mov al, [verify] - ret - -; AH = 2eh -; set disk verify flag -; inputs: -; AL: 0 if off, 1 if on -; outputs: -; none -setverify: - mov [verify], al - ret - -; AH = 35h -; get interrupt vector -; inputs: -; AL: interrupt number -; outputs: -; ES:BX: current interrupt handler -getint: - 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 - ret - -; AH = 25h -; set interrupt vector -; inputs: -; AL: interrupt number -; DS:DX: new interrupt handler -; outputs: -; none -setint: - pusha - xor ah, ah - shl ax, 2 - mov di, ax - xor ax, ax - push es - mov es, ax - mov word es:[di], dx - mov word es:[di+2], ds - pop es - popa - ret +%include "int21/0.s" +%include "int21/2.s" +%include "int21/3.s" +%include "int21/4.s" +%include "int21/5.s" ; read from CMOS register ; inputs: @@ -186,60 +90,3 @@ wrcmos: pop ax sti ret - -; AH = 2ch -; read system time from the CMOS -; inputs: -; none -; outputs: -; CH: hours -; CL: minutes -; DH: seconds -gettime: - 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 - ret - -; AH = 2dh -; set system time in the CMOS -; inputs: -; CH: hours -; CL: minutes -; DH: seconds -; outputs: -; none -settime: - 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 - ret diff --git a/src/kernel.s b/src/kernel.s index f70633c..722ef40 100644 --- a/src/kernel.s +++ b/src/kernel.s @@ -2,7 +2,7 @@ kjmp: ; MUST be a short jump due to loader config jmp kernel_entry -%include "int21.s" +%include "int21/int21.s" kernel_entry: mov si, hello_string