diff --git a/Makefile b/Makefile index 4a9a74e..bf26b2b 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,7 @@ qemu-floppy3: fd1440.img $(ROMS) $(QEMU) $(QEMU_ARGS) -boot a -fda fd1440.img qemu-floppy5: fd360.img $(ROMS) - $(QEMU) $(QEMU_ARGS) -boot a -fda fd360.img + $(QEMU) $(QEMU_ARGS) -boot a -fda fd360.img qemu-hdd: hdimage.img $(ROMS) $(QEMU) $(QEMU_ARGS) -boot c -hda hdimage.img diff --git a/boot/kernel.asm b/boot/kernel.asm index ba05ad7..e9c1b1c 100644 --- a/boot/kernel.asm +++ b/boot/kernel.asm @@ -3,7 +3,6 @@ %include "inc/bpb.asm" %include "inc/mbr.asm" -%include "inc/fcb.asm" %include "inc/dpt.asm" init: cli @@ -56,10 +55,6 @@ relinit: ; print banner sub dl, (0x80-2) .k: call setdd - mov ah, 2 - mov dl, 0x37 - int 0x21 - mov dx, testfcb mov ah, 0xF int 0x21 @@ -68,6 +63,7 @@ restart: hlt: hlt jmp hlt +%include "kernel/psp.asm" %include "kernel/syscall.asm" %include "kernel/char.asm" %include "kernel/fcb.asm" diff --git a/inc/fcb.asm b/inc/fcb.asm deleted file mode 100644 index 811d677..0000000 --- a/inc/fcb.asm +++ /dev/null @@ -1,2 +0,0 @@ -FCBDEN: equ 23 ; directory entry -FCBSIZ: equ 30 diff --git a/kernel/fcb.asm b/kernel/fcb.asm index 9ab93b6..b7201bc 100644 --- a/kernel/fcb.asm +++ b/kernel/fcb.asm @@ -1,35 +1,27 @@ + +; FCB layout +; 1 byte drive (0=default, 1=A:, 2=B:, ...) +; 8.3 filename +; 8.3 filename for rename + +FCBDEN: equ 23 ; WORD directory entry number +FCBSIZ: equ 30 + section .text - ; set default drive for current process - ; IN dl drive number -setdd: push ds - mov ds, [cs:curpsp] - mov [PSPDD], dl - pop ds - ret - - ; get default drive for current process - ; OUT al drive number -getdd: push ds - mov ds, [cs:curpsp] - mov al, [PSPDD] - pop ds - ret - ; auto-complete drive field in fcb - ; IN ds:dx far ptr FCB - ; OUT si copy of dx -fixfcb: mov si, dx - cmp byte [si], 0 + ; IN es:bx far ptr FCB + ; OUT si copy of bx +fixfcb: cmp byte [es:bx], 0 jne .ret call getdd inc dl - mov byte [si], dl -.ret: mov dx, si - ret + mov byte [es:bx], dl +.ret: ret ; Load root directory entry ; IN ax number of directory entry + ; OUT cs:si ptr to directory entry lddir: push ax mov cl, 4 shr ax, cl @@ -43,33 +35,10 @@ lddir: push ax add si, dskbuf ret - ; find next file -fnfile: mov ax, [es:bx+FCBDEN] - inc word [es:bx+FCBDEN] - ; bail out if we are at end of dir - cmp ax, [bpb+BPBRDE] - jnc .err - ; load entry and first byte - push bx - call lddir - pop bx - ; next if hidden, dir or vol label - test byte [si+0x0B], 0xDA - jnz fnfile - ; bail out if end of dir - mov al, [si] - cmp al, 0 - je .err - ; next if deleted entry - cmp al, 0xE5 - je fnfile - clc - ret -.err: stc - ret + ; find first matching file + ; IN ES:BX input fcb +fndfst: - ; Open file using FCB - ; IN DS:DX far ptr to FCB -open: call fixfcb - int 3 + +open: ret diff --git a/kernel/psp.asm b/kernel/psp.asm new file mode 100644 index 0000000..ccdf7bf --- /dev/null +++ b/kernel/psp.asm @@ -0,0 +1,62 @@ +; Program segment prefix headers and constants + +section .bss + +curpsp: resw 1 + +absolute 0 + + resb 2 ; ret 0 exit + resb 2 ; next unusable segment +PSPDD: resb 1 ; BYTE default drive + ; CP/M entry point + resb 1 ; instruction byte + resw 1 ; usable length of segment (needs to be here for compata) + resb 4 ; opcodes to call us + + ; saved userdata +PSPAX: resw 1 +PSPCX: resw 1 + ; SS:SP +PSPSP: resw 1 +PSPSS: resw 1 + ; DS:DX +PSPDX: resw 1 +PSPDS: resw 1 + ; ES:BX +PSPBX: resw 1 +PSPES: resw 1 + +PSPDTA: resd 1 ; DWORD ptr to disk transfer area + +section .text + + ; set default drive for current process + ; IN dl drive number +setdd: push es + mov es, [curpsp] + mov [es:PSPDD], dl + pop es + ret + + ; get default drive for current process + ; OUT al drive number +getdd: push es + mov es, [curpsp] + mov al, [es:PSPDD] + pop es + ret + + ; set DTA ptr + ; IN es:bx far ptr +setdta: push es + mov ds, [curpsp] + mov [PSPDTA], bx + mov [PSPDTA+2], es + pop es + + ; get DTA ptr + ; OUT es:bx far ptr +getdta: mov es, [curpsp] + les bx, [es:PSPDTA] + ret diff --git a/kernel/syscall.asm b/kernel/syscall.asm index 8efe0e9..ec8555b 100644 --- a/kernel/syscall.asm +++ b/kernel/syscall.asm @@ -5,11 +5,7 @@ ; - exports a specified set of registers back to userspace ; ; The syscall table acts as a "export"-list for kernel near funcs. -; Code invoked via it can reply on SS being zero. - -section .bss - -curpsp: resw 1 +; Kernel code can expect CS = DS section .rodata @@ -37,31 +33,6 @@ stab: ; syscall table section .text -absolute 0 - - resb 2 ; ret 0 exit - resb 2 ; allocation length - resb 1 - resb 5 ; CP/M entry point - - ; saved userdata -PSPAX: resw 1 -PSPCX: resw 1 - ; SS:SP -PSPSP: resw 1 -PSPSS: resw 1 - ; DS:DX -PSPDX: resw 1 -PSPDS: resw 1 - ; ES:BX -PSPBX: resw 1 -PSPES: resw 1 - - ; default drive -PSPDD: resb 1 - -section .text - ; WARNING: BP, SI and DI are not saved ; If kernel code uses them, they need to be saved to the stack int21: push ds @@ -89,9 +60,12 @@ int21: push ds ; load sysret and handler ptr push word [cs:bx+2] push word [cs:bx] - ; restore user data and launch ret chain - mov bx, [PSPBX] - mov ds, [PSPDS] + ; DS is always our segment + push cs + pop ds + ; ES:BX is syscall argument + mov bx, [PSPDX] + mov es, [PSPDS] ret err: mov ah, 0xFF @@ -107,6 +81,10 @@ sretw: mov ds, [cs:curpsp] mov es, [PSPES] jmp sret.l02 + ; return carry flag in AL +sretc: mov ds, [cs:curpsp] + sbb al, al + ; return AL to user sretb: mov ds, [cs:curpsp] mov ah, [PSPAX+1]