Restructure kernel to use 1-segment COM convention
This commit is contained in:
parent
71c89387fc
commit
84b754551c
6
Makefile
6
Makefile
@ -1,5 +1,5 @@
|
|||||||
PROGRAMS = hello.com
|
PROGRAMS = hello.com
|
||||||
DISTFILES = kernel.bs $(PROGRAMS)
|
DISTFILES = @rdos.com $(PROGRAMS)
|
||||||
ROMS =
|
ROMS =
|
||||||
|
|
||||||
QEMU = qemu-system-i386
|
QEMU = qemu-system-i386
|
||||||
@ -43,7 +43,7 @@ host/%.elf: host/%.c
|
|||||||
%.bs: boot/%.asm
|
%.bs: boot/%.asm
|
||||||
$(NASM) $(NASM_ARGS) -o $@ $<
|
$(NASM) $(NASM_ARGS) -o $@ $<
|
||||||
|
|
||||||
kernel.bs: kernel/*.asm
|
@rdos.com: kernel/*.asm
|
||||||
|
|
||||||
# Special case: variations of FAT vbr
|
# Special case: variations of FAT vbr
|
||||||
fat1.bs: boot/fat.asm
|
fat1.bs: boot/fat.asm
|
||||||
@ -62,7 +62,7 @@ fat6.bs: boot/fat.asm
|
|||||||
fd%.img: $(DISTFILES) $(SYS)
|
fd%.img: $(DISTFILES) $(SYS)
|
||||||
mformat -C -i $@ -f $* -c 2 -v "$(LABEL)" ::
|
mformat -C -i $@ -f $* -c 2 -v "$(LABEL)" ::
|
||||||
mcopy -i $@ $(DISTFILES) ::
|
mcopy -i $@ $(DISTFILES) ::
|
||||||
$(SYS) $@ hello.com
|
$(SYS) $@ @rdos.com
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.com *.bs *.0 *.lst *.img *.bin *.rom
|
rm -f *.com *.bs *.0 *.lst *.img *.bin *.rom
|
||||||
|
107
boot/kernel.asm
107
boot/kernel.asm
@ -1,107 +0,0 @@
|
|||||||
cpu 8086
|
|
||||||
org 0x0700
|
|
||||||
|
|
||||||
%include "inc/bpb.asm"
|
|
||||||
%include "inc/mbr.asm"
|
|
||||||
%include "inc/dpt.asm"
|
|
||||||
|
|
||||||
init: cli
|
|
||||||
xor ax, ax
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov ss, ax
|
|
||||||
mov sp, ax
|
|
||||||
|
|
||||||
mov si, 0x7C00
|
|
||||||
; relocate to 00700
|
|
||||||
mov di, text_start
|
|
||||||
mov cx, text_length + rodata_length + data_length
|
|
||||||
rep movsb
|
|
||||||
; clear out bss section
|
|
||||||
mov cx, bss_length
|
|
||||||
rep stosb
|
|
||||||
; jump to copy
|
|
||||||
call 0:relinit
|
|
||||||
|
|
||||||
section .rodata
|
|
||||||
|
|
||||||
%define V 0x %+ VERSION
|
|
||||||
version: dd V
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
relinit: ; print banner
|
|
||||||
push word [version]
|
|
||||||
push word [version+2]
|
|
||||||
call printf
|
|
||||||
db "RDOS ",2,2, 0x0A, 0x0D, 0
|
|
||||||
; initialize the disk i/o
|
|
||||||
call dinit
|
|
||||||
; init 21h vector
|
|
||||||
mov word [0x21*4], int21
|
|
||||||
mov word [0x21*4+2], cs
|
|
||||||
; set current PSP, directly after us
|
|
||||||
mov ax, stack
|
|
||||||
mov cl, 4
|
|
||||||
shr ax, cl
|
|
||||||
mov word [curpsp], ax
|
|
||||||
; also the DTA
|
|
||||||
mov bx, dta
|
|
||||||
call setdta
|
|
||||||
; set current drive to boot drive
|
|
||||||
mov al, dl
|
|
||||||
rol al, 1
|
|
||||||
rol al, 1
|
|
||||||
or dl, al
|
|
||||||
and dl, 3
|
|
||||||
call setdd
|
|
||||||
|
|
||||||
mov bx, testfcb
|
|
||||||
call fndfst
|
|
||||||
|
|
||||||
restart:
|
|
||||||
hlt: hlt
|
|
||||||
jmp hlt
|
|
||||||
|
|
||||||
%include "kernel/psp.asm"
|
|
||||||
%include "kernel/syscall.asm"
|
|
||||||
%include "kernel/char.asm"
|
|
||||||
%include "kernel/fcb.asm"
|
|
||||||
%include "kernel/drive.asm"
|
|
||||||
%include "kernel/printf.asm"
|
|
||||||
|
|
||||||
section .bss
|
|
||||||
|
|
||||||
dta: resb 128
|
|
||||||
|
|
||||||
section .data
|
|
||||||
|
|
||||||
testfcb: db 0
|
|
||||||
db "HELLO ", "COM"
|
|
||||||
times 30 db 0
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
text_start equ $$
|
|
||||||
text_length equ $-$$
|
|
||||||
|
|
||||||
section .rodata
|
|
||||||
|
|
||||||
rodata_start equ $$
|
|
||||||
rodata_length equ $-$$
|
|
||||||
|
|
||||||
section .data
|
|
||||||
|
|
||||||
data_start equ $$
|
|
||||||
data_length equ $-$$
|
|
||||||
|
|
||||||
section .bss
|
|
||||||
|
|
||||||
resw 256 ; 512b kern stack
|
|
||||||
alignb 16
|
|
||||||
stack: ; stack grows into this ^
|
|
||||||
; this is also the end marker
|
|
||||||
; programs with their psp start here
|
|
||||||
|
|
||||||
bss_start equ $$
|
|
||||||
bss_length equ $-$$
|
|
38
com/@rdos.asm
Normal file
38
com/@rdos.asm
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
org 0x100
|
||||||
|
|
||||||
|
jmp init
|
||||||
|
|
||||||
|
%defstr V VERSION
|
||||||
|
banner: db "RDOS ", V, 0x0A, 0x0D, 0, 0x1A
|
||||||
|
|
||||||
|
%include "kernel/far.asm"
|
||||||
|
%include "inc/bpb.asm"
|
||||||
|
%include "kernel/drive.asm"
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
init: call rstseg
|
||||||
|
mov si, banner
|
||||||
|
.l01: lodsb
|
||||||
|
test al, al
|
||||||
|
jz .l02
|
||||||
|
mov ah, 0x0e
|
||||||
|
xor bx, bx
|
||||||
|
int 0x10
|
||||||
|
jmp .l01
|
||||||
|
.l02:
|
||||||
|
call dinit
|
||||||
|
|
||||||
|
mov dl, 0
|
||||||
|
call logdrv
|
||||||
|
|
||||||
|
xor ax, ax
|
||||||
|
xor dx, dx
|
||||||
|
call maprd
|
||||||
|
|
||||||
|
inc word [dskbuf+0x80]
|
||||||
|
call dirty
|
||||||
|
call flush
|
||||||
|
|
||||||
|
hlt: hlt
|
||||||
|
jmp hlt
|
16
host/sys.c
16
host/sys.c
@ -117,14 +117,14 @@ int main(int argc, char** argv) {
|
|||||||
char* putsfunc = ptr;
|
char* putsfunc = ptr;
|
||||||
|
|
||||||
// assemble puts function
|
// assemble puts function
|
||||||
ptr = push_imm16(ptr, 0xAC5E);
|
//ptr = push_imm16(ptr, 0xAC5E);
|
||||||
ptr = push_imm16(ptr, 0xC084);
|
//ptr = push_imm16(ptr, 0xC084);
|
||||||
ptr = push_imm16(ptr, 0x0874);
|
//ptr = push_imm16(ptr, 0x0874);
|
||||||
ptr = push_imm16(ptr, 0x0EB4);
|
//ptr = push_imm16(ptr, 0x0EB4);
|
||||||
ptr = push_imm16(ptr, 0xDB31);
|
//ptr = push_imm16(ptr, 0xDB31);
|
||||||
ptr = push_imm16(ptr, 0x10CD);
|
//ptr = push_imm16(ptr, 0x10CD);
|
||||||
ptr = push_imm16(ptr, 0xF3EB);
|
//ptr = push_imm16(ptr, 0xF3EB);
|
||||||
ptr = push_imm16(ptr, 0xE6FF);
|
//ptr = push_imm16(ptr, 0xE6FF);
|
||||||
|
|
||||||
// assemble entry point to our main code
|
// assemble entry point to our main code
|
||||||
push_jmp(bs, ptr);
|
push_jmp(bs, ptr);
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
DPTMTT equ 2
|
|
||||||
DPTSS equ 3
|
|
||||||
DPTSPT equ 4
|
|
||||||
|
|
||||||
DPTSIZE equ 11
|
|
203
kernel/drive.asm
203
kernel/drive.asm
@ -5,78 +5,68 @@
|
|||||||
; - dirty: inform that dskbuf has been written to
|
; - dirty: inform that dskbuf has been written to
|
||||||
; access is done by accessing dskbuf directly
|
; access is done by accessing dskbuf directly
|
||||||
|
|
||||||
|
DPTSIZE equ 11
|
||||||
|
DPTSPT equ 4
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
|
|
||||||
; drive actually selected for I/O
|
|
||||||
dsknum: resb 1
|
|
||||||
|
|
||||||
; bios drive we end up using
|
; bios drive we end up using
|
||||||
biosnum: resb 1
|
biosnum resb 1
|
||||||
|
|
||||||
dap: resw 2
|
|
||||||
.buf: resw 2
|
|
||||||
; current sector number
|
|
||||||
; absolute, ignores partition
|
|
||||||
dskseek: resd 2
|
|
||||||
|
|
||||||
; bit 0 (1) - dirty flag for dskbuf
|
; bit 0 (1) - dirty flag for dskbuf
|
||||||
; bit 1 (2) - controller configured
|
; bit 1 (2) - controller configured
|
||||||
; bit 2 (4) - EBIOS supported
|
; bit 2 (4) - EBIOS supported
|
||||||
dskflag: resb 1
|
dskflag resb 1
|
||||||
|
|
||||||
; disk buffer for I/O operations
|
; disk buffer for I/O operations
|
||||||
dskbuf: resb 512
|
dskbuf resb 512
|
||||||
|
|
||||||
dpt: resb DPTSIZE
|
dpt resb DPTSIZE
|
||||||
bpb: resb BPBSIZ4
|
bpb resb BPBSIZ4
|
||||||
|
|
||||||
|
section .data
|
||||||
|
|
||||||
|
; drive actually selected for I/O
|
||||||
|
dsknum db 0xFF
|
||||||
|
|
||||||
|
dap db 0x10, 0
|
||||||
|
dw 1
|
||||||
|
dapbuf dw dskbuf, 0
|
||||||
|
dskseek dw 0,0,0,0
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
; initial setup for disk i/o
|
; initial setup for disk i/o
|
||||||
dinit: ; copy previously set DPT to our data area
|
; copy previously set DPT to our data area
|
||||||
push ds
|
dinit xor ax, ax
|
||||||
push cs
|
mov es, ax
|
||||||
pop es
|
les bx, [es:4*0x1E]
|
||||||
lds si, [es:4*0x1E]
|
mov dx, dpt
|
||||||
mov di, dpt
|
|
||||||
mov cx, 11
|
mov cx, 11
|
||||||
rep movsb
|
call lodfar
|
||||||
; set vector
|
; set interrupt vector
|
||||||
mov word [cs:4*0x1E], dpt
|
mov es, cx
|
||||||
mov word [cs:4*0x1E+2], ds
|
mov word [es:4*0x1E], dpt
|
||||||
; set to invalid drive
|
mov word [es:4*0x1E+2], ds
|
||||||
mov byte [cs:dsknum], 0xFF
|
; set segment addr in DAP
|
||||||
pop ds
|
mov [dapbuf+2], cs
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; int 13 stub
|
; int 13 stub
|
||||||
int13: ; debug output
|
; this is meant as a central place to implement
|
||||||
push bx
|
; stack switching or some other safeguards
|
||||||
push dx
|
int13 int 0x13
|
||||||
push cx
|
|
||||||
push ax
|
|
||||||
call printf
|
|
||||||
db "int13 CALL AX=",2," CX=",2," DX=",2," BX=",2,0x0A,0x0D,0
|
|
||||||
; do the call
|
|
||||||
int 0x13
|
|
||||||
jc .err
|
|
||||||
ret
|
|
||||||
.err: push ax
|
|
||||||
call printf
|
|
||||||
db "DISK ERR AX=",2,0x0A,0x0D,0
|
|
||||||
stc
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; get drive parameters
|
; get drive parameters
|
||||||
; read BIOS int13h/AH=8 values
|
; read BIOS int13h/AH=8 values
|
||||||
; DPT data gets copied over our dpt
|
; DPT data gets copied over our dpt
|
||||||
; CHS data gets inserted into our bpb
|
; CHS data gets inserted into our bpb
|
||||||
getprm: ; skip if EBIOS extension enabled
|
getprm test byte [dskflag], 4
|
||||||
test byte [cs:dskflag], 4
|
|
||||||
jnz .ret
|
jnz .ret
|
||||||
; do the query
|
; do the query
|
||||||
mov ah, 8
|
mov ah, 8
|
||||||
mov dl, [cs:biosnum]
|
mov dl, [biosnum]
|
||||||
call int13
|
call int13
|
||||||
; bail out if error
|
; bail out if error
|
||||||
jc .ret
|
jc .ret
|
||||||
@ -85,43 +75,31 @@ getprm: ; skip if EBIOS extension enabled
|
|||||||
jz .nochs
|
jz .nochs
|
||||||
; get and store sector number
|
; get and store sector number
|
||||||
and cx, 0x3F
|
and cx, 0x3F
|
||||||
mov word [cs:bpb+BPBSPT], cx
|
mov word [bpb+BPBSPT], cx
|
||||||
; get and store number of heads
|
; get and store number of heads
|
||||||
xchg dl, dh
|
xchg dl, dh
|
||||||
and dx, 0xFF
|
and dx, 0xFF
|
||||||
inc dx
|
inc dx
|
||||||
mov [cs:bpb+BPBNOS], dx
|
mov [bpb+BPBNOS], dx
|
||||||
; test if DPT ptr is non-zero
|
; test if DPT ptr is non-zero
|
||||||
.nochs: mov ax, es
|
.nochs mov ax, es
|
||||||
or ax, di
|
or ax, di
|
||||||
test ax, ax
|
test ax, ax
|
||||||
jz .ret
|
jz .ret
|
||||||
; DS:SI = ES:DI
|
; copy BIOS dpt table over ours
|
||||||
mov ax, es
|
mov dx, dpt
|
||||||
mov ds, ax
|
mov bx, di
|
||||||
mov si, di
|
call lodfar
|
||||||
; ES:DI = dpt
|
.ret ret
|
||||||
xor ax, ax
|
|
||||||
mov es, ax
|
|
||||||
mov di, dpt
|
|
||||||
; do the copy
|
|
||||||
mov cx, 11
|
|
||||||
rep movsb
|
|
||||||
.ret: ret
|
|
||||||
|
|
||||||
; log in drive
|
; log in drive
|
||||||
; IN dl drive number
|
; IN dl drive number
|
||||||
logdrv: ; DS := CS
|
|
||||||
push cs
|
|
||||||
pop ds
|
|
||||||
; dont do anything if drive already selected
|
; dont do anything if drive already selected
|
||||||
cmp dl, [dsknum]
|
logdrv cmp dl, [dsknum]
|
||||||
je logfdd.ret
|
je logfdd.ret
|
||||||
; clear out current contents
|
; clear out current contents
|
||||||
push dx
|
push dx
|
||||||
push ds
|
|
||||||
call flush
|
call flush
|
||||||
pop ds
|
|
||||||
mov ax, 0xFFFF
|
mov ax, 0xFFFF
|
||||||
mov [dskseek], ax
|
mov [dskseek], ax
|
||||||
mov [dskseek+2], ax
|
mov [dskseek+2], ax
|
||||||
@ -133,25 +111,20 @@ logdrv: ; DS := CS
|
|||||||
cmp dl, 2
|
cmp dl, 2
|
||||||
jnc loghdd
|
jnc loghdd
|
||||||
|
|
||||||
logfdd: ; save info for bios
|
; save info for bios
|
||||||
mov [biosnum], dl
|
logfdd mov [biosnum], dl
|
||||||
; reset dpt to defaults
|
; reset dpt to defaults
|
||||||
push ds
|
|
||||||
call getprm
|
call getprm
|
||||||
pop ds
|
|
||||||
; set default geometry (1.44 MB floppy)
|
; set default geometry (1.44 MB floppy)
|
||||||
mov word [bpb+BPBNOS], 2
|
mov word [bpb+BPBNOS], 2
|
||||||
mov word [bpb+BPBSPT], 18
|
mov word [bpb+BPBSPT], 18
|
||||||
; load boot sector
|
; load boot sector
|
||||||
push ds
|
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
xor dx, dx
|
xor dx, dx
|
||||||
call mapabs
|
call mapabs
|
||||||
pop ds
|
|
||||||
; copy bios parameter block
|
; copy bios parameter block
|
||||||
; TODO: guess from first byte of FAT if BPB invalid
|
; TODO: guess from first byte of FAT if BPB invalid
|
||||||
push ds
|
call rstseg
|
||||||
pop es
|
|
||||||
mov si, dskbuf+BPBOFF
|
mov si, dskbuf+BPBOFF
|
||||||
mov di, bpb
|
mov di, bpb
|
||||||
mov cx, BPBSIZ4
|
mov cx, BPBSIZ4
|
||||||
@ -163,10 +136,9 @@ logfdd: ; save info for bios
|
|||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov [bpb+BPBHS], ax
|
mov [bpb+BPBHS], ax
|
||||||
mov [bpb+BPBHS+2], ax
|
mov [bpb+BPBHS+2], ax
|
||||||
.ret: ret
|
.ret ret
|
||||||
|
|
||||||
; assumes that DS == CS
|
loghdd sub dl, 2
|
||||||
loghdd: sub dl, 2
|
|
||||||
cmp dl, 4
|
cmp dl, 4
|
||||||
jnc logerr
|
jnc logerr
|
||||||
push dx
|
push dx
|
||||||
@ -180,16 +152,8 @@ loghdd: sub dl, 2
|
|||||||
jnz .chs
|
jnz .chs
|
||||||
; enable ebios and assume controller is configured
|
; enable ebios and assume controller is configured
|
||||||
or byte [dskflag], (2+4)
|
or byte [dskflag], (2+4)
|
||||||
; initialize DAP
|
|
||||||
mov word [dap], 0x10
|
|
||||||
mov word [dap+2], 1
|
|
||||||
mov word [dap+4], dskbuf
|
|
||||||
xor ax, ax
|
|
||||||
mov word [dap+6], ax
|
|
||||||
mov word [dap+12], ax
|
|
||||||
mov word [dap+14], ax
|
|
||||||
; get chs data (needed or we cant load vbr)
|
; get chs data (needed or we cant load vbr)
|
||||||
.chs: call getprm
|
.chs call getprm
|
||||||
; read mbr
|
; read mbr
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
xor dx, dx
|
xor dx, dx
|
||||||
@ -200,20 +164,17 @@ loghdd: sub dl, 2
|
|||||||
mov cl, 4
|
mov cl, 4
|
||||||
sal bx, cl
|
sal bx, cl
|
||||||
; bail out if no partition
|
; bail out if no partition
|
||||||
cmp byte [cs:dskbuf+0x1be+bx+4], 0
|
cmp byte [dskbuf+0x1be+bx+4], 0
|
||||||
je logerr
|
je logerr
|
||||||
; load partition offset
|
; load partition offset
|
||||||
mov ax, [cs:dskbuf+0x1be+bx+8]
|
mov ax, [dskbuf+0x1be+bx+8]
|
||||||
mov dx, [cs:dskbuf+0x1be+bx+8+2]
|
mov dx, [dskbuf+0x1be+bx+8+2]
|
||||||
; save to to stack
|
; save to to stack
|
||||||
push dx
|
push dx
|
||||||
push ax
|
push ax
|
||||||
; load vbr
|
; load vbr
|
||||||
call mapabs
|
call mapabs
|
||||||
; copy bpb
|
; copy bpb
|
||||||
mov ax, cs
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov si, dskbuf+BPBOFF
|
mov si, dskbuf+BPBOFF
|
||||||
mov di, bpb
|
mov di, bpb
|
||||||
mov cx, BPBSIZ4
|
mov cx, BPBSIZ4
|
||||||
@ -221,44 +182,44 @@ loghdd: sub dl, 2
|
|||||||
; fix CHS data
|
; fix CHS data
|
||||||
call getprm
|
call getprm
|
||||||
; fix partition offset
|
; fix partition offset
|
||||||
pop ax
|
pop word [bpb+BPBHS]
|
||||||
pop dx
|
pop word [bpb+BPBHS+2]
|
||||||
mov [cs:bpb+BPBHS], ax
|
;pop [bpb+BPBNOS]
|
||||||
mov [cs:bpb+BPBHS+2], dx
|
;pop [bpb+BPBSPT]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
logerr: stc
|
logerr stc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
mapclu: ; counting from begin of cluster area
|
; counting from begin of cluster area
|
||||||
mov bx, [cs:bpb+BPBRDE]
|
mapclu mov bx, [bpb+BPBRDE]
|
||||||
mov cl, 4
|
mov cl, 4
|
||||||
shr bx, cl ; 32 bytes per entry
|
shr bx, cl ; 32 bytes per entry
|
||||||
add ax, bx
|
add ax, bx
|
||||||
adc dx, 0
|
adc dx, 0
|
||||||
maprd: ; counting from beginning of dir
|
; counting from beginning of dir
|
||||||
; add fat table sizes
|
; add fat table sizes
|
||||||
xor ch, ch
|
maprd xor ch, ch
|
||||||
mov cl, byte [cs:bpb+BPBFN]
|
mov cl, byte [bpb+BPBFN]
|
||||||
.loop: add ax, [cs:bpb+BPBFS]
|
.loop add ax, [bpb+BPBFS]
|
||||||
adc dx, 0
|
adc dx, 0
|
||||||
loop .loop
|
loop .loop
|
||||||
mapfat: ; counting from beginning of FAT
|
; counting from beginning of FAT
|
||||||
; add reserved sector count
|
; add reserved sector count
|
||||||
add ax, [cs:bpb+BPBRSC]
|
mapfat add ax, [bpb+BPBRSC]
|
||||||
adc dx, 0
|
adc dx, 0
|
||||||
map: ; count from partition start
|
; count from partition start
|
||||||
add ax, [cs:bpb+BPBHS]
|
map add ax, [bpb+BPBHS]
|
||||||
add dx, [cs:bpb+BPBHS+2]
|
add dx, [bpb+BPBHS+2]
|
||||||
mapabs: ; absolute sector count
|
; absolute sector count
|
||||||
; skip doing a read if sector number matches
|
; skip doing a read if sector number matches
|
||||||
cmp ax, [cs:dskseek]
|
mapabs cmp ax, [dskseek]
|
||||||
jne read
|
jne read
|
||||||
cmp dx, [cs:dskseek+2]
|
cmp dx, [dskseek+2]
|
||||||
jne read
|
jne read
|
||||||
ret
|
ret
|
||||||
|
|
||||||
read: push ax
|
read push ax
|
||||||
push dx
|
push dx
|
||||||
call flush
|
call flush
|
||||||
pop dx
|
pop dx
|
||||||
@ -271,9 +232,9 @@ read: push ax
|
|||||||
; low level read and write
|
; low level read and write
|
||||||
; call again to retry, no input registers
|
; call again to retry, no input registers
|
||||||
; read or write is configured in cx
|
; read or write is configured in cx
|
||||||
_read: mov ch, 2
|
_read mov ch, 2
|
||||||
db 0x3D ; cmp ax, imm16: causes next instr to be skipped
|
db 0x3D ; cmp ax, imm16: causes next instr to be skipped
|
||||||
_write: mov ch, 3
|
_write mov ch, 3
|
||||||
mov cl, 1 ; read len
|
mov cl, 1 ; read len
|
||||||
; DS := ES := CS
|
; DS := ES := CS
|
||||||
mov ax, cs
|
mov ax, cs
|
||||||
@ -287,14 +248,14 @@ _write: mov ch, 3
|
|||||||
mov si, dap
|
mov si, dap
|
||||||
jmp .do
|
jmp .do
|
||||||
; check if we can skip controller reset
|
; check if we can skip controller reset
|
||||||
.l00: test byte [dskflag], 2
|
.l00 test byte [dskflag], 2
|
||||||
jnz .l01
|
jnz .l01
|
||||||
; do controller reset
|
; do controller reset
|
||||||
mov dl, [biosnum]
|
mov dl, [biosnum]
|
||||||
mov ah, 0
|
mov ah, 0
|
||||||
call int13
|
call int13
|
||||||
or byte [dskflag], 2
|
or byte [dskflag], 2
|
||||||
.l01: ; put sectors per cylinder into bx
|
.l01 ; put sectors per cylinder into bx
|
||||||
mov ax, [bpb+BPBSPT]
|
mov ax, [bpb+BPBSPT]
|
||||||
mul word [bpb+BPBNOS]
|
mul word [bpb+BPBNOS]
|
||||||
mov bx, ax
|
mov bx, ax
|
||||||
@ -322,7 +283,7 @@ _write: mov ch, 3
|
|||||||
xchg cx, dx
|
xchg cx, dx
|
||||||
xchg dh, dl
|
xchg dh, dl
|
||||||
mov bx, dskbuf
|
mov bx, dskbuf
|
||||||
.do: mov dl, [biosnum]
|
.do mov dl, [biosnum]
|
||||||
; ah: subfunction selected via cx previously
|
; ah: subfunction selected via cx previously
|
||||||
; al: 1 = reading 1 sector
|
; al: 1 = reading 1 sector
|
||||||
; cx: sector and cylinder number
|
; cx: sector and cylinder number
|
||||||
@ -335,19 +296,19 @@ _write: mov ch, 3
|
|||||||
and byte [dskflag], 0xFE
|
and byte [dskflag], 0xFE
|
||||||
clc
|
clc
|
||||||
ret
|
ret
|
||||||
.err: ; assume controller is misconfigured
|
.err ; assume controller is misconfigured
|
||||||
and byte [dskflag], 0xFD
|
and byte [dskflag], 0xFD
|
||||||
; exit with carry flag set
|
; exit with carry flag set
|
||||||
stc
|
stc
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; mark dskbuf as containing unwritten changes
|
; mark dskbuf as containing unwritten changes
|
||||||
dirty: or byte [cs:dskflag], 1 ; dirty
|
dirty or byte [cs:dskflag], 1 ; dirty
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; flush buffer if dirty
|
; flush buffer if dirty
|
||||||
flush: test byte [cs:dskflag], 1
|
flush test byte [cs:dskflag], 1
|
||||||
jz .ret
|
jz .ret
|
||||||
; TODO: error handling & retries
|
; TODO: error handling & retries
|
||||||
jmp _write
|
jmp _write
|
||||||
.ret: ret
|
.ret ret
|
||||||
|
34
kernel/far.asm
Normal file
34
kernel/far.asm
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
; reset segments
|
||||||
|
rstseg mov ax, cs
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; copy to far memory
|
||||||
|
; IN es:bx far memory ptr (preserved)
|
||||||
|
; ds:dx local ptr (preserved)
|
||||||
|
; cx number of bytes to transfer
|
||||||
|
; OUT cx set to zero
|
||||||
|
; si & di trashed
|
||||||
|
stofar mov si, dx
|
||||||
|
mov di, bx
|
||||||
|
rep movsb
|
||||||
|
ret
|
||||||
|
|
||||||
|
; copy from far memory
|
||||||
|
; IN es:bx far memory ptr (preserved)
|
||||||
|
; ds:dx local ptr (preserved)
|
||||||
|
; cx number of bytes to copy
|
||||||
|
; OUT cx set to zero
|
||||||
|
; si & di trashed
|
||||||
|
lodfar call xchgdes
|
||||||
|
mov si, bx
|
||||||
|
mov di, dx
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
; exchange es and ds
|
||||||
|
xchgdes push ds
|
||||||
|
push es
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
ret
|
Loading…
Reference in New Issue
Block a user