cpu 8086 org 0x500 ;Jump to the code jmp start ;Interrupt handler ;Return to the shell int0x20: jmp shell ;Input and output int0x21: cmp ah, 0x0 je printstr cmp ah, 0x1 je readstr cmp ah, 0x2 je println cmp ah, 0x3 je readln iret ;Disk operations int0x22: cmp ah, 0x2 je loadf ;To do: savef iret ;System call includes %include "PRINTSTR.INC" %include "READSTR.INC" %include "PRINTLN.INC" %include "READLN.INC" %include "LOADF.INC" ;Set up the interrupt vectors ;Interrupt 0x20 offset start: mov ax, int0x20 mov [0x80], ax ;Interrupt 0x21 offset mov ax, int0x21 mov [0x84], ax ;Interrupt 0x22 offset mov ax, int0x22 mov [0x88], ax ;Segments mov ax, 0x0 mov [0x82], ax mov [0x86], ax mov [0x8a], ax ;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 mov ah, 0x2 int 0x21 shell: ;Re-set the stack cli mov sp, 0x0 sti ;Prompt for and read a command ;Print the current drive letter mov si, curdriveletter mov ah, 0x0 int 0x21 ;Print a prompt mov si, prompt mov ah, 0x0 int 0x21 ;Read mov di, input mov al, 0x4c mov ah, 0x3 int 0x21 ;Check for an empty command cmp byte [input], 0x0 jz shell ;Set SI at the command ;Set SI at input mov si, input ;Ignore leading spaces call ignoreleading ;Check for a current drive change command cmp byte [si + 0x1], ":" jne extract cmp byte [si + 0x2], 0x0 je changecurdrive cmp byte [si + 0x2], 0x20 je changecurdrive ;Extract the specification of the program file extract: ;Set DI at program mov di, program ;Initialise program with spaces mov cx, 0xe mov al, 0x20 rep stosb sub di, 0xe ;Set the length counter mov bl, 0xa ;Load a character specloop: lodsb ;Check for the string end cmp al, 0x0 je addext ;Check for a space cmp al, 0x20 je addext ;Check for the length limit cmp bl, 0x0 je cmderror ;Store the character stosb ;Decrease the counter dec bl ;Extract the next character jmp specloop ;Store the start of the command tail in the stack addext: push si ;Add extension to the specification mov si, extension mov cx, 0x5 rep movsb ;Load and execute the program ;Load the program mov bx, 0x3000 mov si, program mov ah, 0x2 int 0x22 ;Check for errors cmp al, 0x0 jne shell ;Pass the current drive and command tail to the program mov dl, [curdrive] pop si call ignoreleading ;Execute the program jmp 0x3000 ;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 changecurdrive: int 0x11 ;Get the number of floppy drives times 0x6 shr ax, 0x1 and ax, 0x3 inc ax ;Set the loop and drive letter counters and the drive letter and number mov cx, ax mov di, driveletters mov al, [si] mov dl, 0x0 ;Check which drive to change to checkdrive: cmp al, [di] je contchdrive inc di cmp al, [di] je contchdrive inc di inc dl loop checkdrive ;Print a drive error message and return to the shell mov si, driverrormsg mov ah, 0x2 int 0x21 jmp shell ;Change the drive contchdrive: mov [curdrive], dl call setcurdriveletter jmp shell ;Welcome message welcomemsg db 0xd, 0xa, "Welcome to EttinOS!", 0xd, 0xa, 0x0 ;Drive stuff curdrive db 0x0 driveletters db "AaBbCcDd" ;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 setcurdriveletter: ;Set the drive number and letter counters mov dh, 0x0 mov si, driveletters ;Check the drive number .checkdrive: cmp dl, dh je .set add si, 0x2 inc dh jmp .checkdrive ;Set the drive letter .set: mov al, [si] mov byte [curdriveletter], al ;Return ret ;*** ;Ignore leading spaces in the command and its tail ignoreleading: ;Check for a space lodsb cmp al, 0x20 je ignoreleading ;Set SI to the first non-space character dec si ;Return ret ;*** ;Print a CRLF printcrlf: ;Store SI in the stack push si ;Print the CRLF mov si, .crlf mov ah, 0x0 int 0x21 ;Load SI from the stack pop si ;Return ret ;Data .crlf db 0xd, 0xa, 0x0 ;*** ;File system buffer buffer: