From f7d7f48026d7cb0ce7801ab2ffee6ed424bce45a Mon Sep 17 00:00:00 2001 From: Nero <41307858+nero@users.noreply.github.com> Date: Sat, 1 Jan 2022 21:22:37 +0000 Subject: [PATCH] Implement syscall interface and version data --- src/@rdos.asm | 145 +++++++++++++++++++++++++----------------------- src/farptr.inc | 46 --------------- src/version.inc | 2 + 3 files changed, 79 insertions(+), 114 deletions(-) delete mode 100644 src/farptr.inc create mode 100644 src/version.inc diff --git a/src/@rdos.asm b/src/@rdos.asm index cd96907..0afc174 100644 --- a/src/@rdos.asm +++ b/src/@rdos.asm @@ -1,6 +1,21 @@ org 0x700 cseg equ 0x0 - jmp init + +%include "version.inc" + + jmp _entry +banner db "RDOS KERNEL 1.0", 0x0A, 0x0D, '$', 0x1A +_entry call .l01 +.l01 pop ax + sub ax, .l01 + mov cl, 4 + shr ax, cl + mov cx, cs + add cx, ax + push cx + mov ax, start + push ax + retf ;;; Character I/O @@ -138,10 +153,15 @@ gets mov si, dx call putc ret +;;; System functions + + ; Return OS version from version.inc +ver mov bx, bdosver | 0x1000 + ret + ;;; Disk i/o %include "bpb.inc" -%include "farptr.inc" ; dflags bitfields DRVLOG equ 0x01 ; bit 0 - drive logged in (see drvnum) @@ -150,23 +170,8 @@ DRVEXT equ 0x04 ; bit 2 - EBIOS supported DIRTY equ 0x08 ; bit 3 - dskbuf dirty DRVCHS equ 0x10 ; bit 4 - CHS geometry known - align 16 - ; IBM Interrupt Sharing Protocol structure -i13isp jmp short int13i - dw 0,0xFFFF - dw 0x424B - db 0 - iret - align 16 - - ; Entry point when user program calls int13h - ; TODO: flush buffer and log out drive -int13i call int13 - iret - ; Wrapper around int 13h -int13 pushf - call far [i13isp+2] +int13 int 0x13 ; TODO: on error: reset & retry ; TODO: record errors ; TODO: multi-track reading @@ -209,10 +214,10 @@ getprm test byte [dflags], DRVEXT test ax, ax jz .ret ; copy BIOS dpt table over ours - mov dx, dpt - mov bx, di - mov cx, 11 - call lodfar + ;mov dx, dpt + ;mov bx, di + ;mov cx, 11 + ;call lodfar .ret ret ; select a drive for io @@ -379,14 +384,13 @@ flush test word [cs:dflags], DIRTY ; Sector number is read from [drvseek] diskio mov cl, 1 ; read len ; DS := ES := CS - call rstseg + mov ds, [cs:dseg] ; check if ebios supported test word [dflags], DRVEXT jz .noext ; set up regs for ebios call - mov ax, cx + xchg ax, cx or ah, 0x40 - mov si, dap jmp .do ; check if we can skip controller reset .noext test word [dflags], DRVCTL @@ -419,15 +423,19 @@ diskio mov cl, 1 ; read len ; shuffle values around for bios xchg ax, cx xchg dh, dl - mov bx, dskbuf .do mov dl, [biosnum] ; ah: subfunction selected via cx previously ; al: 1 = reading 1 sector ; cx: sector and cylinder number ; dh: head number ; dl: drive number - ; bx: offset to disk buffer + push es + push si + mov si, dap + les bx, [si+4] call int13 + pop si + pop es jc .err ; clear dirty flag on success and word [dflags], ~DIRTY @@ -439,39 +447,6 @@ diskio mov cl, 1 ; read len stc ret -init mov ax, cs - ; boot failure if loaded wrong - cmp ax, cseg - je $+4 - int 0x18 - call rstseg - ; fetch current DPT - les bx, [4*0x1E] - mov dx, dpt - mov cx, 11 - call lodfar - ; set interrupt vector - mov word [4*0x1E], dpt - mov word [4*0x1E+2], ds - ; save int 13 handler - les bx, [4*0x13] - mov [i13isp+2], bx - mov [i13isp+4], es - ; install ours - mov word [4*0x13], int13i - mov [4*0x13+2], cs - - ; install int21h handler - mov word [4*0x21], int21h - mov [4*0x21+2], cs - - mov dl, 0x36 - mov ah, 2 - int 0x21 - -halt hlt - jmp halt - ;;; Export functions as syscalls ; SP, BP, SI, DI and ES must be preserved by kernel code ; DL, DX or DS:DX is input argument from prog @@ -494,7 +469,9 @@ intE0h push bx ; bx = syscall number ; stack must be -> BX IP CS FL ; for return to prog -sysc add bx, bx +sysc sti + cld + add bx, bx mov bx, [cs:bx+stab] test bh, srw >> 8 ; fork off bx returns jnz .l02 @@ -537,6 +514,38 @@ sysc add bx, bx pop dx ret +start xor ax, ax + mov ds, ax + + ; install int20h handler + mov word [4*0x20], start + mov [4*0x20+2], cs + ; install int21h handler + mov word [4*0x21], int21h + mov [4*0x21+2], cs + ; install intE0h handler + mov word [4*0xE0], intE0h + mov [4*0xE0+2], cs + + mov ax, cs + mov ds, ax + mov [dseg], ax + + ; print banner + mov dx, banner + call puts + + ; read cmdline + mov dl, '>' + call putc + mov dx, inbuf + mov byte [inbuf], 72 + call gets + +halt sti + hlt + jmp halt + section .rodata ; syscall table @@ -549,10 +558,10 @@ stab dw 0 ; 0 reboot dw 0 ; 6 direct console i/o dw 0 ; 7 read i/o byte dw 0 ; 8 get i/o byte - dw 0 ; 9 string output - dw 0 ; 10 string input + dw puts ; 9 string output + dw gets ; 10 string input dw 0 ; 11 console status - dw 0 ; 12 get version number + dw ver ; 12 get version number dw 0 ; 13 reset disks dw 0 ; 14 set drive dw 0 ; 15 open file @@ -587,7 +596,8 @@ section .data dap db 0x10, 0 dw 1 - dw dskbuf, cseg + dw dskbuf +dseg dw 0 drvseek dw 0,0,0,0 ; bit 0 (1) - drive logged in (see drvnum) @@ -603,9 +613,6 @@ drvnum resb 1 ; number, just for bios biosnum resb 1 - ; DPT tables for 4 floppy drives -dpt resb 4*14 - ; Information for logged in drive drvss resb 1 ; sector size, 2^(7+n) bytes drvcs resb 1 ; cluster size, 2^(7+n) bytes @@ -622,3 +629,5 @@ drvfn resb 2 ; sectors per fat table ; disk buffer for I/O operations alignb 2 dskbuf resb 1024 + +inbuf resb 128 diff --git a/src/farptr.inc b/src/farptr.inc deleted file mode 100644 index b98729c..0000000 --- a/src/farptr.inc +++ /dev/null @@ -1,46 +0,0 @@ - ; 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 swpds - mov si, bx - mov di, dx - rep movsb - - ; exchange es and ds -swpds push ds - push es - pop ds - pop es - ret - - ; normalize ptr in ds:dx -norm mov ax, ds - mov cl, 4 - push dx - ror dx, cl - and dh, 0xF - add ax, dx - mov ds, ax - pop dx - and dx, 0xF - ret diff --git a/src/version.inc b/src/version.inc new file mode 100644 index 0000000..9378088 --- /dev/null +++ b/src/version.inc @@ -0,0 +1,2 @@ +bdosver equ 0x10 ; CP/M 1.0 +bdosrev equ 0