mirror of https://github.com/FDOS/kernel.git
additional win 3.x compatibility when WIN31SUPPORT defined (untested)
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/branches/UNSTABLE@1106 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
bae20d0533
commit
65d87b42c4
|
@ -146,8 +146,10 @@ shift
|
|||
if "%1" == "" echo you MUST specify value to define with /D option
|
||||
if "%1" == "" echo such as /D DEBUG : extra DEBUG output
|
||||
if "%1" == "" echo or /D DOSEMU : printf output goes to dosemu log
|
||||
if "%1" == "" echo or /D WIN31SUPPORT : enable Win 3.x hooks
|
||||
if "%1" == "" goto abort
|
||||
set ALLCFLAGS=%ALLCFLAGS% -D%1
|
||||
set NASMFLAGS=%NASMFLAGS% -D%1
|
||||
goto nextOption
|
||||
|
||||
:noenv
|
||||
|
|
23
hdr/lol.h
23
hdr/lol.h
|
@ -75,15 +75,20 @@ struct lol {
|
|||
unsigned short uppermem_root;/* 66 Start of umb chain (usually 9fff) */
|
||||
unsigned short last_para; /* 68 para: start scanning during memalloc */
|
||||
/* FreeDOS specific entries */
|
||||
unsigned char os_setver_minor;/*6a settable minor DOS version */
|
||||
unsigned char os_setver_major;/*6b settable major DOS version */
|
||||
unsigned char os_minor; /* 6c minor DOS version */
|
||||
unsigned char os_major; /* 6d major DOS version */
|
||||
unsigned char rev_number; /* 6e minor DOS version */
|
||||
unsigned char version_flags; /* 6f DOS version flags */
|
||||
struct f_node FAR *f_nodes; /* 70 pointer to the array */
|
||||
unsigned short f_nodes_cnt; /* 74 number of allocated f_nodes */
|
||||
char *os_release; /* 76 near pointer to os_release string */
|
||||
unsigned char os_minor; /* 6a minor DOS version */
|
||||
unsigned char os_major; /* 6b major DOS version */
|
||||
unsigned char rev_number; /* 6c minor DOS version */
|
||||
unsigned char version_flags; /* 6d DOS version flags */
|
||||
struct f_node FAR *f_nodes; /* 6e pointer to the array */
|
||||
unsigned short f_nodes_cnt; /* 72 number of allocated f_nodes */
|
||||
char *os_release; /* 74 near pointer to os_release string */
|
||||
#ifdef WIN31SUPPORT
|
||||
unsigned short winInstanced; /* WinInit called */
|
||||
unsigned long winStartupInfo[4];
|
||||
unsigned short instanceTable[5];
|
||||
#endif
|
||||
unsigned char os_setver_minor;/*76/96 settable minor DOS version */
|
||||
unsigned char os_setver_major;/*77/97 settable major DOS version */
|
||||
};
|
||||
|
||||
#endif /* __LOL_H */
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef __WINSUPPORT_H
|
||||
#define __WINSUPPORT_H
|
||||
#ifdef WIN31SUPPORT /* defined to enable kernel hooks for win3.x compatibility */
|
||||
|
||||
|
||||
extern UWORD winInstanced; /* internal flag marking if Windows is active */
|
||||
|
||||
/* contains information about data that must be kept for each active DOS
|
||||
instance, ie data that can NOT be shared between multiple VMs.
|
||||
*/
|
||||
struct WinStartupInfo
|
||||
{
|
||||
UWORD winver; /* this structure version, matches Windows version */
|
||||
ULONG next; /* far pointer to next WinStartupInfo structure or NULL */
|
||||
ULONG vddName; /* far pointer to ASCIIZ pathname of virtual device driver */
|
||||
ULONG vddInfo; /* far pointer to vdd reference data or NULL if vddName=NULL */
|
||||
ULONG instanceTable; /* far pointer to array of instance data */
|
||||
};
|
||||
extern struct WinStartupInfo winStartupInfo;
|
||||
|
||||
/* contains a list of offsets relative to DOS data segment of
|
||||
various internal variables.
|
||||
*/
|
||||
struct WinPatchTable
|
||||
{
|
||||
UWORD dosver; /* Note: for FreeDOS this overlaps with os_setver version */
|
||||
UWORD OffTempDS;
|
||||
UWORD OffTempBX;
|
||||
UWORD OffInDOS;
|
||||
UWORD OffMachineID;
|
||||
UWORD OffCritSectPatches;
|
||||
UWORD OffLastMCBSeg; /* used by Win 3.1 if DOS version 5 or higher */
|
||||
};
|
||||
extern struct WinPatchTable winPatchTable;
|
||||
|
||||
|
||||
#endif /* WIN31SUPPORT */
|
||||
#endif /* __WINSUPPORT_H */
|
|
@ -54,10 +54,12 @@ Int2f2:
|
|||
FarTabRetn:
|
||||
retf 2 ; Return far
|
||||
Int2f3:
|
||||
cmp ah,16h
|
||||
je FarTabRetn ; Win Hook return fast
|
||||
cmp ah,12h
|
||||
je IntDosCal ; Dos Internal calls
|
||||
cmp ah,16h
|
||||
je IntDosCal ; Win (Multitasking) Hook
|
||||
cmp ah,46h
|
||||
je IntDosCal ; Win Hook to avoid MCB corruption
|
||||
|
||||
cmp ax,4a01h
|
||||
je IntDosCal ; Dos Internal calls
|
||||
|
@ -108,6 +110,7 @@ DriverSysCal:
|
|||
|
||||
;**********************************************************************
|
||||
; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C
|
||||
; also handle Windows' DOS notification hooks
|
||||
;**********************************************************************
|
||||
IntDosCal:
|
||||
; set up register frame
|
||||
|
|
|
@ -59,6 +59,11 @@ struct HugeSectorBlock {
|
|||
BYTE FAR *buf;
|
||||
};
|
||||
|
||||
#ifdef WIN31SUPPORT
|
||||
#include "win.h" /* Structures used for Windows compatibility */
|
||||
#endif /* WIN31SUPPORT */
|
||||
|
||||
|
||||
/* Normal entry. This minimizes user stack usage by avoiding local */
|
||||
/* variables needed for the rest of the handler. */
|
||||
/* this here works on the users stack !! and only very few functions
|
||||
|
@ -1695,6 +1700,7 @@ struct int2f12regs {
|
|||
|
||||
/* WARNING: modifications in `r' are used outside of int2F_12_handler()
|
||||
* On input r.AX==0x12xx, 0x4A01 or 0x4A02
|
||||
* also handle Windows' DOS notification hooks, r.AH==0x16
|
||||
*/
|
||||
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||
{
|
||||
|
@ -1722,6 +1728,168 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
|||
r.BX = size;
|
||||
return;
|
||||
}
|
||||
else if (r.AH == 0x16) /* Window/Multitasking hooks */
|
||||
{
|
||||
#ifdef WIN31SUPPORT /* See "DOS Internals" or RBIL under DOSMGR for details */
|
||||
switch (r.AL)
|
||||
{
|
||||
/* default: unhandled requests pass through unchanged */
|
||||
#if 0
|
||||
case 0x03: /* Windows Get Instance Data */
|
||||
{
|
||||
/* This should only be called if AX=1607h/BX=15h is not supported. */
|
||||
/* The data returned here corresponds directly with text entries that
|
||||
can also be in INSTANCE.386 [which in theory means Windows could
|
||||
be updated to support FD kernel without responding to these?].
|
||||
*/
|
||||
break;
|
||||
} /* 0x03 */
|
||||
#endif
|
||||
case 0x05: /* Windows Startup Broadcast */
|
||||
{
|
||||
/* After receiving this call we activiate compatibility changes
|
||||
as DOS 5 does, though can wait until 0x07 subfunc 0x01
|
||||
*/
|
||||
/* on entry:
|
||||
DX flags, bit 0 is set(=1) for standard mode
|
||||
DI Windows version#, major# in high byte
|
||||
CX 0, set on exit to nonzero to fail load request
|
||||
DS:SI is 0000:0000, for enhanced mode, at most 1 program can
|
||||
set to memory manager calling point to disable V86
|
||||
ES:BX is 0000:0000, set to startup structure
|
||||
*/
|
||||
r.CX = 0x0; /* it is ok to load Windows, give it a shot anyway :-) */
|
||||
r.es = FP_SEG(&winStartupInfo);
|
||||
r.BX = FP_OFF(&winStartupInfo);
|
||||
winStartupInfo.winver = r.di; /* match what caller says it is */
|
||||
winInstanced = 1; /* internal flag marking Windows is active */
|
||||
break;
|
||||
} /* 0x05 */
|
||||
case 0x06: /* Windows Exit Broadcast */
|
||||
{
|
||||
/* can do nothing or can remove any changes made
|
||||
specifically for Windows, must preserve DS.
|
||||
Note: If Windows fatally exits then may not be called.
|
||||
*/
|
||||
winInstanced = 0; /* internal flag marking Windows is NOT active */
|
||||
break;
|
||||
} /* 0x06 */
|
||||
case 0x07: /* DOSMGR Virtual Device API */
|
||||
{
|
||||
if (r.BX == 0x15) /* VxD id of "DOSMGR" */
|
||||
{
|
||||
switch (r.CX)
|
||||
{
|
||||
/* default: unhandled requests pass through unchanged */
|
||||
case 0x00: /* query if supported */
|
||||
{
|
||||
r.CX = winInstanced; /* should always be nonzero if Win is active */
|
||||
r.DX = FP_SEG(&nul_dev); /* data segment / segment of DOS drivers */
|
||||
r.es = FP_SEG(&winPatchTable); /* es:bx points to table of offsets */
|
||||
r.BX = FP_OFF(&winPatchTable);
|
||||
break;
|
||||
}
|
||||
case 0x01: /* enable Win support, ie patch DOS */
|
||||
{
|
||||
/* DOS 5+ return with flags unchanged, Windows critical section
|
||||
needs are handled without need to patch. If this
|
||||
function does not return successfully windows will
|
||||
attempt to do the patching itself (very bad idea).
|
||||
On entry BX is bitflags describing support requested,
|
||||
and on return DX is set to which we can support.
|
||||
Note: any we report as unhandled Windows will attempt
|
||||
to patch kernel to handle, probably not a good idea.
|
||||
0001h: enable critical section signals (int 2Ah functions
|
||||
80h/81h) to allow re-entering DOS while InDOS.
|
||||
0002h: allow nonzero local machine ID, ie different VMs
|
||||
report different values.
|
||||
FIXME: does this mean we need to set this or does Windows?
|
||||
0004h: split up binary reads to increase int 2Ah function 84h scheduling
|
||||
/ turn Int 21h function 3Fh on STDIN into polling loop
|
||||
0008h: notify Windows of halting due to internal stack errors
|
||||
0010h: notify Windows of logical drive map change ("Insert disk X:")
|
||||
*/
|
||||
r.BX = r.DX; /* sure we support everything asked for, ;-) */
|
||||
r.DX = 0xA2AB; /* on succes DS:AX set to A2AB:B97Ch */
|
||||
r.AX = 0xB97C;
|
||||
/* FIXME: do we need to do anything special for FD kernel? */
|
||||
break;
|
||||
}
|
||||
/* case 0x02 is below so we can reuse it for 0x05 */
|
||||
case 0x03: /* get internal structure sizes */
|
||||
{
|
||||
if (r.CX & 0x01) /* size of Current Directory Structure in bytes */
|
||||
{
|
||||
r.DX = 0xA2AB; /* on succes DS:AX set to A2AB:B97Ch */
|
||||
r.AX = 0xB97C;
|
||||
r.CX = sizeof(struct cds);
|
||||
}
|
||||
else
|
||||
r.CX = 0; /* unknown or unsupported structure requested */
|
||||
break;
|
||||
}
|
||||
case 0x04: /* Get Instancing Exemptions */
|
||||
{
|
||||
/* On exit BX is bit flags denoting data that is instanced
|
||||
so Windows need not instance it. DOS 5&6 fail with DX=CX=0.
|
||||
0001h: Current Directory Structure
|
||||
0002h: System File Table and device status of STDOUT
|
||||
0004h: device driver chain
|
||||
0008h: Swappable Data Area
|
||||
*/
|
||||
r.DX = 0xA2AB; /* on succes DS:AX set to A2AB:B97Ch */
|
||||
r.AX = 0xB97C;
|
||||
r.BX = 0x0008; /* our whole data seg is instanced, so
|
||||
anything within it we assume instanced. */
|
||||
break;
|
||||
}
|
||||
case 0x05: /* get device driver size */
|
||||
{
|
||||
r.DX = 0; /* we aren't one so return unsupported */
|
||||
r.AX = 0;
|
||||
r.BX = 0;
|
||||
/* fall through to set CX=0 and exit */
|
||||
}
|
||||
case 0x02: /* disable Win support, ie remove patches */
|
||||
{
|
||||
/* Note: if we do anything special in 'patch DOS', undo it here.
|
||||
This is only called when Windows exits, can be ignored.
|
||||
*/
|
||||
r.CX = 0; /* for compatibility with MS-DOS 5/6 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} /* 0x07 */
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
else if (r.AH == 0x46) /* MS Windows WinOLDAP switching */
|
||||
{
|
||||
#ifdef WIN31SUPPORT /* See "DOS Internals" under DOSMGR or RBIL for details */
|
||||
if (r.AL == 0x01) /* save MCB */
|
||||
{
|
||||
/* To prevent corruption when dos=umb where Windows 3.0 standard
|
||||
writes a sentinel at 9FFEh, DOS 5 will save the MCB marking
|
||||
end of conventional memory (ie MCB following caller's PSP memory
|
||||
block [which I assume occupies all of convential memory] into
|
||||
the DOS data segment.
|
||||
Note: presumably Win3.1 uses the WinPatchTable.OffLastMCBSeg
|
||||
when DOS ver > 5 to do this itself.
|
||||
*/
|
||||
/* FIXME: Implement this! */
|
||||
}
|
||||
else if (r.AL == 0x02) /* restore MCB */
|
||||
{
|
||||
/* Copy the MCB we previously saved back. */
|
||||
/* FIXME: Implement this! */
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
/* else (r.AH == 0x12) */
|
||||
|
||||
switch (r.AL)
|
||||
{
|
||||
|
|
|
@ -291,10 +291,13 @@ _CDSp dd 0 ; 0016 Current Directory Structure
|
|||
_FCBp dd 0 ; 001a FCB table pointer
|
||||
global _nprotfcb
|
||||
_nprotfcb dw 0 ; 001e number of protected fcbs
|
||||
; unused for DOS 5+, see winPatchTable
|
||||
global _nblkdev
|
||||
_nblkdev db 0 ; 0020 number of block devices
|
||||
; should match # of DPBs
|
||||
global _lastdrive
|
||||
_lastdrive db 0 ; 0021 value of last drive
|
||||
; ie max logical drives, should match # of CDSs
|
||||
global _nul_dev
|
||||
_nul_dev: ; 0022 device chain root
|
||||
extern _con_dev:wrt LGROUP
|
||||
|
@ -348,10 +351,6 @@ _uppermem_root dw 0ffffh ; 0066 dmd_upper_root (usually 9fff)
|
|||
_last_para dw 0 ; 0068 para of last mem search
|
||||
SysVarEnd:
|
||||
;; FreeDOS specific entries
|
||||
global _os_setver_minor
|
||||
_os_setver_minor db 0
|
||||
global _os_setver_major
|
||||
_os_setver_major db 5
|
||||
global _os_minor
|
||||
_os_minor db 0
|
||||
global _os_major
|
||||
|
@ -368,6 +367,51 @@ _f_nodes_cnt dw 0
|
|||
extern _os_release
|
||||
os_release dw _os_release
|
||||
|
||||
%IFDEF WIN31SUPPORT
|
||||
global _winStartupInfo, _winInstanced
|
||||
_winInstanced dw 0 ; set to 1 on WinInit broadcast, 0 on WinExit broadcast
|
||||
_winStartupInfo:
|
||||
dw 0 ; structure version (same as windows version)
|
||||
dd 0 ; next startup info structure, 0:0h marks end
|
||||
dd 0 ; far pointer to name virtual device file or 0:0h
|
||||
dd 0 ; far pointer, reference data for virtual device driver
|
||||
dw instance_table,seg instance_table ; array of instance data
|
||||
instance_table: ; should include stacks, Win may auto determine SDA region
|
||||
; we simply include whole DOS data segment
|
||||
dw 0, seg _DATASTART ; [?linear?] address of region's base
|
||||
dw markEndInstanceData wrt seg _DATASTART ; size in bytes
|
||||
dd 0 ; 0 marks end of table
|
||||
dw 0
|
||||
global _winPatchTable
|
||||
_winPatchTable: ; returns offsets to various internal variables
|
||||
%ENDIF ; WIN31SUPPORT
|
||||
; os version reported, patch table includes DOS version
|
||||
; so we include it here to save duplicate data, but even
|
||||
; without WIN31SUPPORT enabled these variables are used.
|
||||
; The setver variants are used so we report to Windows
|
||||
; editable (fake) DOS version user wanted.
|
||||
global _os_setver_minor, _os_setver_major
|
||||
_os_setver_major db 0
|
||||
_os_setver_minor db 0
|
||||
%IFDEF WIN31SUPPORT
|
||||
dw dummy ; where DS stored during int21h dispatch
|
||||
dw dummy ; where BX stored during int21h dispatch
|
||||
dw _InDOS ; offset of InDOS flag
|
||||
dw _MachineId ; offset to variable containing MachineID
|
||||
dw _nprotfcb ; offset of to arrary of offsets to patch
|
||||
; NOTE: this points to a null terminated
|
||||
; array of offsets of critical section bytes
|
||||
; to patch, for now we just point this to
|
||||
; an empty table, so to save space we are
|
||||
; reusing _nprotfcb as it is unused and
|
||||
; can ?safely? be assumed to stay 0
|
||||
; ie we just point to a 0 word to mark end
|
||||
; FIXME is uppermem_root correct? or do what should we use?
|
||||
dw _uppermem_root ; seg of last arena header in conv memory
|
||||
dummy dw 0 ;
|
||||
;patch_bytes dw 0 ; mark end of array of offsets of critical section bytes to patch
|
||||
%ENDIF ; WIN31SUPPORT
|
||||
|
||||
;; The first 5 sft entries appear to have to be at DS:00cc
|
||||
times (0cch - ($ - DATASTART)) db 0
|
||||
global _firstsftt
|
||||
|
@ -695,6 +739,9 @@ segment DYN_DATA
|
|||
global _Dyn
|
||||
_Dyn:
|
||||
DynAllocated dw 0
|
||||
|
||||
markEndInstanceData: ; mark end of DOS data seg we say needs instancing
|
||||
|
||||
|
||||
segment ID_B
|
||||
global __INIT_DATA_START
|
||||
|
|
Loading…
Reference in New Issue