Commit 121bd98c authored by Alexandre Julliard's avatar Alexandre Julliard

Release 0.1.0

WHAT'S NEW with version 0.1.0: - Integrated patches from Alexandre. - Minor bug fix in if1632.S WHAT'S NEW with version 0.0.5: - Patches from Alexandre Julliard. Some integration with Tcl. - Generic interface for callback procedures. This will allow callbacks into DLLs. - MakeProcInstance() has been implemented but untested. WHAT'S NEW with version 0.0.4: - Eric Youngdale modified wine.c and selector.c to allow loading of Windows DLLs. - Added global memory allocation routines (GlobalAlloc, GlobalFree, and GlobalLock) - Bitmap resource loading into global memory.
parent 066d1e09
CFLAGS=-g -DDEBUG_RESOURCE
CFLAGS=-g -DDEBUG_RESOURCE -DDEBUG_HEAP -I./
######################################################################
# FILES:
......@@ -18,19 +18,22 @@ BUILDOBJS=dll_kernel.o dll_user.o dll_gdi.o dll_unixlib.o \
MUST_BE_LINKED_FIRST=if1632.o $(BUILDOBJS)
OBJS=$(MUST_BE_LINKED_FIRST) \
dump.o heap.o ldt.o kernel.o relay.o resource.o \
selector.o user.o wine.o
callback.o dump.o global.o heap.o ldt.o kernel.o relay.o resource.o \
selector.o user.o wine.o wintcl.o
TARGET=wine
LIBS=-lldt
LIBS=-L. -L/usr/X386/lib -L/dasd3/usr/lib -lldt -ltk -ltcl -lX11
all: $(TARGET) libldt.a
all: $(TARGET)
clean:
rm -f *.o *~ *.s dll_*
rm -f *.o *~ *.s dll_* *.a
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
ci:
ci Makefile README *.c *.h *.S build-spec.txt *.spec
$(TARGET): $(OBJS) libldt.a
$(CC) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
build: build.c
cc -g -o build build.c
......@@ -56,3 +59,6 @@ dll_win87em.S dll_win87em_tab.c: build win87em.spec
dll_shell.S dll_shell_tab.c: build shell.spec
build shell.spec
wintcl.o: wintcl.c windows.h
cc -c -I. -g wintcl.c
......@@ -2,11 +2,28 @@ Copyright Robert J. Amstadt, 1993. All code is provided without
warranty. It is my intent to cover this code with the Gnu Public
License.
So here goes release 0.0.3 of the Windows loader. It will do some
So here goes release 0.1.0 of the Windows loader. It will do some
relocations and then run the program. I have successfully loaded
the Windows solitaire game. Try it. It currently stops a call to
GetObject().
WHAT'S NEW with version 0.1.0:
- Integrated patches from Alexandre.
- Minor bug fix in if1632.S
WHAT'S NEW with version 0.0.5:
- Patches from Alexandre Julliard. Some integration with Tcl.
- Generic interface for callback procedures. This will allow
callbacks into DLLs.
- MakeProcInstance() has been implemented but untested.
WHAT'S NEW with version 0.0.4:
- Eric Youngdale modified wine.c and selector.c to allow loading
of Windows DLLs.
- Added global memory allocation routines (GlobalAlloc, GlobalFree,
and GlobalLock)
- Bitmap resource loading into global memory.
WHAT'S NEW with version 0.0.3:
- Fixed bug with sector sizes.
- Registers at program startup are now set correctly.
......@@ -41,24 +58,21 @@ WHAT'S NEW with version 0.0.1:
TODO:
- Segment fixup code completion.
- Make changes to the kernel to allow more than 32 LDT entries.
- Trap and handle DOS and DPMI calls.
- Windows emulation library (connect to Peter MacDonald's library).
- Allowing loading of 16-bit DLLs for use with program.
- global memory allocation.
- global memory allocation completion
- GlobalAlloc should support ZEROINIT.
- GlobalAlloc of code segments.
- complete and improve local heap allocation.
- Handle self-loading applications.
- Deal with callback functions.
- Resource loading
INSTALLATION:
Uncompress and untar this archive into the directory of your
choice. The file "ldt.tar" contains a necessary kernel patch against
Linux 0.99.10. If you installed the "ldt.tar" from the first release
of this package, then you MUST to replace it. In the directory
/usr/src/linux (or whereever you keep your kernel sources), untar
this file it contains three files:
Linux 0.99.10. "ldt.tar" is unchanged from the version released
with release 0.0.2. In the directory /usr/src/linux (or whereever
you keep your kernel sources), untar this file it contains three files:
kernel/ldt.c
- This is source for a new system call.
......
# Windows Tcl/Tk emulation scripts
# Initial implementation by Peter MacDonald pmacdona@sanjuan.uvic.ca
proc CreateWindow { f t x y h w } {
global baseframe
set baseframe $f
wm title . "$t"
frame .$f
pack append . .$f {top}
canvas .$f.canvas1 -scrollregion " $x $y $h $w " -width 15c -height 10c
pack append .$f .$f.canvas1 {top}
}
proc CreateMenuEntry { fn t x } {
global baseframe
menubutton .$fn -text "$t" -underline $x -menu .$fn.m
pack append .$baseframe .$fn left
menu .$fn.m
}
proc CreateMenuBar { f } {
global allmenus
global baseframe
set allmenus ""
frame .$f -relief raised -borderwidth 1
pack before .$baseframe .$f {top fillx}
}
proc AppendMenu { a b c d x } {
global allmenus
global baseframe
if { ($b == 0x10) } {
.$c configure -text "$d" -underline "$x"
pack append .$a .$c left
set allmenus "$allmenus $c"
tk_menuBar .$a $allmenus
tk_bindForTraversal .$baseframe.canvas1
} else { if { ($b == 0x0800) } {
.$a.m add separator
} else {
.$a.m add command -label "$d" -command "wincallback menu $a $b $c $d" -underline $x
}}
}
####################################################################
# Misc unimplemented stuff
####################################################################
proc LoadIcon { wind name } {
echo "LoadIcon"
}
proc LoadBitmap { wind name } {
echo "LoadBitmap"
}
proc LoadCursor { wind name } {
echo "LoadCursor"
}
proc GetObject { obj count ptr } {
echo "GetObject $obj $count $ptr"
}
proc GetStockObject { wind } {
echo "GetStockObject $wind"
}
proc DefWindowProc { a b c d } {
echo "DefWindowProc $a $b $c $d"
}
proc GetMenu { a } {
echo "GetMenu $a"
}
proc SetMenu { a b } {
echo "SetMenu $a $b"
}
proc MessageBeep {a } {
echo "MessageBeep $a"
}
proc MessageBox { wind msg title type } {
echo "MessageBox '$msg'"
}
proc DrawText { f t top left right bottom } {
.$f.canvas1 create text $top $left -text "$t" -anchor n
}
static char RCSId[] = "$Id: build.c,v 1.2 1993/06/30 14:24:33 root Exp root $";
static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
......
static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include "callback.h"
#include "wine.h"
#include "segmem.h"
extern unsigned short SelectorOwners[];
extern unsigned short IF1632_Saved16_ss;
extern unsigned long IF1632_Saved16_esp;
extern struct segment_descriptor_s *MakeProcThunks;
struct thunk_s
{
int used;
unsigned char thunk[10];
};
/**********************************************************************
* PushOn16
*/
static void
PushOn16(int size, unsigned int value)
{
char *p = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
(IF1632_Saved16_esp & 0xffff));
if (size)
{
unsigned long *lp = (unsigned long *) p - 1;
*lp = value;
IF1632_Saved16_esp -= 4;
}
else
{
unsigned short *sp = (unsigned short *) p - 1;
*sp = value;
IF1632_Saved16_esp -= 2;
}
}
/**********************************************************************
* FindDataSegmentForCode
*/
static unsigned short
FindDataSegmentForCode(unsigned long csip)
{
unsigned int seg_idx;
seg_idx = (unsigned short) (csip >> 19);
return SelectorOwners[seg_idx];
}
/**********************************************************************
* CallBack16
*/
int
CallBack16(void *func, int n_args, ...)
{
va_list ap;
int i;
int arg_type, arg_value;
va_start(ap, n_args);
for (i = 0; i < n_args; i++)
{
arg_type = va_arg(ap, int);
arg_value = va_arg(ap, int);
PushOn16(arg_type, arg_value);
}
va_end(ap);
return CallTo16((unsigned int) func,
FindDataSegmentForCode((unsigned long) func));
}
/**********************************************************************
* CALLBACK_MakeProcInstance
*/
void *
CALLBACK_MakeProcInstance(void *func, int instance)
{
int handle;
void *new_func;
struct thunk_s *tp;
int i;
tp = (struct thunk_s *) MakeProcThunks->base_addr;
for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
if (!tp->used)
break;
if (tp->used)
return (void *) 0;
tp->thunk[0] = 0xb8;
tp->thunk[1] = (unsigned char) instance;
tp->thunk[2] = (unsigned char) (instance >> 8);
tp->thunk[3] = 0x8e;
tp->thunk[4] = 0xd8;
tp->thunk[5] = 0xea;
memcpy(&tp->thunk[6], &func, 4);
return tp->thunk;
}
/* $Id$
*/
/*
* Copyright Robert J. Amstadt, 1993
*/
#ifndef CALLBACK_H
#define CALLBACK_H
#include <stdlib.h>
#include <stdarg.h>
#define CALLBACK_SIZE_WORD 0
#define CALLBACK_SIZE_LONG 1
extern int CallTo16(unsigned int csip, unsigned short ds);
extern int CallBack16(void *func, int n_args, ...);
/*
* Windows procedure calling:
* f(a, b, c, d)
* wndprocfunc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
*/
#define CALLWNDPROC(f, a, b, c, d) \
CallBack16((f), 4, CALLBACK_SIZE_WORD, (a), CALLBACK_SIZE_WORD, (b), \
CALLBACK_SIZE_WORD, (c), CALLBACK_SIZE_LONG, (d))
#endif /* CALLBACK_H */
/* $Id: dlls.h,v 1.1 1993/06/29 15:55:18 root Exp $
/* $Id: dlls.h,v 1.2 1993/07/04 04:04:21 root Exp root $
*/
/*
* Copyright Robert J. Amstadt, 1993
......
static char RCSId[] = "$Id: dump.c,v 1.1 1993/06/29 15:55:18 root Exp $";
static char RCSId[] = "$Id: dump.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
......
# $Id: gdi.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
# $Id: gdi.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
#
name gdi
id 3
length 490
27 pascal Rectangle(word word word word word) Rectangle(1 2 3 4 5)
82 pascal GetObject(word word ptr) RSC_GetObject(1 2 3)
87 pascal GetStockObject(word) GetStockObject(1)
static char RCSId[] = "$Id: global.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
#include <stdlib.h>
#include "prototypes.h"
#include "heap.h"
#include "segmem.h"
/*
* Global memory pool descriptor.
*
* handle = 0, this descriptor contains the address of a free pool.
* != 0, this describes an allocated block.
*
* sequence = 0, this is not a huge block
* > 0, this is a portion of a huge block
* =-1, this is a free segment
*
* addr - address of this memory block.
*
* length - used to maintain huge blocks.
*
*/
typedef struct global_mem_desc_s
{
struct global_mem_desc_s *next;
struct global_mem_desc_s *prev;
unsigned short handle;
short sequence;
void *addr;
int length;
} GDESC;
GDESC *GlobalList = NULL;
/**********************************************************************
* GLOBAL_GetFreeSegments
*/
GDESC *
GLOBAL_GetFreeSegments(unsigned int flags, int n_segments)
{
struct segment_descriptor_s *s;
GDESC *g;
GDESC *g_start;
GDESC *g_prev;
int count, i;
/*
* Try to find some empty segments in our list.
*/
count = 0;
for (g = GlobalList; g != NULL && count != n_segments; g = g->next)
{
if ((int) g->sequence == -1)
{
if (count > 0)
{
if (g->prev->handle + 8 != g->handle)
count = 0;
else
count++;
}
else
{
g_start = g;
count = 1;
}
}
else if (count)
count = 0;
}
/*
* If we couldn't find enough segments, then we need to create some.
*/
if (count != n_segments)
{
/*
* Find list tail.
*/
g_prev = NULL;
for (g = GlobalList; g != NULL; g = g->next)
g_prev = g;
/*
* Allocate segments.
*/
for (count = 0; count < n_segments; count++)
{
s = GetNextSegment(flags, 0x10000);
if (s == NULL)
return NULL;
g = (GDESC *) malloc(sizeof(*g));
g->prev = g_prev;
g->next = NULL;
g->handle = s->selector;
g->sequence = -1;
g->addr = s->base_addr;
g->length = s->length;
free(s);
if (count == 0)
g_start = g;
if (g_prev != NULL)
{
g_prev->next = g;
g->prev = g_prev;
}
else
GlobalList = g;
}
}
/*
* We have all of the segments we need. Let's adjust their contents.
*/
g = g_start;
for (i = 0; i < n_segments; i++, g = g->next)
{
g->sequence = i + 1;
g->length = n_segments;
}
return g_start;
}
/**********************************************************************
* GLOBAL_Alloc
*/
unsigned int
GLOBAL_Alloc(unsigned int flags, unsigned long size)
{
GDESC *g;
GDESC *g_prev;
void *m;
int i;
/*
* If this block is fixed or very big we need to allocate entire
* segments.
*/
if (size > 0x8000 || !(flags & GLOBAL_FLAGS_MOVEABLE))
{
int segments = (size >> 16) + 1;
g = GLOBAL_GetFreeSegments(flags, segments);
if (g == NULL)
return 0;
else
return g->handle;
}
/*
* Otherwise we just need a little piece of a segment.
*/
else
{
/*
* Try to allocate from active free lists.
*/
for (g = GlobalList; g != NULL; g = g->next)
{
if (g->handle == 0 && g->sequence == 0)
{
m = HEAP_Alloc((MDESC **) g->addr, 0, size);
if (m != NULL)
break;
}
}
/*
* If we couldn't get the memory there, then we need to create
* a new free list.
*/
if (m == NULL)
{
g = GLOBAL_GetFreeSegments(0, 1);
if (g == NULL)
return 0;
g->handle = 0;
g->sequence = 0;
HEAP_Init((MDESC **) g->addr, (MDESC **) g->addr + 1,
0x10000 - sizeof(MDESC **));
m = HEAP_Alloc((MDESC **) g->addr, 0, size);
if (m == NULL)
return 0;
}
/*
* We have a new block. Let's create a GDESC entry for it.
*/
g_prev = NULL;
i = 0;
for (g = GlobalList; g != NULL; g = g->next, i++)
g_prev = g;
g = malloc(sizeof(*g));
if (g == NULL)
return 0;
g->handle = i << 3;
g->sequence = 0;
g->addr = m;
g->length = size;
g->next = NULL;
if (g_prev != NULL)
{
g_prev->next = g;
g->prev = g_prev;
}
else
{
GlobalList = g;
g->prev = NULL;
}
return g->handle;
}
}
/**********************************************************************
* GLOBAL_Free
*
* Windows programs will pass a handle in the "block" parameter, but
* this function will also accept a 32-bit address.
*/
unsigned int
GLOBAL_Free(unsigned int block)
{
GDESC *g;
if (block == 0)
return 0;
/*
* Find GDESC for this block.
*/
if (block & 0xffff0000)
{
for (g = GlobalList; g != NULL; g = g->next)
if (g->handle > 0 && (unsigned int) g->addr == block)
break;
}
else
{
for (g = GlobalList; g != NULL; g = g->next)
if (g->handle == block)
break;
}
if (g == NULL)
return block;
/*
* If the sequence number is zero then use HEAP_Free to deallocate
* memory, and throw away this descriptor.
*/
if (g->sequence == 0)
{
HEAP_Free((MDESC **) (block & 0xffff0000), (void *) block);
if (g->prev != NULL)
g->prev->next = g->next;
else
GlobalList = g->next;
if (g->next != NULL)
g->next->prev = g->prev;
free(g);
}
/*
* Otherwise just mark these descriptors as free.
*/
else
{
int i, limit;
g->length;
for (i = 0; i < limit; i++)
{
g->sequence = -1;
g->length = 0x10000;
}
}
return 0;
}
/**********************************************************************
* GLOBAL_Lock
*
*/
void *
GLOBAL_Lock(unsigned int block)
{
GDESC *g;
if (block == 0)
return 0;
/*
* Find GDESC for this block.
*/
for (g = GlobalList; g != NULL; g = g->next)
if (g->handle == block)
return g->addr;
return NULL;
}
static char RCSId[] = "$Id: heap.c,v 1.1 1993/06/29 15:55:18 root Exp $";
static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
#include <stdlib.h>
#include "prototypes.h"
#include "segmem.h"
#include "heap.h"
typedef struct heap_mem_desc_s
{
struct heap_mem_desc_s *prev, *next;
int length;
} MDESC;
MDESC *FreeList;
MDESC *LOCAL_FreeList;
/**********************************************************************
* HEAP_LocalInit
* HEAP_Init
*/
void
HEAP_LocalInit(void *start, int length)
HEAP_Init(MDESC **free_list, void *start, int length)
{
FreeList = (MDESC *) start;
FreeList->prev = NULL;
FreeList->next = NULL;
FreeList->length = length - sizeof(MDESC);
*free_list = (MDESC *) start;
(*free_list)->prev = NULL;
(*free_list)->next = NULL;
(*free_list)->length = length - sizeof(MDESC);
}
/**********************************************************************
* HEAP_LocalAlloc
* HEAP_Alloc
*/
void *
HEAP_LocalAlloc(int flags, int bytes)
HEAP_Alloc(MDESC **free_list, int flags, int bytes)
{
MDESC *m, *m_new;
#ifdef HEAP_DEBUG
printf("LocalAlloc: flags %x, bytes %d, ", flags, bytes);
#ifdef DEBUG_HEAP
printf("HeapAlloc: free_list %08x, flags %x, bytes %d\n",
free_list, flags, bytes);
#endif
/*
* Find free block big enough.
*/
for (m = FreeList; m != NULL; m = m->next)
for (m = *free_list; m != NULL; m = m->next)
{
if (m->length == bytes && m->length < bytes + 4 * sizeof(MDESC))
if (m->length >= bytes && m->length < bytes + 4 * sizeof(MDESC))
{
break;
}
......@@ -50,7 +47,7 @@ HEAP_LocalAlloc(int flags, int bytes)
{
m_new = m + (bytes / sizeof(MDESC)) + 2;
if (m->prev == NULL)
FreeList = m_new;
*free_list = m_new;
else
m->prev->next = m_new;
......@@ -62,9 +59,8 @@ HEAP_LocalAlloc(int flags, int bytes)
m_new->length = m->length - ((int) m_new - (int) m);
m->length -= (m_new->length + sizeof(MDESC));
#ifdef HEAP_DEBUG
printf("Returning %x\n", (int) (m + 1));
#endif
m->prev = m;
m->next = m;
return (void *) (m + 1);
}
}
......@@ -72,22 +68,144 @@ HEAP_LocalAlloc(int flags, int bytes)
if (m != NULL)
{
if (m->prev == NULL)
FreeList = m->next;
*free_list = m->next;
else
m->prev->next = m->next;
if (m->next != NULL)
m->next->prev = m->prev;
#ifdef HEAP_DEBUG
printf("Returning %x\n", (int) (m + 1));
#endif
m->prev = m;
m->next = m;
return (void *) (m + 1);
}
#ifdef HEAP_DEBUG
printf("Returning 0\n");
#endif
return 0;
}
/**********************************************************************
* HEAP_Free
*/
void
HEAP_Free(MDESC **free_list, void *block)
{
MDESC *m_free;
MDESC *m;
MDESC *m_prev;
/*
* Validate pointer.
*/
m_free = (MDESC *) block - 1;
if (m_free->prev != m_free || m_free->next != m_free ||
((int) m_free & 0xffff0000) != ((int) *free_list & 0xffff0000))
{
#ifdef DEBUG_HEAP
printf("Attempt to free bad pointer,"
"m_free = %08x, *free_list = %08x\n",
m_free, free_list);
#endif
return;
}
/*
* Find location in free list.
*/
m_prev = NULL;
for (m = *free_list; m != NULL && m < m_free; m = m->next)
m_prev = m;
if (m_prev != NULL && (int) m_prev + m_prev->length > (int) m_free)
{
#ifdef DEBUG_HEAP
printf("Attempt to free bad pointer,"
"m_free = %08x, m_prev = %08x (length %x)\n",
m_free, m_prev, m_prev->length);
#endif
return;
}
if ((m != NULL && (int) m_free + m_free->length > (int) m) ||
(int) m_free + m_free->length > ((int) m_free | 0xffff))
{
#ifdef DEBUG_HEAP
printf("Attempt to free bad pointer,"
"m_free = %08x (length %x), m = %08x\n",
m_free, m_free->length, m);
#endif
return;
}
/*
* Put block back in free list.
* Does it merge with the previos block?
*/
if (m_prev != NULL)
{
if ((int) m_prev + m_prev->length == (int) m_free)
{
m_prev->length += sizeof(MDESC) + m_free->length;
m_free = m_prev;
}
else
{
m_prev->next = m_free;
m_free->prev = m_prev;
}
}
else
{
*free_list = m_free;
m_free->prev = NULL;
}
/*
* Does it merge with the next block?
*/
if (m != NULL)
{
if ((int) m_free + m_free->length == (int) m)
{
m_free->length += sizeof(MDESC) + m->length;
m_free->next = m->next;
}
else
{
m->prev = m_free;
m_free->next = m;
}
}
else
{
m_free->next = NULL;
}
}
/**********************************************************************
* HEAP_LocalInit
*/
void
HEAP_LocalInit(void *start, int length)
{
HEAP_Init(&LOCAL_FreeList, start, length);
}
/**********************************************************************
* HEAP_LocalAlloc
*/
void *
HEAP_LocalAlloc(int flags, int bytes)
{
void *m;
#ifdef DEBUG_HEAP
printf("LocalAlloc: flags %x, bytes %d\n", flags, bytes);
#endif
m = HEAP_Alloc(&LOCAL_FreeList, flags, bytes);
#ifdef DEBUG_HEAP
printf("LocalAlloc: returning %x\n", (int) m);
#endif
return m;
}
/* $Id: heap.h,v 1.2 1993/07/04 04:04:21 root Exp root $
*/
/*
* Copyright Robert J. Amstadt, 1993
*/
#ifndef HEAP_H
#define HEAP_H
typedef struct heap_mem_desc_s
{
struct heap_mem_desc_s *prev, *next;
int length;
} MDESC;
extern void HEAP_Init(MDESC **free_list, void *start, int length);
extern void *HEAP_Alloc(MDESC **free_list, int flags, int bytes);
extern void HEAP_Free(MDESC **free_list, void *block);
#endif /* HEAP_H */
......@@ -19,11 +19,12 @@ saved_ss:
/**********************************************************************
* Places to keep info about the current 16-bit stack frame.
*/
saved_16esp:
.globl _IF1632_Saved16_esp,_IF1632_Saved16_ebp,_IF1632_Saved16_ss
_IF1632_Saved16_esp:
.long 0
saved_16ebp:
_IF1632_Saved16_ebp:
.long 0
saved_16ss:
_IF1632_Saved16_ss:
.word 0
nbytes:
......@@ -136,6 +137,88 @@ _CallToInit16:
ret
/**********************************************************************
* int CallTo16(unsigned long csip, unsigned short ds)
*
* Stack: 0 ebp
* 4 eip
* 8 target ip
* 10 target cs
* 12 target ds
*/
.align 4
.globl _CallTo16
_CallTo16:
pushl %ebp
movl %esp,%ebp
/*
* Get target address and new ds
*/
movl 8(%ebp),%eax
movl %eax,jump_target
lea jump_target,%edx
movw 12(%ebp),%ax
/*
* Switch to 16-bit stack
*/
pushl saved_esp
pushl saved_ebp
pushw saved_ss
movw %ss,saved_ss
movl %esp,saved_esp
movl %ebp,saved_ebp
movw _IF1632_Saved16_ss,%ss
movl _IF1632_Saved16_esp,%esp
movl _IF1632_Saved16_ebp,%ebp
/*
* Call entry point
*/
movw %ax,%ds
.byte 0x66
lcall %fs:(%edx)
/*
* Restore old stack and segment registers.
*
* Two choices here:
* 1. Trust that fs or gs hasn't changed.
* 2. Rely on knowledge of Linux use of segments.
*
* I'll opt for choice 2 because who knows what programs we
* going to run. Linux should be fairly stable in terms of
* GDT usage.
*/
pushl %eax
movw $0x2b,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%fs
movw %ax,%gs
popl %eax
movw %ss,_IF1632_Saved16_ss
movl %esp,_IF1632_Saved16_esp
movl %ebp,_IF1632_Saved16_ebp
movw saved_ss,%ss
movl saved_esp,%esp
movl saved_ebp,%ebp
popw saved_ss
popl saved_ebp
popl saved_esp
movl %eax,return_value
movw return_value+2,%dx
.align 2,0x90
leave
ret
/**********************************************************************
* CallTo32()
*
* This function is called as a relay point to the built function
......@@ -174,13 +257,13 @@ _CallTo32:
* Save old stack save variables, save stack registers, reload
* stack registers.
*/
pushl saved_16esp
pushl saved_16ebp
pushw saved_16ss
pushl _IF1632_Saved16_esp
pushl _IF1632_Saved16_ebp
pushw _IF1632_Saved16_ss
movw %ss,saved_16ss
movl %esp,saved_16esp
movl %ebp,saved_16ebp
movw %ss,_IF1632_Saved16_ss
movl %esp,_IF1632_Saved16_esp
movl %ebp,_IF1632_Saved16_ebp
movw saved_ss,%ss
movl saved_esp,%esp
......@@ -189,21 +272,21 @@ _CallTo32:
/*
* Call entry point
*/
pushw saved_16ss
pushw saved_16esp
pushw _IF1632_Saved16_ss
pushw _IF1632_Saved16_esp
pushl %eax
call _DLLRelay
/*
* Restore registers, but do not destroy return value.
*/
movw saved_16ss,%ss
movl saved_16esp,%esp
movl saved_16ebp,%ebp
movw _IF1632_Saved16_ss,%ss
movl _IF1632_Saved16_esp,%esp
movl _IF1632_Saved16_ebp,%ebp
popw saved_16ss
popl saved_16ebp
popl saved_16esp
popw _IF1632_Saved16_ss
popl _IF1632_Saved16_ebp
popl _IF1632_Saved16_esp
popw %es
popw %ds
......@@ -252,17 +335,15 @@ _KERNEL_InitTask:
/*
* Restore stack
*/
movw saved_16ss,%ss
movl saved_16esp,%esp
movl saved_16ebp,%ebp
movw _IF1632_Saved16_ss,%ss
movl _IF1632_Saved16_esp,%esp
movl _IF1632_Saved16_ebp,%ebp
popw saved_16ss
popl saved_16ebp
popl saved_16esp
popw _IF1632_Saved16_ss
popl _IF1632_Saved16_ebp
popl _IF1632_Saved16_esp
popw %es
/* movw _PSPSelector,%ax
movw %ax,%es */
popw %ds
.align 2,0x90
......
static char RCSId[] = "$Id: kernel.c,v 1.1 1993/06/29 15:55:18 root Exp $";
static char RCSId[] = "$Id: kernel.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
......@@ -93,6 +93,9 @@ KERNEL_DOS3Call(int ax, int cx, int dx, int bx, int sp, int bp,
case 0x35:
return 0;
case 0x4c:
exit(ax & 0xff);
default:
fprintf(stderr, "DOS: AX %04x, BX %04x, CX %04x, DX %04x\n",
ax, bx, cx, dx);
......
# $Id: kernel.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
# $Id: kernel.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
#
name kernel
id 1
......@@ -6,13 +6,18 @@ length 410
3 return GetVersion 0 0x301
5 pascal LocalAlloc(word word) HEAP_LocalAlloc(1 2)
15 pascal GlobalAlloc(word long) GLOBAL_Alloc(1 2)
17 pascal GlobalFree(word) GLOBAL_Free(1)
18 pascal GLobalLock(word) GLOBAL_Lock(1)
23 pascal LockSegment(s_word) KERNEL_LockSegment(1)
24 pascal UnlockSegment(s_word) KERNEL_UnlockSegment(1)
30 pascal WaitEvent(word) KERNEL_WaitEvent(1)
49 pascal GetModuleFileName(word ptr s_word) KERNEL_GetModuleFileName(1 2 3)
51 pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2)
91 pascal InitTask() KERNEL_InitTask()
102 register DOS3Call(word word word word word
word word word word word)
KERNEL_DOS3Call(1 2 3 4 5 6 7 8 9 10)
131 pascal GetDOSEnvironment() GetDOSEnvironment()
132 return GetWinFlags 0 0x413
178 equate __WINFLAGS 0x413
static char RCSId[] = "$Id: ldt.c,v 1.1 1993/06/29 15:55:18 root Exp $";
static char RCSId[] = "$Id: ldt.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
......
static char RCSId[] = "$Id: ldtlib.c,v 1.1 1993/06/29 15:55:18 root Exp $";
static char RCSId[] = "$Id: ldtlib.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
......
/* $Id: neexe.h,v 1.3 1993/06/30 14:24:33 root Exp root $
/* $Id: neexe.h,v 1.4 1993/07/04 04:04:21 root Exp root $
*/
/*
* Copyright Robert J. Amstadt, 1993
......
/* $Id: prototypes.h,v 1.1 1993/06/29 15:55:18 root Exp $
/* $Id: prototypes.h,v 1.3 1993/07/04 04:04:21 root Exp root $
*/
/*
* Copyright Robert J. Amstadt, 1993
......@@ -9,10 +9,10 @@
#include <sys/types.h>
#include "neexe.h"
#include "segmem.h"
#include "wine.h"
extern struct segment_descriptor_s *
CreateSelectors(int fd, struct ne_segment_table_entry_s *seg_table,
struct ne_header_s *ne_header);
CreateSelectors(struct w_files *);
extern void PrintFileHeader(struct ne_header_s *ne_header);
extern void PrintSegmentTable(struct ne_segment_table_entry_s *seg_table,
......@@ -20,18 +20,17 @@ extern void PrintSegmentTable(struct ne_segment_table_entry_s *seg_table,
extern void PrintRelocationTable(char *exe_ptr,
struct ne_segment_table_entry_s *seg_entry_p,
int segment);
extern int FixupSegment(int fd, struct mz_header_s * mz_header,
struct ne_header_s *ne_header,
struct ne_segment_table_entry_s *seg_table,
struct segment_descriptor_s *selecetor_table,
int segment_num);
extern int FixupSegment(struct w_files * wpnt, int segment_num);
extern struct dll_table_entry_s *FindDLLTable(char *dll_name);
extern unsigned int GetEntryPointFromOrdinal(int fd,
struct mz_header_s *mz_header,
struct ne_header_s *ne_header,
extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt,
int ordinal);
extern char WIN_CommandLine[];
extern struct segment_descriptor_s *GetNextSegment(unsigned int flags,
unsigned int limit);
extern unsigned int GLOBAL_Alloc(unsigned int flags, unsigned long size);
extern unsigned int GLOBAL_Free(unsigned int block);
extern void *GLOBAL_Lock(unsigned int block);
extern struct mz_header_s *CurrentMZHeader;
extern struct ne_header_s *CurrentNEHeader;
extern int CurrentNEFile;
......
static char RCSId[] = "$Id: relay.c,v 1.1 1993/06/29 15:55:18 root Exp $";
static char RCSId[] = "$Id: relay.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
......
static char RCSId[] = "$Id: resource.c,v 1.3 1993/06/30 14:24:33 root Exp root $";
static char RCSId[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
#include <stdlib.h>
#include "prototypes.h"
#include "neexe.h"
#include "windows.h"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
......@@ -14,10 +15,90 @@ typedef struct resource_data_s
void *resource_data;
} RSCD;
int ResourceSizes[16] =
{
0, 0, sizeof(BITMAP), 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
};
RSCD *Resources;
int ResourceArraySize;
/**********************************************************************
* ConvertCoreBitmap
*/
void *
ConvertCoreBitmap(BITMAPCOREHEADER *image, int image_size)
{
BITMAP *new_image;
char *old_p, *new_p;
int old_line_length, new_line_length;
unsigned int handle;
int i;
int n_colors;
n_colors = 1 << image->bcBitCount;
handle = GLOBAL_Alloc(GMEM_MOVEABLE,
image_size + sizeof(*new_image) + n_colors);
new_image = GLOBAL_Lock(handle);
if (new_image == NULL)
return NULL;
new_image->bmType = 0;
new_image->bmWidth = image->bcWidth;
new_image->bmHeight = image->bcHeight;
new_image->bmPlanes = image->bcPlanes;
new_image->bmBitsPixel = image->bcBitCount;
if (image->bcBitCount < 24)
{
RGBTRIPLE *old_color = (RGBTRIPLE *) (image + 1);
RGBQUAD *new_color = (RGBQUAD *) (new_image + 1);
for (i = 0; i < n_colors; i++)
{
memcpy(new_color, old_color, sizeof(*old_color));
new_color++;
old_color++;
}
old_p = (char *) old_color;
new_p = (char *) new_color;
old_line_length = image->bcWidth / (8 / image->bcBitCount);
}
else
{
old_p = (char *) (image + 1);
new_p = (char *) (new_image + 1);
old_line_length = image->bcWidth * 3;
}
new_line_length = (old_line_length + 1) & ~1;
old_line_length = (old_line_length + 3) & ~3;
new_image->bmBits = (unsigned long) new_p;
new_image->bmWidthBytes = new_line_length;
for (i = 0; i < image->bcHeight; i++)
{
memcpy(new_p, old_p, new_line_length);
new_p += new_line_length;
old_p += old_line_length;
}
return new_image;
}
/**********************************************************************
* ConvertInfoBitmap
*/
void *
ConvertInfoBitmap(BITMAPINFOHEADER *image, int image_size)
{
}
/**********************************************************************
* AddResource
*/
int
......@@ -183,37 +264,35 @@ RSC_LoadString(int instance, int resource_id, char *buffer, int buflen)
}
/**********************************************************************
* RSC_LoadBitmap
* RSC_LoadResource
*/
int
RSC_LoadBitmap(int instance, char *bmp_name)
RSC_LoadResource(int instance, char *rsc_name, int type)
{
struct resource_nameinfo_s nameinfo;
void *image;
void *rsc_image;
long *lp;
int image_size;
int size_shift;
#ifdef DEBUG_RESOURCE
printf("LoadBitmap: instance = %04x, name = %08x\n",
instance, bmp_name);
#endif
/*
* Built-in bitmaps
* Built-in resources
*/
if (instance == 0)
{
return 0;
}
/*
* Get bitmap by ordinal
* Get resource by ordinal
*/
else if (((int) bmp_name & 0xffff0000) == 0)
else if (((int) rsc_name & 0xffff0000) == 0)
{
size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_BITMAP,
(int) bmp_name | 0x8000);
size_shift = FindResourceByNumber(&nameinfo, type,
(int) rsc_name | 0x8000);
}
/*
* Get bitmap by name
* Get resource by name
*/
else
{
......@@ -223,7 +302,7 @@ RSC_LoadBitmap(int instance, char *bmp_name)
return 0;
/*
* Read bitmap.
* Read resource.
*/
lseek(CurrentNEFile, ((int) nameinfo.offset << size_shift), SEEK_SET);
......@@ -236,7 +315,81 @@ RSC_LoadBitmap(int instance, char *bmp_name)
}
/*
* Convert bitmap to internal format.
*/
lp = (long *) image;
if (*lp == sizeof(BITMAPCOREHEADER))
rsc_image = ConvertCoreBitmap(image, image_size);
else if (*lp == sizeof(BITMAPINFOHEADER))
rsc_image = ConvertInfoBitmap(image, image_size);
free(image);
/*
* Add to resource list.
*/
return AddResource(NE_RSCTYPE_BITMAP, image);
if (rsc_image)
return AddResource(type, rsc_image);
else
return 0;
}
/**********************************************************************
* RSC_LoadIcon
*/
int
RSC_LoadIcon(int instance, char *icon_name)
{
#ifdef DEBUG_RESOURCE
printf("LoadIcon: instance = %04x, name = %08x\n",
instance, icon_name);
#endif
return RSC_LoadResource( instance, icon_name, NE_RSCTYPE_ICON);
}
/**********************************************************************
* RSC_LoadBitmap
*/
int
RSC_LoadBitmap(int instance, char *bmp_name)
{
#ifdef DEBUG_RESOURCE
printf("LoadBitmap: instance = %04x, name = %08x\n",
instance, bmp_name);
#endif
return RSC_LoadResource( instance, bmp_name, NE_RSCTYPE_BITMAP);
}
/**********************************************************************
* RSC_LoadCursor
*/
int
RSC_LoadCursor(int instance, char *cursor_name)
{
#ifdef DEBUG_RESOURCE
printf("LoadCursor: instance = %04x, name = %08x\n",
instance, cursor_name);
#endif
return RSC_LoadResource( instance, cursor_name, NE_RSCTYPE_CURSOR);
}
/**********************************************************************
* RSC_GetObject
*/
int
RSC_GetObject(int handle, int nbytes, void *buffer)
{
if (handle > 0 && handle <= ResourceArraySize)
{
RSCD *r = &Resources[handle - 1];
if (r->resource_type > 0)
{
int n = MIN(nbytes, ResourceSizes[r->resource_type & 0xf]);
memcpy(buffer, r->resource_data, n);
return n;
}
}
return 0;
}
/* $Id: segmem.h,v 1.1 1993/06/29 15:55:18 root Exp $
/* $Id: segmem.h,v 1.3 1993/07/04 04:04:21 root Exp root $
*/
/*
* Copyright Robert J. Amstadt, 1993
......@@ -23,4 +23,13 @@ struct segment_descriptor_s
*/
#define NE_SEGFLAGS_MALLOCED 0x00010000 /* Memory allocated with malloc() */
/*
* Global memory flags
*/
#define GLOBAL_FLAGS_MOVEABLE 0x0002
#define GLOBAL_FLAGS_ZEROINIT 0x0040
#define GLOBAL_FLAGS_CODE 0x00010000
#define GLOBAL_FLAGS_EXECUTEONLY 0x00020000
#define GLOBAL_FLAGS_READONLY 0x00020000
#endif /* SEGMEM_H */
# $Id: shell.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
# $Id: shell.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
#
name shell
id 5
......
# Tcl autoload index file: each line identifies a Tcl
# procedure and the file where that procedure is
# defined. Generated by the "auto_mkindex" command.
CreateWindow Windows.tcl
CreateMenuBar Windows.tcl
AppendMenu Windows.tcl
# Unimplemented stuff
LoadIcon Windows.tcl
LoadCursor Windows.tcl
GetStockObject Windows.tcl
DefWindowProc Windows.tcl
This diff is collapsed. Click to expand it.
# $Id: unixlib.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
# $Id: unixlib.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
#
name unixlib
id 4
......
static char RCSId[] = "$Id: user.c,v 1.1 1993/06/29 15:55:18 root Exp $";
static char RCSId[] = "$Id: user.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <stdio.h>
......
# $Id: user.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
# $Id: user.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
#
name user
id 2
length 540
1 pascal MessageBox(word ptr ptr word) MessageBox(1 2 3 4)
5 pascal InitApp(word) USER_InitApp(1)
6 pascal PostQuitMessage(word) PostQuitMessage(1)
33 pascal GetClientRect(word ptr) GetClientRect(1 2)
39 pascal BeginPaint(word ptr) BeginPaint(1 2)
40 pascal EndPaint(word ptr) EndPaint(1 2)
41 pascal CreateWindow(ptr ptr long word word word word word word word ptr)
CreateWindow(1 2 3 4 5 6 7 8 9 10 11)
42 pascal ShowWindow(word word) ShowWindow(1 2)
57 pascal RegisterClass(ptr) RegisterClass(1)
66 pascal GetDC(word) GetDC(1)
85 pascal DrawText(word ptr word ptr word) DrawText(1 2 3 4 5)
104 pascal MessageBeep(word) MessageBeep(1)
107 pascal DefWindowProc(word word word long) DefWindowProc(1 2 3 4)
108 pascal GetMessage(ptr word word word) GetMessage(1 2 3 4)
113 pascal TranslateMessage(ptr) TranslateMessage(1)
114 pascal DispatchMessage(ptr) DispatchMessage(1)
124 pascal UpdateWindow(word) UpdateWindow(1)
151 pascal CreateMenu() CreateMenu()
157 pascal GetMenu(word) GetMenu(1)
158 pascal SetMenu(word word) SetMenu(1 2)
173 pascal LoadCursor(word ptr) RSC_LoadCursor(1 2)
174 pascal LoadIcon(word ptr) RSC_LoadIcon(1 2)
175 pascal LoadBitmap(word ptr) RSC_LoadBitmap(1 2)
176 pascal LoadString(word word ptr s_word) RSC_LoadString(1 2 3 4)
411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4)
# $Id: win87em.spec,v 1.2 1993/06/30 14:24:33 root Exp root $
# $Id: win87em.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
#
name win87em
id 5
......
#ifndef WINE_H
#define WINE_H
#include "dlls.h"
struct w_files{
struct w_files * next;
char * name; /* Name, as it appears in the windows binaries */
char * filename; /* Actual name of the unix file that satisfies this */
int fd;
struct mz_header_s *mz_header;
struct ne_header_s *ne_header;
struct ne_segment_table_entry_s *seg_table;
struct segment_descriptor_s *selector_table;
char * lookup_table;
char * nrname_table;
char * rname_table;
};
extern struct w_files * wine_files;
#endif
This diff is collapsed. Click to expand it.
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