Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
9d7ff6c8
Commit
9d7ff6c8
authored
Dec 15, 2002
by
Jukka Heinonen
Committed by
Alexandre Julliard
Dec 15, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for DPMI32. Make winedos16.dll unnecessary.
parent
91c6f817
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
488 additions
and
157 deletions
+488
-157
Makefile.in
dlls/winedos/Makefile.in
+1
-1
dosexe.h
dlls/winedos/dosexe.h
+16
-0
himem.c
dlls/winedos/himem.c
+40
-1
int31.c
dlls/winedos/int31.c
+8
-48
interrupts.c
dlls/winedos/interrupts.c
+161
-68
relay.c
dlls/winedos/relay.c
+262
-0
winedos16.spec
dlls/winedos/winedos16.spec
+0
-39
No files found.
dlls/winedos/Makefile.in
View file @
9d7ff6c8
...
@@ -4,7 +4,6 @@ SRCDIR = @srcdir@
...
@@ -4,7 +4,6 @@ SRCDIR = @srcdir@
VPATH
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
winedos.dll
MODULE
=
winedos.dll
IMPORTS
=
user32 advapi32 kernel32 ntdll
IMPORTS
=
user32 advapi32 kernel32 ntdll
ALTNAMES
=
winedos16.dll
EXTRALIBS
=
$(LIBUNICODE)
EXTRALIBS
=
$(LIBUNICODE)
LDDLLFLAGS
=
@LDDLLFLAGS@
LDDLLFLAGS
=
@LDDLLFLAGS@
...
@@ -43,6 +42,7 @@ C_SRCS = \
...
@@ -43,6 +42,7 @@ C_SRCS = \
interrupts.c
\
interrupts.c
\
ioports.c
\
ioports.c
\
module.c
\
module.c
\
relay.c
\
soundblaster.c
\
soundblaster.c
\
vga.c
\
vga.c
\
xms.c
xms.c
...
...
dlls/winedos/dosexe.h
View file @
9d7ff6c8
...
@@ -28,6 +28,10 @@
...
@@ -28,6 +28,10 @@
#include "miscemu.h"
#include "miscemu.h"
struct
_DOSEVENT
;
struct
_DOSEVENT
;
struct
_STACK16FRAME
;
/* amount of space reserved for relay stack */
#define DOSVM_RELAY_DATA_SIZE 4096
/* various real-mode code stubs */
/* various real-mode code stubs */
struct
DPMI_segments
struct
DPMI_segments
...
@@ -37,6 +41,9 @@ struct DPMI_segments
...
@@ -37,6 +41,9 @@ struct DPMI_segments
WORD
dpmi_seg
;
WORD
dpmi_seg
;
WORD
dpmi_sel
;
WORD
dpmi_sel
;
WORD
int48_sel
;
WORD
int48_sel
;
WORD
int16_sel
;
WORD
relay_code_sel
;
WORD
relay_data_sel
;
};
};
/* 48-bit segmented pointers for DOS DPMI32 */
/* 48-bit segmented pointers for DOS DPMI32 */
...
@@ -67,6 +74,8 @@ extern struct DPMI_segments *DOSVM_dpmi_segments;
...
@@ -67,6 +74,8 @@ extern struct DPMI_segments *DOSVM_dpmi_segments;
#define BIOS_DATA ((void *)0x400)
#define BIOS_DATA ((void *)0x400)
#define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
/* module.c */
/* module.c */
extern
void
WINAPI
MZ_LoadImage
(
LPCSTR
filename
,
HANDLE
hFile
);
extern
void
WINAPI
MZ_LoadImage
(
LPCSTR
filename
,
HANDLE
hFile
);
extern
BOOL
WINAPI
MZ_Exec
(
CONTEXT86
*
context
,
LPCSTR
filename
,
BYTE
func
,
LPVOID
paramblk
);
extern
BOOL
WINAPI
MZ_Exec
(
CONTEXT86
*
context
,
LPCSTR
filename
,
BYTE
func
,
LPVOID
paramblk
);
...
@@ -181,6 +190,7 @@ extern void WINAPI DOSVM_Int2fHandler(CONTEXT86*);
...
@@ -181,6 +190,7 @@ extern void WINAPI DOSVM_Int2fHandler(CONTEXT86*);
/* int31.c */
/* int31.c */
extern
void
WINAPI
DOSVM_Int31Handler
(
CONTEXT86
*
);
extern
void
WINAPI
DOSVM_Int31Handler
(
CONTEXT86
*
);
extern
void
WINAPI
DOSVM_RawModeSwitchHandler
(
CONTEXT86
*
);
extern
BOOL
DOSVM_IsDos32
(
void
);
extern
BOOL
DOSVM_IsDos32
(
void
);
extern
FARPROC16
WINAPI
DPMI_AllocInternalRMCB
(
RMCBPROC
);
extern
FARPROC16
WINAPI
DPMI_AllocInternalRMCB
(
RMCBPROC
);
extern
void
WINAPI
DPMI_FreeInternalRMCB
(
FARPROC16
);
extern
void
WINAPI
DPMI_FreeInternalRMCB
(
FARPROC16
);
...
@@ -213,6 +223,12 @@ extern FARPROC48 DOSVM_GetPMHandler48( BYTE intnum );
...
@@ -213,6 +223,12 @@ extern FARPROC48 DOSVM_GetPMHandler48( BYTE intnum );
extern
void
DOSVM_SetPMHandler48
(
BYTE
intnum
,
FARPROC48
handler
);
extern
void
DOSVM_SetPMHandler48
(
BYTE
intnum
,
FARPROC48
handler
);
extern
INTPROC
DOSVM_GetBuiltinHandler
(
BYTE
intnum
);
extern
INTPROC
DOSVM_GetBuiltinHandler
(
BYTE
intnum
);
/* relay.c */
void
DOSVM_RelayHandler
(
CONTEXT86
*
);
void
DOSVM_SaveCallFrame
(
CONTEXT86
*
,
struct
_STACK16FRAME
*
);
void
DOSVM_RestoreCallFrame
(
CONTEXT86
*
,
struct
_STACK16FRAME
*
);
void
DOSVM_BuildCallFrame
(
CONTEXT86
*
,
DOSRELAY
,
LPVOID
);
/* soundblaster.c */
/* soundblaster.c */
extern
void
SB_ioport_out
(
WORD
port
,
BYTE
val
);
extern
void
SB_ioport_out
(
WORD
port
,
BYTE
val
);
extern
BYTE
SB_ioport_in
(
WORD
port
);
extern
BYTE
SB_ioport_in
(
WORD
port
);
...
...
dlls/winedos/himem.c
View file @
9d7ff6c8
...
@@ -178,6 +178,12 @@ void DOSVM_InitSegments( void )
...
@@ -178,6 +178,12 @@ void DOSVM_InitSegments( void )
0xCB
/* lret */
0xCB
/* lret */
};
};
static
const
char
relay
[]
=
{
0xca
,
0x04
,
0x00
,
/* 16-bit far return and pop 4 bytes (relay void* arg) */
0xcd
,
0x31
/* int 31 */
};
/*
/*
* Allocate pointer array.
* Allocate pointer array.
*/
*/
...
@@ -216,7 +222,7 @@ void DOSVM_InitSegments( void )
...
@@ -216,7 +222,7 @@ void DOSVM_InitSegments( void )
/*
/*
* Each 32-bit interrupt handler is 6 bytes:
* Each 32-bit interrupt handler is 6 bytes:
* 0xCD,<i> = int <i> (nested 16-bit interrupt)
* 0xCD,<i> = int <i> (nested 16-bit interrupt)
* 0x66,0xCA,0x04,0x00 = ret 4 (32-bit far return and pop 4 bytes)
* 0x66,0xCA,0x04,0x00 = ret 4 (32-bit far return and pop 4 bytes
/ eflags
)
*/
*/
ptr
[
i
*
6
+
0
]
=
0xCD
;
ptr
[
i
*
6
+
0
]
=
0xCD
;
ptr
[
i
*
6
+
1
]
=
i
;
ptr
[
i
*
6
+
1
]
=
i
;
...
@@ -225,4 +231,37 @@ void DOSVM_InitSegments( void )
...
@@ -225,4 +231,37 @@ void DOSVM_InitSegments( void )
ptr
[
i
*
6
+
4
]
=
0x04
;
ptr
[
i
*
6
+
4
]
=
0x04
;
ptr
[
i
*
6
+
5
]
=
0x00
;
ptr
[
i
*
6
+
5
]
=
0x00
;
}
}
/*
* PM / offset N*5: Interrupt N in 16-bit protected mode.
*/
ptr
=
DOSVM_AllocCodeUMB
(
5
*
256
,
0
,
&
DOSVM_dpmi_segments
->
int16_sel
);
for
(
i
=
0
;
i
<
256
;
i
++
)
{
/*
* Each 16-bit interrupt handler is 5 bytes:
* 0xCD,<i> = int <i> (interrupt)
* 0xCA,0x02,0x00 = ret 2 (16-bit far return and pop 2 bytes / eflags)
*/
ptr
[
i
*
5
+
0
]
=
0xCD
;
ptr
[
i
*
5
+
1
]
=
i
;
ptr
[
i
*
5
+
2
]
=
0xCA
;
ptr
[
i
*
5
+
3
]
=
0x02
;
ptr
[
i
*
5
+
4
]
=
0x00
;
}
/*
* PM / offset 0: Stub where __wine_call_from_16_regs returns.
* PM / offset 3: Stub which swaps back to 32-bit application code/stack.
*/
ptr
=
DOSVM_AllocCodeUMB
(
sizeof
(
relay
),
0
,
&
DOSVM_dpmi_segments
->
relay_code_sel
);
memcpy
(
ptr
,
relay
,
sizeof
(
relay
)
);
/*
* Space for 16-bit stack used by relay code.
*/
ptr
=
DOSVM_AllocDataUMB
(
DOSVM_RELAY_DATA_SIZE
,
0
,
&
DOSVM_dpmi_segments
->
relay_data_sel
);
memset
(
ptr
,
0
,
DOSVM_RELAY_DATA_SIZE
);
}
}
dlls/winedos/int31.c
View file @
9d7ff6c8
...
@@ -722,52 +722,21 @@ void WINAPI DOSVM_FreeRMCB( CONTEXT86 *context )
...
@@ -722,52 +722,21 @@ void WINAPI DOSVM_FreeRMCB( CONTEXT86 *context )
}
}
}
}
/**********************************************************************
/**********************************************************************
* DOSVM_RawModeSwitch
Wrapp
er
* DOSVM_RawModeSwitch
Handl
er
*
*
* DPMI Raw Mode Switch
wrapp
er.
* DPMI Raw Mode Switch
handl
er.
* This routine does all the stack manipulation tricks needed
* This routine does all the stack manipulation tricks needed
* to return from protected mode interrupt using modified
* to return from protected mode interrupt using modified
* code and stack pointers.
* code and stack pointers.
*/
*/
static
void
DOSVM_RawModeSwitchWrapp
er
(
CONTEXT86
*
context
)
void
WINAPI
DOSVM_RawModeSwitchHandl
er
(
CONTEXT86
*
context
)
{
{
/*
STACK16FRAME
frame
;
* FIXME: This routine will not work if it is called
DOSVM_SaveCallFrame
(
context
,
&
frame
);
* from 32 bit DPMI program and the program returns
* to protected mode while ESP or EIP is over 0xffff.
* FIXME: This routine will not work if it is not called
* using 16-bit-to-Wine callback glue function.
*/
STACK16FRAME
frame
=
*
CURRENT_STACK16
;
DOSVM_RawModeSwitch
(
context
);
DOSVM_RawModeSwitch
(
context
);
DOSVM_RestoreCallFrame
(
context
,
&
frame
);
/*
* After this function returns to relay code, protected mode
* 16 bit stack will contain STACK16FRAME and single WORD
* (EFlags, see next comment).
*/
NtCurrentTeb
()
->
cur_stack
=
MAKESEGPTR
(
context
->
SegSs
,
context
->
Esp
-
sizeof
(
STACK16FRAME
)
-
sizeof
(
WORD
)
);
/*
* After relay code returns to glue function, protected
* mode 16 bit stack will contain interrupt return record:
* IP, CS and EFlags. Since EFlags is ignored, it won't
* need to be initialized.
*/
context
->
Esp
-=
3
*
sizeof
(
WORD
);
/*
* Restore stack frame so that relay code won't be confused.
* It should be noted that relay code overwrites IP and CS
* in STACK16FRAME with values taken from current CONTEXT86.
* These values are what is returned to glue function
* (see previous comment).
*/
*
CURRENT_STACK16
=
frame
;
}
}
...
@@ -781,15 +750,6 @@ static void DOSVM_RawModeSwitchWrapper( CONTEXT86 *context )
...
@@ -781,15 +750,6 @@ static void DOSVM_RawModeSwitchWrapper( CONTEXT86 *context )
*/
*/
static
BOOL
DOSVM_CheckWrappers
(
CONTEXT86
*
context
)
static
BOOL
DOSVM_CheckWrappers
(
CONTEXT86
*
context
)
{
{
/* Handle protected mode interrupts. */
if
(
!
ISV86
(
context
))
{
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
dpmi_sel
)
{
DOSVM_RawModeSwitchWrapper
(
context
);
return
TRUE
;
}
return
FALSE
;
}
/* check if it's our wrapper */
/* check if it's our wrapper */
TRACE
(
"called from real mode
\n
"
);
TRACE
(
"called from real mode
\n
"
);
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
dpmi_seg
)
{
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
dpmi_seg
)
{
...
@@ -828,7 +788,7 @@ static BOOL DOSVM_CheckWrappers( CONTEXT86 *context )
...
@@ -828,7 +788,7 @@ static BOOL DOSVM_CheckWrappers( CONTEXT86 *context )
*/
*/
void
WINAPI
DOSVM_Int31Handler
(
CONTEXT86
*
context
)
void
WINAPI
DOSVM_Int31Handler
(
CONTEXT86
*
context
)
{
{
if
(
DOSVM_CheckWrappers
(
context
))
if
(
ISV86
(
context
)
&&
DOSVM_CheckWrappers
(
context
))
return
;
return
;
RESET_CFLAG
(
context
);
RESET_CFLAG
(
context
);
...
...
dlls/winedos/interrupts.c
View file @
9d7ff6c8
...
@@ -56,11 +56,9 @@ static const INTPROC DOSVM_VectorsBuiltin[] =
...
@@ -56,11 +56,9 @@ static const INTPROC DOSVM_VectorsBuiltin[] =
/* 64 */
0
,
0
,
0
,
DOSVM_Int67Handler
/* 64 */
0
,
0
,
0
,
DOSVM_Int67Handler
};
};
/* Ordinal number for interrupt 0 handler in winedos16.dll */
#define FIRST_INTERRUPT 100
/**********************************************************************
/**********************************************************************
* DOSVM_DefaultHandler
(WINEDOS16.356)
* DOSVM_DefaultHandler
*
*
* Default interrupt handler. This will be used to emulate all
* Default interrupt handler. This will be used to emulate all
* interrupts that don't have their own interrupt handler.
* interrupts that don't have their own interrupt handler.
...
@@ -69,6 +67,70 @@ void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
...
@@ -69,6 +67,70 @@ void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
{
{
}
}
/**********************************************************************
* DOSVM_IntProcRelay
*
* Simple DOSRELAY that interprets its argument as INTPROC and calls it.
*/
static
void
DOSVM_IntProcRelay
(
CONTEXT86
*
context
,
LPVOID
data
)
{
INTPROC
proc
=
(
INTPROC
)
data
;
proc
(
context
);
}
/**********************************************************************
* DOSVM_PushFlags
*
* This routine is used to make default int25 and int26 handlers leave the
* original eflags into stack. In order to do this, stack is manipulated
* so that it actually contains two copies of eflags, one of which is
* popped during return from interrupt handler.
*/
static
void
DOSVM_PushFlags
(
CONTEXT86
*
context
,
BOOL
islong
,
BOOL
isstub
)
{
if
(
islong
)
{
DWORD
*
stack
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegSs
,
context
->
Esp
);
context
->
Esp
+=
-
4
;
/* One item will be added to stack. */
if
(
isstub
)
{
DWORD
ip
=
stack
[
0
];
DWORD
cs
=
stack
[
1
];
stack
+=
2
;
/* Pop ip and cs. */
*
(
--
stack
)
=
context
->
EFlags
;
*
(
--
stack
)
=
cs
;
*
(
--
stack
)
=
ip
;
}
else
*
(
--
stack
)
=
context
->
EFlags
;
}
else
{
WORD
*
stack
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegSs
,
context
->
Esp
);
ADD_LOWORD
(
context
->
Esp
,
-
2
);
/* One item will be added to stack. */
if
(
isstub
)
{
WORD
ip
=
stack
[
0
];
WORD
cs
=
stack
[
1
];
stack
+=
2
;
/* Pop ip and cs. */
*
(
--
stack
)
=
LOWORD
(
context
->
EFlags
);
*
(
--
stack
)
=
cs
;
*
(
--
stack
)
=
ip
;
}
else
*
(
--
stack
)
=
LOWORD
(
context
->
EFlags
);
}
}
/**********************************************************************
/**********************************************************************
* DOSVM_EmulateInterruptPM
* DOSVM_EmulateInterruptPM
*
*
...
@@ -80,49 +142,97 @@ void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
...
@@ -80,49 +142,97 @@ void WINAPI DOSVM_DefaultHandler( CONTEXT86 *context )
*/
*/
void
WINAPI
DOSVM_EmulateInterruptPM
(
CONTEXT86
*
context
,
BYTE
intnum
)
void
WINAPI
DOSVM_EmulateInterruptPM
(
CONTEXT86
*
context
,
BYTE
intnum
)
{
{
BOOL
islong
;
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
dpmi_sel
)
{
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
int48_sel
)
DOSVM_BuildCallFrame
(
context
,
islong
=
FALSE
;
DOSVM_IntProcRelay
,
else
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
dpmi_sel
)
DOSVM_RawModeSwitchHandler
);
islong
=
FALSE
;
}
else
if
(
DOSVM_IsDos32
())
else
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
relay_code_sel
)
islong
=
TRUE
;
{
else
if
(
IS_SELECTOR_32BIT
(
context
->
SegCs
))
{
/*
WARN
(
"Interrupt in 32-bit code and mode is not DPMI32
\n
"
);
* This must not be called using DOSVM_BuildCallFrame.
islong
=
TRUE
;
*/
}
else
DOSVM_RelayHandler
(
context
);
islong
=
FALSE
;
}
else
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
int48_sel
)
if
(
islong
)
{
{
if
(
intnum
==
0x25
||
intnum
==
0x26
)
FARPROC48
addr
=
DOSVM_GetPMHandler48
(
intnum
);
DOSVM_PushFlags
(
context
,
TRUE
,
TRUE
);
DWORD
*
stack
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegSs
,
context
->
Esp
);
/* Push the flags and return address on the stack */
DOSVM_BuildCallFrame
(
context
,
*
(
--
stack
)
=
context
->
EFlags
;
DOSVM_IntProcRelay
,
*
(
--
stack
)
=
context
->
SegCs
;
DOSVM_GetBuiltinHandler
(
intnum
)
);
*
(
--
stack
)
=
context
->
Eip
;
}
/* Jump to the interrupt handler */
else
if
(
context
->
SegCs
==
DOSVM_dpmi_segments
->
int16_sel
)
context
->
SegCs
=
addr
.
selector
;
{
context
->
Eip
=
addr
.
offset
;
if
(
intnum
==
0x25
||
intnum
==
0x26
)
}
DOSVM_PushFlags
(
context
,
FALSE
,
TRUE
);
else
{
DOSVM_BuildCallFrame
(
context
,
FARPROC16
addr
=
DOSVM_GetPMHandler16
(
intnum
);
DOSVM_IntProcRelay
,
WORD
*
stack
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegSs
,
context
->
Esp
);
DOSVM_GetBuiltinHandler
(
intnum
)
);
/* Push the flags and return address on the stack */
}
*
(
--
stack
)
=
LOWORD
(
context
->
EFlags
);
else
if
(
DOSVM_IsDos32
())
*
(
--
stack
)
=
context
->
SegCs
;
{
*
(
--
stack
)
=
LOWORD
(
context
->
Eip
);
FARPROC48
addr
=
DOSVM_GetPMHandler48
(
intnum
);
/* Jump to the interrupt handler */
context
->
SegCs
=
HIWORD
(
addr
);
if
(
addr
.
selector
==
DOSVM_dpmi_segments
->
int48_sel
)
context
->
Eip
=
LOWORD
(
addr
);
{
}
if
(
intnum
==
0x25
||
intnum
==
0x26
)
DOSVM_PushFlags
(
context
,
TRUE
,
FALSE
);
DOSVM_BuildCallFrame
(
context
,
DOSVM_IntProcRelay
,
DOSVM_GetBuiltinHandler
(
intnum
)
);
}
else
{
DWORD
*
stack
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegSs
,
context
->
Esp
);
/* Push the flags and return address on the stack */
*
(
--
stack
)
=
context
->
EFlags
;
*
(
--
stack
)
=
context
->
SegCs
;
*
(
--
stack
)
=
context
->
Eip
;
context
->
Esp
+=
-
12
;
/* Jump to the interrupt handler */
context
->
SegCs
=
addr
.
selector
;
context
->
Eip
=
addr
.
offset
;
}
}
else
{
FARPROC16
addr
=
DOSVM_GetPMHandler16
(
intnum
);
if
(
SELECTOROF
(
addr
)
==
DOSVM_dpmi_segments
->
int16_sel
)
{
if
(
intnum
==
0x25
||
intnum
==
0x26
)
DOSVM_PushFlags
(
context
,
FALSE
,
FALSE
);
if
(
IS_SELECTOR_32BIT
(
context
->
SegSs
))
DOSVM_BuildCallFrame
(
context
,
context
->
Esp
+=
islong
?
-
12
:
-
6
;
DOSVM_IntProcRelay
,
else
DOSVM_GetBuiltinHandler
(
intnum
)
);
context
->
Esp
=
(
context
->
Esp
&
~
0xffff
)
|
(
WORD
)((
context
->
Esp
&
0xffff
)
+
(
islong
?
-
12
:
-
6
));
}
else
{
WORD
*
stack
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegSs
,
context
->
Esp
);
/* Push the flags and return address on the stack */
*
(
--
stack
)
=
LOWORD
(
context
->
EFlags
);
*
(
--
stack
)
=
context
->
SegCs
;
*
(
--
stack
)
=
LOWORD
(
context
->
Eip
);
ADD_LOWORD
(
context
->
Esp
,
-
6
);
/* Jump to the interrupt handler */
context
->
SegCs
=
HIWORD
(
addr
);
context
->
Eip
=
LOWORD
(
addr
);
}
}
}
}
/**********************************************************************
/**********************************************************************
...
@@ -147,6 +257,7 @@ void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
...
@@ -147,6 +257,7 @@ void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
((
FARPROC16
*
)
0
)[
intnum
]
=
handler
;
((
FARPROC16
*
)
0
)[
intnum
]
=
handler
;
}
}
/**********************************************************************
/**********************************************************************
* DOSVM_GetPMHandler16
* DOSVM_GetPMHandler16
*
*
...
@@ -154,31 +265,13 @@ void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
...
@@ -154,31 +265,13 @@ void DOSVM_SetRMHandler( BYTE intnum, FARPROC16 handler )
*/
*/
FARPROC16
DOSVM_GetPMHandler16
(
BYTE
intnum
)
FARPROC16
DOSVM_GetPMHandler16
(
BYTE
intnum
)
{
{
static
HMODULE16
procs
;
if
(
!
DOSVM_Vectors16
[
intnum
])
FARPROC16
handler
=
DOSVM_Vectors16
[
intnum
];
if
(
!
handler
)
{
if
(
!
procs
&&
(
procs
=
GetModuleHandle16
(
"winedos16"
))
<
32
&&
(
procs
=
LoadLibrary16
(
"winedos16"
))
<
32
)
{
{
ERR
(
"could not load winedos16.dll
\n
"
);
FARPROC16
proc
=
(
FARPROC16
)
MAKESEGPTR
(
DOSVM_dpmi_segments
->
int16_sel
,
procs
=
0
;
5
*
intnum
)
;
return
0
;
DOSVM_Vectors16
[
intnum
]
=
proc
;
}
}
return
DOSVM_Vectors16
[
intnum
];
handler
=
GetProcAddress16
(
procs
,
(
LPCSTR
)(
FIRST_INTERRUPT
+
intnum
));
if
(
!
handler
)
{
WARN
(
"int%x not implemented, returning dummy handler
\n
"
,
intnum
);
handler
=
GetProcAddress16
(
procs
,
(
LPCSTR
)(
FIRST_INTERRUPT
+
256
));
}
DOSVM_Vectors16
[
intnum
]
=
handler
;
}
return
handler
;
}
}
...
...
dlls/winedos/relay.c
0 → 100644
View file @
9d7ff6c8
/*
* Routines for dynamically building calls to Wine from
* protected mode applications.
*
* Copyright 2002 Jukka Heinonen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "dosexe.h"
#include "stackframe.h"
#include "wine/debug.h"
#include "builtin16.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
int
);
/*
* Magic DWORD used to check stack integrity.
*/
#define RELAY_MAGIC 0xabcdef00
/*
* Memory block for temporary 16-bit stacks used when
* 32-bit code calls relay.
*/
typedef
struct
{
DWORD
inuse
;
/* non-zero if stack block is in use */
DWORD
eip
;
/* saved ip */
DWORD
seg_cs
;
/* saved cs */
DWORD
esp
;
/* saved sp */
DWORD
seg_ss
;
/* saved ss */
DWORD
stack_bottom
;
/* guard dword */
BYTE
stack
[
256
-
7
*
4
];
/* 16-bit stack */
DWORD
stack_top
;
/* guard dword */
}
RELAY_Stack16
;
/**********************************************************************
* RELAY_GetPointer
*
* Get pointer to stack block when given esp pointing to 16-bit stack
* inside relay data segment.
*/
static
RELAY_Stack16
*
RELAY_GetPointer
(
DWORD
offset
)
{
offset
=
offset
/
sizeof
(
RELAY_Stack16
)
*
sizeof
(
RELAY_Stack16
);
return
MapSL
(
MAKESEGPTR
(
DOSVM_dpmi_segments
->
relay_data_sel
,
offset
));
}
/**********************************************************************
* RELAY_MakeShortContext
*
* If context is using 32-bit stack or code segment, allocate
* 16-bit stack, make stack pointer point to this stack and
* make code pointer point to stub that restores everything.
* So, after this routine, SS and CS are guaranteed to be 16-bit.
*
* Note: This might be called from signal handler, so the stack
* allocation algorithm must be signal safe.
*/
static
void
RELAY_MakeShortContext
(
CONTEXT86
*
context
)
{
if
(
IS_SELECTOR_32BIT
(
context
->
SegCs
)
||
IS_SELECTOR_32BIT
(
context
->
SegSs
))
{
DWORD
offset
=
offsetof
(
RELAY_Stack16
,
stack_top
);
RELAY_Stack16
*
stack
=
RELAY_GetPointer
(
0
);
while
(
stack
->
inuse
&&
offset
<
DOSVM_RELAY_DATA_SIZE
)
{
stack
++
;
offset
+=
sizeof
(
RELAY_Stack16
);
}
if
(
offset
>=
DOSVM_RELAY_DATA_SIZE
)
ERR
(
"Too many nested interrupts!
\n
"
);
stack
->
inuse
=
1
;
stack
->
eip
=
context
->
Eip
;
stack
->
seg_cs
=
context
->
SegCs
;
stack
->
esp
=
context
->
Esp
;
stack
->
seg_ss
=
context
->
SegSs
;
stack
->
stack_bottom
=
RELAY_MAGIC
;
stack
->
stack_top
=
RELAY_MAGIC
;
context
->
SegSs
=
DOSVM_dpmi_segments
->
relay_data_sel
;
context
->
Esp
=
offset
;
context
->
SegCs
=
DOSVM_dpmi_segments
->
relay_code_sel
;
context
->
Eip
=
3
;
}
}
/**********************************************************************
* RELAY_RelayStub
*
* This stub is called by __wine_call_from_16_regs in order to marshall
* relay parameters.
*/
static
void
__stdcall
RELAY_RelayStub
(
DOSRELAY
proc
,
unsigned
char
*
args
,
void
*
context
)
{
proc
(
(
CONTEXT86
*
)
context
,
*
(
LPVOID
*
)
args
);
}
/**********************************************************************
* DOSVM_RelayHandler
*
* Restore saved code and stack pointers and release stack block.
*/
void
DOSVM_RelayHandler
(
CONTEXT86
*
context
)
{
RELAY_Stack16
*
stack
=
RELAY_GetPointer
(
context
->
Esp
);
context
->
SegSs
=
stack
->
seg_ss
;
context
->
Esp
=
stack
->
esp
;
context
->
SegCs
=
stack
->
seg_cs
;
context
->
Eip
=
stack
->
eip
;
if
(
!
stack
->
inuse
||
stack
->
stack_bottom
!=
RELAY_MAGIC
||
stack
->
stack_top
!=
RELAY_MAGIC
)
ERR
(
"Stack corrupted!
\n
"
);
stack
->
inuse
=
0
;
}
/**********************************************************************
* DOSVM_SaveCallFrame
*
* Save current call frame. This routine must be called from DOSRELAY
* called using DOSVM_BuildCallFrame before the relay modifies stack
* pointer. This routine makes sure that the relay can return safely
* to application context and that no memory is leaked.
*
* Note: If DOSVM_BuildCallFrame was called using 32-bit CS or SS,
* old values of CS and SS will be lost. This does not matter
* since this routine is only used by Raw Mode Switch.
*/
void
DOSVM_SaveCallFrame
(
CONTEXT86
*
context
,
STACK16FRAME
*
frame
)
{
*
frame
=
*
CURRENT_STACK16
;
/*
* If context is using allocated stack, release it.
*/
if
(
context
->
SegSs
==
DOSVM_dpmi_segments
->
relay_data_sel
)
{
RELAY_Stack16
*
stack
=
RELAY_GetPointer
(
context
->
Esp
);
if
(
!
stack
->
inuse
||
stack
->
stack_bottom
!=
RELAY_MAGIC
||
stack
->
stack_top
!=
RELAY_MAGIC
)
ERR
(
"Stack corrupted!
\n
"
);
stack
->
inuse
=
0
;
}
}
/**********************************************************************
* DOSVM_RestoreCallFrame
*
* Restore saved call frame to currect stack. This routine must always
* be called after DOSVM_SaveCallFrame has been called and before returning
* from DOSRELAY.
*/
void
DOSVM_RestoreCallFrame
(
CONTEXT86
*
context
,
STACK16FRAME
*
frame
)
{
/*
* Make sure that CS and SS are 16-bit.
*/
RELAY_MakeShortContext
(
context
);
/*
* After this function returns to relay code, protected mode
* 16 bit stack will contain STACK16FRAME and single WORD
* (EFlags, see next comment).
*/
NtCurrentTeb
()
->
cur_stack
=
MAKESEGPTR
(
context
->
SegSs
,
context
->
Esp
-
sizeof
(
STACK16FRAME
)
-
sizeof
(
WORD
)
);
/*
* After relay code returns to glue function, protected
* mode 16 bit stack will contain interrupt return record:
* IP, CS and EFlags. Since EFlags is ignored, it won't
* need to be initialized.
*/
context
->
Esp
-=
3
*
sizeof
(
WORD
);
/*
* Restore stack frame so that relay code won't be confused.
* It should be noted that relay code overwrites IP and CS
* in STACK16FRAME with values taken from current CONTEXT86.
* These values are what is returned to glue function
* (see previous comment).
*/
*
CURRENT_STACK16
=
*
frame
;
}
/**********************************************************************
* DOSVM_BuildCallFrame
*
* Modifies the context so that return to context calls DOSRELAY and
* only after return from DOSRELAY the original context will be returned to.
*/
void
DOSVM_BuildCallFrame
(
CONTEXT86
*
context
,
DOSRELAY
relay
,
LPVOID
data
)
{
WORD
*
stack
;
WORD
code_sel
=
DOSVM_dpmi_segments
->
relay_code_sel
;
/*
* Make sure that CS and SS are 16-bit.
*/
RELAY_MakeShortContext
(
context
);
/*
* Get stack pointer after RELAY_MakeShortContext.
*/
stack
=
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegSs
,
context
->
Esp
);
/*
* Build call frame.
*/
*
(
--
stack
)
=
HIWORD
(
data
);
/* argument.hiword */
*
(
--
stack
)
=
LOWORD
(
data
);
/* argument.loword */
*
(
--
stack
)
=
context
->
SegCs
;
/* STACK16FRAME.cs */
*
(
--
stack
)
=
LOWORD
(
context
->
Eip
);
/* STACK16FRAME.ip */
*
(
--
stack
)
=
LOWORD
(
context
->
Ebp
);
/* STACK16FRAME.bp */
*
(
--
stack
)
=
HIWORD
(
relay
);
/* STACK16FRAME.entry_point.hiword */
*
(
--
stack
)
=
LOWORD
(
relay
);
/* STACK16FRAME.entry_point.loword */
*
(
--
stack
)
=
0
;
/* STACK16FRAME.entry_ip */
*
(
--
stack
)
=
HIWORD
(
RELAY_RelayStub
);
/* STACK16FRAME.relay.hiword */
*
(
--
stack
)
=
LOWORD
(
RELAY_RelayStub
);
/* STACK16FRAME.relay.loword */
*
(
--
stack
)
=
0
;
/* STACK16FRAME.module_cs.hiword */
*
(
--
stack
)
=
code_sel
;
/* STACK16FRAME.module_cs.loword */
*
(
--
stack
)
=
0
;
/* STACK16FRAME.callfrom_ip.hiword */
*
(
--
stack
)
=
0
;
/* STACK16FRAME.callfrom_ip.loword */
/*
* Adjust stack and code pointers.
*/
ADD_LOWORD
(
context
->
Esp
,
-
28
);
context
->
SegCs
=
wine_get_cs
();
context
->
Eip
=
(
DWORD
)
__wine_call_from_16_regs
;
}
dlls/winedos/winedos16.spec
deleted
100644 → 0
View file @
91c6f817
# Interrupt vectors 0-255 are ordinals 100-355
# The '-interrupt' keyword takes care of the flags pushed on the stack by the interrupt
109 pascal -interrupt DOSVM_Int09Handler() DOSVM_Int09Handler
116 pascal -interrupt DOSVM_Int10Handler() DOSVM_Int10Handler
117 pascal -interrupt DOSVM_Int11Handler() DOSVM_Int11Handler
118 pascal -interrupt DOSVM_Int12Handler() DOSVM_Int12Handler
119 pascal -interrupt DOSVM_Int13Handler() DOSVM_Int13Handler
121 pascal -interrupt DOSVM_Int15Handler() DOSVM_Int15Handler
122 pascal -interrupt DOSVM_Int16Handler() DOSVM_Int16Handler
123 pascal -interrupt DOSVM_Int17Handler() DOSVM_Int17Handler
126 pascal -interrupt DOSVM_Int1aHandler() DOSVM_Int1aHandler
132 pascal -interrupt DOSVM_Int20Handler() DOSVM_Int20Handler
133 pascal -interrupt DOSVM_Int21Handler() DOSVM_Int21Handler
# Note: int 25 and 26 don't pop the flags from the stack
137 pascal -register DOSVM_Int25Handler() DOSVM_Int25Handler
138 pascal -register DOSVM_Int26Handler() DOSVM_Int26Handler
141 pascal -interrupt DOSVM_Int29Handler() DOSVM_Int29Handler
142 pascal -interrupt DOSVM_Int2aHandler() DOSVM_Int2aHandler
147 pascal -interrupt DOSVM_Int2fHandler() DOSVM_Int2fHandler
149 pascal -interrupt DOSVM_Int31Handler() DOSVM_Int31Handler
151 pascal -interrupt DOSVM_Int33Handler() DOSVM_Int33Handler
152 pascal -interrupt DOSVM_Int34Handler() DOSVM_Int34Handler
153 pascal -interrupt DOSVM_Int35Handler() DOSVM_Int35Handler
154 pascal -interrupt DOSVM_Int36Handler() DOSVM_Int36Handler
155 pascal -interrupt DOSVM_Int37Handler() DOSVM_Int37Handler
156 pascal -interrupt DOSVM_Int38Handler() DOSVM_Int38Handler
157 pascal -interrupt DOSVM_Int39Handler() DOSVM_Int39Handler
158 pascal -interrupt DOSVM_Int3aHandler() DOSVM_Int3aHandler
159 pascal -interrupt DOSVM_Int3bHandler() DOSVM_Int3bHandler
160 pascal -interrupt DOSVM_Int3cHandler() DOSVM_Int3cHandler
161 pascal -interrupt DOSVM_Int3dHandler() DOSVM_Int3dHandler
162 pascal -interrupt DOSVM_Int3eHandler() DOSVM_Int3eHandler
165 pascal -interrupt DOSVM_Int41Handler() DOSVM_Int41Handler
175 pascal -interrupt DOSVM_Int4bHandler() DOSVM_Int4bHandler
192 pascal -interrupt DOSVM_Int5cHandler() DOSVM_Int5cHandler
203 pascal -interrupt DOSVM_Int67Handler() DOSVM_Int67Handler
# default handler for unimplemented interrupts
356 pascal -interrupt DOSVM_DefaultHandler() DOSVM_DefaultHandler
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment