Organize int 21h handlers into separate files

This commit is contained in:
Ry 2022-11-02 22:03:41 -07:00
parent bbd12ac117
commit 7debf61fb5
8 changed files with 172 additions and 162 deletions

View File

@ -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)

15
src/int21/0.s Normal file
View File

@ -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

89
src/int21/2.s Normal file
View File

@ -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

36
src/int21/3.s Normal file
View File

@ -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

13
src/int21/4.s Normal file
View File

@ -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

11
src/int21/5.s Normal file
View File

@ -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

View File

@ -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

View File

@ -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