2023-02-01 20:42:05 -06:00
|
|
|
extern error_screen ; 80x50 words
|
|
|
|
|
|
|
|
; Switches to text mode and shit
|
|
|
|
extern error_environment
|
|
|
|
_fault_coda:
|
|
|
|
xchg bx,bx
|
|
|
|
mov ax, 0x10
|
|
|
|
mov es, ax
|
2023-02-02 18:15:14 -06:00
|
|
|
; move to 'safe' location
|
|
|
|
mov ebp, 0x318000
|
2023-02-07 23:53:13 -06:00
|
|
|
; copy stack a bit
|
|
|
|
mov ecx, 0
|
|
|
|
.copy:
|
|
|
|
mov eax, [esp+ecx*4]
|
|
|
|
mov [ebp+ecx*4], eax
|
|
|
|
inc ecx
|
|
|
|
cmp ecx, 6
|
|
|
|
jl .copy
|
2023-02-01 20:42:05 -06:00
|
|
|
mov esp, ebp
|
|
|
|
call error_environment
|
|
|
|
.hlt:
|
|
|
|
hlt
|
|
|
|
jmp .hlt
|
|
|
|
|
2023-02-04 18:51:09 -06:00
|
|
|
global _gpf_eax_save
|
|
|
|
_gpf_eax_save: dd 0
|
2023-02-08 10:33:49 -06:00
|
|
|
global _gpf_eflags_save
|
|
|
|
_gpf_eflags_save: dd 0
|
2023-02-01 20:42:05 -06:00
|
|
|
extern gpf_handler_v86
|
|
|
|
global gpfHandler
|
|
|
|
gpfHandler:
|
2023-02-02 18:15:14 -06:00
|
|
|
cli ; make sure we're in a 'friendly' env
|
2023-02-01 20:42:05 -06:00
|
|
|
push eax
|
2023-02-02 00:50:16 -06:00
|
|
|
push ebx
|
2023-02-02 18:15:14 -06:00
|
|
|
push ecx
|
|
|
|
; save old ds
|
2023-02-02 00:50:16 -06:00
|
|
|
mov bx, ds
|
2023-02-01 20:42:05 -06:00
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
2023-02-02 00:50:16 -06:00
|
|
|
mov word [_gpf_old_ds], bx
|
2023-02-02 18:15:14 -06:00
|
|
|
; relocate stack so other interrupts don't fuck us over
|
|
|
|
; not sure if this is necessary, it doesn't seem to fix our race conditions...
|
|
|
|
mov ebx, esp
|
|
|
|
sub esp, 0x1000
|
|
|
|
xor ecx, ecx
|
|
|
|
.l:
|
|
|
|
mov eax, [ebx]
|
|
|
|
mov [esp+ecx], eax
|
|
|
|
add ebx, 4
|
|
|
|
add ecx, 4
|
|
|
|
cmp ebx, 0x320000 ; tss esp0
|
|
|
|
jl .l
|
|
|
|
pop ecx
|
2023-02-02 00:50:16 -06:00
|
|
|
pop ebx
|
2023-02-02 18:15:14 -06:00
|
|
|
sti ; we shouldn't crash now?
|
2023-02-01 20:42:05 -06:00
|
|
|
mov eax, dword [esp+16] ; EFLAGS
|
2023-02-08 10:33:49 -06:00
|
|
|
mov dword [_gpf_eflags_save], eax ; save
|
2023-02-01 20:42:05 -06:00
|
|
|
and eax, 1 << 17 ; VM flag
|
|
|
|
test eax, eax
|
|
|
|
pop eax
|
2023-02-07 23:53:13 -06:00
|
|
|
mov dword [_gpf_eax_save], eax
|
2023-02-01 20:42:05 -06:00
|
|
|
jnz gpf_handler_v86
|
|
|
|
jmp gpf_handler_32
|
|
|
|
gpf_unhandled:
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | 'G' | 'P' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
|
2023-02-02 21:40:39 -06:00
|
|
|
xchg bx,bx
|
2023-02-01 20:42:05 -06:00
|
|
|
jmp _fault_coda
|
|
|
|
|
2023-02-02 00:50:16 -06:00
|
|
|
_gpf_old_ds: dw 0
|
|
|
|
extern get_key
|
2023-02-06 05:49:03 -06:00
|
|
|
extern get_scancode
|
2024-01-07 22:33:27 -06:00
|
|
|
extern get_key_no_wait
|
|
|
|
extern get_scancode_no_wait
|
2023-02-02 00:50:16 -06:00
|
|
|
extern task_ptr
|
|
|
|
extern _enter_v86_internal_no_task
|
|
|
|
extern return_prev_task
|
2023-02-06 02:27:33 -06:00
|
|
|
extern v86Interrupt
|
2024-01-07 22:33:27 -06:00
|
|
|
extern TIMERVAL
|
2023-02-01 20:42:05 -06:00
|
|
|
gpf_handler_32:
|
|
|
|
push eax
|
|
|
|
mov eax, dword [esp+8] ; EIP
|
|
|
|
movzx eax, word [eax]
|
|
|
|
cmp eax, 0x30CD ; int 0x30
|
2023-02-02 00:50:16 -06:00
|
|
|
je .int30
|
|
|
|
cmp eax, 0x21CD ; int 0x21
|
|
|
|
je .int21
|
|
|
|
jmp gpf_unhandled
|
2023-02-17 01:41:30 -06:00
|
|
|
|
2023-02-02 00:50:16 -06:00
|
|
|
.int21:
|
|
|
|
pop eax ; command
|
|
|
|
cmp al, 0x00 ; get key
|
|
|
|
jne .s1
|
|
|
|
call get_key
|
|
|
|
jmp .return_to_offender
|
2023-02-06 05:49:03 -06:00
|
|
|
.s1: cmp al, 0x01 ; get scancode
|
2024-01-07 22:33:27 -06:00
|
|
|
jne .s2
|
2023-02-06 05:49:03 -06:00
|
|
|
call get_scancode
|
|
|
|
jmp .return_to_offender
|
2024-01-07 22:33:27 -06:00
|
|
|
.s2: cmp al, 0x02 ; get key no wait
|
|
|
|
jne .s3
|
|
|
|
call get_key_no_wait
|
|
|
|
jmp .return_to_offender
|
|
|
|
.s3: cmp al, 0x03 ; get scancode no wait
|
|
|
|
jne .s4
|
|
|
|
call get_scancode_no_wait
|
|
|
|
jmp .return_to_offender
|
|
|
|
.s4: cmp al, 0x04 ; get timer
|
|
|
|
jne .s5
|
|
|
|
mov eax, dword [TIMERVAL]
|
|
|
|
jmp .return_to_offender
|
|
|
|
.s5: cmp al, 0x05 ; short wait (hlt)
|
|
|
|
jne .s86
|
|
|
|
hlt
|
|
|
|
jmp .return_to_offender
|
2023-02-06 05:49:03 -06:00
|
|
|
.s86: cmp al, 0x86 ; v86 interrupt call
|
2023-02-17 01:41:30 -06:00
|
|
|
je .v86int
|
|
|
|
cmp ax, 0x86D8 ; get v86 data pointer
|
2023-02-02 00:50:16 -06:00
|
|
|
jne .return_to_offender
|
2023-02-17 01:41:30 -06:00
|
|
|
mov eax, 0x30000 ; V86 Data
|
|
|
|
jmp .return_to_offender
|
|
|
|
|
|
|
|
.v86int:
|
2023-02-02 01:34:49 -06:00
|
|
|
add esp, 4
|
|
|
|
add dword [esp+0], 2
|
2023-02-02 00:50:16 -06:00
|
|
|
; add a new task
|
|
|
|
call _gpf_create_return_task
|
|
|
|
; now enter v86 mode
|
2023-02-06 02:27:33 -06:00
|
|
|
; get int & regs from return stack
|
2023-02-02 14:52:26 -06:00
|
|
|
mov eax, [esp+12] ; return esp
|
2023-02-06 02:27:33 -06:00
|
|
|
mov eax, [eax] ; interrupt
|
|
|
|
and eax, 0xff ; ensure 1 byte
|
|
|
|
shl eax, 8
|
|
|
|
or eax, 0x30CD00CD ; command
|
|
|
|
mov dword [v86Interrupt], eax
|
|
|
|
mov eax, [esp+12] ; return esp
|
|
|
|
mov eax, [eax+4] ; regs
|
2023-02-02 14:52:26 -06:00
|
|
|
push eax ; regs
|
2023-02-06 02:27:33 -06:00
|
|
|
mov eax, v86Interrupt
|
2023-02-02 00:50:16 -06:00
|
|
|
and eax, 0xffff
|
|
|
|
push eax ; ip
|
2023-02-06 02:27:33 -06:00
|
|
|
mov eax, v86Interrupt
|
2023-02-02 14:52:26 -06:00
|
|
|
shr eax, 4
|
|
|
|
and eax, 0xf000
|
2023-02-02 00:50:16 -06:00
|
|
|
push eax ; cs
|
|
|
|
push 0xFF00 ; sp
|
|
|
|
push 0x8000 ; ss
|
|
|
|
jmp _enter_v86_internal_no_task ; NOT a function call
|
2023-02-17 01:41:30 -06:00
|
|
|
|
2023-02-02 00:50:16 -06:00
|
|
|
.int30:
|
2023-02-01 20:42:05 -06:00
|
|
|
pop eax ; return value
|
|
|
|
jmp return_prev_task
|
2023-02-02 00:50:16 -06:00
|
|
|
.return_to_offender:
|
|
|
|
add dword [esp+4], 2
|
|
|
|
push eax
|
|
|
|
mov ax, word [_gpf_old_ds]
|
|
|
|
mov ds, ax
|
|
|
|
pop eax
|
|
|
|
add esp, 4 ; error code
|
|
|
|
iret
|
|
|
|
|
|
|
|
_gpf_create_return_task:
|
|
|
|
; handler stack stored in edx
|
|
|
|
mov edx, esp
|
|
|
|
mov esp, dword [task_ptr]
|
|
|
|
mov eax, [edx+20] ; ss
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+16] ; esp
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+12] ; eflags
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+8] ; cs
|
|
|
|
push eax
|
|
|
|
mov eax, [edx+4] ; eip
|
|
|
|
push eax
|
|
|
|
mov ax, word [_gpf_old_ds] ; restore old ds
|
|
|
|
mov ds, ax
|
|
|
|
push ds
|
|
|
|
push es
|
|
|
|
push fs
|
|
|
|
push gs
|
|
|
|
push ebp
|
|
|
|
push ebx
|
|
|
|
push esi
|
|
|
|
push edi
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [task_ptr], esp ; save new task pointer
|
|
|
|
mov esp, edx ; restore handler stack
|
|
|
|
ret
|
|
|
|
|
|
|
|
global unhandled_handler
|
|
|
|
unhandled_handler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | 'E' | 'R' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'R' | 'O' << 16
|
|
|
|
mov dword [error_screen+0x08], 0x0f000f00 | 'R' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
|
|
|
|
global pageFaultHandler
|
|
|
|
pageFaultHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
pop eax ; error code
|
|
|
|
mov ebx, 0x0f000f00 | '0' | '!' << 16
|
|
|
|
and eax, 0x7 ; U/S,R/W,P
|
|
|
|
add ebx, eax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | 'P' | 'G' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | 'L' << 16
|
|
|
|
mov dword [error_screen+0x08], 0x0f000f00 | 'T' | ':' << 16
|
|
|
|
mov dword [error_screen+0x0C], ebx
|
|
|
|
jmp _fault_coda
|
2023-02-01 20:42:05 -06:00
|
|
|
|
|
|
|
|
|
|
|
global divisionErrorHandler
|
|
|
|
divisionErrorHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'D' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'E' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global boundRangeHandler
|
|
|
|
boundRangeHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'B' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'R' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global invalidOpcodeHandler
|
|
|
|
invalidOpcodeHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'U' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'D' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global deviceNotAvailableHandler
|
|
|
|
deviceNotAvailableHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'N' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'D' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global doubleFaultHandler
|
|
|
|
doubleFaultHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [0xb8000+0x00], 0x0f000f00 | '#' | 'D' << 16
|
|
|
|
mov dword [0xb8000+0x04], 0x0f000f00 | 'F' | '!' << 16
|
|
|
|
; double faults simply abort right then
|
|
|
|
.hlt: hlt
|
|
|
|
jmp .hlt
|
|
|
|
global invalidTSSHandler
|
|
|
|
invalidTSSHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'T' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'S' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global segmentNotPresentHandler
|
|
|
|
segmentNotPresentHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'N' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'P' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global stackSegmentHandler
|
|
|
|
stackSegmentHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'S' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'S' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global x87FloatingHandler
|
|
|
|
x87FloatingHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'M' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global alignmentCheckHandler
|
|
|
|
alignmentCheckHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'A' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'C' | '!' << 16
|
|
|
|
jmp _fault_coda
|
|
|
|
global controlProtectionHandler
|
|
|
|
controlProtectionHandler:
|
|
|
|
mov ax, 0x10
|
|
|
|
mov ds, ax
|
|
|
|
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'C' << 16
|
|
|
|
mov dword [error_screen+0x04], 0x0f000f00 | 'P' | '!' << 16
|
|
|
|
jmp _fault_coda
|