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:
Kenneth J Davis 2005-01-31 04:08:39 +00:00
parent bae20d0533
commit 65d87b42c4
6 changed files with 278 additions and 15 deletions

View File

@ -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

View File

@ -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 */

38
hdr/win.h Normal file
View File

@ -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 */

View File

@ -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

View File

@ -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)
{

View File

@ -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