|
@@ -73,7 +73,6 @@
|
|
|
extern __SaveInt75
|
|
|
|
|
|
extern __fpu_status
|
|
|
- extern __fpu_control
|
|
|
|
|
|
extern FPC_HANDLE_I8086_ERROR
|
|
|
|
|
@@ -283,7 +282,8 @@ error_msg:
|
|
|
|
|
|
global FPC_INT00_HANDLER
|
|
|
FPC_INT00_HANDLER:
|
|
|
- sub sp, 4 ; reserve space on the stack for the retf
|
|
|
+ pushf
|
|
|
+ sub sp, 4 ; reserve space on the stack for the iret
|
|
|
|
|
|
push cx
|
|
|
push ds
|
|
@@ -310,7 +310,7 @@ FPC_INT00_HANDLER:
|
|
|
%ifndef __FAR_CODE__
|
|
|
; check whether we're coming from the same code segment
|
|
|
mov bp, sp
|
|
|
- mov cx, [bp + 3*2 + 6] ; get caller segment
|
|
|
+ mov cx, [bp + 3*2 + 6 + 2] ; get caller segment
|
|
|
mov bp, cs
|
|
|
cmp bp, cx
|
|
|
jne .call_previous_handler00
|
|
@@ -318,12 +318,12 @@ FPC_INT00_HANDLER:
|
|
|
|
|
|
; Call Fpc_Handle_I8086_Error, with err=0
|
|
|
mov bp, sp
|
|
|
- mov cx, [bp + 3*2 + 4] ; get caller offset
|
|
|
+ mov cx, [bp + 3*2 + 6] ; get caller offset
|
|
|
%ifdef __FAR_CODE__
|
|
|
- mov dx, [bp + 3*2 + 6] ; get caller segment
|
|
|
+ mov dx, [bp + 3*2 + 6 + 2] ; get caller segment
|
|
|
%endif
|
|
|
pop bp
|
|
|
- add sp, 2*2 + 4 + 6
|
|
|
+ add sp, 2*2 + 6 + 6
|
|
|
xor ax, ax
|
|
|
push ax
|
|
|
mov ax, 0
|
|
@@ -333,6 +333,7 @@ FPC_INT00_HANDLER:
|
|
|
%endif
|
|
|
push cx
|
|
|
cld
|
|
|
+ sti
|
|
|
%ifdef __FAR_CODE__
|
|
|
jmp far FPC_HANDLE_I8086_ERROR
|
|
|
%else
|
|
@@ -348,11 +349,12 @@ FPC_INT00_HANDLER:
|
|
|
pop bp
|
|
|
pop ds
|
|
|
pop cx
|
|
|
- retf ; jumps to the previous handler with all registers and stack intact
|
|
|
+ iret ; jumps to the previous handler with all registers and stack intact
|
|
|
|
|
|
global FPC_INT10_HANDLER
|
|
|
FPC_INT10_HANDLER:
|
|
|
- sub sp, 4 ; reserve space on the stack for the retf
|
|
|
+ pushf
|
|
|
+ sub sp, 4 ; reserve space on the stack for the iret
|
|
|
|
|
|
push cx
|
|
|
push ds
|
|
@@ -368,21 +370,8 @@ FPC_INT10_HANDLER:
|
|
|
%endif
|
|
|
mov ds, bp
|
|
|
; Check that an unmasked exception is indeed set
|
|
|
- ; First load FPU control register to __fpu_control
|
|
|
- fnstcw word [__fpu_control]
|
|
|
- ; Move control register value to bx register
|
|
|
- mov bx,word [__fpu_control]
|
|
|
- ; Now load status register to ax
|
|
|
fnstsw word [__fpu_status]
|
|
|
- ; Only the exception part is useful, clear other parts
|
|
|
- and bx,3fh
|
|
|
- ; at least one same bit must also be set in bx
|
|
|
- ; in that case with a bit set in status register
|
|
|
- ; which means an exception has been generated by the FPU
|
|
|
- ; and the exeception is not masked, as the same
|
|
|
- ; bit is set in control register
|
|
|
- mov ax,word [__fpu_status]
|
|
|
- and ax,bx
|
|
|
+ test byte [__fpu_status], 80h ; really just this bit is enough, see i8087 datasheet
|
|
|
je .call_previous_handler10
|
|
|
|
|
|
%ifdef __NEAR_DATA__
|
|
@@ -396,7 +385,7 @@ FPC_INT10_HANDLER:
|
|
|
%ifndef __FAR_CODE__
|
|
|
; check whether we're coming from the same code segment
|
|
|
mov bp, sp
|
|
|
- mov cx, [bp + 3*2 + 6] ; get caller segment
|
|
|
+ mov cx, [bp + 3*2 + 6 + 2] ; get caller segment
|
|
|
mov bp, cs
|
|
|
cmp bp, cx
|
|
|
jne .call_previous_handler10
|
|
@@ -404,12 +393,12 @@ FPC_INT10_HANDLER:
|
|
|
|
|
|
; Call Fpc_Handle_I8086_Error, with err=$10
|
|
|
mov bp, sp
|
|
|
- mov cx, [bp + 3*2 + 4] ; get caller offset
|
|
|
+ mov cx, [bp + 3*2 + 6] ; get caller offset
|
|
|
%ifdef __FAR_CODE__
|
|
|
- mov dx, [bp + 3*2 + 6] ; get caller segment
|
|
|
+ mov dx, [bp + 3*2 + 6 + 2] ; get caller segment
|
|
|
%endif
|
|
|
pop bp
|
|
|
- add sp, 2*2 + 4 + 6
|
|
|
+ add sp, 2*2 + 6 + 6
|
|
|
xor ax, ax
|
|
|
push ax
|
|
|
mov ax, 10h
|
|
@@ -419,6 +408,7 @@ FPC_INT10_HANDLER:
|
|
|
%endif
|
|
|
push cx
|
|
|
cld
|
|
|
+ sti
|
|
|
%ifdef __FAR_CODE__
|
|
|
jmp far FPC_HANDLE_I8086_ERROR
|
|
|
%else
|
|
@@ -434,11 +424,12 @@ FPC_INT10_HANDLER:
|
|
|
pop bp
|
|
|
pop ds
|
|
|
pop cx
|
|
|
- retf ; jumps to the previous handler with all registers and stack intact
|
|
|
+ iret ; jumps to the previous handler with all registers and stack intact
|
|
|
|
|
|
global FPC_INT75_HANDLER
|
|
|
FPC_INT75_HANDLER:
|
|
|
- sub sp, 4 ; reserve space on the stack for the retf
|
|
|
+ pushf
|
|
|
+ sub sp, 4 ; reserve space on the stack for the iret
|
|
|
|
|
|
push cx
|
|
|
push ds
|
|
@@ -465,7 +456,7 @@ FPC_INT75_HANDLER:
|
|
|
%ifndef __FAR_CODE__
|
|
|
; check whether we're coming from the same code segment
|
|
|
mov bp, sp
|
|
|
- mov cx, [bp + 3*2 + 6] ; get caller segment
|
|
|
+ mov cx, [bp + 3*2 + 6 + 2] ; get caller segment
|
|
|
mov bp, cs
|
|
|
cmp bp, cx
|
|
|
jne .call_previous_handler75
|
|
@@ -473,12 +464,12 @@ FPC_INT75_HANDLER:
|
|
|
|
|
|
; Call Fpc_Handle_I8086_Error, with err=$75
|
|
|
mov bp, sp
|
|
|
- mov cx, [bp + 3*2 + 4] ; get caller offset
|
|
|
+ mov cx, [bp + 3*2 + 6] ; get caller offset
|
|
|
%ifdef __FAR_CODE__
|
|
|
- mov dx, [bp + 3*2 + 6] ; get caller segment
|
|
|
+ mov dx, [bp + 3*2 + 6 + 2] ; get caller segment
|
|
|
%endif
|
|
|
pop bp
|
|
|
- add sp, 2*2 + 4 + 6
|
|
|
+ add sp, 2*2 + 6 + 6
|
|
|
xor ax, ax
|
|
|
push ax
|
|
|
mov ax, 75h
|
|
@@ -488,6 +479,14 @@ FPC_INT75_HANDLER:
|
|
|
%endif
|
|
|
push cx
|
|
|
cld
|
|
|
+
|
|
|
+ ; Reset IRQ/#IGNNE latch; signal EOI; enable interrupts
|
|
|
+ mov al,20h
|
|
|
+ out 0F0h,al ; al=any
|
|
|
+ out 0A0h,al
|
|
|
+ out 020h,al
|
|
|
+ sti
|
|
|
+
|
|
|
%ifdef __FAR_CODE__
|
|
|
jmp far FPC_HANDLE_I8086_ERROR
|
|
|
%else
|
|
@@ -509,9 +508,9 @@ FPC_INT75_HANDLER:
|
|
|
|
|
|
global FPC_INSTALL_INTERRUPT_HANDLERS
|
|
|
FPC_INSTALL_INTERRUPT_HANDLERS:
|
|
|
- push ds
|
|
|
|
|
|
%ifdef __HUGE__
|
|
|
+ push ds
|
|
|
mov ax, SYSTEM_DATA
|
|
|
mov ds, ax
|
|
|
%endif
|
|
@@ -525,14 +524,16 @@ FPC_INSTALL_INTERRUPT_HANDLERS:
|
|
|
|
|
|
; install the new int 00 handler
|
|
|
%ifndef __TINY__
|
|
|
+ push ds
|
|
|
push cs
|
|
|
pop ds
|
|
|
%endif
|
|
|
mov dx, FPC_INT00_HANDLER
|
|
|
- pop ds
|
|
|
- push ds
|
|
|
mov ax, 2500h
|
|
|
int 21h
|
|
|
+%ifndef __TINY__
|
|
|
+ pop ds
|
|
|
+%endif
|
|
|
|
|
|
; save old int $10 handler
|
|
|
mov ax, 3510h
|
|
@@ -543,14 +544,16 @@ FPC_INSTALL_INTERRUPT_HANDLERS:
|
|
|
|
|
|
; install the new int $10 handler
|
|
|
%ifndef __TINY__
|
|
|
+ push ds
|
|
|
push cs
|
|
|
pop ds
|
|
|
%endif
|
|
|
mov dx, FPC_INT10_HANDLER
|
|
|
mov ax, 2510h
|
|
|
int 21h
|
|
|
+%ifndef __TINY__
|
|
|
pop ds
|
|
|
- push ds
|
|
|
+%endif
|
|
|
|
|
|
; save old int $75 handler
|
|
|
mov ax, 3575h
|
|
@@ -561,15 +564,21 @@ FPC_INSTALL_INTERRUPT_HANDLERS:
|
|
|
|
|
|
; install the new int $75 handler
|
|
|
%ifndef __TINY__
|
|
|
+ push ds
|
|
|
push cs
|
|
|
pop ds
|
|
|
%endif
|
|
|
mov dx, FPC_INT75_HANDLER
|
|
|
mov ax, 2575h
|
|
|
int 21h
|
|
|
+%ifndef __TINY__
|
|
|
+ pop ds
|
|
|
+%endif
|
|
|
|
|
|
|
|
|
+%ifdef __HUGE__
|
|
|
pop ds
|
|
|
+%endif
|
|
|
%ifdef __FAR_CODE__
|
|
|
retf
|
|
|
%else
|
|
@@ -579,26 +588,33 @@ FPC_INSTALL_INTERRUPT_HANDLERS:
|
|
|
|
|
|
global FPC_RESTORE_INTERRUPT_HANDLERS
|
|
|
FPC_RESTORE_INTERRUPT_HANDLERS:
|
|
|
- push ds
|
|
|
|
|
|
%ifdef __HUGE__
|
|
|
+ push ds
|
|
|
mov ax, SYSTEM_DATA
|
|
|
mov ds, ax
|
|
|
%endif
|
|
|
-
|
|
|
+ push ds
|
|
|
mov ax, 2500h
|
|
|
lds dx, [__SaveInt00]
|
|
|
int 21h
|
|
|
+ pop ds
|
|
|
|
|
|
+ push ds
|
|
|
mov ax, 2510h
|
|
|
lds dx, [__SaveInt10]
|
|
|
int 21h
|
|
|
+ pop ds
|
|
|
|
|
|
+ push ds
|
|
|
mov ax, 2575h
|
|
|
lds dx, [__SaveInt75]
|
|
|
int 21h
|
|
|
+ pop ds
|
|
|
|
|
|
+%ifdef __HUGE__
|
|
|
pop ds
|
|
|
+%endif
|
|
|
%ifdef __FAR_CODE__
|
|
|
retf
|
|
|
%else
|