diff --git a/README.MD b/README.MD index 8f852cd..74bb71e 100644 --- a/README.MD +++ b/README.MD @@ -1,9 +1,9 @@ EttinOS ======= -EttinOS is a minimalist 16-bit DOS-like hobbyist operating system for -the IBM Personal Computer and compatible machines. Its git repository -can be found at https://ahti.space/git/crazyettin/EttinOS and that of +EttinOS is a minimalist 16-bit hobbyist disk operating system for the +IBM Personal Computer and compatible machines. Its git repository can be +found at https://ahti.space/git/crazyettin/EttinOS and that of EttinOS-extra, a collection of programs for the system, at https://ahti.space/git/crazyettin/EttinOS-extra. @@ -39,13 +39,11 @@ The input system is inspired by typewriters. Typing a character overwrites the cursor location and the erase (=tab) key erases it. The space and backspace keys move the cursor. -EttinOS assigns the drives letters from A to D and uses the FAT12 file -system. The hidden and total sectors entries of the BIOS parameter -block, the entire extended BIOS parameter block, file attributes, and -the file access date are not supported and are ignored if present: as a -result disk labels and subdirectories are not supported. Drive letters -and file names are case-insensitive and the latter follow the 8.3 -format. Text files use CRLF line endings. +EttinOS assigns the drives letters from A to D and uses a version of the +MS-DOS 3.0 FAT12 file system (in actual use since 2.1) without support +for file attributes and thus disk labels and subdirectories. Drive +letters and file names are case-insensitive and the latter follow the +8.3 format. Text files use CRLF line endings. Drives and files are specified as ([A-D]:) and ([A-D]:)FILENAME.EXT respectively. Specifying the current drive, indicated in the prompt, is @@ -53,11 +51,11 @@ optional. A command can be followed by arguments separated from eachother and the command with spaces. Extra spaces are ignored. Commands other than -changing the drive are stored as external programs: the command for a -program is its file specification without the extension. +changing the current drive are stored as external programs: the command +for a program is its file specification without the extension. Commands included in EttinOS: - * [A-D]:: Change the drive. + * [A-D]:: Change the current drive. * ECHO: Print a message. Syntax: ECHO Message to be printed * HELLO: Print "Hello world!". * LIST: Print a list of the files on a drive. Syntax: LIST DRIVE @@ -80,7 +78,7 @@ has finished running. System calls: * Interrupt 0x20: Return to the shell. - * Interrupt 0x21: Input and output: + * Interrupt 0x21: String operations: * AH = 0x0: Print a string ending in a null from SI. * AH = 0x1: Read a string ending in a null of at most AL characters to DI until a return. @@ -88,8 +86,25 @@ System calls: CRLF. * AH = 0x3: Read a string ending in a null of at most AL characters to DI until a return and print a CRLF. + * AH = 0x4: (Under construction) Convert a decimal string ending + in a null at SI to a value in AL. + * AH = 0x5: (Under construction) Convert a value in AL to a + decimal string ending in a null at DI. + * AH = 0x6: (Under construction) Convert a hexadecimal string + ending in a null at SI to a value in AL. + * AH = 0x7: (Under construction) Convert a value in AL to a + hexadecimal string ending in a null at DI. * Interrupt 0x22: Disk operations: - * AH = 0x0: Load a file named at SI as a string ending in a null + * AH = 0x0: (Under construction) Load the directory of a drive + named at SI as a string ending in a null to the offset + BX and store the error codes in AL: + * AL = 0x0: Succesful load + * AL = 0x1: Drive not found + * AL = 0x2: Unable to read disk + * AH = 0x1: (Under construction) Store a directory at the offset + BX to a drive named at SI as a string ending in a + null. + * AH = 0x2: Load a file named at SI as a string ending in a null to the offset BX and store the file size in CX and the error codes in AL: * AL = 0x0: Succesful load @@ -97,7 +112,7 @@ System calls: * AL = 0x2: Unable to read disk * AL = 0x4: File or command not found * AL = 0x8: Not enough memory - * AH = 0x1: Save a file (under construction). + * AH = 0x3: (Under construction) Save a file. Known bugs ---------- diff --git a/src/BOOT.ASM b/src/BOOT.ASM index 3b112e3..e6f8532 100644 --- a/src/BOOT.ASM +++ b/src/BOOT.ASM @@ -23,6 +23,7 @@ mediadescriptor db 0xf0 sectorsperfat dw 0x9 sectorspertrack dw 0x12 heads dw 0x2 +hiddensectors dw 0x0 %else @@ -37,10 +38,10 @@ mediadescriptor db 0xfd sectorsperfat dw 0x2 sectorspertrack dw 0x9 heads dw 0x2 +hiddensectors dw 0x0 %endif - ;Setup ;Set the segments start: diff --git a/src/LOADF.INC b/src/LOADF.INC index 83aabe0..b7af675 100644 --- a/src/LOADF.INC +++ b/src/LOADF.INC @@ -16,8 +16,8 @@ push di ;Store the current drive and offset mov word [.pointer], bx -mov dl, byte [drive] -mov byte [.drive], dl +mov dl, byte [curdrive] +mov byte [drive], dl ;Change the drive if needed ;Check for a drive specification @@ -53,7 +53,7 @@ mov cx, 0x0 jmp .done ;Change the drive .contchdrive: -mov [.drive], dl +mov [drive], dl ;Move to the file name add si, 0x2 @@ -112,7 +112,7 @@ pop ax ;Load the disk description table ;Set the source -mov dl, [.drive] +mov dl, [drive] mov ch, 0x0 mov dh, 0x0 mov cl, 0x1 @@ -136,48 +136,48 @@ jmp .done ;Store the disk values used for the rest of the call .storevalues: mov ax, [buffer + 0xb] -mov [.sectorsize], ax +mov [sectorsize], ax mov al, [buffer + 0xd] -mov [.clustersize], al +mov [clustersize], al mov ax, [buffer + 0xe] -mov [.reservedsectors], ax +mov [reservedsectors], ax mov al, [buffer + 0x10] -mov [.fats], al +mov [fats], al mov ax, [buffer + 0x11] -mov [.rootentries], ax +mov [rootentries], ax mov ax, [buffer + 0x16] -mov [.sectorsperfat], ax +mov [sectorsperfat], ax mov ax, [buffer + 0x18] -mov [.sectorspertrack], ax +mov [sectorspertrack], ax mov ax, [buffer + 0x1a] -mov [.heads], ax +mov [heads], ax ;Calculate and store variables not found in the BPB ;Start of the root mov ah, 0x0 -mov al, [.fats] -mul word [.sectorsperfat] -add ax, [.reservedsectors] -mov [.rootstart], ax +mov al, [fats] +mul word [sectorsperfat] +add ax, [reservedsectors] +mov [rootstart], ax ;Size of the root in sectors -mov ax, [.rootentries] +mov ax, [rootentries] mov dx, 0x20 mul dx mov dx, 0x0 -div word [.sectorsize] -mov [.rootsectors], ax +div word [sectorsize] +mov [rootsectors], ax ;Start of data -add ax, [.rootstart] -mov [.datastart], ax +add ax, [rootstart] +mov [datastart], ax ;Load the root ;Set the source -mov ax, [.rootstart] +mov ax, [rootstart] ;Set the destination mov si, buffer mov bx, si ;Set the size -mov cx, [.rootsectors] +mov cx, [rootsectors] ;Store the source and the loop counter in the stack .loadrootsector: push ax @@ -194,7 +194,7 @@ pop cx pop ax ;Set the next sector add ax, 0x1 -add bx, word [.sectorsize] +add bx, word [sectorsize] ;Load the next sector loop .loadrootsector @@ -202,7 +202,7 @@ loop .loadrootsector ;Set DI to the root mov di, buffer ;Set the number of root entries -mov cx, word [.rootentries] +mov cx, word [rootentries] ;Set the entry pointer mov ax, 0x0 ;Store the loop counter in the stack @@ -238,8 +238,8 @@ cmp word [di + 0x13], 0x0 jne .sizerror ;Get the cluster size in bytes mov ah, 0x0 -mov al, [.clustersize] -mul word [.sectorsize] +mov al, [clustersize] +mul word [sectorsize] mov bx, ax ;Store the file size mov ax, [di + 0x11] @@ -267,12 +267,12 @@ jmp .done mov ax, [di + 0xf] mov [.cluster], ax ;Set the source -mov ax, [.reservedsectors] +mov ax, [reservedsectors] call .calcsource ;Set the destination mov bx, buffer ;Set the size -mov ax, [.sectorsperfat] +mov ax, [sectorsperfat] ;Load the FAT mov ah, 0x2 int 0x13 @@ -282,13 +282,13 @@ int 0x13 ;Set the source mov ax, word [.cluster] sub ax, 0x2 -mul byte [.clustersize] -add ax, [.datastart] +mul byte [clustersize] +add ax, [datastart] ;Set the destination mov bx, word [.pointer] ;Set the size mov ch, 0x0 -mov cl, byte [.clustersize] +mov cl, byte [clustersize] ;Store the loop counter in the stack .loadsector: push cx @@ -303,7 +303,7 @@ int 0x13 pop ax ;Set the next sector add ax, 0x1 -add bx, word [.sectorsize] +add bx, word [sectorsize] ;Load the loop counter from the stack pop cx ;Load the next sector @@ -335,8 +335,8 @@ jge .success ;Store the address of the next cluster mov word [.cluster], ax ;Set the destination of the next cluster -mov ax, [.sectorsize] -mul word [.clustersize] +mov ax, [sectorsize] +mul word [clustersize] add word [.pointer], ax ;Load the next cluster jmp .loadcluster @@ -362,18 +362,6 @@ mov ah, 0x0 iret ;Data -.drive db 0x0 -.sectorsize dw 0x0 ;bytes -.clustersize db 0x0 ;sectors -.reservedsectors dw 0x0 -.fats db 0x0 -.rootentries dw 0x0 -.sectorsperfat dw 0x0 -.sectorspertrack dw 0x0 -.heads dw 0x0 -.rootstart dw 0x0 -.rootsectors dw 0x0 -.datastart dw 0x0 .file times 0xb db 0x20 .size dw 0x0 .cluster dw 0x0 @@ -454,21 +442,21 @@ push bx mov bx, ax ;Calculate the sector mov dx, 0x0 -div word [.sectorspertrack] +div word [sectorspertrack] add dl, 0x1 mov cl, dl ;Load the logical sector from BX mov ax, bx ;Calculate the head and cylinder mov dx, 0x0 -div word [.sectorspertrack] +div word [sectorspertrack] mov dx, 0x0 -div word [.heads] +div word [heads] mov dh, dl ;Head mov ch, al ;Cylinder ;Load the drive number -mov dl, byte [.drive] +mov dl, byte [drive] ;Load BX and AX from the stack pop bx diff --git a/src/PRINT.ASM b/src/PRINT.ASM index 7e571b2..11586da 100644 --- a/src/PRINT.ASM +++ b/src/PRINT.ASM @@ -40,7 +40,7 @@ stosb ;Load load: mov bx, stack + 0x100 -mov ah, 0x0 +mov ah, 0x2 int 0x22 ;Check for errors cmp al, 0x0 diff --git a/src/SYSTEM.ASM b/src/SYSTEM.ASM index 22079c1..b5e52b0 100644 --- a/src/SYSTEM.ASM +++ b/src/SYSTEM.ASM @@ -21,7 +21,7 @@ je readln iret ;Disk operations int0x22: -cmp ah, 0x0 +cmp ah, 0x2 je loadf ;To do: savef iret @@ -50,9 +50,10 @@ mov [0x82], ax mov [0x86], ax mov [0x8a], ax -;Store the boot drive number and set the drive letter -mov [drive], dl -call setdriveletter +;Store the boot drive number as the current drive and set the current +;drive letter +mov [curdrive], dl +call setcurdriveletter ;Print a welcome message mov si, welcomemsg @@ -67,8 +68,8 @@ mov sp, 0x0 sti ;Prompt for and read a command -;Print the drive letter -mov si, driveletter +;Print the current drive letter +mov si, curdriveletter mov ah, 0x0 int 0x21 ;Print a prompt @@ -85,26 +86,24 @@ int 0x21 cmp byte [input], 0x0 jz shell -;Check for a drive change command +;Set SI at the command ;Set SI at input mov si, input ;Ignore leading spaces call ignoreleading -;Check + +;Check for a current drive change command cmp byte [si + 0x1], ":" jne extract cmp byte [si + 0x2], 0x0 -je changedrive +je changecurdrive cmp byte [si + 0x2], 0x20 -je changedrive +je changecurdrive ;Extract the specification of the program file extract: -;Set SI at input and DI at program -mov si, input +;Set DI at program mov di, program -;Ignore leading spaces -call ignoreleading ;Initialise program with spaces mov cx, 0xe mov al, 0x20 @@ -142,21 +141,28 @@ rep movsb ;Load the program mov bx, 0x3000 mov si, program -mov ah, 0x0 +mov ah, 0x2 int 0x22 ;Check for errors cmp al, 0x0 jne shell -;Pass the drive and command tail to the program -mov dl, [drive] +;Pass the current drive and command tail to the program +mov dl, [curdrive] pop si call ignoreleading ;Execute the program jmp 0x3000 -;Change the drive +;Print a command error message and return to the shell +cmderror: +mov si, cmderrormsg +mov ah, 0x2 +int 0x21 +jmp shell + +;Change the current drive ;Get the BIOS equipment list -changedrive: +changecurdrive: int 0x11 ;Get the number of floppy drives times 0x6 shr ax, 0x1 @@ -184,33 +190,44 @@ int 0x21 jmp shell ;Change the drive contchdrive: -mov [drive], dl -call setdriveletter +mov [curdrive], dl +call setcurdriveletter jmp shell -;Print a command error message and return to the shell -cmderror: -mov si, cmderrormsg -mov ah, 0x2 -int 0x21 -jmp shell +;Welcome message +welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0 -;Data -welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0 -drive db 0x0 -driveletter db "?:", 0x0 +;Drive stuff +curdrive db 0x0 driveletters db "AaBbCcDd" -prompt db "> ", 0x0 -input times 0x4c db 0x0 -program times 0xf db 0x0 -extension db ".BIN", 0x0 -cmderrormsg db "File or command not found", 0x0 -driverrormsg db "Drive not found", 0x0 + +;Shell +curdriveletter db "?:", 0x0 +prompt db "> ", 0x0 +input times 0x4c db 0x0 +program times 0xf db 0x0 +extension db ".BIN", 0x0 +cmderrormsg db "File or command not found", 0x0 +driverrormsg db "Drive not found", 0x0 + +;Disk parameters +drive db 0x0 +sectorsize dw 0x0 ;bytes +clustersize db 0x0 ;sectors +reservedsectors dw 0x0 +fats db 0x0 +rootentries dw 0x0 +sectorsperfat dw 0x0 +sectorspertrack dw 0x0 +heads dw 0x0 +rootstart dw 0x0 +rootsectors dw 0x0 +datastart dw 0x0 ;*** ;Set the drive letter -setdriveletter: +setcurdriveletter: ;Set the drive number and letter counters mov dh, 0x0 @@ -227,7 +244,7 @@ jmp .checkdrive ;Set the drive letter .set: mov al, [si] -mov byte [driveletter], al +mov byte [curdriveletter], al ;Return ret