; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. TrapHandlers.prolog: nul ebp ; eax = caller's cr1 call RFS.LoadReg, nx2, $cr1 ; we don't preserve the nx0 we got mov nx0, eax nul edx jmp ecx TrapHandlers.epilog: ; TRAP return values: eax-edx mov ax2, eax call RFS.StoreReg, nx2, $eax mov ax2, edx call RFS.StoreReg, nx2, $edx call IDT.DoneHandling, nx1 iret ; ; TRAP #0 handler ; DefaultTrapHandler: .init: mov ecx, .text mov esp, TRAP0_STACK jmp TrapHandlers.prolog .text: call RFS.LoadReg, nx2, $eax call RFS.LoadArgs, nx2 ; will be optimized with a table ; when we have a "finished" consistent API jraxz .handle_Shutdown beq eax, Sys.Exit, .handle_Exit beq eax, Sys.ExecuteInFrame, .handle_EIF beq eax, Sys.ReadFile, .handle_ReadFile beq eax, Sys.OpenFile, .handle_OpenFile beq eax, Sys.CloseFile, .handle_CloseFile beq eax, Sys.CreateFile, .handle_CreateFile beq eax, Sys.RemoveFile, .handle_RemoveFile beq eax, Sys.FindNext, .handle_FindNext beq eax, Sys.FindFirst, .handle_FindFirst beq eax, Sys.EnterHaltMode, .handle_HaltMode .sod: call ScreenOfDeath, .badsyscall, nx1 .wrong: call ScreenOfDeath, .badparams, nx1 .fini.savecx: mov ax2, ecx call RFS.StoreReg, nx2, $ecx .fini: jmp TrapHandlers.epilog .badsyscall = "Invalid syscall number in eax" .badparams = "Invalid syscall parameters" ;------------------------------------------------; ; Syscall implementations ; ;------------------------------------------------; ; ; Pass control to COMMAND.COM in frame 0 ; .handle_Exit: ; deactivate current rframe bzr nx2, .hE_nz ; unless it's 0... call RFS.DeactivateFrame, nx2 .hE_nz: ; open COMMAND.COM call DISK.OpenFile, .cmdcom ; crash on failure bltz eax, abort ; load at CMDCOM_LOADP mov ax1, CMDCOM_LOADP mov ax2, CMDCOM_MAXSZ call DISK.ReadFile, eax ; assume that COMMAND.COM being ; less then 4KB means something ; went wrong blt eax, 0x1000, abort ; close the handle call DISK.CloseFile, eax ; code address mov ax2, 0x100000 call RFS.StoreReg, zero, $eip ; usermode mov ax2, 3 call RFS.StoreReg, zero, $cr0 mov ecx, CMDCOM_LOADP sub ecx, 0x100000 ; code offset mov ax2, ecx call RFS.StoreReg, zero, $cr1 ; return frame nul nx2 jmp .fini .cmdcom = "command.com" .handle_EIF: blt ax1, 5, .wrong ; eip can't be <1MB mov ecx, 0x100000 blt ax0, ecx, .wrong ; add old CR1 add ax0, nx0 ; real eip can't be <1MB+32KB either ; (kernel + cmdcom personal space) add edx, ecx, 0x8000 blt ax0, ecx, .wrong ; save rframe and compute new CR1 mov ebx, ax1 sub edi, ax0, ecx ; activate rframe call RFS.ActivateFrame, ebx ; save new CR1 mov ax2, edi call RFS.StoreReg, ebx, $cr1 ; interruptible user mode mov ax2, 3 call RFS.StoreReg, ebx, $cr0 ; set eip = 1MB mov ax2, ecx call RFS.StoreReg, ebx, $eip ; change return frame mov nx2, ebx jmp .fini ; ; Disk API ; .handle_FindFirst: add ax0, nx0 call DISK.FindFirst jmp .fini.savecx .handle_FindNext: add ax0, nx0 call DISK.FindNext jmp .fini.savecx .handle_OpenFile: add ax0, nx0 call DISK.OpenFile jmp .fini .handle_CreateFile: add ax0, nx0 call DISK.CreateFile jmp .fini .handle_RemoveFile: add ax0, nx0 call DISK.RemoveFile jmp .fini .handle_CloseFile: call DISK.CloseFile jmp .fini .handle_ReadFile: add ax1, nx0 call DISK.ReadFile jmp .fini ; ; Misc. ; .handle_Shutdown: call IDT.DelHandler, zero stop .handle_HaltMode: pause pause hlt jmp .handle_HaltMode