mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-24 22:34:29 +02:00
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 you MUST specify value to define with /D option
|
||||||
if "%1" == "" echo such as /D DEBUG : extra DEBUG output
|
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 DOSEMU : printf output goes to dosemu log
|
||||||
|
if "%1" == "" echo or /D WIN31SUPPORT : enable Win 3.x hooks
|
||||||
if "%1" == "" goto abort
|
if "%1" == "" goto abort
|
||||||
set ALLCFLAGS=%ALLCFLAGS% -D%1
|
set ALLCFLAGS=%ALLCFLAGS% -D%1
|
||||||
|
set NASMFLAGS=%NASMFLAGS% -D%1
|
||||||
goto nextOption
|
goto nextOption
|
||||||
|
|
||||||
:noenv
|
: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 uppermem_root;/* 66 Start of umb chain (usually 9fff) */
|
||||||
unsigned short last_para; /* 68 para: start scanning during memalloc */
|
unsigned short last_para; /* 68 para: start scanning during memalloc */
|
||||||
/* FreeDOS specific entries */
|
/* FreeDOS specific entries */
|
||||||
unsigned char os_setver_minor;/*6a settable minor DOS version */
|
unsigned char os_minor; /* 6a minor DOS version */
|
||||||
unsigned char os_setver_major;/*6b settable major DOS version */
|
unsigned char os_major; /* 6b major DOS version */
|
||||||
unsigned char os_minor; /* 6c minor DOS version */
|
unsigned char rev_number; /* 6c minor DOS version */
|
||||||
unsigned char os_major; /* 6d major DOS version */
|
unsigned char version_flags; /* 6d DOS version flags */
|
||||||
unsigned char rev_number; /* 6e minor DOS version */
|
struct f_node FAR *f_nodes; /* 6e pointer to the array */
|
||||||
unsigned char version_flags; /* 6f DOS version flags */
|
unsigned short f_nodes_cnt; /* 72 number of allocated f_nodes */
|
||||||
struct f_node FAR *f_nodes; /* 70 pointer to the array */
|
char *os_release; /* 74 near pointer to os_release string */
|
||||||
unsigned short f_nodes_cnt; /* 74 number of allocated f_nodes */
|
#ifdef WIN31SUPPORT
|
||||||
char *os_release; /* 76 near pointer to os_release string */
|
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 */
|
#endif /* __LOL_H */
|
||||||
|
38
hdr/win.h
Normal file
38
hdr/win.h
Normal 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 */
|
@ -54,10 +54,12 @@ Int2f2:
|
|||||||
FarTabRetn:
|
FarTabRetn:
|
||||||
retf 2 ; Return far
|
retf 2 ; Return far
|
||||||
Int2f3:
|
Int2f3:
|
||||||
cmp ah,16h
|
|
||||||
je FarTabRetn ; Win Hook return fast
|
|
||||||
cmp ah,12h
|
cmp ah,12h
|
||||||
je IntDosCal ; Dos Internal calls
|
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
|
cmp ax,4a01h
|
||||||
je IntDosCal ; Dos Internal calls
|
je IntDosCal ; Dos Internal calls
|
||||||
@ -108,6 +110,7 @@ DriverSysCal:
|
|||||||
|
|
||||||
;**********************************************************************
|
;**********************************************************************
|
||||||
; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C
|
; internal dos calls INT2F/12xx and INT2F/4A01,4A02 - handled through C
|
||||||
|
; also handle Windows' DOS notification hooks
|
||||||
;**********************************************************************
|
;**********************************************************************
|
||||||
IntDosCal:
|
IntDosCal:
|
||||||
; set up register frame
|
; set up register frame
|
||||||
|
@ -59,6 +59,11 @@ struct HugeSectorBlock {
|
|||||||
BYTE FAR *buf;
|
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 */
|
/* Normal entry. This minimizes user stack usage by avoiding local */
|
||||||
/* variables needed for the rest of the handler. */
|
/* variables needed for the rest of the handler. */
|
||||||
/* this here works on the users stack !! and only very few functions
|
/* 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()
|
/* 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
|
||||||
*/
|
*/
|
||||||
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||||
{
|
{
|
||||||
@ -1722,6 +1728,168 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
|||||||
r.BX = size;
|
r.BX = size;
|
||||||
return;
|
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)
|
switch (r.AL)
|
||||||
{
|
{
|
||||||
|
@ -291,10 +291,13 @@ _CDSp dd 0 ; 0016 Current Directory Structure
|
|||||||
_FCBp dd 0 ; 001a FCB table pointer
|
_FCBp dd 0 ; 001a FCB table pointer
|
||||||
global _nprotfcb
|
global _nprotfcb
|
||||||
_nprotfcb dw 0 ; 001e number of protected fcbs
|
_nprotfcb dw 0 ; 001e number of protected fcbs
|
||||||
|
; unused for DOS 5+, see winPatchTable
|
||||||
global _nblkdev
|
global _nblkdev
|
||||||
_nblkdev db 0 ; 0020 number of block devices
|
_nblkdev db 0 ; 0020 number of block devices
|
||||||
|
; should match # of DPBs
|
||||||
global _lastdrive
|
global _lastdrive
|
||||||
_lastdrive db 0 ; 0021 value of last drive
|
_lastdrive db 0 ; 0021 value of last drive
|
||||||
|
; ie max logical drives, should match # of CDSs
|
||||||
global _nul_dev
|
global _nul_dev
|
||||||
_nul_dev: ; 0022 device chain root
|
_nul_dev: ; 0022 device chain root
|
||||||
extern _con_dev:wrt LGROUP
|
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
|
_last_para dw 0 ; 0068 para of last mem search
|
||||||
SysVarEnd:
|
SysVarEnd:
|
||||||
;; FreeDOS specific entries
|
;; FreeDOS specific entries
|
||||||
global _os_setver_minor
|
|
||||||
_os_setver_minor db 0
|
|
||||||
global _os_setver_major
|
|
||||||
_os_setver_major db 5
|
|
||||||
global _os_minor
|
global _os_minor
|
||||||
_os_minor db 0
|
_os_minor db 0
|
||||||
global _os_major
|
global _os_major
|
||||||
@ -368,6 +367,51 @@ _f_nodes_cnt dw 0
|
|||||||
extern _os_release
|
extern _os_release
|
||||||
os_release dw _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
|
;; The first 5 sft entries appear to have to be at DS:00cc
|
||||||
times (0cch - ($ - DATASTART)) db 0
|
times (0cch - ($ - DATASTART)) db 0
|
||||||
global _firstsftt
|
global _firstsftt
|
||||||
@ -695,6 +739,9 @@ segment DYN_DATA
|
|||||||
global _Dyn
|
global _Dyn
|
||||||
_Dyn:
|
_Dyn:
|
||||||
DynAllocated dw 0
|
DynAllocated dw 0
|
||||||
|
|
||||||
|
markEndInstanceData: ; mark end of DOS data seg we say needs instancing
|
||||||
|
|
||||||
|
|
||||||
segment ID_B
|
segment ID_B
|
||||||
global __INIT_DATA_START
|
global __INIT_DATA_START
|
||||||
|
Loading…
x
Reference in New Issue
Block a user