mirror of https://github.com/FDOS/kernel.git
assembly glue to wrap misc interrupts with C handler
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1155 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
b4d8701d5c
commit
fb6e86f388
|
@ -0,0 +1,161 @@
|
|||
;
|
||||
; File:
|
||||
; intwrap.asm
|
||||
; Description:
|
||||
; support for hooking misc interrupts
|
||||
; BIOS disk interrupt support code
|
||||
; warm boot support code
|
||||
;
|
||||
; Copyright (c) 2005
|
||||
; Pasquale J. Villani
|
||||
; All Rights Reserved
|
||||
;
|
||||
; This file is part of DOS-C.
|
||||
;
|
||||
; DOS-C is free software; you can redistribute it and/or
|
||||
; modify it under the terms of the GNU General Public License
|
||||
; as published by the Free Software Foundation; either version
|
||||
; 2, or (at your option) any later version.
|
||||
;
|
||||
; DOS-C is distributed in the hope that it will be useful, but
|
||||
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
; the GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public
|
||||
; License along with DOS-C; see the file COPYING. If not,
|
||||
; write to the Free Software Foundation, 675 Mass Ave,
|
||||
; Cambridge, MA 02139, USA.
|
||||
;
|
||||
|
||||
%include "segs.inc"
|
||||
%include "stacks.inc"
|
||||
|
||||
segment HMA_TEXT
|
||||
extern _DGROUP_
|
||||
|
||||
; defined in kernel.asm
|
||||
extern _UserInt13 ; actual BIOS int13 disk handler used by kernel
|
||||
extern _BIOSInt19 ; original int19 (reboot)
|
||||
|
||||
|
||||
; receives int 13h request, invokes original handler,
|
||||
; but passes to C routine in inthndr.c on error
|
||||
; this lets successful calls proceed with minimal overhead
|
||||
; while allowing us to handle errors, store disk change, ...
|
||||
|
||||
global reloc_call_int13_handler
|
||||
reloc_call_int13_handler:
|
||||
cli ; disable other interrupts for now
|
||||
stc ; force error unless BIOS clears
|
||||
push dx ; store BIOS drive # for error handling usage
|
||||
|
||||
push ds ; get segment of kernel DATA
|
||||
mov ds, [cs:_DGROUP_]
|
||||
pushf ; simulate int call so returns back here (flags+cs:ip on stack)
|
||||
call far [ds:_UserInt13]
|
||||
pop ds ; restore ds
|
||||
|
||||
jc int13err ; test if error, if not return to caller
|
||||
|
||||
int13iret:
|
||||
inc sp ; clean up stack
|
||||
inc sp
|
||||
sti ; ensure int's are renabled
|
||||
retf 2 ; return to caller leaving flags asis
|
||||
|
||||
int13err:
|
||||
pushf ; don't mess up flags
|
||||
|
||||
cmp ah, 06h ; disk changed
|
||||
je int13wrap
|
||||
|
||||
; add check for other errors here, such as DMA issues
|
||||
|
||||
popf
|
||||
jmp int13iret ; pass error asis back to user
|
||||
|
||||
|
||||
int13wrap:
|
||||
%IF XCPU < 186
|
||||
push ax ; preserve registers, setup stack frame
|
||||
push bp
|
||||
mov bp, sp
|
||||
mov ax, 13h ; want to push 0x13 onto stack
|
||||
xchg ax, [bp+2] ; so restore pushed ax value and put 0x13 on stack
|
||||
pop bp ; clean up stack frame (leaving just 0x13 pushed on stack)
|
||||
%ELSE
|
||||
push 13h ; the 186+ way to push a constant on the stack
|
||||
%ENDIF
|
||||
|
||||
; at this point stack has initial flags, called cs,ip, initial dx,
|
||||
; flags returned from int13 call, and value 13h
|
||||
; fall through to intWrapCall to invoke C handler
|
||||
|
||||
|
||||
; assumes interrupt # and single word param already pushed on stack
|
||||
; pushes all registers on stack
|
||||
; calls C handler
|
||||
; restores registers (replacing value if changed by C code)
|
||||
; pops int# and param off stack
|
||||
; returns via iret
|
||||
intWrapCall:
|
||||
; set up register frame
|
||||
push ax
|
||||
push cx
|
||||
push dx
|
||||
push bx
|
||||
push bp
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
|
||||
cld
|
||||
|
||||
Protect386Registers ; ensure 386+ registers possibly modified by kernel safe
|
||||
|
||||
mov ds,[cs:_DGROUP_]
|
||||
push ds ; mov es, ds
|
||||
pop es
|
||||
extern _intXX_filter
|
||||
call _intXX_filter
|
||||
|
||||
Restore386Registers
|
||||
|
||||
pop es
|
||||
pop ds
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
pop bx
|
||||
pop dx
|
||||
pop cx
|
||||
pop ax
|
||||
|
||||
add sp, 2 ; pop int# off stack
|
||||
popf ; restore flags
|
||||
inc sp ; pop param off stack (without altering flags)
|
||||
inc sp
|
||||
retf 2 ; iret but ignore pushed flags
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
; receives int 19h request, resets various int values,
|
||||
; clears hma if in use, and finally invokes original handler,
|
||||
|
||||
global reloc_call_int19_handler
|
||||
reloc_call_int19_handler:
|
||||
|
||||
mov ds, [cs:_DGROUP_]
|
||||
lds ax,[_BIOSInt19] ; iret calls original handler, doesn't return
|
||||
add sp, 4 ; so pop callers return address off stack
|
||||
push ds ; and replace with address of original handler
|
||||
push ax
|
||||
push ax ; param, ignored
|
||||
pushf ; flags, ignored
|
||||
mov ax, 19h ; handler for int 19h
|
||||
push ax
|
||||
jmp intWrapCall
|
||||
#endif
|
Loading…
Reference in New Issue