Commit 770eb51e authored by Alexandre Julliard's avatar Alexandre Julliard

Moved most global data out of the LPDOSTASK structure.

Allocate DPMI real-mode segments globally at startup. Try to allocate DOS memory at address 0.
parent 0ff083ba
......@@ -11,38 +11,13 @@
#include "winbase.h" /* for LPSTARTUPINFO32A */
#include "winnt.h" /* for PCONTEXT */
typedef struct _DOSSYSTEM {
int id;
void *data;
struct _DOSSYSTEM *next;
} DOSSYSTEM;
struct _DOSEVENT;
typedef struct _DOSTASK {
LPVOID img;
unsigned img_ofs;
WORD psp_seg,load_seg;
WORD init_cs,init_ip,init_ss,init_sp;
WORD xms_seg;
WORD dpmi_seg,dpmi_sel,dpmi_flag;
char mm_name[128];
int mm_fd;
HANDLE hReadPipe,hXPipe,hConInput,hConOutput;
int read_pipe,write_pipe;
pid_t task;
int sig_sent,entered,idling;
struct _DOSEVENT *pending,*current;
DOSSYSTEM *sys;
WORD psp_seg;
WORD dpmi_flag;
} DOSTASK, *LPDOSTASK;
typedef struct _DOSEVENT {
int irq,priority;
void (*relay)(LPDOSTASK,CONTEXT86*,void*);
void *data;
struct _DOSEVENT *next;
} DOSEVENT, *LPDOSEVENT;
#define DOS_PRIORITY_REALTIME 0 /* IRQ0 */
#define DOS_PRIORITY_KEYBOARD 1 /* IRQ1 */
#define DOS_PRIORITY_VGA 2 /* IRQ9 */
......@@ -50,26 +25,19 @@ typedef struct _DOSEVENT {
#define DOS_PRIORITY_SERIAL 10 /* IRQ4 */
#if defined(linux) && defined(__i386__)
#define MZ_SUPPORTED
extern BOOL MZ_InitTask( LPDOSTASK lpDosTask );
extern void MZ_KillTask( LPDOSTASK lpDosTask );
extern LPDOSTASK MZ_AllocDPMITask( void );
#endif /* linux-i386 */
#define V86_FLAG 0x00020000
extern BOOL MZ_LoadImage( HMODULE module, HANDLE hFile, LPCSTR filename );
extern LPDOSTASK MZ_Current( void );
extern LPDOSTASK MZ_AllocDPMITask( void );
extern int DOSVM_Enter( CONTEXT86 *context );
extern void DOSVM_Wait( int read_pipe, HANDLE hObject );
extern void DOSVM_QueueEvent( int irq, int priority, void (*relay)(LPDOSTASK,CONTEXT86*,void*), void *data );
extern void DOSVM_QueueEvent( int irq, int priority, void (*relay)(CONTEXT86*,void*), void *data );
extern void DOSVM_PIC_ioport_out( WORD port, BYTE val );
extern void DOSVM_SetTimer( unsigned ticks );
extern unsigned DOSVM_GetTimer( void );
extern void DOSVM_SetSystemData( int id, void *data );
extern void* DOSVM_GetSystemData( int id );
#endif /* __WINE_DOSEXE_H */
......@@ -60,6 +60,8 @@ extern ldt_copy_entry ldt_copy[LDT_SIZE];
#define PTR_SEG_OFF_TO_LIN(seg,off) \
((void*)(GET_SEL_BASE(seg) + (unsigned int)(off)))
#define PTR_REAL_TO_LIN(seg,off) \
((void*)(((unsigned int)(seg) << 4) + LOWORD(off)))
#define PTR_SEG_TO_LIN(ptr) \
PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr))
#define PTR_SEG_OFF_TO_SEGPTR(seg,off) \
......
......@@ -128,8 +128,11 @@ extern BYTE * DOSMEM_BiosSys();
extern DWORD DOSMEM_CollateTable;
extern DWORD DOSMEM_ErrorCall;
extern DWORD DOSMEM_ErrorBuffer;
/* various real-mode code stubs */
extern WORD DOSMEM_wrap_seg;
extern WORD DOSMEM_xms_seg;
extern WORD DOSMEM_dpmi_seg;
extern WORD DOSMEM_dpmi_sel;
extern DWORD DOS_LOLSeg;
extern struct _DOS_LISTOFLISTS * DOSMEM_LOL();
......@@ -249,7 +252,7 @@ extern void ASPI_DOS_HandleInt(CONTEXT86 *context);
* a *32-bit* general register as third parameter, e.g.
* CTX_SEG_OFF_TO_LIN( context, DS_reg(context), EDX_reg(context) )
* This will generate a linear pointer in all three cases:
* Real-Mode: Seg*16 + LOWORD(Offset) + V86BASE
* Real-Mode: Seg*16 + LOWORD(Offset)
* 16-bit: convert (Seg, LOWORD(Offset)) to linear
* 32-bit: use Offset as linear address (DeviceIoControl!)
*
......@@ -258,8 +261,8 @@ extern void ASPI_DOS_HandleInt(CONTEXT86 *context);
* (0 counts also as 32-bit segment).
*/
#define CTX_SEG_OFF_TO_LIN(context,seg,off) \
(ISV86(context) ? (void*)(V86BASE(context)+((seg)<<4)+(off&0xffff)) : \
(!seg || IS_SELECTOR_SYSTEM(seg))? (void *)off : PTR_SEG_OFF_TO_LIN(seg,off&0xffff))
(ISV86(context) ? PTR_REAL_TO_LIN((seg),(off)) : \
(!seg || IS_SELECTOR_SYSTEM(seg))? (void *)(off) : PTR_SEG_OFF_TO_LIN((seg),LOWORD(off)))
#define INT_BARF(context,num) \
ERR( "int%x: unknown/not implemented parameters:\n" \
......
......@@ -730,7 +730,6 @@ typedef HANDLE *PHANDLE;
#define RESET_ZFLAG(context) (EFL_reg(context) &= ~0x0040)
#define ISV86(context) (EFL_reg(context) & 0x00020000)
#define V86BASE(context) DOSMEM_MemoryBase()
/* Macros to retrieve the current context */
......
......@@ -29,13 +29,13 @@
#include "winsock.h"
#include "syslevel.h"
#include "debugtools.h"
#include "dosexe.h"
#include "services.h"
#include "server.h"
DEFAULT_DEBUG_CHANNEL(task)
DECLARE_DEBUG_CHANNEL(relay)
DECLARE_DEBUG_CHANNEL(toolhelp)
DEFAULT_DEBUG_CHANNEL(task);
DECLARE_DEBUG_CHANNEL(relay);
DECLARE_DEBUG_CHANNEL(toolhelp);
/* Min. number of thunks allocated when creating a new segment */
#define MIN_THUNKS 32
......@@ -243,7 +243,6 @@ BOOL TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline,
/* NOTE: for 16-bit tasks, the instance handles are updated later on
in NE_InitProcess */
}
if (MZ_Current() && MZ_Current()->load_seg) pTask->flags |= TDBF_WINOLDAP;
pTask->version = pModule->expected_version;
pTask->hModule = pModule->self;
......
......@@ -29,7 +29,7 @@ inline static void add_stack( CONTEXT86 *context, int offset )
inline static void *make_ptr( CONTEXT86 *context, DWORD seg, DWORD off, int long_addr )
{
if (ISV86(context)) return DOSMEM_MemoryBase() + (seg << 4) + LOWORD(off);
if (ISV86(context)) return PTR_REAL_TO_LIN( seg, off );
if (IS_SELECTOR_SYSTEM(seg)) return (void *)off;
if (!long_addr) off = LOWORD(off);
return PTR_SEG_OFF_TO_LIN( seg, off );
......@@ -38,7 +38,7 @@ inline static void *make_ptr( CONTEXT86 *context, DWORD seg, DWORD off, int long
inline static void *get_stack( CONTEXT86 *context )
{
if (ISV86(context))
return DOSMEM_MemoryBase() + (context->SegSs << 4) + LOWORD(context->Esp);
return PTR_REAL_TO_LIN( context->SegSs, context->Esp );
if (IS_SELECTOR_SYSTEM(context->SegSs))
return (void *)context->Esp;
if (IS_SELECTOR_32BIT(context->SegSs))
......
......@@ -47,8 +47,9 @@ typedef struct {
#define CON_BUFFER 128
#define SYSTEM_STRATEGY_NUL 0x0100
#define SYSTEM_STRATEGY_CON 0x0101
enum strategy { SYSTEM_STRATEGY_NUL, SYSTEM_STRATEGY_CON, NB_SYSTEM_STRATEGIES };
static void *strategy_data[NB_SYSTEM_STRATEGIES];
#define NONEXT ((DWORD)-1)
......@@ -150,20 +151,19 @@ static void do_lret(CONTEXT86*ctx)
static void do_strategy(CONTEXT86*ctx, int id, int extra)
{
REQUEST_HEADER *hdr = CTX_SEG_OFF_TO_LIN(ctx, ES_reg(ctx), EBX_reg(ctx));
void **hdr_ptr = DOSVM_GetSystemData(id);
void **hdr_ptr = strategy_data[id];
if (!hdr_ptr) {
hdr_ptr = calloc(1,sizeof(void *)+extra);
DOSVM_SetSystemData(id, hdr_ptr);
strategy_data[id] = hdr_ptr;
}
*hdr_ptr = hdr;
do_lret(ctx);
}
static REQUEST_HEADER * get_hdr(int id, void**extra)
{
void **hdr_ptr = DOSVM_GetSystemData(id);
void **hdr_ptr = strategy_data[id];
if (extra)
*extra = hdr_ptr ? (void*)(hdr_ptr+1) : (void *)NULL;
return hdr_ptr ? *hdr_ptr : (void *)NULL;
......@@ -209,7 +209,6 @@ static void WINAPI con_interrupt(CONTEXT86*ctx)
BYTE *curbuffer = (lol->offs_unread_CON) ?
(((BYTE*)dataseg) + lol->offs_unread_CON) : (BYTE*)NULL;
DOS_DEVICE_HEADER *con = dataseg->dev;
LPDOSTASK lpDosTask = MZ_Current();
switch (hdr->command) {
case CMD_INPUT:
......@@ -301,7 +300,7 @@ static void WINAPI con_interrupt(CONTEXT86*ctx)
/* a character */
if ((len+1)<CON_BUFFER) {
linebuffer[len] = LOBYTE(data);
WriteFile(lpDosTask->hConOutput, &linebuffer[len++], 1, NULL, NULL);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), &linebuffer[len++], 1, NULL, NULL);
}
/* else beep, but I don't like noise */
}
......@@ -309,7 +308,7 @@ static void WINAPI con_interrupt(CONTEXT86*ctx)
case '\b':
if (len>0) {
len--;
WriteFile(lpDosTask->hConOutput, "\b \b", 3, NULL, NULL);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\b \b", 3, NULL, NULL);
}
break;
}
......@@ -377,7 +376,7 @@ static void WINAPI con_interrupt(CONTEXT86*ctx)
SELECTOROF(io->buffer),
(DWORD)OFFSETOF(io->buffer));
DWORD result = 0;
WriteFile(lpDosTask->hConOutput, buffer, io->count, &result, NULL);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, io->count, &result, NULL);
io->count = result;
hdr->status = STAT_DONE;
}
......
......@@ -15,9 +15,11 @@ DEFAULT_DEBUG_CHANNEL(int);
#define QUEUELEN 31
typedef struct {
static struct
{
BYTE queuelen,queue[QUEUELEN],ascii[QUEUELEN];
} KBDSYSTEM;
} kbdinfo;
/**********************************************************************
* INT_Int09Handler
......@@ -58,48 +60,35 @@ void WINAPI INT_Int09Handler( CONTEXT86 *context )
DOSVM_PIC_ioport_out(0x20, 0x20); /* send EOI */
}
static void KbdRelay( LPDOSTASK lpDosTask, CONTEXT86 *context, void *data )
static void KbdRelay( CONTEXT86 *context, void *data )
{
KBDSYSTEM *sys = (KBDSYSTEM *)DOSVM_GetSystemData(0x09);
if (sys && sys->queuelen) {
if (kbdinfo.queuelen) {
/* cleanup operation, called from DOSVM_PIC_ioport_out:
* we'll remove current scancode from keyboard buffer here,
* rather than in ReadScan, because some DOS apps depend on
* the scancode being available for reading multiple times... */
if (--sys->queuelen) {
memmove(sys->queue,sys->queue+1,sys->queuelen);
memmove(sys->ascii,sys->ascii+1,sys->queuelen);
if (--kbdinfo.queuelen) {
memmove(kbdinfo.queue,kbdinfo.queue+1,kbdinfo.queuelen);
memmove(kbdinfo.ascii,kbdinfo.ascii+1,kbdinfo.queuelen);
}
}
}
void WINAPI INT_Int09SendScan( BYTE scan, BYTE ascii )
{
KBDSYSTEM *sys = (KBDSYSTEM *)DOSVM_GetSystemData(0x09);
if (!sys) {
sys = calloc(1,sizeof(KBDSYSTEM));
DOSVM_SetSystemData(0x09,sys);
}
if (sys->queuelen == QUEUELEN) {
if (kbdinfo.queuelen == QUEUELEN) {
ERR("keyboard queue overflow\n");
return;
}
/* add scancode to queue */
sys->queue[sys->queuelen] = scan;
sys->ascii[sys->queuelen++] = ascii;
kbdinfo.queue[kbdinfo.queuelen] = scan;
kbdinfo.ascii[kbdinfo.queuelen++] = ascii;
/* tell app to read it by triggering IRQ 1 (int 09) */
DOSVM_QueueEvent(1,DOS_PRIORITY_KEYBOARD,KbdRelay,NULL);
}
BYTE WINAPI INT_Int09ReadScan( BYTE*ascii )
{
KBDSYSTEM *sys = (KBDSYSTEM *)DOSVM_GetSystemData(0x09);
if (sys) {
if (ascii) *ascii = sys->ascii[0];
return sys->queue[0];
} else {
if (ascii) *ascii = 0;
return 0;
}
if (ascii) *ascii = kbdinfo.ascii[0];
return kbdinfo.queue[0];
}
......@@ -115,9 +115,7 @@ void WINAPI INT_Int2fHandler( CONTEXT86 *context )
break;
case 0x10: /* XMS v2+ get driver address */
{
LPDOSTASK lpDosTask = MZ_Current();
ES_reg(context) = lpDosTask ? lpDosTask->xms_seg : 0;
ES_reg(context) = DOSMEM_xms_seg;
BX_reg(context) = 0;
break;
}
......@@ -349,15 +347,13 @@ static void do_int2f_16( CONTEXT86 *context )
#endif
{
SYSTEM_INFO si;
LPDOSTASK lpDosTask = MZ_Current();
GetSystemInfo(&si);
AX_reg(context) = 0x0000; /* DPMI Installed */
BX_reg(context) = 0x0001; /* 32bits available */
CL_reg(context) = si.wProcessorLevel;
DX_reg(context) = 0x005a; /* DPMI major/minor 0.90 */
SI_reg(context) = 0; /* # of para. of DOS extended private data */
ES_reg(context) = lpDosTask ? lpDosTask->dpmi_seg : 0;
ES_reg(context) = DOSMEM_dpmi_seg;
DI_reg(context) = 0; /* ES:DI is DPMI switch entry point */
break;
}
......@@ -402,8 +398,7 @@ static void MSCDEX_Dump(char* pfx, BYTE* req, int dorealmode)
case 3:
case 12:
ptr += sprintf(ptr, "\n\t\t\t\tIO_struct => ");
ios = (dorealmode) ?
DOSMEM_MapRealToLinear(MAKELONG(PTR_AT(req, 14, WORD), PTR_AT(req, 16, WORD))) :
ios = (dorealmode) ? PTR_REAL_TO_LIN( PTR_AT(req, 16, WORD), PTR_AT(req, 14, WORD)) :
PTR_SEG_OFF_TO_LIN(PTR_AT(req, 16, WORD), PTR_AT(req, 14, WORD));
for (i = 0; i < PTR_AT(req, 18, WORD); i++) {
......@@ -476,9 +471,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
BYTE Error = 255; /* No Error */
int dorealmode = ISV86(context);
driver_request = (dorealmode) ?
DOSMEM_MapRealToLinear(MAKELONG(BX_reg(context), ES_reg(context))) :
PTR_SEG_OFF_TO_LIN(ES_reg(context), BX_reg(context));
driver_request = CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Ebx);
if (!driver_request) {
/* FIXME - to be deleted ?? */
......@@ -517,7 +510,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
switch (driver_request[2]) {
case 3:
io_stru = (dorealmode) ?
DOSMEM_MapRealToLinear(MAKELONG(PTR_AT(driver_request, 14, WORD), PTR_AT(driver_request, 16, WORD))) :
PTR_REAL_TO_LIN( PTR_AT(driver_request, 16, WORD), PTR_AT(driver_request, 14, WORD) ) :
PTR_SEG_OFF_TO_LIN(PTR_AT(driver_request, 16, WORD), PTR_AT(driver_request, 14, WORD));
TRACE(" --> IOCTL INPUT <%d>\n", io_stru[0]);
......@@ -682,7 +675,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
case 12:
io_stru = (dorealmode) ?
DOSMEM_MapRealToLinear(MAKELONG(PTR_AT(driver_request, 14, WORD), PTR_AT(driver_request, 16, WORD))) :
PTR_REAL_TO_LIN( PTR_AT(driver_request, 16, WORD), PTR_AT(driver_request, 14, WORD)) :
PTR_SEG_OFF_TO_LIN(PTR_AT(driver_request, 16, WORD), PTR_AT(driver_request, 14, WORD));
TRACE(" --> IOCTL OUTPUT <%d>\n", io_stru[0]);
......
......@@ -13,11 +13,12 @@
DEFAULT_DEBUG_CHANNEL(int)
typedef struct {
static struct
{
DWORD x, y, but;
FARPROC16 callback;
WORD callmask;
} MOUSESYSTEM;
} mouse_info;
/**********************************************************************
* INT_Int33Handler
......@@ -26,15 +27,12 @@ typedef struct {
*/
void WINAPI INT_Int33Handler( CONTEXT86 *context )
{
MOUSESYSTEM *sys = (MOUSESYSTEM *)DOSVM_GetSystemData(0x33);
switch (AX_reg(context)) {
case 0x00:
TRACE("Reset mouse driver and request status\n");
AX_reg(context) = 0xFFFF; /* installed */
BX_reg(context) = 3; /* # of buttons */
sys = calloc(1,sizeof(MOUSESYSTEM));
DOSVM_SetSystemData(0x33, sys);
memset( &mouse_info, 0, sizeof(mouse_info) );
break;
case 0x01:
FIXME("Show mouse cursor\n");
......@@ -44,9 +42,9 @@ void WINAPI INT_Int33Handler( CONTEXT86 *context )
break;
case 0x03:
TRACE("Return mouse position and button status\n");
BX_reg(context) = sys->but;
CX_reg(context) = sys->x;
DX_reg(context) = sys->y;
BX_reg(context) = mouse_info.but;
CX_reg(context) = mouse_info.x;
DX_reg(context) = mouse_info.y;
break;
case 0x04:
FIXME("Position mouse cursor\n");
......@@ -65,8 +63,8 @@ void WINAPI INT_Int33Handler( CONTEXT86 *context )
break;
case 0x0C:
TRACE("Define mouse interrupt subroutine\n");
sys->callmask = CX_reg(context);
sys->callback = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR(ES_reg(context), DX_reg(context));
mouse_info.callmask = CX_reg(context);
mouse_info.callback = (FARPROC16)PTR_SEG_OFF_TO_SEGPTR(ES_reg(context), DX_reg(context));
break;
case 0x10:
FIXME("Define screen region for update\n");
......@@ -81,7 +79,7 @@ typedef struct {
WORD mask,but,x,y,mx,my;
} MCALLDATA;
static void MouseRelay(LPDOSTASK lpDosTask,CONTEXT86 *context,void *mdata)
static void MouseRelay(CONTEXT86 *context,void *mdata)
{
MCALLDATA *data = (MCALLDATA *)mdata;
CONTEXT86 ctx = *context;
......@@ -100,58 +98,56 @@ static void MouseRelay(LPDOSTASK lpDosTask,CONTEXT86 *context,void *mdata)
void WINAPI INT_Int33Message(UINT message,WPARAM wParam,LPARAM lParam)
{
MOUSESYSTEM *sys = (MOUSESYSTEM *)DOSVM_GetSystemData(0x33);
WORD mask = 0;
unsigned Height, Width, SX=1, SY=1;
if (!sys) return;
if (!VGA_GetMode(&Height,&Width,NULL)) {
/* may need to do some coordinate scaling */
SX = 640/Width;
if (!SX) SX=1;
}
sys->x = LOWORD(lParam) * SX;
sys->y = HIWORD(lParam) * SY;
mouse_info.x = LOWORD(lParam) * SX;
mouse_info.y = HIWORD(lParam) * SY;
switch (message) {
case WM_MOUSEMOVE:
mask |= 0x01;
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
sys->but |= 0x01;
mouse_info.but |= 0x01;
mask |= 0x02;
break;
case WM_LBUTTONUP:
sys->but &= ~0x01;
mouse_info.but &= ~0x01;
mask |= 0x04;
break;
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
sys->but |= 0x02;
mouse_info.but |= 0x02;
mask |= 0x08;
break;
case WM_RBUTTONUP:
sys->but &= ~0x02;
mouse_info.but &= ~0x02;
mask |= 0x10;
break;
case WM_MBUTTONDOWN:
case WM_MBUTTONDBLCLK:
sys->but |= 0x04;
mouse_info.but |= 0x04;
mask |= 0x20;
break;
case WM_MBUTTONUP:
sys->but &= ~0x04;
mouse_info.but &= ~0x04;
mask |= 0x40;
break;
}
if ((mask & sys->callmask) && sys->callback) {
if ((mask & mouse_info.callmask) && mouse_info.callback) {
MCALLDATA *data = calloc(1,sizeof(MCALLDATA));
data->proc = sys->callback;
data->mask = mask & sys->callmask;
data->but = sys->but;
data->x = sys->x;
data->y = sys->y;
data->proc = mouse_info.callback;
data->mask = mask & mouse_info.callmask;
data->but = mouse_info.but;
data->x = mouse_info.x;
data->y = mouse_info.y;
DOSVM_QueueEvent(-1, DOS_PRIORITY_MOUSE, MouseRelay, data);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment