mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-25 14:54:28 +02:00
initial BIOS disk int 13h wrapper, only passively detects and notes floppy disk change
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1154 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
9c7fd183f4
commit
b4d8701d5c
@ -56,6 +56,8 @@ FarTabRetn:
|
|||||||
Int2f3:
|
Int2f3:
|
||||||
cmp ah,12h
|
cmp ah,12h
|
||||||
je IntDosCal ; Dos Internal calls
|
je IntDosCal ; Dos Internal calls
|
||||||
|
cmp ah,13h
|
||||||
|
je IntDosCal ; Install Int13h Hook
|
||||||
cmp ah,16h
|
cmp ah,16h
|
||||||
je IntDosCal ; Win (Multitasking) Hook
|
je IntDosCal ; Win (Multitasking) Hook
|
||||||
cmp ah,46h
|
cmp ah,46h
|
||||||
|
@ -41,7 +41,7 @@ BYTE *RcsId =
|
|||||||
|
|
||||||
#ifdef TSC
|
#ifdef TSC
|
||||||
STATIC VOID StartTrace(VOID);
|
STATIC VOID StartTrace(VOID);
|
||||||
static bTraceNext = FALSE;
|
STATIC bTraceNext = FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* Very suspicious, passing structure by value??
|
#if 0 /* Very suspicious, passing structure by value??
|
||||||
@ -1703,6 +1703,9 @@ struct int2f12regs {
|
|||||||
xreg callerARG1; /* used if called from INT2F/12 */
|
xreg callerARG1; /* used if called from INT2F/12 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern intvec BIOSInt13, UserInt13, BIOSInt19;
|
||||||
|
|
||||||
|
|
||||||
/* WARNING: modifications in `r' are used outside of int2F_12_handler()
|
/* WARNING: modifications in `r' are used outside of int2F_12_handler()
|
||||||
* On input r.AX==0x12xx, 0x4A01 or 0x4A02
|
* On input r.AX==0x12xx, 0x4A01 or 0x4A02
|
||||||
* also handle Windows' DOS notification hooks, r.AH==0x16
|
* also handle Windows' DOS notification hooks, r.AH==0x16
|
||||||
@ -1733,6 +1736,17 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
|||||||
r.BX = size;
|
r.BX = size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (r.AH == 0x13) /* set disk interrupt (13h) handler */
|
||||||
|
{
|
||||||
|
/* set new values for int13h calls, and must return old values */
|
||||||
|
register intvec tmp = UserInt13;
|
||||||
|
UserInt13 = MK_FP(r.ds, r.DX); /* int13h handler to use */
|
||||||
|
r.ds = FP_SEG(tmp); r.DX = FP_OFF(tmp);
|
||||||
|
tmp = BIOSInt13;
|
||||||
|
BIOSInt13 = MK_FP(r.es, r.BX); /* int13h handler to restore on reboot */
|
||||||
|
r.es = FP_SEG(tmp); r.BX = FP_OFF(tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (r.AH == 0x16) /* Window/Multitasking hooks */
|
else if (r.AH == 0x16) /* Window/Multitasking hooks */
|
||||||
{
|
{
|
||||||
#ifdef WIN31SUPPORT /* See "DOS Internals" or RBIL under DOSMGR for details */
|
#ifdef WIN31SUPPORT /* See "DOS Internals" or RBIL under DOSMGR for details */
|
||||||
@ -1915,9 +1929,8 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
|||||||
case 0x80: /* Win Release Time-slice */
|
case 0x80: /* Win Release Time-slice */
|
||||||
{
|
{
|
||||||
/* This function is generally only called in idle loops */
|
/* This function is generally only called in idle loops */
|
||||||
enable; /* enable interrupts */
|
__emit__(0xfb); /* sti; enable interrupts */
|
||||||
// __emit__(0xf4); /* halt */
|
__emit__(0xf4); /* hlt; halt until interrupt */
|
||||||
asm hlt;
|
|
||||||
r.AX = 0;
|
r.AX = 0;
|
||||||
/* DebugPrintf(("Release Time Slice\n")); */
|
/* DebugPrintf(("Release Time Slice\n")); */
|
||||||
break;
|
break;
|
||||||
@ -2259,6 +2272,91 @@ error_exit:
|
|||||||
r.FLAGS |= FLG_CARRY;
|
r.FLAGS |= FLG_CARRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* how registers pushed on stack prior to calling int wrapper function,
|
||||||
|
when returns these are then popped off, so any changes to these
|
||||||
|
will effectively set the returned value in these registers
|
||||||
|
*/
|
||||||
|
struct intXXregs {
|
||||||
|
#ifdef I386
|
||||||
|
/* preserved 386+ only registers, compiler specific */
|
||||||
|
#endif
|
||||||
|
UWORD es, ds;
|
||||||
|
UWORD di, si, bp;
|
||||||
|
xreg b, d, c, a;
|
||||||
|
UWORD intreq; /* which interrupt filter request for */
|
||||||
|
UWORD flags; /* flags duplicated, one pushed by int call ignored */
|
||||||
|
xreg param;
|
||||||
|
UWORD ip, cs , oflags;
|
||||||
|
/* top item of int caller's stack, possibly additional params */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* additional processing for various wrapped/filtered interrupts
|
||||||
|
WARNING: this function also called during kernel init phase
|
||||||
|
-- int 13h
|
||||||
|
filter for BIOS int13h support, only called on int13h error
|
||||||
|
for ms-dos compatibility this should at minimal
|
||||||
|
watch for disk-change notification and set internal status
|
||||||
|
(may be called multiple times in row when BIOS reports same
|
||||||
|
change multiple times, ie delays clearing disk change status)
|
||||||
|
TODO: move DMA bounday check from int25/26 to here
|
||||||
|
Note: use stored user (usually BIOS) hooked int13 handler
|
||||||
|
-- int 19h
|
||||||
|
clean up prior to a warm reboot
|
||||||
|
for ms compatibility this should at a minimal
|
||||||
|
restore original (or indicated as original) BIOS int13h handler
|
||||||
|
and any others that may be hooked (including this one)
|
||||||
|
if himem loaded clear high memory area (clear vdisk signature so himem loads)
|
||||||
|
*/
|
||||||
|
VOID ASMCFUNC intXX_filter(struct intXXregs r)
|
||||||
|
{
|
||||||
|
DebugPrintf(("int %02xh filter\n", r.intreq));
|
||||||
|
switch(r.intreq)
|
||||||
|
{
|
||||||
|
case 0x19: /* reboot via bootstrap */
|
||||||
|
{
|
||||||
|
setvec(0x13, BIOSInt13);
|
||||||
|
setvec(0x19, BIOSInt19);
|
||||||
|
|
||||||
|
/* clear vdisk signature if kernel loaded in hma */
|
||||||
|
if (version_flags & 0x10)
|
||||||
|
fmemset(MK_FP(0xffff, 0x0010),0,512);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x13: /* error with disk handler */
|
||||||
|
{
|
||||||
|
DebugPrintf(("disk error %i [ah=%x] (drive %x)\n", r.a.b.h, r.param.b.h, r.param.b.l));
|
||||||
|
DebugPrintf(("bx==(%x) cx==(%x) dx==(%x)\n", r.BX, r.CX, r.DX));
|
||||||
|
/* currently just marks floppy as changed on disk change error */
|
||||||
|
if ((r.a.b.h == 0x06) && (r.param.b.l < 0x80)) /* diskchange and is it a floppy? */
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
/* mark floppy as changed */
|
||||||
|
for(i=0; i < blk_dev.dh_name[0]; i++)
|
||||||
|
{
|
||||||
|
ddt *pddt = getddt(i);
|
||||||
|
if (pddt->ddt_driveno == r.param.b.l)
|
||||||
|
{
|
||||||
|
DebugPrintf(("ddt[%i] match, flags=%04x\n", i, pddt->ddt_descflags));
|
||||||
|
if ((pddt->ddt_descflags & DF_CHANGELINE) && /* drive must have changeline support */
|
||||||
|
(pddt->ddt_descflags & DF_CURBPBLOCK)) /* and BPB not currently locked (in-use) */
|
||||||
|
pddt->ddt_descflags |= DF_DISKCHANGE;
|
||||||
|
/* or get dpb pointer from ddt and set dpbp->dpb_flags = M_CHANGED; */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
DebugPrintf(("INT_ERROR!\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2000/09/04 Brian Reifsnyder
|
* 2000/09/04 Brian Reifsnyder
|
||||||
* Modified interrupts 0x25 & 0x26 to return more accurate error codes.
|
* Modified interrupts 0x25 & 0x26 to return more accurate error codes.
|
||||||
|
@ -652,6 +652,22 @@ _ext_open_action dw 0 ;2DD - extended open action
|
|||||||
_ext_open_attrib dw 0 ;2DF - extended open attrib
|
_ext_open_attrib dw 0 ;2DF - extended open attrib
|
||||||
_ext_open_mode dw 0 ;2E1 - extended open mode
|
_ext_open_mode dw 0 ;2E1 - extended open mode
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; these 3 placed here so init code and int wrapper can easily access
|
||||||
|
; holds pointers to actual disk handler routines and interrupt
|
||||||
|
; vectors that we try to restore before a warm reboot
|
||||||
|
global _SAVEDIVLST
|
||||||
|
_SAVEDIVLST:
|
||||||
|
; used by int13 handler and get/set via int 2f/13h
|
||||||
|
global _BIOSInt13
|
||||||
|
global _UserInt13
|
||||||
|
_BIOSInt13 dd 0 ; used to restore int13 on reboot (see int19 wrapper)
|
||||||
|
_UserInt13 dd 0 ; actual disk handler used by kernel
|
||||||
|
global _BIOSInt19
|
||||||
|
_BIOSInt19 dd 0 ; original int19
|
||||||
|
|
||||||
|
|
||||||
; Pad to 0620h
|
; Pad to 0620h
|
||||||
times (300h - ($ - _internal_data)) db 0
|
times (300h - ($ - _internal_data)) db 0
|
||||||
global _szNames
|
global _szNames
|
||||||
@ -846,6 +862,18 @@ initforceEnableA20:
|
|||||||
global __HMARelocationTableStart
|
global __HMARelocationTableStart
|
||||||
__HMARelocationTableStart:
|
__HMARelocationTableStart:
|
||||||
|
|
||||||
|
global _int13_handler
|
||||||
|
extern reloc_call_int13_handler
|
||||||
|
_int13_handler: jmp 0:reloc_call_int13_handler
|
||||||
|
call near forceEnableA20
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
global _int19_handler
|
||||||
|
extern reloc_call_int19_handler
|
||||||
|
_int19_handler: jmp 0:reloc_call_int19_handler
|
||||||
|
call near forceEnableA20
|
||||||
|
#endif
|
||||||
|
|
||||||
global _int2f_handler
|
global _int2f_handler
|
||||||
extern reloc_call_int2f_handler
|
extern reloc_call_int2f_handler
|
||||||
_int2f_handler: jmp 0:reloc_call_int2f_handler
|
_int2f_handler: jmp 0:reloc_call_int2f_handler
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "portab.h"
|
#include "portab.h"
|
||||||
#include "init-mod.h"
|
#include "init-mod.h"
|
||||||
#include "dyndata.h"
|
#include "dyndata.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
#ifdef VERSION_STRINGS
|
#ifdef VERSION_STRINGS
|
||||||
static BYTE *mainRcsId =
|
static BYTE *mainRcsId =
|
||||||
@ -48,6 +49,7 @@ STATIC VOID init_internal_devices(void);
|
|||||||
|
|
||||||
STATIC VOID update_dcb(struct dhdr FAR *);
|
STATIC VOID update_dcb(struct dhdr FAR *);
|
||||||
STATIC VOID init_kernel(VOID);
|
STATIC VOID init_kernel(VOID);
|
||||||
|
STATIC VOID do_fixup(VOID);
|
||||||
STATIC VOID signon(VOID);
|
STATIC VOID signon(VOID);
|
||||||
STATIC VOID init_shell(VOID);
|
STATIC VOID init_shell(VOID);
|
||||||
STATIC VOID FsConfig(VOID);
|
STATIC VOID FsConfig(VOID);
|
||||||
@ -55,6 +57,11 @@ STATIC VOID InitPrinters(VOID);
|
|||||||
STATIC VOID InitSerialPorts(VOID);
|
STATIC VOID InitSerialPorts(VOID);
|
||||||
STATIC void CheckContinueBootFromHarddisk(void);
|
STATIC void CheckContinueBootFromHarddisk(void);
|
||||||
STATIC void setup_int_vectors(void);
|
STATIC void setup_int_vectors(void);
|
||||||
|
#define setup_fastprint_hook() setvec(0x29, int29_handler) /* required for printf! */
|
||||||
|
|
||||||
|
|
||||||
|
void setvec(unsigned char intno, intvec vector);
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
BYTE _acrtused = 0;
|
BYTE _acrtused = 0;
|
||||||
@ -67,6 +74,7 @@ __segment DosTextSeg = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct lol FAR * const LoL = &DATASTART;
|
struct lol FAR * const LoL = &DATASTART;
|
||||||
|
intvec FAR * const savedIVs = &SAVEDIVLST;
|
||||||
|
|
||||||
void ASMCFUNC FreeDOSmain(void)
|
void ASMCFUNC FreeDOSmain(void)
|
||||||
{
|
{
|
||||||
@ -120,14 +128,25 @@ void ASMCFUNC FreeDOSmain(void)
|
|||||||
fmemcpy(&InitKernelConfig, p, sizeof InitKernelConfig);
|
fmemcpy(&InitKernelConfig, p, sizeof InitKernelConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_int_vectors();
|
/* printfs won't work until int29, fast console output hook is installed */
|
||||||
|
setup_fastprint_hook();
|
||||||
|
|
||||||
|
/* check if booting from CD before we hook too many interrupts */
|
||||||
CheckContinueBootFromHarddisk();
|
CheckContinueBootFromHarddisk();
|
||||||
|
|
||||||
|
/* display copyright info and kernel emulation status */
|
||||||
signon();
|
signon();
|
||||||
init_kernel();
|
|
||||||
init_shell();
|
|
||||||
|
|
||||||
|
/* finish initial HMA segment relocation (move up until DOS=HIGH known) */
|
||||||
|
do_fixup();
|
||||||
|
|
||||||
|
/* install DOS API and other interrupt service routines, basic kernel functionality works */
|
||||||
|
setup_int_vectors();
|
||||||
|
|
||||||
|
/* initialize all internal variables, process CONFIG.SYS, load drivers, etc */
|
||||||
|
init_kernel();
|
||||||
|
|
||||||
|
init_shell();
|
||||||
init_call_p_0(&Config); /* execute process 0 (the shell) */
|
init_call_p_0(&Config); /* execute process 0 (the shell) */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +214,30 @@ void setvec(unsigned char intno, intvec vector)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ensures int vectors we may need to restore are saved */
|
||||||
|
STATIC VOID save_int_vectors(VOID)
|
||||||
|
{
|
||||||
|
/* we create far pointers otherwise compiler sets value
|
||||||
|
in initial data segment (IDATA) which does us no good.
|
||||||
|
*/
|
||||||
|
extern intvec BIOSInt13, UserInt13, BIOSInt19; /* in kernel.asm */
|
||||||
|
intvec FAR *pBIOSInt13, FAR *pUserInt13, FAR *pBIOSInt19;
|
||||||
|
|
||||||
|
pBIOSInt13 = MK_FP(FP_SEG(savedIVs), FP_OFF(savedIVs));
|
||||||
|
pUserInt13 = pBIOSInt13 + 1;
|
||||||
|
pBIOSInt19 = pBIOSInt13 + 2;
|
||||||
|
|
||||||
|
/* store for later use by our replacement int13handler */
|
||||||
|
*pBIOSInt13 = getvec(0x13); /* save original BIOS int 0x13 handler */
|
||||||
|
*pUserInt13 = *pBIOSInt13; /* default to it for user int 0x13 handler */
|
||||||
|
*pBIOSInt19 = getvec(0x19); /* save reboot handler so we can clean up a little */
|
||||||
|
|
||||||
|
DDebugPrintf(("\n")); /* force anything printed to start on next line after BS */
|
||||||
|
DDebugPrintf(("BIOSInt13(at %p) is %p\n", pBIOSInt13, *pBIOSInt13));
|
||||||
|
DDebugPrintf(("BIOSInt19(at %p) is %p\n", pBIOSInt19, *pBIOSInt19));
|
||||||
|
}
|
||||||
|
|
||||||
STATIC void setup_int_vectors(void)
|
STATIC void setup_int_vectors(void)
|
||||||
{
|
{
|
||||||
static struct vec
|
static struct vec
|
||||||
@ -208,20 +251,27 @@ STATIC void setup_int_vectors(void)
|
|||||||
{ 0x1, FP_OFF(empty_handler) }, /* single step */
|
{ 0x1, FP_OFF(empty_handler) }, /* single step */
|
||||||
{ 0x3, FP_OFF(empty_handler) }, /* debug breakpoint */
|
{ 0x3, FP_OFF(empty_handler) }, /* debug breakpoint */
|
||||||
{ 0x6, FP_OFF(int6_handler) }, /* invalid opcode */
|
{ 0x6, FP_OFF(int6_handler) }, /* invalid opcode */
|
||||||
|
{ 0x13, FP_OFF(int13_handler) }, /* BIOS disk filter */
|
||||||
|
#if 0
|
||||||
|
{ 0x19, FP_OFF(int19_handler) }, /* BIOS bootstrap loader, vdisk */
|
||||||
|
#endif
|
||||||
{ 0x20, FP_OFF(int20_handler) },
|
{ 0x20, FP_OFF(int20_handler) },
|
||||||
{ 0x21, FP_OFF(int21_handler) },
|
{ 0x21, FP_OFF(int21_handler) }, /* primary DOS API */
|
||||||
{ 0x22, FP_OFF(int22_handler) },
|
{ 0x22, FP_OFF(int22_handler) },
|
||||||
{ 0x24, FP_OFF(int24_handler) },
|
{ 0x24, FP_OFF(int24_handler) },
|
||||||
{ 0x25, FP_OFF(low_int25_handler) },
|
{ 0x25, FP_OFF(low_int25_handler) }, /* DOS abs read/write calls */
|
||||||
{ 0x26, FP_OFF(low_int26_handler) },
|
{ 0x26, FP_OFF(low_int26_handler) },
|
||||||
{ 0x27, FP_OFF(int27_handler) },
|
{ 0x27, FP_OFF(int27_handler) },
|
||||||
{ 0x28, FP_OFF(int28_handler) },
|
{ 0x28, FP_OFF(int28_handler) },
|
||||||
{ 0x2a, FP_OFF(int2a_handler) },
|
{ 0x2a, FP_OFF(int2a_handler) },
|
||||||
{ 0x2f, FP_OFF(int2f_handler) }
|
{ 0x2f, FP_OFF(int2f_handler) } /* multiplex int */
|
||||||
};
|
};
|
||||||
struct vec *pvec;
|
struct vec *pvec;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
save_int_vectors();
|
||||||
|
|
||||||
|
/* install default handlers */
|
||||||
for (i = 0x23; i <= 0x3f; i++)
|
for (i = 0x23; i <= 0x3f; i++)
|
||||||
setvec(i, empty_handler);
|
setvec(i, empty_handler);
|
||||||
for (pvec = vectors; pvec < ENDOF(vectors); pvec++)
|
for (pvec = vectors; pvec < ENDOF(vectors); pvec++)
|
||||||
@ -229,7 +279,7 @@ STATIC void setup_int_vectors(void)
|
|||||||
pokeb(0, 0x30 * 4, 0xea);
|
pokeb(0, 0x30 * 4, 0xea);
|
||||||
pokel(0, 0x30 * 4 + 1, (ULONG)cpm_entry);
|
pokel(0, 0x30 * 4 + 1, (ULONG)cpm_entry);
|
||||||
|
|
||||||
/* these two are in the device driver area LOWTEXT (0x70) */
|
/* handlers for int 0x1b and 0x29 are in the device driver area LOWTEXT (0x70) */
|
||||||
setvec(0x1b, got_cbreak);
|
setvec(0x1b, got_cbreak);
|
||||||
setvec(0x29, int29_handler); /* required for printf! */
|
setvec(0x29, int29_handler); /* required for printf! */
|
||||||
}
|
}
|
||||||
@ -251,14 +301,8 @@ STATIC void printIRQvectors(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATIC void init_kernel(void)
|
STATIC void do_fixup(void)
|
||||||
{
|
{
|
||||||
COUNT i;
|
|
||||||
|
|
||||||
LoL->os_setver_major = LoL->os_major = MAJOR_RELEASE;
|
|
||||||
LoL->os_setver_minor = LoL->os_minor = MINOR_RELEASE;
|
|
||||||
LoL->rev_number = REVISION_SEQ;
|
|
||||||
|
|
||||||
/* move kernel to high conventional RAM, just below the init code */
|
/* move kernel to high conventional RAM, just below the init code */
|
||||||
/* Note: kernel.asm actually moves and jumps here, but MoveKernel
|
/* Note: kernel.asm actually moves and jumps here, but MoveKernel
|
||||||
must still be called to do the necessary segment fixups */
|
must still be called to do the necessary segment fixups */
|
||||||
@ -275,6 +319,15 @@ STATIC void init_kernel(void)
|
|||||||
chunk allocated, lpTop. I.e. lpTop is top of free conv memory
|
chunk allocated, lpTop. I.e. lpTop is top of free conv memory
|
||||||
*/
|
*/
|
||||||
lpTop = MK_FP(FP_SEG(lpTop) - 0xfff, 0xfff0);
|
lpTop = MK_FP(FP_SEG(lpTop) - 0xfff, 0xfff0);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC void init_kernel(void)
|
||||||
|
{
|
||||||
|
COUNT i;
|
||||||
|
|
||||||
|
LoL->os_setver_major = LoL->os_major = MAJOR_RELEASE;
|
||||||
|
LoL->os_setver_minor = LoL->os_minor = MINOR_RELEASE;
|
||||||
|
LoL->rev_number = REVISION_SEQ;
|
||||||
|
|
||||||
/* Initialize IO subsystem */
|
/* Initialize IO subsystem */
|
||||||
init_internal_devices();
|
init_internal_devices();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user