Release 0.4.3

Tue Sep 28 19:59:21 1993  David Metcalfe

	* [windows/win.c]
	Implemented support for windows with no borders.  Added
 	GetParent(), GetDlgCtrlID(), GetWindowText() and
	GetWindowTextLength() functions.

	* [misc/xt.c]
	Added processing of WM_GETTEXT and WM_GETTEXTLENGTH messages
	to DefWindowProc and Implemented MessageBeep().

	* [windows/syscolor.c]
	Added preliminary system color support.

	* [controls/button1.c]
	Mods to new button control and integration with Wine.

Tue Sep 28 19:59:21 1993  Johannes Ruscheinski

	* [controls/button1.c]
	New button control using GDI functions.
	
Tue Sep 28 19:59:21 1993  Eric Youngdale

	* [debugger/*]
	Added debugging capabilities to Wine

Sat Sep 25 13:22:50 1993  Alexandre Julliard  (julliard@di.epfl.ch)

	* [objects/region.c]
	Bug fix

Fri Sep 24 07:35:11 1993  Bob Amstadt  (bob at pooh)

	* [tools/build.c]
	Changed the entry point code to reduce the standard entry
	point size from 22 bytes to 10 bytes.  This leaves about
	4000 free entry points instead of the 800 in version 0.4.2.

	* [loader/resource.c]
	Rewrote functions to allow loading of resources from any
	DLL.

	* [loader/wine.c] [include/wine.h]
	Added functions GetFilenameFromInstance() and GetFileInfo()
	to search for a loaded file based on its instance handle.
	Added a field in struct w_files to make searching by an instance
	handle faster.

Tue Sep 21 09:57:01 1993  miguel@roxanne.nuclecu.unam.mx (Miguel de Icaza)

	* [misc/profile.c]
	Implementation of .INI file handling

Mon Sep 20 10:54:32 1993  David Metcalfe

	* [misc/profile.c.old]
	Implementation of .INI file handling

Mon Sep 20 10:54:32 1993  John Brezak

	* [controls/WinButton.c]
	Bug fix with call to XtVaSetValues.

Mon Sep 20 10:54:32 1993  Alexandre Julliard

	* [windows/win.c]
	Quick patch to get colormaps to work with button widget.

Mon Sep 20 02:42:54 1993    (yngvi@hafro.is)

	* misc/keyboard.c: 
	Ifdefed out some bogus Ansi<->Oem conversion functions

	* misc/lstr.c: 
	New file with string functions like lstr* IsChar* *Ansi* 

Wed Sep 15 20:35:10 1993  John Brezak

	* [loader/signal.c]
	Additional changes to support NetBSD.

Wed Sep 15 22:19:22 1993  Martin Ayotte

	* [windows/graphics.c]
	Added FrameRect function

Tue Sep 14 13:54:45 1993  Alexandre Julliard

	* [objects/color.c] [objects/palette.c]
	Preliminary support for private color map.

	* [windows/class.c]
	Implemented CS_CLASSDC style.

	* [windows/dce.c]
	Moved DCEs to USER heap.
	Implemented class and window DCs.

	* [windows/event.c]
	Implemented CS_DBLCLKS style.

	* [windows/graphics.c]
	Bug fix in SetPixel().

	* [windows/win.c]	
	Implemented CS_OWNDC style.
	Implemented Get/SetWindowLong().

	* [controls/menu.c] [windows/class.c] [windows/clipping.c] 
	  [windows/dce.c] [windows/message.c] [windows/win.c]	
	Moved windows from global heap to USER heap.
diff --git a/ALPHA-pl13.diff b/ALPHA-pl13.diff
deleted file mode 100644
index 6f675a5..0000000
--- a/ALPHA-pl13.diff
+++ /dev/null
@@ -1,7864 +0,0 @@
-diff -u --recursive --new-file pl12/linux/README linux/README
---- pl12/linux/README	Sun Aug 15 14:26:24 1993
-+++ linux/README	Mon Aug 16 22:18:24 1993
-@@ -1,7 +1,13 @@
- 
--	Linux kernel release 0.99 patchlevel 12
-+	Linux kernel release 0.99 patchlevel 13
- 
--These are the release notes for linux version 0.99.12.  Read them
-+[ Just to show everybody that I have no personal integrity at all, this
-+release is dedicated to Martin Mueller and Sebastian Hetze just because
-+they wrote the German Linux Anwenderhandbuch.  The fact that they sent
-+me some of the money they made on selling it has nothing at all to do
-+with the dedication.  Oh, no.  That would be crass.  ]
-+
-+These are the release notes for linux version 0.99.13.  Read them
- carefully, as they tell you what's new, explain how to install the
- kernel, and what to do if something goes wrong. 
- 
-diff -u --recursive --new-file pl12/linux/config.in linux/config.in
---- pl12/linux/config.in	Sun Aug 15 11:24:56 1993
-+++ linux/config.in	Sat Sep  4 15:17:42 1993
-@@ -13,6 +13,10 @@
- bool 'System V IPC' CONFIG_SYSVIPC y
- bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
- *
-+* Program binary formats
-+*
-+bool 'Elf executables' CONFIG_BINFMT_ELF y
-+*
- * SCSI support
- *
- bool 'SCSI support?' CONFIG_SCSI n
-@@ -49,14 +53,14 @@
- bool 'SLIP (serial line) support' CONFIG_SLIP n
- bool 'PLIP (parallel port) support' CONFIG_PLIP n
- bool 'NE2000/NE1000 support' CONFIG_NE2000 y
--bool 'WD80*3 support' CONFIG_WD80x3 y
-+bool 'WD80*3 support' CONFIG_WD80x3 n
- #bool '3c501 support' CONFIG_EL1 n
- bool '3c503 support' CONFIG_EL2 y
- #bool '3c509 support' CONFIG_EL3 n
--bool 'HP PCLAN support' CONFIG_HPLAN y
--bool 'AT1500 and NE2100 support' CONFIG_AT1500 y
-+bool 'HP PCLAN support' CONFIG_HPLAN n
-+bool 'AT1500 and NE2100 support' CONFIG_AT1500 n
- #bool 'DEPCA support' CONFIG_DEPCA n
--bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 y
-+bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
- #bool 'AT-LAN-TEC pocket adaptor support' CONFIG_ATP n
- #bool 'EtherExpress support' CONFIG_EEXPRESS n
- fi
-@@ -79,7 +83,7 @@
- *
- bool 'Keyboard meta-key sends ESC-prefix' CONFIG_KBD_META y
- bool 'Keyboard Num Lock on by default' CONFIG_KBD_NUML y
--bool 'Logitech busmouse support' CONFIG_BUSMOUSE n
-+bool 'Logitech busmouse support' CONFIG_BUSMOUSE y
- bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
- bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
- bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
-@@ -95,5 +99,5 @@
- bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n
- bool 'Kernel profiling support' CONFIG_PROFILE n
- if [ "$CONFIG_SCSI" = "y" ]
--bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS n
-+bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
- fi
-diff -u --recursive --new-file pl12/linux/fs/Makefile linux/fs/Makefile
---- pl12/linux/fs/Makefile	Sun Mar  7 16:21:10 1993
-+++ linux/fs/Makefile	Fri Aug 20 08:59:30 1993
-@@ -34,6 +34,9 @@
- FS_SUBDIRS := $(FS_SUBDIRS) xiafs
- endif
- 
-+ifdef CONFIG_BINFMT_ELF
-+BINFMTS := $(BINFMTS) binfmt_elf.o
-+endif
- 
- .c.s:
- 	$(CC) $(CFLAGS) -S $<
-@@ -44,7 +47,7 @@
- 
- OBJS=	open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \
- 	block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
--	select.o fifo.o locks.o filesystems.o
-+	select.o fifo.o locks.o filesystems.o $(BINFMTS)
- 
- all: fs.o filesystems.a
- 
-diff -u --recursive --new-file pl12/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
---- pl12/linux/fs/binfmt_elf.c
-+++ linux/fs/binfmt_elf.c	Sat Sep  4 03:36:30 1993
-@@ -0,0 +1,368 @@
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+#include <linux/mm.h>
-+#include <linux/mman.h>
-+#include <linux/a.out.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/binfmts.h>
-+#include <asm/segment.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+
-+asmlinkage int sys_exit(int exit_code);
-+asmlinkage int sys_close(unsigned fd);
-+asmlinkage int sys_open(const char *, int, int);
-+
-+/*
-+ * These are the functions used to load ELF style executables and shared
-+ * libraries.  There is no binary dependent code anywhere else.
-+ */
-+
-+#include <linux/elf.h>
-+
-+int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
-+{
-+	struct elfhdr elf_ex;
-+	struct file * file;
-+  	struct exec ex;
-+	struct inode *interpreter_inode;
-+	int i;
-+	int old_fs;
-+	int error;
-+	struct elf_phdr * elf_ppnt, *elf_phdata;
-+	int elf_exec_fileno;
-+	unsigned int elf_bss, k, elf_brk;
-+	int retval;
-+	char * elf_interpreter;
-+	unsigned int elf_entry;
-+	int status;
-+	unsigned int start_code, end_code, end_data;
-+	unsigned int elf_stack;
-+	char passed_fileno[6];
-+	
-+	status = 0;
-+	elf_ex = *((struct elfhdr *) bprm->buf);	  /* exec-header */
-+	
-+	if (elf_ex.e_ident[0] != 0x7f ||
-+	    strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
-+		return  -ENOEXEC;
-+	
-+	
-+	/* First of all, some simple consistency checks */
-+	if(elf_ex.e_type != ET_EXEC || 
-+	   (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
-+	   (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
-+	    !bprm->inode->i_op->default_file_ops->mmap)){
-+		return -ENOEXEC;
-+	};
-+	
-+	/* Now read in all of the header information */
-+	
-+	elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * 
-+						 elf_ex.e_phnum, GFP_KERNEL);
-+	
-+	old_fs = get_fs();
-+	set_fs(get_ds());
-+	retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
-+			   elf_ex.e_phentsize * elf_ex.e_phnum);
-+	set_fs(old_fs);
-+	if (retval < 0) {
-+	        kfree (elf_phdata);
-+		return retval;
-+	}
-+	
-+	elf_ppnt = elf_phdata;
-+	
-+	elf_bss = 0;
-+	elf_brk = 0;
-+	
-+	elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
-+
-+	if (elf_exec_fileno < 0) {
-+	        kfree (elf_phdata);
-+		return elf_exec_fileno;
-+	}
-+	
-+	file = current->filp[elf_exec_fileno];
-+	
-+	elf_stack = 0xffffffff;
-+	elf_interpreter = NULL;
-+	start_code = 0;
-+	end_code = 0;
-+	end_data = 0;
-+	
-+	old_fs = get_fs();
-+	set_fs(get_ds());
-+	
-+	for(i=0;i < elf_ex.e_phnum; i++){
-+		if(elf_ppnt->p_type == PT_INTERP) {
-+			/* This is the program interpreter used for shared libraries - 
-+			   for now assume that this is an a.out format binary */
-+			
-+			elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, 
-+							   GFP_KERNEL);
-+			
-+			retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
-+					   elf_ppnt->p_filesz);
-+			printk("Using ELF interpreter %s\n", elf_interpreter);
-+			if(retval >= 0)
-+				retval = namei(elf_interpreter, &interpreter_inode);
-+			if(retval >= 0)
-+				retval = read_exec(interpreter_inode,0,bprm->buf,128);
-+			
-+			if(retval >= 0){
-+				ex = *((struct exec *) bprm->buf);		/* exec-header */
-+				
-+#if 0
-+				printk("Interpreter: %x %x %x\n",N_MAGIC(ex), ex.a_text,ex.a_data);
-+#endif
-+			};
-+		};
-+		elf_ppnt++;
-+	};
-+	
-+	set_fs(old_fs);
-+	
-+	/* Some simple consistency checks for the interpreter */
-+	if(elf_interpreter){
-+		if(retval < 0) {
-+			kfree(elf_interpreter);
-+			kfree(elf_phdata);
-+			return -ELIBACC;
-+		};
-+		if((N_MAGIC(ex) != OMAGIC) && (N_MAGIC(ex) != ZMAGIC)) {
-+			kfree(elf_interpreter);
-+			kfree(elf_phdata);
-+			return -ELIBBAD;
-+		};
-+	}
-+	
-+	/* OK, we are done with that, now set up the arg stuff,
-+	   and then start this sucker up */
-+	
-+	if (!bprm->sh_bang) {
-+		char * passed_p;
-+		
-+		sprintf(passed_fileno, "%d", elf_exec_fileno);
-+		passed_p = passed_fileno;
-+		
-+		if(elf_interpreter) {
-+			bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
-+			bprm->argc++;
-+		};
-+		if (!bprm->p) {
-+		        if(elf_interpreter) {
-+			      kfree(elf_interpreter);
-+			}
-+		        kfree (elf_phdata);
-+			return -E2BIG;
-+		}
-+	}
-+	
-+	/* OK, This is the point of no return */
-+	flush_old_exec(bprm);
-+
-+	current->end_data = 0;
-+	current->end_code = 0;
-+	current->start_mmap = ELF_START_MMAP;
-+	current->mmap = NULL;
-+	elf_entry = (unsigned int) elf_ex.e_entry;
-+	
-+	/* Do this so that we can load the interpreter, if need be.  We will
-+	   change some of these later */
-+	current->rss = 0;
-+	bprm->p += change_ldt(0, bprm->page);
-+	current->start_stack = bprm->p;
-+	
-+	/* Now we do a little grungy work by mmaping the ELF image into
-+	   the correct location in memory.  At this point, we assume that
-+	   the image should be loaded at fixed address, not at a variable
-+	   address. */
-+	
-+	old_fs = get_fs();
-+	set_fs(get_ds());
-+	
-+	elf_ppnt = elf_phdata;
-+	for(i=0;i < elf_ex.e_phnum; i++){
-+		
-+		if(elf_ppnt->p_type == PT_INTERP) {
-+			/* Set these up so that we are able to load the interpreter */
-+			current->brk = ex.a_bss +
-+				(current->end_data = ex.a_data +
-+				 (current->end_code = ex.a_text));
-+			elf_entry = ex.a_entry;
-+			
-+			/* Now load the interpreter into user address space */
-+			set_fs(old_fs);
-+			
-+			if (N_MAGIC(ex) == OMAGIC) {
-+				retval = read_exec(interpreter_inode, 32, (char *) 0, 
-+						   ex.a_text+ex.a_data);
-+				iput(interpreter_inode);
-+			} else if (N_MAGIC(ex) == ZMAGIC) {
-+				retval = read_exec(interpreter_inode, 1024, (char *) 0, 
-+						   ex.a_text+ex.a_data);
-+				iput(interpreter_inode);
-+			} else
-+				retval = -1;
-+			
-+			old_fs = get_fs();
-+			set_fs(get_ds());
-+			
-+			if(retval >= 0)
-+				zeromap_page_range((ex.a_text + ex.a_data + 0xfff) & 
-+						   0xfffff000, ex.a_bss, PAGE_COPY);
-+			kfree(elf_interpreter);
-+			
-+			if(retval < 0) { 
-+				kfree(elf_phdata);
-+				send_sig(SIGSEGV, current, 0);
-+				return 0;
-+			};
-+		};
-+		
-+		
-+		if(elf_ppnt->p_type == PT_LOAD) {
-+			error = do_mmap(file,
-+					elf_ppnt->p_vaddr & 0xfffff000,
-+					elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
-+					PROT_READ | PROT_WRITE | PROT_EXEC,
-+					MAP_FIXED | MAP_PRIVATE,
-+					elf_ppnt->p_offset & 0xfffff000);
-+			
-+#ifdef LOW_ELF_STACK
-+			if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack) 
-+				elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
-+#endif
-+			
-+			k = elf_ppnt->p_vaddr;
-+			if(k > start_code) start_code = k;
-+			k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
-+			if(k > elf_bss) elf_bss = k;
-+			if((elf_ppnt->p_flags | PROT_WRITE) && end_code <  k)
-+				end_code = k; 
-+			if(end_data < k) end_data = k; 
-+			k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
-+			if(k > elf_brk) elf_brk = k;		     
-+			
-+			if(status == 0xffffffff) {
-+				set_fs(old_fs);
-+				kfree(elf_phdata);
-+				send_sig(SIGSEGV, current, 0);
-+				return 0;
-+			};
-+		};
-+		elf_ppnt++;
-+	};
-+	set_fs(old_fs);
-+	
-+	kfree(elf_phdata);
-+	
-+	if(!elf_interpreter) sys_close(elf_exec_fileno);
-+	current->elf_executable = 1;
-+	current->executable = bprm->inode;
-+	bprm->inode->i_count++;
-+#ifdef LOW_ELF_STACK
-+	current->start_stack = p = elf_stack - 4;
-+#endif
-+	bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
-+	bprm->p = (unsigned long) create_tables((char *)bprm->p,bprm->argc,bprm->envc);
-+	if(elf_interpreter) current->arg_start += strlen(passed_fileno) + 1;
-+	current->start_brk = current->brk = elf_brk;
-+	current->end_code = end_code;
-+	current->start_code = start_code;
-+	current->start_stack = bprm->p;
-+	current->suid = current->euid = bprm->e_uid;
-+	current->sgid = current->egid = bprm->e_gid;
-+	zeromap_page_range((elf_bss + 0xfff) & 0xfffff000, elf_brk - elf_bss,
-+			   PAGE_COPY);
-+	regs->eip = elf_entry;		/* eip, magic happens :-) */
-+	regs->esp = bprm->p;			/* stack pointer */
-+	if (current->flags & PF_PTRACED)
-+		send_sig(SIGTRAP, current, 0);
-+	
-+	return 0;
-+}
-+
-+
-+int load_elf_library(int fd){
-+        struct file * file;
-+	struct elfhdr elf_ex;
-+	struct elf_phdr *elf_phdata  =  NULL;
-+	struct  inode * inode;
-+	unsigned int len;
-+	int old_fs, retval;
-+	unsigned int bss;
-+	int error;
-+	int i,j;
-+	
-+	len = 0;
-+	file = current->filp[fd];
-+	inode = file->f_inode;
-+	
-+	set_fs(KERNEL_DS);
-+	if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
-+		sys_close(fd);
-+		return -EACCES;
-+	}
-+	set_fs(USER_DS);
-+	
-+	if (elf_ex.e_ident[0] != 0x7f ||
-+	    strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
-+		return -ENOEXEC;
-+	
-+	/* First of all, some simple consistency checks */
-+	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
-+	   (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
-+	   (!inode->i_op || !inode->i_op->bmap || 
-+	    !inode->i_op->default_file_ops->mmap)){
-+		return -ENOEXEC;
-+	};
-+	
-+	/* Now read in all of the header information */
-+	
-+	if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) 
-+		return -ENOEXEC;
-+	
-+	elf_phdata =  (struct elf_phdr *) 
-+		kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
-+	
-+	old_fs = get_fs();
-+	set_fs(get_ds());
-+	retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
-+			   sizeof(struct elf_phdr) * elf_ex.e_phnum);
-+	set_fs(old_fs);
-+	
-+	j = 0;
-+	for(i=0; i<elf_ex.e_phnum; i++)
-+		if((elf_phdata + i)->p_type == PT_LOAD) j++;
-+	
-+	if(j != 1)  {
-+		kfree(elf_phdata);
-+		return -ENOEXEC;
-+	};
-+	
-+	while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
-+	
-+	/* Now use mmap to map the library into memory. */
-+	error = do_mmap(file,
-+			elf_phdata->p_vaddr & 0xfffff000,
-+			elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
-+			PROT_READ | PROT_WRITE | PROT_EXEC,
-+			MAP_FIXED | MAP_PRIVATE,
-+			elf_phdata->p_offset & 0xfffff000);
-+	
-+	sys_close(fd);
-+	if (error != elf_phdata->p_vaddr & 0xfffff000) {
-+	        kfree(elf_phdata);
-+		return error;
-+	}
-+	len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
-+	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
-+	if (bss > len)
-+		zeromap_page_range(len, bss-len, PAGE_COPY);
-+	kfree(elf_phdata);
-+	return 0;
-+}
-diff -u --recursive --new-file pl12/linux/fs/buffer.c linux/fs/buffer.c
---- pl12/linux/fs/buffer.c	Sat Aug 14 23:47:21 1993
-+++ linux/fs/buffer.c	Sat Sep  4 03:36:30 1993
-@@ -160,7 +160,7 @@
- 	return sync_buffers(dev, 1);
- }
- 
--extern "C" int sys_sync(void)
-+asmlinkage int sys_sync(void)
- {
- 	sync_dev(0);
- 	return 0;
-@@ -171,7 +171,7 @@
- 	return fsync_dev(inode->i_dev);
- }
- 
--extern "C" int sys_fsync(unsigned int fd)
-+asmlinkage int sys_fsync(unsigned int fd)
- {
- 	struct file * file;
- 	struct inode * inode;
-diff -u --recursive --new-file pl12/linux/fs/exec.c linux/fs/exec.c
---- pl12/linux/fs/exec.c	Sun Aug 15 11:33:07 1993
-+++ linux/fs/exec.c	Sat Sep  4 03:36:30 1993
-@@ -44,13 +44,13 @@
- #include <asm/segment.h>
- #include <asm/system.h>
- 
--extern "C" int sys_exit(int exit_code);
--extern "C" int sys_close(unsigned fd);
--extern "C" int sys_open(const char *, int, int);
-+asmlinkage int sys_exit(int exit_code);
-+asmlinkage int sys_close(unsigned fd);
-+asmlinkage int sys_open(const char *, int, int);
- 
- extern void shm_exit (void);
- 
--static int open_inode(struct inode * inode, int mode)
-+int open_inode(struct inode * inode, int mode)
- {
- 	int error, fd;
- 	struct file *f, **fpp;
-@@ -225,7 +225,7 @@
-  *
-  * Also note that we take the address to load from from the file itself.
-  */
--extern "C" int sys_uselib(const char * library)
-+asmlinkage int sys_uselib(const char * library)
- {
- 	int fd, retval;
- 	struct file * file;
-@@ -316,7 +316,7 @@
-  * it is expensive to load a segment register, we try to avoid calling
-  * set_fs() unless we absolutely have to.
-  */
--static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
-+unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
- 		unsigned long p, int from_kmem)
- {
- 	char *tmp, *pag = NULL;
-@@ -459,7 +459,7 @@
- 	current->mmap = NULL;
- 	while (mpnt) {
- 		mpnt1 = mpnt->vm_next;
--		if (mpnt->vm_ops->close)
-+		if (mpnt->vm_ops && mpnt->vm_ops->close)
- 			mpnt->vm_ops->close(mpnt);
- 		kfree(mpnt);
- 		mpnt = mpnt1;
-@@ -649,6 +649,7 @@
- 		}
- 	}
- 
-+	bprm.sh_bang = sh_bang;
- 	fmt = formats;
- 	do {
- 		int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
-@@ -672,7 +673,7 @@
- /*
-  * sys_execve() executes a new program.
-  */
--extern "C" int sys_execve(struct pt_regs regs)
-+asmlinkage int sys_execve(struct pt_regs regs)
- {
- 	int error;
- 	char * filename;
-@@ -694,9 +695,16 @@
- 			    struct pt_regs * regs);
- extern int load_aout_library(int fd);
- 
-+extern int load_elf_binary(struct linux_binprm *,
-+			    struct pt_regs * regs);
-+extern int load_elf_library(int fd);
-+
- /* Here are the actual binaries that will be accepted  */
- struct linux_binfmt formats[] = {
- 	{load_aout_binary, load_aout_library},
-+#ifdef CONFIG_BINFMT_ELF
-+	{load_elf_binary, load_elf_library},
-+#endif
- 	{NULL, NULL}
- };
- 
-@@ -713,17 +721,20 @@
- 	unsigned long p = bprm->p;
- 
- 	ex = *((struct exec *) bprm->buf);		/* exec-header */
--	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) ||
-+	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
-+	     N_MAGIC(ex) != QMAGIC) ||
- 	    ex.a_trsize || ex.a_drsize ||
- 	    bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
- 		return -ENOEXEC;
- 	}
--	if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
-+
-+	if (N_MAGIC(ex) == ZMAGIC &&
- 	    (N_TXTOFF(ex) < bprm->inode->i_sb->s_blocksize)) {
- 		printk("N_TXTOFF < BLOCK_SIZE. Please convert binary.");
- 		return -ENOEXEC;
- 	}
--	if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) {
-+
-+	if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) == ZMAGIC) {
- 		printk("N_TXTOFF != BLOCK_SIZE. See a.out.h.");
- 		return -ENOEXEC;
- 	}
-@@ -732,7 +743,10 @@
- 	flush_old_exec(bprm);
- 	current->start_brk = current->brk = ex.a_bss +
- 		(current->end_data = ex.a_data +
--		 (current->end_code = ex.a_text));
-+		 (current->end_code = N_TXTADDR(ex) + ex.a_text));
-+
-+	current->start_code += N_TXTADDR(ex);
-+
- 	current->rss = 0;
- 	current->suid = current->euid = bprm->e_uid;
- 	current->mmap = NULL;
-@@ -751,23 +765,25 @@
- 		file = current->filp[fd];
- 		if (!file->f_op || !file->f_op->mmap) {
- 			sys_close(fd);
--			read_exec(bprm->inode, 1024, (char *) 0, ex.a_text+ex.a_data);
-+			read_exec(bprm->inode, N_TXTOFF(ex), 
-+				  (char *) N_TXTADDR(ex), ex.a_text+ex.a_data);
- 			goto beyond_if;
- 		}
--		error = do_mmap(file, 0, ex.a_text,
-+		error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
- 				PROT_READ | PROT_EXEC,
- 				MAP_FIXED | MAP_SHARED, N_TXTOFF(ex));
--		if (error != 0) {
-+
-+		if (error != N_TXTADDR(ex)) {
- 			sys_close(fd);
- 			send_sig(SIGSEGV, current, 0);
- 			return 0;
- 		};
- 		
--		error = do_mmap(file, ex.a_text, ex.a_data,
-+ 		error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
- 				PROT_READ | PROT_WRITE | PROT_EXEC,
- 				MAP_FIXED | MAP_PRIVATE, N_TXTOFF(ex) + ex.a_text);
- 		sys_close(fd);
--		if (error != ex.a_text) {
-+		if (error != N_TXTADDR(ex) + ex.a_text) {
- 			send_sig(SIGSEGV, current, 0);
- 			return 0;
- 		};
-@@ -775,7 +791,7 @@
- 		bprm->inode->i_count++;
- 	}
- beyond_if:
--	zeromap_page_range((ex.a_text + ex.a_data + 0xfff) & 0xfffff000,ex.a_bss, PAGE_COPY);
-+	zeromap_page_range((N_TXTADDR(ex) + ex.a_text + ex.a_data + 0xfff) & 0xfffff000,ex.a_bss, PAGE_COPY);
- 	p += change_ldt(ex.a_text,bprm->page);
- 	p -= MAX_ARG_PAGES*PAGE_SIZE;
- 	p = (unsigned long) create_tables((char *)p,bprm->argc,bprm->envc);
-@@ -795,6 +811,7 @@
- 	struct  inode * inode;
- 	unsigned int len;
- 	unsigned int bss;
-+	unsigned int start_addr;
- 	int error;
- 	
- 	file = current->filp[fd];
-@@ -807,8 +824,8 @@
- 	set_fs(USER_DS);
- 	
- 	/* We come in here for the regular a.out style of shared libraries */
--	if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize ||
--	    ex.a_drsize || ex.a_entry & 0xfff ||
-+	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || ex.a_trsize ||
-+	    ex.a_drsize || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
- 	    inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
- 		return -ENOEXEC;
- 	}
-@@ -818,15 +835,22 @@
- 		return -ENOEXEC;
- 	}
- 	
-+	if (N_FLAGS(ex)) return -ENOEXEC;
-+
-+	/* For  QMAGIC, the starting address is 0x20 into the page.  We mask
-+	   this off to get the starting address for the page */
-+
-+	start_addr =  ex.a_entry & 0xfffff000;
-+
- 	/* Now use mmap to map the library into memory. */
--	error = do_mmap(file, ex.a_entry, ex.a_text + ex.a_data,
-+	error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
- 			PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
- 			N_TXTOFF(ex));
--	if (error != ex.a_entry)
-+	if (error != start_addr)
- 		return error;
- 	len = (ex.a_text + ex.a_data + 0xfff) & 0xfffff000;
- 	bss = ex.a_text + ex.a_data + ex.a_bss;
- 	if (bss > len)
--		zeromap_page_range(ex.a_entry + len, bss-len, PAGE_COPY);
-+		zeromap_page_range(start_addr + len, bss-len, PAGE_COPY);
- 	return 0;
- }
-diff -u --recursive --new-file pl12/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
---- pl12/linux/fs/ext2/namei.c	Thu Aug 12 20:54:00 1993
-+++ linux/fs/ext2/namei.c	Sat Aug 21 19:21:56 1993
-@@ -937,6 +937,8 @@
- 		new_inode->i_nlink--;
- 		new_inode->i_dirt = 1;
- 	}
-+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-+	old_dir->i_dirt = 1;
- 	old_bh->b_dirt = 1;
- 	new_bh->b_dirt = 1;
- 	if (dir_bh) {
-diff -u --recursive --new-file pl12/linux/fs/fcntl.c linux/fs/fcntl.c
---- pl12/linux/fs/fcntl.c	Wed Jul  7 10:39:21 1993
-+++ linux/fs/fcntl.c	Sat Sep  4 03:36:30 1993
-@@ -35,7 +35,7 @@
- 	return arg;
- }
- 
--extern "C" int sys_dup2(unsigned int oldfd, unsigned int newfd)
-+asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
- {
- 	if (oldfd >= NR_OPEN || !current->filp[oldfd])
- 		return -EBADF;
-@@ -58,12 +58,12 @@
- 	return dupfd(oldfd,newfd);
- }
- 
--extern "C" int sys_dup(unsigned int fildes)
-+asmlinkage int sys_dup(unsigned int fildes)
- {
- 	return dupfd(fildes,0);
- }
- 
--extern "C" int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
-+asmlinkage int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
- {	
- 	struct file * filp;
- 
-diff -u --recursive --new-file pl12/linux/fs/file_table.c linux/fs/file_table.c
---- pl12/linux/fs/file_table.c	Mon Aug  9 17:41:22 1993
-+++ linux/fs/file_table.c	Tue Aug 17 18:32:13 1993
-@@ -45,7 +45,7 @@
- 	struct file * file;
- 	int i;
- 
--	file = (struct file*) __get_free_page(GFP_BUFFER);
-+	file = (struct file *) get_free_page(GFP_KERNEL);
- 
- 	if (!file)
- 		return;
-diff -u --recursive --new-file pl12/linux/fs/inode.c linux/fs/inode.c
---- pl12/linux/fs/inode.c	Mon Aug  9 17:41:22 1993
-+++ linux/fs/inode.c	Tue Aug 17 18:41:05 1993
-@@ -87,7 +87,7 @@
- 	struct inode * inode;
- 	int i;
- 
--	if(!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
-+	if (!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
- 		return;
- 
- 	i=PAGE_SIZE / sizeof(struct inode);
-diff -u --recursive --new-file pl12/linux/fs/ioctl.c linux/fs/ioctl.c
---- pl12/linux/fs/ioctl.c	Sat Jul  3 01:07:31 1993
-+++ linux/fs/ioctl.c	Sat Sep  4 03:36:30 1993
-@@ -54,7 +54,7 @@
- }
- 
- 
--extern "C" int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-+asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
- {	
- 	struct file * filp;
- 	int on;
-diff -u --recursive --new-file pl12/linux/fs/namei.c linux/fs/namei.c
---- pl12/linux/fs/namei.c	Mon Aug  9 18:02:29 1993
-+++ linux/fs/namei.c	Sat Sep  4 03:36:30 1993
-@@ -266,7 +266,7 @@
-  *
-  * namei for open - this is in fact almost the whole open-routine.
-  *
-- * Note that the low bits of "flag" aren't the same asin the open
-+ * Note that the low bits of "flag" aren't the same as in the open
-  * system call - they are 00 - no permissions needed
-  *			  01 - read permission needed
-  *			  10 - write permission needed
-@@ -369,6 +369,8 @@
-  				return -ETXTBSY;
-  			}
- 			for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
-+				if (mpnt->vm_page_prot & PAGE_RW)
-+					continue;
- 				if (inode == mpnt->vm_inode) {
- 					iput(inode);
- 					return -ETXTBSY;
-@@ -376,6 +378,16 @@
- 			}
-  		}
-  	}
-+	if (flag & O_TRUNC) {
-+	      inode->i_size = 0;
-+	      if (inode->i_op && inode->i_op->truncate)
-+	           inode->i_op->truncate(inode);
-+	      if ((error = notify_change(NOTIFY_SIZE, inode))) {
-+		   iput(inode);
-+		   return error;
-+	      }
-+	      inode->i_dirt = 1;
-+	}
- 	*res_inode = inode;
- 	return 0;
- }
-@@ -409,7 +421,7 @@
- 	return dir->i_op->mknod(dir,basename,namelen,mode,dev);
- }
- 
--extern "C" int sys_mknod(const char * filename, int mode, dev_t dev)
-+asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev)
- {
- 	int error;
- 	char * tmp;
-@@ -452,7 +464,7 @@
- 	return dir->i_op->mkdir(dir,basename,namelen,mode);
- }
- 
--extern "C" int sys_mkdir(const char * pathname, int mode)
-+asmlinkage int sys_mkdir(const char * pathname, int mode)
- {
- 	int error;
- 	char * tmp;
-@@ -493,7 +505,7 @@
- 	return dir->i_op->rmdir(dir,basename,namelen);
- }
- 
--extern "C" int sys_rmdir(const char * pathname)
-+asmlinkage int sys_rmdir(const char * pathname)
- {
- 	int error;
- 	char * tmp;
-@@ -534,7 +546,7 @@
- 	return dir->i_op->unlink(dir,basename,namelen);
- }
- 
--extern "C" int sys_unlink(const char * pathname)
-+asmlinkage int sys_unlink(const char * pathname)
- {
- 	int error;
- 	char * tmp;
-@@ -575,7 +587,7 @@
- 	return dir->i_op->symlink(dir,basename,namelen,oldname);
- }
- 
--extern "C" int sys_symlink(const char * oldname, const char * newname)
-+asmlinkage int sys_symlink(const char * oldname, const char * newname)
- {
- 	int error;
- 	char * from, * to;
-@@ -631,7 +643,7 @@
- 	return dir->i_op->link(oldinode, dir, basename, namelen);
- }
- 
--extern "C" int sys_link(const char * oldname, const char * newname)
-+asmlinkage int sys_link(const char * oldname, const char * newname)
- {
- 	int error;
- 	char * to;
-@@ -703,7 +715,7 @@
- 		new_dir, new_base, new_len);
- }
- 
--extern "C" int sys_rename(const char * oldname, const char * newname)
-+asmlinkage int sys_rename(const char * oldname, const char * newname)
- {
- 	int error;
- 	char * from, * to;
-diff -u --recursive --new-file pl12/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c
---- pl12/linux/fs/nfs/mmap.c	Sun Aug 15 11:46:03 1993
-+++ linux/fs/nfs/mmap.c	Sat Aug 21 10:31:31 1993
-@@ -50,11 +50,9 @@
- {
- 	struct vm_area_struct * mpnt;
- 
--	if (off & (inode->i_sb->s_blocksize - 1))
-+	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported now */
- 		return -EINVAL;
--	if (len > high_memory || off > high_memory - len) /* avoid overflow */
--		return -ENXIO;
--	if (get_limit(USER_DS) != TASK_SIZE)
-+	if (off & (inode->i_sb->s_blocksize - 1))
- 		return -EINVAL;
- 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
- 		return -EACCES;
-@@ -79,10 +77,6 @@
- 	mpnt->vm_ops = &nfs_file_mmap;
- 	mpnt->vm_next = current->mmap;
- 	current->mmap = mpnt;
--#if 0
--	printk("VFS: Loaded mmap at %08x - %08x\n",
--		mpnt->vm_start,	mpnt->vm_end);
--#endif
- 	return 0;
- }
- 
-diff -u --recursive --new-file pl12/linux/fs/open.c linux/fs/open.c
---- pl12/linux/fs/open.c	Mon Aug  9 18:02:29 1993
-+++ linux/fs/open.c	Sat Sep  4 03:35:17 1993
-@@ -21,12 +21,12 @@
- 
- extern void fcntl_remove_locks(struct task_struct *, struct file *);
- 
--extern "C" int sys_ustat(int dev, struct ustat * ubuf)
-+asmlinkage int sys_ustat(int dev, struct ustat * ubuf)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_statfs(const char * path, struct statfs * buf)
-+asmlinkage int sys_statfs(const char * path, struct statfs * buf)
- {
- 	struct inode * inode;
- 	int error;
-@@ -46,7 +46,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_fstatfs(unsigned int fd, struct statfs * buf)
-+asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
- {
- 	struct inode * inode;
- 	struct file * file;
-@@ -65,7 +65,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_truncate(const char * path, unsigned int length)
-+asmlinkage int sys_truncate(const char * path, unsigned int length)
- {
- 	struct inode * inode;
- 	int error;
-@@ -91,7 +91,7 @@
- 	return error;
- }
- 
--extern "C" int sys_ftruncate(unsigned int fd, unsigned int length)
-+asmlinkage int sys_ftruncate(unsigned int fd, unsigned int length)
- {
- 	struct inode * inode;
- 	struct file * file;
-@@ -114,7 +114,7 @@
-  * must be owner or have write permission.
-  * Else, update from *times, must be owner or super user.
-  */
--extern "C" int sys_utime(char * filename, struct utimbuf * times)
-+asmlinkage int sys_utime(char * filename, struct utimbuf * times)
- {
- 	struct inode * inode;
- 	long actime,modtime;
-@@ -155,7 +155,7 @@
-  * XXX we should use the real ids for checking _all_ components of the
-  * path.  Now we only use them for the final component of the path.
-  */
--extern "C" int sys_access(const char * filename,int mode)
-+asmlinkage int sys_access(const char * filename,int mode)
- {
- 	struct inode * inode;
- 	int res, i_mode;
-@@ -189,7 +189,7 @@
- 	return -EACCES;
- }
- 
--extern "C" int sys_chdir(const char * filename)
-+asmlinkage int sys_chdir(const char * filename)
- {
- 	struct inode * inode;
- 	int error;
-@@ -210,7 +210,7 @@
- 	return (0);
- }
- 
--extern "C" int sys_chroot(const char * filename)
-+asmlinkage int sys_chroot(const char * filename)
- {
- 	struct inode * inode;
- 	int error;
-@@ -231,7 +231,7 @@
- 	return (0);
- }
- 
--extern "C" int sys_fchmod(unsigned int fd, mode_t mode)
-+asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
- {
- 	struct inode * inode;
- 	struct file * file;
-@@ -252,7 +252,7 @@
- 	return notify_change(NOTIFY_MODE, inode);
- }
- 
--extern "C" int sys_chmod(const char * filename, mode_t mode)
-+asmlinkage int sys_chmod(const char * filename, mode_t mode)
- {
- 	struct inode * inode;
- 	int error;
-@@ -278,7 +278,7 @@
- 	return error;
- }
- 
--extern "C" int sys_fchown(unsigned int fd, uid_t user, gid_t group)
-+asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
- {
- 	struct inode * inode;
- 	struct file * file;
-@@ -305,7 +305,7 @@
- 	return -EPERM;
- }
- 
--extern "C" int sys_chown(const char * filename, uid_t user, gid_t group)
-+asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
- {
- 	struct inode * inode;
- 	int error;
-@@ -378,18 +378,7 @@
- 		f->f_count--;
- 		return error;
- 	}
--	if (flag & O_TRUNC) {
--		inode->i_size = 0;
--		if (inode->i_op && inode->i_op->truncate)
--			inode->i_op->truncate(inode);
--		if ((error = notify_change(NOTIFY_SIZE, inode))) {
--			iput(inode);
--			current->filp[fd] = NULL;
--			f->f_count--;
--			return error;
--		}
--		inode->i_dirt = 1;
--	}
-+
- 	f->f_inode = inode;
- 	f->f_pos = 0;
- 	f->f_reada = 0;
-@@ -409,7 +398,7 @@
- 	return (fd);
- }
- 
--extern "C" int sys_open(const char * filename,int flags,int mode)
-+asmlinkage int sys_open(const char * filename,int flags,int mode)
- {
- 	char * tmp;
- 	int error;
-@@ -422,7 +411,7 @@
- 	return error;
- }
- 
--extern "C" int sys_creat(const char * pathname, int mode)
-+asmlinkage int sys_creat(const char * pathname, int mode)
- {
- 	return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
- }
-@@ -450,7 +439,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_close(unsigned int fd)
-+asmlinkage int sys_close(unsigned int fd)
- {	
- 	struct file * filp;
- 
-@@ -467,7 +456,7 @@
-  * This routine simulates a hangup on the tty, to arrange that users
-  * are given clean terminals at login time.
-  */
--extern "C" int sys_vhangup(void)
-+asmlinkage int sys_vhangup(void)
- {
- 	struct tty_struct *tty;
- 
-diff -u --recursive --new-file pl12/linux/fs/pipe.c linux/fs/pipe.c
---- pl12/linux/fs/pipe.c	Sun Jul 18 18:19:42 1993
-+++ linux/fs/pipe.c	Sat Sep  4 03:36:30 1993
-@@ -288,7 +288,7 @@
- 	NULL			/* permission */
- };
- 
--extern "C" int sys_pipe(unsigned long * fildes)
-+asmlinkage int sys_pipe(unsigned long * fildes)
- {
- 	struct inode * inode;
- 	struct file * f[2];
-diff -u --recursive --new-file pl12/linux/fs/proc/array.c linux/fs/proc/array.c
---- pl12/linux/fs/proc/array.c	Mon Aug  9 18:02:29 1993
-+++ linux/fs/proc/array.c	Fri Aug 20 09:40:57 1993
-@@ -194,7 +194,7 @@
- 	if (vsize) {
- 		eip = KSTK_EIP(vsize);
- 		esp = KSTK_ESP(vsize);
--		vsize = (*p)->brk + PAGE_SIZE-1;
-+		vsize = (*p)->brk - (*p)->start_code + PAGE_SIZE-1;
- 		if (esp)
- 			vsize += TASK_SIZE - esp;
- 	}
-@@ -264,7 +264,7 @@
- 		return 0;
- 	tpag = (*p)->end_code / PAGE_SIZE;
- 	if ((*p)->state != TASK_ZOMBIE) {
--	  pagedir = PAGE_DIR_OFFSET((*p)->tss.cr3,(*p)->start_code);
-+	  pagedir = (unsigned long *) (*p)->tss.cr3;
- 	  for (i = 0; i < 0x300; ++i) {
- 	    if ((ptbl = pagedir[i]) == 0) {
- 	      tpag -= PTRS_PER_PAGE;
-diff -u --recursive --new-file pl12/linux/fs/proc/kmsg.c linux/fs/proc/kmsg.c
---- pl12/linux/fs/proc/kmsg.c	Sat Jul  3 01:31:56 1993
-+++ linux/fs/proc/kmsg.c	Sat Sep  4 03:39:22 1993
-@@ -17,7 +17,7 @@
- extern unsigned long log_size;
- extern struct wait_queue * log_wait;
- 
--extern "C" int sys_syslog(int type, char * bug, int count);
-+asmlinkage int sys_syslog(int type, char * bug, int count);
- 
- static int kmsg_open(struct inode * inode, struct file * file)
- {
-diff -u --recursive --new-file pl12/linux/fs/read_write.c linux/fs/read_write.c
---- pl12/linux/fs/read_write.c	Sat Jul  3 01:05:39 1993
-+++ linux/fs/read_write.c	Sat Sep  4 03:36:30 1993
-@@ -16,7 +16,7 @@
-  * Count is not yet used: but we'll probably support reading several entries
-  * at once in the future. Use count=1 in the library for future expansions.
-  */
--extern "C" int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
-+asmlinkage int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
- {
- 	int error;
- 	struct file * file;
-@@ -34,7 +34,7 @@
- 	return error;
- }
- 
--extern "C" int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
-+asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
- {
- 	struct file * file;
- 	int tmp = -1;
-@@ -67,7 +67,7 @@
- 	return file->f_pos;
- }
- 
--extern "C" int sys_read(unsigned int fd,char * buf,unsigned int count)
-+asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
- {
- 	int error;
- 	struct file * file;
-@@ -87,7 +87,7 @@
- 	return file->f_op->read(inode,file,buf,count);
- }
- 
--extern "C" int sys_write(unsigned int fd,char * buf,unsigned int count)
-+asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
- {
- 	int error;
- 	struct file * file;
-diff -u --recursive --new-file pl12/linux/fs/select.c linux/fs/select.c
---- pl12/linux/fs/select.c	Mon Aug  9 18:02:30 1993
-+++ linux/fs/select.c	Sat Sep  4 03:36:30 1993
-@@ -192,7 +192,7 @@
-  * Update: ERESTARTSYS breaks at least the xview clock binary, so
-  * I'm trying ERESTARTNOHAND which restart only when you want to.
-  */
--extern "C" int sys_select( unsigned long *buffer )
-+asmlinkage int sys_select( unsigned long *buffer )
- {
- /* Perform the select(nd, in, out, ex, tv) system call. */
- 	int i;
-diff -u --recursive --new-file pl12/linux/fs/stat.c linux/fs/stat.c
---- pl12/linux/fs/stat.c	Sat Jul  3 01:04:26 1993
-+++ linux/fs/stat.c	Sat Sep  4 03:36:30 1993
-@@ -86,7 +86,7 @@
- 	memcpy_tofs(statbuf,&tmp,sizeof(tmp));
- }
- 
--extern "C" int sys_stat(char * filename, struct old_stat * statbuf)
-+asmlinkage int sys_stat(char * filename, struct old_stat * statbuf)
- {
- 	struct inode * inode;
- 	int error;
-@@ -102,7 +102,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_newstat(char * filename, struct new_stat * statbuf)
-+asmlinkage int sys_newstat(char * filename, struct new_stat * statbuf)
- {
- 	struct inode * inode;
- 	int error;
-@@ -118,7 +118,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_lstat(char * filename, struct old_stat * statbuf)
-+asmlinkage int sys_lstat(char * filename, struct old_stat * statbuf)
- {
- 	struct inode * inode;
- 	int error;
-@@ -134,7 +134,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_newlstat(char * filename, struct new_stat * statbuf)
-+asmlinkage int sys_newlstat(char * filename, struct new_stat * statbuf)
- {
- 	struct inode * inode;
- 	int error;
-@@ -150,7 +150,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_fstat(unsigned int fd, struct old_stat * statbuf)
-+asmlinkage int sys_fstat(unsigned int fd, struct old_stat * statbuf)
- {
- 	struct file * f;
- 	struct inode * inode;
-@@ -165,7 +165,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
-+asmlinkage int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
- {
- 	struct file * f;
- 	struct inode * inode;
-@@ -180,7 +180,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_readlink(const char * path, char * buf, int bufsiz)
-+asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
- {
- 	struct inode * inode;
- 	int error;
-diff -u --recursive --new-file pl12/linux/fs/super.c linux/fs/super.c
---- pl12/linux/fs/super.c	Wed Aug 11 20:56:05 1993
-+++ linux/fs/super.c	Sat Sep  4 03:36:30 1993
-@@ -243,7 +243,7 @@
-  * functions, they should be faked here.  -- jrs
-  */
- 
--extern "C" int sys_umount(char * name)
-+asmlinkage int sys_umount(char * name)
- {
- 	struct inode * inode;
- 	dev_t dev;
-@@ -390,7 +390,7 @@
-  * isn't present, the flags and data info isn't used, as the syscall assumes we
-  * are talking to an older version that didn't understand them.
-  */
--extern "C" int sys_mount(char * dev_name, char * dir_name, char * type,
-+asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
- 	unsigned long new_flags, void * data)
- {
- 	struct file_system_type * fstype;
-diff -u --recursive --new-file pl12/linux/ibcs/emulate.c linux/ibcs/emulate.c
---- pl12/linux/ibcs/emulate.c	Sat Jul  3 00:36:31 1993
-+++ linux/ibcs/emulate.c	Sat Sep  4 14:29:34 1993
-@@ -20,7 +20,7 @@
- #include <asm/segment.h>
- #include <asm/system.h>
- 
--extern "C" void iABI_emulate(struct pt_regs * regs)
-+asmlinkage void iABI_emulate(struct pt_regs * regs)
- {
- 	printk("lcall 7,xxx: eax = %08x\n",regs->eax);
- }
-diff -u --recursive --new-file pl12/linux/include/asm/irq.h linux/include/asm/irq.h
---- pl12/linux/include/asm/irq.h	Sun Jul 18 17:19:24 1993
-+++ linux/include/asm/irq.h	Sat Sep  4 03:00:24 1993
-@@ -8,6 +8,8 @@
-  */
- 
- #include <linux/segment.h>
-+#include <linux/linkage.h>
-+
- #define __STR(x) #x
- #define STR(x) __STR(x)
-  
-@@ -117,9 +119,9 @@
- #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
- 	
- #define BUILD_IRQ(chip,nr,mask) \
--extern "C" void IRQ_NAME(nr); \
--extern "C" void FAST_IRQ_NAME(nr); \
--extern "C" void BAD_IRQ_NAME(nr); \
-+asmlinkage void IRQ_NAME(nr); \
-+asmlinkage void FAST_IRQ_NAME(nr); \
-+asmlinkage void BAD_IRQ_NAME(nr); \
- __asm__( \
- "\n.align 4\n" \
- "_IRQ" #nr "_interrupt:\n\t" \
-diff -u --recursive --new-file pl12/linux/include/asm/segment.h linux/include/asm/segment.h
---- pl12/linux/include/asm/segment.h	Mon Aug  2 14:31:28 1993
-+++ linux/include/asm/segment.h	Sat Sep  4 03:02:56 1993
-@@ -1,7 +1,7 @@
- #ifndef _ASM_SEGMENT_H
- #define _ASM_SEGMENT_H
- 
--static inline unsigned char get_fs_byte(const char * addr)
-+static inline unsigned char get_user_byte(const char * addr)
- {
- 	register unsigned char _v;
- 
-@@ -9,23 +9,9 @@
- 	return _v;
- }
- 
--static inline unsigned char get_fs_byte(const unsigned char * addr)
--{
--	register unsigned char _v;
--
--	__asm__ ("movb %%fs:%1,%0":"=q" (_v):"m" (*addr));
--	return _v;
--}
--
--static inline unsigned short get_fs_word(const short *addr)
--{
--	unsigned short _v;
--
--	__asm__ ("movw %%fs:%1,%0":"=r" (_v):"m" (*addr));
--	return _v;
--}
-+#define get_fs_byte(addr) get_user_byte((char *)(addr))
- 
--static inline unsigned short get_fs_word(const unsigned short *addr)
-+static inline unsigned short get_user_word(const short *addr)
- {
- 	unsigned short _v;
- 
-@@ -33,31 +19,9 @@
- 	return _v;
- }
- 
--static inline unsigned long get_fs_long(const int *addr)
--{
--	unsigned long _v;
--
--	__asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
--	return _v;
--}
--
--static inline unsigned long get_fs_long(const unsigned int *addr)
--{
--	unsigned long _v;
--
--	__asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
--	return _v;
--}
--
--static inline unsigned long get_fs_long(const long *addr)
--{
--	unsigned long _v;
--
--	__asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
--	return _v;
--}
-+#define get_fs_word(addr) get_user_word((short *)(addr))
- 
--static inline unsigned long get_fs_long(const unsigned long *addr)
-+static inline unsigned long get_user_long(const int *addr)
- {
- 	unsigned long _v;
- 
-@@ -65,45 +29,28 @@
- 	return _v;
- }
- 
--static inline void put_fs_byte(char val,char *addr)
--{
--__asm__ ("movb %0,%%fs:%1": /* no outputs */ :"iq" (val),"m" (*addr));
--}
-+#define get_fs_long(addr) get_user_long((int *)(addr))
- 
--static inline void put_fs_byte(char val,unsigned char *addr)
-+static inline void put_user_byte(char val,char *addr)
- {
- __asm__ ("movb %0,%%fs:%1": /* no outputs */ :"iq" (val),"m" (*addr));
- }
- 
--static inline void put_fs_word(short val,short * addr)
--{
--__asm__ ("movw %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
--}
-+#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
- 
--static inline void put_fs_word(short val,unsigned short * addr)
-+static inline void put_user_word(short val,short * addr)
- {
- __asm__ ("movw %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
- }
- 
--static inline void put_fs_long(unsigned long val,int * addr)
--{
--__asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
--}
--
--static inline void put_fs_long(unsigned long val,unsigned int * addr)
--{
--__asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
--}
-+#define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
- 
--static inline void put_fs_long(unsigned long val,long * addr)
-+static inline void put_user_long(unsigned long val,int * addr)
- {
- __asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
- }
- 
--static inline void put_fs_long(unsigned long val,unsigned long * addr)
--{
--__asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
--}
-+#define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
- 
- static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
- {
-diff -u --recursive --new-file pl12/linux/include/linux/a.out.h linux/include/linux/a.out.h
---- pl12/linux/include/linux/a.out.h	Mon Aug  9 17:41:23 1993
-+++ linux/include/linux/a.out.h	Fri Aug 20 08:59:31 1993
-@@ -71,24 +71,26 @@
- #define NMAGIC 0410
- /* Code indicating demand-paged executable.  */
- #define ZMAGIC 0413
-+/* This indicates a demand-paged executable with the header in the text. 
-+   The first page is unmapped to help trap NULL pointer references */
-+#define QMAGIC 0314
- 
- /* Code indicating core file.  */
- #define CMAGIC 0421
-+
- #if !defined (N_BADMAG)
--#define N_BADMAG(x)					\
-- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC		\
--  && N_MAGIC(x) != ZMAGIC)
-+#define N_BADMAG(x)	  (N_MAGIC(x) != OMAGIC		\
-+			&& N_MAGIC(x) != NMAGIC		\
-+  			&& N_MAGIC(x) != ZMAGIC \
-+		        && N_MAGIC(x) != QMAGIC)
- #endif
- 
--#define _N_BADMAG(x)					\
-- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC		\
--  && N_MAGIC(x) != ZMAGIC)
--
- #define _N_HDROFF(x) (1024 - sizeof (struct exec))
- 
- #if !defined (N_TXTOFF)
- #define N_TXTOFF(x) \
-- (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))
-+ (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
-+  (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
- #endif
- 
- #if !defined (N_DATOFF)
-@@ -113,7 +115,7 @@
- 
- /* Address of text segment in memory after it is loaded.  */
- #if !defined (N_TXTADDR)
--#define N_TXTADDR(x) 0
-+#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
- #endif
- 
- /* Address of data segment in memory after it is loaded.
-diff -u --recursive --new-file pl12/linux/include/linux/binfmts.h linux/include/linux/binfmts.h
---- pl12/linux/include/linux/binfmts.h	Fri Aug  6 13:32:00 1993
-+++ linux/include/linux/binfmts.h	Sat Sep  4 03:39:51 1993
-@@ -1,6 +1,8 @@
- #ifndef _LINUX_BINFMTS_H
- #define _LINUX_BINFMTS_H
- 
-+#include <linux/ptrace.h>
-+
- /*
-  * MAX_ARG_PAGES defines the number of pages allocated for arguments
-  * and envelope for the new program. 32 should suffice, this gives
-@@ -15,6 +17,7 @@
-   char buf[128];
-   unsigned long page[MAX_ARG_PAGES];
-   unsigned long p;
-+  int sh_bang;
-   struct inode * inode;
-   int e_uid, e_gid;
-   int argc, envc;
-@@ -31,6 +34,15 @@
- 
- extern struct linux_binfmt formats[];
- 
-+extern int read_exec(struct inode *inode, unsigned long offset,
-+	char * addr, unsigned long count);
-+
-+extern int open_inode(struct inode * inode, int mode);
- 
-+extern void flush_old_exec(struct linux_binprm * bprm);
-+extern unsigned long change_ldt(unsigned long text_size,unsigned long * page);
-+extern unsigned long * create_tables(char * p,int argc,int envc);
-+extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
-+		unsigned long p, int from_kmem);
- 
- #endif
-diff -u --recursive --new-file pl12/linux/include/linux/elf.h linux/include/linux/elf.h
---- pl12/linux/include/linux/elf.h
-+++ linux/include/linux/elf.h	Sat Sep  4 01:48:20 1993
-@@ -0,0 +1,153 @@
-+#ifndef _ELF_H
-+#define _ELF_H
-+
-+/* THese constants are for the segment types stored in the image headers */
-+#define PT_NULL    0
-+#define PT_LOAD    1
-+#define PT_DYNAMIC 2
-+#define PT_INTERP  3
-+#define PT_NOTE    4
-+#define PT_SHLIB   5
-+#define PT_PHDR    6
-+#define PT_LOPROC  0x70000000
-+#define PT_HIPROC  0x7fffffff
-+
-+/* These constants define the different elf file types */
-+#define ET_NONE   0
-+#define ET_REL    1
-+#define ET_EXEC   2
-+#define ET_DYN    3
-+#define ET_CORE   4
-+#define ET_LOPROC 5
-+#define ET_HIPROC 6
-+
-+/* These constants define the various ELF target machines */
-+#define EM_NONE  0
-+#define EM_M32   1
-+#define EM_SPARC 2
-+#define EM_386   3
-+#define EM_68K   4
-+#define EM_88K   5
-+#define EM_486   6   /* Perhaps disused */
-+#define EM_860   7
-+
-+/* This is the info that is needed to parse the dynamic section of the file */
-+#define DT_NULL		0
-+#define DT_NEEDED	1
-+#define DT_PLTRELSZ	2
-+#define DT_PLTGOT	3
-+#define DT_HASH		4
-+#define DT_STRTAB	5
-+#define DT_SYMTAB	6
-+#define DT_RELA		7
-+#define DT_RELASZ	8
-+#define DT_RELAENT	9
-+#define DT_STRSZ	10
-+#define DT_SYMENT	11
-+#define DT_INIT		12
-+#define DT_FINI		13
-+#define DT_SONAME	14
-+#define DT_RPATH 	15
-+#define DT_SYMBOLIC	16
-+#define DT_REL	        17
-+#define DT_RELSZ	18
-+#define DT_RELENT	19
-+#define DT_PLTREL	20
-+#define DT_DEBUG	21
-+#define DT_TEXTREL	22
-+#define DT_JMPREL	23
-+#define DT_LOPROC	0x70000000
-+#define DT_HIPROC	0x7fffffff
-+
-+/* This info is needed when parsing the symbol table */
-+#define STB_LOCAL  0
-+#define STB_GLOBAL 1
-+#define STB_WEAK   2
-+
-+#define STT_NOTYPE  0
-+#define STT_OBJECT  1
-+#define STT_FUNC    2
-+#define STT_SECTION 3
-+#define STT_FILE    4
-+
-+#define ELF32_ST_BIND(x) ((x) >> 4)
-+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
-+
-+
-+
-+struct dynamic{
-+  int d_tag;
-+  union{
-+    int d_val;
-+    char * d_ptr;
-+  } d_un;
-+};
-+
-+/* THe following are used with relocations */
-+#define ELF32_R_SYM(x) ((x) >> 8)
-+#define ELF32_R_TYPE(x) ((x) & 0xff)
-+
-+#define R_386_NONE	0
-+#define R_386_32	1
-+#define R_386_PC32	2
-+#define R_386_GOT32	3
-+#define R_386_PLT32	4
-+#define R_386_COPY	5
-+#define R_386_GLOB_DAT	6
-+#define R_386_JMP_SLOT	7
-+#define R_386_RELATIVE	8
-+#define R_386_GOTOFF	9
-+#define R_386_GOTPC	10
-+#define R_386_NUM	11
-+
-+struct Elf32_Rel{
-+  unsigned int * offset;
-+  int info;
-+};
-+
-+struct Elf32_Rela{
-+  unsigned int * offset;
-+  int info;
-+  int addend;
-+};
-+
-+struct Elf32_Sym{
-+  int st_name;
-+  unsigned int st_value;
-+  int st_size;
-+  unsigned char st_info;
-+  unsigned char st_other;
-+  short int st_shndx;
-+};
-+
-+struct elfhdr{
-+  char	e_ident[16];
-+  short int e_type;
-+  short int e_machine;
-+  int   e_version;
-+  char *e_entry;  /* Entry point */
-+  int   e_phoff;
-+  int   e_shoff;
-+  int   e_flags;
-+  short int e_ehsize;
-+  short int e_phentsize;
-+  short int e_phnum;
-+  short int e_shentsize;
-+  short int e_shnum;
-+  short int e_shstrndx;
-+};
-+
-+struct elf_phdr{
-+  int p_type;
-+  int p_offset;
-+  int p_vaddr;
-+  int p_paddr;
-+  int p_filesz;
-+  int p_memsz;
-+  int p_flags;
-+  int p_align;
-+};
-+
-+#define ELF_START_MMAP 0x80000000
-+
-+#endif
-diff -u --recursive --new-file pl12/linux/include/linux/fs.h linux/include/linux/fs.h
---- pl12/linux/include/linux/fs.h	Wed Aug 11 22:52:45 1993
-+++ linux/include/linux/fs.h	Sat Sep  4 02:55:18 1993
-@@ -6,6 +6,7 @@
-  * structures etc.
-  */
- 
-+#include <linux/linkage.h>
- #include <linux/limits.h>
- #include <linux/wait.h>
- #include <linux/types.h>
-@@ -319,8 +320,8 @@
- 
- #ifdef __KERNEL__
- 
--extern "C" int sys_open(const char *, int, int);
--extern "C" int sys_close(unsigned int);		/* yes, it's really unsigned */
-+asmlinkage int sys_open(const char *, int, int);
-+asmlinkage int sys_close(unsigned int);		/* yes, it's really unsigned */
- 
- extern int getname(const char * filename, char **result);
- extern void putname(char * name);
-diff -u --recursive --new-file pl12/linux/include/linux/ioport.h linux/include/linux/ioport.h
---- pl12/linux/include/linux/ioport.h
-+++ linux/include/linux/ioport.h	Wed Sep  1 17:39:36 1993
-@@ -0,0 +1,28 @@
-+/*
-+ * portio.h	Definitions of routines for detecting, reserving and
-+ *		allocating system resources.
-+ *
-+ * Version:	0.01	8/30/93
-+ *
-+ * Author:	Donald Becker (becker@super.org)
-+ */
-+
-+#ifndef _LINUX_PORTIO_H
-+#define _LINUX_PORTIO_H
-+
-+#define HAVE_PORTRESERVE
-+/*
-+ * Call check_region() before probing for your hardware.
-+ * Once you have found you hardware, register it with snarf_region().
-+ */
-+extern void reserve_setup(char *str, int *ints);
-+extern int check_region(unsigned int from, unsigned int extent);
-+extern void snarf_region(unsigned int from, unsigned int extent);
-+
-+
-+#define HAVE_AUTOIRQ
-+extern void *irq2dev_map[16];		/* Use only if you own the IRQ. */
-+extern void autoirq_setup(int waittime);
-+extern int autoirq_report(int waittime);
-+
-+#endif	/* _LINUX_PORTIO_H */
-diff -u --recursive --new-file pl12/linux/include/linux/kernel.h linux/include/linux/kernel.h
---- pl12/linux/include/linux/kernel.h	Mon Aug  9 18:02:30 1993
-+++ linux/include/linux/kernel.h	Sat Sep  4 02:56:46 1993
-@@ -8,6 +8,7 @@
- #ifdef __KERNEL__
- 
- #include <linux/config.h>
-+#include <linux/linkage.h>
- 
- #define INT_MAX		((int)(~0U>>1))
- #define UINT_MAX	(~0U)
-@@ -25,7 +26,7 @@
- unsigned long simple_strtoul(const char *,char **,unsigned int);
- int sprintf(char * buf, const char * fmt, ...);
- 
--extern "C" int printk(const char * fmt, ...);
-+asmlinkage int printk(const char * fmt, ...);
- 
- #ifdef CONFIG_DEBUG_MALLOC
- #define kmalloc(a,b) deb_kmalloc(__FILE__,__LINE__, a,b)
-diff -u --recursive --new-file pl12/linux/include/linux/linkage.h linux/include/linux/linkage.h
---- pl12/linux/include/linux/linkage.h
-+++ linux/include/linux/linkage.h	Sat Sep  4 02:56:10 1993
-@@ -0,0 +1,10 @@
-+#ifndef _LINUX_LINKAGE_H
-+#define _LINUX_LINKAGE_H
-+
-+#ifdef __cplusplus
-+#define asmlinkage extern "C"
-+#else
-+#define asmlinkage
-+#endif
-+
-+#endif
-diff -u --recursive --new-file pl12/linux/include/linux/page.h linux/include/linux/page.h
---- pl12/linux/include/linux/page.h	Mon Aug  9 18:02:30 1993
-+++ linux/include/linux/page.h	Sat Sep  4 03:09:00 1993
-@@ -25,7 +25,7 @@
-   ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)*2&PTR_MASK&~PAGE_MASK)))
- 			/* to find an entry in a page-table */
- #define PAGE_PTR(address)		\
--  ((unsigned long)(address)>>PAGE_SHIFT-SIZEOF_PTR_LOG2&PTR_MASK&~PAGE_MASK)
-+  ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
- 			/* the no. of pointers that fit on a page */
- #define PTRS_PER_PAGE			(PAGE_SIZE/sizeof(void*))
- 
-diff -u --recursive --new-file pl12/linux/include/linux/sched.h linux/include/linux/sched.h
---- pl12/linux/include/linux/sched.h	Sat Aug 14 16:01:26 1993
-+++ linux/include/linux/sched.h	Sat Sep  4 02:42:39 1993
-@@ -85,7 +85,7 @@
- extern void trap_init(void);
- extern void panic(const char * str);
- 
--extern "C" void schedule(void);
-+asmlinkage void schedule(void);
- 
- #endif /* __KERNEL__ */
- 
-diff -u --recursive --new-file pl12/linux/include/linux/shm.h linux/include/linux/shm.h
---- pl12/linux/include/linux/shm.h	Mon Aug  9 18:02:30 1993
-+++ linux/include/linux/shm.h	Sun Aug 29 23:26:57 1993
-@@ -63,11 +63,11 @@
- #define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
- #define SHM_READ_ONLY	(1<<BITS_PER_PTR-1)
- 
--#define SHMMAX (1<<PAGE_SHIFT+_SHM_IDX_BITS)	/* max shared seg size (bytes) */
--#define SHMMIN 1	 /* really PAGE_SIZE */	/* min shared seg size (bytes)*/
-+#define SHMMAX 0x400000				/* max shared seg size (bytes) */
-+#define SHMMIN 1	 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
- #define SHMMNI (1<<_SHM_ID_BITS)		/* max num of segs system wide */
- #define SHMALL (1<<_SHM_IDX_BITS+_SHM_ID_BITS)	/* max shm system wide (pages) */
--#define	SHMLBA PAGE_SIZE			/* attach addr a multiple of this */
-+#define	SHMLBA 0x1000				/* attach addr a multiple of this */
- #define SHMSEG SHMMNI				/* max shared segs per process */
- 
- #ifdef __KERNEL__
-diff -u --recursive --new-file pl12/linux/include/linux/signal.h linux/include/linux/signal.h
---- pl12/linux/include/linux/signal.h	Thu May 20 10:34:30 1993
-+++ linux/include/linux/signal.h	Mon Aug 16 18:55:12 1993
-@@ -53,6 +53,9 @@
- */
- #define SIGPWR		30
- 
-+/* Arggh. Bad user source code wants this.. */
-+#define SIGBUS		SIGUNUSED
-+
- /*
-  * sa_flags values: SA_STACK is not currently supported, but will allow the
-  * usage of signal stacks by using the (now obsolete) sa_restorer field in
-diff -u --recursive --new-file pl12/linux/include/linux/sys.h linux/include/linux/sys.h
---- pl12/linux/include/linux/sys.h	Tue Jul 20 01:35:31 1993
-+++ linux/include/linux/sys.h	Sat Sep  4 02:43:53 1993
-@@ -4,7 +4,9 @@
- 
- #define sys_clone sys_fork
- 
-+#ifdef __cplusplus
- extern "C" {
-+#endif
- 
- extern int sys_setup();
- extern int sys_exit();
-@@ -170,7 +172,9 @@
- sys_wait4, sys_swapoff, sys_sysinfo, sys_ipc, sys_fsync, sys_sigreturn,
- sys_clone, sys_setdomainname, sys_newuname, sys_modify_ldt};
- 
-+#ifdef __cplusplus
- }
-+#endif
- 
- /* So we don't have to do any more manual updating.... */
- int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
-diff -u --recursive --new-file pl12/linux/include/linux/tasks.h linux/include/linux/tasks.h
---- pl12/linux/include/linux/tasks.h	Mon Jan 18 22:06:34 1993
-+++ linux/include/linux/tasks.h	Wed Aug 18 23:05:21 1993
-@@ -4,6 +4,6 @@
- /*
-  * This is the maximum nr of tasks - change it if you need to
-  */
--#define NR_TASKS	64
-+#define NR_TASKS	128
- 
- #endif
-diff -u --recursive --new-file pl12/linux/include/linux/timer.h linux/include/linux/timer.h
---- pl12/linux/include/linux/timer.h	Sat Aug 14 23:47:22 1993
-+++ linux/include/linux/timer.h	Tue Aug 17 18:39:34 1993
-@@ -17,6 +17,8 @@
-  * 
-  * HD_TIMER		harddisk timer
-  *
-+ * HD_TIMER2		(atdisk2 patches)
-+ *
-  * FLOPPY_TIMER		floppy disk timer (not used right now)
-  * 
-  * SCSI_TIMER		scsi.c timeout timer
-@@ -43,6 +45,8 @@
- 
- #define TAPE_QIC02_TIMER	22	/* hhb */
- #define MCD_TIMER	23
-+
-+#define HD_TIMER2	24
- 
- struct timer_struct {
- 	unsigned long expires;
-diff -u --recursive --new-file pl12/linux/init/main.c linux/init/main.c
---- pl12/linux/init/main.c	Mon Aug  9 18:02:31 1993
-+++ linux/init/main.c	Sat Sep  4 02:58:36 1993
-@@ -23,12 +23,13 @@
- #include <linux/ctype.h>
- #include <linux/delay.h>
- #include <linux/utsname.h>
-+#include <linux/ioport.h>
- 
- extern unsigned long * prof_buffer;
- extern unsigned long prof_len;
- extern char edata, end;
- extern char *linux_banner;
--extern "C" void lcall7(void);
-+asmlinkage void lcall7(void);
- struct desc_struct default_ldt;
- 
- /*
-@@ -43,6 +44,7 @@
-  * won't be any messing with the stack from main(), but we define
-  * some others too.
-  */
-+#define __NR__exit __NR_exit
- static inline _syscall0(int,idle)
- static inline _syscall0(int,fork)
- static inline _syscall0(int,pause)
-@@ -54,7 +56,7 @@
- static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
- static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
- static inline _syscall1(int,close,int,fd)
--static inline _syscall1(int,exit,int,exitcode)
-+static inline _syscall1(int,_exit,int,exitcode)
- static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
- 
- static inline pid_t wait(int * wait_stat)
-@@ -189,6 +191,7 @@
- 	char *str;
- 	void (*setup_func)(char *, int *);
- } bootsetups[] = {
-+	{ "reserve=", reserve_setup },
- #ifdef CONFIG_INET
- 	{ "ether=", eth_setup },
- #endif
-@@ -329,7 +332,7 @@
- 	outb_p(0,0xf0);
- }
- 
--extern "C" void start_kernel(void)
-+asmlinkage void start_kernel(void)
- {
- /*
-  * Interrupts are still disabled. Do necessary setups, then
-@@ -466,9 +469,9 @@
- 	if (!(pid=fork())) {
- 		close(0);
- 		if (open("/etc/rc",O_RDONLY,0))
--			exit(1);
-+			_exit(1);
- 		execve("/bin/sh",argv_rc,envp_rc);
--		exit(2);
-+		_exit(2);
- 	}
- 	if (pid>0)
- 		while (pid != wait(&i))
-@@ -484,7 +487,7 @@
- 			(void) open("/dev/tty1",O_RDWR,0);
- 			(void) dup(0);
- 			(void) dup(0);
--			exit(execve("/bin/sh",argv,envp));
-+			_exit(execve("/bin/sh",argv,envp));
- 		}
- 		while (1)
- 			if (pid == wait(&i))
-@@ -492,5 +495,5 @@
- 		printf("\n\rchild %d died with code %04x\n\r",pid,i);
- 		sync();
- 	}
--	exit(0);
-+	_exit(0);
- }
-diff -u --recursive --new-file pl12/linux/ipc/util.c linux/ipc/util.c
---- pl12/linux/ipc/util.c	Mon Aug  9 18:02:31 1993
-+++ linux/ipc/util.c	Sat Sep  4 14:29:20 1993
-@@ -13,7 +13,7 @@
- #include <linux/stat.h>
- 
- void ipc_init (void);
--extern "C" int sys_ipc (uint call, int first, int second, int third, void *ptr); 
-+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr); 
- 
- #ifdef CONFIG_SYSVIPC
- 
-@@ -67,7 +67,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_ipc (uint call, int first, int second, int third, void *ptr) 
-+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr) 
- {
- 	
- 	if (call <= SEMCTL)
-@@ -123,7 +123,7 @@
- 
- #else /* not CONFIG_SYSVIPC */
- 
--extern "C" int sys_ipc (uint call, int first, int second, int third, void *ptr) 
-+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr) 
- {
-     return -ENOSYS;
- }
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/errors.c linux/kernel/FPU-emu/errors.c
---- pl12/linux/kernel/FPU-emu/errors.c	Thu Jul 22 01:11:49 1993
-+++ linux/kernel/FPU-emu/errors.c	Sat Sep  4 03:25:27 1993
-@@ -312,7 +312,7 @@
- 
- /* Real operation attempted on two operands, one a NaN. */
- /* Returns nz if the exception is unmasked */
--extern "C" int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
-+asmlinkage int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
- {
-   FPU_REG *x;
-   int signalling;
-@@ -326,7 +326,7 @@
- 	{
- 	  signalling = !(a->sigh & b->sigh & 0x40000000);
- 	  /* find the "larger" */
--	  if ( *(long long *)&(a->sigl) < *(long long *)&(b->sigl) )
-+	  if ( significand(a) < significand(b) )
- 	    x = b;
- 	}
-       else
-@@ -378,7 +378,7 @@
- 
- /* Invalid arith operation on Valid registers */
- /* Returns nz if the exception is unmasked */
--extern "C" int arith_invalid(FPU_REG *dest)
-+asmlinkage int arith_invalid(FPU_REG *dest)
- {
- 
-   EXCEPTION(EX_Invalid);
-@@ -395,7 +395,7 @@
- 
- 
- /* Divide a finite number by zero */
--extern "C" int divide_by_zero(int sign, FPU_REG *dest)
-+asmlinkage int divide_by_zero(int sign, FPU_REG *dest)
- {
- 
-   if ( control_word & CW_ZeroDiv )
-@@ -430,7 +430,7 @@
- 
- 
- /* This may be called often, so keep it lean */
--extern "C" void set_precision_flag_up(void)
-+asmlinkage void set_precision_flag_up(void)
- {
-   if ( control_word & CW_Precision )
-     partial_status |= (SW_Precision | SW_C1);   /* The masked response */
-@@ -441,7 +441,7 @@
- 
- 
- /* This may be called often, so keep it lean */
--extern "C" void set_precision_flag_down(void)
-+asmlinkage void set_precision_flag_down(void)
- {
-   if ( control_word & CW_Precision )
-     {   /* The masked response */
-@@ -453,7 +453,7 @@
- }
- 
- 
--extern "C" int denormal_operand(void)
-+asmlinkage int denormal_operand(void)
- {
-   if ( control_word & CW_Denormal )
-     {   /* The masked response */
-@@ -468,7 +468,7 @@
- }
- 
- 
--extern "C" int arith_overflow(FPU_REG *dest)
-+asmlinkage int arith_overflow(FPU_REG *dest)
- {
- 
-   if ( control_word & CW_Overflow )
-@@ -502,7 +502,7 @@
- }
- 
- 
--extern "C" int arith_underflow(FPU_REG *dest)
-+asmlinkage int arith_underflow(FPU_REG *dest)
- {
- 
-   if ( control_word & CW_Underflow )
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_arith.c linux/kernel/FPU-emu/fpu_arith.c
---- pl12/linux/kernel/FPU-emu/fpu_arith.c	Thu Jul 22 01:11:50 1993
-+++ linux/kernel/FPU-emu/fpu_arith.c	Wed Sep  1 18:30:04 1993
-@@ -19,10 +19,7 @@
- void fadd__()
- {
-   /* fadd st,st(i) */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_add(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
- }
- 
-@@ -30,10 +27,7 @@
- void fmul__()
- {
-   /* fmul st,st(i) */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_mul(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
- }
- 
-@@ -42,10 +36,7 @@
- void fsub__()
- {
-   /* fsub st,st(i) */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_sub(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
- }
- 
-@@ -53,10 +44,7 @@
- void fsubr_()
- {
-   /* fsubr st,st(i) */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_sub(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word);
- }
- 
-@@ -64,10 +52,7 @@
- void fdiv__()
- {
-   /* fdiv st,st(i) */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_div(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
- }
- 
-@@ -75,10 +60,7 @@
- void fdivr_()
- {
-   /* fdivr st,st(i) */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_div(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word);
- }
- 
-@@ -87,10 +69,7 @@
- void fadd_i()
- {
-   /* fadd st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
- }
- 
-@@ -98,10 +77,7 @@
- void fmul_i()
- {
-   /* fmul st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_mul(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
- }
- 
-@@ -111,10 +87,7 @@
-   /* fsubr st(i),st */
-   /* This is the sense of the 80486 manual
-      reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
- }
- 
-@@ -124,10 +97,7 @@
-   /* fsub st(i),st */
-   /* This is the sense of the 80486 manual
-      reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
- }
- 
-@@ -135,10 +105,7 @@
- void fdivri()
- {
-   /* fdivr st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
- }
- 
-@@ -146,10 +113,7 @@
- void fdiv_i()
- {
-   /* fdiv st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
- }
- 
-@@ -158,10 +122,7 @@
- void faddp_()
- {
-   /* faddp st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
-     pop();
- }
-@@ -170,10 +131,7 @@
- void fmulp_()
- {
-   /* fmulp st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !reg_mul(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
-     pop();
- }
-@@ -185,10 +143,7 @@
-   /* fsubrp st(i),st */
-   /* This is the sense of the 80486 manual
-      reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
-     pop();
- }
-@@ -199,10 +154,7 @@
-   /* fsubp st(i),st */
-   /* This is the sense of the 80486 manual
-      reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word) )
-     pop();
- }
-@@ -211,10 +163,7 @@
- void fdivrp()
- {
-   /* fdivrp st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
-     pop();
- }
-@@ -223,10 +172,7 @@
- void fdivp_()
- {
-   /* fdivp st(i),st */
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word) )
-     pop();
- }
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_aux.c linux/kernel/FPU-emu/fpu_aux.c
---- pl12/linux/kernel/FPU-emu/fpu_aux.c	Thu Jul 22 01:11:50 1993
-+++ linux/kernel/FPU-emu/fpu_aux.c	Wed Sep  1 18:30:04 1993
-@@ -139,10 +139,7 @@
-       stack_underflow();
-       return;
-     }
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   reg_move(FPU_st0_ptr, &t);
-   reg_move(sti_ptr, FPU_st0_ptr);
-   reg_move(&t, sti_ptr);
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_emu.h linux/kernel/FPU-emu/fpu_emu.h
---- pl12/linux/kernel/FPU-emu/fpu_emu.h	Thu Jul 22 01:11:50 1993
-+++ linux/kernel/FPU-emu/fpu_emu.h	Sat Sep  4 03:28:02 1993
-@@ -58,6 +58,7 @@
- #ifndef __ASSEMBLER__
- 
- #include <linux/math_emu.h>
-+#include <linux/linkage.h>
- 
- #ifdef PARANOID
- extern char emulating;
-@@ -110,33 +111,36 @@
- 		 *(long *)&((y)->exp) = *(long *)&((x)->exp); \
- 		 *(long long *)&((y)->sigl) = *(long long *)&((x)->sigl); }
- 
-+#define significand(x) ( ((unsigned long long *)&((x)->sigl))[0] )
- 
-+
- /*----- Prototypes for functions written in assembler -----*/
- /* extern void reg_move(FPU_REG *a, FPU_REG *b); */
- 
--extern "C" void mul64(long long *a, long long *b, long long *result);
--extern "C" void poly_div2(long long *x);
--extern "C" void poly_div4(long long *x);
--extern "C" void poly_div16(long long *x);
--extern "C" void polynomial(unsigned accum[], unsigned x[],
-+asmlinkage void mul64(unsigned long long *a, unsigned long long *b,
-+		      unsigned long long *result);
-+asmlinkage void poly_div2(unsigned long long *x);
-+asmlinkage void poly_div4(unsigned long long *x);
-+asmlinkage void poly_div16(unsigned long long *x);
-+asmlinkage void polynomial(unsigned accum[], unsigned x[],
- 		       unsigned short terms[][4], int n);
--extern "C" void normalize(FPU_REG *x);
--extern "C" void normalize_nuo(FPU_REG *x);
--extern "C" int reg_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
-+asmlinkage void normalize(FPU_REG *x);
-+asmlinkage void normalize_nuo(FPU_REG *x);
-+asmlinkage int reg_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
- 		    unsigned int control_w);
--extern "C" int reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
-+asmlinkage int reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
- 		      unsigned int control_w);
--extern "C" int reg_u_mul(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
-+asmlinkage int reg_u_mul(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
- 		      unsigned int control_w);
--extern "C" int reg_u_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
-+asmlinkage int reg_u_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
- 		      unsigned int control_w);
--extern "C" int reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
-+asmlinkage int reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
- 		      unsigned int control_w);
--extern "C" int wm_sqrt(FPU_REG *n, unsigned int control_w);
--extern "C" unsigned	shrx(void *l, unsigned x);
--extern "C" unsigned	shrxs(void *v, unsigned x);
--extern "C" unsigned long div_small(unsigned long long *x, unsigned long y);
--extern "C" void round_reg(FPU_REG *arg, unsigned int extent,
-+asmlinkage int wm_sqrt(FPU_REG *n, unsigned int control_w);
-+asmlinkage unsigned	shrx(void *l, unsigned x);
-+asmlinkage unsigned	shrxs(void *v, unsigned x);
-+asmlinkage unsigned long div_small(unsigned long long *x, unsigned long y);
-+asmlinkage void round_reg(FPU_REG *arg, unsigned int extent,
- 		      unsigned int control_w);
- 
- #ifndef MAKING_PROTO
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_entry.c linux/kernel/FPU-emu/fpu_entry.c
---- pl12/linux/kernel/FPU-emu/fpu_entry.c	Thu Jul 22 01:11:50 1993
-+++ linux/kernel/FPU-emu/fpu_entry.c	Sat Sep  4 03:25:27 1993
-@@ -155,7 +155,7 @@
- static int valid_prefix(unsigned char byte);
- 
- 
--extern "C" void math_emulate(long arg)
-+asmlinkage void math_emulate(long arg)
- {
-   unsigned char  FPU_modrm;
-   unsigned short code;
-@@ -183,7 +183,7 @@
-       current->used_math = 1;
-     }
- 
--  FPU_info = (struct info *) &arg;
-+  SETUP_DATA_AREA(arg);
- 
-   /* We cannot handle emulation in v86-mode */
-   if (FPU_EFLAGS & 0x00020000)
-@@ -401,20 +401,12 @@
- 	      switch ( (FPU_modrm >> 3) & 7 )
- 		{
- 		case 0:         /* fadd */
--#ifdef PECULIAR_486
--		  /* Default, this conveys no information,
--		     but an 80486 does it. */
- 		  clear_C1();
--#endif PECULIAR_486
- 		  reg_add(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
- 			  control_word);
- 		  break;
- 		case 1:         /* fmul */
--#ifdef PECULIAR_486
--		  /* Default, this conveys no information,
--		     but an 80486 does it. */
- 		  clear_C1();
--#endif PECULIAR_486
- 		  reg_mul(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
- 			  control_word);
- 		  break;
-@@ -426,38 +418,22 @@
- 		    pop();
- 		  break;
- 		case 4:         /* fsub */
--#ifdef PECULIAR_486
--		  /* Default, this conveys no information,
--		     but an 80486 does it. */
- 		  clear_C1();
--#endif PECULIAR_486
- 		  reg_sub(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
- 			  control_word);
- 		  break;
- 		case 5:         /* fsubr */
--#ifdef PECULIAR_486
--		  /* Default, this conveys no information,
--		     but an 80486 does it. */
- 		  clear_C1();
--#endif PECULIAR_486
- 		  reg_sub(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr,
- 			  control_word);
- 		  break;
- 		case 6:         /* fdiv */
--#ifdef PECULIAR_486
--		  /* Default, this conveys no information,
--		     but an 80486 does it. */
- 		  clear_C1();
--#endif PECULIAR_486
- 		  reg_div(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
- 			  control_word);
- 		  break;
- 		case 7:         /* fdivr */
--#ifdef PECULIAR_486
--		  /* Default, this conveys no information,
--		     but an 80486 does it. */
- 		  clear_C1();
--#endif PECULIAR_486
- 		  if ( FPU_st0_tag == TW_Zero )
- 		    partial_status = status1;  /* Undo any denorm tag,
- 					       zero-divide has priority. */
-@@ -637,7 +613,7 @@
- #include <linux/signal.h>
- #include <linux/sched.h>
- 
--extern "C" void math_emulate(long arg)
-+asmlinkage void math_emulate(long arg)
- {
-   printk("math-emulation not enabled and no coprocessor found.\n");
-   printk("killing %s.\n",current->comm);
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_etc.c linux/kernel/FPU-emu/fpu_etc.c
---- pl12/linux/kernel/FPU-emu/fpu_etc.c	Thu Jul 22 01:11:50 1993
-+++ linux/kernel/FPU-emu/fpu_etc.c	Wed Sep  1 18:30:04 1993
-@@ -22,10 +22,7 @@
-   if ( NOT_EMPTY_0 )
-     {
-       FPU_st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
--#ifdef PECULIAR_486
--      /* Default, this conveys no information, but an 80486 does it. */
-       clear_C1();
--#endif PECULIAR_486
-     }
-   else
-     stack_underflow();
-@@ -36,10 +33,7 @@
-   if ( FPU_st0_tag ^ TW_Empty )
-     {
-       FPU_st0_ptr->sign = SIGN_POS;
--#ifdef PECULIAR_486
--      /* Default, this conveys no information, but an 80486 does it. */
-       clear_C1();
--#endif PECULIAR_486
-     }
-   else
-     stack_underflow();
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_proto.h linux/kernel/FPU-emu/fpu_proto.h
---- pl12/linux/kernel/FPU-emu/fpu_proto.h	Thu Jul 22 01:11:50 1993
-+++ linux/kernel/FPU-emu/fpu_proto.h	Sat Sep  4 03:25:27 1993
-@@ -6,15 +6,15 @@
- extern void stack_underflow_i(int i);
- extern void stack_underflow_pop(int i);
- extern int set_precision_flag(int flags);
--extern "C" void exception(int n);
--extern "C" int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest);
--extern "C" int arith_invalid(FPU_REG *dest);
--extern "C" int divide_by_zero(int sign, FPU_REG *dest);
--extern "C" void set_precision_flag_up(void);
--extern "C" void set_precision_flag_down(void);
--extern "C" int denormal_operand(void);
--extern "C" int arith_overflow(FPU_REG *dest);
--extern "C" int arith_underflow(FPU_REG *dest);
-+asmlinkage void exception(int n);
-+asmlinkage int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest);
-+asmlinkage int arith_invalid(FPU_REG *dest);
-+asmlinkage int divide_by_zero(int sign, FPU_REG *dest);
-+asmlinkage void set_precision_flag_up(void);
-+asmlinkage void set_precision_flag_down(void);
-+asmlinkage int denormal_operand(void);
-+asmlinkage int arith_overflow(FPU_REG *dest);
-+asmlinkage int arith_underflow(FPU_REG *dest);
- 
- /* fpu_arith.c */
- extern void fadd__(void);
-@@ -50,7 +50,7 @@
- extern void fstp_i(void);
- 
- /* fpu_entry.c */
--extern "C" void math_emulate(long arg);
-+asmlinkage void math_emulate(long arg);
- extern void __math_abort(struct info *info, unsigned int signal);
- 
- /* fpu_etc.c */
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_system.h linux/kernel/FPU-emu/fpu_system.h
---- pl12/linux/kernel/FPU-emu/fpu_system.h	Thu Jul 22 01:11:50 1993
-+++ linux/kernel/FPU-emu/fpu_system.h	Wed Sep  1 18:30:04 1993
-@@ -14,6 +14,10 @@
- #include <linux/sched.h>
- #include <linux/kernel.h>
- 
-+/* This sets the pointer FPU_info to point to the argument part
-+   of the stack frame of math_emulate() */
-+#define SETUP_DATA_AREA(arg)    FPU_info = (struct info *) &arg
-+
- #define I387			(current->tss.i387)
- #define FPU_info		(I387.soft.info)
- 
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_trig.c linux/kernel/FPU-emu/fpu_trig.c
---- pl12/linux/kernel/FPU-emu/fpu_trig.c	Thu Jul 22 01:11:51 1993
-+++ linux/kernel/FPU-emu/fpu_trig.c	Wed Sep  1 18:30:05 1993
-@@ -20,7 +20,7 @@
- 
- static void rem_kernel(unsigned long long st0, unsigned long long *y,
- 		       unsigned long long st1,
--		       long long q, int n);
-+		       unsigned long long q, int n);
- 
- #define BETTER_THAN_486
- 
-@@ -27,6 +27,7 @@
- #define FCOS  4
- #define FPTAN 1
- 
-+
- /* Used only by fptan, fsin, fcos, and fsincos. */
- /* This routine produces very accurate results, similar to
-    using a value of pi with more than 128 bits precision. */
-@@ -36,7 +37,7 @@
- static int trig_arg(FPU_REG *X, int even)
- {
-   FPU_REG tmp;
--  long long q;
-+  unsigned long long q;
-   int old_cw = control_word, saved_status = partial_status;
- 
-   if ( X->exp >= EXP_BIAS + 63 )
-@@ -51,12 +52,12 @@
-   reg_div(X, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f);
-   round_to_int(&tmp);  /* Fortunately, this can't overflow
- 			  to 2^64 */
--  q = ((long long *)&(tmp.sigl))[0];
-+  q = significand(&tmp);
-   if ( q )
-     {
--      rem_kernel(((unsigned long long *)&(X->sigl))[0],
--		 (unsigned long long *)&(tmp.sigl),
--		 ((unsigned long long *)&(CONST_PI2.sigl))[0],
-+      rem_kernel(significand(X),
-+		 &significand(&tmp),
-+		 significand(&CONST_PI2),
- 		 q, X->exp - CONST_PI2.exp);
-       tmp.exp = CONST_PI2.exp;
-       normalize(&tmp);
-@@ -85,7 +86,7 @@
- 	{
- 	  /* This code gives the effect of having p/2 to better than
- 	     128 bits precision. */
--	  ((long long *)&(tmp.sigl))[0] = q + 1;
-+	  significand(&tmp) = q + 1;
- 	  tmp.exp = EXP_BIAS + 63;
- 	  normalize(&tmp);
- 	  reg_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION);
-@@ -104,7 +105,7 @@
- 	{
- 	  /* This code gives the effect of having p/2 to better than
- 	     128 bits precision. */
--	  ((long long *)&(tmp.sigl))[0] = q;
-+	  significand(&tmp) = q;
- 	  tmp.exp = EXP_BIAS + 63;
- 	  normalize(&tmp);
- 	  reg_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION);
-@@ -204,10 +205,7 @@
- 
- static void f2xm1(void)
- {
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   switch ( FPU_st0_tag )
-     {
-     case TW_Valid:
-@@ -363,11 +361,7 @@
- 
-   if ( STACK_OVERFLOW )
-     {  stack_overflow(); return; }
--
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !(FPU_st0_tag ^ TW_Valid) )
-     {
-       long e;
-@@ -432,19 +426,13 @@
- 
- static void fdecstp(void)
- {
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   top--;  /* FPU_st0_ptr will be fixed in math_emulate() before the next instr */
- }
- 
- static void fincstp(void)
- {
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   top++;  /* FPU_st0_ptr will be fixed in math_emulate() before the next instr */
- }
- 
-@@ -451,10 +439,7 @@
- 
- static void fsqrt_(void)
- {
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !(FPU_st0_tag ^ TW_Valid) )
-     {
-       int expon;
-@@ -729,7 +714,7 @@
-  */
- static void rem_kernel(unsigned long long st0, unsigned long long *y,
- 		       unsigned long long st1,
--		       long long q, int n)
-+		       unsigned long long q, int n)
- {
-   unsigned long long x;
- 
-@@ -790,11 +775,11 @@
- 		{
- 		  round_to_int(&tmp);  /* Fortunately, this can't overflow
- 					  to 2^64 */
--		  q = ((long long *)&(tmp.sigl))[0];
-+		  q = significand(&tmp);
- 
--		  rem_kernel(((unsigned long long *)&(FPU_st0_ptr->sigl))[0],
--			     (unsigned long long *)&(tmp.sigl),
--			     ((unsigned long long *)&(st1_ptr->sigl))[0],
-+		  rem_kernel(significand(FPU_st0_ptr),
-+			     &significand(&tmp),
-+			     significand(st1_ptr),
- 			     q, expdif);
- 
- 		  tmp.exp = st1_ptr->exp;
-@@ -808,14 +793,24 @@
- 
- 	      if ( (round == RC_RND) && (tmp.sigh & 0xc0000000) )
- 		{
--		  /* We may need to subtract st(1) once more. */
-+		  /* We may need to subtract st(1) once more,
-+		     to get a result <= 1/2 of st(1). */
- 		  unsigned long long x;
--		  x = ((unsigned long long *)&(st1_ptr->sigl))[0] -
--		    ((unsigned long long *)&(tmp.sigl))[0];
--		  if ( x < ((unsigned long long *)&(tmp.sigl))[0] )
-+		  expdif = st1_ptr->exp - tmp.exp;
-+		  if ( expdif <= 1 )
- 		    {
--		      tmp.sign ^= (SIGN_POS^SIGN_NEG);
--		      ((unsigned long long *)&(tmp.sigl))[0] = x;
-+		      if ( expdif == 0 )
-+			x = significand(st1_ptr) - significand(&tmp);
-+		      else /* expdif is 1 */
-+			x = (significand(st1_ptr) << 1) - significand(&tmp);
-+		      if ( (x < significand(&tmp)) ||
-+			  /* or equi-distant (from 0 & st(1)) and q is odd */
-+			  ((x == significand(&tmp)) && (q & 1) ) )
-+			{
-+			  tmp.sign ^= (SIGN_POS^SIGN_NEG);
-+			  significand(&tmp) = x;
-+			  q++;
-+			}
- 		    }
- 		}
- 
-@@ -849,10 +844,10 @@
- 
- 	  round_to_int(&tmp);  /* Fortunately, this can't overflow to 2^64 */
- 
--	  rem_kernel(((unsigned long long *)&(FPU_st0_ptr->sigl))[0],
--		     ((unsigned long long *)&(tmp.sigl)),
--		     ((unsigned long long *)&(st1_ptr->sigl))[0],
--		     ((long long *)&(tmp.sigl))[0],
-+	  rem_kernel(significand(FPU_st0_ptr),
-+		     &significand(&tmp),
-+		     significand(st1_ptr),
-+		     significand(&tmp),
- 		     tmp.exp - EXP_BIAS
- 		     ); 
- 	  tmp.exp = exp_1 + expdif;
-@@ -882,13 +877,15 @@
- 
-       control_word = old_cw;
-       partial_status = saved_status;
--      normalize(&tmp);
-+      normalize_nuo(&tmp);
-       reg_move(&tmp, FPU_st0_ptr);
-       setcc(cc);
- 
--      if ( FPU_st0_ptr->tag != TW_Zero )
--	/* Use round_reg() to properly detect under/overflow etc */
--	round_reg(FPU_st0_ptr, 0, control_word);
-+      /* The only condition to be looked for is underflow,
-+	 and it can occur here only if underflow is unmasked. */
-+      if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (FPU_st0_ptr->tag != TW_Zero)
-+	  && !(control_word & CW_Underflow) )
-+	arith_underflow(FPU_st0_ptr);
- 
-       return;
-     }
-@@ -961,10 +958,7 @@
-   FPU_REG *st1_ptr = &st(1);
-   char st1_tag = st1_ptr->tag;
- 
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
-     {
-       if ( FPU_st0_ptr->sign == SIGN_POS )
-@@ -1155,10 +1149,7 @@
-   char st1_tag = st1_ptr->tag;
-   char st1_sign = st1_ptr->sign, st0_sign = FPU_st0_ptr->sign;
- 
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
-     {
-       int saved_control, saved_status;
-@@ -1336,10 +1327,7 @@
-   FPU_REG *st1_ptr = &st(1);
-   char st1_tag = st1_ptr->tag;
- 
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
-     {
-       int saved_control, saved_status;
-@@ -1560,10 +1548,7 @@
-   int old_cw = control_word;
-   char sign = FPU_st0_ptr->sign;
- 
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
-   if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
-     {
-       long scale;
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/load_store.c linux/kernel/FPU-emu/load_store.c
---- pl12/linux/kernel/FPU-emu/load_store.c	Thu Jul 22 01:11:51 1993
-+++ linux/kernel/FPU-emu/load_store.c	Wed Sep  1 18:30:05 1993
-@@ -84,10 +84,7 @@
- switch ( type )
-   {
-   case 000:       /* fld m32real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_load_single();
-     if ( (FPU_loaded_data.tag == TW_NaN) &&
- 	real_2op_NaN(&FPU_loaded_data, &FPU_loaded_data, &FPU_loaded_data) )
-@@ -98,18 +95,12 @@
-     reg_move(&FPU_loaded_data, pop_ptr);
-     break;
-   case 001:      /* fild m32int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_load_int32();
-     reg_move(&FPU_loaded_data, pop_ptr);
-     break;
-   case 002:      /* fld m64real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_load_double();
-     if ( (FPU_loaded_data.tag == TW_NaN) &&
- 	real_2op_NaN(&FPU_loaded_data, &FPU_loaded_data, &FPU_loaded_data) )
-@@ -120,73 +111,46 @@
-     reg_move(&FPU_loaded_data, pop_ptr);
-     break;
-   case 003:      /* fild m16int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_load_int16();
-     reg_move(&FPU_loaded_data, pop_ptr);
-     break;
-   case 010:      /* fst m32real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_store_single();
-     break;
-   case 011:      /* fist m32int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_store_int32();
-     break;
-   case 012:     /* fst m64real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_store_double();
-     break;
-   case 013:     /* fist m16int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_store_int16();
-     break;
-   case 014:     /* fstp m32real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     if ( reg_store_single() )
-       pop_0();  /* pop only if the number was actually stored
- 		 (see the 80486 manual p16-28) */
-     break;
-   case 015:     /* fistp m32int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     if ( reg_store_int32() )
-       pop_0();  /* pop only if the number was actually stored
- 		 (see the 80486 manual p16-28) */
-     break;
-   case 016:     /* fstp m64real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     if ( reg_store_double() )
-       pop_0();  /* pop only if the number was actually stored
- 		 (see the 80486 manual p16-28) */
-     break;
-   case 017:     /* fistp m16int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     if ( reg_store_int16() )
-       pop_0();  /* pop only if the number was actually stored
- 		 (see the 80486 manual p16-28) */
-@@ -198,10 +162,7 @@
-     frstor();
-     break;
-   case 023:     /* fbld m80dec */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_load_bcd();
-     reg_move(&FPU_loaded_data, pop_ptr);
-     break;
-@@ -220,18 +181,12 @@
-     NO_NET_INSTR_EFFECT;
-     break;
-   case 025:      /* fld m80real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_load_extended();
-     reg_move(&FPU_loaded_data, pop_ptr);
-     break;
-   case 027:      /* fild m64int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     reg_load_int64();
-     reg_move(&FPU_loaded_data, pop_ptr);
-     break;
-@@ -244,10 +199,7 @@
-     NO_NET_DATA_EFFECT;
-     break;
-   case 033:      /* fbstp m80dec */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     if ( reg_store_bcd() )
-       pop_0();  /* pop only if the number was actually stored
- 		 (see the 80486 manual p16-28) */
-@@ -261,10 +213,7 @@
-     NO_NET_INSTR_EFFECT;
-     break;
-   case 035:      /* fstp m80real */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     if ( reg_store_extended() )
-       pop_0();  /* pop only if the number was actually stored
- 		 (see the 80486 manual p16-28) */
-@@ -278,10 +227,7 @@
-     NO_NET_INSTR_EFFECT;
-     break;
-   case 037:      /* fistp m64int */
--#ifdef PECULIAR_486
--    /* Default, this conveys no information, but an 80486 does it. */
-     clear_C1();
--#endif PECULIAR_486
-     if ( reg_store_int64() )
-       pop_0();  /* pop only if the number was actually stored
- 		 (see the 80486 manual p16-28) */
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_atan.c linux/kernel/FPU-emu/poly_atan.c
---- pl12/linux/kernel/FPU-emu/poly_atan.c	Thu Jul 22 01:11:51 1993
-+++ linux/kernel/FPU-emu/poly_atan.c	Wed Sep  1 18:30:05 1993
-@@ -38,12 +38,9 @@
-   { 0xf1dd2dbf, 0x000a530a }
- };
- 
-+static unsigned long long denomterm = 0xea2e6612fc4bd208LL;
- 
--static unsigned denomterm[2] =
--{ 0xfc4bd208, 0xea2e6612 };
- 
--
--
- /*--- poly_atan() -----------------------------------------------------------+
-  |                                                                           |
-  +---------------------------------------------------------------------------*/
-@@ -53,7 +50,7 @@
-   short		exponent;
-   FPU_REG       odd_poly, even_poly, pos_poly, neg_poly, ratio;
-   FPU_REG       argSq;
--  long long     arg_signif, argSqSq;
-+  unsigned long long     arg_signif, argSqSq;
-   
- 
- #ifdef PARANOID
-@@ -97,20 +94,20 @@
- 
- 	  recursions++;
- 
--	  arg_signif = *(long long *)&(arg->sigl);
-+	  arg_signif = significand(arg);
- 	  if ( exponent < -1 )
- 	    {
- 	      if ( shrx(&arg_signif, -1-exponent) >= 0x80000000U )
- 		arg_signif++;	/* round up */
- 	    }
--	  *(long long *)&(numerator.sigl) = -arg_signif;
-+	  significand(&numerator) = -arg_signif;
- 	  numerator.exp = EXP_BIAS - 1;
- 	  normalize(&numerator);                       /* 1 - arg */
- 
--	  arg_signif = *(long long *)&(arg->sigl);
-+	  arg_signif = significand(arg);
- 	  if ( shrx(&arg_signif, -exponent) >= 0x80000000U )
- 	    arg_signif++;	/* round up */
--	  *(long long *)&(denom.sigl) = arg_signif;
-+	  significand(&denom) = arg_signif;
- 	  denom.sigh |= 0x80000000;                    /* 1 + arg */
- 
- 	  arg->exp = numerator.exp;
-@@ -120,7 +117,7 @@
- 	}
-     }
- 
--  *(long long *)&arg_signif = *(long long *)&(arg->sigl);
-+  arg_signif = significand(arg);
- 
- #ifdef PARANOID
-   /* This must always be true */
-@@ -136,8 +133,8 @@
-   
-   /* Now have arg_signif with binary point at the left
-      .1xxxxxxxx */
--  mul64(&arg_signif, &arg_signif, (long long *)(&argSq.sigl));
--  mul64((long long *)(&argSq.sigl), (long long *)(&argSq.sigl), &argSqSq);
-+  mul64(&arg_signif, &arg_signif, &significand(&argSq));
-+  mul64(&significand(&argSq), &significand(&argSq), &argSqSq);
- 
-   /* will be a valid positive nr with expon = 0 */
-   *(short *)&(pos_poly.sign) = 0;
-@@ -146,8 +143,8 @@
-   /* Do the basic fixed point polynomial evaluation */
-   polynomial(&pos_poly.sigl, (unsigned *)&argSqSq,
- 	     (unsigned short (*)[4])oddplterms, HIPOWERop-1);
--  mul64((long long *)(&argSq.sigl), (long long *)(&pos_poly.sigl),
--	(long long *)(&pos_poly.sigl));
-+  mul64(&significand(&argSq), &significand(&pos_poly),
-+	&significand(&pos_poly));
- 
-   /* will be a valid positive nr with expon = 0 */
-   *(short *)&(neg_poly.sign) = 0;
-@@ -158,7 +155,7 @@
- 	     (unsigned short (*)[4])oddnegterms, HIPOWERon-1);
- 
-   /* Subtract the mantissas */
--  *((long long *)(&pos_poly.sigl)) -= *((long long *)(&neg_poly.sigl));
-+  significand(&pos_poly) -= significand(&neg_poly);
- 
-   reg_move(&pos_poly, &odd_poly);
-   poly_add_1(&odd_poly);
-@@ -166,8 +163,7 @@
-   /* will be a valid positive nr with expon = 0 */
-   *(short *)&(even_poly.sign) = 0;
- 
--  mul64((long long *)(&argSq.sigl),
--	(long long *)(&denomterm), (long long *)(&even_poly.sigl));
-+  mul64(&significand(&argSq), &denomterm, &significand(&even_poly));
- 
-   poly_add_1(&even_poly);
- 
-@@ -198,7 +194,7 @@
- shrx(&src->sigl, 1);
- 
- #ifdef OBSOLETE
--if ( round ) (*(long long *)&src->sigl)++;   /* Round to even */
-+if ( round ) significand(src)++;   /* Round to even */
- #endif OBSOLETE
- 
- src->sigh |= 0x80000000;
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_div.S linux/kernel/FPU-emu/poly_div.S
---- pl12/linux/kernel/FPU-emu/poly_div.S	Tue Nov 10 12:54:54 1992
-+++ linux/kernel/FPU-emu/poly_div.S	Wed Sep  1 18:30:05 1993
-@@ -8,9 +8,9 @@
-  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
-  |                                                                           |
-  | Call from C as:                                                           |
-- |   void poly_div2(long long *x)                                            |
-- |   void poly_div4(long long *x)                                            |
-- |   void poly_div16(long long *x)                                           |
-+ |   void poly_div2(unsigned long long *x)                                   |
-+ |   void poly_div4(unsigned long long *x)                                   |
-+ |   void poly_div16(unsigned long long *x)                                  |
-  |                                                                           |
-  +---------------------------------------------------------------------------*/
- 
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_l2.c linux/kernel/FPU-emu/poly_l2.c
---- pl12/linux/kernel/FPU-emu/poly_l2.c	Sun May 23 14:48:35 1993
-+++ linux/kernel/FPU-emu/poly_l2.c	Wed Sep  1 18:30:05 1993
-@@ -45,7 +45,7 @@
-   short		  exponent;
-   char		  zero;		/* flag for an Xx == 0 */
-   unsigned short  bits, shift;
--  long long       Xsq;
-+  unsigned long long       Xsq;
-   FPU_REG	  accum, denom, num, Xx;
- 
- 
-@@ -79,7 +79,7 @@
- 
-   denom.sigl = num.sigl;
-   denom.sigh = num.sigh;
--  poly_div4((long long *)&(denom.sigl));
-+  poly_div4(&significand(&denom));
-   denom.sigh += 0x80000000;			/* set the msb */
-   Xx.exp = EXP_BIAS;  /* needed to prevent errors in div routine */
-   reg_u_div(&num, &denom, &Xx, FULL_PRECISION);
-@@ -86,7 +86,7 @@
- 
-   zero = !(Xx.sigh | Xx.sigl);
-   
--  mul64((long long *)&Xx.sigl, (long long *)&Xx.sigl, &Xsq);
-+  mul64(&significand(&Xx), &significand(&Xx), &Xsq);
-   poly_div16(&Xsq);
- 
-   accum.exp = -1;		/* exponent of accum */
-@@ -123,7 +123,7 @@
- 	    {
- 	      /* The argument is of the form 1-x */
- 	      /* Use  1-1/(1-x) = x/(1-x) */
--	      *((long long *)&num.sigl) = - *((long long *)&(arg->sigl));
-+	      significand(&num) = - significand(arg);
- 	      normalize(&num);
- 	      reg_div(&num, arg, &num, FULL_PRECISION);
- 	    }
-@@ -149,16 +149,16 @@
-       return;
-     }
- 
--  mul64((long long *)&accum.sigl,
--	(long long *)&Xx.sigl, (long long *)&accum.sigl);
-+  mul64(&significand(&accum),
-+	&significand(&Xx), &significand(&accum));
- 
--  *((long long *)(&accum.sigl)) += *((long long *)(&Xx.sigl));
-+  significand(&accum) += significand(&Xx);
- 
-   if ( Xx.sigh > accum.sigh )
-     {
-       /* There was an overflow */
- 
--      poly_div2((long long *)&accum.sigl);
-+      poly_div2(&significand(&accum));
-       accum.sigh |= 0x80000000;
-       accum.exp++;
-     }
-@@ -179,11 +179,11 @@
- 	  /* Shift to get exponent == 0 */
- 	  if ( accum.exp < 0 )
- 	    {
--	      poly_div2((long long *)&accum.sigl);
-+	      poly_div2(&significand(&accum));
- 	      accum.exp++;
- 	    }
- 	  /* Just negate, but throw away the sign */
--	  *((long long *)&(accum.sigl)) = - *((long long *)&(accum.sigl));
-+	  significand(&accum) = - significand(&accum);
- 	  if ( exponent < 0 )
- 	    exponent++;
- 	  else
-@@ -198,11 +198,11 @@
-       if ( accum.exp )
- 	{
- 	  accum.exp++;
--	  poly_div2((long long *)&accum.sigl);
-+	  poly_div2(&significand(&accum));
- 	}
-       while ( shift )
- 	{
--	  poly_div2((long long *)&accum.sigl);
-+	  poly_div2(&significand(&accum));
- 	  if ( shift & 1)
- 	    accum.sigh |= 0x80000000;
- 	  shift >>= 1;
-@@ -227,7 +227,7 @@
- int	poly_l2p1(FPU_REG *arg, FPU_REG *result)
- {
-   char		sign = 0;
--  long long     Xsq;
-+  unsigned long long     Xsq;
-   FPU_REG      	arg_pl1, denom, accum, local_arg, poly_arg;
- 
- 
-@@ -263,7 +263,7 @@
-   /* Get poly_arg bits aligned as required */
-   shrx((unsigned *)&(poly_arg.sigl), -(poly_arg.exp - EXP_BIAS + 3));
- 
--  mul64((long long *)&(poly_arg.sigl), (long long *)&(poly_arg.sigl), &Xsq);
-+  mul64(&significand(&poly_arg), &significand(&poly_arg), &Xsq);
-   poly_div16(&Xsq);
- 
-   /* Do the basic fixed point polynomial evaluation */
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_sin.c linux/kernel/FPU-emu/poly_sin.c
---- pl12/linux/kernel/FPU-emu/poly_sin.c	Thu Jul 22 01:11:51 1993
-+++ linux/kernel/FPU-emu/poly_sin.c	Wed Sep  1 18:30:05 1993
-@@ -82,13 +82,13 @@
-     {
-       /* shift the argument right by the required places */
-       if ( shrx(&(fixed_arg.sigl), -1-exponent) >= 0x80000000U )
--	(*((long long *)(&(fixed_arg.sigl))))++;	/* round up */
-+	significand(&fixed_arg)++;	/* round up */
-     }
-   
--  mul64((long long *)&(fixed_arg.sigl), (long long *)&(fixed_arg.sigl),
--	(long long *)&(arg_sqrd.sigl));
--  mul64((long long *)&(arg_sqrd.sigl), (long long *)&(arg_sqrd.sigl),
--	(long long *)&(arg_to_4.sigl));
-+  mul64(&significand(&fixed_arg), &significand(&fixed_arg),
-+	&significand(&arg_sqrd));
-+  mul64(&significand(&arg_sqrd), &significand(&arg_sqrd),
-+	&significand(&arg_to_4));
-   
-   /* will be a valid positive nr with expon = 0 */
-   *(short *)&(accum.sign) = 0;
-@@ -103,11 +103,11 @@
-   
-   /* Do the basic fixed point polynomial evaluation */
-   polynomial(&(negaccum.sigl), &(arg_to_4.sigl), negterms, HIPOWER-1);
--  mul64((long long *)&(arg_sqrd.sigl), (long long *)&(negaccum.sigl),
--	(long long *)&(negaccum.sigl));
-+  mul64(&significand(&arg_sqrd), &significand(&negaccum),
-+	&significand(&negaccum));
- 
-   /* Subtract the mantissas */
--  *((long long *)(&(accum.sigl))) -= *((long long *)(&(negaccum.sigl)));
-+  significand(&accum) -= significand(&negaccum);
-   
-   /* Convert to 64 bit signed-compatible */
-   accum.exp = EXP_BIAS - 1 + accum.exp;
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_tan.c linux/kernel/FPU-emu/poly_tan.c
---- pl12/linux/kernel/FPU-emu/poly_tan.c	Thu Jul 22 01:11:51 1993
-+++ linux/kernel/FPU-emu/poly_tan.c	Wed Sep  1 18:30:05 1993
-@@ -54,7 +54,7 @@
-   short		exponent;
-   FPU_REG       odd_poly, even_poly, pos_poly, neg_poly;
-   FPU_REG       argSq;
--  long long     arg_signif, argSqSq;
-+  unsigned long long     arg_signif, argSqSq;
-   
- 
-   exponent = arg->exp - EXP_BIAS;
-@@ -64,7 +64,7 @@
-     { arith_invalid(y_reg); return; }  /* Need a positive number */
- #endif PARANOID
- 
--  *(long long *)&arg_signif = *(long long *)&(arg->sigl);
-+  arg_signif = significand(arg);
-   if ( exponent < -1 )
-     {
-       /* shift the argument right by the required places */
-@@ -72,8 +72,8 @@
- 	arg_signif++;	/* round up */
-     }
- 
--  mul64(&arg_signif, &arg_signif, (long long *)(&argSq.sigl));
--  mul64((long long *)(&argSq.sigl), (long long *)(&argSq.sigl), &argSqSq);
-+  mul64(&arg_signif, &arg_signif, &significand(&argSq));
-+  mul64(&significand(&argSq), &significand(&argSq), &argSqSq);
- 
-   /* will be a valid positive nr with expon = 0 */
-   *(short *)&(pos_poly.sign) = 0;
-@@ -88,11 +88,11 @@
- 
-   /* Do the basic fixed point polynomial evaluation */
-   polynomial(&neg_poly.sigl, (unsigned *)&argSqSq, oddnegterms, HIPOWERon-1);
--  mul64((long long *)(&argSq.sigl), (long long *)(&neg_poly.sigl),
--	(long long *)(&neg_poly.sigl));
-+  mul64(&significand(&argSq), &significand(&neg_poly),
-+	&significand(&neg_poly));
- 
-   /* Subtract the mantissas */
--  *((long long *)(&pos_poly.sigl)) -= *((long long *)(&neg_poly.sigl));
-+  significand(&pos_poly) -= significand(&neg_poly);
- 
-   /* Convert to 64 bit signed-compatible */
-   pos_poly.exp -= 1;
-@@ -110,8 +110,8 @@
-   
-   /* Do the basic fixed point polynomial evaluation */
-   polynomial(&pos_poly.sigl, (unsigned *)&argSqSq, evenplterms, HIPOWERep-1);
--  mul64((long long *)(&argSq.sigl),
--	(long long *)(&pos_poly.sigl), (long long *)(&pos_poly.sigl));
-+  mul64(&significand(&argSq),
-+	&significand(&pos_poly), &significand(&pos_poly));
-   
-   /* will be a valid positive nr with expon = 0 */
-   *(short *)&(neg_poly.sign) = 0;
-@@ -121,7 +121,7 @@
-   polynomial(&neg_poly.sigl, (unsigned *)&argSqSq, evennegterms, HIPOWERen-1);
- 
-   /* Subtract the mantissas */
--  *((long long *)(&neg_poly.sigl)) -= *((long long *)(&pos_poly.sigl));
-+  significand(&neg_poly) -= significand(&pos_poly);
-   /* and multiply by argSq */
- 
-   /* Convert argSq to a valid reg number */
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/reg_constant.c linux/kernel/FPU-emu/reg_constant.c
---- pl12/linux/kernel/FPU-emu/reg_constant.c	Thu Jul 22 01:11:52 1993
-+++ linux/kernel/FPU-emu/reg_constant.c	Wed Sep  1 18:30:05 1993
-@@ -67,10 +67,7 @@
-     }
-   push();
-   reg_move(c, FPU_st0_ptr);
--#ifdef PECULIAR_486
--  /* Default, this conveys no information, but an 80486 does it. */
-   clear_C1();
--#endif PECULIAR_486
- }
- 
- 
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/reg_ld_str.c linux/kernel/FPU-emu/reg_ld_str.c
---- pl12/linux/kernel/FPU-emu/reg_ld_str.c	Thu Jul 22 01:11:52 1993
-+++ linux/kernel/FPU-emu/reg_ld_str.c	Wed Sep  1 18:30:05 1993
-@@ -312,7 +312,7 @@
-   }
- 
-   e = EXP_BIAS + 63;
--  *((long long *)&FPU_loaded_data.sigl) = s;
-+  significand(&FPU_loaded_data) = s;
-   FPU_loaded_data.exp = e;
-   FPU_loaded_data.tag = TW_Valid;
-   normalize_nuo(&FPU_loaded_data);
-@@ -417,7 +417,7 @@
-     }
-   else
-     {
--      *((long long *)&FPU_loaded_data.sigl) = l;
-+      significand(&FPU_loaded_data) = l;
-       FPU_loaded_data.exp = EXP_BIAS + 63;
-       FPU_loaded_data.tag = TW_Valid;
-       normalize_nuo(&FPU_loaded_data);
-@@ -1033,7 +1033,7 @@
- 
-   reg_move(FPU_st0_ptr, &t);
-   precision_loss = round_to_int(&t);
--  ll = *(unsigned long long *)(&t.sigl);
-+  ll = significand(&t);
- 
-   /* Check for overflow, by comparing with 999999999999999999 decimal. */
-   if ( (t.sigh > 0x0de0b6b3) ||
-@@ -1042,14 +1042,16 @@
-       EXCEPTION(EX_Invalid);
-       /* This is a special case: see sec 16.2.5.1 of the 80486 book */
-     invalid_operand:
--      if ( control_word & EX_Invalid )
-+      if ( control_word & CW_Invalid )
- 	{
- 	  /* Produce the QNaN "indefinite" */
- 	  RE_ENTRANT_CHECK_OFF
- 	  verify_area(VERIFY_WRITE,d,10);
--	  put_fs_byte(0xff,(unsigned char *) d+7); /* This byte undefined */
--	  put_fs_byte(0xff,(unsigned char *) d+8);
--	  put_fs_byte(0xff,(unsigned char *) d+9);
-+	  for ( i = 0; i < 7; i++)
-+	    put_fs_byte(0, (unsigned char *) d+i); /* These bytes "undefined" */
-+	  put_fs_byte(0xc0, (unsigned char *) d+7); /* This byte "undefined" */
-+	  put_fs_byte(0xff, (unsigned char *) d+8);
-+	  put_fs_byte(0xff, (unsigned char *) d+9);
- 	  RE_ENTRANT_CHECK_ON
- 	  return 1;
- 	}
-@@ -1058,8 +1060,8 @@
-     }
-   else if ( precision_loss )
-     {
--      if ( set_precision_flag(precision_loss) )
--	return 0;
-+      /* Precision loss doesn't stop the data transfer */
-+      set_precision_flag(precision_loss);
-     }
- 
-   verify_area(VERIFY_WRITE,d,10);
-@@ -1096,7 +1098,7 @@
-   if (r->tag == TW_Zero)
-     {
-       /* Make sure that zero is returned */
--      *(long long *)&r->sigl = 0;
-+      significand(r) = 0;
-       return 0;        /* o.k. */
-     }
-   
-@@ -1118,7 +1120,7 @@
- 	  || (half_or_more && (r->sigl & 1)) )	/* odd -> even */
- 	{
- 	  if ( very_big ) return 1;        /* overflow */
--	  (*(long long *)(&r->sigl)) ++;
-+	  significand(r) ++;
- 	  return PRECISION_LOST_UP;
- 	}
-       break;
-@@ -1126,7 +1128,7 @@
-       if (frac_part && r->sign)
- 	{
- 	  if ( very_big ) return 1;        /* overflow */
--	  (*(long long *)(&r->sigl)) ++;
-+	  significand(r) ++;
- 	  return PRECISION_LOST_UP;
- 	}
-       break;
-@@ -1134,7 +1136,7 @@
-       if (frac_part && !r->sign)
- 	{
- 	  if ( very_big ) return 1;        /* overflow */
--	  (*(long long *)(&r->sigl)) ++;
-+	  significand(r) ++;
- 	  return PRECISION_LOST_UP;
- 	}
-       break;
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/status_w.h linux/kernel/FPU-emu/status_w.h
---- pl12/linux/kernel/FPU-emu/status_w.h	Thu Jul 22 01:11:53 1993
-+++ linux/kernel/FPU-emu/status_w.h	Wed Sep  1 18:30:06 1993
-@@ -10,6 +10,7 @@
- #ifndef _STATUS_H_
- #define _STATUS_H_
- 
-+#include "fpu_emu.h"    /* for definition of PECULIAR_486 */
- 
- #ifdef __ASSEMBLER__
- #define	Const__(x)	$##x
-@@ -51,8 +52,13 @@
-   partial_status &= ~(SW_C0|SW_C1|SW_C2|SW_C3); \
-   partial_status |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3); })
- 
--/* Clear the SW_C1 bit, "other bits undefined" */
--#define clear_C1()  { partial_status &= ~SW_C1; }
-+#ifdef PECULIAR_486
-+   /* Default, this conveys no information, but an 80486 does it. */
-+   /* Clear the SW_C1 bit, "other bits undefined". */
-+#  define clear_C1()  { partial_status &= ~SW_C1; }
-+# else
-+#  define clear_C1()
-+#endif PECULIAR_486
- 
- #endif __ASSEMBLER__
- 
-diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/version.h linux/kernel/FPU-emu/version.h
---- pl12/linux/kernel/FPU-emu/version.h	Thu Jul 22 01:11:53 1993
-+++ linux/kernel/FPU-emu/version.h	Wed Sep  1 18:30:06 1993
-@@ -9,5 +9,5 @@
-  |                                                                           |
-  +---------------------------------------------------------------------------*/
- 
--#define FPU_VERSION "wm-FPU-emu version BETA 1.5"
-+#define FPU_VERSION "wm-FPU-emu version BETA 1.6"
- 
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/blk.h linux/kernel/blk_drv/blk.h
---- pl12/linux/kernel/blk_drv/blk.h	Sat Aug 14 23:47:22 1993
-+++ linux/kernel/blk_drv/blk.h	Sat Sep  4 03:21:32 1993
-@@ -3,6 +3,7 @@
- 
- #include <linux/sched.h>
- #include <linux/locks.h>
-+#include <linux/genhd.h>
- 
- /*
-  * NR_REQUEST is the number of entries in the request-queue.
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/genhd.c linux/kernel/blk_drv/genhd.c
---- pl12/linux/kernel/blk_drv/genhd.c	Sat Jul  3 03:01:45 1993
-+++ linux/kernel/blk_drv/genhd.c	Sat Sep  4 03:22:38 1993
-@@ -194,7 +194,7 @@
- }
- 	
- /* This may be used only once, enforced by 'static int callable' */
--extern "C" int sys_setup(void * BIOS)
-+asmlinkage int sys_setup(void * BIOS)
- {
- 	static int callable = 1;
- 	struct gendisk *p;
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/hd.c linux/kernel/blk_drv/hd.c
---- pl12/linux/kernel/blk_drv/hd.c	Wed Jul 28 00:19:32 1993
-+++ linux/kernel/blk_drv/hd.c	Wed Sep  1 17:04:43 1993
-@@ -559,7 +559,7 @@
- 		case BLKFLSBUF:
- 			if(!suser())  return -EACCES;
- 			if(!inode->i_rdev) return -EINVAL;
--			sync_dev(inode->i_rdev);
-+			fsync_dev(inode->i_rdev);
- 			invalidate_buffers(inode->i_rdev);
- 			return 0;
- 
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/ramdisk.c linux/kernel/blk_drv/ramdisk.c
---- pl12/linux/kernel/blk_drv/ramdisk.c	Wed Aug  4 22:38:40 1993
-+++ linux/kernel/blk_drv/ramdisk.c	Sat Sep  4 01:48:21 1993
-@@ -37,7 +37,8 @@
- repeat:
- 	INIT_REQUEST;
- 	addr = rd_start + (CURRENT->sector << 9);
--	len = CURRENT->nr_sectors << 9;
-+	len = CURRENT->current_nr_sectors << 9;
-+
- 	if ((MINOR(CURRENT->dev) != MINOR_RAMDISK) ||
- 	    (addr+len > rd_start+rd_length)) {
- 		end_request(0);
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/aha1542.c linux/kernel/blk_drv/scsi/aha1542.c
---- pl12/linux/kernel/blk_drv/scsi/aha1542.c	Wed Jul 28 00:19:32 1993
-+++ linux/kernel/blk_drv/scsi/aha1542.c	Sat Sep  4 01:48:21 1993
-@@ -15,6 +15,7 @@
- #include <linux/head.h>
- #include <linux/types.h>
- #include <linux/string.h>
-+#include <linux/ioport.h>
- 
- #include <linux/sched.h>
- #include <asm/dma.h>
-@@ -663,8 +664,10 @@
-     
-     indx = 0;
-     while(indx < sizeof(bases)/sizeof(bases[0])){
--      i = aha1542_test_port(bases[indx]);
--      if (i) break;
-+      if(!check_region(bases[indx], 4)){
-+	i = aha1542_test_port(bases[indx]);
-+	if (i) break;
-+      };
-       indx++;
-     }
-     if (indx == sizeof(bases)/sizeof(bases[0])) return 0;
-@@ -755,6 +758,7 @@
- 	  aha1542_command(0, cmd, buffer, 512);
-       }
- #endif
-+    snarf_region(bases[indx], 4);  /* Register the IO ports that we use */
-     aha1542_host = hostnum;
-     return 1;
- }
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/aha1740.c linux/kernel/blk_drv/scsi/aha1740.c
---- pl12/linux/kernel/blk_drv/scsi/aha1740.c	Wed Jul 28 00:19:32 1993
-+++ linux/kernel/blk_drv/scsi/aha1740.c	Sat Sep  4 01:48:21 1993
-@@ -21,6 +21,7 @@
- #include <linux/head.h>
- #include <linux/types.h>
- #include <linux/string.h>
-+#include <linux/ioport.h>
- 
- #include <linux/sched.h>
- #include <asm/dma.h>
-@@ -432,6 +433,12 @@
-     for ( slot=MINEISA; slot <= MAXEISA; slot++ )
-     {
- 	base = SLOTBASE(slot);
-+
-+	/* The ioports for eisa boards are generally beyond that used in the
-+	   check,snarf_region code, but this may change at some point, so we
-+	   go through the motions. */
-+
-+	if(check_region(base, 0x5c)) continue;  /* See if in use */
- 	if ( aha1740_test_port())  break;
-     }
-     if ( slot > MAXEISA )
-@@ -455,6 +462,7 @@
-         printk("Unable to allocate IRQ for adaptec controller.\n");
-         return 0;
-     }
-+    snarf_region(base, 0x5c);  /* Reserve the space that we need to use */
-     return 1;
- }
- 
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/fdomain.c linux/kernel/blk_drv/scsi/fdomain.c
---- pl12/linux/kernel/blk_drv/scsi/fdomain.c	Sat Aug 14 09:05:16 1993
-+++ linux/kernel/blk_drv/scsi/fdomain.c	Sat Sep  4 01:48:21 1993
-@@ -138,6 +138,7 @@
- #include <asm/system.h>
- #include <linux/errno.h>
- #include <linux/string.h>
-+#include <linux/ioport.h>
- 
- #define VERSION          "$Revision: 3.18 $"
- 
-@@ -528,6 +529,8 @@
- 
-       for (i = 0; !flag && i < PORT_COUNT; i++) {
- 	 port_base = ports[i];
-+	 if(check_region(port_base, 0x10)) continue;  /* skip if I/O port in
-+							 use */
- #if DEBUG_DETECT
- 	 printk( " %x,", port_base );
- #endif
-@@ -607,6 +610,8 @@
-       scsi_hosts[this_host].this_id = 7;
-    }
-    
-+   snarf_region(port_base, 0x10);  /* Register */
-+
- #if DO_DETECT
- 
-    /* These routines are here because of the way the SCSI bus behaves after
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/scsi.c linux/kernel/blk_drv/scsi/scsi.c
---- pl12/linux/kernel/blk_drv/scsi/scsi.c	Sun Aug 15 10:55:23 1993
-+++ linux/kernel/blk_drv/scsi/scsi.c	Sat Sep  4 01:48:22 1993
-@@ -68,6 +68,7 @@
- #define WAS_TIMEDOUT 	0x02
- #define WAS_SENSE	0x04
- #define IS_RESETTING	0x08
-+#define ASKED_FOR_SENSE 0x10
- 
- extern int last_reset[];
- 
-@@ -661,7 +662,7 @@
- static void scsi_request_sense (Scsi_Cmnd * SCpnt)
- 	{
- 	cli();
--	SCpnt->flags |= WAS_SENSE;
-+	SCpnt->flags |= WAS_SENSE | ASKED_FOR_SENSE;
- 	update_timeout(SCpnt, SENSE_TIMEOUT);
- 	sti();
- 	
-@@ -805,9 +806,17 @@
- 
- static int check_sense (Scsi_Cmnd * SCpnt)
- 	{
--  /* If there is no sense information, request it.  */
--  if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7)
--    return SUGGEST_SENSE;
-+  /* If there is no sense information, request it.  If we have already
-+     requested it, there is no point in asking again - the firmware must be
-+     confused. */
-+  if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7) {
-+    if(!SCpnt->flags & ASKED_FOR_SENSE)
-+      return SUGGEST_SENSE;
-+    else
-+      return SUGGEST_RETRY;
-+      }
-+  
-+  SCpnt->flags &= ~ASKED_FOR_SENSE;
- 
- #ifdef DEBUG_INIT
- 	printk("scsi%d : ", SCpnt->host);
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/sd.c linux/kernel/blk_drv/scsi/sd.c
---- pl12/linux/kernel/blk_drv/scsi/sd.c	Wed Aug 11 22:36:48 1993
-+++ linux/kernel/blk_drv/scsi/sd.c	Sat Sep  4 01:48:22 1993
-@@ -324,6 +324,7 @@
- 
-     INIT_SCSI_REQUEST;
- 
-+
- /* We have to be careful here.  allocate_device will get a free pointer, but
-    there is no guarantee that it is queueable.  In normal usage, we want to
-    call this, because other types of devices may have the host all tied up,
-@@ -668,6 +669,7 @@
-   int j = 0;
-   unsigned char cmd[10];
-   unsigned char *buffer;
-+  char spintime;
-   int the_result, retries;
-   Scsi_Cmnd * SCpnt;
- 
-@@ -677,6 +679,58 @@
- 
-   SCpnt = allocate_device(NULL, rscsi_disks[i].device->index, 1);
-   buffer = (unsigned char *) scsi_malloc(512);
-+
-+  spintime = 0;
-+
-+  /* Spin up drives, as required.  Only do this at boot time */
-+  if (current == task[0]){
-+    do{
-+      cmd[0] = TEST_UNIT_READY;
-+      cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
-+      memset ((void *) &cmd[2], 0, 8);
-+      SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
-+      SCpnt->sense_buffer[0] = 0;
-+      SCpnt->sense_buffer[2] = 0;
-+      
-+      scsi_do_cmd (SCpnt,
-+		   (void *) cmd, (void *) buffer,
-+		   512, sd_init_done,  SD_TIMEOUT,
-+		   MAX_RETRIES);
-+      
-+      while(SCpnt->request.dev != 0xfffe);
-+      
-+      the_result = SCpnt->result;
-+      
-+      /* Look for non-removable devices that return NOT_READY.  Issue command
-+	 to spin up drive for these cases. */
-+      if(the_result && !rscsi_disks[i].device->removable && 
-+	 SCpnt->sense_buffer[2] == NOT_READY) {
-+	int time1;
-+	if(!spintime){
-+	  cmd[0] = START_STOP;
-+	  cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
-+	  memset ((void *) &cmd[2], 0, 8);
-+	  cmd[4] = 1; /* Start spin cycle */
-+	  SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
-+	  SCpnt->sense_buffer[0] = 0;
-+	  SCpnt->sense_buffer[2] = 0;
-+	  
-+	  scsi_do_cmd (SCpnt,
-+		       (void *) cmd, (void *) buffer,
-+		       512, sd_init_done,  SD_TIMEOUT,
-+		       MAX_RETRIES);
-+	  
-+	  while(SCpnt->request.dev != 0xfffe);
-+
-+	  spintime = jiffies;
-+	};
-+
-+	time1 = jiffies;
-+	while(jiffies < time1 + 100); /* Wait 1 second for next try */
-+      };
-+    } while(the_result && spintime && spintime < jiffies+1500);
-+  };  /* current == task[0] */
-+
- 
-   retries = 3;
-   do {
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/sd_ioctl.c linux/kernel/blk_drv/scsi/sd_ioctl.c
---- pl12/linux/kernel/blk_drv/scsi/sd_ioctl.c	Wed Jul 28 00:19:33 1993
-+++ linux/kernel/blk_drv/scsi/sd_ioctl.c	Wed Sep  1 17:04:43 1993
-@@ -55,7 +55,7 @@
- 		case BLKFLSBUF:
- 			if(!suser())  return -EACCES;
- 			if(!inode->i_rdev) return -EINVAL;
-- 			sync_dev(inode->i_rdev);
-+ 			fsync_dev(inode->i_rdev);
- 			invalidate_buffers(inode->i_rdev);
- 			return 0;
- 
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/seagate.c linux/kernel/blk_drv/scsi/seagate.c
---- pl12/linux/kernel/blk_drv/scsi/seagate.c	Sat Aug  7 11:27:00 1993
-+++ linux/kernel/blk_drv/scsi/seagate.c	Sat Sep  4 01:48:22 1993
-@@ -10,6 +10,8 @@
-  * 	Note : TMC-880 boards don't work because they have two bits in 
-  *		the status register flipped, I'll fix this "RSN"
-  *
-+ *      This card does all the I/O via memory mapped I/O, so there is no need
-+ *      to check or snarf a region of the I/O address space.
-  */
- 
- /*
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/st.c linux/kernel/blk_drv/scsi/st.c
---- pl12/linux/kernel/blk_drv/scsi/st.c	Wed Aug 11 22:36:49 1993
-+++ linux/kernel/blk_drv/scsi/st.c	Sun Aug 29 23:07:52 1993
-@@ -127,9 +127,11 @@
- /* Convert the result to success code */
- static int st_chk_result(Scsi_Cmnd * SCpnt)
- {
-+#ifdef DEBUG
-   int dev = SCpnt->request.dev;
-+#endif
-   int result = SCpnt->result;
--  char * sense = SCpnt->sense_buffer;
-+  unsigned char * sense = SCpnt->sense_buffer;
- 
-   if (!result)
-     return 0;
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/ultrastor.c linux/kernel/blk_drv/scsi/ultrastor.c
---- pl12/linux/kernel/blk_drv/scsi/ultrastor.c	Wed Jul 28 00:19:35 1993
-+++ linux/kernel/blk_drv/scsi/ultrastor.c	Sat Sep  4 01:48:22 1993
-@@ -43,6 +43,7 @@
- #include <linux/string.h>
- #include <linux/sched.h>
- #include <linux/kernel.h>
-+#include <linux/ioport.h>
- 
- #include <asm/io.h>
- #include <asm/system.h>
-@@ -194,6 +195,12 @@
-     PORT_ADDRESS = 0;
-     for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
- 	PORT_ADDRESS = ultrastor_ports_14f[i];
-+	if(check_region(PORT_ADDRESS, 4)) continue;
-+#else
-+	if(check_region(PORT_ADDRESS, 4)) {
-+	  printk("Ultrastor I/O space already in use\n");
-+	  return FALSE;
-+	};
- #endif
- 
- #if (ULTRASTOR_DEBUG & UD_DETECT)
-@@ -248,6 +255,7 @@
- 	   PORT_ADDRESS);
- #endif
- 
-+    snarf_region(PORT_ADDRESS, 4); /* Register the I/O space that we use */
-     /* All above tests passed, must be the right thing.  Get some useful
-        info. */
-     *(char *)&config_1 = inb(CONFIG(PORT_ADDRESS + 0));
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/wd7000.c linux/kernel/blk_drv/scsi/wd7000.c
---- pl12/linux/kernel/blk_drv/scsi/wd7000.c	Sat Jul  3 03:40:30 1993
-+++ linux/kernel/blk_drv/scsi/wd7000.c	Sat Sep  4 01:48:23 1993
-@@ -20,6 +20,8 @@
- #include <asm/system.h>
- #include <asm/dma.h>
- #include <asm/io.h>
-+#include <linux/ioport.h>
-+
- #include "../blk.h"
- #include "scsi.h"
- #include "hosts.h"
-@@ -526,6 +528,7 @@
-     int i,j;
-     char const *base_address = NULL;
- 
-+    if(check_region(IO_BASE, 4)) return 0;  /* IO ports in use */
-     for(i=0;i<(sizeof(wd_bases)/sizeof(char *));i++){
- 	for(j=0;j<NUM_SIGNATURES;j++){
- 	    if(!memcmp((void *)(wd_bases[i] + signatures[j].offset),
-@@ -537,6 +540,7 @@
-     }
-     if (base_address == NULL) return 0;
- 
-+    snarf_region(IO_BASE, 4); /* Register our ports */
-     /* Store our host number */
-     wd7000_host = hostnum;
- 
-diff -u --recursive --new-file pl12/linux/kernel/blk_drv/xd.c linux/kernel/blk_drv/xd.c
---- pl12/linux/kernel/blk_drv/xd.c	Wed Jul 28 00:19:35 1993
-+++ linux/kernel/blk_drv/xd.c	Wed Sep  1 17:04:43 1993
-@@ -222,7 +222,7 @@
- 			case BLKFLSBUF:
- 				if(!suser())  return -EACCES;
- 				if(!inode->i_rdev) return -EINVAL;
--				sync_dev(inode->i_rdev);
-+				fsync_dev(inode->i_rdev);
- 				invalidate_buffers(inode->i_rdev);
- 				return 0;
- 				
-diff -u --recursive --new-file pl12/linux/kernel/chr_drv/keyboard.c linux/kernel/chr_drv/keyboard.c
---- pl12/linux/kernel/chr_drv/keyboard.c	Sat Aug 14 18:52:34 1993
-+++ linux/kernel/chr_drv/keyboard.c	Wed Sep  1 09:04:14 1993
-@@ -65,7 +65,11 @@
- unsigned long kbd_dead_keys = 0;
- unsigned long kbd_prev_dead_keys = 0;
- 
-+/* shift state counters.. */
- static unsigned char k_down[NR_SHIFT] = {0, };
-+/* keyboard key bitmap */
-+static unsigned long key_down[8] = { 0, };
-+
- static int want_console = -1;
- static int last_console = 0;		/* last used VC */
- static char rep = 0;			/* flag telling character repeat */
-@@ -149,6 +153,7 @@
- 	kbd = kbd_table + fg_console;
- 	if (vc_kbd_flag(kbd,VC_RAW)) {
- 		memset(k_down, 0, sizeof(k_down));
-+		memset(key_down, 0, sizeof(key_down));
- 		put_queue(scancode);
- 		goto end_kbd_intr;
- 	} else
-@@ -160,7 +165,6 @@
- static inline void translate(unsigned char scancode)
- {
- 	char break_flag;
--	static unsigned long key_down[8] = { 0, };
-      	static unsigned char e0_keys[] = {
- 		0x1c,	/* keypad enter */
- 		0x1d,	/* right control */
-@@ -584,6 +588,8 @@
- 		value = KVAL(K_SHIFT);
- 		clr_vc_kbd_flag(kbd, VC_CAPSLOCK);
- 	}
-+	if (value > 3)
-+		return;
- 
- 	if (up_flag) {
- 		if (k_down[value])
-diff -u --recursive --new-file pl12/linux/kernel/chr_drv/mem.c linux/kernel/chr_drv/mem.c
---- pl12/linux/kernel/chr_drv/mem.c	Mon Aug  9 18:02:32 1993
-+++ linux/kernel/chr_drv/mem.c	Sat Aug 21 10:19:32 1993
-@@ -129,12 +129,28 @@
- static int mmap_mem(struct inode * inode, struct file * file,
- 	unsigned long addr, size_t len, int prot, unsigned long off)
- {
-+	struct vm_area_struct * mpnt;
-+
- 	if (off & 0xfff || off + len < off)
- 		return -ENXIO;
--
- 	if (remap_page_range(addr, off, len, prot))
- 		return -EAGAIN;
--	
-+/* try to create a dummy vmm-structure so that the rest of the kernel knows we are here */
-+	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
-+	if (!mpnt)
-+		return 0;
-+
-+	mpnt->vm_task = current;
-+	mpnt->vm_start = addr;
-+	mpnt->vm_end = addr + len;
-+	mpnt->vm_page_prot = prot;
-+	mpnt->vm_share = NULL;
-+	mpnt->vm_inode = inode;
-+	inode->i_count++;
-+	mpnt->vm_offset = off;
-+	mpnt->vm_ops = NULL;
-+	mpnt->vm_next = current->mmap;
-+	current->mmap = mpnt;
- 	return 0;
- }
- 
-diff -u --recursive --new-file pl12/linux/kernel/chr_drv/serial.c linux/kernel/chr_drv/serial.c
---- pl12/linux/kernel/chr_drv/serial.c	Fri Aug 13 21:20:52 1993
-+++ linux/kernel/chr_drv/serial.c	Wed Aug 18 01:13:23 1993
-@@ -1321,12 +1321,10 @@
- 	
- 	switch (cmd) {
- 		case TCSBRK:	/* SVID version: non-zero arg --> no break */
--			wait_until_sent(tty);
- 			if (!arg)
- 				send_break(info, HZ/4);	/* 1/4 second */
- 			return 0;
- 		case TCSBRKP:	/* support for POSIX tcsendbreak() */
--			wait_until_sent(tty);
- 			send_break(info, arg ? arg*(HZ/10) : HZ/4);
- 			return 0;
- 		case TIOCGSOFTCAR:
-diff -u --recursive --new-file pl12/linux/kernel/chr_drv/tty_ioctl.c linux/kernel/chr_drv/tty_ioctl.c
---- pl12/linux/kernel/chr_drv/tty_ioctl.c	Thu Jul 29 12:15:25 1993
-+++ linux/kernel/chr_drv/tty_ioctl.c	Wed Aug 18 01:13:07 1993
-@@ -605,7 +605,12 @@
- 			     tty->packet = 0;
- 			   return (0);
- 			}
--
-+		case TCSBRK: case TCSBRKP:
-+			wait_until_sent(tty);
-+			if (!tty->ioctl)
-+				return 0;
-+			tty->ioctl(tty, file, cmd, arg);
-+			return 0;
- 		default:
- 			if (tty->ioctl) {
- 				retval = (tty->ioctl)(tty, file, cmd, arg);
-diff -u --recursive --new-file pl12/linux/kernel/chr_drv/vt.c linux/kernel/chr_drv/vt.c
---- pl12/linux/kernel/chr_drv/vt.c	Sat Jul 31 20:32:36 1993
-+++ linux/kernel/chr_drv/vt.c	Sat Sep  4 03:17:54 1993
-@@ -35,7 +35,7 @@
- 
- struct vt_cons vt_cons[NR_CONSOLES];
- 
--extern "C" int sys_ioperm(unsigned long from, unsigned long num, int on);
-+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
- 
- extern void change_console(unsigned int new_console);
- extern void complete_change_console(unsigned int new_console);
-diff -u --recursive --new-file pl12/linux/kernel/exit.c linux/kernel/exit.c
---- pl12/linux/kernel/exit.c	Mon Aug  2 18:16:26 1993
-+++ linux/kernel/exit.c	Sat Sep  4 03:04:34 1993
-@@ -274,7 +274,7 @@
-  * POSIX specifies that kill(-1,sig) is unspecified, but what we have
-  * is probably wrong.  Should make it like BSD or SYSV.
-  */
--extern "C" int sys_kill(int pid,int sig)
-+asmlinkage int sys_kill(int pid,int sig)
- {
- 	int err, retval = 0, count = 0;
- 
-@@ -376,7 +376,7 @@
- 		current->mmap = NULL;
- 		while (mpnt) {
- 			mpnt1 = mpnt->vm_next;
--			if (mpnt->vm_ops->close)
-+			if (mpnt->vm_ops && mpnt->vm_ops->close)
- 				mpnt->vm_ops->close(mpnt);
- 			kfree(mpnt);
- 			mpnt = mpnt1;
-@@ -491,12 +491,12 @@
- 	goto fake_volatile;
- }
- 
--extern "C" int sys_exit(int error_code)
-+asmlinkage int sys_exit(int error_code)
- {
- 	do_exit((error_code&0xff)<<8);
- }
- 
--extern "C" int sys_wait4(pid_t pid,unsigned long * stat_addr, int options, struct rusage * ru)
-+asmlinkage int sys_wait4(pid_t pid,unsigned long * stat_addr, int options, struct rusage * ru)
- {
- 	int flag, retval;
- 	struct wait_queue wait = { current, NULL };
-@@ -587,7 +587,7 @@
-  * sys_waitpid() remains for compatibility. waitpid() should be
-  * implemented by calling sys_wait4() from libc.a.
-  */
--extern "C" int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
-+asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
- {
- 	return sys_wait4(pid, stat_addr, options, NULL);
- }
-diff -u --recursive --new-file pl12/linux/kernel/fork.c linux/kernel/fork.c
---- pl12/linux/kernel/fork.c	Mon Aug  9 17:41:24 1993
-+++ linux/kernel/fork.c	Sat Sep  4 03:01:14 1993
-@@ -23,7 +23,7 @@
- #include <asm/segment.h>
- #include <asm/system.h>
- 
--extern "C" void ret_from_sys_call(void) __asm__("ret_from_sys_call");
-+asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
- 
- #define MAX_TASKS_PER_USER (NR_TASKS/2)
- 
-@@ -113,7 +113,7 @@
-  * information (task[nr]) and sets up the necessary registers. It
-  * also copies the data segment in it's entirety.
-  */
--extern "C" int sys_fork(struct pt_regs regs)
-+asmlinkage int sys_fork(struct pt_regs regs)
- {
- 	struct pt_regs * childregs;
- 	struct task_struct *p;
-@@ -176,7 +176,7 @@
- 	p->exit_signal = clone_flags & CSIGNAL;
- 	p->tss.ldt = _LDT(nr);
- 	if (p->ldt) {
--		if (p->ldt = (struct desc_struct*) __get_free_page(GFP_KERNEL))
-+		if ((p->ldt = (struct desc_struct*) __get_free_page(GFP_KERNEL)) != NULL)
- 			memcpy(p->ldt, current->ldt, PAGE_SIZE);
- 	}
- 	p->tss.bitmap = offsetof(struct tss_struct,io_bitmap);
-diff -u --recursive --new-file pl12/linux/kernel/info.c linux/kernel/info.c
---- pl12/linux/kernel/info.c	Sat Jul  3 01:02:33 1993
-+++ linux/kernel/info.c	Sat Sep  4 03:11:09 1993
-@@ -14,7 +14,7 @@
- #include <linux/types.h>
- #include <linux/mm.h>
- 
--extern "C" int sys_sysinfo(struct sysinfo *info)
-+asmlinkage int sys_sysinfo(struct sysinfo *info)
- {
- 	int error;
- 	struct sysinfo val;
-diff -u --recursive --new-file pl12/linux/kernel/ioport.c linux/kernel/ioport.c
---- pl12/linux/kernel/ioport.c	Wed Jul 14 19:07:28 1993
-+++ linux/kernel/ioport.c	Sat Sep  4 03:10:28 1993
-@@ -9,7 +9,10 @@
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/types.h>
-+#include <linux/ioport.h>
- 
-+static unsigned long ioport_registrar[IO_BITMAP_SIZE] = {0, /* ... */};
-+
- #define _IODEBUG
- 
- #ifdef IODEBUG
-@@ -40,14 +43,76 @@
- }
- #endif
- 
-+/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
-+asmlinkage void set_bitmap(unsigned long *bitmap,
-+						   short base, short extent, int new_value)
-+{
-+	int mask;
-+	unsigned long *bitmap_base = bitmap + (base >> 5);
-+	unsigned short low_index = base & 0x1f;
-+	int length = low_index + extent;
-+
-+	if (low_index != 0) {
-+		mask = (~0 << low_index);
-+		if (length < 32)
-+				mask &= ~(~0 << length);
-+		if (new_value)
-+			*bitmap_base++ |= mask;
-+		else
-+			*bitmap_base++ &= ~mask;
-+		length -= 32;
-+	}
-+
-+	mask = (new_value ? ~0 : 0);
-+	while (length >= 32) {
-+		*bitmap_base++ = mask;
-+		length -= 32;
-+	}
-+
-+	if (length > 0) {
-+		mask = ~(~0 << length);
-+		if (new_value)
-+			*bitmap_base++ |= mask;
-+		else
-+			*bitmap_base++ &= ~mask;
-+	}
-+}
-+
-+/* Check for set bits in BITMAP starting at BASE, going to EXTENT. */
-+asmlinkage int check_bitmap(unsigned long *bitmap, short base, short extent)
-+{
-+	int mask;
-+	unsigned long *bitmap_base = bitmap + (base >> 5);
-+	unsigned short low_index = base & 0x1f;
-+	int length = low_index + extent;
-+
-+	if (low_index != 0) {
-+		mask = (~0 << low_index);
-+		if (length < 32)
-+				mask &= ~(~0 << length);
-+		if (*bitmap_base++ & mask)
-+			return 1;
-+		length -= 32;
-+	}
-+	while (length >= 32) {
-+		if (*bitmap_base++ != 0)
-+			return 1;
-+		length -= 32;
-+	}
-+
-+	if (length > 0) {
-+		mask = ~(~0 << length);
-+		if (*bitmap_base++ & mask)
-+			return 1;
-+	}
-+	return 0;
-+}
-+
- /*
-  * this changes the io permissions bitmap in the current task.
-  */
--extern "C" int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
-+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
- {
--	unsigned long froml, lindex, tnum, numl, rindex, mask;
--	unsigned long *iop;
--
- 	if (from + num <= from)
- 		return -EINVAL;
- 	if (from + num > IO_BITMAP_SIZE*32)
-@@ -54,42 +119,11 @@
- 		return -EINVAL;
- 	if (!suser())
- 		return -EPERM;
--	froml = from >> 5;
--	lindex = from & 0x1f;
--	tnum = lindex + num;
--	numl = (tnum + 0x1f) >> 5;
--	rindex = tnum & 0x1f;
- 
- #ifdef IODEBUG
- 	printk("io: from=%d num=%d %s\n", from, num, (turn_on ? "on" : "off"));
- #endif
--
--	if (numl) {
--		iop = (unsigned long *)current->tss.io_bitmap + froml;
--		if (lindex != 0) {
--			mask = (~0 << lindex);
--			if (--numl == 0 && rindex)
--				mask &= ~(~0 << rindex);
--			if (turn_on)
--				*iop++ &= ~mask;
--			else
--				*iop++ |= mask;
--		}
--		if (numl) {
--			if (rindex)
--				--numl;
--			mask = (turn_on ? 0 : ~0);
--			while (numl--)
--				*iop++ = mask;
--			if (numl && rindex) {
--				mask = ~(~0 << rindex);
--				if (turn_on)
--					*iop++ &= ~mask;
--				else
--					*iop++ |= mask;
--			}
--		}
--	}
-+	set_bitmap((unsigned long *)current->tss.io_bitmap, from, num, !turn_on);
- 	return 0;
- }
- 
-@@ -105,7 +139,7 @@
-  * on system-call entry - see also fork() and the signal handling
-  * code.
-  */
--extern "C" int sys_iopl(long ebx,long ecx,long edx,
-+asmlinkage int sys_iopl(long ebx,long ecx,long edx,
- 	     long esi, long edi, long ebp, long eax, long ds,
- 	     long es, long fs, long gs, long orig_eax,
- 	     long eip,long cs,long eflags,long esp,long ss)
-@@ -118,4 +152,33 @@
- 		return -EPERM;
- 	*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
- 	return 0;
-+}
-+
-+
-+void snarf_region(unsigned int from, unsigned int num)
-+{
-+	if (from > IO_BITMAP_SIZE*32)
-+		return;
-+	if (from + num > IO_BITMAP_SIZE*32)
-+		num = IO_BITMAP_SIZE*32 - from;
-+	set_bitmap(ioport_registrar, from, num, 1);
-+	return;
-+}
-+
-+int check_region(unsigned int from, unsigned int num)
-+{
-+	if (from > IO_BITMAP_SIZE*32)
-+		return 0;
-+	if (from + num > IO_BITMAP_SIZE*32)
-+		num = IO_BITMAP_SIZE*32 - from;
-+	return check_bitmap(ioport_registrar, from, num);
-+}
-+
-+/* Called from init/main.c to reserve IO ports. */
-+void reserve_setup(char *str, int *ints)
-+{
-+	int i;
-+
-+	for (i = 1; i < ints[0]; i += 2)
-+		snarf_region(ints[i], ints[i+1]);
- }
-diff -u --recursive --new-file pl12/linux/kernel/irq.c linux/kernel/irq.c
---- pl12/linux/kernel/irq.c	Sun Jul 18 16:01:35 1993
-+++ linux/kernel/irq.c	Sat Sep  4 02:59:06 1993
-@@ -47,7 +47,7 @@
-  * enabled.  do_bottom_half() is atomic with respect to itself: a
-  * bottom_half handler need not be re-entrant.
-  */
--extern "C" void do_bottom_half(void)
-+asmlinkage void do_bottom_half(void)
- {
- 	unsigned long active;
- 	unsigned long mask, left;
-@@ -156,7 +156,7 @@
-  * IRQ's should use this format: notably the keyboard/timer
-  * routines.
-  */
--extern "C" void do_IRQ(int irq, struct pt_regs * regs)
-+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
- {
- 	struct sigaction * sa = irq + irq_sigaction;
- 
-@@ -168,7 +168,7 @@
-  * stuff - the handler is also running with interrupts disabled unless
-  * it explicitly enables them later.
-  */
--extern "C" void do_fast_IRQ(int irq)
-+asmlinkage void do_fast_IRQ(int irq)
- {
- 	struct sigaction * sa = irq + irq_sigaction;
- 
-diff -u --recursive --new-file pl12/linux/kernel/itimer.c linux/kernel/itimer.c
---- pl12/linux/kernel/itimer.c	Sat Jul  3 01:01:39 1993
-+++ linux/kernel/itimer.c	Sat Sep  4 03:10:51 1993
-@@ -53,7 +53,7 @@
- 	return(0);
- }
- 
--extern "C" int sys_getitimer(int which, struct itimerval *value)
-+asmlinkage int sys_getitimer(int which, struct itimerval *value)
- {
- 	int error;
- 	struct itimerval get_buffer;
-@@ -98,7 +98,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
-+asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
- {
- 	int error;
- 	struct itimerval set_buffer, get_buffer;
-diff -u --recursive --new-file pl12/linux/kernel/ldt.c linux/kernel/ldt.c
---- pl12/linux/kernel/ldt.c	Mon Aug  9 18:02:32 1993
-+++ linux/kernel/ldt.c	Sat Sep  4 03:11:30 1993
-@@ -86,7 +86,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-+asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
- {
- 	if (func == 0)
- 		return read_ldt(ptr, bytecount);
-diff -u --recursive --new-file pl12/linux/kernel/panic.c linux/kernel/panic.c
---- pl12/linux/kernel/panic.c	Sat Jul  3 01:03:15 1993
-+++ linux/kernel/panic.c	Sat Sep  4 03:01:42 1993
-@@ -11,7 +11,7 @@
- #include <linux/kernel.h>
- #include <linux/sched.h>
- 
--extern "C" void sys_sync(void);	/* it's really int */
-+asmlinkage void sys_sync(void);	/* it's really int */
- 
- volatile void panic(const char * s)
- {
-diff -u --recursive --new-file pl12/linux/kernel/printk.c linux/kernel/printk.c
---- pl12/linux/kernel/printk.c	Mon Aug  9 18:02:32 1993
-+++ linux/kernel/printk.c	Sat Sep  4 03:04:18 1993
-@@ -47,7 +47,7 @@
-  * 	6 -- Disable printk's to console
-  * 	7 -- Enable printk's to console
-  */
--extern "C" int sys_syslog(int type, char * buf, int len)
-+asmlinkage int sys_syslog(int type, char * buf, int len)
- {
- 	unsigned long i, j, count;
- 	int do_clear = 0;
-@@ -104,7 +104,7 @@
- 				count = logged_chars;
- 			j = log_start + log_size - count;
- 			for (i = 0; i < count; i++) {
--				c = *((char *) log_buf + (j++ & LOG_BUF_LEN-1));
-+				c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1)));
- 				put_fs_byte(c, buf++);
- 			}
- 			if (do_clear)
-@@ -124,7 +124,7 @@
- }
- 			
- 
--extern "C" int printk(const char *fmt, ...)
-+asmlinkage int printk(const char *fmt, ...)
- {
- 	va_list args;
- 	int i,j;
-@@ -133,7 +133,7 @@
- 	i=vsprintf(buf,fmt,args);
- 	va_end(args);
- 	for (j = 0; j < i ; j++) {
--		log_buf[(log_start+log_size) & LOG_BUF_LEN-1] = buf[j];
-+		log_buf[(log_start+log_size) & (LOG_BUF_LEN-1)] = buf[j];
- 		if (log_size < LOG_BUF_LEN)
- 			log_size++;
- 		else
-diff -u --recursive --new-file pl12/linux/kernel/ptrace.c linux/kernel/ptrace.c
---- pl12/linux/kernel/ptrace.c	Mon Aug  9 18:02:32 1993
-+++ linux/kernel/ptrace.c	Sat Sep  4 03:10:15 1993
-@@ -152,7 +152,7 @@
- 	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- 		low = get_long(tsk,addr & ~(sizeof(long)-1));
- 		high = get_long(tsk,(addr+sizeof(long)) & ~(sizeof(long)-1));
--		switch (addr & sizeof(long)-1) {
-+		switch (addr & (sizeof(long)-1)) {
- 			case 1:
- 				low >>= 8;
- 				low |= high << 24;
-@@ -186,7 +186,7 @@
- 	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- 		low = get_long(tsk,addr & ~(sizeof(long)-1));
- 		high = get_long(tsk,(addr+sizeof(long)) & ~(sizeof(long)-1));
--		switch (addr & sizeof(long)-1) {
-+		switch (addr & (sizeof(long)-1)) {
- 			case 0: /* shouldn't happen, but safety first */
- 				low = data;
- 				break;
-@@ -216,7 +216,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_ptrace(long request, long pid, long addr, long data)
-+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
- {
- 	struct task_struct *child;
- 
-@@ -285,6 +285,10 @@
- 			if (res)
- 				return res;
- 			tmp = get_stack_long(child, sizeof(long)*addr - MAGICNUMBER);
-+			if (addr == DS || addr == ES ||
-+			    addr == FS || addr == GS ||
-+			    addr == CS || addr == SS)
-+				tmp &= 0xffff;
- 			put_fs_long(tmp,(unsigned long *) data);
- 			return 0;
- 		}
-@@ -302,8 +306,11 @@
- 				return -EIO;
- 			if (addr == DS || addr == ES ||
- 			    addr == FS || addr == GS ||
--			    addr == CS || addr == SS)
--				return -EIO;
-+			    addr == CS || addr == SS) {
-+			    	data &= 0xffff;
-+			    	if (data && (data & 3) != 3)
-+					return -EIO;
-+			}
- 			if (addr == EFL) {   /* flags. */
- 				data &= FLAG_MASK;
- 				data |= get_stack_long(child, EFL*sizeof(long)-MAGICNUMBER)  & ~FLAG_MASK;
-@@ -382,7 +389,7 @@
- 	}
- }
- 
--extern "C" void syscall_trace(void)
-+asmlinkage void syscall_trace(void)
- {
- 	if ((current->flags & (PF_PTRACED|PF_TRACESYS))
- 			!= (PF_PTRACED|PF_TRACESYS))
-diff -u --recursive --new-file pl12/linux/kernel/sched.c linux/kernel/sched.c
---- pl12/linux/kernel/sched.c	Mon Aug  9 18:02:32 1993
-+++ linux/kernel/sched.c	Sat Sep  4 02:45:09 1993
-@@ -51,7 +51,7 @@
- extern void mem_use(void);
- 
- extern int timer_interrupt(void);
--extern "C" int system_call(void);
-+asmlinkage int system_call(void);
- 
- static unsigned long init_kernel_stack[1024];
- struct task_struct init_task = INIT_TASK;
-@@ -82,7 +82,7 @@
-  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
-  * Don't touch unless you *really* know how it works.
-  */
--extern "C" void math_state_restore(void)
-+asmlinkage void math_state_restore(void)
- {
- 	__asm__ __volatile__("clts");
- 	if (last_task_used_math == current)
-@@ -115,7 +115,7 @@
-  * The "confuse_gcc" goto is used only to get better assembly code..
-  * Djikstra probably hates me.
-  */
--extern "C" void schedule(void)
-+asmlinkage void schedule(void)
- {
- 	int c;
- 	struct task_struct * p;
-@@ -160,7 +160,7 @@
- 	switch_to(next);
- }
- 
--extern "C" int sys_pause(void)
-+asmlinkage int sys_pause(void)
- {
- 	current->state = TASK_INTERRUPTIBLE;
- 	schedule();
-@@ -421,7 +421,7 @@
- 	sti();
- }
- 
--extern "C" int sys_alarm(long seconds)
-+asmlinkage int sys_alarm(long seconds)
- {
- 	struct itimerval it_new, it_old;
- 
-@@ -432,37 +432,37 @@
- 	return(it_old.it_value.tv_sec + (it_old.it_value.tv_usec / 1000000));
- }
- 
--extern "C" int sys_getpid(void)
-+asmlinkage int sys_getpid(void)
- {
- 	return current->pid;
- }
- 
--extern "C" int sys_getppid(void)
-+asmlinkage int sys_getppid(void)
- {
- 	return current->p_pptr->pid;
- }
- 
--extern "C" int sys_getuid(void)
-+asmlinkage int sys_getuid(void)
- {
- 	return current->uid;
- }
- 
--extern "C" int sys_geteuid(void)
-+asmlinkage int sys_geteuid(void)
- {
- 	return current->euid;
- }
- 
--extern "C" int sys_getgid(void)
-+asmlinkage int sys_getgid(void)
- {
- 	return current->gid;
- }
- 
--extern "C" int sys_getegid(void)
-+asmlinkage int sys_getegid(void)
- {
- 	return current->egid;
- }
- 
--extern "C" int sys_nice(long increment)
-+asmlinkage int sys_nice(long increment)
- {
- 	int newprio;
- 
-diff -u --recursive --new-file pl12/linux/kernel/signal.c linux/kernel/signal.c
---- pl12/linux/kernel/signal.c	Sun Aug 15 14:28:14 1993
-+++ linux/kernel/signal.c	Sat Sep  4 02:44:57 1993
-@@ -20,14 +20,39 @@
- 
- extern int core_dump(long signr,struct pt_regs * regs);
- 
--extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs);
-+asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs);
- 
--extern "C" int sys_sgetmask(void)
-+struct sigcontext_struct {
-+	unsigned short gs, __gsh;
-+	unsigned short fs, __fsh;
-+	unsigned short es, __esh;
-+	unsigned short ds, __dsh;
-+	unsigned long edi;
-+	unsigned long esi;
-+	unsigned long ebp;
-+	unsigned long esp;
-+	unsigned long ebx;
-+	unsigned long edx;
-+	unsigned long ecx;
-+	unsigned long eax;
-+	unsigned long trapno;
-+	unsigned long err;
-+	unsigned long eip;
-+	unsigned short cs, __csh;
-+	unsigned long eflags;
-+	unsigned long esp_at_signal;
-+	unsigned short ss, __ssh;
-+	unsigned long i387;
-+	unsigned long oldmask;
-+	unsigned long cr2;
-+};
-+
-+asmlinkage int sys_sgetmask(void)
- {
- 	return current->blocked;
- }
- 
--extern "C" int sys_ssetmask(int newmask)
-+asmlinkage int sys_ssetmask(int newmask)
- {
- 	int old=current->blocked;
- 
-@@ -35,7 +60,7 @@
- 	return old;
- }
- 
--extern "C" int sys_sigpending(sigset_t *set)
-+asmlinkage int sys_sigpending(sigset_t *set)
- {
- 	int error;
- 	/* fill in "set" with signals pending but blocked. */
-@@ -48,7 +73,7 @@
- /*
-  * atomically swap in the new signal mask, and wait for a signal.
-  */
--extern "C" int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
-+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
- {
- 	unsigned long mask;
- 	struct pt_regs * regs = (struct pt_regs *) &restart;
-@@ -98,7 +123,7 @@
- 	}	
- }
- 
--extern "C" int sys_signal(int signum, unsigned long handler)
-+asmlinkage int sys_signal(int signum, unsigned long handler)
- {
- 	struct sigaction tmp;
- 
-@@ -116,7 +141,7 @@
- 	return handler;
- }
- 
--extern "C" int sys_sigaction(int signum, const struct sigaction * action,
-+asmlinkage int sys_sigaction(int signum, const struct sigaction * action,
- 	struct sigaction * oldaction)
- {
- 	struct sigaction new_sa, *p;
-@@ -146,20 +171,37 @@
- 	return 0;
- }
- 
--extern "C" int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
-+asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
- 
- /*
-  * This sets regs->esp even though we don't actually use sigstacks yet..
-  */
--extern "C" int sys_sigreturn(unsigned long oldmask, unsigned long eip, unsigned long esp)
-+asmlinkage int sys_sigreturn(unsigned long __unused)
- {
-+#define CHECK_SEG(x) if (x) x |= 3
-+#define COPY(x) regs->x = context.x
-+	struct sigcontext_struct context;
- 	struct pt_regs * regs;
- 
--	regs = (struct pt_regs *) &oldmask;
--	current->blocked = oldmask & _BLOCKABLE;
--	regs->eip = eip;
--	regs->esp = esp;
--	return 0;
-+	regs = (struct pt_regs *) &__unused;
-+	memcpy_fromfs(&context,(void *) regs->esp, sizeof(context));
-+	current->blocked = context.oldmask & _BLOCKABLE;
-+	CHECK_SEG(context.ss);
-+	CHECK_SEG(context.cs);
-+	CHECK_SEG(context.ds);
-+	CHECK_SEG(context.es);
-+	CHECK_SEG(context.fs);
-+	CHECK_SEG(context.gs);
-+	COPY(eip); COPY(eflags);
-+	COPY(ecx); COPY(edx);
-+	COPY(ebx);
-+	COPY(esp); COPY(ebp);
-+	COPY(edi); COPY(esi);
-+	COPY(cs); COPY(ss);
-+	COPY(ds); COPY(es);
-+	COPY(fs); COPY(gs);
-+	regs->orig_eax = -1;		/* disable syscall checks */
-+	return context.eax;
- }
- 
- /*
-@@ -166,15 +208,17 @@
-  * Set up a signal frame... Make the stack look the way iBCS2 expects
-  * it to look.
-  */
--static void setup_frame(unsigned long ** fp, unsigned long eip,
--	struct pt_regs * regs, int signr,
--	unsigned long sa_handler, unsigned long oldmask)
-+static void setup_frame(struct sigaction * sa, unsigned long ** fp, unsigned long eip,
-+	struct pt_regs * regs, int signr, unsigned long oldmask)
- {
- 	unsigned long * frame;
- 
- #define __CODE ((unsigned long)(frame+24))
- #define CODE(x) ((unsigned long *) ((x)+__CODE))
--	frame = *fp - 32;
-+	frame = *fp;
-+	if (regs->ss != USER_DS)
-+		frame = (unsigned long *) sa->sa_restorer;
-+	frame -= 32;
- 	verify_area(VERIFY_WRITE,frame,32*4);
- /* set up the "normal" stack seen by the signal handler (iBCS2) */
- 	put_fs_long(__CODE,frame);
-@@ -186,32 +230,26 @@
- 	put_fs_long(regs->edi, frame+6);
- 	put_fs_long(regs->esi, frame+7);
- 	put_fs_long(regs->ebp, frame+8);
--	put_fs_long(regs->esp, frame+9);
-+	put_fs_long((long)*fp, frame+9);
- 	put_fs_long(regs->ebx, frame+10);
- 	put_fs_long(regs->edx, frame+11);
- 	put_fs_long(regs->ecx, frame+12);
- 	put_fs_long(regs->eax, frame+13);
--	put_fs_long(0, frame+14);		/* trapno */
--	put_fs_long(0, frame+15);		/* err */
--	put_fs_long(regs->eip, frame+16);
-+	put_fs_long(0, frame+14);		/* trapno - not implemented */
-+	put_fs_long(0, frame+15);		/* err - not implemented */
-+	put_fs_long(eip, frame+16);
- 	put_fs_long(regs->cs, frame+17);
- 	put_fs_long(regs->eflags, frame+18);
- 	put_fs_long(regs->esp, frame+19);
- 	put_fs_long(regs->ss, frame+20);
--	put_fs_long(0,frame+21);		/* 387 state pointer */
--/* linux extended stack - easier to handle.. */
--	put_fs_long(regs->eflags, frame+22);
--	put_fs_long(eip, frame+23);
-+	put_fs_long(0,frame+21);		/* 387 state pointer - not implemented*/
-+/* non-iBCS2 extensions.. */
-+	put_fs_long(oldmask, frame+22);
-+	put_fs_long(0, frame+23);		/* cr2 - not implemented */
- /* set up the return code... */
- 	put_fs_long(0x0000b858, CODE(0));	/* popl %eax ; movl $,%eax */
--	put_fs_long(0x00bb0000, CODE(4));	/* movl $,%ebx */
--	put_fs_long(0xcd000000, CODE(8));	/* int $0x80 */
--	put_fs_long(0x0fa90f80, CODE(12));	/* pop %gs ; pop %fs */
--	put_fs_long(0x611f07a1, CODE(16));	/* pop %es ; pop %ds ; popad */
--	put_fs_long(0x20c48390, CODE(20));	/* nop ; addl $32,%esp */
--	put_fs_long(0x0020c29d, CODE(24));	/* popfl ; ret $32 */
--	put_fs_long(__NR_ssetmask, CODE(2));
--	put_fs_long(oldmask, CODE(7));
-+	put_fs_long(0x80cd0000, CODE(4));	/* int $0x80 */
-+	put_fs_long(__NR_sigreturn, CODE(2));
- 	*fp = frame;
- #undef __CODE
- #undef CODE
-@@ -226,7 +264,7 @@
-  * the kernel can handle, and then we build all the user-level signal handling
-  * stack-frames in one go after that.
-  */
--extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs)
-+asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
- {
- 	unsigned long mask = ~current->blocked;
- 	unsigned long handler_signal = 0;
-@@ -233,7 +271,6 @@
- 	unsigned long *frame = NULL;
- 	unsigned long eip = 0;
- 	unsigned long signr;
--	unsigned long sa_handler;
- 	struct sigaction * sa;
- 
- 	while ((signr = current->signal & mask)) {
-@@ -317,20 +354,20 @@
- 	frame = (unsigned long *) regs->esp;
- 	signr = 1;
- 	sa = current->sigaction;
--	if (regs->cs != USER_CS || regs->ss != USER_DS)
--		printk("Warning: signal handler with nonstandard code/stack segment\n");
- 	for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
- 		if (mask > handler_signal)
- 			break;
- 		if (!(mask & handler_signal))
- 			continue;
--		sa_handler = (unsigned long) sa->sa_handler;
-+		setup_frame(sa,&frame,eip,regs,signr,oldmask);
-+		eip = (unsigned long) sa->sa_handler;
- 		if (sa->sa_flags & SA_ONESHOT)
- 			sa->sa_handler = NULL;
- /* force a supervisor-mode page-in of the signal handler to reduce races */
--		__asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler));
--		setup_frame(&frame,eip,regs,signr,sa_handler,oldmask);
--		eip = sa_handler;
-+		__asm__("testb $0,%%fs:%0": :"m" (*(char *) eip));
-+		regs->cs = USER_CS; regs->ss = USER_DS;
-+		regs->ds = USER_DS; regs->es = USER_DS;
-+		regs->gs = USER_DS; regs->fs = USER_DS;
- 		current->blocked |= sa->sa_mask;
- 		oldmask |= sa->sa_mask;
- 	}
-diff -u --recursive --new-file pl12/linux/kernel/sys.c linux/kernel/sys.c
---- pl12/linux/kernel/sys.c	Mon Aug  9 18:02:32 1993
-+++ linux/kernel/sys.c	Sat Sep  4 02:44:45 1993
-@@ -56,7 +56,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_setpriority(int which, int who, int niceval)
-+asmlinkage int sys_setpriority(int which, int who, int niceval)
- {
- 	struct task_struct **p;
- 	int error = ESRCH;
-@@ -86,7 +86,7 @@
- 	return -error;
- }
- 
--extern "C" int sys_getpriority(int which, int who)
-+asmlinkage int sys_getpriority(int which, int who)
- {
- 	struct task_struct **p;
- 	int max_prio = 0;
-@@ -103,37 +103,37 @@
- 	return(max_prio ? max_prio : -ESRCH);
- }
- 
--extern "C" int sys_profil(void)
-+asmlinkage int sys_profil(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_ftime(void)
-+asmlinkage int sys_ftime(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_break(void)
-+asmlinkage int sys_break(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_stty(void)
-+asmlinkage int sys_stty(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_gtty(void)
-+asmlinkage int sys_gtty(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_prof(void)
-+asmlinkage int sys_prof(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" unsigned long save_v86_state(struct vm86_regs * regs)
-+asmlinkage unsigned long save_v86_state(struct vm86_regs * regs)
- {
- 	unsigned long stack;
- 
-@@ -169,7 +169,7 @@
- 	}
- }
- 
--extern "C" int sys_vm86(struct vm86_struct * v86)
-+asmlinkage int sys_vm86(struct vm86_struct * v86)
- {
- 	struct vm86_struct info;
- 	struct pt_regs * pt_regs = (struct pt_regs *) &v86;
-@@ -216,7 +216,7 @@
-  *
-  * reboot doesn't sync: do that yourself before calling this.
-  */
--extern "C" int sys_reboot(int magic, int magic_too, int flag)
-+asmlinkage int sys_reboot(int magic, int magic_too, int flag)
- {
- 	if (!suser())
- 		return -EPERM;
-@@ -258,7 +258,7 @@
-  * 100% compatible with BSD.  A program which uses just setgid() will be
-  * 100% compatible with POSIX w/ Saved ID's. 
-  */
--extern "C" int sys_setregid(gid_t rgid, gid_t egid)
-+asmlinkage int sys_setregid(gid_t rgid, gid_t egid)
- {
- 	int old_rgid = current->gid;
- 
-@@ -287,7 +287,7 @@
- /*
-  * setgid() is implemeneted like SysV w/ SAVED_IDS 
-  */
--extern "C" int sys_setgid(gid_t gid)
-+asmlinkage int sys_setgid(gid_t gid)
- {
- 	if (suser())
- 		current->gid = current->egid = current->sgid = gid;
-@@ -298,37 +298,37 @@
- 	return 0;
- }
- 
--extern "C" int sys_acct(void)
-+asmlinkage int sys_acct(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_phys(void)
-+asmlinkage int sys_phys(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_lock(void)
-+asmlinkage int sys_lock(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_mpx(void)
-+asmlinkage int sys_mpx(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_ulimit(void)
-+asmlinkage int sys_ulimit(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_old_syscall(void)
-+asmlinkage int sys_old_syscall(void)
- {
- 	return -ENOSYS;
- }
- 
--extern "C" int sys_time(long * tloc)
-+asmlinkage int sys_time(long * tloc)
- {
- 	int i, error;
- 
-@@ -355,7 +355,7 @@
-  * 100% compatible with BSD.  A program which uses just setuid() will be
-  * 100% compatible with POSIX w/ Saved ID's. 
-  */
--extern "C" int sys_setreuid(uid_t ruid, uid_t euid)
-+asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
- {
- 	int old_ruid = current->uid;
- 	
-@@ -392,7 +392,7 @@
-  * will allow a root program to temporarily drop privileges and be able to
-  * regain them by swapping the real and effective uid.  
-  */
--extern "C" int sys_setuid(uid_t uid)
-+asmlinkage int sys_setuid(uid_t uid)
- {
- 	if (suser())
- 		current->uid = current->euid = current->suid = uid;
-@@ -403,7 +403,7 @@
- 	return(0);
- }
- 
--extern "C" int sys_stime(long * tptr)
-+asmlinkage int sys_stime(long * tptr)
- {
- 	if (!suser())
- 		return -EPERM;
-@@ -412,7 +412,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_times(struct tms * tbuf)
-+asmlinkage int sys_times(struct tms * tbuf)
- {
- 	if (tbuf) {
- 		int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
-@@ -426,7 +426,7 @@
- 	return jiffies;
- }
- 
--extern "C" int sys_brk(unsigned long brk)
-+asmlinkage int sys_brk(unsigned long brk)
- {
- 	int freepages;
- 	unsigned long rlim;
-@@ -487,7 +487,7 @@
-  * only important on a multi-user system anyway, to make sure one user
-  * can't send a signal to a process owned by another.  -TYT, 12/12/91
-  */
--extern "C" int sys_setpgid(pid_t pid, pid_t pgid)
-+asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
- {
- 	int i; 
- 
-@@ -513,12 +513,12 @@
- 	return -ESRCH;
- }
- 
--extern "C" int sys_getpgrp(void)
-+asmlinkage int sys_getpgrp(void)
- {
- 	return current->pgrp;
- }
- 
--extern "C" int sys_setsid(void)
-+asmlinkage int sys_setsid(void)
- {
- 	if (current->leader && !suser())
- 		return -EPERM;
-@@ -531,7 +531,7 @@
- /*
-  * Supplementary group ID's
-  */
--extern "C" int sys_getgroups(int gidsetsize, gid_t *grouplist)
-+asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
- {
- 	int i;
- 
-@@ -551,7 +551,7 @@
- 	return(i);
- }
- 
--extern "C" int sys_setgroups(int gidsetsize, gid_t *grouplist)
-+asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
- {
- 	int	i;
- 
-@@ -583,7 +583,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_newuname(struct new_utsname * name)
-+asmlinkage int sys_newuname(struct new_utsname * name)
- {
- 	int error;
- 
-@@ -595,7 +595,7 @@
- 	return error;
- }
- 
--extern "C" int sys_uname(struct old_utsname * name)
-+asmlinkage int sys_uname(struct old_utsname * name)
- {
- 	int error;
- 	if (!name)
-@@ -616,7 +616,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_olduname(struct oldold_utsname * name)
-+asmlinkage int sys_olduname(struct oldold_utsname * name)
- {
- 	int error;
- 	if (!name)
-@@ -640,7 +640,7 @@
- /*
-  * Only sethostname; gethostname can be implemented by calling uname()
-  */
--extern "C" int sys_sethostname(char *name, int len)
-+asmlinkage int sys_sethostname(char *name, int len)
- {
- 	int	i;
- 	
-@@ -660,7 +660,7 @@
-  * Only setdomainname; getdomainname can be implemented by calling
-  * uname()
-  */
--extern "C" int sys_setdomainname(char *name, int len)
-+asmlinkage int sys_setdomainname(char *name, int len)
- {
- 	int	i;
- 	
-@@ -676,7 +676,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
-+asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
- {
- 	int error;
- 
-@@ -692,7 +692,7 @@
- 	return 0;	
- }
- 
--extern "C" int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
-+asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
- {
- 	struct rlimit new_rlim, *old_rlim;
- 
-@@ -761,7 +761,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_getrusage(int who, struct rusage *ru)
-+asmlinkage int sys_getrusage(int who, struct rusage *ru)
- {
- 	if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
- 		return -EINVAL;
-@@ -808,7 +808,7 @@
- #endif /* not __i386__ */
- }
- 
--extern "C" int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
-+asmlinkage int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
- {
- 	int error;
- 
-@@ -840,7 +840,7 @@
-  * soon as possible, so that the clock can be set right.  Otherwise,
-  * various programs will get confused when the clock gets warped.
-  */
--extern "C" int sys_settimeofday(struct timeval *tv, struct timezone *tz)
-+asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz)
- {
- 	static int	firsttime = 1;
- 
-@@ -888,7 +888,7 @@
- 	startup_time += sys_tz.tz_minuteswest*60;
- }
- 
--extern "C" int sys_umask(int mask)
-+asmlinkage int sys_umask(int mask)
- {
- 	int old = current->umask;
- 
-diff -u --recursive --new-file pl12/linux/kernel/traps.c linux/kernel/traps.c
---- pl12/linux/kernel/traps.c	Wed Jul 14 16:57:11 1993
-+++ linux/kernel/traps.c	Sat Sep  4 02:44:31 1993
-@@ -41,31 +41,32 @@
- 
- void page_exception(void);
- 
--extern "C" void divide_error(void);
--extern "C" void debug(void);
--extern "C" void nmi(void);
--extern "C" void int3(void);
--extern "C" void overflow(void);
--extern "C" void bounds(void);
--extern "C" void invalid_op(void);
--extern "C" void device_not_available(void);
--extern "C" void double_fault(void);
--extern "C" void coprocessor_segment_overrun(void);
--extern "C" void invalid_TSS(void);
--extern "C" void segment_not_present(void);
--extern "C" void stack_segment(void);
--extern "C" void general_protection(void);
--extern "C" void page_fault(void);
--extern "C" void coprocessor_error(void);
--extern "C" void reserved(void);
--extern "C" void alignment_check(void);
-+asmlinkage void divide_error(void);
-+asmlinkage void debug(void);
-+asmlinkage void nmi(void);
-+asmlinkage void int3(void);
-+asmlinkage void overflow(void);
-+asmlinkage void bounds(void);
-+asmlinkage void invalid_op(void);
-+asmlinkage void device_not_available(void);
-+asmlinkage void double_fault(void);
-+asmlinkage void coprocessor_segment_overrun(void);
-+asmlinkage void invalid_TSS(void);
-+asmlinkage void segment_not_present(void);
-+asmlinkage void stack_segment(void);
-+asmlinkage void general_protection(void);
-+asmlinkage void page_fault(void);
-+asmlinkage void coprocessor_error(void);
-+asmlinkage void reserved(void);
-+asmlinkage void alignment_check(void);
- 
- /*static*/ void die_if_kernel(char * str, struct pt_regs * regs, long err)
- {
- 	int i;
- 
--	if ((regs->eflags & VM_MASK) || ((0xffff & regs->cs) == USER_CS))
-+	if ((regs->eflags & VM_MASK) || (3 & regs->cs) == 3)
- 		return;
-+
- 	printk("%s: %04x\n", str, err & 0xffff);
- 	printk("EIP:    %04x:%p\nEFLAGS: %p\n", 0xffff & regs->cs,regs->eip,regs->eflags);
- 	printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",
-@@ -82,31 +83,31 @@
- 	do_exit(SIGSEGV);
- }
- 
--extern "C" void do_double_fault(struct pt_regs * regs, long error_code)
-+asmlinkage void do_double_fault(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("double fault",regs,error_code);
- }
- 
--extern "C" void do_general_protection(struct pt_regs * regs, long error_code)
-+asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("general protection",regs,error_code);
- }
- 
--extern "C" void do_alignment_check(struct pt_regs * regs, long error_code)
-+asmlinkage void do_alignment_check(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("alignment check",regs,error_code);
- }
- 
--extern "C" void do_divide_error(struct pt_regs * regs, long error_code)
-+asmlinkage void do_divide_error(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGFPE, current, 1);
- 	die_if_kernel("divide error",regs,error_code);
- }
- 
--extern "C" void do_int3(struct pt_regs * regs, long error_code)
-+asmlinkage void do_int3(struct pt_regs * regs, long error_code)
- {
- 	if (current->flags & PF_PTRACED)
- 		current->blocked &= ~(1 << (SIGTRAP-1));
-@@ -114,12 +115,12 @@
- 	die_if_kernel("int3",regs,error_code);
- }
- 
--extern "C" void do_nmi(struct pt_regs * regs, long error_code)
-+asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
- {
- 	printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
- }
- 
--extern "C" void do_debug(struct pt_regs * regs, long error_code)
-+asmlinkage void do_debug(struct pt_regs * regs, long error_code)
- {
- 	if (current->flags & PF_PTRACED)
- 		current->blocked &= ~(1 << (SIGTRAP-1));
-@@ -127,49 +128,49 @@
- 	die_if_kernel("debug",regs,error_code);
- }
- 
--extern "C" void do_overflow(struct pt_regs * regs, long error_code)
-+asmlinkage void do_overflow(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("overflow",regs,error_code);
- }
- 
--extern "C" void do_bounds(struct pt_regs * regs, long error_code)
-+asmlinkage void do_bounds(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("bounds",regs,error_code);
- }
- 
--extern "C" void do_invalid_op(struct pt_regs * regs, long error_code)
-+asmlinkage void do_invalid_op(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGILL, current, 1);
- 	die_if_kernel("invalid operand",regs,error_code);
- }
- 
--extern "C" void do_device_not_available(struct pt_regs * regs, long error_code)
-+asmlinkage void do_device_not_available(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("device not available",regs,error_code);
- }
- 
--extern "C" void do_coprocessor_segment_overrun(struct pt_regs * regs, long error_code)
-+asmlinkage void do_coprocessor_segment_overrun(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGFPE, last_task_used_math, 1);
- 	die_if_kernel("coprocessor segment overrun",regs,error_code);
- }
- 
--extern "C" void do_invalid_TSS(struct pt_regs * regs,long error_code)
-+asmlinkage void do_invalid_TSS(struct pt_regs * regs,long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("invalid TSS",regs,error_code);
- }
- 
--extern "C" void do_segment_not_present(struct pt_regs * regs,long error_code)
-+asmlinkage void do_segment_not_present(struct pt_regs * regs,long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("segment not present",regs,error_code);
- }
- 
--extern "C" void do_stack_segment(struct pt_regs * regs,long error_code)
-+asmlinkage void do_stack_segment(struct pt_regs * regs,long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("stack segment",regs,error_code);
-@@ -210,13 +211,13 @@
- 	env->twd = 0xffffffff;
- }
- 
--extern "C" void do_coprocessor_error(struct pt_regs * regs, long error_code)
-+asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
- {
- 	ignore_irq13 = 1;
- 	math_error();
- }
- 
--extern "C" void do_reserved(struct pt_regs * regs, long error_code)
-+asmlinkage void do_reserved(struct pt_regs * regs, long error_code)
- {
- 	send_sig(SIGSEGV, current, 1);
- 	die_if_kernel("reserved (15,17-47) error",regs,error_code);
-diff -u --recursive --new-file pl12/linux/mm/memory.c linux/mm/memory.c
---- pl12/linux/mm/memory.c	Sun Aug 15 11:09:18 1993
-+++ linux/mm/memory.c	Sat Sep  4 03:34:22 1993
-@@ -278,7 +278,7 @@
- 	}
- 	size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
- 	dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
--	poff = (from >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
-+	poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
- 	if ((pcnt = PTRS_PER_PAGE - poff) > size)
- 		pcnt = size;
- 
-@@ -337,7 +337,7 @@
- 	}
- 	dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
- 	size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
--	poff = (from >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
-+	poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
- 	if ((pcnt = PTRS_PER_PAGE - poff) > size)
- 		pcnt = size;
- 
-@@ -399,7 +399,7 @@
- 	}
- 	dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
- 	size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
--	poff = (from >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
-+	poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
- 	if ((pcnt = PTRS_PER_PAGE - poff) > size)
- 		pcnt = size;
- 
-@@ -484,7 +484,7 @@
- 		*page_table = BAD_PAGETABLE | PAGE_TABLE;
- 		return 0;
- 	}
--	page_table += (address >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
-+	page_table += (address >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
- 	if (*page_table) {
- 		printk("put_page: page already exists\n");
- 		*page_table = 0;
-@@ -523,7 +523,7 @@
- 			page_table = (unsigned long *) tmp;
- 		}
- 	}
--	page_table += (address >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
-+	page_table += (address >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
- 	if (*page_table) {
- 		printk("put_dirty_page: page already exists\n");
- 		*page_table = 0;
-@@ -760,7 +760,7 @@
- {
- 	struct task_struct ** p;
- 
--	if (!inode || inode->i_count < 2)
-+	if (!inode || inode->i_count < 2 || !area->vm_ops)
- 		return 0;
- 	for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
- 		if (!*p)
-@@ -773,8 +773,8 @@
- 			   we can share pages with */
- 			if(area){
- 			  struct vm_area_struct * mpnt;
--			  for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next){
--			    if(mpnt->vm_ops && mpnt->vm_ops == area->vm_ops &&
-+			  for (mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
-+			    if (mpnt->vm_ops == area->vm_ops &&
- 			       mpnt->vm_inode->i_ino == area->vm_inode->i_ino&&
- 			       mpnt->vm_inode->i_dev == area->vm_inode->i_dev){
- 			      if (mpnt->vm_ops->share(mpnt, area, address))
-@@ -851,6 +851,8 @@
- 			continue;
- 		if (address >= ((mpnt->vm_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
- 			continue;
-+		if (!mpnt->vm_ops || !mpnt->vm_ops->nopage)
-+			break;
- 		mpnt->vm_ops->nopage(error_code, mpnt, address);
- 		return;
- 	}
-@@ -858,7 +860,7 @@
- 	get_empty_page(tsk,address);
- 	if (tsk != current)
- 		return;
--	if (address < tsk->brk)
-+	if (address >= tsk->end_data && address < tsk->brk)
- 		return;
- 	if (address+8192 >= (user_esp & 0xfffff000) && 
- 	    address <= current->start_stack)
-@@ -872,7 +874,7 @@
-  * and the problem, and then passes it off to one of the appropriate
-  * routines.
-  */
--extern "C" void do_page_fault(struct pt_regs *regs, unsigned long error_code)
-+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
- {
- 	unsigned long address;
- 	unsigned long user_esp = 0;
-@@ -966,9 +968,9 @@
- 	int shared = 0;
- 
- 	printk("Mem-info:\n");
--	printk("Free pages:      %6dkB\n",nr_free_pages<<PAGE_SHIFT-10);
--	printk("Secondary pages: %6dkB\n",nr_secondary_pages<<PAGE_SHIFT-10);
--	printk("Free swap:       %6dkB\n",nr_swap_pages<<PAGE_SHIFT-10);
-+	printk("Free pages:      %6dkB\n",nr_free_pages<<(PAGE_SHIFT-10));
-+	printk("Secondary pages: %6dkB\n",nr_secondary_pages<<(PAGE_SHIFT-10));
-+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- 	printk("Buffer memory:   %6dkB\n",buffermem>>10);
- 	printk("Buffer heads:    %6d\n",nr_buffer_heads);
- 	printk("Buffer blocks:   %6d\n",nr_buffers);
-@@ -1085,9 +1087,9 @@
- 	printk("Memory: %dk/%dk available (%dk kernel code, %dk reserved, %dk data)\n",
- 		tmp >> 10,
- 		end_mem >> 10,
--		codepages << PAGE_SHIFT-10,
--		reservedpages << PAGE_SHIFT-10,
--		datapages << PAGE_SHIFT-10);
-+		codepages << (PAGE_SHIFT-10),
-+		reservedpages << (PAGE_SHIFT-10),
-+		datapages << (PAGE_SHIFT-10));
- 	return;
- }
- 
-diff -u --recursive --new-file pl12/linux/mm/mmap.c linux/mm/mmap.c
---- pl12/linux/mm/mmap.c	Mon Aug  9 18:02:33 1993
-+++ linux/mm/mmap.c	Sat Sep  4 02:45:22 1993
-@@ -52,11 +52,11 @@
- 	switch (flags & MAP_TYPE) {
- 	case MAP_SHARED:
- 		if ((prot & PROT_WRITE) && !(file->f_mode & 2))
--			return -EINVAL;
-+			return -EACCES;
- 		/* fall through */
- 	case MAP_PRIVATE:
- 		if (!(file->f_mode & 1))
--			return -EINVAL;
-+			return -EACCES;
- 		break;
- 
- 	default:
-@@ -121,7 +121,7 @@
- 	return -1;
- }
- 
--extern "C" int sys_mmap(unsigned long *buffer)
-+asmlinkage int sys_mmap(unsigned long *buffer)
- {
- 	unsigned long fd;
- 	struct file * file;
-@@ -133,7 +133,7 @@
- 		get_fs_long(buffer+2), get_fs_long(buffer+3), get_fs_long(buffer+5));
- }
- 
--extern "C" int sys_munmap(unsigned long addr, size_t len)
-+asmlinkage int sys_munmap(unsigned long addr, size_t len)
- {
- 	struct vm_area_struct *mpnt, **p, *free;
- 
-@@ -169,7 +169,7 @@
- 	while (free) {
- 		mpnt = free;
- 		free = free->vm_next;
--		if (mpnt->vm_ops->close)
-+		if (mpnt->vm_ops && mpnt->vm_ops->close)
- 			mpnt->vm_ops->close(mpnt);
- 		kfree(mpnt);
- 	}
-@@ -197,11 +197,9 @@
- 	extern struct vm_operations_struct file_mmap;
- 	struct buffer_head * bh;
- 
--	if (off & (inode->i_sb->s_blocksize - 1))
-+	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported right now */
- 		return -EINVAL;
--	if (len > high_memory || off > high_memory - len) /* avoid overflow */
--		return -ENXIO;
--	if (get_limit(USER_DS)  != TASK_SIZE)
-+	if (off & (inode->i_sb->s_blocksize - 1))
- 		return -EINVAL;
- 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
- 		return -EACCES;
-@@ -231,10 +229,6 @@
- 	mpnt->vm_ops = &file_mmap;
- 	mpnt->vm_next = current->mmap;
- 	current->mmap = mpnt;
--#if 0
--	printk("VFS: Loaded mmap at %08x -  %08x\n",
--		mpnt->vm_start,	mpnt->vm_end);
--#endif
- 	return 0;
- }
- 
-diff -u --recursive --new-file pl12/linux/mm/swap.c linux/mm/swap.c
---- pl12/linux/mm/swap.c	Sat Aug 14 15:59:34 1993
-+++ linux/mm/swap.c	Sat Sep  4 02:45:34 1993
-@@ -265,7 +265,7 @@
-  * swapping out or forgetting about. This speeds up the search when we
-  * actually have to swap.
-  */
--extern "C" int sys_idle(void)
-+asmlinkage int sys_idle(void)
- {
- 	need_resched = 1;
- 	return 0;
-@@ -661,7 +661,7 @@
- 	return 0;
- }
- 
--extern "C" int sys_swapoff(const char * specialfile)
-+asmlinkage int sys_swapoff(const char * specialfile)
- {
- 	struct swap_info_struct * p;
- 	struct inode * inode;
-@@ -713,7 +713,7 @@
-  *
-  * The swapon system call
-  */
--extern "C" int sys_swapon(const char * specialfile)
-+asmlinkage int sys_swapon(const char * specialfile)
- {
- 	struct swap_info_struct * p;
- 	struct inode * swap_inode;
-diff -u --recursive --new-file pl12/linux/net/inet/3c509.c linux/net/inet/3c509.c
---- pl12/linux/net/inet/3c509.c	Fri Aug 13 06:35:44 1993
-+++ linux/net/inet/3c509.c	Fri Sep  3 22:08:32 1993
-@@ -1,4 +1,4 @@
--/* el3.c: An 3c509 EtherLink3 ethernet driver for linux. */
-+/* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
- /*
-     Written 1993 by Donald Becker.
- 
-@@ -7,13 +7,13 @@
-     distributed according to the terms of the GNU Public License,
-     incorporated herein by reference.
-     
--    This driver should work with the 3Com EtherLinkIII series.
-+    This driver is for the 3Com EtherLinkIII series.
- 
-     The author may be reached as becker@super.org or
-     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
- */
- 
--static char *version = "el3.c: v0.02 8/13/93 becker@super.org\n";
-+static char *version = "3c509.c: v0.06 9/3/93 becker@super.org\n";
- 
- #include <linux/config.h>
- #include <linux/kernel.h>
-@@ -23,6 +23,14 @@
- #include <linux/ptrace.h>
- #include <linux/errno.h>
- #include <linux/in.h>
-+
-+#ifndef PRE_PL13
-+#include <linux/ioport.h>
-+#else
-+#define snarf_region(base,extent) do {;}while(0)
-+#define check_region(base,extent) (0)
-+#endif
-+
- /*#include <asm/system.h>*/
- #include <asm/io.h>
- #ifndef port_read
-@@ -34,10 +42,12 @@
- #include "skbuff.h"
- #include "arp.h"
- 
-+#ifndef HAVE_AUTOIRQ
- /* From auto_irq.c, should be in a *.h file. */
- extern void autoirq_setup(int waittime);
- extern int autoirq_report(int waittime);
- extern struct device *irq2dev_map[16];
-+#endif
- 
- /* These should be in <asm/io.h>. */
- #define port_read_l(port,buf,nr) \
-@@ -49,9 +59,12 @@
- #ifdef EL3_DEBUG
- int el3_debug = EL3_DEBUG;
- #else
--int el3_debug = 1;
-+int el3_debug = 2;
- #endif
- 
-+/* To minimize the size of the driver source I only define operating
-+   constants if they are used several times.  You'll need the manual
-+   if you want to understand driver details. */
- /* Offsets from base I/O address. */
- #define EL3_DATA 0x00
- #define EL3_CMD 0x0e
-@@ -59,6 +72,9 @@
- #define ID_PORT 0x100
- #define  EEPROM_READ 0x80
- 
-+#define EL3WINDOW(win_num) outw(0x0800+(win_num), ioaddr + EL3_CMD)
-+
-+
- /* Register window 1 offsets, used in normal operation. */
- #define TX_FREE 0x0C
- #define TX_STATUS 0x0B
-@@ -66,11 +82,12 @@
- #define RX_STATUS 0x08
- #define RX_FIFO 0x00
- 
-+#define WN4_MEDIA	0x0A
-+
- struct el3_private {
-     struct enet_statistics stats;
- };
- 
--static int el3_init(struct device *dev);
- static int read_eeprom(int index);
- static int el3_open(struct device *dev);
- static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
-@@ -85,7 +102,9 @@
- int el3_probe(struct device *dev)
- {
-     short lrs_state = 0xff, i;
--    unsigned short iobase = 0;
-+    short ioaddr, irq;
-+    short *phys_addr = (short *)dev->dev_addr;
-+    static int current_tag = 0;
- 
-     /* Send the ID sequence to the ID_PORT. */
-     outb(0x00, ID_PORT);
-@@ -96,75 +115,57 @@
- 	lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
-     }
- 
--    /* The current Space.c initialization makes it difficult to have more
--       than one adaptor initialized.  Send me email if you have a need for
--       multiple adaptors. */
--
--    /* Read in EEPROM data.
--       Only the highest address board will stay on-line. */
-+    /* For the first probe, clear all board's tag registers. */
-+    if (current_tag == 0)
-+	outb(0xd0, ID_PORT);
-+    else		/* Otherwise kill off already-found boards. */
-+	outb(0xd8, ID_PORT);
- 
--    {
--	short *phys_addr = (short *)dev->dev_addr;
--	phys_addr[0] = htons(read_eeprom(0));
--	if (phys_addr[0] != 0x6000)
--	    return 1;
--	phys_addr[1] = htons(read_eeprom(1));
--	phys_addr[2] = htons(read_eeprom(2));
-+    if (read_eeprom(7) != 0x6d50) {
-+	return -ENODEV;
-     }
- 
--    iobase = read_eeprom(8);
--    dev->irq = read_eeprom(9) >> 12;
--
--    /* Activate the adaptor at the EEPROM location (if set), else 0x320. */
--
--    if (iobase == 0x0000) {
--	dev->base_addr = 0x320;
--	outb(0xf2, ID_PORT);
--    } else {
--	dev->base_addr = 0x200 + ((iobase & 0x1f) << 4);
--	outb(0xff, ID_PORT);
-+    /* Read in EEPROM data, which does contention-select.
-+       Only the lowest address board will stay "on-line".
-+       3Com got the byte order backwards. */
-+    for (i = 0; i < 3; i++) {
-+	phys_addr[i] = htons(read_eeprom(i));
-     }
- 
--    outw(0x0800, dev->base_addr + EL3_CMD);	 /* Window 0. */
--    printk("%s: 3c509 at %#3.3x  key %4.4x iobase %4.4x.\n",
--	   dev->name, dev->base_addr, inw(dev->base_addr), iobase);
-+    {
-+	unsigned short iobase = read_eeprom(8);
-+	dev->if_port = iobase >> 14;
-+	ioaddr = 0x200 + ((iobase & 0x1f) << 4);
-+    }
-+    irq = read_eeprom(9) >> 12;
- 
--    if (inw(dev->base_addr) == 0x6d50) {
--	el3_init(dev);
--	return 0;
--    } else
-+    /* The current Space.c structure makes it difficult to have more
-+       than one adaptor initialized.  Send me email if you have a need for
-+       multiple adaptors, and we'll work out something.  -becker@super.org */
-+    if (dev->base_addr != 0
-+	&&  dev->base_addr != (unsigned short)ioaddr) {
- 	return -ENODEV;
--}
--
--static int
--read_eeprom(int index)
--{
--    int timer, bit, word = 0;
--    
--    /* Issue read command, and pause for at least 162 us. for it to complete.
--       Assume extra-fast 16Mhz bus. */
--    outb(EEPROM_READ + index, ID_PORT);
-+    }
- 
--    for (timer = 0; timer < 162*4 + 400; timer++)
--	SLOW_DOWN_IO;
-+    /* Set the adaptor tag so that the next card can be found. */
-+    outb(0xd0 + ++current_tag, ID_PORT);
- 
--    for (bit = 15; bit >= 0; bit--)
--	word = (word << 1) + (inb(ID_PORT) & 0x01);
--	
--    if (el3_debug > 3)
--	printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
-+    /* Activate the adaptor at the EEPROM location. */
-+    outb(0xff, ID_PORT);
- 
--    return word;
--}
-+    EL3WINDOW(0);
-+    if (inw(ioaddr) != 0x6d50)
-+	return -ENODEV;
- 
--static int
--el3_init(struct device *dev)
--{
--    struct el3_private *lp;
--    int ioaddr = dev->base_addr;
--    int i;
-+    dev->base_addr = ioaddr;
-+    dev->irq = irq;
-+    snarf_region(dev->base_addr, 16);
- 
--    printk("%s: EL3 at %#3x, address", dev->name, ioaddr);
-+    {
-+	char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
-+	printk("%s: 3c509 at %#3.3x  tag %d, %s port, address ",
-+	       dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
-+    }
- 
-     /* Read in the station address. */
-     for (i = 0; i < 6; i++)
-@@ -174,9 +175,8 @@
-     /* Make up a EL3-specific-data structure. */
-     dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
-     memset(dev->priv, 0, sizeof(struct el3_private));
--    lp = (struct el3_private *)dev->priv;
- 
--    if (el3_debug > 1)
-+    if (el3_debug > 0)
- 	printk(version);
- 
-     /* The EL3-specific entries in the device structure. */
-@@ -199,7 +199,7 @@
-     dev->hard_header_len = ETH_HLEN;
-     dev->mtu		= 1500; /* eth_mtu */
-     dev->addr_len	= ETH_ALEN;
--    for (i = 0; i < dev->addr_len; i++) {
-+    for (i = 0; i < ETH_ALEN; i++) {
- 	dev->broadcast[i]=0xff;
-     }
- 
-@@ -214,6 +214,30 @@
-     return 0;
- }
- 
-+
-+static int
-+read_eeprom(int index)
-+{
-+    int timer, bit, word = 0;
-+    
-+    /* Issue read command, and pause for at least 162 us. for it to complete.
-+       Assume extra-fast 16Mhz bus. */
-+    outb(EEPROM_READ + index, ID_PORT);
-+
-+    /* This should really be done by looking at one of the timer channels. */
-+    for (timer = 0; timer < 162*4 + 400; timer++)
-+	SLOW_DOWN_IO;
-+
-+    for (bit = 15; bit >= 0; bit--)
-+	word = (word << 1) + (inb(ID_PORT) & 0x01);
-+	
-+    if (el3_debug > 3)
-+	printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
-+
-+    return word;
-+}
-+
-+
- 
- static int
- el3_open(struct device *dev)
-@@ -225,26 +249,36 @@
- 	return -EAGAIN;
-     }
- 
-+    EL3WINDOW(0);
-     if (el3_debug > 3)
--	printk("%s: Opening, IRQ %d  status@%x %4.4x reg4 %4.4x.\n",
--	       dev->name, dev->irq, ioaddr + EL3_STATUS,
--	       inw(ioaddr + EL3_STATUS), inw(ioaddr + 4));
--    outw(0x0800, ioaddr + EL3_CMD); /* Make certain we are in window 0. */
-+	printk("%s: Opening, IRQ %d  status@%x %4.4x.\n", dev->name,
-+	       dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
- 
--    /* This is probably unnecessary. */
-+    /* Activate board: this is probably unnecessary. */
-     outw(0x0001, ioaddr + 4);
- 
--    outw((dev->irq << 12) | 0x0f00, ioaddr + 8);
--
-     irq2dev_map[dev->irq] = dev;
- 
-+    /* Set the IRQ line. */
-+    outw((dev->irq << 12) | 0x0f00, ioaddr + 8);
-+
-     /* Set the station address in window 2 each time opened. */
--    outw(0x0802, ioaddr + EL3_CMD);
-+    EL3WINDOW(2);
- 
-     for (i = 0; i < 6; i++)
- 	outb(dev->dev_addr[i], ioaddr + i);
- 
--    outw(0x1000, ioaddr + EL3_CMD); /* Start the thinnet transceiver. */
-+    if (dev->if_port == 3)
-+	/* Start the thinnet transceiver. We should really wait 50ms...*/
-+	outw(0x1000, ioaddr + EL3_CMD);
-+    else if (dev->if_port == 0) {
-+	/* 10baseT interface, enabled link beat and jabber check. */
-+	EL3WINDOW(4);
-+	outw(inw(ioaddr + WN4_MEDIA) | 0x00C0, ioaddr + WN4_MEDIA);
-+    }
-+
-+    /* Switch to register set 1 for normal use. */
-+    EL3WINDOW(1);
- 
-     outw(0x8005, ioaddr + EL3_CMD); /* Accept b-case and phys addr only. */
-     outw(0xA800, ioaddr + EL3_CMD); /* Turn on statistics. */
-@@ -251,19 +285,15 @@
-     outw(0x2000, ioaddr + EL3_CMD); /* Enable the receiver. */
-     outw(0x4800, ioaddr + EL3_CMD); /* Enable transmitter. */
-     outw(0x78ff, ioaddr + EL3_CMD); /* Allow all status bits to be seen. */
-+    dev->interrupt = 0;
-+    dev->tbusy = 0;
-+    dev->start = 1;
-     outw(0x7098, ioaddr + EL3_CMD); /* Set interrupt mask. */
- 
--    /* Switch to register set 1 for normal use. */
--    outw(0x0801, ioaddr + EL3_CMD);
--
-     if (el3_debug > 3)
- 	printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
- 	       dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
- 
--    dev->tbusy = 0;
--    dev->interrupt = 0;
--    dev->start = 1;
--
-     return 0;			/* Always succeed */
- }
- 
-@@ -278,7 +308,7 @@
- 	int tickssofar = jiffies - dev->trans_start;
- 	if (tickssofar < 10)
- 	    return 1;
--	printk("%s: transmit timed out, tx_status %4.4x status %4.4x.\n",
-+	printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
- 	       dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS));
- 	dev->trans_start = jiffies;
- 	/* Issue TX_RESET and TX_START commands. */
-@@ -308,8 +338,9 @@
-     }
- 
-     if (inw(ioaddr + EL3_STATUS) & 0x0001) { /* IRQ line active, missed one. */
--      printk("%s: Missed interrupt, status %4.4x.\n", dev->name,
--	     inw(ioaddr + EL3_STATUS));
-+      printk("%s: Missed interrupt, status %4.4x  Tx %2.2x Rx %4.4x.\n",
-+	     dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
-+	     inw(ioaddr + RX_STATUS));
-       outw(0x7800, ioaddr + EL3_CMD); /* Fake interrupt trigger. */
-       outw(0x6899, ioaddr + EL3_CMD); /* Ack IRQ */
-       outw(0x78ff, ioaddr + EL3_CMD); /* Allow all status bits to be seen. */
-@@ -322,8 +353,7 @@
-     outw(skb->len, ioaddr + TX_FIFO);
-     outw(0x00, ioaddr + TX_FIFO);
-     /* ... and the packet rounded to a doubleword. */
--    port_write(ioaddr + TX_FIFO, (void *)(skb+1),
--	       ((skb->len + 3) >> 1) & ~0x1);
-+    port_write_l(ioaddr + TX_FIFO, (void *)(skb+1), (skb->len + 3) >> 2);
-     
-     dev->trans_start = jiffies;
-     if (skb->free)
-@@ -360,8 +390,9 @@
- el3_interrupt(int reg_ptr)
- {
-     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
--    struct device *dev = irq2dev_map[irq];
-+    struct device *dev = (struct device *)(irq2dev_map[irq]);
-     int ioaddr, status;
-+    int i = 0;
- 
-     if (dev == NULL) {
- 	printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
-@@ -380,6 +411,9 @@
-     
-     while ((status = inw(ioaddr + EL3_STATUS)) & 0x01) {
- 
-+	if (status & 0x10)
-+	    el3_rx(dev);
-+
- 	if (status & 0x08) {
- 	    if (el3_debug > 5)
- 		printk("    TX room bit was handled.\n");
-@@ -391,10 +425,12 @@
- 	if (status & 0x80)		/* Statistics full. */
- 	    update_stats(ioaddr, dev);
- 	
--	if (status & 0x10)
--	    el3_rx(dev);
--
--	/* Clear the interrupts we've handled. */
-+	if (++i > 10) {
-+	    printk("%s: Infinite loop in interrupt, status %4.4x.\n",
-+		   dev->name, status);
-+	    break;
-+	}
-+	/* Clear the other interrupts we have handled. */
- 	outw(0x6899, ioaddr + EL3_CMD); /* Ack IRQ */
-     }
- 
-@@ -403,16 +439,6 @@
- 	       inw(ioaddr + EL3_STATUS));
-     }
-     
--    if (inw(ioaddr + EL3_STATUS) & 0x01) {
--	int i = 100000;
--	printk("%s: exiting interrupt with status %4.4x.\n", dev->name,
--	       inw(ioaddr + EL3_STATUS));
--	while (i--)		/* Delay loop to see the message. */
--	    inw(ioaddr + EL3_STATUS);
--	while ((inw(ioaddr + EL3_STATUS) & 0x0010)  && i++ < 20)
--	    outw(0x00, ioaddr + RX_STATUS);
--    }
--
-     dev->interrupt = 0;
-     return;
- }
-@@ -430,7 +456,9 @@
- }
- 
- /* Update statistics.  We change to register window 6, so this
--   must be run single-threaded. */
-+   should be run single-threaded if the device is active. This
-+   is expected to be a rare operation, and not worth a special
-+   window-state variable. */
- static void update_stats(int ioaddr, struct device *dev)
- {
-     struct el3_private *lp = (struct el3_private *)dev->priv;
-@@ -440,7 +468,7 @@
-     /* Turn off statistics updates while reading. */
-     outw(0xB000, ioaddr + EL3_CMD);
-     /* Switch to the stats window, and read everything. */
--    outw(0x0806, ioaddr + EL3_CMD);
-+    EL3WINDOW(6);
-     lp->stats.tx_carrier_errors	+= inb(ioaddr + 0);
-     lp->stats.tx_heartbeat_errors	+= inb(ioaddr + 1);
-     /* Multiple collisions. */	   inb(ioaddr + 2);
-@@ -454,25 +482,11 @@
-     inw(ioaddr + 12);
- 
-     /* Back to window 1, and turn statistics back on. */
--    outw(0x0801, ioaddr + EL3_CMD);
-+    EL3WINDOW(1);
-     outw(0xA800, ioaddr + EL3_CMD);
-     return;
- }
- 
--/* Print statistics on the kernel error output. */
--void printk_stats(struct enet_statistics *stats)
--{
--
--    printk("  Ethernet statistics:  Rx packets %6d  Tx packets %6d.\n",
--	   stats->rx_packets, stats->tx_packets);
--    printk("   Carrier errors:   %6d.\n", stats->tx_carrier_errors);
--    printk("   Heartbeat errors: %6d.\n", stats->tx_heartbeat_errors);
--    printk("   Collisions:       %6d.\n", stats->collisions);
--    printk("   Rx FIFO problems: %6d.\n", stats->rx_fifo_errors);
--
--    return;
--}
--
- static int
- el3_rx(struct device *dev)
- {
-@@ -498,21 +512,32 @@
- 	}
- 	if ( (! (rx_status & 0x4000))
- 	    || ! (rx_status & 0x2000)) { /* Dribble bits are OK. */
--	    short length = rx_status & 0x3ff;
--	    int sksize = sizeof(struct sk_buff) + length + 3;
-+	    short pkt_len = rx_status & 0x3ff;
-+	    int sksize = sizeof(struct sk_buff) + pkt_len + 3;
- 	    struct sk_buff *skb;
- 	    skb = (struct sk_buff *) kmalloc(sksize, GFP_ATOMIC);
- 
- 	    if (el3_debug > 4)
- 		printk("       Receiving packet size %d status %4.4x.\n",
--		       length, rx_status);
-+		       pkt_len, rx_status);
- 	    if (skb != NULL) {
--		skb->lock = 0;
- 		skb->mem_len = sksize;
- 		skb->mem_addr = skb;
-+		skb->len = pkt_len;
-+		skb->dev = dev;
-+
- 		/* 'skb+1' points to the start of sk_buff data area. */
--		port_read(ioaddr+RX_FIFO, (void *)(skb+1), ((length + 3) >> 2) << 1);
--		if (dev_rint((unsigned char *)skb, length, IN_SKBUFF,dev)== 0){
-+		port_read_l(ioaddr+RX_FIFO, (void *)(skb+1),
-+			    (pkt_len + 3) >> 2);
-+
-+#ifdef HAVE_NETIF_RX
-+		netif_rx(skb);
-+		outw(0x4000, ioaddr + EL3_CMD); /* Rx discard */
-+		continue;
-+#else
-+		skb->lock = 0;
-+		if (dev_rint((unsigned char *)skb, pkt_len,
-+			     IN_SKBUFF,dev)== 0){
- 		    if (el3_debug > 6)
- 			printk("     dev_rint() happy, status %4.4x.\n",
- 			inb(ioaddr + EL3_STATUS));
-@@ -527,7 +552,8 @@
- 		} else {
- 		    printk("%s: receive buffers full.\n", dev->name);
- 		    kfree_s(skb, sksize);
--		}	    
-+		}
-+#endif
- 	    } else if (el3_debug)
- 		printk("%s: Couldn't allocate a sk_buff of size %d.\n",
- 		       dev->name, sksize);
-@@ -564,22 +590,21 @@
-     outw(0x1800, ioaddr + EL3_CMD);
-     outw(0x5000, ioaddr + EL3_CMD);
- 
--    /* Turn off thinnet power. */
--    outw(0xb800, ioaddr + EL3_CMD);
--
--    if (el3_debug > 2) {
--	struct el3_private *lp = (struct el3_private *)dev->priv;
--	printk("%s: Status was %4.4x.\n", dev->name, inw(ioaddr + EL3_STATUS));
--	printk_stats(&lp->stats);
-+    if (dev->if_port == 3)
-+	/* Turn off thinnet power. */
-+	outw(0xb800, ioaddr + EL3_CMD);
-+    else if (dev->if_port == 0) {
-+	/* Disable link beat and jabber, if_port may change ere next open(). */
-+	EL3WINDOW(4);
-+	outw(inw(ioaddr + WN4_MEDIA) & ~ 0x00C0, ioaddr + WN4_MEDIA);
-     }
- 
--    /* Free the interrupt line. */
-     free_irq(dev->irq);
--    outw(0x1000, ioaddr + EL3_CMD);
-+    /* Switching back to window 0 disables the IRQ. */
-+    EL3WINDOW(0);
-+    /* But we explicitly zero the IRQ line select anyway. */
-     outw(0x0f00, ioaddr + 8);
- 
--    /* Switch back to register window 0. */
--    outw(0x0800, ioaddr + EL3_CMD);
- 
-     irq2dev_map[dev->irq] = 0;
- 
-diff -u --recursive --new-file pl12/linux/net/inet/8390.c linux/net/inet/8390.c
---- pl12/linux/net/inet/8390.c	Fri Aug 13 04:24:31 1993
-+++ linux/net/inet/8390.c	Fri Sep  3 23:27:54 1993
-@@ -14,15 +14,8 @@
- */
- 
- static char *version =
--    "8390.c:v0.99-12 8/9/93 for 0.99.12+ Donald Becker (becker@super.org)\n";
-+    "8390.c:v0.99-13 9/3/93 for 0.99.13 Donald Becker (becker@super.org)\n";
- #include <linux/config.h>
--#if !defined(EL2) && !defined(NE2000) && !defined(WD80x3) && !defined(HPLAN)
--/* They don't know what they want -- give it all to them! */
--#define EL2
--#define NE2000
--#define WD80x3
--#define HPLAN
--#endif
- 
- /*
-   Braindamage remaining:
-@@ -94,12 +87,6 @@
- static void NS8390_trigger_send(struct device *dev, unsigned int length,
- 				int start_page);
- 
--extern int el2autoprobe(int ioaddr, struct device *dev);
--extern int el2probe(int ioaddr, struct device *dev);
--extern int neprobe(int ioaddr, struct device *dev);
--extern int wdprobe(int ioaddr, struct device *dev);
--extern int hpprobe(int ioaddr, struct device *dev);
--
- struct sigaction ei_sigaction = { ei_interrupt, 0, 0, NULL, };
- 
- /* Open/initialize the board.  This routine goes all-out, setting everything
-@@ -260,7 +247,7 @@
- ei_interrupt(int reg_ptr)
- {
-     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
--    struct device *dev = irq2dev_map[irq];
-+    struct device *dev = (struct device *)(irq2dev_map[irq]);
-     int e8390_base;
-     int interrupts, boguscount = 0;
-     struct ei_device *ei_local;
-@@ -580,35 +567,14 @@
-     return &ei_local->stat;
- }
- 
--int
--ethif_init(struct device *dev)
--{
--    if (1
--#ifdef WD80x3
--	&& ! wdprobe(dev->base_addr, dev)
--#endif
--#ifdef EL2
--	&& ! el2autoprobe(dev->base_addr, dev)
--#endif
--#ifdef NE2000
--	&& ! neprobe(dev->base_addr, dev)
--#endif
--#ifdef HPLAN
--	&& ! hpprobe(dev->base_addr, dev)
--#endif
--	&& 1 ) {
--	return 1;	/* -ENODEV or -EAGAIN would be more accurate. */
--    }
--    if (ei_debug > 1)
--	printk(version);
--    return 0;
--}
--
--/* Initialize the rest of the device structure. */
-+/* Initialize the rest of the 8390 device structure. */
- int
- ethdev_init(struct device *dev)
- {
-     int i;
-+
-+    if (ei_debug > 1)
-+	printk(version);
- 
-     for (i = 0; i < DEV_NUMBUFFS; i++)
- 	dev->buffs[i] = NULL;
-diff -u --recursive --new-file pl12/linux/net/inet/8390.h linux/net/inet/8390.h
---- pl12/linux/net/inet/8390.h	Fri Aug 13 04:24:32 1993
-+++ linux/net/inet/8390.h	Mon Aug 30 22:43:18 1993
-@@ -8,6 +8,7 @@
- #define _8390_h
- 
- #include <linux/if_ether.h>
-+#include <linux/ioport.h>
- 
- #define TX_2X_PAGES 12
- #define TX_1X_PAGES 6
-@@ -25,10 +26,12 @@
- extern int ei_open(struct device *dev);
- extern void ei_interrupt(int reg_ptr);
- 
-+#ifndef HAVE_AUTOIRQ
- /* From auto_irq.c */
- extern struct device *irq2dev_map[16];
- extern void autoirq_setup(int waittime);
- extern int autoirq_report(int waittime);
-+#endif
- 
- /* Most of these entries should be in 'struct device' (or most of the
-    things in there should be here!) */
-diff -u --recursive --new-file pl12/linux/net/inet/CONFIG linux/net/inet/CONFIG
---- pl12/linux/net/inet/CONFIG	Fri Aug  6 20:46:27 1993
-+++ linux/net/inet/CONFIG	Fri Sep  3 23:54:30 1993
-@@ -1,53 +1,47 @@
- #
--# Set the address and IRQ here. The ne.c and 3c503 driver will autoprobe
-+# Set any special options here.  Most drivers will autoprobe/autoIRQ
- # if you set the address or IRQ to zero, so we do that by default.
--# Cards supportted:
-+# Cards and options supported:
- #
--#	WD80x3		The Western Digital (SMC) WD80x3 driver
--#	  WD_SHMEM=xxx	Forces the address of the shared memory
--#	  FORCE_8BIT	Force card into 8-bit mode (WD8003)
--#	NE2000		The Novell NE-2000 driver
--#	HPLAN		The HP-LAN driver
--#	EL1		The 3c501 EtherLink I driver (source missing?)
--#	EL2		The 3c503 EtherLink II driver
--#	  EL2_AUI	Selects the AUI port instead of the BNC port
--#	PLIP		The Crynwe PL/IP driver
--#	SLIP		The MicroWalt SLIP driver
-+#  EI_DEBUG		Set the debugging level for 8390-based boards
-+#  CONFIG_WD80x3	The Western Digital (SMC) WD80x3 driver
-+#	WD_SHMEM=xxx	Forces the address of the shared memory
-+#	WD_no_mapout	Don't map out the shared memory (faster, but
-+#			your machine may not warm-boot).
-+#  CONFIG_NE2000	The NE-[12]000 clone driver.
-+#	PACKETBUF_MEMSIZE  Allows an extra-large packet buffer to be
-+#			used.  Usually pointless under Linux.
-+#	show_all_SAPROM  Show the entire address PROM, not just the
-+#			ethernet address, during boot.
-+#	rw_bugfix	Patch an obscure bug with a version of the 8390.
-+#  CONFIG_HPLAN		The HP-LAN driver (for 8390-based boards only).
-+#	rw_bugfix	Fix the same obscure bug.
-+#  CONFIG_EL1		The 3c501 driver (just joking, never released)
-+#  CONFIG_EL2		The 3c503 EtherLink II driver
-+#	EL2_AUI		Default to the AUI port instead of the BNC port
-+#	no_probe_nonshared_memory  Don't probe for programmed-I/O boards.
-+#	EL2MEMTEST	Test shared memory at boot-time.
-+#  CONFIG_EL3
-+#	EL3_DEBUG	Set the debugging message level.
-+#  CONFIG_AT1500
-+#	LANCE_DEBUG	Set the debugging message level.
-+#	DEFAULT_DMA	Change the default DMA to other than 5.
-+#  CONFIG_PLIP		The Crynwr-protocol PL/IP driver
-+#  SLIP			The MicroWalt SLIP driver
- #	  SL_DUMP	Uses the "dump frame" debug code
- #	  SL_COMPRESSED Use CSLIP
--#	D_LINK		The D-Link DE-600 Portable Ethernet Adaptor.
-+#  D_LINK		The D-Link DE-600 Portable Ethernet Adaptor.
- #	  D_LINK_IO	The D-Link I/O address (0x378 == default)
- #	  D_LINK_IRQ	The D-Link IRQ number to use (IRQ7 == default)
- #	  D_LINK_DEBUG	Enable or disable D-Link debugging
- #
--# Note: for most WD (SMC) cards, the AutoProbe doesn't work.  You have
--#	to force those cards into operation, by specifying the I/O add-
--#	ress (EI8390=xxx), the IRQ (EI8390_IRQ=xxx) and the address of
--#	the shared memory (WD_SHMEM=xxxx).  All other supported cards
--#	behave like they should, you can leave the values to 0. -FvK
--#
--
--# Comment out the lines you don't want..
--
--#CARDS	:= $(CARDS) -DSLIP
--#CARDS	:= $(CARDS) -DPLIP
--CARDS	:= $(CARDS) -DWD80x3
--CARDS	:= $(CARDS) -DNE2000
--CARDS	:= $(CARDS) -DHPLAN
--CARDS	:= $(CARDS) -DEL2
--CARDS	:= $(CARDS) -DD_LINK
--CARDS	:= $(CARDS) -DCONFIG_AT1500
- 
--# For WD and SMC cards:
--#OPTS		= -DEI8390=0x280 -DEI8390_IRQ=15
--#WD_OPTS		= -DWD_SHMEM=0xCC000 -UFORCE_8BIT
--OPTS		= -DEI8390=0 -DEI8390_IRQ=0
--WD_OPTS		= -DWD_SHMEM=0
-+# This is at the top level with 'make config'
-+CARDS =
- 
--# For all other cards:
--#OPTS		= -DEI8390=0 -DEI8390_IRQ=0
--#WD_OPTS	= -DUD_SHMEM=0xCC000 -UFORCE_8BIT
- 
-+OPTS		= #-DEI8390=0 -DEI8390_IRQ=0
-+WD_OPTS		= #-DWD_SHMEM=0
- EL2_OPTS	= #-UEL2_AUI
- NE_OPTS		=
- HP_OPTS		=
-diff -u --recursive --new-file pl12/linux/net/inet/Makefile linux/net/inet/Makefile
---- pl12/linux/net/inet/Makefile	Fri Aug  6 20:44:14 1993
-+++ linux/net/inet/Makefile	Fri Sep  3 23:57:25 1993
-@@ -20,7 +20,7 @@
- OBJS	= Space.o sock.o utils.o route.o proc.o timer.o protocol.o loopback.o \
- 	  eth.o packet.o arp.o dev.o 8390.o wd.o ne.o el2.o hp.o plip.o \
- 	  slip.o slhc.o d_link.o auto_irq.o ip.o raw.o icmp.o tcp.o udp.o\
--	  lance.o
-+	  lance.o 3c509.o #ip-frag.o
- 
- ifdef CONFIG_INET
- 
-@@ -38,36 +38,39 @@
- include	CONFIG
- 
- 
--Space.o:	CONFIG Space.c Makefile
-+Space.o:	Space.c CONFIG /usr/include/linux/autoconf.h
- 		$(CC) $(CPPFLAGS) $(CFLAGS) $(OPTS) $(CARDS) $(DL_OPTS) \
--							-c Space.c -o $@
-+							-c $< -o $@
- 
--8390.o:		CONFIG 8390.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(CARDS) -c 8390.c -o $@
-+8390.o:		8390.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(CARDS) -c $< -o $@
- 
--wd.o:		CONFIG wd.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(WD_OPTS) -c wd.c -o $@
-+wd.o:		wd.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(WD_OPTS) -c $< -o $@
- 
--el2.o:		CONFIG el2.c el2reg.h Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(EL2_OPTS) -c el2.c -o $@
-+el2.o:		el2.c CONFIG el2reg.h
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(EL2_OPTS) -c $< -o $@
- 
--ne.o:		CONFIG ne.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(NE_OPTS) -c ne.c -o $@
-+ne.o:		ne.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(NE_OPTS) -c $< -o $@
- 
--hp.o:		CONFIG hp.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(HP_OPTS) -c hp.c -o $@
-+hp.o:		hp.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(HP_OPTS) -c $< -o $@
- 
--plip.o:		CONFIG plip.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(PLIP_OPTS) -c plip.c -o $@
-+plip.o:		plip.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(PLIP_OPTS) -c $< -o $@
- 
--slip.o:		CONFIG slip.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(SLIP_OPTS) -c slip.c -o $@
-+slip.o:		slip.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(SLIP_OPTS) -c $< -o $@
- 
--d_link.o:	CONFIG d_link.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(DL_OPTS) -c d_link.c -o $@
-+d_link.o:	d_link.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(DL_OPTS) -c $< -o $@
- 
--lance.o:	CONFIG lance.c Makefile
--		$(CC) $(CPPFLAGS) $(CFLAGS) $(AT_OPTS) -c lance.c -o $@
-+lance.o:	lance.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(AT_OPTS) -c $< -o $@
-+
-+3c509.o:	3c509.c CONFIG
-+		$(CC) $(CPPFLAGS) $(CFLAGS) $(EL3_OPTS) -c $< -o $@
- 
- subdirs:	dummy
- 		for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
-diff -u --recursive --new-file pl12/linux/net/inet/Space.c linux/net/inet/Space.c
---- pl12/linux/net/inet/Space.c	Fri Aug 13 04:27:58 1993
-+++ linux/net/inet/Space.c	Sat Sep  4 13:42:55 1993
-@@ -33,6 +33,73 @@
- #define	NEXT_DEV	NULL
- 
- 
-+/* A unifed ethernet device probe.  This is the easiest way to have every
-+   ethernet adaptor have the name "eth[0123...]".
-+   */
-+
-+extern int wd_probe(struct device *dev);
-+extern int el2_probe(struct device *dev);
-+extern int ne_probe(struct device *dev);
-+extern int hp_probe(struct device *dev);
-+extern int znet_probe(struct device *);
-+extern int express_probe(struct device *);
-+extern int el3_probe(struct device *);
-+extern int atp_probe(struct device *);
-+extern int at1500_probe(struct device *);
-+extern int depca_probe(struct device *);
-+extern int el1_probe(struct device *);
-+
-+static int
-+ethif_probe(struct device *dev)
-+{
-+    short base_addr = dev->base_addr;
-+
-+    if (base_addr < 0  ||  base_addr == 1)
-+	return 1;		/* ENXIO */
-+
-+    if (1
-+#if defined(CONFIG_WD80x3) || defined(WD80x3)
-+	&& wd_probe(dev)
-+#endif
-+#if defined(CONFIG_EL2) || defined(EL2)
-+	&& el2_probe(dev)
-+#endif
-+#if defined(CONFIG_NE2000) || defined(NE2000)
-+	&& ne_probe(dev)
-+#endif
-+#if defined(CONFIG_HPLAN) || defined(HPLAN)
-+	&& hp_probe(dev)
-+#endif
-+#ifdef CONFIG_AT1500
-+	&& at1500_probe(dev)
-+#endif
-+#ifdef CONFIG_EL3
-+	&& el3_probe(dev)
-+#endif
-+#ifdef CONFIG_ZNET
-+	&& znet_probe(dev)
-+#endif
-+#ifdef CONFIG_EEXPRESS
-+	&& express_probe(dev)
-+#endif
-+#ifdef CONFIG_ATP		/* AT-LAN-TEC (RealTek) pocket adaptor. */
-+	&& atp_probe(dev)
-+#endif
-+#ifdef CONFIG_DEPCA
-+	&& depca_probe(dev)
-+#endif
-+#ifdef CONFIG_EL1
-+	&& el1_probe(dev)
-+#endif
-+	&& 1 ) {
-+	return 1;	/* -ENODEV or -EAGAIN would be more accurate. */
-+    }
-+    return 0;
-+}
-+
-+
-+/* This remains seperate because it requires the addr and IRQ to be
-+   set. */
- #if defined(D_LINK) || defined(CONFIG_DE600)
-     extern int d_link_init(struct device *);
-     static struct device d_link_dev = {
-@@ -51,101 +118,32 @@
- #   define NEXT_DEV	(&d_link_dev)
- #endif
- 
--#ifdef CONFIG_EL1
--#error 
--#   ifndef EL1_IRQ
--#	define EL1_IRQ 9
--#   endif
--#   ifndef EL1
--#	define EL1 0
--#   endif
--    extern int el1_init(struct device *);
--    static struct device el1_dev = {
--        "el0", 0, 0, 0, 0, EL1,	EL1_IRQ, 0, 0, 0, NEXT_DEV, el1_init
--    };
--#   undef NEXT_DEV
--#   define NEXT_DEV	(&el1_dev)
--#endif  /* EL1 */
--
--#ifdef CONFIG_DEPCA
--    extern int depca_probe(struct device *);
--    static struct device depca_dev = {
--        "depca0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, depca_probe,
--    };
--#   undef NEXT_DEV
--#   define NEXT_DEV	(&depca_dev)
--#endif  /* CONFIG_DEPCA */
--
--
--#ifdef CONFIG_ATP		/* AT-LAN-TEC (RealTek) pocket adaptor. */
--    extern int atp_probe(struct device *);
--    static struct device atp_dev = {
--        "atp0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, atp_probe,
--    };
--#   undef NEXT_DEV
--#   define NEXT_DEV	(&atp_dev)
--#endif  /* CONFIG_ATP */
--
--#ifdef CONFIG_EL3
--    extern int el3_probe(struct device *);
--    static struct device eliii0_dev = {
--        "eliii0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, el3_probe,
--    };
--#   undef NEXT_DEV
--#   define NEXT_DEV	(&eliii0_dev)
--#endif  /* CONFIG_3C509 aka EL3 */
--
--#ifdef CONFIG_ZNET
--    extern int znet_probe(struct device *);
--    static struct device znet_dev = {
--	"znet", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, znet_probe, };
--#   undef NEXT_DEV
--#   define NEXT_DEV	(&znet_dev)
--#endif  /* CONFIG_ZNET */
-+/* The first device defaults to I/O base '0', which means autoprobe. */
-+#ifdef EI8390
-+# define ETH0_ADDR EI8390
-+#else
-+# define ETH0_ADDR 0
-+#endif
-+#ifdef EI8390_IRQ
-+# define ETH0_IRQ EI8390_IRQ
-+#else
-+# define ETH0_IRQ 0
-+#endif
-+/* "eth0" defaults to autoprobe, other use a base of "-0x20", "don't probe".
-+   Enable these with boot-time setup. 0.99pl13+ can optionally autoprobe. */
- 
--#ifdef CONFIG_EEXPRESS
--    extern int express_probe(struct device *);
--    static struct device express0_dev = {
--	"exp0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, express_probe, };
--#   undef NEXT_DEV
--#   define NEXT_DEV	(&express0_dev)
--#endif  /* CONFIG_EEPRESS */
-+static struct device eth3_dev = {
-+    "eth3", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe };
-+static struct device eth2_dev = {
-+    "eth2", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, &eth3_dev, ethif_probe };
-+static struct device eth1_dev = {
-+    "eth1", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, &eth2_dev, ethif_probe };
- 
--#ifdef CONFIG_AT1500
--    extern int at1500_probe(struct device *);
--    static struct device lance_dev = {
--        "le0",
--	0,0,0,0, 0 /* I/O Base */, 0 /* pre-set IRQ */,
--        0, 0, 0, NEXT_DEV, at1500_probe,
--    };
--#   undef NEXT_DEV
--#   define NEXT_DEV	(&lance_dev)
--#endif  /* AT1500BT */
-+static struct device eth0_dev = {
-+    "eth0", 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, &eth1_dev, ethif_probe };
- 
--#if defined(EI8390) || defined(CONFIG_EL2) || defined(CONFIG_NE2000) \
--    || defined(CONFIG_WD80x3) || defined(CONFIG_HPLAN)
--#   ifndef EI8390
--#	define EI8390 0
--#   endif
--#   ifndef EI8390_IRQ
--#	define EI8390_IRQ 0
--#   endif
--    extern int ethif_init(struct device *);
--    static struct device ei8390_dev = {
--	"eth0",
--	0,				/* auto-config			*/
--	0,
--	0,
--	0,
--	EI8390,
--	EI8390_IRQ,
--	0, 0, 0,
--	NEXT_DEV,
--	ethif_init
--    };
- #   undef NEXT_DEV
--#   define NEXT_DEV	(&ei8390_dev)
--#endif  /* The EI8390 drivers. */
-+#   define NEXT_DEV	(&eth0_dev)
- 
- #if defined(PLIP) || defined(CONFIG_PLIP)
-     extern int plip_init(struct device *);
-diff -u --recursive --new-file pl12/linux/net/inet/dev.c linux/net/inet/dev.c
---- pl12/linux/net/inet/dev.c	Sat Aug 14 14:32:05 1993
-+++ linux/net/inet/dev.c	Tue Aug 31 05:00:04 1993
-@@ -18,6 +18,7 @@
-  */
- #include <asm/segment.h>
- #include <asm/system.h>
-+#include <asm/bitops.h>
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-@@ -29,6 +30,7 @@
- #include <linux/in.h>
- #include <linux/errno.h>
- #include <linux/interrupt.h>
-+#include <linux/if_ether.h>
- #include "inet.h"
- #include "dev.h"
- #include "eth.h"
-@@ -368,9 +370,40 @@
-   sti();
- }
- 
-+/*
-+ * Receive a packet from a device driver and queue it for the upper
-+ * (protocol) levels.  It always succeeds.
-+ */
-+void
-+netif_rx(struct sk_buff *skb)
-+{
-+  /* Set any necessary flags. */
-+  skb->lock = 0;
-+  skb->sk = NULL;
-+
-+  /* and add it to the "backlog" queue. */
-+  cli();
-+  if (backlog == NULL) {
-+	skb->prev = skb;
-+	skb->next = skb;
-+	backlog = skb;
-+  } else {
-+	skb->prev = (struct sk_buff *) backlog->prev;
-+	skb->next = (struct sk_buff *) backlog;
-+	skb->next->prev = skb;
-+	skb->prev->next = skb;
-+  }
-+  sti();
-+   
-+  /* If any packet arrived, mark it for processing. */
-+  if (backlog != NULL) mark_bh(INET_BH);
-+
-+  return;
-+}
-+
- 
- /*
-- * Fetch a packet from a device driver.
-+ * The old interface to fetch a packet from a device driver.
-  * This function is the base level entry point for all drivers that
-  * want to send a packet to the upper (protocol) levels.  It takes
-  * care of de-multiplexing the packet to the various modules based
-@@ -389,18 +422,20 @@
-   int len2;
- 
-   if (dev == NULL || buff == NULL || len <= 0) return(1);
--  if (dropping && backlog != NULL) {
--	return(1);
--  }
--  if (dropping) printk("INET: dev_rint: no longer dropping packets.\n");
--  dropping = 0;
--
-   if (flags & IN_SKBUFF) {
- 	skb = (struct sk_buff *) buff;
-   } else {
-+	if (dropping) {
-+	  if (backlog != NULL)
-+	      return(1);
-+	  printk("INET: dev_rint: no longer dropping packets.\n");
-+	  dropping = 0;
-+	}
-+
- 	skb = (struct sk_buff *) kmalloc(sizeof(*skb) + len, GFP_ATOMIC);
- 	if (skb == NULL) {
--		printk("dev_rint: packet dropped (no memory) !\n");
-+		printk("dev_rint: packet dropped on %s (no memory) !\n",
-+		       dev->name);
- 		dropping = 1;
- 		return(1);
- 	}
-@@ -426,25 +461,8 @@
-   }
-   skb->len = len;
-   skb->dev = dev;
--  skb->sk = NULL;
--
--  /* Now add it to the backlog. */
--  cli();
--  if (backlog == NULL) {
--	skb->prev = skb;
--	skb->next = skb;
--	backlog = skb;
--  } else {
--	skb->prev = (struct sk_buff *) backlog->prev;
--	skb->next = (struct sk_buff *) backlog;
--	skb->next->prev = skb;
--	skb->prev->next = skb;
--  }
--  sti();
--   
--  /* If any packet arrived, mark it for processing. */
--  if (backlog != NULL) mark_bh(INET_BH);
- 
-+  netif_rx(skb);
-   /* OK, all done. */
-   return(0);
- }
-@@ -475,16 +493,11 @@
-   struct packet_type *ptype;
-   unsigned short type;
-   unsigned char flag = 0;
--  static volatile int in_bh = 0;
-+  static volatile char in_bh = 0;
- 
--  /* Check && mark our BUSY state. */
--  cli();
--  if (in_bh != 0) {
--	sti();
--	return;
--  }
--  in_bh = 1;
--  sti();
-+  /* Atomically check and mark our BUSY state. */
-+  if (set_bit(1, (void*)&in_bh))
-+      return;
- 
-   /* Can we send anything now? */
-   dev_transmit();
-@@ -671,14 +684,46 @@
-   return(pos - arg);
- }
- 
-+/* Print device statistics. */
-+char *sprintf_stats(char *buffer, struct device *dev)
-+{
-+  char *pos = buffer;
-+  struct enet_statistics *stats = (dev->get_stats ? dev->get_stats(dev): NULL);
-+
-+  if (stats)
-+    pos += sprintf(pos, "%6s:%7d %4d %4d %4d %4d %8d %4d %4d %4d %5d %4d\n",
-+		   dev->name,
-+		   stats->rx_packets, stats->rx_errors,
-+		   stats->rx_dropped + stats->rx_missed_errors,
-+		   stats->rx_fifo_errors,
-+		   stats->rx_length_errors + stats->rx_over_errors
-+		   + stats->rx_crc_errors + stats->rx_frame_errors,
-+		   stats->tx_packets, stats->tx_errors, stats->tx_dropped,
-+		   stats->tx_fifo_errors, stats->collisions,
-+		   stats->tx_carrier_errors + stats->tx_aborted_errors
-+		   + stats->tx_window_errors + stats->tx_heartbeat_errors);
-+  else
-+      pos += sprintf(pos, "%6s: No statistics available.\n", dev->name);
-+
-+  return pos;
-+}
- 
- /* Called from the PROCfs module. */
- int
- dev_get_info(char *buffer)
- {
--  return(dev_ifconf(buffer));
--}
-+  char *pos = buffer;
-+  struct device *dev;
- 
-+  pos +=
-+      sprintf(pos,
-+	      "Inter-|   Receive                  |  Transmit\n"
-+	      " face |packets errs drop fifo frame|packets errs drop fifo colls carrier\n");
-+  for (dev = dev_base; dev != NULL; dev = dev->next) {
-+      pos = sprintf_stats(pos, dev);
-+  }
-+  return pos - buffer;
-+}
- 
- /* Perform the SIOCxIFxxx calls. */
- static int
-@@ -702,18 +747,18 @@
- 		ret = 0;
- 		break;
- 	case SIOCSIFFLAGS:
--		ret = dev->flags;
--		dev->flags = ifr.ifr_flags & (
-+		{
-+		  int old_flags = dev->flags;
-+		  dev->flags = ifr.ifr_flags & (
- 			IFF_UP | IFF_BROADCAST | IFF_DEBUG | IFF_LOOPBACK |
- 			IFF_POINTOPOINT | IFF_NOTRAILERS | IFF_RUNNING |
- 			IFF_NOARP | IFF_PROMISC | IFF_ALLMULTI);
--		if ((ret & IFF_UP) && ((dev->flags & IFF_UP) == 0)) {
-+		  if ((old_flags & IFF_UP) && ((dev->flags & IFF_UP) == 0)) {
- 			ret = dev_close(dev);
--		} else {
--			if (((ret & IFF_UP) == 0) && (dev->flags & IFF_UP)) {
--				ret = dev_open(dev);
--			} else ret = 0;
--		}
-+		  } else
-+		      ret = (! (old_flags & IFF_UP) && (dev->flags & IFF_UP))
-+			? dev_open(dev) : 0;
-+	        }
- 		break;
- 	case SIOCGIFADDR:
- 		(*(struct sockaddr_in *)
-@@ -820,9 +865,55 @@
-   int ret;
- 
-   switch(cmd) {
--	case IP_SET_DEV:
--		printk("INET: Warning: old-style ioctl(IP_SET_DEV) called!\n");
--		return(-EINVAL);
-+  case IP_SET_DEV:
-+      {	  /* Maintain backwards-compatibility, to be deleted for 1.00. */
-+	  struct device *dev;
-+	  /* The old 'struct ip_config'. */
-+	  struct ip_config {
-+	      char name[MAX_IP_NAME];
-+	      unsigned long paddr, router, net,up:1,destroy:1;
-+	  } ipc;
-+	  int retval, loopback;
-+
-+	  printk("INET: Warning: old-style ioctl(IP_SET_DEV) called!\n");
-+	  if (!suser())
-+	      return (-EPERM);
-+	  
-+	  verify_area (VERIFY_WRITE, arg, sizeof (ipc));
-+	  memcpy_fromfs(&ipc, arg, sizeof (ipc));
-+	  ipc.name[MAX_IP_NAME-1] = 0;
-+	  loopback = (strcmp(ipc.name, "loopback") == 0);
-+	  dev = dev_get( loopback ? "lo" : ipc.name);
-+	  if (dev == NULL)
-+	      return -EINVAL;
-+	  ipc.destroy = 0;
-+	  dev->pa_addr = ipc.paddr;
-+	  dev->family = AF_INET;
-+	  dev->pa_mask = get_mask(dev->pa_addr);
-+	  dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;
-+	  if (ipc.net != 0xffffffff) {
-+	      dev->flags |= IFF_BROADCAST;
-+	      dev->pa_brdaddr = ipc.net;
-+	  }
-+	  
-+	  /* To be proper we should delete the route here. */
-+	  if (ipc.up == 0)
-+	      return (dev->flags & IFF_UP != 0) ? dev_close(dev) : 0;
-+
-+	  if ((dev->flags & IFF_UP) == 0
-+	      && (retval = dev_open(dev)) != 0)
-+	      return retval;
-+	  printk("%s: adding HOST route of %8.8x.\n", dev->name,
-+		 htonl(ipc.paddr));
-+	  rt_add(RTF_HOST, ipc.paddr, 0, dev);
-+	  if (ipc.router != 0 && ipc.router != -1) {
-+	      rt_add(RTF_GATEWAY, ipc.paddr, ipc.router, dev);
-+	      printk("%s: adding GATEWAY route of %8.8x.\n",
-+		     dev->name, htonl(ipc.paddr));
-+
-+	  }
-+	  return 0;
-+      }
- 	case SIOCGIFCONF:
- 		(void) dev_ifconf((char *) arg);
- 		ret = 0;
-diff -u --recursive --new-file pl12/linux/net/inet/dev.h linux/net/inet/dev.h
---- pl12/linux/net/inet/dev.h	Fri Aug 13 04:24:31 1993
-+++ linux/net/inet/dev.h	Sat Aug 28 00:48:47 1993
-@@ -169,6 +169,9 @@
- extern int		dev_close(struct device *dev);
- extern void		dev_queue_xmit(struct sk_buff *skb, struct device *dev,
- 				       int pri);
-+#define HAVE_NETIF_RX 1
-+extern void		netif_rx(struct sk_buff *skb);
-+/* The old interface to netif_rx(). */
- extern int		dev_rint(unsigned char *buff, long len, int flags,
- 				 struct device * dev);
- extern void		dev_transmit(void);
-diff -u --recursive --new-file pl12/linux/net/inet/el2.c linux/net/inet/el2.c
---- pl12/linux/net/inet/el2.c	Fri Aug 13 04:24:27 1993
-+++ linux/net/inet/el2.c	Mon Aug 30 23:59:57 1993
-@@ -16,7 +16,7 @@
- */
- 
- static char *version =
--    "el2.c:v0.99.12B 8/12/93 Donald Becker (becker@super.org)\n";
-+    "el2.c:v0.99.13 8/30/93 Donald Becker (becker@super.org)\n";
- 
- #include <linux/config.h>
- #include <linux/kernel.h>
-@@ -30,9 +30,9 @@
- #include "8390.h"
- #include "el2reg.h"
- 
--int el2autoprobe(int ioaddr, struct device *dev);
-+int el2_probe(struct device *dev);
- int el2_pio_autoprobe(struct device *dev);
--int el2probe(int ioaddr, struct device *dev);
-+int el2probe1(int ioaddr, struct device *dev);
- 
- static int el2_open(struct device *dev);
- static int el2_close(struct device *dev);
-@@ -55,13 +55,15 @@
- static int ports[] = {0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
- 
- int
--el2autoprobe(int ioaddr, struct device *dev)
-+el2_probe(struct device *dev)
- {
-     int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
-+    short ioaddr = dev->base_addr;
- 
--    /* Non-autoprobe case first: */
-+    if (ioaddr < 0)
-+	return ENXIO;		/* Don't probe at all. */
-     if (ioaddr > 0)
--	return el2probe(ioaddr, dev);
-+	return ! el2probe1(ioaddr, dev);
- 
-     for (addr = addrs; *addr; addr++) {
- 	int i;
-@@ -70,13 +72,19 @@
- 	for(i = 7; i >= 0; i--, base_bits >>= 1)
- 	    if (base_bits & 0x1)
- 		break;
--	if (base_bits == 1 &&  el2probe(ports[i], dev))
--	    return dev->base_addr;
-+	if (base_bits != 1)
-+	    continue;
-+#ifdef HAVE_PORTRESERVE
-+	if (check_region(ports[i], 16))
-+	    continue;
-+#endif
-+	if (el2probe1(ports[i], dev))
-+	    return 0;
-     }
--#ifdef probe_nonshared_memory
-+#ifndef no_probe_nonshared_memory
-     return el2_pio_autoprobe(dev);
- #else
--    return 0;
-+    return ENODEV;
- #endif
- }
- 
-@@ -87,14 +95,18 @@
- {
-     int i;
-     for (i = 0; i < 8; i++) {
-+#ifdef HAVE_PORTRESERVE
-+	if (check_region(ports[i], 16))
-+	    continue;
-+#endif
- 	/* Reset and/or avoid any lurking NE2000 */
- 	if (inb_p(ports[i] + 0x408) == 0xff)
- 	    continue;
- 	if (inb(ports[i] + 0x403) == (0x80 >> i) /* Preliminary check */
--	    && el2probe(ports[i], dev))
--	    return dev->base_addr;
-+	    && el2probe1(ports[i], dev))
-+	    return 0;
-     }
--    return 0;
-+    return ENODEV;
- }
- 
- /* Probe for the Etherlink II card at I/O port base IOADDR,
-@@ -101,7 +113,7 @@
-    returning non-zero on sucess.  If found, set the station
-    address and memory parameters in DEVICE. */
- int
--el2probe(int ioaddr, struct device *dev)
-+el2probe1(int ioaddr, struct device *dev)
- {
-     int i, iobase_reg, membase_reg, saved_406;
-     unsigned char *station_addr = dev->dev_addr;
-@@ -134,6 +146,9 @@
- 	return 0;
-     }
- 
-+#ifdef HAVE_PORTRESERVE
-+    snarf_region(ioaddr, 16);
-+#endif
-     ethdev_init(dev);
- 
-     /* Map the 8390 back into the window. */
-diff -u --recursive --new-file pl12/linux/net/inet/hp.c linux/net/inet/hp.c
---- pl12/linux/net/inet/hp.c	Fri Aug 13 04:24:29 1993
-+++ linux/net/inet/hp.c	Tue Aug 31 00:02:40 1993
-@@ -13,7 +13,7 @@
- */
- 
- static char *version =
--    "hp.c:v0.99.12+ 8/12/93 Donald Becker (becker@super.org)\n";
-+    "hp.c:v0.99.13 8/30/93 Donald Becker (becker@super.org)\n";
- 
- #include <linux/config.h>
- #include <linux/kernel.h>
-@@ -40,7 +40,7 @@
- #define HP_8BSTOP_PG	0x80	/* Last page +1 of RX ring */
- #define HP_16BSTOP_PG	0xFF	/* Last page +1 of RX ring */
- 
--int hpprobe(int ioaddr, struct device *dev);
-+int hp_probe(struct device *dev);
- int hpprobe1(int ioaddr, struct device *dev);
- 
- static void hp_reset_8390(struct device *dev);
-@@ -59,17 +59,27 @@
-     Also initialize the card and fill in STATION_ADDR with the station
-    address. */
- 
--int hpprobe(int ioaddr,  struct device *dev)
-+int hp_probe(struct device *dev)
- {
-     int *port, ports[] = {0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0};
-+    short ioaddr = dev->base_addr;
- 
-+    if (ioaddr < 0)
-+	return ENXIO;		/* Don't probe at all. */
-     if (ioaddr > 0x100)
--	return hpprobe1(ioaddr, dev);
-+	return ! hpprobe1(ioaddr, dev);
- 
--    for (port = &ports[0]; *port; port++)
--	if (inb_p(*port) != 0xff && hpprobe1(*port, dev))
--	    return dev->base_addr;
--    return 0;
-+    for (port = &ports[0]; *port; port++) {
-+#ifdef HAVE_PORTRESERVE
-+	if (check_region(*port, 32))
-+	    continue;
-+#endif
-+	if (inb_p(*port) != 0xff && hpprobe1(*port, dev)) {
-+	    return 0;
-+	}
-+    }
-+    dev->base_addr = ioaddr;
-+    return ENODEV;
- }
- 
- int hpprobe1(int ioaddr, struct device *dev)
-@@ -139,6 +149,10 @@
- 	  return 0;
-       }
-   }
-+
-+#ifdef HAVE_PORTRESERVE
-+    snarf_region(ioaddr, 32);
-+#endif
- 
-   if (ei_debug > 1)
-       printk(version);
-diff -u --recursive --new-file pl12/linux/net/inet/ip.c linux/net/inet/ip.c
---- pl12/linux/net/inet/ip.c	Fri Aug  6 20:40:18 1993
-+++ linux/net/inet/ip.c	Sat Sep  4 00:00:14 1993
-@@ -5,10 +5,11 @@
-  *
-  *		The Internet Protocol (IP) module.
-  *
-- * Version:	@(#)ip.c	1.0.16	06/02/93
-+ * Version:	@(#)ip.c	1.0.16b	9/1/93
-  *
-  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
-  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
-+ *		Donald Becker, <becker@super.org>
-  *
-  *		This program is free software; you can redistribute it and/or
-  *		modify it under the terms of the GNU General Public License
-@@ -382,6 +383,27 @@
-   return(0);
- }
- 
-+/* This is a version of ip_compute_csum() optimized for IP headers, which
-+   always checksum on 4 octet boundaries. */
-+static inline unsigned short
-+ip_fast_csum(unsigned char * buff, int wlen)
-+{
-+    unsigned long sum = 0;
-+    __asm__("\t clc\n"
-+	    "1:\n"
-+	    "\t lodsl\n"
-+	    "\t adcl %%eax, %%ebx\n"
-+	    "\t loop 1b\n"
-+	    "\t adcl $0, %%ebx\n"
-+	    "\t movl %%ebx, %%eax\n"
-+	    "\t shrl $16, %%eax\n"
-+	    "\t addw %%ax, %%bx\n"
-+	    "\t adcw $0, %%bx\n"
-+	    : "=b" (sum) , "=S" (buff)
-+	    : "0" (sum), "c" (wlen) ,"1" (buff)
-+	    : "ax", "cx", "si", "bx" );
-+    return (~sum) & 0xffff;
-+}
- 
- /*
-  * This routine does all the checksum computations that don't
-@@ -429,23 +451,21 @@
-   return(sum & 0xffff);
- }
- 
--
--/* Check the header of an incoming IP datagram. */
-+/* Check the header of an incoming IP datagram.  This version is still used in slhc.c. */
- int
- ip_csum(struct iphdr *iph)
- {
--  if (iph->check == 0) return(0);
--  if (ip_compute_csum((unsigned char *)iph, iph->ihl*4) == 0) return(0);
-+  if (iph->check == 0  || ip_fast_csum((unsigned char *)iph, iph->ihl) == 0)
-+      return(0);
-   return(1);
- }
- 
--
- /* Generate a checksym for an outgoing IP datagram. */
- static void
- ip_send_check(struct iphdr *iph)
- {
-    iph->check = 0;
--   iph->check = ip_compute_csum((unsigned char *)iph, iph->ihl*4);
-+   iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
- }
- 
- 
-@@ -554,21 +574,20 @@
- int
- ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
- {
--  struct iphdr *iph;
-+  struct iphdr *iph = skb->h.iph;
-   unsigned char hash;
-   unsigned char flag = 0;
-+  unsigned char opts_p = 0;	/* Set iff the packet has options. */
-   struct inet_protocol *ipprot;
-   static struct options opt; /* since we don't use these yet, and they
- 				take up stack space. */
-   int brd;
- 
--  iph = skb->h.iph;
--  memset((char *) &opt, 0, sizeof(opt));
-   DPRINTF((DBG_IP, "<<\n"));
--  ip_print(iph);
- 
-   /* Is the datagram acceptable? */
--  if (ip_csum(iph) || do_options(iph, &opt) || iph->version != 4) {
-+  if (iph->version != 4
-+      || (iph->check != 0 && ip_fast_csum((unsigned char *)iph, iph->ihl) !=0)) {
- 	DPRINTF((DBG_IP, "\nIP: *** datagram error ***\n"));
- 	DPRINTF((DBG_IP, "    SRC = %s   ", in_ntoa(iph->saddr)));
- 	DPRINTF((DBG_IP, "    DST = %s (ignored)\n", in_ntoa(iph->daddr)));
-@@ -577,7 +596,15 @@
- 	return(0);
-   }
- 
--  /* Do any IP forwarding required. */
-+  if (iph->ihl != 5) {  	/* Fast path for the typical optionless IP packet. */
-+      ip_print(iph);		/* Bogus, only for debugging. */
-+      memset((char *) &opt, 0, sizeof(opt));
-+      if (do_options(iph, &opt) != 0)
-+	  return 0;
-+      opts_p = 1;
-+  }
-+
-+  /* Do any IP forwarding required.  chk_addr() is expensive -- avoid it someday. */
-   if ((brd = chk_addr(iph->daddr)) == 0) {
- #ifdef CONFIG_IP_FORWARD
- 	ip_forward(skb, dev);
-@@ -588,17 +615,12 @@
-   }
- 
-   /*
--   * Deal with fragments: not really...
--   * Fragmentation is definitely a required part of IP (yeah, guys,
--   * I read Linux-Activists.NET too :-), but the current "sk_buff"
--   * allocation stuff doesn't make things simpler.  When we're all
--   * done cleaning up the mess, we'll add Ross Biro's "mbuf" stuff
--   * to the code, which will replace the sk_buff stuff completely.
--   * That will (a) make the code even cleaner, (b) allow me to do
--   * the DDI (Device Driver Interface) the way I want to, and (c),
--   * it will allow for easy addition of fragging.  Any takers? -FvK
--   */
--  if ((iph->frag_off & 32) || (ntohs(iph->frag_off) & 0x1fff)) {
-+   * Reassemble IP fragments. */
-+
-+  if ((iph->frag_off & 0x0020) || (ntohs(iph->frag_off) & 0x1fff)) {
-+#ifdef CONFIG_IP_DEFRAG
-+      ip_defrag(skb);
-+#else
- 	printk("\nIP: *** datagram fragmentation not yet implemented ***\n");
- 	printk("    SRC = %s   ", in_ntoa(iph->saddr));
- 	printk("    DST = %s (ignored)\n", in_ntoa(iph->daddr));
-@@ -606,6 +628,7 @@
- 	skb->sk = NULL;
- 	kfree_skb(skb, FREE_WRITE);
- 	return(0);
-+#endif
-   }
- 
-   /* Point into the IP datagram, just past the header. */
-@@ -646,7 +669,7 @@
- 	* based on the datagram protocol.  We should really
- 	* check the protocol handler's return values here...
- 	*/
--	ipprot->handler(skb2, dev, &opt, iph->daddr,
-+	ipprot->handler(skb2, dev, opts_p ? &opt : 0, iph->daddr,
- 			(ntohs(iph->tot_len) - (iph->ihl * 4)),
- 			iph->saddr, 0, ipprot);
- 
-diff -u --recursive --new-file pl12/linux/net/inet/lance.c linux/net/inet/lance.c
---- pl12/linux/net/inet/lance.c	Fri Aug 13 04:56:54 1993
-+++ linux/net/inet/lance.c	Fri Sep  3 22:50:10 1993
-@@ -7,13 +7,14 @@
-     distributed according to the terms of the GNU Public License,
-     incorporated herein by reference.
- 
--    This driver should work with the Allied Telesis 1500, and NE2100 clones.
-+    This driver is for the Allied Telesis AT1500, and should work with
-+    NE2100 clones.
- 
-     The author may be reached as becker@super.org or
-     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
- */
- 
--static char *version = "lance.c:v0.08 8/12/93 becker@super.org\n";
-+static char *version = "lance.c:v0.12 9/3/93 becker@super.org\n";
- 
- #include <linux/config.h>
- #include <linux/kernel.h>
-@@ -22,6 +23,7 @@
- /*#include <linux/interrupt.h>*/
- #include <linux/ptrace.h>
- #include <linux/errno.h>
-+#include <linux/ioport.h>
- #include <asm/io.h>
- #include <asm/dma.h>
- /*#include <asm/system.h>*/
-@@ -32,12 +34,12 @@
- #include "skbuff.h"
- #include "arp.h"
- 
-+#ifndef HAVE_AUTOIRQ
- /* From auto_irq.c, should be in a *.h file. */
- extern void autoirq_setup(int waittime);
- extern int autoirq_report(int waittime);
- extern struct device *irq2dev_map[16];
--
--extern void printk_stats(struct enet_statistics *stats);
-+#endif
- 
- #ifdef LANCE_DEBUG
- int lance_debug = LANCE_DEBUG;
-@@ -60,6 +62,7 @@
- #define LANCE_ADDR 0x12
- #define LANCE_RESET 0x14
- #define LANCE_BUS_IF 0x16
-+#define LANCE_TOTAL_SIZE 0x18
- 
- /* The LANCE Rx and Tx ring descriptors. */
- struct lance_rx_head {
-@@ -96,14 +99,17 @@
-     int pad0, pad1;		/* Used for alignment */
- };
- 
--/* This is a temporary solution to the lack of a ethercard low-memory
--   allocation scheme.  We need it for bus-master or DMA ethercards if
--   they are to work >16M memory systems.  */
-+/* We need a ethercard low-memory allocation scheme for for bus-master or
-+   DMA ethercards if they are to work >16M memory systems. This is a
-+   temporary solution to the lack of one, but it limits us to a single
-+   AT1500 and <16M. Bummer. */
-+
- #define PKT_BUF_SZ	1550
- static char rx_buffs[PKT_BUF_SZ][RING_SIZE];
- 
--int at1500_init(int ioaddr, struct device *dev);
-+int at1500_probe1(struct device *dev);
- static int lance_open(struct device *dev);
-+static void lance_init_ring(struct device *dev);
- static int lance_start_xmit(struct sk_buff *skb, struct device *dev);
- static int lance_rx(struct device *dev);
- static void lance_interrupt(int reg_ptr);
-@@ -119,33 +125,52 @@
- int at1500_probe(struct device *dev)
- {
-     int *port, ports[] = {0x300, 0x320, 0x340, 0x360, 0};
--    int ioaddr = dev->base_addr;
--
--    if (ioaddr > 0x100)
--	return ! at1500_init(ioaddr, dev);
-+    int base_addr = dev->base_addr;
- 
-+    if (base_addr < 0)
-+	return ENXIO;		/* Don't probe at all. */
-+    if (base_addr > 0x100)	/* Check a single specified location. */
-+	return at1500_probe1(dev);
-+
-+    /* First probe for the ethercard ID, 0x57, and then look for a LANCE
-+       chip. */
-+    
-     for (port = &ports[0]; *port; port++) {
--	/* Probe for the Allied-Telesys vendor ID.  This will not detect
--	   other NE2100-like ethercards, which must use a hard-wired ioaddr.
--	   There must be a better way to detect a LANCE... */
--	int ioaddr = *port;
--	if (inb(ioaddr) != 0x00
--	    || inb(ioaddr+1) != 0x00
--	    || inb(ioaddr+2) != 0xF4)
-+	int probe_addr = *port;
-+	short temp;
-+
-+#ifdef HAVE_PORTRESERVE
-+	if (check_region(probe_addr, LANCE_TOTAL_SIZE))
-+	    continue;
-+#endif
-+	if (inb(probe_addr + 14) != 0x57
-+	    || inb(probe_addr + 15) != 0x57)
-+	    continue;
-+
-+	/* Reset the LANCE. Un-Reset needed only for the real NE2100. */
-+	temp = inw(probe_addr+LANCE_RESET); /* Reset the LANCE */
-+	outw(temp, probe_addr+LANCE_RESET);	/* "Un-reset" */
-+	
-+	outw(0x0000, probe_addr+LANCE_ADDR); /* Switch to window 0 */
-+	if (inw(probe_addr+LANCE_DATA) != 0x0004)
- 	    continue;
--	if (at1500_init(ioaddr, dev))
-+	dev->base_addr = probe_addr;
-+	if (at1500_probe1(dev) == 0)
- 	    return 0;
-     }
--    return 1;			/* ENODEV would be more accurate. */
-+
-+    dev->base_addr = base_addr;
-+    return ENODEV;			/* ENODEV would be more accurate. */
- }
- 
- int
--at1500_init(int ioaddr, struct device *dev)
-+at1500_probe1(struct device *dev)
- {
-     struct lance_private *lp;
-+    short ioaddr = dev->base_addr;
-+
-     int i;
- 
--    dev->base_addr = ioaddr;
-     printk("%s: LANCE at %#3x, address", dev->name, ioaddr);
- 
-     /* There is a 16 byte station address PROM at the base address.
-@@ -163,12 +188,16 @@
- 
-     if ((int)dev->priv & 0xff000000  ||  (int) rx_buffs & 0xff000000) {
- 	printk(" disabled (buff %#x > 16M).\n", (int)rx_buffs);
--	return 0;
-+	return -ENOMEM;
-     }
- 
-     memset(dev->priv, 0, sizeof(struct lance_private));
-     lp = (struct lance_private *)dev->priv;
- 
-+    if ((int)(lp->rx_ring) & 0x07)
-+	printk("%s: LANCE Rx and Tx rings not on even boundary.\n",
-+	       dev->name);
-+
-     /* Un-Reset the LANCE, needed only for the NE2100. */
-     outw(0, ioaddr+LANCE_RESET);
- 
-@@ -199,11 +228,14 @@
- 	    printk(", using IRQ %d.\n", dev->irq);
- 	else {
- 	    printk(", failed to detect IRQ line.\n");
--	    return 0;
-+	    return -EAGAIN;
- 	}
-     } else
- 	printk(" assigned IRQ %d.\n", dev->irq);
- 
-+    /* The DMA channel may be passed in on this parameter. */
-+    dev->dma = dev->mem_start & 0x07;
-+
- #ifndef NE2100			/* The NE2100 might not understand */
-     /* Turn on auto-select of media (10baseT or BNC) so that the user
-        can watch the LEDs even if the board isn't opened. */
-@@ -211,9 +243,9 @@
-     outw(0x0002, ioaddr+LANCE_BUS_IF);
- #endif
- 
--    if ((int)(lp->rx_ring) & 0x07)
--	printk("%s: LANCE Rx and Tx rings not on even boundary.\n",
--	       dev->name);
-+#ifdef HAVE_PORTRESERVE
-+    snarf_region(ioaddr, LANCE_TOTAL_SIZE);
-+#endif
- 
-     if (lance_debug > 0)
- 	printk(version);
-@@ -225,7 +257,6 @@
-     dev->get_stats = &lance_get_stats;
- 
-     dev->mem_start = 0;
--    dev->rmem_end = 0x00ffffff;		/* Bogus, needed for dev_rint(). */
- 
-     /* Fill in the generic field of the device structure. */
-     for (i = 0; i < DEV_NUMBUFFS; i++)
-@@ -253,7 +284,7 @@
-     dev->pa_mask	= 0;
-     dev->pa_alen	= sizeof(unsigned long);
- 
--    return ioaddr;
-+    return 0;
- }
- 
- 
-@@ -268,8 +299,7 @@
- 	return -EAGAIN;
-     }
- 
--    if (lp->dma < 1)
--	lp->dma = DEFAULT_DMA;
-+    lp->dma = dev->dma ? dev->dma : DEFAULT_DMA;
- 
-     if (request_dma(lp->dma)) {
- 	free_irq(dev->irq);
-@@ -287,7 +317,8 @@
-     /* Un-Reset the LANCE, needed only for the NE2100. */
-     outw(0, ioaddr+LANCE_RESET);
- 
--#ifndef NE2100			/* The NE2100 might not understand */
-+#ifndef NE2100
-+    /* This is really 79C960-specific, NE2100 might not understand */
-     /* Turn on auto-select of media (10baseT or BNC). */
-     outw(0x0002, ioaddr+LANCE_ADDR);
-     outw(0x0002, ioaddr+LANCE_BUS_IF);
-@@ -298,23 +329,7 @@
- 	       dev->name, dev->irq, lp->dma, lp->tx_ring, lp->rx_ring,
- 	       &lp->init_block);
- 
--    lp->cur_rx = lp->cur_tx = 0;
--    lp->dirty_rx = lp->dirty_tx = 0;
--
--    for (i = 0; i < RING_SIZE; i++) {
--	lp->rx_ring[i].base = (int)rx_buffs | 0x80000000 + i*PKT_BUF_SZ;
--	lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
--	lp->tx_ring[i].base = 0;
--    }
--
--    lp->init_block.mode = 0x0000;
--    for (i = 0; i < 6; i++)
--	lp->init_block.phys_addr[i] = dev->dev_addr[i];
--    lp->init_block.filter[0] = 0x00000000;
--    lp->init_block.filter[1] = 0x00000000;
--    lp->init_block.rx_ring = (int)lp->rx_ring | RING_LEN_BITS;
--    lp->init_block.tx_ring = (int)lp->tx_ring | RING_LEN_BITS;
--
-+    lance_init_ring(dev);
-     /* Re-initialize the LANCE, and start it when done. */
-     outw(0x0001, ioaddr+LANCE_ADDR);
-     outw((short) &lp->init_block, ioaddr+LANCE_DATA);
-@@ -343,6 +358,31 @@
-     return 0;			/* Always succeed */
- }
- 
-+/* Initialize the LANCE Rx and Tx rings. */
-+static void
-+lance_init_ring(struct device *dev)
-+{
-+    struct lance_private *lp = (struct lance_private *)dev->priv;
-+    int i;
-+
-+    lp->cur_rx = lp->cur_tx = 0;
-+    lp->dirty_rx = lp->dirty_tx = 0;
-+
-+    for (i = 0; i < RING_SIZE; i++) {
-+	lp->rx_ring[i].base = (int)rx_buffs | 0x80000000 + i*PKT_BUF_SZ;
-+	lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
-+	lp->tx_ring[i].base = 0;
-+    }
-+
-+    lp->init_block.mode = 0x0000;
-+    for (i = 0; i < 6; i++)
-+	lp->init_block.phys_addr[i] = dev->dev_addr[i];
-+    lp->init_block.filter[0] = 0x00000000;
-+    lp->init_block.filter[1] = 0x00000000;
-+    lp->init_block.rx_ring = (int)lp->rx_ring | RING_LEN_BITS;
-+    lp->init_block.tx_ring = (int)lp->tx_ring | RING_LEN_BITS;
-+}
-+
- static int
- lance_start_xmit(struct sk_buff *skb, struct device *dev)
- {
-@@ -352,18 +392,16 @@
-     /* Transmitter timeout, serious problems. */
-     if (dev->tbusy) {
- 	int tickssofar = jiffies - dev->trans_start;
--	int entry = lp->cur_tx++;
- 	if (tickssofar < 5)
- 	    return 1;
- 	outw(0, ioaddr+LANCE_ADDR);
--	printk("%s: transmit timed out, status %4.4x.\n", dev->name,
--	       inw(ioaddr+LANCE_DATA));
-+	printk("%s: transmit timed out, status %4.4x, resetting.\n",
-+	       dev->name, inw(ioaddr+LANCE_DATA));
- 
--	if (lp->tx_ring[(entry+1) & RING_MOD_MASK].base >= 0)
--	    dev->tbusy=0;
--	else
--	    outw(0x00, ioaddr+LANCE_DATA),
--	    outw(0x43, ioaddr+LANCE_DATA);;
-+	lance_init_ring(dev);
-+	outw(0x43, ioaddr+LANCE_DATA);
-+
-+	dev->tbusy=0;
- 	dev->trans_start = jiffies;
- 
- 	return 0;
-@@ -446,7 +484,7 @@
- lance_interrupt(int reg_ptr)
- {
-     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
--    struct device *dev = irq2dev_map[irq];
-+    struct device *dev = (struct device *)(irq2dev_map[irq]);
-     struct lance_private *lp;
-     int csr0, ioaddr;
- 
-@@ -510,6 +548,7 @@
- 		kfree_skb (skb-1, FREE_WRITE);
- 	    dirty_tx = ++lp->dirty_tx & RING_MOD_MASK;
- 	}
-+	/* mark_bh(INET_BH); */
-     }
- 
-     /* Clear the interrupts we've handled. */
-@@ -531,21 +570,10 @@
-     struct lance_private *lp = (struct lance_private *)dev->priv;
-     int entry = lp->cur_rx & RING_MOD_MASK;
- 	
--    /* Check to see if we own this entry. */
-+    /* If we own the next entry, it's a new packet. Send it up. */
-     while (lp->rx_ring[entry].base >= 0) {
- 	int status = lp->rx_ring[entry].base >> 24;
--	if (lance_debug > 5) {
--	    unsigned char *pkt =
--		(unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff);
--	    printk("%s: Rx packet at ring entry %d, len %d status %2.2x.\n",
--		   dev->name, entry, lp->rx_ring[entry].msg_length,
--		   lp->rx_ring[entry].base >> 24);
--	    printk("%s:  Rx %2.2x %2.2x %2.2x ... %2.2x  %2.2x %2.2x %2.2x...%2.2x len %2.2x %2.2x  %2.2x %2.2x.\n",
--		   dev->name, pkt[0], pkt[1], pkt[2], pkt[5], pkt[6],
--		   pkt[7], pkt[8], pkt[11], pkt[12], pkt[13],
--		   pkt[14], pkt[15]);
--	}
--	/* If so, copy it to the upper layers. */
-+
- 	if (status & 0x40) {	/* There was an error. */
- 	    lp->stats.rx_errors++;
- 	    if (status & 0x20) lp->stats.rx_frame_errors++;
-@@ -553,12 +581,33 @@
- 	    if (status & 0x08) lp->stats.rx_crc_errors++;
- 	    if (status & 0x04) lp->stats.rx_fifo_errors++;
- 	} else {
--	    if (dev_rint((unsigned char *)(lp->rx_ring[entry].base
--					   & 0x00ffffff),
--			 lp->rx_ring[entry].msg_length, 0, dev)) {
-+	    /* Malloc up new buffer, compatible with net-2e. */
-+	    short pkt_len = lp->rx_ring[entry].msg_length;
-+	    int sksize = sizeof(struct sk_buff) + pkt_len;
-+	    struct sk_buff *skb;
-+	    skb = (struct sk_buff *) kmalloc(sksize, GFP_ATOMIC);
-+	    if (skb == NULL) {
-+		printk("%s: Memory squeeze, deferring packet.\n", dev->name);
-+		lp->stats.rx_dropped++;	/* Really, deferred. */
-+		break;
-+	    }
-+	    skb->mem_len = sksize;
-+	    skb->mem_addr = skb;
-+	    skb->len = pkt_len;
-+	    skb->dev = dev;
-+	    memcpy((unsigned char *) (skb + 1),
-+		   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
-+		   pkt_len);
-+#ifdef HAVE_NETIF_RX
-+	    netif_rx(skb);
-+#else
-+	    skb->lock = 0;
-+	    if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
-+		kfree_s(skb, sksize);
- 		lp->stats.rx_dropped++;
- 		break;
- 	    }
-+#endif
- 	    lp->stats.rx_packets++;
- 	}
- 
-@@ -565,6 +614,10 @@
- 	lp->rx_ring[entry].base |= 0x80000000;
- 	entry = (entry+1) & RING_MOD_MASK;
-     }
-+
-+    /* We should check that at least two ring entries are free.  If not,
-+       we should free one and mark stats->rx_dropped++. */
-+
-     lp->cur_rx = entry;
- 
-     return 0;
-@@ -587,10 +640,6 @@
-     if (lance_debug > 1)
- 	printk("%s: Shutting down ethercard, status was %2.2x.\n",
- 	       dev->name, inw(ioaddr+LANCE_DATA));
--#ifdef PRINTK_STATS
--    if (lance_debug > 2)
--	printk_stats(&lp->stats);
--#endif
- 
-     /* We stop the LANCE here -- it occasionally polls
-        memory if we don't. */
-diff -u --recursive --new-file pl12/linux/net/inet/loopback.c linux/net/inet/loopback.c
---- pl12/linux/net/inet/loopback.c	Sat Jul 31 15:42:22 1993
-+++ linux/net/inet/loopback.c	Fri Aug 20 17:58:22 1993
-@@ -5,10 +5,11 @@
-  *
-  *		Pseudo-driver for the loopback interface.
-  *
-- * Version:	@(#)loopback.c	1.0.4	05/25/93
-+ * Version:	@(#)loopback.c	1.0.4b	08/16/93
-  *
-  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
-  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
-+ *		Donald Becker, <becker@super.org>
-  *
-  *		This program is free software; you can redistribute it and/or
-  *		modify it under the terms of the GNU General Public License
-@@ -30,6 +31,7 @@
- #include <linux/errno.h>
- #include <linux/fcntl.h>
- #include <linux/in.h>
-+#include <linux/if_ether.h>	/* For the statistics structure. */
- #include "inet.h"
- #include "dev.h"
- #include "eth.h"
-@@ -44,6 +46,7 @@
- static int
- loopback_xmit(struct sk_buff *skb, struct device *dev)
- {
-+  struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
-   int done;
- 
-   DPRINTF((DBG_LOOPB, "loopback_xmit(dev=%X, skb=%X)\n", dev, skb));
-@@ -52,17 +55,27 @@
-   cli();
-   if (dev->tbusy != 0) {
- 	sti();
-+	stats->tx_errors++;
- 	return(1);
-   }
-   dev->tbusy = 1;
-   sti();
- 
--  done = dev_rint((unsigned char *)(skb+1), skb->len, 0, dev);
--  if (skb->free) kfree_skb(skb, FREE_WRITE);
-+  skb->lock = 0;
- 
--  while (done != 1) {
--	done = dev_rint(NULL, 0, 0, dev);
--  }
-+  stats->tx_packets++;
-+
-+  /* Copy the packet only if it isn't marked as free. */
-+
-+  done = dev_rint((unsigned char *)(skb->free ? skb : skb + 1), skb->len,
-+		  skb->free ? IN_SKBUFF : 0, dev);
-+
-+  if (done != 0)
-+      stats->rx_errors++;
-+  else
-+      stats->rx_packets++;
-+
-+
-   dev->tbusy = 0;
- 
- #if 1
-@@ -83,6 +96,11 @@
-   return(0);
- }
- 
-+static struct enet_statistics *
-+get_stats(struct device *dev)
-+{
-+    return (struct enet_statistics *)dev->priv;
-+}
- 
- /* Initialize the rest of the LOOPBACK device. */
- int
-@@ -118,6 +136,9 @@
-   dev->pa_brdaddr	= in_aton("127.255.255.255");
-   dev->pa_mask		= in_aton("255.0.0.0");
-   dev->pa_alen		= sizeof(unsigned long);
--
-+  dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
-+  memset(dev->priv, 0, sizeof(struct enet_statistics));
-+  dev->get_stats = get_stats;
-+  
-   return(0);
- };
-diff -u --recursive --new-file pl12/linux/net/inet/ne.c linux/net/inet/ne.c
---- pl12/linux/net/inet/ne.c	Fri Aug 13 05:57:28 1993
-+++ linux/net/inet/ne.c	Mon Aug 30 23:35:36 1993
-@@ -17,11 +17,12 @@
- /* Routines for the NatSemi-based designs (NE[12]000). */
- 
- static char *version =
--    "ne.c:v0.99-12B 8/12/93 Donald Becker (becker@super.org)\n";
-+    "ne.c:v0.99-13 8/30/93 Donald Becker (becker@super.org)\n";
- 
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/errno.h>
- #include <asm/system.h>
- #include <asm/io.h>
- #ifndef port_read
-@@ -41,7 +42,7 @@
- #define NESM_START_PG	0x40	/* First page of TX buffer */
- #define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
- 
--int neprobe(int ioaddr, struct device *dev);
-+int ne_probe(struct device *dev);
- static int neprobe1(int ioaddr, struct device *dev, int verbose);
- 
- static void ne_reset_8390(struct device *dev);
-@@ -72,17 +73,28 @@
- 	E2010	 starts at 0x100 and ends at 0x4000.
- 	E2010-x starts at 0x100 and ends at 0xffff.  */
- 
--int neprobe(int ioaddr,  struct device *dev)
-+int ne_probe(struct device *dev)
- {
-     int *port, ports[] = {0x300, 0x280, 0x320, 0x340, 0x360, 0};
-+    short ioaddr = dev->base_addr;
- 
-+    if (ioaddr < 0)
-+	return ENXIO;		/* Don't probe at all. */
-     if (ioaddr > 0x100)
--	return neprobe1(ioaddr, dev, 1);
-+	return ! neprobe1(ioaddr, dev, 1);
- 
--    for (port = &ports[0]; *port; port++)
--	if (inb_p(*port) != 0xff && neprobe1(*port, dev, 0))
--	    return dev->base_addr = *port;
--    return 0;
-+    for (port = &ports[0]; *port; port++) {
-+#ifdef HAVE_PORTRESERVE
-+	if (check_region(*port, 32))
-+	    continue;
-+#endif
-+	if (inb_p(*port) != 0xff && neprobe1(*port, dev, 0)) {
-+	    dev->base_addr = *port;
-+	    return 0;
-+	}
-+    }
-+    dev->base_addr = ioaddr;
-+    return ENODEV;
- }
- 
- static int neprobe1(int ioaddr, struct device *dev, int verbose)
-@@ -216,12 +228,15 @@
- 	}
-     }
- 
--    printk("\n%s: %s found at %#x, using IRQ %d.\n",
--	   dev->name, name, ioaddr, dev->irq);
--
-     dev->base_addr = ioaddr;
- 
-+#ifdef HAVE_PORTRESERVE
-+    snarf_region(ioaddr, 32);
-+#endif
-+
-     ethdev_init(dev);
-+    printk("\n%s: %s found at %#x, using IRQ %d.\n",
-+	   dev->name, name, ioaddr, dev->irq);
- 
-     if (ei_debug > 0)
- 	printk(version);
-diff -u --recursive --new-file pl12/linux/net/inet/route.c linux/net/inet/route.c
---- pl12/linux/net/inet/route.c	Sat Aug  7 18:36:52 1993
-+++ linux/net/inet/route.c	Fri Aug 20 01:18:19 1993
-@@ -219,8 +219,10 @@
- 	dev = dev_check(((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr);
-   else
- 	if ((rt = rt_route(((struct sockaddr_in *) &r->rt_gateway)->sin_addr.
--	    s_addr,NULL))) dev = rt->rt_dev;
--	else dev = NULL;
-+			   s_addr,NULL)))
-+	    dev = rt->rt_dev;
-+	else
-+	    dev = NULL;
- 
-   DPRINTF((DBG_RT, "RT: dev for %s gw ",
- 	in_ntoa((*(struct sockaddr_in *)&r->rt_dst).sin_addr.s_addr)));
-@@ -258,12 +260,14 @@
- 
-   pos = buffer;
- 
--  pos += sprintf(pos, "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\n");
-+  pos += sprintf(pos,
-+		 "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\n");
-   
-+  /* This isn't quite right -- r->rt_dst is a struct! */
-   for (r = rt_base; r != NULL; r = r->rt_next) {
--        pos += sprintf(pos, "%s\t%08X\t%08X\t%02X\t%d\t%d\n",
-+        pos += sprintf(pos, "%s\t%08X\t%08X\t%02X\t%d\t%d\t%d\n",
- 		r->rt_dev->name, r->rt_dst, r->rt_gateway,
--		r->rt_flags, r->rt_refcnt, r->rt_use);
-+		r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric);
-   }
-   return(pos - buffer);
- }
-@@ -317,7 +321,9 @@
- int
- rt_ioctl(unsigned int cmd, void *arg)
- {
-+  struct device *dev;
-   struct rtentry rt;
-+  char namebuf[32];
-   int ret;
- 
-   switch(cmd) {
-@@ -325,16 +331,17 @@
- 		ret = dbg_ioctl(arg, DBG_RT);
- 		break;
- 	case SIOCADDRT:
--		if (!suser()) return(-EPERM);
--		verify_area(VERIFY_WRITE, arg, sizeof(struct rtentry));
--		memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
--		ret = rt_new(&rt);
--		break;
- 	case SIOCDELRT:
- 		if (!suser()) return(-EPERM);
- 		verify_area(VERIFY_WRITE, arg, sizeof(struct rtentry));
- 		memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
--		ret = rt_kill(&rt);
-+		if (rt.rt_dev) {
-+		    verify_area(VERIFY_WRITE, rt.rt_dev, sizeof namebuf);
-+		    memcpy_fromfs(&namebuf, rt.rt_dev, sizeof namebuf);
-+		    dev = dev_get(namebuf);
-+		    rt.rt_dev = dev;
-+		}
-+		ret = (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
- 		break;
- 	default:
- 		ret = -EINVAL;
-diff -u --recursive --new-file pl12/linux/net/inet/slip.c linux/net/inet/slip.c
---- pl12/linux/net/inet/slip.c	Sat Jul 31 15:42:22 1993
-+++ linux/net/inet/slip.c	Thu Aug 19 09:46:23 1993
-@@ -688,7 +688,7 @@
-   if (already++ == 0) {
- 	printk("SLIP: version %s (%d channels): ",
- 				SLIP_VERSION, SL_NRUNIT);
--
-+	printk("CSLIP code copyright 1989 Regents of the University of California\n");
- 	/* Fill in our LDISC request block. */
- 	sl_ldisc.flags	= 0;
- 	sl_ldisc.open	= slip_open;
-diff -u --recursive --new-file pl12/linux/net/inet/sock.c linux/net/inet/sock.c
---- pl12/linux/net/inet/sock.c	Sat Jul 31 15:42:22 1993
-+++ linux/net/inet/sock.c	Wed Aug 18 19:19:51 1993
-@@ -967,6 +967,8 @@
- 		sti();
- 		return(-EADDRINUSE);
- 	}
-+	if (sk2->num != snum) continue;		/* more than one */
-+	if (sk2->saddr != sk->saddr) continue;	/* socket per slot ! -FB */
- 	if (!sk2->reuse) {
- 		sti();
- 		return(-EADDRINUSE);
-diff -u --recursive --new-file pl12/linux/net/inet/tcp.c linux/net/inet/tcp.c
---- pl12/linux/net/inet/tcp.c	Wed Aug 11 20:41:15 1993
-+++ linux/net/inet/tcp.c	Wed Aug 18 19:20:37 1993
-@@ -1434,6 +1434,7 @@
-   t1->source = th->dest;
-   t1->seq = th->ack_seq; /* add one so it will be in the right range */
-   t1->rst = 1;
-+  t1->ack_seq = ntohl(ntohl(th->seq)+1); /* send correct ack -FB */
-   t1->window = 0;		/* should be set to 0 -FB */
-   t1->ack = 0;
-   t1->syn = 0;
-diff -u --recursive --new-file pl12/linux/net/inet/wd.c linux/net/inet/wd.c
---- pl12/linux/net/inet/wd.c	Fri Aug 13 04:24:28 1993
-+++ linux/net/inet/wd.c	Mon Aug 30 23:40:32 1993
-@@ -15,11 +15,12 @@
- */
- 
- static char *version =
--    "wd.c:v0.99-12 8/12/93 Donald Becker (becker@super.org)\n";
-+    "wd.c:v0.99-13 8/30/93 Donald Becker (becker@super.org)\n";
- 
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/errno.h>
- #include <asm/io.h>
- #include <asm/system.h>
- #include <memory.h>
-@@ -59,19 +60,28 @@
-     The wdprobe1() routine initializes the card and fills the
-     station address field. */
- 
--int wdprobe(int ioaddr,  struct device *dev)
-+int wd_probe(struct device *dev)
- {
-     int *port, ports[] = {0x300, 0x280, 0x380, 0x240, 0};
-+    short ioaddr = dev->base_addr;
- 
-+    if (ioaddr < 0)
-+	return ENXIO;		/* Don't probe at all. */
-     if (ioaddr > 0x100)
--	return wdprobe1(ioaddr, dev);
-+	return ! wdprobe1(ioaddr, dev);
- 
--    for (port = &ports[0]; *port; port++)
-+    for (port = &ports[0]; *port; port++) {
-+#ifdef HAVE_PORTRESERVE
-+	if (check_region(*port, 32))
-+	    continue;
-+#endif
- 	if (inb(*port + 8) != 0xff
- 	    && inb(*port + 9) != 0xff /* Extra check to avoid soundcard. */
- 	    && wdprobe1(*port, dev))
--	    return *port;
--    return 0;
-+	    return 0;
-+    }
-+    dev->base_addr = ioaddr;
-+    return ENODEV;
- }
- 
- int wdprobe1(int ioaddr, struct device *dev)
-@@ -93,7 +103,7 @@
-       printk(" %2.2X", station_addr[i] = inb(ioaddr + 8 + i));
- 
-   /* The following PureData probe code was contributed by
--     Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata seem to do software
-+     Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
-      configuration differently from others so we have to check for them.
-      This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.
-      */
-@@ -192,6 +202,9 @@
-   }
- 
-   /* OK, were are certain this is going to work.  Setup the device. */
-+#ifdef HAVE_PORTRESERVE
-+  snarf_region(ioaddr, 32);
-+#endif
-   ethdev_init(dev);
- 
-   ei_status.name = model_name;
-@@ -231,8 +244,9 @@
-   ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16;
- 
-   if (ei_status.word16)
--      outb(ISA16 | ei_status.reg5, ioaddr+WD_CMDREG5);
-+      outb(ei_status.reg5, ioaddr+WD_CMDREG5);
-   outb(ei_status.reg0, ioaddr); /* WD_CMDREG */
-+
-   return ei_open(dev);
- }
- 
-@@ -273,7 +287,8 @@
- }
- 
- /* Block input and output are easy on shared memory ethercards, and trivial
--   on the Western digital card where there is no choice of how to do it. */
-+   on the Western digital card where there is no choice of how to do it.
-+   The only complication is if the ring buffer wraps. */
- 
- static int
- wd_block_input(struct device *dev, int count, char *buf, int ring_offset)
-@@ -281,7 +296,7 @@
-     void *xfer_start = (void *)(dev->mem_start + ring_offset
- 				- (WD_START_PG<<8));
- 
--    /* This mapout won't be necessary when wd_close_card is called. */
-+    /* This mapout isn't necessary if wd_close_card is called. */
- #if !defined(WD_no_mapout)
-     int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
- 
-@@ -299,12 +314,6 @@
- 	return dev->rmem_start + count;
-     }
-     memcpy(buf, xfer_start, count);
--    if (ei_debug > 4) {
--	unsigned short *board = (unsigned short *) xfer_start;
--	printk("%s: wd8013 block_input(cnt=%d offset=%3x addr=%#x) = %2x %2x %2x...\n",
--	       dev->name, count, ring_offset, xfer_start,
--	       board[-1], board[0], board[1]);
--    }
- 
- #if !defined(WD_no_mapout)
-     /* Turn off 16 bit access so that reboot works. */
-@@ -314,8 +323,6 @@
-     return ring_offset + count;
- }
- 
--/* This could only be outputting to the transmit buffer.  The
--   ping-pong transmit setup doesn't work with this yet. */
- static void
- wd_block_output(struct device *dev, int count, const unsigned char *buf,
- 		int start_page)
-@@ -332,9 +339,6 @@
- #endif
- 
-     memcpy(shmem, buf, count);
--    if (ei_debug > 4)
--	printk("%s: wd80*3 block_output(addr=%#x cnt=%d) -> %2x=%2x %2x=%2x %d...\n",
--	       shmem, count, shmem[23], buf[23], shmem[24], buf[24], memcmp(shmem,buf,count));
- 
- #if !defined(WD_no_mapout)
-     /* Turn off 16 bit access so that reboot works. */
-diff -u --recursive --new-file pl12/linux/net/socket.c linux/net/socket.c
---- pl12/linux/net/socket.c	Wed Jul  7 10:39:58 1993
-+++ linux/net/socket.c	Sat Sep  4 02:45:52 1993
-@@ -806,7 +806,7 @@
-  * we have this level of indirection. Not a lot of overhead, since more of
-  * the work is done via read/write/select directly.
-  */
--extern "C" int
-+asmlinkage int
- sys_socketcall(int call, unsigned long *args)
- {
-   switch(call) {
-diff -u --recursive --new-file pl12/linux/net/unix/sock.c linux/net/unix/sock.c
---- pl12/linux/net/unix/sock.c	Mon Aug  9 18:02:33 1993
-+++ linux/net/unix/sock.c	Sat Sep  4 14:02:42 1993
-@@ -737,7 +737,7 @@
- 		if (UN_BUF_AVAIL(upd) || peerupd)
- 			put_fs_long(UN_BUF_AVAIL(upd),(unsigned long *)arg);
- 		  else
--			put_fs_long(1,(unsigned long *)arg); /* read EOF */
-+			put_fs_long(0,(unsigned long *)arg);
- 		break;
- 	case TIOCOUTQ:
- 		if (sock->flags & SO_ACCEPTCON) return(-EINVAL);
diff --git a/ChangeLog b/ChangeLog
index 0ff96cb..18ff63d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,116 @@
+Tue Sep 28 19:59:21 1993  David Metcalfe
+
+	* [windows/win.c]
+	Implemented support for windows with no borders.  Added
+ 	GetParent(), GetDlgCtrlID(), GetWindowText() and
+	GetWindowTextLength() functions.
+
+	* [misc/xt.c]
+	Added processing of WM_GETTEXT and WM_GETTEXTLENGTH messages
+	to DefWindowProc and Implemented MessageBeep().
+
+	* [windows/syscolor.c]
+	Added preliminary system color support.
+
+	* [controls/button1.c]
+	Mods to new button control and integration with Wine.
+
+Tue Sep 28 19:59:21 1993  Johannes Ruscheinski
+
+	* [controls/button1.c]
+	New button control using GDI functions.
+	
+Tue Sep 28 19:59:21 1993  Eric Youngdale
+
+	* [debugger/*]
+	Added debugging capabilities to Wine
+
+Sat Sep 25 13:22:50 1993  Alexandre Julliard  (julliard@di.epfl.ch)
+
+	* [objects/region.c]
+	Bug fix
+
+Fri Sep 24 07:35:11 1993  Bob Amstadt  (bob at pooh)
+
+	* [tools/build.c]
+	Changed the entry point code to reduce the standard entry
+	point size from 22 bytes to 10 bytes.  This leaves about
+	4000 free entry points instead of the 800 in version 0.4.2.
+
+	* [loader/resource.c]
+	Rewrote functions to allow loading of resources from any
+	DLL.
+
+	* [loader/wine.c] [include/wine.h]
+	Added functions GetFilenameFromInstance() and GetFileInfo()
+	to search for a loaded file based on its instance handle.
+	Added a field in struct w_files to make searching by an instance
+	handle faster.
+
+Tue Sep 21 09:57:01 1993  miguel@roxanne.nuclecu.unam.mx (Miguel de Icaza)
+
+	* [misc/profile.c]
+	Implementation of .INI file handling
+
+Mon Sep 20 10:54:32 1993  David Metcalfe
+
+	* [misc/profile.c.old]
+	Implementation of .INI file handling
+
+Mon Sep 20 10:54:32 1993  John Brezak
+
+	* [controls/WinButton.c]
+	Bug fix with call to XtVaSetValues.
+
+Mon Sep 20 10:54:32 1993  Alexandre Julliard
+
+	* [windows/win.c]
+	Quick patch to get colormaps to work with button widget.
+
+Mon Sep 20 02:42:54 1993    (yngvi@hafro.is)
+
+	* misc/keyboard.c: 
+	Ifdefed out some bogus Ansi<->Oem conversion functions
+
+	* misc/lstr.c: 
+	New file with string functions like lstr* IsChar* *Ansi* 
+
+Wed Sep 15 20:35:10 1993  John Brezak
+
+	* [loader/signal.c]
+	Additional changes to support NetBSD.
+
+Wed Sep 15 22:19:22 1993  Martin Ayotte
+
+	* [windows/graphics.c]
+	Added FrameRect function
+
+Tue Sep 14 13:54:45 1993  Alexandre Julliard
+
+	* [objects/color.c] [objects/palette.c]
+	Preliminary support for private color map.
+
+	* [windows/class.c]
+	Implemented CS_CLASSDC style.
+
+	* [windows/dce.c]
+	Moved DCEs to USER heap.
+	Implemented class and window DCs.
+
+	* [windows/event.c]
+	Implemented CS_DBLCLKS style.
+
+	* [windows/graphics.c]
+	Bug fix in SetPixel().
+
+	* [windows/win.c]	
+	Implemented CS_OWNDC style.
+	Implemented Get/SetWindowLong().
+
+	* [controls/menu.c] [windows/class.c] [windows/clipping.c] 
+	  [windows/dce.c] [windows/message.c] [windows/win.c]	
+	Moved windows from global heap to USER heap.
+
 Mon Sep 13 05:00:11 1993  Eric Youngdale
 
 	* [Makefile] [if1632/relay.c] [include/dlls.h] [selector.c]
diff --git a/Makefile b/Makefile
index ea2caf1..b6d3236 100644
--- a/Makefile
+++ b/Makefile
@@ -3,14 +3,15 @@
 DEBUGOPTS=
 COPTS=-O2 -m486
 INCLUDE_DIR=include
+LDFLAGS=
 
 ######################################################################
 # These definitions are for the top level
 TARGET=wine
 LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm
 OBJS=if1632/if1632.o controls/controls.o loader/loader.o \
-	memory/memory.o misc/misc.o objects/objects.o windows/windows.o
-SUBDIRS=if1632 controls loader memory misc objects windows
+	memory/memory.o misc/misc.o objects/objects.o windows/windows.o debugger/debugger.o
+SUBDIRS=if1632 controls loader memory misc objects windows debugger
 
 all: $(TARGET)
 
diff --git a/README b/README
index 7b8666f..bdc28e2 100644
--- a/README
+++ b/README
@@ -7,14 +7,13 @@
 Linux:
 
     Uncompress and untar this archive into the directory of your
-choice.  This release requires a Linux version 0.99 pl12 kernel with
-ALPHA-pl13-diffs.
+choice.  This release requires a Linux version 0.99 pl13 kernel
+or above.
 
 NetBSD:
 
     If you use BSD make rather than GNU make, you must apply the patches
-in the file "bsdmake.patch".  This release requires NetBSD 0.9 with
-additional patches.
+in the file "bsdmake.patch".  This release requires NetBSD-current.
 
 All:
 
@@ -28,6 +27,24 @@
 Have a nice game of solitaire, but be careful.  Emulation isn't perfect.
 So, occassionally it will crash.
 
+WHAT'S NEW with version 0.4.3: (see ChangeLog for details)
+	- Bug fixes
+	- Resource loading now able to load DLL resources
+	- Button control now based on GDI calls
+	- Preliminary system color support
+	- Miscellaneous window functions
+	- Limited debugging facility (sometimes hangs)
+
+WHAT'S NEW with version 0.4.2: (see ChangeLog for details)
+	- Bug fixes
+	- 32-bit callback functions allowed
+	- .INI file handling
+	- lstr* functions and ANSI<->OEM conversion functions.
+
+WHAT'S NEW with version 0.4.1: (see ChangeLog for details)
+	- Bug fixes
+	- Memory usage changes.
+
 WHAT'S NEW with version 0.4.0: (see ChangeLog for details)
 	- Wine now compiles and runs under NetBSD.  Patches are
 	  required for NetBSD.
diff --git a/README.DEBUGGER b/README.DEBUGGER
new file mode 100644
index 0000000..2f6ff99
--- /dev/null
+++ b/README.DEBUGGER
@@ -0,0 +1,47 @@
+Date: Sun, 26 Sep 93 03:18:19 EDT
+From: eric@tantalus.nrl.navy.mil (Eric Youngdale)
+Message-Id: <9309260718.AA13966@tantalus.nrl.navy.mil>
+To: bob@amscons.amscons.com
+Cc: linux-activists@Niksula.hut.fi
+In-Reply-To: Bob Amstadt's message of Sat, 25 Sep 1993 23:36:32 +0300
+    <m0oggMt-000CrhC@amscons.amscons.com>
+X-Mn-Key: WABI
+
+
+
+>I may just be dreaming, but I'm beginning to like the idea of a built
+>in debugger.
+
+	So do I.  I like it so much that I wrote one.  It turns out that the
+disassembly code in gdb is pretty much localized to one source file, and this
+was easy to splice into a simple program.  In addition, there are 2 variables
+that you set if you are disassembling 16 bit code, so it makes it all the
+better.
+
+	Anyway, there is a parser that understands a limited set of gdb
+commands (very limited, but the 'x' command is pretty functional as long as you
+stick to numeric rather than symbolic addresses).  The parser understands $pc
+and $sp for your convenience, and you can do things like "x/10i $pc" and "info
+regs" to see what is going on.  In principle you can do "x/x", "x/s", "x/d",
+"x/w", "x/b", "x/i" and "x/c".  I implemented an "info stack" command that
+simply dumps a number of bytes from the stack onto the screen, but it currently
+makes no attempt to actually interpret the stack frames.
+
+	This will probably not work on non-linux systems, and I have no idea
+how much work it will be to fix it.  To start with we need some simple macros
+to determine (based upon a segment selector) whether we are in a 16 bit or a 32
+bit segment, but this should be pretty easy to fix.  I shamelessly ripped off a
+bunch of files from gdb, and I obviously picked the ones for linux.  For other
+systems you may need to make adjustments to these files somehow.  It is too
+late in the evening to worry about this now.
+
+	It will probably be easy to modify the parser to allow you to change
+memory locations and/or register values and then continue execution.  Also,
+some of the hooks for using readline with the parser are in place, but it does
+not work reliably for some reason, so I left it out for now.  Adding gnu
+readline really would bloat the package a lot.  Instead I could use Rich Salz's
+editlib (the canonical test case for the DLL tools), which has a command line
+history feature that could be an acceptable substitute - this is much smaller
+than gnu readline, but I am not sure what features are present.
+
+-Eric
diff --git a/README.OEMANSI b/README.OEMANSI
new file mode 100644
index 0000000..c27b49d
--- /dev/null
+++ b/README.OEMANSI
@@ -0,0 +1,29 @@
+
+In this directory you might find my implemantation of the Windows
+String.  The patch lstr.patch includes whats needed for the following
+functions:
+lstrcat,lstrcmp,lstrcmpi,lstrcpy,lstrcpyn,lstrlen,AnsiUpper,AnsiLower,
+IsCharAlpha,IsCharAlphanumeric,IsCharUpper,IsCharLower,AnsiUpperBuff,
+AnsiLowerBuff,AnsiNext,AnsiPrev. Simply apply the patch to Wine.0.4.1
+and remake.
+
+
+Also there should be the files oem2ansi.trl and ansi2oem.trl that
+define how to translate between ansi and oem codepage 861 I believe
+they call it. These files where created by the Windows program
+oemansi.exe which is also included. To get the oem<->ansi translations
+right for your part of the world just run oemansi under Windows not
+Wine and oemansi will create oem2ansi and ansi2oem for your locale
+that is if your Windows/Dos is set up correctly. Move the .trl files
+into the directory from where you run wine. If Wine does not find the
+*.trl in the current directory AnsiToOem and OemToAnsi will be
+passive.
+
+Shortcomings/Bugs: 
+Some functions depend upon libc functions like toupper, tolower and
+isalpha that, as far as I know, are totally without support for NLS
+and ISO 8859-1.  Default Ansi<->OEM translations when *.trl files are
+not found are missing.
+
+
+NOTE: Please don't run oemansi.exe under wine.
diff --git a/ansi2oem.trl b/ansi2oem.trl
new file mode 100755
index 0000000..2805bb3
--- /dev/null
+++ b/ansi2oem.trl
Binary files differ
diff --git a/bsdmake.patch b/bsdmake.patch
index 42f0ea1..7be2893 100644
--- a/bsdmake.patch
+++ b/bsdmake.patch
@@ -1,147 +1,124 @@
-*** ./windows/Makefile.orig	Fri Sep  3 16:37:58 1993
---- ./windows/Makefile	Thu Sep  9 22:56:21 1993
-***************
-*** 14,19 ****
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
---- 14,19 ----
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-*** ./tools/Makefile.orig	Tue Jul 20 18:40:18 1993
---- ./tools/Makefile	Thu Sep  9 22:56:21 1993
-***************
-*** 12,17 ****
-  #
-  # Dependency lists
-  #
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
---- 12,21 ----
-  #
-  # Dependency lists
-  #
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-! 
-! #ifeq (.depend,$(wildcard .depend))
-! #include .depend
-! #endif
-*** ./objects/Makefile.orig	Fri Sep  3 16:39:20 1993
---- ./objects/Makefile	Thu Sep  9 22:56:23 1993
-***************
-*** 14,19 ****
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
---- 14,19 ----
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-*** ./misc/Makefile.orig	Thu Sep  9 11:16:49 1993
---- ./misc/Makefile	Thu Sep  9 22:56:23 1993
-***************
-*** 13,18 ****
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
---- 13,18 ----
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-*** ./memory/Makefile.orig	Tue Jul 20 18:43:02 1993
---- ./memory/Makefile	Thu Sep  9 22:56:34 1993
-***************
-*** 13,18 ****
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
---- 13,18 ----
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-*** ./loader/Makefile.orig	Mon Aug 30 20:44:18 1993
---- ./loader/Makefile	Thu Sep  9 22:56:36 1993
-***************
-*** 13,18 ****
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
---- 13,18 ----
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-*** ./if1632/Makefile.orig	Thu Sep  9 11:15:58 1993
---- ./if1632/Makefile	Thu Sep  9 22:56:38 1993
-***************
-*** 42,50 ****
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
-  
-  
-  
---- 42,50 ----
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-  
-  
-  
-*** ./controls/Makefile.orig	Mon Aug 30 19:40:39 1993
---- ./controls/Makefile	Thu Sep  9 22:56:43 1993
-***************
-*** 14,19 ****
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! ifeq (.depend,$(wildcard .depend))
-! include .depend
-! endif
---- 14,20 ----
-  depend:
-  	$(CC) $(CFLAGS) -M *.c > .depend
-  
-! .if exists(.depend)
-! .include ".depend"
-! .endif
-! 
+diff -ruN ../Backup//Makefile ./Makefile
+--- ../Backup//Makefile	Tue Sep 14 09:47:00 1993
++++ ./Makefile	Thu Sep 16 09:59:52 1993
+@@ -7,7 +7,7 @@
+ ######################################################################
+ # These definitions are for the top level
+ TARGET=wine
+-LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm
++LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -li386
+ OBJS=if1632/if1632.o controls/controls.o loader/loader.o \
+ 	memory/memory.o misc/misc.o objects/objects.o windows/windows.o
+ SUBDIRS=if1632 controls loader memory misc objects windows
+diff -ruN ../Backup//controls/Makefile ./controls/Makefile
+--- ../Backup//controls/Makefile	Sat Sep 11 22:13:44 1993
++++ ./controls/Makefile	Thu Sep 16 10:00:24 1993
+@@ -14,6 +14,7 @@
+ depend:
+ 	$(CC) $(CFLAGS) -M *.c > .depend
+ 
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
++
+diff -ruN ../Backup//if1632/Makefile ./if1632/Makefile
+--- ../Backup//if1632/Makefile	Tue Sep 14 08:56:17 1993
++++ ./if1632/Makefile	Thu Sep 16 10:00:24 1993
+@@ -45,9 +45,9 @@
+ depend:
+ 	$(CC) $(CFLAGS) -M *.c > .depend
+ 
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
+ 
+ 
+ 
+diff -ruN ../Backup//loader/Makefile ./loader/Makefile
+--- ../Backup//loader/Makefile	Sat Sep 11 21:42:05 1993
++++ ./loader/Makefile	Thu Sep 16 10:00:24 1993
+@@ -13,6 +13,6 @@
+ depend:
+ 	$(CC) $(CFLAGS) -M *.c > .depend
+ 
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
+diff -ruN ../Backup//memory/Makefile ./memory/Makefile
+--- ../Backup//memory/Makefile	Sat Sep 11 21:42:05 1993
++++ ./memory/Makefile	Thu Sep 16 10:00:24 1993
+@@ -13,6 +13,6 @@
+ depend:
+ 	$(CC) $(CFLAGS) -M *.c > .depend
+ 
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
+diff -ruN ../Backup//misc/Makefile ./misc/Makefile
+--- ../Backup//misc/Makefile	Tue Sep 14 09:17:00 1993
++++ ./misc/Makefile	Thu Sep 16 10:00:24 1993
+@@ -14,6 +14,6 @@
+ depend:
+ 	$(CC) $(CFLAGS) -M *.c > .depend
+ 
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
+diff -ruN ../Backup//objects/Makefile ./objects/Makefile
+--- ../Backup//objects/Makefile	Tue Sep 14 13:59:04 1993
++++ ./objects/Makefile	Thu Sep 16 10:00:24 1993
+@@ -14,6 +14,6 @@
+ depend:
+ 	$(CC) $(CFLAGS) -M *.c > .depend
+ 
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
+diff -ruN ../Backup//tools/Makefile ./tools/Makefile
+--- ../Backup//tools/Makefile	Tue Sep 14 09:46:40 1993
++++ ./tools/Makefile	Thu Sep 16 10:00:24 1993
+@@ -14,6 +14,10 @@
+ #
+ # Dependency lists
+ #
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
++
++#ifeq (.depend,$(wildcard .depend))
++#include .depend
++#endif
+diff -ruN ../Backup//windows/Makefile ./windows/Makefile
+--- ../Backup//windows/Makefile	Tue Sep 14 08:39:45 1993
++++ ./windows/Makefile	Thu Sep 16 10:00:24 1993
+@@ -14,6 +14,6 @@
+ depend:
+ 	$(CC) $(CFLAGS) -M *.c > .depend
+ 
+-ifeq (.depend,$(wildcard .depend))
+-include .depend
+-endif
++.if exists(.depend)
++.include ".depend"
++.endif
diff --git a/controls/Makefile b/controls/Makefile
index dc3c187..46a93ba 100644
--- a/controls/Makefile
+++ b/controls/Makefile
@@ -1,7 +1,7 @@
 CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
 
 OBJS=menu.o widgets.o button.o SmeMenuButto.o WinLabel.o WinCommand.o \
-     WinMenuButto.o WinButton.o
+     WinMenuButto.o
 
 default: controls.o
 
diff --git a/controls/WinButton.c b/controls/WinButton.c
deleted file mode 100644
index 59773ce..0000000
--- a/controls/WinButton.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/***********************************************************
-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
-and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the names of Digital or MIT not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
- * Modifications for Wine
- *
- * 8/28/93  David Metcalfe (david@prism.demon.co.uk)
- *          Created from Command widget and added 3D effect
- */
-
-/*
- * WinButton.c - WinButton button widget
- */
-
-#include <stdio.h>
-#include <X11/IntrinsicP.h>
-#include <X11/StringDefs.h>
-#include <X11/Xmu/Misc.h>
-#include <X11/Xaw/XawInit.h>
-#include "WinButtonP.h"
-#include <X11/Xmu/Converters.h>
-
-#define DEFAULT_HIGHLIGHT_THICKNESS 0
-#define DEFAULT_SHAPE_HIGHLIGHT 32767
-
-/****************************************************************
- *
- * Full class record constant
- *
- ****************************************************************/
-
-/* Private Data */
-
-static char defaultTranslations[] =
-    "<EnterWindow>:	highlight()		\n\
-     <LeaveWindow>:	reset()			\n\
-     <Btn1Down>:	set()			\n\
-     <Btn1Up>:		notify() unset()	";
-
-#define offset(field) XtOffsetOf(WinButtonRec, field)
-static XtResource resources[] = { 
-   {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer), 
-      offset(winbutton.callbacks), XtRCallback, (XtPointer)NULL},
-   {XtNhighlightThickness, XtCThickness, XtRDimension, sizeof(Dimension),
-      offset(winbutton.highlight_thickness), XtRImmediate,
-      (XtPointer) DEFAULT_SHAPE_HIGHLIGHT},
-   {XtNshapeStyle, XtCShapeStyle, XtRShapeStyle, sizeof(int),
-      offset(winbutton.shape_style), XtRImmediate, 
-	    (XtPointer)XawShapeRectangle},
-   {XtNcornerRoundPercent, XtCCornerRoundPercent, 
-	XtRDimension, sizeof(Dimension),
-	offset(winbutton.corner_round), XtRImmediate, (XtPointer) 25},
-   {XtNshadowThickness, XtCShadowThickness, XtRDimension, sizeof(Dimension),
-	offset(winbutton.shadow_thickness), XtRImmediate, (XtPointer) 2},
-   {XtNshadowHighlight, XtCShadowHighlight, XtRPixel, sizeof(Pixel),
-        offset(winbutton.shadow_highlight), XtRString, (XtPointer) "white"},
-   {XtNshadowShade, XtCShadowShade, XtRPixel, sizeof(Pixel),
-	offset(winbutton.shadow_shade), XtRString, (XtPointer) "grey25"},
-};
-#undef offset
-
-static Boolean SetValues();
-static void Initialize(), Redisplay(), Set(), Reset(), Notify(), Unset();
-static void Highlight(), Unhighlight(), Destroy(), PaintWinButtonWidget();
-static void ClassInitialize();
-static Boolean ShapeButton();
-static void Realize(), Resize();
-
-static XtActionsRec actionsList[] = {
-  {"set",		Set},
-  {"notify",		Notify},
-  {"highlight",		Highlight},
-  {"reset",		Reset},
-  {"unset",		Unset},
-  {"unhighlight",	Unhighlight}
-};
-
-#define SuperClass ((WinLabelWidgetClass)&winLabelClassRec)
-
-WinButtonClassRec winButtonClassRec = {
-  {
-    (WidgetClass) SuperClass,		/* superclass		  */	
-    "WinButton",			/* class_name		  */
-    sizeof(WinButtonRec),		/* size			  */
-    ClassInitialize,			/* class_initialize	  */
-    NULL,				/* class_part_initialize  */
-    FALSE,				/* class_inited		  */
-    Initialize,				/* initialize		  */
-    NULL,				/* initialize_hook	  */
-    Realize,				/* realize		  */
-    actionsList,			/* actions		  */
-    XtNumber(actionsList),		/* num_actions		  */
-    resources,				/* resources		  */
-    XtNumber(resources),		/* resource_count	  */
-    NULLQUARK,				/* xrm_class		  */
-    FALSE,				/* compress_motion	  */
-    TRUE,				/* compress_exposure	  */
-    TRUE,				/* compress_enterleave    */
-    FALSE,				/* visible_interest	  */
-    Destroy,				/* destroy		  */
-    Resize,				/* resize		  */
-    Redisplay,				/* expose		  */
-    SetValues,				/* set_values		  */
-    NULL,				/* set_values_hook	  */
-    XtInheritSetValuesAlmost,		/* set_values_almost	  */
-    NULL,				/* get_values_hook	  */
-    NULL,				/* accept_focus		  */
-    XtVersion,				/* version		  */
-    NULL,				/* callback_private	  */
-    defaultTranslations,		/* tm_table		  */
-    XtInheritQueryGeometry,		/* query_geometry	  */
-    XtInheritDisplayAccelerator,	/* display_accelerator	  */
-    NULL				/* extension		  */
-  },  /* CoreClass fields initialization */
-  {
-    XtInheritChangeSensitive		/* change_sensitive	*/
-  },  /* SimpleClass fields initialization */
-  {
-    0,                                     /* field not used    */
-  },  /* WinLabelClass fields initialization */
-  {
-    0,                                     /* field not used    */
-  },  /* WinButtonClass fields initialization */
-};
-
-  /* for public consumption */
-WidgetClass winButtonWidgetClass = (WidgetClass) &winButtonClassRec;
-
-/****************************************************************
- *
- * Private Procedures
- *
- ****************************************************************/
-
-static GC 
-Get_GC(cbw, fg, bg)
-WinButtonWidget cbw;
-Pixel fg, bg;
-{
-  XGCValues	values;
-  
-  values.foreground   = fg;
-  values.background	= bg;
-  values.font		= cbw->winlabel.font->fid;
-  values.cap_style = CapProjecting;
-  
-  if (cbw->winbutton.highlight_thickness > 1 )
-    values.line_width   = cbw->winbutton.highlight_thickness;
-  else 
-    values.line_width   = 0;
-  
-  return XtGetGC((Widget)cbw,
-		 (GCForeground|GCBackground|GCFont|GCLineWidth|GCCapStyle),
-		 &values);
-}
-
-static void 
-Get_Shadow_GCs(cbw)
-WinButtonWidget cbw;
-{
-  XGCValues	values;
-  
-  values.foreground     = cbw->winbutton.shadow_highlight;
-  values.line_width	= cbw->winbutton.shadow_thickness;
-  values.cap_style      = CapProjecting;
-  cbw->winbutton.shadow_highlight_gc =
-	  XtGetGC((Widget)cbw, (GCForeground|GCLineWidth|GCCapStyle), &values);
-
-  values.foreground     = cbw->winbutton.shadow_shade;
-  values.line_width	= cbw->winbutton.shadow_thickness;
-  values.cap_style      = CapProjecting;
-  cbw->winbutton.shadow_shade_gc =
-	  XtGetGC((Widget)cbw, (GCForeground|GCLineWidth|GCCapStyle), &values);
-}
-
-
-/* ARGSUSED */
-static void 
-Initialize(request, new, args, num_args)
-Widget request, new;
-ArgList args;			/* unused */
-Cardinal *num_args;		/* unused */
-{
-  WinButtonWidget cbw = (WinButtonWidget) new;
-  int shape_event_base, shape_error_base;
-
-  if (cbw->winbutton.shape_style != XawShapeRectangle
-      && !XShapeQueryExtension(XtDisplay(new), &shape_event_base, 
-			       &shape_error_base))
-      cbw->winbutton.shape_style = XawShapeRectangle;
-  if (cbw->winbutton.highlight_thickness == DEFAULT_SHAPE_HIGHLIGHT) {
-      if (cbw->winbutton.shape_style != XawShapeRectangle)
-	  cbw->winbutton.highlight_thickness = 0;
-      else
-	  cbw->winbutton.highlight_thickness = DEFAULT_HIGHLIGHT_THICKNESS;
-  }
-
-  XtVaSetValues(new, XtNbackground, "grey75");
-  cbw->winbutton.normal_GC = Get_GC(cbw, cbw->winlabel.foreground, 
-				  cbw->core.background_pixel);
-  cbw->winbutton.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, 
-				   cbw->winlabel.foreground);
-  XtReleaseGC(new, cbw->winlabel.normal_GC);
-  cbw->winlabel.normal_GC = cbw->winbutton.normal_GC;
-
-  Get_Shadow_GCs(cbw);
-
-  cbw->winbutton.set = FALSE;
-  cbw->winbutton.highlighted = HighlightNone;
-}
-
-static Region 
-HighlightRegion(cbw)
-WinButtonWidget cbw;
-{
-  static Region outerRegion = NULL, innerRegion, emptyRegion;
-  XRectangle rect;
-
-  if (cbw->winbutton.highlight_thickness == 0 ||
-      cbw->winbutton.highlight_thickness >
-      (Dimension) ((Dimension) Min(cbw->core.width, cbw->core.height)/2))
-    return(NULL);
-
-  if (outerRegion == NULL) {
-    /* save time by allocating scratch regions only once. */
-    outerRegion = XCreateRegion();
-    innerRegion = XCreateRegion();
-    emptyRegion = XCreateRegion();
-  }
-
-  rect.x = rect.y = 0;
-  rect.width = cbw->core.width;
-  rect.height = cbw->core.height;
-  XUnionRectWithRegion( &rect, emptyRegion, outerRegion );
-  rect.x = rect.y = cbw->winbutton.highlight_thickness;
-  rect.width -= cbw->winbutton.highlight_thickness * 2;
-  rect.height -= cbw->winbutton.highlight_thickness * 2;
-  XUnionRectWithRegion( &rect, emptyRegion, innerRegion );
-  XSubtractRegion( outerRegion, innerRegion, outerRegion );
-  return outerRegion;
-}
-
-/***************************
-*
-*  Action Procedures
-*
-***************************/
-
-/* ARGSUSED */
-static void 
-Set(w,event,params,num_params)
-Widget w;
-XEvent *event;
-String *params;		/* unused */
-Cardinal *num_params;	/* unused */
-{
-  WinButtonWidget cbw = (WinButtonWidget)w;
-
-  if (cbw->winbutton.set)
-    return;
-
-  cbw->winbutton.set= TRUE;
-  if (XtIsRealized(w))
-    PaintWinButtonWidget(w, (Region) NULL, TRUE);
-}
-
-/* ARGSUSED */
-static void
-Unset(w,event,params,num_params)
-Widget w;
-XEvent *event;
-String *params;		/* unused */
-Cardinal *num_params;
-{
-  WinButtonWidget cbw = (WinButtonWidget)w;
-
-  if (!cbw->winbutton.set)
-    return;
-
-  cbw->winbutton.set = FALSE;
-  if (XtIsRealized(w)) {
-    XClearWindow(XtDisplay(w), XtWindow(w));
-    PaintWinButtonWidget(w, (Region) NULL, TRUE);
-  }
-}
-
-/* ARGSUSED */
-static void 
-Reset(w,event,params,num_params)
-Widget w;
-XEvent *event;
-String *params;		/* unused */
-Cardinal *num_params;   /* unused */
-{
-  WinButtonWidget cbw = (WinButtonWidget)w;
-
-  if (cbw->winbutton.set) {
-    cbw->winbutton.highlighted = HighlightNone;
-    Unset(w, event, params, num_params);
-  }
-  else
-    Unhighlight(w, event, params, num_params);
-}
-
-/* ARGSUSED */
-static void 
-Highlight(w,event,params,num_params)
-Widget w;
-XEvent *event;
-String *params;		
-Cardinal *num_params;	
-{
-  WinButtonWidget cbw = (WinButtonWidget)w;
-
-  if ( *num_params == (Cardinal) 0) 
-    cbw->winbutton.highlighted = HighlightWhenUnset;
-  else {
-    if ( *num_params != (Cardinal) 1) 
-      XtWarning("Too many parameters passed to highlight action table.");
-    switch (params[0][0]) {
-    case 'A':
-    case 'a':
-      cbw->winbutton.highlighted = HighlightAlways;
-      break;
-    default:
-      cbw->winbutton.highlighted = HighlightWhenUnset;
-      break;
-    }
-  }
-
-  if (XtIsRealized(w))
-    PaintWinButtonWidget(w, HighlightRegion(cbw), TRUE);
-}
-
-/* ARGSUSED */
-static void 
-Unhighlight(w,event,params,num_params)
-Widget w;
-XEvent *event;
-String *params;		/* unused */
-Cardinal *num_params;	/* unused */
-{
-  WinButtonWidget cbw = (WinButtonWidget)w;
-
-  cbw->winbutton.highlighted = HighlightNone;
-  if (XtIsRealized(w))
-    PaintWinButtonWidget(w, HighlightRegion(cbw), TRUE);
-}
-
-/* ARGSUSED */
-static void 
-Notify(w,event,params,num_params)
-Widget w;
-XEvent *event;
-String *params;		/* unused */
-Cardinal *num_params;	/* unused */
-{
-  WinButtonWidget cbw = (WinButtonWidget)w; 
-
-  /* check to be sure state is still Set so that user can cancel
-     the action (e.g. by moving outside the window, in the default
-     bindings.
-  */
-  if (cbw->winbutton.set)
-    XtCallCallbackList(w, cbw->winbutton.callbacks, NULL);
-}
-
-/*
- * Repaint the widget window
- */
-
-/************************
-*
-*  REDISPLAY (DRAW)
-*
-************************/
-
-/* ARGSUSED */
-static void 
-Redisplay(w, event, region)
-Widget w;
-XEvent *event;
-Region region;
-{
-  PaintWinButtonWidget(w, region, FALSE);
-}
-
-/*	Function Name: PaintWinButtonWidget
- *	Description: Paints the winbutton widget.
- *	Arguments: w - the winbutton widget.
- *                 region - region to paint (passed to the superclass).
- *                 change - did it change either set or highlight state?
- *	Returns: none
- */
-
-static void 
-PaintWinButtonWidget(w, region, change)
-Widget w;
-Region region;
-Boolean change;
-{
-  WinButtonWidget cbw = (WinButtonWidget) w;
-  Boolean very_thick;
-  GC norm_gc, rev_gc;
-  int offset;
-   
-  very_thick = cbw->winbutton.highlight_thickness >
-               (Dimension)((Dimension) Min(cbw->core.width, 
-					   cbw->core.height)/2);
-
-  offset = cbw->winbutton.shadow_thickness / 2;
-  if (cbw->winbutton.set) {
-      XClearWindow(XtDisplay(w), XtWindow(w));
-      region = NULL;		/* Force label to repaint text. */
-  }
-  else {
-      XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_highlight_gc,
-		offset, offset, cbw->core.width - offset, offset);
-      XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_highlight_gc,
-		offset, offset, offset, cbw->core.height - offset);
-      XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_shade_gc,
-		offset, cbw->core.height - offset + 1, 
-		cbw->core.width - offset, cbw->core.height - offset);
-      XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_shade_gc,
-		cbw->core.width - offset, offset + 1, 
-		cbw->core.width - offset, cbw->core.height - offset);
-  }
-
-  if (cbw->winbutton.highlight_thickness <= 0)
-  {
-    (*SuperClass->core_class.expose) (w, (XEvent *) NULL, region);
-    return;
-  }
-
-/*
- * If we are set then use the same colors as if we are not highlighted. 
- */
-
-  if (cbw->winbutton.set == (cbw->winbutton.highlighted == HighlightNone)) {
-    norm_gc = cbw->winbutton.inverse_GC;
-    rev_gc = cbw->winbutton.normal_GC;
-  }
-  else {
-    norm_gc = cbw->winbutton.normal_GC;
-    rev_gc = cbw->winbutton.inverse_GC;
-  }
-
-  if ( !( (!change && (cbw->winbutton.highlighted == HighlightNone)) ||
-	  ((cbw->winbutton.highlighted == HighlightWhenUnset) &&
-	   (cbw->winbutton.set))) ) {
-    if (very_thick) {
-      cbw->winlabel.normal_GC = norm_gc; /* Give the label the right GC. */
-      XFillRectangle(XtDisplay(w),XtWindow(w), rev_gc,
-		     0, 0, cbw->core.width, cbw->core.height);
-    }
-    else {
-      /* wide lines are centered on the path, so indent it */
-      int offset = cbw->winbutton.highlight_thickness/2;
-      XDrawRectangle(XtDisplay(w),XtWindow(w), rev_gc, offset, offset, 
-		     cbw->core.width - cbw->winbutton.highlight_thickness,
-		     cbw->core.height - cbw->winbutton.highlight_thickness);
-    }
-  }
-  (*SuperClass->core_class.expose) (w, (XEvent *) NULL, region);
-}
-
-static void 
-Destroy(w)
-Widget w;
-{
-  WinButtonWidget cbw = (WinButtonWidget) w;
-
-  /* so WinLabel can release it */
-  if (cbw->winlabel.normal_GC == cbw->winbutton.normal_GC)
-    XtReleaseGC( w, cbw->winbutton.inverse_GC );
-  else
-    XtReleaseGC( w, cbw->winbutton.normal_GC );
-}
-
-/*
- * Set specified arguments into widget
- */
-
-/* ARGSUSED */
-static Boolean 
-SetValues (current, request, new)
-Widget current, request, new;
-{
-  WinButtonWidget oldcbw = (WinButtonWidget) current;
-  WinButtonWidget cbw = (WinButtonWidget) new;
-  Boolean redisplay = False;
-
-  if ( oldcbw->core.sensitive != cbw->core.sensitive && !cbw->core.sensitive) {
-    /* about to become insensitive */
-    cbw->winbutton.set = FALSE;
-    cbw->winbutton.highlighted = HighlightNone;
-    redisplay = TRUE;
-  }
-  
-  if ( (oldcbw->winlabel.foreground != cbw->winlabel.foreground)           ||
-       (oldcbw->core.background_pixel != cbw->core.background_pixel) ||
-       (oldcbw->winbutton.highlight_thickness != 
-                                   cbw->winbutton.highlight_thickness) ||
-       (oldcbw->winlabel.font != cbw->winlabel.font) ) 
-  {
-    if (oldcbw->winlabel.normal_GC == oldcbw->winbutton.normal_GC)
-	/* WinLabel has release one of these */
-      XtReleaseGC(new, cbw->winbutton.inverse_GC);
-    else
-      XtReleaseGC(new, cbw->winbutton.normal_GC);
-
-    cbw->winbutton.normal_GC = Get_GC(cbw, cbw->winlabel.foreground, 
-				    cbw->core.background_pixel);
-    cbw->winbutton.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, 
-				     cbw->winlabel.foreground);
-    XtReleaseGC(new, cbw->winlabel.normal_GC);
-    cbw->winlabel.normal_GC = (cbw->winbutton.set
-			    ? cbw->winbutton.inverse_GC
-			    : cbw->winbutton.normal_GC);
-    
-    redisplay = True;
-  }
-
-  if ( XtIsRealized(new)
-       && oldcbw->winbutton.shape_style != cbw->winbutton.shape_style
-       && !ShapeButton(cbw, TRUE))
-  {
-      cbw->winbutton.shape_style = oldcbw->winbutton.shape_style;
-  }
-
-  return (redisplay);
-}
-
-static void ClassInitialize()
-{
-    XawInitializeWidgetSet();
-    XtSetTypeConverter( XtRString, XtRShapeStyle, XmuCvtStringToShapeStyle,
-		        NULL, 0, XtCacheNone, NULL );
-}
-
-
-static Boolean
-ShapeButton(cbw, checkRectangular)
-WinButtonWidget cbw;
-Boolean checkRectangular;
-{
-    Dimension corner_size;
-
-    if ( (cbw->winbutton.shape_style == XawShapeRoundedRectangle) ) {
-	corner_size = (cbw->core.width < cbw->core.height) ? cbw->core.width 
-	                                                   : cbw->core.height;
-	corner_size = (int) (corner_size * cbw->winbutton.corner_round) / 100;
-    }
-
-    if (checkRectangular || cbw->winbutton.shape_style != XawShapeRectangle) {
-	if (!XmuReshapeWidget((Widget) cbw, cbw->winbutton.shape_style,
-			      corner_size, corner_size)) {
-	    cbw->winbutton.shape_style = XawShapeRectangle;
-	    return(False);
-	}
-    }
-    return(TRUE);
-}
-
-static void Realize(w, valueMask, attributes)
-    Widget w;
-    Mask *valueMask;
-    XSetWindowAttributes *attributes;
-{
-    (*winButtonWidgetClass->core_class.superclass->core_class.realize)
-	(w, valueMask, attributes);
-
-    ShapeButton( (WinButtonWidget) w, FALSE);
-}
-
-static void Resize(w)
-    Widget w;
-{
-    if (XtIsRealized(w)) 
-	ShapeButton( (WinButtonWidget) w, FALSE);
-
-    (*winButtonWidgetClass->core_class.superclass->core_class.resize)(w);
-}
-
diff --git a/controls/WinButton.h b/controls/WinButton.h
deleted file mode 100644
index 54dee6a..0000000
--- a/controls/WinButton.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/***********************************************************
-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
-and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the names of Digital or MIT not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
- * Modifications for Wine
- *
- * 8/28/93  David Metcalfe (david@prism.demon.co.uk)
- *          Created from Command widget and added 3D effect
- */
-
-#ifndef _WinButton_h
-#define _WinButton_h
-
-#include "WinLabel.h"
-
-/* WinButton widget resources:
-
- Name		     Class		RepType		Default Value
- ----		     -----		-------		-------------
- accelerators	     Accelerators	AcceleratorTable NULL
- ancestorSensitive   AncestorSensitive	Boolean		True
- background	     Background		Pixel		XtDefaultBackground
- backgroundPixmap    Pixmap		Pixmap		XtUnspecifiedPixmap
- bitmap		     Pixmap		Pixmap		None
- borderColor	     BorderColor	Pixel		XtDefaultForeground
- borderPixmap	     Pixmap		Pixmap		XtUnspecifiedPixmap
- borderWidth	     BorderWidth	Dimension	1
- callback	     Callback		XtCallbackList	NULL
- colormap	     Colormap		Colormap	parent's colormap
- cornerRoundPercent  CornerRoundPercent	Dimension	25
- cursor		     Cursor		Cursor		None
- cursorName	     Cursor		String		NULL
- depth		     Depth		int		parent's depth
- destroyCallback     Callback		XtCallbackList	NULL
- encoding	     Encoding		UnsignedChar	XawTextEncoding8bit
- font		     Font		XFontStruct*	XtDefaultFont
- foreground	     Foreground		Pixel		XtDefaultForeground
- height		     Height		Dimension	text height
- highlightThickness  Thickness		Dimension	0 if shaped, else 2
- insensitiveBorder   Insensitive	Pixmap		Gray
- internalHeight	     Height		Dimension	2
- internalWidth	     Width		Dimension	4
- justify	     Justify		XtJustify	XtJustifyCenter
- label		     Label		String		NULL
- leftBitmap	     LeftBitmap		Pixmap		None
- mappedWhenManaged   MappedWhenManaged	Boolean		True
- pointerColor	     Foreground		Pixel		XtDefaultForeground
- pointerColorBackground Background	Pixel		XtDefaultBackground
- resize		     Resize		Boolean		True
- screen		     Screen		Screen		parent's Screen
- sensitive	     Sensitive		Boolean		True
- shadowHighlight     ShadowHighlight    Pixel           White
- shadowShade         ShadowShade        Pixel           Grey25
- shadowThickness     ShadowThickness    Dimension       2 
- shapeStyle	     ShapeStyle		ShapeStyle	Rectangle
- translations	     Translations	TranslationTable see doc or source
- width		     Width		Dimension	text width
- x		     Position		Position	0
- y		     Position		Position	0
-
-*/
-
-#define XtNhighlightThickness "highlightThickness"
-
-#define XtNshapeStyle "shapeStyle"
-#define XtCShapeStyle "ShapeStyle"
-#define XtRShapeStyle "ShapeStyle"
-#define XtNcornerRoundPercent "cornerRoundPercent"
-#define XtCCornerRoundPercent "CornerRoundPercent"
-#define XtNshadowThickness "shadowThickness"
-#define XtCShadowThickness "ShadowThickness"
-#define XtNshadowHighlight "shadowHighlight"
-#define XtCShadowHighlight "ShadowHighlight"
-#define XtNshadowShade "shadowShade"
-#define XtCShadowShade "ShadowShade"
-
-#define XawShapeRectangle XmuShapeRectangle
-#define XawShapeOval XmuShapeOval
-#define XawShapeEllipse XmuShapeEllipse
-#define XawShapeRoundedRectangle XmuShapeRoundedRectangle
-
-extern WidgetClass     winButtonWidgetClass;
-
-typedef struct _WinButtonClassRec   *WinButtonWidgetClass;
-typedef struct _WinButtonRec        *WinButtonWidget;
-
-#endif /* _WinButton_h */
-/* DON'T ADD STUFF AFTER THIS */
diff --git a/controls/WinButtonP.h b/controls/WinButtonP.h
deleted file mode 100644
index 207f19a..0000000
--- a/controls/WinButtonP.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/***********************************************************
-Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
-and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the names of Digital or MIT not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
- * Modifications for Wine
- *
- * 8/28/93  David Metcalfe (david@prism.demon.co.uk)
- *          Created from Command widget and added 3D effect
- */
-
-/* 
- * WinButtonP.h - Private definitions for WinButton widget
- * 
- */
-
-#ifndef _WinButtonP_h
-#define _WinButtonP_h
-
-#include "WinButton.h"
-#include "WinLabelP.h"
-
-/***********************************************************************
- *
- * WinButton Widget Private Data
- *
- ***********************************************************************/
-
-typedef enum {
-  HighlightNone,		/* Do not highlight. */
-  HighlightWhenUnset,		/* Highlight only when unset, this is
-				   to preserve current command widget 
-				   functionality. */
-  HighlightAlways		/* Always highlight, lets the toggle widget
-				   and other subclasses do the right thing. */
-} XtCommandHighlight;
-
-/************************************
- *
- *  Class structure
- *
- ***********************************/
-
-
-   /* New fields for the WinButton widget class record */
-typedef struct _WinButtonClass 
-  {
-    int makes_compiler_happy;  /* not used */
-  } WinButtonClassPart;
-
-   /* Full class record declaration */
-typedef struct _WinButtonClassRec {
-    CoreClassPart	core_class;
-    SimpleClassPart	simple_class;
-    WinLabelClassPart	winlabel_class;
-    WinButtonClassPart  winbutton_class;
-} WinButtonClassRec;
-
-extern WinButtonClassRec winButtonClassRec;
-
-/***************************************
- *
- *  Instance (widget) structure 
- *
- **************************************/
-
-    /* New fields for the WinButton widget record */
-typedef struct {
-    /* resources */
-    Dimension   highlight_thickness;
-    Dimension   shadow_thickness;
-    Pixel       shadow_shade;
-    Pixel       shadow_highlight;
-    XtCallbackList callbacks;
-
-    /* private state */
-    Pixmap      	gray_pixmap;
-    GC          	normal_GC;
-    GC          	inverse_GC;
-    GC                  shadow_highlight_gc;
-    GC                  shadow_shade_gc;
-    Boolean     	set;
-    XtCommandHighlight	highlighted;
-    /* more resources */
-    int			shape_style;    
-    Dimension		corner_round;
-} WinButtonPart;
-
-
-/*    XtEventsPtr eventTable;*/
-
-
-   /* Full widget declaration */
-typedef struct _WinButtonRec {
-    CorePart         core;
-    SimplePart	     simple;
-    WinLabelPart     winlabel;
-    WinButtonPart    winbutton;
-} WinButtonRec;
-
-#endif /* _WinButtonP_h */
-
-
diff --git a/controls/button.c b/controls/button.c
index 3a65bc0..f843beb 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -1,86 +1,351 @@
-/*
- * Interface code to button widgets
+/* File: button.c -- MS-Windows(tm) compatible "Button" replacement widget
  *
- * Copyright  David W. Metcalfe, 1993
+ *                   programmed by Johannes Ruscheinski for the Linux WABI
+ *                   project.
+ *		     (C) 1993 by Johannes Ruscheinski
  *
+ *                   Modifications by David Metcalfe
  */
 
-static char Copyright[] = "Copyright  David W. Metcalfe, 1993";
-
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include "WinButton.h"
-#include "windows.h"
-#include "heap.h"
+#include <windows.h>
 #include "win.h"
 
-static void BUTTON_WinButtonCallback(Widget w, XtPointer client_data,
-				               XtPointer call_data);
+LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);
 
-void BUTTON_CreateButton(LPSTR className, LPSTR buttonLabel, HWND hwnd)
+static COLORREF color_windowframe, color_btnface, color_btnshadow,
+		color_btntext, color_btnhighlight;
+
+static BOOL pressed;
+
+#define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
+	SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
+		    GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
+#define DIM(array)	((sizeof array)/(sizeof array[0]))
+
+static LONG PB_Paint(HWND hWnd);
+static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
+static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
+static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
+static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc);
+static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc);
+
+typedef struct
 {
-    WND *wndPtr    = WIN_FindWndPtr(hwnd);
-    WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
-    DWORD style;
-    char widgetName[15];
+    LONG (*paintfn)();
+    LONG (*lButtonDownfn)();
+    LONG (*lButtonUpfn)();
+    LONG (*lButtonDblClkfn)();
+} BTNFN;
 
-#ifdef DEBUG_BUTTON
-    printf("button: label = %s, x = %d, y = %d\n", buttonLabel,
-	   wndPtr->rectClient.left, wndPtr->rectClient.top);
-    printf("        width = %d, height = %d\n",
-	   wndPtr->rectClient.right - wndPtr->rectClient.left,
-	   wndPtr->rectClient.bottom - wndPtr->rectClient.top);
+#define MAX_BTN_TYPE  2
+
+static BTNFN btnfn[MAX_BTN_TYPE] =
+{
+    { 
+	(LONG(*)())PB_Paint,                       /* BS_PUSHBUTTON */
+	(LONG(*)())PB_LButtonDown,
+	(LONG(*)())PB_LButtonUp,
+	(LONG(*)())PB_LButtonDblClk
+    },
+    { 
+	(LONG(*)())PB_Paint,                       /* BS_DEFPUSHBUTTON */
+	(LONG(*)())PB_LButtonDown,
+	(LONG(*)())PB_LButtonUp,
+	(LONG(*)())PB_LButtonDblClk
+    }
+};
+
+
+LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
+{
+	LONG lResult = 0;
+	HDC hDC;
+	RECT rc;
+
+	WND *wndPtr = WIN_FindWndPtr(hWnd);
+	LONG style = wndPtr->dwStyle & 0x0000000F;
+
+	switch (uMsg) {
+/*	case WM_GETDLGCODE:
+		lResult = DLGC_BUTTON;
+		break;
+*/
+	case WM_ENABLE:
+		InvalidateRect(hWnd, NULL, FALSE);
+		break;
+
+	case WM_CREATE:
+		if (style < 0L || style >= (LONG)DIM(btnfn))
+		    lResult = -1L;
+		else
+		{
+		    /* initialise colours used for button rendering: */
+		    color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
+		    color_btnface      = GetSysColor(COLOR_BTNFACE);
+		    color_btnshadow    = GetSysColor(COLOR_BTNSHADOW);
+		    color_btntext      = GetSysColor(COLOR_BTNTEXT);
+		    color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
+
+		    pressed = FALSE;
+		    lResult = 0L;
+		}
+		break;
+
+	case WM_PAINT:
+		(btnfn[style].paintfn)(hWnd);
+		break;
+
+	case WM_LBUTTONDOWN:
+		(btnfn[style].lButtonDownfn)(hWnd, wParam, lParam);
+		break;
+
+	case WM_LBUTTONUP:
+		(btnfn[style].lButtonUpfn)(hWnd, wParam, lParam);
+		break;
+
+	case WM_LBUTTONDBLCLK:
+		(btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam);
+		break;
+
+	case WM_SETFOCUS:
+		break;
+
+	case WM_KILLFOCUS:
+		InvalidateRect(hWnd, NULL, FALSE);
+		UpdateWindow(hWnd);
+		break;
+
+	case WM_SYSCOLORCHANGE:
+		color_windowframe  = GetSysColor(COLOR_WINDOWFRAME);
+		color_btnface      = GetSysColor(COLOR_BTNFACE);
+		color_btnshadow    = GetSysColor(COLOR_BTNSHADOW);
+		color_btntext      = GetSysColor(COLOR_BTNTEXT);
+		color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
+		InvalidateRect(hWnd, NULL, TRUE);
+		break;
+
+	default:
+		lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
+		break;
+	}
+
+	GlobalUnlock(hWnd);
+	return lResult;
+}
+
+
+/**********************************************************************
+ *       Push Button Functions
+ */
+
+static LONG PB_Paint(HWND hWnd)
+{
+    PAINTSTRUCT ps;
+    RECT rc;
+    HDC hDC;
+
+    hDC = BeginPaint(hWnd, &ps);
+    GetClientRect(hWnd, &rc);
+    if (pressed)
+	DrawPressedPushButton(hDC, hWnd, rc);
+    else
+	DrawRaisedPushButton(hDC, hWnd, rc);
+    EndPaint(hWnd, &ps);
+}
+
+static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
+{
+/*  SetFocus(hWnd);   */
+    SetCapture(hWnd);
+    pressed = TRUE;
+    InvalidateRect(hWnd, NULL, FALSE);
+    UpdateWindow(hWnd);
+}
+
+static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
+{
+    RECT rc;
+
+    pressed = FALSE;
+    ReleaseCapture();
+    GetClientRect(hWnd, &rc);
+    if (PtInRect(&rc, MAKEPOINT(lParam)))
+	NOTIFY_PARENT(hWnd, BN_CLICKED);
+    InvalidateRect(hWnd, NULL, FALSE);
+    UpdateWindow(hWnd);
+}
+
+static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
+{
+    RECT rc;
+
+    GetClientRect(hWnd, &rc);
+    if (PtInRect(&rc, MAKEPOINT(lParam)))
+	NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
+}
+
+static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
+{
+	HPEN hOldPen, hFramePen;
+	HBRUSH hOldBrush, hShadowBrush, hHighlightBrush, hBackgrndBrush;
+	HRGN rgn1, rgn2, rgn;
+	int len;
+	static char text[50+1];
+	POINT points[6];
+	DWORD dwTextSize;
+	int delta;
+	TEXTMETRIC tm;
+	int i;
+
+	hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
+	hBackgrndBrush = CreateSolidBrush(color_btnface);
+
+	hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
+	hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
+	SetBkMode(hDC, TRANSPARENT);
+
+	rgn = CreateRectRgn(0, 0,  0,  0);
+	rgn1 = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
+
+	SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
+		    MAKELPARAM(hButton, CTLCOLOR_BTN));
+	Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
+
+	/* draw button label, if any: */
+	len = GetWindowText(hButton, text, sizeof text);
+	if (len >= 1) {
+		rc.left--;	rc.bottom--;
+		DrawText(hDC, text, len, &rc,
+			 DT_SINGLELINE | DT_CENTER| DT_VCENTER);
+	}
+
+	/* draw button highlight */
+	points[0].x = rc.left+2;
+	points[0].y = rc.bottom;
+	points[1].x = rc.left+4;
+	points[1].y = rc.bottom-2;
+	points[2].x = rc.left+4;
+	points[2].y = rc.top+3;
+	points[3].x = rc.right-3;
+	points[3].y = rc.top+3;
+	points[4].x = rc.right-1;
+	points[4].y = rc.top+1;
+	points[5].x = rc.left+2;
+	points[5].y = rc.top+1;
+	hHighlightBrush = CreateSolidBrush(color_btnhighlight);
+	rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
+	CombineRgn(rgn, rgn1, rgn2, RGN_AND);
+	FillRgn(hDC, rgn2, hHighlightBrush);
+
+	/* draw button shadow: */
+	points[0].x = rc.left+2;
+	points[0].y = rc.bottom;
+	points[1].x = rc.left+4;
+	points[1].y = rc.bottom-2;
+	points[2].x = rc.right-3;
+	points[2].y = rc.bottom-2;
+	points[3].x = rc.right-3;
+	points[3].y = rc.top+3;
+	points[4].x = rc.right-1;
+	points[4].y = rc.top;
+	points[5].x = rc.right-1;
+	points[5].y = rc.bottom;
+	hShadowBrush = CreateSolidBrush(color_btnshadow);
+	rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
+	CombineRgn(rgn, rgn1, rgn2, RGN_AND);
+	FillRgn(hDC, rgn2, hShadowBrush);
+
+#if 0
+	/* do we have the focus? */
+	if (len >= 1 && GetFocus() == hButton) {
+		dwTextSize = GetTextExtent(hDC, text, len);
+		delta = ((rc.right - rc.left) - LOWORD(dwTextSize) + 1) >> 1;
+		rc.left += delta;	rc.right -= delta;
+		GetTextMetrics(hDC, &tm);
+		delta = ((rc.bottom - rc.top) -
+			 tm.tmHeight + tm.tmInternalLeading) >> 1;
+		rc.top += delta; 	rc.bottom -= delta;
+		DrawFocusRect(hDC, &rc);
+	}
 #endif
 
-    if (!wndPtr)
-	return;
-
-    style = wndPtr->dwStyle & 0x0000000F;
-
-    switch (style)
-    {
-    case BS_PUSHBUTTON:
-    case BS_DEFPUSHBUTTON:
-	sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu);
-	wndPtr->winWidget = XtVaCreateManagedWidget(widgetName,
-				      winButtonWidgetClass,
-				      parentPtr->winWidget,
-				      XtNlabel, buttonLabel,
-				      XtNx, wndPtr->rectClient.left,
-				      XtNy, wndPtr->rectClient.top,
-				      XtNwidth, wndPtr->rectClient.right -
-					        wndPtr->rectClient.left,
-				      XtNheight, wndPtr->rectClient.bottom -
-					         wndPtr->rectClient.top,
-				      XtVaTypedArg, XtNbackground, XtRString,
-					      "grey70", strlen("grey75")+1,
-				      NULL);
-
-	XtAddCallback(wndPtr->winWidget, XtNcallback,
-		      BUTTON_WinButtonCallback, (XtPointer) hwnd);
-	break;
-
-    default:
-	printf("CreateButton: Unsupported button style %lX\n", 
-	                                         wndPtr->dwStyle);
-    }
-
-    GlobalUnlock(hwnd);
-    GlobalUnlock(wndPtr->hwndParent);
+	SelectObject(hDC, (HANDLE)hOldPen);
+	SelectObject(hDC, (HANDLE)hOldBrush);
+	DeleteObject((HANDLE)hFramePen);
+	DeleteObject((HANDLE)hShadowBrush);
+	DeleteObject((HANDLE)hBackgrndBrush);
+	DeleteObject((HANDLE)rgn1);
+#if 0
+	DeleteObject((HANDLE)rgn2);
+	DeleteObject((HANDLE)rgn);
+#endif
 }
 
-static void BUTTON_WinButtonCallback(Widget w, XtPointer client_data,
-				               XtPointer call_data)
+
+static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
 {
-    HWND hwnd = (HWND) client_data;
-    WND  *wndPtr;
-    wndPtr = WIN_FindWndPtr(hwnd);
+	HPEN hOldPen, hShadowPen, hFramePen;
+	HBRUSH hOldBrush, hBackgrndBrush;
+	HRGN rgn1, rgn2, rgn;
+	int len;
+	static char text[50+1];
+	DWORD dwTextSize;
+	int delta;
+	TEXTMETRIC tm;
 
-    CallWindowProc(wndPtr->lpfnWndProc, wndPtr->hwndParent, WM_COMMAND,
-		   wndPtr->wIDmenu, MAKELPARAM(hwnd, BN_CLICKED));
+	hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
+	hBackgrndBrush = CreateSolidBrush(color_btnface);
 
-    GlobalUnlock(hwnd);
+	hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
+	hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
+	SetBkMode(hDC, TRANSPARENT);
+
+	/* give parent a chance to alter parameters: */
+	SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
+		    MAKELPARAM(hButton, CTLCOLOR_BTN));
+	Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
+
+	/* draw button shadow: */
+	hShadowPen = CreatePen(PS_SOLID, 1, color_btnshadow);
+	SelectObject(hDC, (HANDLE)hShadowPen);
+	MoveTo(hDC, rc.left+1, rc.bottom-1);
+	LineTo(hDC, rc.left+1, rc.top+1);
+	LineTo(hDC, rc.right-1, rc.top+1);
+
+	/* draw button label, if any: */
+	len = GetWindowText(hButton, text, sizeof text);
+	if (len >= 1) {
+		rc.top++;	rc.left++;
+		DrawText(hDC, text, len, &rc,
+			 DT_SINGLELINE | DT_CENTER| DT_VCENTER);
+	}
+
+#if 0
+	/* do we have the focus? */
+	if (len >= 1 && GetFocus() == hButton) {
+		dwTextSize = GetTextExtent(hDC, text, len);
+		delta = ((rc.right - rc.left) - LOWORD(dwTextSize)) >> 1;
+		rc.left += delta;	rc.right -= delta;
+		GetTextMetrics(hDC, &tm);
+		delta = ((rc.bottom - rc.top) -
+			 tm.tmHeight + tm.tmInternalLeading) >> 1;
+		rc.top += delta; 	rc.bottom -= delta;
+		DrawFocusRect(hDC, &rc);
+	}
+#endif
+
+	SelectObject(hDC, (HANDLE)hOldPen);
+	SelectObject(hDC, (HANDLE)hOldBrush);
+	DeleteObject((HANDLE)hBackgrndBrush);
+	DeleteObject(SelectObject(hDC, (HANDLE)hFramePen));
+	DeleteObject(SelectObject(hDC, (HANDLE)hShadowPen));
 }
 
 
 
+
+
+
+
+
+
diff --git a/controls/menu.c b/controls/menu.c
index 951fc74..2d22115 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -141,7 +141,7 @@
     menu = MENU_FindMenuBar(this_item);
     if (menu != NULL)
     {
-	wndPtr = (WND *) GlobalLock(menu->ownerWnd);
+	wndPtr = WIN_FindWndPtr(menu->ownerWnd);
 	if (wndPtr == NULL)
 	    return;
 
@@ -152,8 +152,6 @@
 	
 	CallWindowProc(wndPtr->lpfnWndProc, menu->ownerWnd, WM_COMMAND,
 		       this_item->item_id, 0);
-	
-	GlobalUnlock(menu->ownerWnd);
     }
 }
 
diff --git a/controls/widgets.c b/controls/widgets.c
index 3c68d9c..90272e5 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -10,8 +10,7 @@
 #include "win.h"
 
 
-static LONG WIDGETS_ButtonWndProc( HWND hwnd, WORD message,
-				   WORD wParam, LONG lParam );
+LONG ButtonWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 static LONG WIDGETS_StaticWndProc( HWND hwnd, WORD message,
 				   WORD wParam, LONG lParam );
 
@@ -19,8 +18,8 @@
 
 static WNDCLASS WIDGETS_BuiltinClasses[NB_BUILTIN_CLASSES] =
 {
-    { 0, WIDGETS_ButtonWndProc, 0, 0, 0, 0, 0, 0, NULL, "BUTTON" },
-    { 0, WIDGETS_StaticWndProc, 0, 0, 0, 0, 0, 0, NULL, "STATIC" }
+    { 0, (LONG(*)())ButtonWndProc, 0, 0, 0, 0, 0, 0, NULL, "BUTTON" },
+    { 0, (LONG(*)())WIDGETS_StaticWndProc, 0, 0, 0, 0, 0, 0, NULL, "STATIC" }
 };
 
 static FARPROC WndProc32[NB_BUILTIN_CLASSES];
@@ -38,8 +37,6 @@
         
     for (i = 0; i < NB_BUILTIN_CLASSES; i++, pClass++)
     {
-	WndProc32[i] = pClass->lpfnWndProc;
-	pClass->lpfnWndProc = (FARPROC) i+1;
 	if (!RegisterClass(pClass)) return FALSE;
     }
     return TRUE;
@@ -61,39 +58,6 @@
 
 
 /***********************************************************************
- *           WIDGETS_ButtonWndProc
- */
-static LONG WIDGETS_ButtonWndProc( HWND hwnd, WORD message,
-				   WORD wParam, LONG lParam )
-{    
-    switch(message)
-    {
-    case WM_CREATE:
-	return 0;
-	
-    case WM_PAINT:
-    {
-	PAINTSTRUCT ps;
-	BeginPaint( hwnd, &ps );
-	EndPaint( hwnd, &ps );
-	return 0;
-    }
-
-    case WM_COMMAND:
-    {
-	WND  *wndParent;
-	wndParent = WIN_FindWndPtr(hwnd);
-	CallWindowProc(wndParent->lpfnWndProc, hwnd, message, wParam, lParam);
-	return 0;
-    }
-	
-    default:
-	return DefWindowProc( hwnd, message, wParam, lParam );
-    }
-}
-
-
-/***********************************************************************
  *           WIDGETS_StaticWndProc
  */
 static LONG WIDGETS_StaticWndProc( HWND hwnd, WORD message,
diff --git a/debugger/Makefile b/debugger/Makefile
new file mode 100644
index 0000000..493297a
--- /dev/null
+++ b/debugger/Makefile
@@ -0,0 +1,31 @@
+CFLAGS=-g -I../include # -DUSE_READLINE
+LIBS= readline/libedit.a
+OBJS=dbg.tab.o hash.o lex.yy.o info.o i386-pinsn.o
+
+debugger.o: ${OBJS} readline/libedit.a
+	(cd readline; make)
+	ld -r -o debugger.o ${OBJS} $(LIBS)
+
+
+readline/libedit.a:
+	(cd readline; make)
+
+dbg.tab.o: dbg.tab.c
+	gcc  $(CFLAGS) -DYYDEBUG=1 -c dbg.tab.c
+
+lex.yy.o: lex.yy.c
+	gcc $(CFLAGS) -I. -c lex.yy.c
+
+
+lex.yy.c: debug.l
+	flex -I debug.l
+
+dbg.tab.c dbg.tab.h: dbg.y
+	bison -v -d  dbg.y
+
+dtest: dtest.o debugger.o
+	gcc -o dtest dtest.o debugger.o
+
+clean:
+	rm -f *.o main dbg.tab.* lex.yy.* *.output *~ *# dtest
+	(cd readline; make clean)
diff --git a/debugger/README b/debugger/README
new file mode 100644
index 0000000..5715339
--- /dev/null
+++ b/debugger/README
@@ -0,0 +1,17 @@
+
+	This is the core of the Wine debugger.  Many pieces have been
+shamelessly stolen - the reverse assember was stolen from gdb more or
+less intact.  It turns out that there are two variables that are set
+differently if you are reverse assembling 16 bit code, and on the
+whole it seems to work.  There may be bugs for all I know.
+
+	As far as non-linux systems are concerned, I simply ripped off
+the linux configuration files from gdb.  Other systems may be close
+enough for these to work properly, but some tweaking may be required.
+
+	I apologize for the non-portability of this, but I wrote the
+whole thing in about 4 hours, most of the time spent debugging a
+stupid mistake in the parser.
+
+-Eric
+
diff --git a/debugger/TODO b/debugger/TODO
new file mode 100644
index 0000000..54de7a6
--- /dev/null
+++ b/debugger/TODO
@@ -0,0 +1,30 @@
+This is a list of things that theoretically should be possible in some
+way or another.  No commitment to actually do these, but these sound
+possible to me right now.   In no particular order.  If someone else
+wants to dig in, feel free.
+
+1) Some kind of crude display capability.  Not too hard, I guess.
+	Just keep a list of addresses, counts and formats that we
+	want displayed each time we enter the debugger.
+
+2) Some kind of single step capability.
+	I am not sure - I think you just set a flag
+	in AFLAGS, and you get an interrupt back again.
+	The signal type would proabably be different, however,
+	but Wine could easily be patched to accept this one as well.
+	The main problem with this is that gdb normally runs in a
+	separate process so it is easy to single step second process.
+	Here we are all part of the same process.  Perhaps we could look
+	ahead to the end of the instruction and set another breakpoint?
+
+3) Some kind of breakpoint capability.
+	Requires single step.  When we restart, we
+	remove the breakpoint, single step one instruction
+	replace the breakpoint, and then continue.
+
+4) Some kind of watchpoint capability.  Pretty easy once we have a
+	single step capability, but we end up running the program
+	really slowly one instruction at a time.
+
+5) Some kind of .wdbinit file.
+
diff --git a/debugger/ansidecl.h b/debugger/ansidecl.h
new file mode 100644
index 0000000..68e4d75
--- /dev/null
+++ b/debugger/ansidecl.h
@@ -0,0 +1,127 @@
+/* ANSI and traditional C compatability macros
+   Copyright 1991 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* ANSI and traditional C compatibility macros
+
+   ANSI C is assumed if __STDC__ is #defined.
+
+   Macro	ANSI C definition	Traditional C definition
+   -----	---- - ----------	----------- - ----------
+   PTR		`void *'		`char *'
+   LONG_DOUBLE	`long double'		`double'
+   CONST	`const'			`'
+   VOLATILE	`volatile'		`'
+   SIGNED	`signed'		`'
+   PTRCONST	`void *const'		`char *'
+
+   DEFUN(name, arglist, args)
+
+	Defines function NAME.
+
+	ARGLIST lists the arguments, separated by commas and enclosed in
+	parentheses.  ARGLIST becomes the argument list in traditional C.
+
+	ARGS list the arguments with their types.  It becomes a prototype in
+	ANSI C, and the type declarations in traditional C.  Arguments should
+	be separated with `AND'.  For functions with a variable number of
+	arguments, the last thing listed should be `DOTS'.
+
+   DEFUN_VOID(name)
+
+	Defines a function NAME, which takes no arguments.
+
+   EXFUN(name, prototype)
+
+	Is used in an external function declaration.
+	In ANSI C it is `NAMEPROTOTYPE' (so PROTOTYPE should be enclosed in
+	parentheses).  In traditional C it is `NAME()'.
+	For a function that takes no arguments, PROTOTYPE should be `(NOARGS)'.
+
+    For example:
+	extern int EXFUN(printf, (CONST char *format DOTS));
+	int DEFUN(fprintf, (stream, format),
+		  FILE *stream AND CONST char *format DOTS) { ... }
+	void DEFUN_VOID(abort) { ... }
+*/
+
+#ifndef	_ANSIDECL_H
+
+#define	_ANSIDECL_H	1
+
+
+/* Every source file includes this file,
+   so they will all get the switch for lint.  */
+/* LINTLIBRARY */
+
+
+#ifdef	__STDC__
+
+#define	PTR		void *
+#define	PTRCONST	void *CONST
+#define	LONG_DOUBLE	long double
+
+#define	AND		,
+#define	NOARGS		void
+#define	CONST		const
+#define	VOLATILE	volatile
+#define	SIGNED		signed
+#define	DOTS		, ...
+
+#define	EXFUN(name, proto)		name proto
+#define	DEFUN(name, arglist, args)	name(args)
+#define	DEFUN_VOID(name)		name(NOARGS)
+
+#define PROTO(type, name, arglist) type name arglist
+
+/* We could use the EXFUN macro to handle prototypes, but
+   the name is misleading and the result is ugly.  So just define a
+   simple macro to handle the parameter lists, as in:
+
+	static int foo PARAMS ((int, char));
+
+   EXFUN would do it like this:
+
+	static int EXFUN (foo, (int, char));
+
+   but the function is not external...  EXFUN should be considered
+   obsolete, and new code written to use PARAMS.  */
+
+#define PARAMS(paramlist) paramlist
+
+#else	/* Not ANSI C.  */
+
+#define	PTR		char *
+#define	PTRCONST	PTR
+#define	LONG_DOUBLE	double
+
+#define	AND		;
+#define	NOARGS
+#define	CONST
+#define	VOLATILE
+#define	SIGNED
+#define	DOTS
+
+#define	EXFUN(name, proto)		name()
+#define	DEFUN(name, arglist, args)	name arglist args;
+#define	DEFUN_VOID(name)		name()
+#define PROTO(type, name, arglist) type name ()
+#define PARAMS(paramlist)		()
+
+#endif	/* ANSI C.  */
+
+#endif	/* ansidecl.h	*/
diff --git a/debugger/bfd.h b/debugger/bfd.h
new file mode 100644
index 0000000..430b0ab
--- /dev/null
+++ b/debugger/bfd.h
@@ -0,0 +1,1421 @@
+/* A -*- C -*- header file for the bfd library
+   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* bfd.h -- The only header file required by users of the bfd library 
+
+This file is generated from various .c files, if you change it, your
+bits may be lost.
+
+All the prototypes and definitions following the comment "THE FOLLOWING
+IS EXTRACTED FROM THE SOURCE" are extracted from the source files for
+BFD.  If you change it, someone oneday will extract it from the source
+again, and your changes will be lost.  To save yourself from this bind,
+change the definitions in the source in the bfd directory.  Type "make
+docs" and then "make headers" in that directory, and magically this file
+will change to reflect your changes.
+
+If you don't have the tools to perform the extraction, then you are
+safe from someone on your system trampling over your header files.
+You should still maintain the equivalence between the source and this
+file though; every change you make to the .c file should be reflected
+here.  */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#include "ansidecl.h"
+#include "obstack.h"
+
+/* Make it easier to declare prototypes (puts conditional here) */
+#ifndef PROTO
+#	if __STDC__
+#		define PROTO(type, name, arglist) type name arglist
+#	else
+#		define PROTO(type, name, arglist) type name ()
+#	endif
+#endif
+
+#define BFD_VERSION "2.0"
+
+/* forward declaration */
+typedef struct _bfd bfd;
+
+/* General rules: functions which are boolean return true on success
+   and false on failure (unless they're a predicate).   -- bfd.doc */
+/* I'm sure this is going to break something and someone is going to
+   force me to change it. */
+/* typedef enum boolean {false, true} boolean; */
+/* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h>  -fnf */
+typedef enum bfd_boolean {false, true} boolean;
+
+/* A pointer to a position in a file.  */
+/* FIXME:  This should be using off_t from <sys/types.h>.
+   For now, try to avoid breaking stuff by not including <sys/types.h> here.
+   This will break on systems with 64-bit file offsets (e.g. 4.4BSD).
+   Probably the best long-term answer is to avoid using file_ptr AND off_t 
+   in this header file, and to handle this in the BFD implementation
+   rather than in its interface.  */
+/* typedef off_t	file_ptr; */
+typedef long int file_ptr;
+
+/* Support for different sizes of target format ints and addresses */
+
+#ifdef	HOST_64_BIT
+typedef HOST_64_BIT rawdata_offset;
+typedef HOST_64_BIT bfd_vma;
+typedef HOST_64_BIT bfd_word;
+typedef HOST_64_BIT bfd_offset;
+typedef HOST_64_BIT bfd_size_type;
+typedef HOST_64_BIT symvalue;
+typedef HOST_64_BIT bfd_64_type;
+#define fprintf_vma(s,x) \
+		fprintf(s,"%08x%08x", uint64_typeHIGH(x), uint64_typeLOW(x))
+#else
+typedef struct {int a,b;} bfd_64_type;
+typedef unsigned long rawdata_offset;
+typedef unsigned long bfd_vma;
+typedef unsigned long bfd_offset;
+typedef unsigned long bfd_word;
+typedef unsigned long bfd_size;
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+#define fprintf_vma(s,x) fprintf(s, "%08lx", x)
+#endif
+#define printf_vma(x) fprintf_vma(stdout,x)
+
+typedef unsigned int flagword;	/* 32 bits of flags */
+
+/** File formats */
+
+typedef enum bfd_format {
+	      bfd_unknown = 0,	/* file format is unknown */
+	      bfd_object,	/* linker/assember/compiler output */
+	      bfd_archive,	/* object archive file */
+	      bfd_core,		/* core dump */
+	      bfd_type_end}	/* marks the end; don't use it! */
+         bfd_format;
+
+/* Object file flag values */
+#define NO_FLAGS    	0x00
+#define HAS_RELOC   	0x01
+#define EXEC_P      	0x02
+#define HAS_LINENO  	0x04
+#define HAS_DEBUG   	0x08
+#define HAS_SYMS    	0x10
+#define HAS_LOCALS  	0x20
+#define DYNAMIC     	0x40
+#define WP_TEXT     	0x80
+#define D_PAGED     	0x100
+#define BFD_IS_RELAXABLE 0x200
+
+/* symbols and relocation */
+
+typedef unsigned long symindex;
+
+#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
+
+typedef enum bfd_symclass {
+	      bfd_symclass_unknown = 0,
+	      bfd_symclass_fcommon, /* fortran common symbols */
+	      bfd_symclass_global, /* global symbol, what a surprise */
+	      bfd_symclass_debugger, /* some debugger symbol */
+	      bfd_symclass_undefined /* none known */
+	    } symclass;
+
+
+typedef int symtype;		/* Who knows, yet? */
+
+
+/* general purpose part of a symbol;
+   target specific parts will be found in libcoff.h, liba.out.h etc */
+
+
+#define bfd_get_section(x) ((x)->section)
+#define bfd_get_output_section(x) ((x)->section->output_section)
+#define bfd_set_section(x,y) ((x)->section) = (y)
+#define bfd_asymbol_base(x) ((x)->section?((x)->section->vma):0)
+#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + x->value)
+#define bfd_asymbol_name(x) ((x)->name)
+
+/* This is a type pun with struct ranlib on purpose! */
+typedef struct carsym {
+  char *name;
+  file_ptr file_offset;		/* look here to find the file */
+} carsym;			/* to make these you call a carsymogen */
+
+  
+/* Used in generating armaps.  Perhaps just a forward definition would do? */
+struct orl {			/* output ranlib */
+  char **name;			/* symbol name */ 
+  file_ptr pos;			/* bfd* or file position */
+  int namidx;			/* index into string table */
+};
+
+
+
+/* Linenumber stuff */
+typedef struct lineno_cache_entry {
+  unsigned int line_number;	/* Linenumber from start of function*/  
+  union {
+ struct symbol_cache_entry *sym;		/* Function name */
+    unsigned long offset;	/* Offset into section */
+  } u;
+} alent;
+
+/* object and core file sections */
+
+
+#define	align_power(addr, align)	\
+	( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
+
+typedef struct sec *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0)
+#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0)
+#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
+#define bfd_section_vma(bfd, ptr) ((ptr)->vma)
+#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power)
+#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0)
+#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata)
+
+#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (val)), ((ptr)->user_set_vma = true), true)
+#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true)
+#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true)
+
+typedef struct stat stat_type; 
+
+/** Error handling */
+
+typedef enum bfd_error {
+	      no_error = 0, system_call_error, invalid_target,
+	      wrong_format, invalid_operation, no_memory,
+	      no_symbols, no_relocation_info,
+	      no_more_archived_files, malformed_archive,
+	      symbol_not_found, file_not_recognized,
+	      file_ambiguously_recognized, no_contents,
+	      bfd_error_nonrepresentable_section,
+	      no_debug_section, bad_value,
+	      invalid_error_code} bfd_ec;
+
+extern bfd_ec bfd_error;
+struct reloc_cache_entry;
+struct bfd_seclet_struct ;
+
+
+typedef struct bfd_error_vector {
+  PROTO(void,(* nonrepresentable_section ),(CONST bfd  *CONST abfd,
+					    CONST char *CONST name));
+  PROTO(void,(* undefined_symbol),(CONST struct reloc_cache_entry *rel,
+				   CONST struct bfd_seclet_struct *sec
+				   ));
+  PROTO(void, (* reloc_value_truncated),(CONST struct
+					  reloc_cache_entry *rel,
+					  struct bfd_seclet_struct *sec));
+
+  PROTO(void, (* reloc_dangerous),(CONST struct reloc_cache_entry *rel,
+				   CONST struct bfd_seclet_struct *sec));
+  
+} bfd_error_vector_type;
+
+PROTO (CONST char *, bfd_errmsg, (bfd_ec error_tag));
+PROTO (void, bfd_perror, (CONST char *message));
+
+
+typedef enum bfd_print_symbol
+{ 
+  bfd_print_symbol_name,
+  bfd_print_symbol_more,
+  bfd_print_symbol_all,
+  bfd_print_symbol_nm	/* Pretty format suitable for nm program. */
+} bfd_print_symbol_type;
+    
+
+
+/* The code that implements targets can initialize a jump table with this
+   macro.  It must name all its routines the same way (a prefix plus
+   the standard routine suffix), or it must #define the routines that
+   are not so named, before calling JUMP_TABLE in the initializer.  */
+
+/* Semi-portable string concatenation in cpp */
+#ifndef CAT
+#ifdef __STDC__
+#define CAT(a,b) a##b
+#else
+#define CAT(a,b) a/**/b
+#endif
+#endif
+
+#define JUMP_TABLE(NAME)\
+CAT(NAME,_core_file_failing_command),\
+CAT(NAME,_core_file_failing_signal),\
+CAT(NAME,_core_file_matches_executable_p),\
+CAT(NAME,_slurp_armap),\
+CAT(NAME,_slurp_extended_name_table),\
+CAT(NAME,_truncate_arname),\
+CAT(NAME,_write_armap),\
+CAT(NAME,_close_and_cleanup),	\
+CAT(NAME,_set_section_contents),\
+CAT(NAME,_get_section_contents),\
+CAT(NAME,_new_section_hook),\
+CAT(NAME,_get_symtab_upper_bound),\
+CAT(NAME,_get_symtab),\
+CAT(NAME,_get_reloc_upper_bound),\
+CAT(NAME,_canonicalize_reloc),\
+CAT(NAME,_make_empty_symbol),\
+CAT(NAME,_print_symbol),\
+CAT(NAME,_get_lineno),\
+CAT(NAME,_set_arch_mach),\
+CAT(NAME,_openr_next_archived_file),\
+CAT(NAME,_find_nearest_line),\
+CAT(NAME,_generic_stat_arch_elt),\
+CAT(NAME,_sizeof_headers),\
+CAT(NAME,_bfd_debug_info_start),\
+CAT(NAME,_bfd_debug_info_end),\
+CAT(NAME,_bfd_debug_info_accumulate),\
+CAT(NAME,_bfd_get_relocated_section_contents),\
+CAT(NAME,_bfd_relax_section)
+
+#define COFF_SWAP_TABLE \
+ coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, \
+ coff_swap_aux_out, coff_swap_sym_out, \
+ coff_swap_lineno_out, coff_swap_reloc_out, \
+ coff_swap_filehdr_out, coff_swap_aouthdr_out, \
+ coff_swap_scnhdr_out
+
+
+
+/* User program access to BFD facilities */
+
+extern CONST short _bfd_host_big_endian;
+#define HOST_BYTE_ORDER_BIG_P	(*(char *)&_bfd_host_big_endian)
+
+/* The bfd itself */
+
+/* Cast from const char * to char * so that caller can assign to
+   a char * without a warning.  */
+#define bfd_get_filename(abfd) ((char *) (abfd)->filename)
+#define bfd_get_format(abfd) ((abfd)->format)
+#define bfd_get_target(abfd) ((abfd)->xvec->name)
+#define bfd_get_file_flags(abfd) ((abfd)->flags)
+#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
+#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
+#define bfd_my_archive(abfd) ((abfd)->my_archive)
+#define bfd_has_map(abfd) ((abfd)->has_armap)
+#define bfd_header_twiddle_required(abfd) \
+        ((((abfd)->xvec->header_byteorder_big_p)		\
+	  != (boolean)HOST_BYTE_ORDER_BIG_P) ? true:false)
+
+#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
+#define bfd_usrdata(abfd) ((abfd)->usrdata)
+
+#define bfd_get_start_address(abfd) ((abfd)->start_address)
+#define bfd_get_symcount(abfd) ((abfd)->symcount)
+#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols)
+#define bfd_count_sections(abfd) ((abfd)->section_count)
+#define bfd_get_architecture(abfd) ((abfd)->obj_arch)
+#define bfd_get_machine(abfd) ((abfd)->obj_machine)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+#define BYTE_SIZE 1
+#define SHORT_SIZE 2
+#define LONG_SIZE 4
+
+/* And more from the source.  */
+void EXFUN(bfd_init, (void));
+bfd *EXFUN(bfd_openr, (CONST char *filename, CONST char*target));
+bfd *EXFUN(bfd_fdopenr, (CONST char *filename, CONST char *target, int fd));
+bfd *EXFUN(bfd_openw, (CONST char *filename, CONST char *target));
+boolean EXFUN(bfd_close, (bfd *));
+boolean EXFUN(bfd_close_all_done, (bfd *));
+bfd_size_type EXFUN(bfd_alloc_size, (bfd *abfd));
+bfd *EXFUN(bfd_create, (CONST char *filename, bfd *template));
+#define bfd_put_8(abfd, val, ptr) \
+                (*((char *)ptr) = (char)val)
+#define bfd_get_8(abfd, ptr) \
+                (*((char *)ptr))
+#define bfd_put_16(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx16, (val,ptr))
+#define bfd_get_16(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx16, (ptr))
+#define bfd_put_32(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx32, (val,ptr))
+#define bfd_get_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx32, (ptr))
+#define bfd_put_64(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_putx64, (val, ptr))
+#define bfd_get_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_getx64, (ptr))
+#define bfd_h_put_8(abfd, val, ptr) \
+                (*((char *)ptr) = (char)val)
+#define bfd_h_get_8(abfd, ptr) \
+                (*((char *)ptr))
+#define bfd_h_put_16(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
+#define bfd_h_get_16(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx16,(ptr))
+#define bfd_h_put_32(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
+#define bfd_h_get_32(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx32,(ptr))
+#define bfd_h_put_64(abfd, val, ptr) \
+                BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
+#define bfd_h_get_64(abfd, ptr) \
+                BFD_SEND(abfd, bfd_h_getx64,(ptr))
+typedef struct sec 
+{
+         /* The name of the section, the name isn't a copy, the pointer is
+        the same as that passed to bfd_make_section. */
+
+    CONST char *name;
+
+
+         /* Which section is it 0.nth      */
+
+   int index;                      
+
+         /* The next section in the list belonging to the BFD, or NULL. */
+
+    struct sec *next;
+
+         /* The field flags contains attributes of the section. Some of
+           flags are read in from the object file, and some are
+           synthesized from other information.  */         
+
+    flagword flags;
+
+#define SEC_NO_FLAGS   0x000
+
+         /* Tells the OS to allocate space for this section when loaded.
+           This would clear for a section containing debug information
+           only. */
+          
+
+#define SEC_ALLOC      0x001
+         /* Tells the OS to load the section from the file when loading.
+           This would be clear for a .bss section */
+
+#define SEC_LOAD       0x002
+         /* The section contains data still to be relocated, so there will
+           be some relocation information too. */
+
+#define SEC_RELOC      0x004
+
+         /* Obsolete ? */
+
+#define SEC_BALIGN     0x008
+
+         /* A signal to the OS that the section contains read only
+          data. */
+#define SEC_READONLY   0x010
+
+         /* The section contains code only. */
+
+#define SEC_CODE       0x020
+
+         /* The section contains data only. */
+
+#define SEC_DATA        0x040
+
+         /* The section will reside in ROM. */
+
+#define SEC_ROM        0x080
+
+         /* The section contains constructor information. This section
+           type is used by the linker to create lists of constructors and
+           destructors used by <<g++>>. When a back end sees a symbol
+           which should be used in a constructor list, it creates a new
+           section for the type of name (eg <<__CTOR_LIST__>>), attaches
+           the symbol to it and builds a relocation. To build the lists
+           of constructors, all the linker has to to is catenate all the
+           sections called <<__CTOR_LIST__>> and relocte the data
+           contained within - exactly the operations it would peform on
+           standard data. */
+
+#define SEC_CONSTRUCTOR 0x100
+
+         /* The section is a constuctor, and should be placed at the
+          end of the . */
+
+
+#define SEC_CONSTRUCTOR_TEXT 0x1100
+
+#define SEC_CONSTRUCTOR_DATA 0x2100
+
+#define SEC_CONSTRUCTOR_BSS  0x3100
+
+
+         /* The section has contents - a bss section could be
+           <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>, a debug section could be
+           <<SEC_HAS_CONTENTS>> */
+
+#define SEC_HAS_CONTENTS 0x200
+
+         /* An instruction to the linker not to output sections
+          containing this flag even if they have information which
+          would normally be written. */
+
+#define SEC_NEVER_LOAD 0x400
+
+
+       
+   bfd_vma vma;
+   boolean user_set_vma;
+
+         /* The size of the section in bytes, as it will be output.
+           contains a value even if the section has no contents (eg, the
+           size of <<.bss>>). This will be filled in after relocation */
+
+   bfd_size_type _cooked_size;    
+
+         /* The size on disk of the section in bytes originally.  Normally this
+	    value is the same as the size, but if some relaxing has
+	    been done, then this value will be bigger.  */
+
+   bfd_size_type _raw_size;    
+
+         /* If this section is going to be output, then this value is the
+           offset into the output section of the first byte in the input
+           section. Eg, if this was going to start at the 100th byte in
+           the output section, this value would be 100. */
+
+   bfd_vma output_offset;
+
+         /* The output section through which to map on output. */
+
+   struct sec *output_section;
+
+         /* The alignment requirement of the section, as an exponent - eg
+           3 aligns to 2^3 (or 8) */
+
+   unsigned int alignment_power;
+
+         /* If an input section, a pointer to a vector of relocation
+           records for the data in this section. */
+
+   struct reloc_cache_entry *relocation;
+
+         /* If an output section, a pointer to a vector of pointers to
+           relocation records for the data in this section. */
+
+   struct reloc_cache_entry **orelocation;
+
+         /* The number of relocation records in one of the above  */
+
+   unsigned reloc_count;
+
+         /* Information below is back end specific - and not always used
+           or updated 
+
+           File position of section data    */
+
+   file_ptr filepos;      
+        
+         /* File position of relocation info */
+
+   file_ptr rel_filepos;
+
+         /* File position of line data       */
+
+   file_ptr line_filepos;
+
+         /* Pointer to data for applications */
+
+   PTR userdata;
+
+   struct lang_output_section *otheruserdata;
+
+         /* Attached line number information */
+
+   alent *lineno;
+        
+         /* Number of line number records   */
+
+   unsigned int lineno_count;
+
+         /* When a section is being output, this value changes as more
+           linenumbers are written out */
+
+   file_ptr moving_line_filepos;
+
+         /* what the section number is in the target world  */
+
+   int target_index;
+
+   PTR used_by_bfd;
+
+         /* If this is a constructor section then here is a list of the
+           relocations created to relocate items within it. */
+
+   struct relent_chain *constructor_chain;
+
+         /* The BFD which owns the section. */
+
+   bfd *owner;
+
+   boolean reloc_done;
+	  /* A symbol which points at this section only */
+   struct symbol_cache_entry *symbol;  
+   struct symbol_cache_entry **symbol_ptr_ptr;
+   struct bfd_seclet_struct *seclets_head;
+   struct bfd_seclet_struct *seclets_tail;
+} asection ;
+
+
+#define BFD_ABS_SECTION_NAME "*ABS*"
+#define BFD_UND_SECTION_NAME "*UND*"
+#define BFD_COM_SECTION_NAME "*COM*"
+
+     /* the absolute section */
+ extern   asection bfd_abs_section;
+     /* Pointer to the undefined section */
+ extern   asection bfd_und_section;
+     /* Pointer to the common section */
+ extern asection bfd_com_section;
+
+ extern struct symbol_cache_entry *bfd_abs_symbol;
+ extern struct symbol_cache_entry *bfd_com_symbol;
+ extern struct symbol_cache_entry *bfd_und_symbol;
+#define bfd_get_section_size_before_reloc(section) \
+     (section->reloc_done ? (abort(),1): (section)->_raw_size)
+#define bfd_get_section_size_after_reloc(section) \
+     ((section->reloc_done) ? (section)->_cooked_size: (abort(),1))
+asection *EXFUN(bfd_get_section_by_name, (bfd *abfd, CONST char *name));
+asection *EXFUN(bfd_make_section_old_way, (bfd *, CONST char *name));
+asection * EXFUN(bfd_make_section, (bfd *, CONST char *name));
+boolean EXFUN(bfd_set_section_flags, (bfd *, asection *, flagword));
+void EXFUN(bfd_map_over_sections, (bfd *abfd,
+    void (*func)(bfd *abfd,
+    asection *sect,
+    PTR obj),
+    PTR obj));
+boolean EXFUN(bfd_set_section_size, (bfd *, asection *, bfd_size_type val));
+boolean EXFUN(bfd_set_section_contents
+    , (bfd *abfd,        
+    asection *section,
+    PTR data,
+    file_ptr offset,
+    bfd_size_type count));
+boolean EXFUN(bfd_get_section_contents 
+    , (bfd *abfd, asection *section, PTR location,
+    file_ptr offset, bfd_size_type count));
+enum bfd_architecture 
+{
+  bfd_arch_unknown,    /* File arch not known */
+  bfd_arch_obscure,    /* Arch known, not one of these */
+  bfd_arch_m68k,       /* Motorola 68xxx */
+  bfd_arch_vax,        /* DEC Vax */   
+  bfd_arch_i960,       /* Intel 960 */
+     /* The order of the following is important.
+       lower number indicates a machine type that 
+       only accepts a subset of the instructions
+       available to machines with higher numbers.
+       The exception is the "ca", which is
+       incompatible with all other machines except 
+       "core". */
+
+#define bfd_mach_i960_core      1
+#define bfd_mach_i960_ka_sa     2
+#define bfd_mach_i960_kb_sb     3
+#define bfd_mach_i960_mc        4
+#define bfd_mach_i960_xa        5
+#define bfd_mach_i960_ca        6
+
+  bfd_arch_a29k,       /* AMD 29000 */
+  bfd_arch_sparc,      /* SPARC */
+  bfd_arch_mips,       /* MIPS Rxxxx */
+  bfd_arch_i386,       /* Intel 386 */
+  bfd_arch_we32k,      /* AT&T WE32xxx */
+  bfd_arch_tahoe,      /* CCI/Harris Tahoe */
+  bfd_arch_i860,       /* Intel 860 */
+  bfd_arch_romp,       /* IBM ROMP PC/RT */
+  bfd_arch_alliant,    /* Alliant */
+  bfd_arch_convex,     /* Convex */
+  bfd_arch_m88k,       /* Motorola 88xxx */
+  bfd_arch_pyramid,    /* Pyramid Technology */
+  bfd_arch_h8300,      /* Hitachi H8/300 */
+  bfd_arch_rs6000,     /* IBM RS/6000 */
+  bfd_arch_hppa,       /* HP PA RISC */
+  bfd_arch_z8k,        /* Zilog Z8000 */
+#define bfd_mach_z8001		1
+#define bfd_mach_z8002		2
+  bfd_arch_last
+  };
+
+typedef struct bfd_arch_info 
+{
+  int bits_per_word;
+  int bits_per_address;
+  int bits_per_byte;
+  enum bfd_architecture arch;
+  long mach;
+  char *arch_name;
+  CONST  char *printable_name;
+  unsigned int section_align_power;
+  /* true if this is the default machine for the architecture */
+  boolean the_default;	
+  CONST struct bfd_arch_info * EXFUN((*compatible),
+	(CONST struct bfd_arch_info *a,
+	 CONST struct bfd_arch_info *b));
+
+  boolean EXFUN((*scan),(CONST struct bfd_arch_info *,CONST char *));
+  unsigned int EXFUN((*disassemble),(bfd_vma addr, CONST char *data,
+				     PTR stream));
+
+  struct bfd_arch_info *next;
+} bfd_arch_info_type;
+CONST char *EXFUN(bfd_printable_name, (bfd *abfd));
+bfd_arch_info_type *EXFUN(bfd_scan_arch, (CONST char *));
+CONST bfd_arch_info_type *EXFUN(bfd_arch_get_compatible, (
+    CONST bfd *abfd,
+    CONST bfd *bbfd));
+void EXFUN(bfd_set_arch_info, (bfd *, bfd_arch_info_type *));
+enum bfd_architecture EXFUN(bfd_get_arch, (bfd *abfd));
+unsigned long EXFUN(bfd_get_mach, (bfd *abfd));
+unsigned int EXFUN(bfd_arch_bits_per_byte, (bfd *abfd));
+unsigned int EXFUN(bfd_arch_bits_per_address, (bfd *abfd));
+bfd_arch_info_type * EXFUN(bfd_get_arch_info, (bfd *));
+bfd_arch_info_type *EXFUN(bfd_lookup_arch
+    , (enum bfd_architecture
+    arch,
+    long machine));
+CONST char * EXFUN(bfd_printable_arch_mach
+    , (enum bfd_architecture arch, unsigned long machine));
+typedef enum bfd_reloc_status 
+{
+        /* No errors detected */
+  bfd_reloc_ok,
+
+        /* The relocation was performed, but there was an overflow. */
+  bfd_reloc_overflow,
+
+        /* The address to relocate was not within the section supplied*/
+  bfd_reloc_outofrange,
+
+        /* Used by special functions */
+  bfd_reloc_continue,
+
+        /* Unused */
+  bfd_reloc_notsupported,
+
+        /* Unsupported relocation size requested.  */
+  bfd_reloc_other,
+
+        /* The symbol to relocate against was undefined.*/
+  bfd_reloc_undefined,
+
+        /* The relocation was performed, but may not be ok - presently
+          generated only when linking i960 coff files with i960 b.out
+          symbols. */
+  bfd_reloc_dangerous
+ }
+ bfd_reloc_status_type;
+
+
+typedef struct reloc_cache_entry 
+{
+        /* A pointer into the canonical table of pointers  */
+  struct symbol_cache_entry **sym_ptr_ptr;
+
+        /* offset in section */
+  rawdata_offset address;
+
+        /* addend for relocation value */
+  bfd_vma addend;    
+
+        /* Pointer to how to perform the required relocation */
+  CONST struct reloc_howto_struct *howto;
+
+} arelent;
+
+typedef CONST struct reloc_howto_struct 
+{ 
+        /*  The type field has mainly a documetary use - the back end can
+           to what it wants with it, though the normally the back end's
+           external idea of what a reloc number would be would be stored
+           in this field. For example, the a PC relative word relocation
+           in a coff environment would have the type 023 - because that's
+           what the outside world calls a R_PCRWORD reloc. */
+  unsigned int type;
+
+        /*  The value the final relocation is shifted right by. This drops
+           unwanted data from the relocation.  */
+  unsigned int rightshift;
+
+        /*  The size of the item to be relocated - 0, is one byte, 1 is 2
+           bytes, 3 is four bytes.  A -ve value indicates that the
+	    result is to be subtracted from the data*/
+  int size;
+
+        /*  Now obsolete */
+  unsigned int bitsize;
+
+        /*  Notes that the relocation is relative to the location in the
+           data section of the addend. The relocation function will
+           subtract from the relocation value the address of the location
+           being relocated. */
+  boolean pc_relative;
+
+        /*  Now obsolete */
+  unsigned int bitpos;
+
+        /*  Now obsolete */
+  boolean absolute;
+
+        /* Causes the relocation routine to return an error if overflow
+          is detected when relocating. */
+  boolean complain_on_overflow;
+
+        /* If this field is non null, then the supplied function is
+          called rather than the normal function. This allows really
+          strange relocation methods to be accomodated (eg, i960 callj
+          instructions). */
+  bfd_reloc_status_type EXFUN ((*special_function), 
+					    (bfd *abfd,
+					     arelent *reloc_entry,
+                                            struct symbol_cache_entry *symbol,
+                                            PTR data,
+                                            asection *input_section, 
+                                            bfd *output_bfd     ));
+
+        /* The textual name of the relocation type. */
+  char *name;
+
+        /* When performing a partial link, some formats must modify the
+          relocations rather than the data - this flag signals this.*/
+  boolean partial_inplace;
+
+        /* The src_mask is used to select what parts of the read in data
+          are to be used in the relocation sum. Eg, if this was an 8 bit
+          bit of data which we read and relocated, this would be
+          0x000000ff. When we have relocs which have an addend, such as
+          sun4 extended relocs, the value in the offset part of a
+          relocating field is garbage so we never use it. In this case
+          the mask would be 0x00000000. */
+  bfd_word src_mask;
+
+        /* The dst_mask is what parts of the instruction are replaced
+          into the instruction. In most cases src_mask == dst_mask,
+          except in the above special case, where dst_mask would be
+          0x000000ff, and src_mask would be 0x00000000.   */
+  bfd_word dst_mask;           
+
+        /* When some formats create PC relative instructions, they leave
+          the value of the pc of the place being relocated in the offset
+          slot of the instruction, so that a PC relative relocation can
+          be made just by adding in an ordinary offset (eg sun3 a.out).
+          Some formats leave the displacement part of an instruction
+          empty (eg m88k bcs), this flag signals the fact.*/
+  boolean pcrel_offset;
+
+} reloc_howto_type;
+#define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+  {(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
+#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,false,false,FUNCTION, NAME,false,0,0,IN)
+
+#define HOWTO_PREPARE(relocation, symbol)      \
+  {                                            \
+  if (symbol != (asymbol *)NULL) {             \
+    if (symbol->section == &bfd_com_section) { \
+      relocation = 0;                          \
+    }                                          \
+    else {                                     \
+      relocation = symbol->value;              \
+    }                                          \
+  }                                            \
+}                      
+typedef unsigned char bfd_byte;
+
+typedef struct relent_chain {
+  arelent relent;
+  struct   relent_chain *next;
+} arelent_chain;
+bfd_reloc_status_type
+EXFUN(bfd_perform_relocation
+    , (bfd * abfd,
+    arelent *reloc_entry,
+    PTR data,
+    asection *input_section,
+    bfd *output_bfd));
+typedef enum bfd_reloc_code_real 
+
+{
+        /* 16 bits wide, simple reloc */
+  BFD_RELOC_16,        
+
+        /* 8 bits wide, but used to form an address like 0xffnn */
+  BFD_RELOC_8_FFnn,
+
+        /* 8 bits wide, simple */
+  BFD_RELOC_8,
+
+        /* 8 bits wide, pc relative */
+  BFD_RELOC_8_PCREL,
+
+        /* The type of reloc used to build a contructor table - at the
+          moment probably a 32 bit wide abs address, but the cpu can
+          choose. */
+
+  BFD_RELOC_CTOR,
+
+        /* 32 bits wide, simple reloc */
+  BFD_RELOC_32,
+	 /* 32 bits, PC-relative */
+  BFD_RELOC_32_PCREL,
+
+	 /* High 22 bits of 32-bit value; simple reloc.  */
+  BFD_RELOC_HI22,
+	 /* Low 10 bits.  */
+  BFD_RELOC_LO10,
+
+	 /* Reloc types used for i960/b.out.  */
+  BFD_RELOC_24_PCREL,
+  BFD_RELOC_I960_CALLJ,
+
+  BFD_RELOC_16_PCREL,
+	 /* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit
+	   word displacement, e.g. for SPARC) */
+  BFD_RELOC_32_PCREL_S2,
+
+   /* now for the sparc/elf codes */
+  BFD_RELOC_NONE,		 /* actually used */
+  BFD_RELOC_SPARC_WDISP22,
+  BFD_RELOC_SPARC22,
+  BFD_RELOC_SPARC13,
+  BFD_RELOC_SPARC_BASE13,
+  BFD_RELOC_SPARC_GOT10,
+  BFD_RELOC_SPARC_GOT13,
+  BFD_RELOC_SPARC_GOT22,
+  BFD_RELOC_SPARC_PC10,
+  BFD_RELOC_SPARC_PC22,
+  BFD_RELOC_SPARC_WPLT30,
+  BFD_RELOC_SPARC_COPY,
+  BFD_RELOC_SPARC_GLOB_DAT,
+  BFD_RELOC_SPARC_JMP_SLOT,
+  BFD_RELOC_SPARC_RELATIVE,
+  BFD_RELOC_SPARC_UA32,
+
+   /* this one is a.out specific? */
+  BFD_RELOC_SPARC_BASE22,
+
+   /* this must be the highest numeric value */
+  BFD_RELOC_UNUSED
+ } bfd_reloc_code_real_type;
+CONST struct reloc_howto_struct *
+EXFUN(bfd_reloc_type_lookup , (bfd *abfd, bfd_reloc_code_real_type code));
+typedef struct symbol_cache_entry 
+{
+	 /* A pointer to the BFD which owns the symbol. This information
+	   is necessary so that a back end can work out what additional
+   	   (invisible to the application writer) information is carried
+	   with the symbol.  */
+
+  struct _bfd *the_bfd;
+
+	 /* The text of the symbol. The name is left alone, and not copied - the
+	   application may not alter it. */
+  CONST char *name;
+
+	 /* The value of the symbol.*/
+  symvalue value;
+
+	 /* Attributes of a symbol: */
+
+#define BSF_NO_FLAGS    0x00
+
+	 /* The symbol has local scope; <<static>> in <<C>>. The value
+ 	   is the offset into the section of the data. */
+#define BSF_LOCAL	0x01
+
+	 /* The symbol has global scope; initialized data in <<C>>. The
+	   value is the offset into the section of the data. */
+#define BSF_GLOBAL	0x02
+
+	 /* Obsolete */
+#define BSF_IMPORT	0x04
+
+	 /* The symbol has global scope, and is exported. The value is
+	   the offset into the section of the data. */
+#define BSF_EXPORT	0x08
+
+	 /* The symbol is undefined. <<extern>> in <<C>>. The value has
+	   no meaning. */
+#define BSF_UNDEFINED_OBS 0x10	
+
+	 /* The symbol is common, initialized to zero; default in
+	   <<C>>. The value is the size of the object in bytes. */
+#define BSF_FORT_COMM_OBS	0x20	
+
+	 /* A normal C symbol would be one of:
+	   <<BSF_LOCAL>>, <<BSF_FORT_COMM>>,  <<BSF_UNDEFINED>> or
+	   <<BSF_EXPORT|BSD_GLOBAL>> */
+
+	 /* The symbol is a debugging record. The value has an arbitary
+	   meaning. */
+#define BSF_DEBUGGING	0x40
+
+	 /* Used by the linker */
+#define BSF_KEEP        0x10000
+#define BSF_KEEP_G      0x80000
+
+	 /* Unused */
+#define BSF_WEAK        0x100000
+#define BSF_CTOR        0x200000 
+
+        /* This symbol was created to point to a section, e.g. ELF's
+	   STT_SECTION symbols.  */
+#define BSF_SECTION_SYM 0x400000 
+
+	 /* The symbol used to be a common symbol, but now it is
+	   allocated. */
+#define BSF_OLD_COMMON  0x800000  
+
+	 /* The default value for common data. */
+#define BFD_FORT_COMM_DEFAULT_VALUE 0
+
+	 /* In some files the type of a symbol sometimes alters its
+	   location in an output file - ie in coff a <<ISFCN>> symbol
+	   which is also <<C_EXT>> symbol appears where it was
+	   declared and not at the end of a section.  This bit is set
+  	   by the target BFD part to convey this information. */
+
+#define BSF_NOT_AT_END    0x40000
+
+	 /* Signal that the symbol is the label of constructor section. */
+#define BSF_CONSTRUCTOR   0x1000000
+
+	 /* Signal that the symbol is a warning symbol. If the symbol
+	   is a warning symbol, then the value field (I know this is
+	   tacky) will point to the asymbol which when referenced will
+	   cause the warning. */
+#define BSF_WARNING       0x2000000
+
+	 /* Signal that the symbol is indirect. The value of the symbol
+	   is a pointer to an undefined asymbol which contains the
+	   name to use instead. */
+#define BSF_INDIRECT      0x4000000
+
+	 /* BSF_FILE marks symbols that contain a file name.  This is used
+	   for ELF STT_FILE symbols.  */
+#define BSF_FILE          0x08000000
+
+  flagword flags;
+
+	 /* A pointer to the section to which this symbol is 
+	   relative.  This will always be non NULL, there are special
+          sections for undefined and absolute symbols */
+  struct sec *section;
+
+	 /* Back end special data. This is being phased out in favour
+	   of making this a union. */
+  PTR udata;	
+
+} asymbol;
+#define get_symtab_upper_bound(abfd) \
+     BFD_SEND (abfd, _get_symtab_upper_bound, (abfd))
+#define bfd_canonicalize_symtab(abfd, location) \
+     BFD_SEND (abfd, _bfd_canonicalize_symtab,\
+                  (abfd, location))
+boolean EXFUN(bfd_set_symtab , (bfd *, asymbol **, unsigned int ));
+void EXFUN(bfd_print_symbol_vandf, (PTR file, asymbol *symbol));
+#define bfd_make_empty_symbol(abfd) \
+     BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+#define bfd_make_debug_symbol(abfd,ptr,size) \
+        BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+int EXFUN(bfd_decode_symclass, (asymbol *symbol));
+struct _bfd 
+{
+     /* The filename the application opened the BFD with.  */
+    CONST char *filename;                
+
+     /* A pointer to the target jump table.             */
+    struct bfd_target *xvec;
+
+     /* To avoid dragging too many header files into every file that
+       includes `<<bfd.h>>', IOSTREAM has been declared as a "char
+       *", and MTIME as a "long".  Their correct types, to which they
+       are cast when used, are "FILE *" and "time_t".    The iostream
+       is the result of an fopen on the filename. */
+    char *iostream;
+
+     /* Is the file being cached */
+
+    boolean cacheable;
+
+     /* Marks whether there was a default target specified when the
+       BFD was opened. This is used to select what matching algorithm
+       to use to chose the back end. */
+
+    boolean target_defaulted;
+
+     /* The caching routines use these to maintain a
+       least-recently-used list of BFDs */
+
+    struct _bfd *lru_prev, *lru_next;
+
+     /* When a file is closed by the caching routines, BFD retains
+       state information on the file here: 
+     */
+
+    file_ptr where;              
+
+     /* and here:*/
+
+    boolean opened_once;
+
+     /* Set if we have a locally maintained mtime value, rather than
+       getting it from the file each time: */
+
+    boolean mtime_set;
+
+     /* File modified time, if mtime_set is true: */
+
+    long mtime;          
+
+     /* Reserved for an unimplemented file locking extension.*/
+
+    int ifd;
+
+     /* The format which belongs to the BFD.*/
+
+    bfd_format format;
+
+     /* The direction the BFD was opened with*/
+
+    enum bfd_direction {no_direction = 0,
+                        read_direction = 1,
+                        write_direction = 2,
+                        both_direction = 3} direction;
+
+     /* Format_specific flags*/
+
+    flagword flags;              
+
+     /* Currently my_archive is tested before adding origin to
+       anything. I believe that this can become always an add of
+       origin, with origin set to 0 for non archive files.   */
+
+    file_ptr origin;             
+
+     /* Remember when output has begun, to stop strange things
+       happening. */
+    boolean output_has_begun;
+
+     /* Pointer to linked list of sections*/
+    struct sec  *sections;
+
+     /* The number of sections */
+    unsigned int section_count;
+
+     /* Stuff only useful for object files: 
+       The start address. */
+    bfd_vma start_address;
+
+     /* Used for input and output*/
+    unsigned int symcount;
+
+     /* Symbol table for output BFD*/
+    struct symbol_cache_entry  **outsymbols;             
+
+     /* Pointer to structure which contains architecture information*/
+    struct bfd_arch_info *arch_info;
+
+     /* Stuff only useful for archives:*/
+    PTR arelt_data;              
+    struct _bfd *my_archive;     
+    struct _bfd *next;           
+    struct _bfd *archive_head;   
+    boolean has_armap;           
+
+     /* Used by the back end to hold private data. */
+
+    union 
+      {
+      struct aout_data_struct *aout_data;
+      struct artdata *aout_ar_data;
+      struct _oasys_data *oasys_obj_data;
+      struct _oasys_ar_data *oasys_ar_data;
+      struct coff_tdata *coff_obj_data;
+      struct ieee_data_struct *ieee_data;
+      struct ieee_ar_data_struct *ieee_ar_data;
+      struct srec_data_struct *srec_data;
+      struct srec_data_struct *tekhex_data;
+      struct elf_obj_tdata *elf_obj_data;
+      struct bout_data_struct *bout_data;
+      struct sun_core_struct *sun_core_data;
+      struct trad_core_struct *trad_core_data;
+      struct hppa_data_struct *hppa_data;
+      PTR any;
+      } tdata;
+  
+     /* Used by the application to hold private data*/
+    PTR usrdata;
+
+     /* Where all the allocated stuff under this BFD goes */
+    struct obstack memory;
+
+     /* Is this really needed in addition to usrdata?  */
+    asymbol **ld_symbols;
+};
+
+unsigned int EXFUN(bfd_get_reloc_upper_bound, (bfd *abfd, asection *sect));
+unsigned int EXFUN(bfd_canonicalize_reloc
+    , (bfd *abfd,
+    asection *sec,
+    arelent **loc,
+    asymbol	**syms));
+boolean EXFUN(bfd_set_file_flags, (bfd *abfd, flagword flags));
+void EXFUN(bfd_set_reloc
+    , (bfd *abfd, asection *sec, arelent **rel, unsigned int count)
+    
+    );
+boolean EXFUN(bfd_set_start_address, (bfd *, bfd_vma));
+long EXFUN(bfd_get_mtime, (bfd *));
+#define bfd_sizeof_headers(abfd, reloc) \
+     BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+     BFD_SEND (abfd, _bfd_find_nearest_line,  (abfd, sec, syms, off, file, func, line))
+
+        /* Do these three do anything useful at all, for any back end?  */
+#define bfd_debug_info_start(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+        BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+        BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+
+#define bfd_stat_arch_elt(abfd, stat) \
+        BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+
+#define bfd_coff_swap_aux_in(a,e,t,c,i) \
+        BFD_SEND (a, _bfd_coff_swap_aux_in, (a,e,t,c,i))
+
+#define bfd_coff_swap_sym_in(a,e,i) \
+        BFD_SEND (a, _bfd_coff_swap_sym_in, (a,e,i))
+
+#define bfd_coff_swap_lineno_in(a,e,i) \
+        BFD_SEND ( a, _bfd_coff_swap_lineno_in, (a,e,i))
+
+#define bfd_set_arch_mach(abfd, arch, mach)\
+        BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
+
+#define bfd_coff_swap_reloc_out(abfd, i, o) \
+        BFD_SEND (abfd, _bfd_coff_swap_reloc_out, (abfd, i, o))
+
+#define bfd_coff_swap_lineno_out(abfd, i, o) \
+        BFD_SEND (abfd, _bfd_coff_swap_lineno_out, (abfd, i, o))
+
+#define bfd_coff_swap_aux_out(abfd, i, t,c,o) \
+        BFD_SEND (abfd, _bfd_coff_swap_aux_out, (abfd, i,t,c, o))
+
+#define bfd_coff_swap_sym_out(abfd, i,o) \
+        BFD_SEND (abfd, _bfd_coff_swap_sym_out, (abfd, i, o))
+
+#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
+        BFD_SEND (abfd, _bfd_coff_swap_scnhdr_out, (abfd, i, o))
+
+#define bfd_coff_swap_filehdr_out(abfd, i,o) \
+        BFD_SEND (abfd, _bfd_coff_swap_filehdr_out, (abfd, i, o))
+
+#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
+        BFD_SEND (abfd, _bfd_coff_swap_aouthdr_out, (abfd, i, o))
+
+#define bfd_get_relocated_section_contents(abfd, seclet, data) \
+	BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data))
+ 
+#define bfd_relax_section(abfd, section, symbols) \
+       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
+symindex EXFUN(bfd_get_next_mapent, (bfd *, symindex previous, carsym ** sym));
+boolean EXFUN(bfd_set_archive_head, (bfd *output, bfd *new_head));
+bfd *EXFUN(bfd_get_elt_at_index, (bfd * archive, int index));
+bfd* EXFUN(bfd_openr_next_archived_file, (bfd *archive, bfd *previous));
+CONST char *EXFUN(bfd_core_file_failing_command, (bfd *));
+int EXFUN(bfd_core_file_failing_signal, (bfd *));
+boolean EXFUN(core_file_matches_executable_p
+    , (bfd *core_bfd, bfd *exec_bfd));
+#define SDEF(ret, name, arglist) \
+                PROTO(ret,(*name),arglist)
+#define SDEF_FMT(ret, name, arglist) \
+                PROTO(ret,(*name[bfd_type_end]),arglist)
+#define BFD_SEND(bfd, message, arglist) \
+               ((*((bfd)->xvec->message)) arglist)
+#define BFD_SEND_FMT(bfd, message, arglist) \
+            (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
+typedef struct bfd_target
+{
+  char *name;
+  enum target_flavour {
+    bfd_target_unknown_flavour,
+    bfd_target_aout_flavour,
+    bfd_target_coff_flavour,
+    bfd_target_elf_flavour,
+    bfd_target_ieee_flavour,
+    bfd_target_oasys_flavour,
+    bfd_target_tekhex_flavour,
+    bfd_target_srec_flavour,
+    bfd_target_hppa_flavour} flavour;
+  boolean byteorder_big_p;
+  boolean header_byteorder_big_p;
+  flagword object_flags;       
+  flagword section_flags;
+  char symbol_leading_char;
+  char ar_pad_char;            
+ unsigned short ar_max_namelen;
+  unsigned int align_power_min;
+  SDEF (bfd_vma,      bfd_getx64, (bfd_byte *));
+  SDEF (void,         bfd_putx64, (bfd_vma, bfd_byte *));
+  SDEF (bfd_vma, bfd_getx32, (bfd_byte *));
+  SDEF (void,         bfd_putx32, (bfd_vma, bfd_byte *));
+  SDEF (bfd_vma, bfd_getx16, (bfd_byte *));
+  SDEF (void,         bfd_putx16, (bfd_vma, bfd_byte *));
+  SDEF (bfd_vma,   bfd_h_getx64, (bfd_byte *));
+  SDEF (void,          bfd_h_putx64, (bfd_vma, bfd_byte *));
+  SDEF (bfd_vma,  bfd_h_getx32, (bfd_byte *));
+  SDEF (void,          bfd_h_putx32, (bfd_vma, bfd_byte *));
+  SDEF (bfd_vma,  bfd_h_getx16, (bfd_byte *));
+  SDEF (void,          bfd_h_putx16, (bfd_vma, bfd_byte *));
+  SDEF_FMT (struct bfd_target *, _bfd_check_format, (bfd *));
+  SDEF_FMT (boolean,            _bfd_set_format, (bfd *));
+  SDEF_FMT (boolean,            _bfd_write_contents, (bfd *));
+  SDEF (char *, _core_file_failing_command, (bfd *));
+  SDEF (int,    _core_file_failing_signal, (bfd *));
+  SDEF (boolean, _core_file_matches_executable_p, (bfd *, bfd *));
+ SDEF (boolean, _bfd_slurp_armap, (bfd *));
+ SDEF (boolean, _bfd_slurp_extended_name_table, (bfd *));
+ SDEF (void,   _bfd_truncate_arname, (bfd *, CONST char *, char *));
+ SDEF (boolean, write_armap, (bfd *arch, 
+                              unsigned int elength,
+                              struct orl *map,
+                              unsigned int orl_count, 
+                              int stridx));
+  SDEF (boolean, _close_and_cleanup, (bfd *));
+  SDEF (boolean, _bfd_set_section_contents, (bfd *, sec_ptr, PTR,
+                                            file_ptr, bfd_size_type));
+  SDEF (boolean, _bfd_get_section_contents, (bfd *, sec_ptr, PTR, 
+                                            file_ptr, bfd_size_type));
+  SDEF (boolean, _new_section_hook, (bfd *, sec_ptr));
+  SDEF (unsigned int, _get_symtab_upper_bound, (bfd *));
+  SDEF (unsigned int, _bfd_canonicalize_symtab,
+           (bfd *, struct symbol_cache_entry **));
+  SDEF (unsigned int, _get_reloc_upper_bound, (bfd *, sec_ptr));
+  SDEF (unsigned int, _bfd_canonicalize_reloc, (bfd *, sec_ptr, arelent **,
+                                               struct symbol_cache_entry**));
+  SDEF (struct symbol_cache_entry  *, _bfd_make_empty_symbol, (bfd *));
+  SDEF (void,     _bfd_print_symbol, (bfd *, PTR, struct symbol_cache_entry  *,
+                                      bfd_print_symbol_type));
+#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e))
+  SDEF (alent *,   _get_lineno, (bfd *, struct symbol_cache_entry  *));
+
+  SDEF (boolean,   _bfd_set_arch_mach, (bfd *, enum bfd_architecture,
+                                       unsigned long));
+
+  SDEF (bfd *,  openr_next_archived_file, (bfd *arch, bfd *prev));
+  SDEF (boolean, _bfd_find_nearest_line,
+        (bfd *abfd, struct sec  *section,
+         struct symbol_cache_entry  **symbols,bfd_vma offset,
+        CONST char **file, CONST char **func, unsigned int *line));
+  SDEF (int,    _bfd_stat_arch_elt, (bfd *, struct stat *));
+
+  SDEF (int,    _bfd_sizeof_headers, (bfd *, boolean));
+
+  SDEF (void, _bfd_debug_info_start, (bfd *));
+  SDEF (void, _bfd_debug_info_end, (bfd *));
+  SDEF (void, _bfd_debug_info_accumulate, (bfd *, struct sec  *));
+  SDEF (bfd_byte *, _bfd_get_relocated_section_contents, (bfd*,struct bfd_seclet_struct *, bfd_byte *data));
+  SDEF (boolean,_bfd_relax_section,(bfd *, struct sec *, struct symbol_cache_entry **));
+  SDEF(void, _bfd_coff_swap_aux_in,(
+       bfd            *abfd ,
+       PTR             ext,
+       int             type,
+       int             class ,
+       PTR             in));
+
+  SDEF(void, _bfd_coff_swap_sym_in,(
+       bfd            *abfd ,
+       PTR             ext,
+       PTR             in));
+
+  SDEF(void, _bfd_coff_swap_lineno_in,  (
+       bfd            *abfd,
+       PTR            ext,
+       PTR             in));
+
+ SDEF(unsigned int, _bfd_coff_swap_aux_out,(
+       bfd   	*abfd,
+       PTR	in,
+       int    	type,
+       int    	class,
+       PTR    	ext));
+
+ SDEF(unsigned int, _bfd_coff_swap_sym_out,(
+      bfd      *abfd,
+      PTR	in,
+      PTR	ext));
+
+ SDEF(unsigned int, _bfd_coff_swap_lineno_out,(
+      	bfd   	*abfd,
+      	PTR	in,
+	PTR	ext));
+
+ SDEF(unsigned int, _bfd_coff_swap_reloc_out,(
+      	bfd     *abfd,
+     	PTR	src,
+	PTR	dst));
+
+ SDEF(unsigned int, _bfd_coff_swap_filehdr_out,(
+      	bfd  	*abfd,
+	PTR 	in,
+	PTR 	out));
+
+ SDEF(unsigned int, _bfd_coff_swap_aouthdr_out,(
+      	bfd 	*abfd,
+	PTR 	in,
+	PTR	out));
+
+ SDEF(unsigned int, _bfd_coff_swap_scnhdr_out,(
+      	bfd  	*abfd,
+      	PTR	in,
+	PTR	out));
+
+  /* See documentation on reloc types.  */
+ SDEF (CONST struct reloc_howto_struct *,
+       reloc_type_lookup,
+       (bfd *abfd, bfd_reloc_code_real_type code));
+
+  /* Complete and utter crock, currently used for the assembler
+    when creating COFF files.  */
+ SDEF (asymbol *, _bfd_make_debug_symbol, (
+       bfd *abfd,
+       void *ptr,
+       unsigned long size));
+ PTR backend_data;
+} bfd_target;
+bfd_target *EXFUN(bfd_find_target, (CONST char *, bfd *));
+CONST char **EXFUN(bfd_target_list, (void));
+boolean EXFUN(bfd_check_format, (bfd *abfd, bfd_format format));
+boolean EXFUN(bfd_set_format, (bfd *, bfd_format));
+CONST char *EXFUN(bfd_format_string, (bfd_format));
+#endif
diff --git a/debugger/dbg.y b/debugger/dbg.y
new file mode 100644
index 0000000..80e8d34
--- /dev/null
+++ b/debugger/dbg.y
@@ -0,0 +1,151 @@
+
+%{
+
+/* Parser for command lines in the Wine debugger
+ *
+ * Version 1.0
+ * Eric Youngdale
+ * 9/93
+ */
+
+#include <stdio.h>
+#define YYSTYPE int
+
+#include "regpos.h"
+extern FILE * yyin;
+unsigned int * regval = NULL;
+unsigned int dbg_mask = 0;
+unsigned int dbg_mode = 0;
+
+void issue_prompt();
+%}
+
+
+%token CONT
+%token QUIT
+%token HELP
+%token INFO
+%token STACK
+%token REG
+%token REGS
+%token NUM
+%token SET
+%token PRINT
+%token IDENTIFIER
+%token NO_SYMBOL
+%token SYMBOLFILE
+%token DEFINE
+
+%%
+
+ input:  /* empty */
+	| input line  { issue_prompt(); }
+
+ line:		'\n'
+	| infocmd '\n'
+	| error '\n'       {yyerrok; }
+	| QUIT  '\n'       { exit(0); };
+	| HELP  '\n'       { dbg_help(); };
+	| CONT '\n'        { return; };
+	| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); };
+	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, $3); };
+	| x_command
+	| print_command
+	| deposit_command
+
+deposit_command:
+	SET REG '=' expr '\n' { regval[$2] = $4; }
+	| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
+	| SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
+
+
+x_command:
+	  'x' expr  '\n' { examine_memory($2, 1, 'x'); };
+	| 'x' '/' fmt expr  '\n' { examine_memory($4, 1, $3); };
+	| 'x' '/' NUM fmt expr  '\n' { examine_memory($5, $3, $4); };
+
+ print_command:
+	PRINT expr  '\n' { examine_memory(((unsigned int) &$2 ), 1, 'x'); };
+
+ fmt:  'x'     { $$ = 'x'; }
+	| 'd'  { $$ = 'd'; }
+	| 'i'  { $$ = 'i'; }
+	| 'w'  { $$ = 'w'; }
+	| 's'  { $$ = 's'; }
+	| 'c'  { $$ = 'c'; }
+	| 'b' { $$ = 'b'; }
+
+ symbol: IDENTIFIER             { $$ = find_hash($1);
+			           if($$ == 0xffffffff) {
+					   fprintf(stderr,"Symbol %s not found\n", $1);
+					   YYERROR;
+				   };
+			        }; 
+
+ expr:  NUM			{ $$ = $1;	}
+	| REG			{ $$ = regval[$1]; }
+	| symbol   		{ $$ = *((unsigned int *) $1); }
+	| expr '+' NUM		{ $$ = $1 + $3; }
+	| expr '-' NUM		{ $$ = $1 - $3; };
+	| '(' expr ')'		{ $$ = $2; };
+	| '*' expr		{ $$ = *((unsigned int *) $2); };
+	
+ infocmd: INFO REGS { info_reg(); }
+	| INFO STACK  { info_stack(); };
+
+
+%%
+
+void 
+issue_prompt(){
+#ifndef USE_READLINE
+	fprintf(stderr,"Wine-dbg>");
+#endif
+}
+
+static int loaded_symbols = 0;
+
+void
+wine_debug(int * regs)
+{
+	int i;
+#ifdef YYDEBUG
+	yydebug = 0;
+#endif
+	yyin = stdin;
+	regval = regs;
+
+	/* This only works for linux - NetBSD will need something different here. */
+	if((SC_CS & 7) != 7) {
+		dbg_mask = 0xffffffff;
+		dbg_mode = 32;
+	} else {
+		dbg_mask = 0xffff;
+		dbg_mode = 16;
+	};
+
+	/* This is intended to read the entry points from the Windows image, and
+	   insert them in the hash table.  It does not work yet, so it is commented out. */
+#if 0
+	if(!loaded_symbols){
+		loaded_symbols++;
+		load_entrypoints();
+	};
+#endif
+
+	/* Show where we crashed */
+	examine_memory(SC_EIP(dbg_mask), 1, 'i');
+
+	issue_prompt();
+
+	yyparse();
+	flush_symbols();
+	fprintf(stderr,"Returning to Wine...\n");
+
+}
+
+
+yyerror(char * s){
+	fprintf(stderr,"%s\n", s);
+}
+
diff --git a/debugger/debug.l b/debugger/debug.l
new file mode 100644
index 0000000..dac7d3f
--- /dev/null
+++ b/debugger/debug.l
@@ -0,0 +1,197 @@
+
+
+/* Lexical scanner for command line parsing in the Wine debugger
+ *
+ * Version 1.0
+ * Eric Youngdale
+ * 9/93
+ */
+
+%{
+#include <stdio.h>
+#include <string.h>
+#include "dbg.tab.h"
+#include "regpos.h"
+
+#ifdef USE_READLINE
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( (result = dbg_read((char *) buf, max_size )) < 0 ) \
+	    YY_FATAL_ERROR( "read() in flex scanner failed" );
+#endif
+
+extern char * readline(char *);
+static char * make_symbol(char *);
+void flush_symbols();
+static int syntax_error;
+%}
+
+DIGIT	[0-9]
+HEXDIGIT [0-9a-fA-F]
+
+IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
+
+%%
+
+\n		{ syntax_error = 0; return '\n'; } /* Indicate end of command */
+
+"+"		{ return '+'; } 
+
+"-"		{ return '-'; } 
+
+"/"		{ return '/'; } 
+
+"="		{ return '='; } 
+
+"("		{ return '('; } 
+
+")"		{ return ')'; } 
+
+"*"		{ return '*'; } 
+
+"?"		{ return HELP; }
+
+"0x"+{HEXDIGIT}+   {
+		sscanf(yytext, "%lx", &yylval);
+		return NUM;
+		}
+
+{DIGIT}+   {
+		sscanf(yytext, "%lx", &yylval);
+		return NUM;
+		}
+
+$pc		{ yylval = RN_EIP; return REG;}
+$sp		{ yylval = RN_ESP; return REG;}
+$eip		{ yylval = RN_EIP; return REG;}
+$esp		{ yylval = RN_ESP; return REG;}
+$ebp		{ yylval = RN_EBP; return REG;}
+$eax		{ yylval = RN_EAX; return REG;}
+$ebx		{ yylval = RN_EBX; return REG;}
+$ecx		{ yylval = RN_ECX; return REG;}
+$edx		{ yylval = RN_EDX; return REG;}
+$esi		{ yylval = RN_ESI; return REG;}
+$edi		{ yylval = RN_EDI; return REG;}
+
+info|inf|in		{ return INFO; }
+
+quit|qui|qu 	{ return QUIT; }
+
+help|hel|he	{ return HELP; }
+
+set|se		{ return SET; }
+
+cont|con|co		{ return CONT; }
+
+symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
+
+define|defin|defi|def|de        { return DEFINE; }
+print|prin|pri|pr		{ return PRINT; }
+
+regs|reg|re	{ return REGS; }
+
+stack|stac|sta|st     	{ return STACK; }
+
+x		{ return 'x'; }
+d		{ return 'd'; }
+i		{ return 'i'; }
+w		{ return 'w'; }
+b		{ return 'b'; }
+s		{ return 's'; }
+c		{ return 'c'; }
+
+{IDENTIFIER}	{yylval = (int) make_symbol(yytext); 
+	          return IDENTIFIER;
+	         }
+
+[ \t]+        /* Eat up whitespace */
+
+.		{ if(syntax_error == 0) {
+		syntax_error ++; fprintf(stderr, "Syntax Error\n"); }
+		}
+
+%%
+
+#ifdef USE_READLINE
+#ifndef whitespace
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
+
+#if 0
+/* Used only with GNU readline */
+#include "readline/readline.h"
+#include "readline/chardefs.h"
+#endif
+
+dbg_read(char * buf, int size){
+	char * line;
+	int len;
+
+	do{
+		flush_symbols();
+		line = readline ("Wine-dbg>");
+		len = strlen(line);
+				
+		if (!line)
+		{
+			return 0;
+		}
+		else
+		{
+			/* Remove leading and trailing whitespace from the line.
+			   Then, if there is anything left, add it to the history list
+			   and execute it. */
+			stripwhite (line);
+			
+			if (*line)
+			{
+				add_history (line);
+				if(size < len + 1){
+					fprintf(stderr,"Fatal readline goof.\n");
+					exit(0);
+				};
+				strcpy(buf, line);
+				buf[len] = '\n';
+				buf[len+1] = 0;
+				free(line);
+				return len + 1;
+			}
+		}
+
+	} while (1==1);
+}
+
+/* Strip whitespace from the start and end of STRING. */
+stripwhite (string)
+     char *string;
+{
+  register int i = 0;
+
+  while (whitespace (string[i]))
+    i++;
+
+  if (i)
+    strcpy (string, string + i);
+
+  i = strlen (string) - 1;
+
+  while (i > 0 && whitespace (string[i]))
+    i--;
+
+  string[++i] = '\0';
+}
+
+static char *local_symbols[10];
+static int next_symbol;
+
+char * make_symbol(char * symbol){
+	return local_symbols[next_symbol++] = strdup(symbol);
+}
+
+void
+flush_symbols(){
+	while(--next_symbol>= 0) free(local_symbols[next_symbol]);
+	next_symbol = 0;
+}
+
+#endif
diff --git a/debugger/defs.h b/debugger/defs.h
new file mode 100644
index 0000000..e789dd3
--- /dev/null
+++ b/debugger/defs.h
@@ -0,0 +1,818 @@
+/* Basic, host-specific, and target-specific definitions for GDB.
+   Copyright (C) 1986, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if !defined (DEFS_H)
+#define DEFS_H 1
+
+#include <stdio.h>
+
+/* First include ansidecl.h so we can use the various macro definitions
+   here and in all subsequent file inclusions.  */
+
+#include "ansidecl.h"
+
+/* An address in the program being debugged.  Host byte order.  */
+typedef unsigned int CORE_ADDR;
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+/* The character C++ uses to build identifiers that must be unique from
+   the program's identifiers (such as $this and $$vptr).  */
+#define CPLUS_MARKER '$'	/* May be overridden to '.' for SysV */
+
+#include <errno.h>		/* System call error return status */
+
+extern int quit_flag;
+extern int immediate_quit;
+
+extern void
+quit PARAMS ((void));
+
+#define QUIT { if (quit_flag) quit (); }
+
+/* Command classes are top-level categories into which commands are broken
+   down for "help" purposes.  
+   Notes on classes: class_alias is for alias commands which are not
+   abbreviations of the original command.  class-pseudo is for commands
+   which are not really commands nor help topics ("stop").  */
+
+enum command_class
+{
+  /* Special args to help_list */
+  all_classes = -2, all_commands = -1,
+  /* Classes of commands */
+  no_class = -1, class_run = 0, class_vars, class_stack,
+  class_files, class_support, class_info, class_breakpoint,
+  class_alias, class_obscure, class_user, class_maintenance,
+  class_pseudo
+};
+
+/* the cleanup list records things that have to be undone
+   if an error happens (descriptors to be closed, memory to be freed, etc.)
+   Each link in the chain records a function to call and an
+   argument to give it.
+
+   Use make_cleanup to add an element to the cleanup chain.
+   Use do_cleanups to do all cleanup actions back to a given
+   point in the chain.  Use discard_cleanups to remove cleanups
+   from the chain back to a given point, not doing them.  */
+
+struct cleanup
+{
+  struct cleanup *next;
+  void (*function) PARAMS ((PTR));
+  PTR arg;
+};
+
+/* From blockframe.c */
+
+extern int
+inside_entry_func PARAMS ((CORE_ADDR));
+
+extern int
+inside_entry_file PARAMS ((CORE_ADDR addr));
+
+extern int
+inside_main_func PARAMS ((CORE_ADDR pc));
+
+/* From cplus-dem.c */
+
+extern char *
+cplus_demangle PARAMS ((const char *, int));
+
+extern char *
+cplus_mangle_opname PARAMS ((char *, int));
+
+/* From libmmalloc.a (memory mapped malloc library) */
+
+extern PTR
+mmalloc_attach PARAMS ((int, PTR));
+
+extern PTR
+mmalloc_detach PARAMS ((PTR));
+
+extern PTR
+mmalloc PARAMS ((PTR, long));
+
+extern PTR
+mrealloc PARAMS ((PTR, PTR, long));
+
+extern void
+mfree PARAMS ((PTR, PTR));
+
+extern int
+mmalloc_setkey PARAMS ((PTR, int, PTR));
+
+extern PTR
+mmalloc_getkey PARAMS ((PTR, int));
+
+/* From utils.c */
+
+extern char *
+demangle_and_match PARAMS ((const char *, const char *, int));
+
+extern int
+strcmp_iw PARAMS ((const char *, const char *));
+
+extern char *
+safe_strerror PARAMS ((int));
+
+extern char *
+safe_strsignal PARAMS ((int));
+
+extern void
+init_malloc PARAMS ((PTR));
+
+extern void
+request_quit PARAMS ((int));
+
+extern void
+do_cleanups PARAMS ((struct cleanup *));
+
+extern void
+discard_cleanups PARAMS ((struct cleanup *));
+
+/* The bare make_cleanup function is one of those rare beasts that
+   takes almost any type of function as the first arg and anything that
+   will fit in a "void *" as the second arg.
+
+   Should be, once all calls and called-functions are cleaned up:
+extern struct cleanup *
+make_cleanup PARAMS ((void (*function) (PTR), PTR));
+
+   Until then, lint and/or various type-checking compiler options will
+   complain about make_cleanup calls.  It'd be wrong to just cast things,
+   since the type actually passed when the function is called would be
+   wrong.  */
+
+extern struct cleanup *
+make_cleanup ();
+
+extern struct cleanup *
+save_cleanups PARAMS ((void));
+
+extern void
+restore_cleanups PARAMS ((struct cleanup *));
+
+extern void
+free_current_contents PARAMS ((char **));
+
+extern void
+null_cleanup PARAMS ((char **));
+
+extern int
+myread PARAMS ((int, char *, int));
+
+extern int
+query ();
+
+extern void
+wrap_here PARAMS ((char *));
+
+extern void
+reinitialize_more_filter PARAMS ((void));
+
+extern int
+print_insn PARAMS ((CORE_ADDR, CORE_ADDR, FILE *, int));
+
+extern void
+fputs_filtered PARAMS ((const char *, FILE *));
+
+extern void
+puts_filtered PARAMS ((char *));
+
+extern void
+vfprintf_filtered ();
+
+extern void
+fprintf_filtered ();
+
+extern void
+fprintfi_filtered ();
+
+extern void
+printf_filtered ();
+
+extern void
+printfi_filtered ();
+
+extern void
+print_spaces PARAMS ((int, FILE *));
+
+extern void
+print_spaces_filtered PARAMS ((int, FILE *));
+
+extern char *
+n_spaces PARAMS ((int));
+
+extern void
+printchar PARAMS ((int, FILE *, int));
+
+extern char *
+strdup_demangled PARAMS ((const char *));
+
+extern void
+fprint_symbol PARAMS ((FILE *, char *));
+
+extern void
+fputs_demangled PARAMS ((char *, FILE *, int));
+
+extern void
+perror_with_name PARAMS ((char *));
+
+extern void
+print_sys_errmsg PARAMS ((char *, int));
+
+/* From regex.c */
+
+extern char *
+re_comp PARAMS ((char *));
+
+/* From symfile.c */
+
+extern void
+symbol_file_command PARAMS ((char *, int));
+
+/* From main.c */
+
+extern char *
+skip_quoted PARAMS ((char *));
+
+extern char *
+gdb_readline PARAMS ((char *));
+
+extern char *
+command_line_input PARAMS ((char *, int));
+
+extern void
+print_prompt PARAMS ((void));
+
+extern int
+batch_mode PARAMS ((void));
+
+extern int
+input_from_terminal_p PARAMS ((void));
+
+extern int
+catch_errors PARAMS ((int (*) (char *), char *, char *));
+
+/* From printcmd.c */
+
+extern void
+set_next_address PARAMS ((CORE_ADDR));
+
+extern void
+print_address_symbolic PARAMS ((CORE_ADDR, FILE *, int, char *));
+
+extern void
+print_address PARAMS ((CORE_ADDR, FILE *));
+
+/* From source.c */
+
+extern int
+openp PARAMS ((char *, int, char *, int, int, char **));
+
+extern void
+mod_path PARAMS ((char *, char **));
+
+extern void
+directory_command PARAMS ((char *, int));
+
+extern void
+init_source_path PARAMS ((void));
+
+/* From findvar.c */
+
+extern int
+read_relative_register_raw_bytes PARAMS ((int, char *));
+
+/* From readline (but not in any readline .h files).  */
+
+extern char *
+tilde_expand PARAMS ((char *));
+
+/* Structure for saved commands lines
+   (for breakpoints, defined commands, etc).  */
+
+struct command_line
+{
+  struct command_line *next;
+  char *line;
+};
+
+extern struct command_line *
+read_command_lines PARAMS ((void));
+
+extern void
+free_command_lines PARAMS ((struct command_line **));
+
+/* String containing the current directory (what getwd would return).  */
+
+extern char *current_directory;
+
+/* Default radixes for input and output.  Only some values supported.  */
+extern unsigned input_radix;
+extern unsigned output_radix;
+
+/* Baud rate specified for communication with serial target systems.  */
+extern char *baud_rate;
+
+/* Languages represented in the symbol table and elsewhere. */
+
+enum language 
+{
+   language_unknown, 		/* Language not known */
+   language_auto,		/* Placeholder for automatic setting */
+   language_c, 			/* C */
+   language_cplus, 		/* C++ */
+   language_m2			/* Modula-2 */
+};
+
+/* Return a format string for printf that will print a number in the local
+   (language-specific) hexadecimal format.  Result is static and is
+   overwritten by the next call.  local_hex_format_custom takes printf
+   options like "08" or "l" (to produce e.g. %08x or %lx).  */
+
+#define local_hex_format() (current_language->la_hex_format)
+
+extern char *
+local_hex_format_custom PARAMS ((char *));	/* language.c */
+
+/* Return a string that contains a number formatted in the local
+   (language-specific) hexadecimal format.  Result is static and is
+   overwritten by the next call.  local_hex_string_custom takes printf
+   options like "08" or "l".  */
+
+extern char *
+local_hex_string PARAMS ((int));		/* language.c */
+
+extern char *
+local_hex_string_custom PARAMS ((int, char *));	/* language.c */
+
+
+/* Host machine definition.  This will be a symlink to one of the
+   xm-*.h files, built by the `configure' script.  */
+
+#include "xm.h"
+
+/* If the xm.h file did not define the mode string used to open the
+   files, assume that binary files are opened the same way as text
+   files */
+#ifndef FOPEN_RB
+#include "fopen-same.h"
+#endif
+
+/*
+ * Allow things in gdb to be declared "const".  If compiling ANSI, it
+ * just works.  If compiling with gcc but non-ansi, redefine to __const__.
+ * If non-ansi, non-gcc, then eliminate "const" entirely, making those
+ * objects be read-write rather than read-only.
+ */
+
+#ifndef const
+#ifndef __STDC__
+# ifdef __GNUC__
+#  define const __const__
+# else
+#  define const /*nothing*/
+# endif /* GNUC */
+#endif /* STDC */
+#endif /* const */
+
+#ifndef volatile
+#ifndef __STDC__
+# ifdef __GNUC__
+#  define volatile __volatile__
+# else
+#  define volatile /*nothing*/
+# endif /* GNUC */
+#endif /* STDC */
+#endif /* volatile */
+
+/* Some compilers (many AT&T SVR4 compilers for instance), do not accept
+   declarations of functions that never return (exit for instance) as
+   "volatile void".  For such compilers "NORETURN" can be defined away
+   to keep them happy */
+
+#ifndef NORETURN
+# ifdef __lucid
+#   define NORETURN /*nothing*/
+# else
+#   define NORETURN volatile
+# endif
+#endif
+
+/* Defaults for system-wide constants (if not defined by xm.h, we fake it).  */
+
+#if !defined (UINT_MAX)
+#define UINT_MAX 0xffffffff
+#endif
+
+#if !defined (LONG_MAX)
+#define LONG_MAX 0x7fffffff
+#endif
+
+#if !defined (INT_MAX)
+#define INT_MAX 0x7fffffff
+#endif
+
+#if !defined (INT_MIN)
+/* Two's complement, 32 bit.  */
+#define INT_MIN -0x80000000
+#endif
+
+/* Number of bits in a char or unsigned char for the target machine.
+   Just like CHAR_BIT in <limits.h> but describes the target machine.  */
+#if !defined (TARGET_CHAR_BIT)
+#define TARGET_CHAR_BIT 8
+#endif
+
+/* Number of bits in a short or unsigned short for the target machine. */
+#if !defined (TARGET_SHORT_BIT)
+#define TARGET_SHORT_BIT (sizeof (short) * TARGET_CHAR_BIT)
+#endif
+
+/* Number of bits in an int or unsigned int for the target machine. */
+#if !defined (TARGET_INT_BIT)
+#define TARGET_INT_BIT (sizeof (int) * TARGET_CHAR_BIT)
+#endif
+
+/* Number of bits in a long or unsigned long for the target machine. */
+#if !defined (TARGET_LONG_BIT)
+#define TARGET_LONG_BIT (sizeof (long) * TARGET_CHAR_BIT)
+#endif
+
+/* Number of bits in a long long or unsigned long long for the target machine. */
+#if !defined (TARGET_LONG_LONG_BIT)
+#define TARGET_LONG_LONG_BIT (2 * TARGET_LONG_BIT)
+#endif
+
+/* Number of bits in a float for the target machine. */
+#if !defined (TARGET_FLOAT_BIT)
+#define TARGET_FLOAT_BIT (sizeof (float) * TARGET_CHAR_BIT)
+#endif
+
+/* Number of bits in a double for the target machine. */
+#if !defined (TARGET_DOUBLE_BIT)
+#define TARGET_DOUBLE_BIT (sizeof (double) * TARGET_CHAR_BIT)
+#endif
+
+/* Number of bits in a long double for the target machine. */
+#if !defined (TARGET_LONG_DOUBLE_BIT)
+#define TARGET_LONG_DOUBLE_BIT (2 * TARGET_DOUBLE_BIT)
+#endif
+
+/* Number of bits in a "complex" for the target machine. */
+#if !defined (TARGET_COMPLEX_BIT)
+#define TARGET_COMPLEX_BIT (2 * TARGET_FLOAT_BIT)
+#endif
+
+/* Number of bits in a "double complex" for the target machine. */
+#if !defined (TARGET_DOUBLE_COMPLEX_BIT)
+#define TARGET_DOUBLE_COMPLEX_BIT (2 * TARGET_DOUBLE_BIT)
+#endif
+
+/* Number of bits in a pointer for the target machine */
+#if !defined (TARGET_PTR_BIT)
+#define TARGET_PTR_BIT TARGET_INT_BIT
+#endif
+
+/* Convert a LONGEST to an int.  This is used in contexts (e.g. number
+   of arguments to a function, number in a value history, register
+   number, etc.) where the value must not be larger than can fit
+   in an int.  */
+#if !defined (longest_to_int)
+#if defined (LONG_LONG)
+#define longest_to_int(x) (((x) > INT_MAX || (x) < INT_MIN) \
+			   ? (error ("Value out of range."),0) : (int) (x))
+#else /* No LONG_LONG.  */
+/* Assume sizeof (int) == sizeof (long).  */
+#define longest_to_int(x) ((int) (x))
+#endif /* No LONG_LONG.  */
+#endif /* No longest_to_int.  */
+
+/* This should not be a typedef, because "unsigned LONGEST" needs
+   to work. LONG_LONG is defined if the host has "long long".  */
+
+#ifndef LONGEST
+# ifdef LONG_LONG
+#  define LONGEST long long
+# else
+#  define LONGEST long
+# endif
+#endif
+
+/* Assorted functions we can declare, now that const and volatile are 
+   defined.  */
+
+extern char *
+savestring PARAMS ((const char *, int));
+
+extern char *
+msavestring PARAMS ((void *, const char *, int));
+
+extern char *
+strsave PARAMS ((const char *));
+
+extern char *
+mstrsave PARAMS ((void *, const char *));
+
+extern char *
+concat PARAMS ((char *, ...));
+
+extern PTR
+xmalloc PARAMS ((long));
+
+extern PTR
+xrealloc PARAMS ((PTR, long));
+
+extern PTR
+xmmalloc PARAMS ((PTR, long));
+
+extern PTR
+xmrealloc PARAMS ((PTR, PTR, long));
+
+extern PTR
+mmalloc PARAMS ((PTR, long));
+
+extern PTR
+mrealloc PARAMS ((PTR, PTR, long));
+
+extern void
+mfree PARAMS ((PTR, PTR));
+
+extern int
+mmcheck PARAMS ((PTR, void (*) (void)));
+
+extern int
+mmtrace PARAMS ((void));
+
+extern int
+parse_escape PARAMS ((char **));
+
+extern const char * const reg_names[];
+
+extern NORETURN void			/* Does not return to the caller.  */
+error ();
+
+extern NORETURN void			/* Does not return to the caller.  */
+fatal ();
+
+extern NORETURN void			/* Not specified as volatile in ... */
+exit PARAMS ((int));			/* 4.10.4.3 */
+
+extern NORETURN void			/* Does not return to the caller.  */
+nomem PARAMS ((long));
+
+extern NORETURN void			/* Does not return to the caller.  */
+return_to_top_level PARAMS ((void));
+
+extern void
+warning_setup PARAMS ((void));
+
+extern void
+warning ();
+
+/* Global functions from other, non-gdb GNU thingies (libiberty for
+   instance) */
+
+extern char *
+basename PARAMS ((char *));
+
+extern char *
+getenv PARAMS ((const char *));
+
+extern char **
+buildargv PARAMS ((char *));
+
+extern void
+freeargv PARAMS ((char **));
+
+extern char *
+strerrno PARAMS ((int));
+
+extern char *
+strsigno PARAMS ((int));
+
+extern int
+errno_max PARAMS ((void));
+
+extern int
+signo_max PARAMS ((void));
+
+extern int
+strtoerrno PARAMS ((char *));
+
+extern int
+strtosigno PARAMS ((char *));
+
+extern char *
+strsignal PARAMS ((int));
+
+/* From other system libraries */
+
+#ifndef PSIGNAL_IN_SIGNAL_H
+extern void
+psignal PARAMS ((unsigned, char *));
+#endif
+
+/* For now, we can't include <stdlib.h> because it conflicts with
+   "../include/getopt.h".  (FIXME)
+
+   However, if a function is defined in the ANSI C standard and a prototype
+   for that function is defined and visible in any header file in an ANSI
+   conforming environment, then that prototype must match the definition in
+   the ANSI standard.  So we can just duplicate them here without conflict,
+   since they must be the same in all conforming ANSI environments.  If
+   these cause problems, then the environment is not ANSI conformant. */
+   
+#ifdef __STDC__
+#include <stddef.h>
+#endif
+
+extern int
+fclose PARAMS ((FILE *stream));				/* 4.9.5.1 */
+
+extern void
+perror PARAMS ((const char *));				/* 4.9.10.4 */
+
+extern double
+atof PARAMS ((const char *nptr));			/* 4.10.1.1 */
+
+extern int
+atoi PARAMS ((const char *));				/* 4.10.1.2 */
+
+#ifndef MALLOC_INCOMPATIBLE
+
+extern PTR
+malloc PARAMS ((size_t size));                          /* 4.10.3.3 */
+
+extern PTR
+realloc PARAMS ((void *ptr, size_t size));              /* 4.10.3.4 */
+
+extern void
+free PARAMS ((void *));					/* 4.10.3.2 */
+
+#endif	/* MALLOC_INCOMPATIBLE */
+
+extern void
+qsort PARAMS ((void *base, size_t nmemb,		/* 4.10.5.2 */
+	       size_t size,
+	       int (*comp)(const void *, const void *)));
+
+#ifndef	MEM_FNS_DECLARED	/* Some non-ANSI use void *, not char *.  */
+extern PTR
+memcpy PARAMS ((void *, const void *, size_t));		/* 4.11.2.1 */
+#endif
+
+extern int
+memcmp PARAMS ((const void *, const void *, size_t));	/* 4.11.4.1 */
+
+extern char *
+strchr PARAMS ((const char *, int));			/* 4.11.5.2 */
+
+extern char *
+strrchr PARAMS ((const char *, int));			/* 4.11.5.5 */
+
+extern char *
+strstr PARAMS ((const char *, const char *));		/* 4.11.5.7 */
+
+extern char *
+strtok PARAMS ((char *, const char *));			/* 4.11.5.8 */
+
+#ifndef	MEM_FNS_DECLARED	/* Some non-ANSI use void *, not char *.  */
+extern PTR
+memset PARAMS ((void *, int, size_t));			/* 4.11.6.1 */
+#endif
+
+extern char *
+strerror PARAMS ((int));				/* 4.11.6.2 */
+
+/* Various possibilities for alloca.  */
+#ifndef alloca
+# ifdef __GNUC__
+#  define alloca __builtin_alloca
+# else
+#  ifdef sparc
+#   include <alloca.h>		/* NOTE:  Doesn't declare alloca() */
+#  endif
+#  ifdef __STDC__
+   extern void *alloca (size_t);
+#  else /* __STDC__ */
+   extern char *alloca ();
+#  endif
+# endif
+#endif
+
+/* TARGET_BYTE_ORDER and HOST_BYTE_ORDER must be defined to one of these.  */
+
+#if !defined (BIG_ENDIAN)
+#define BIG_ENDIAN 4321
+#endif
+
+#if !defined (LITTLE_ENDIAN)
+#define LITTLE_ENDIAN 1234
+#endif
+
+/* Target-system-dependent parameters for GDB.
+
+   The standard thing is to include defs.h.  However, files that are
+   specific to a particular target can define TM_FILE_OVERRIDE before
+   including defs.h, then can include any particular tm-file they desire.  */
+
+/* Target machine definition.  This will be a symlink to one of the
+   tm-*.h files, built by the `configure' script.  */
+
+#ifndef TM_FILE_OVERRIDE
+#include "tm.h"
+#endif
+
+/* The bit byte-order has to do just with numbering of bits in
+   debugging symbols and such.  Conceptually, it's quite separate
+   from byte/word byte order.  */
+
+#if !defined (BITS_BIG_ENDIAN)
+#if TARGET_BYTE_ORDER == BIG_ENDIAN
+#define BITS_BIG_ENDIAN 1
+#endif /* Big endian.  */
+
+#if TARGET_BYTE_ORDER == LITTLE_ENDIAN
+#define BITS_BIG_ENDIAN 0
+#endif /* Little endian.  */
+#endif /* BITS_BIG_ENDIAN not defined.  */
+
+/* Swap LEN bytes at BUFFER between target and host byte-order.  */
+#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
+#define SWAP_TARGET_AND_HOST(buffer,len)
+#else /* Target and host byte order differ.  */
+#define SWAP_TARGET_AND_HOST(buffer,len) \
+  {	       	       	       	       	       	       	       	       	 \
+    char tmp;								 \
+    char *p = (char *)(buffer);						 \
+    char *q = ((char *)(buffer)) + len - 1;		   		 \
+    for (; p < q; p++, q--)				 		 \
+      {									 \
+        tmp = *q;							 \
+        *q = *p;							 \
+        *p = tmp;							 \
+      }									 \
+  }
+#endif /* Target and host byte order differ.  */
+
+/* On some machines there are bits in addresses which are not really
+   part of the address, but are used by the kernel, the hardware, etc.
+   for special purposes.  ADDR_BITS_REMOVE takes out any such bits
+   so we get a "real" address such as one would find in a symbol
+   table.  ADDR_BITS_SET sets those bits the way the system wants
+   them.  */
+#if !defined (ADDR_BITS_REMOVE)
+#define ADDR_BITS_REMOVE(addr) (addr)
+#define ADDR_BITS_SET(addr) (addr)
+#endif /* No ADDR_BITS_REMOVE.  */
+
+/* From valops.c */
+
+extern CORE_ADDR
+push_bytes PARAMS ((CORE_ADDR, char *, int));
+
+/* In some modules, we don't have a definition of REGISTER_TYPE yet, so we
+   must avoid prototyping this function for now.  FIXME.  Should be:
+extern CORE_ADDR
+push_word PARAMS ((CORE_ADDR, REGISTER_TYPE));
+ */
+extern CORE_ADDR
+push_word ();
+
+/* Some parts of gdb might be considered optional, in the sense that they
+   are not essential for being able to build a working, usable debugger
+   for a specific environment.  For example, the maintenance commands
+   are there for the benefit of gdb maintainers.  As another example,
+   some environments really don't need gdb's that are able to read N
+   different object file formats.  In order to make it possible (but
+   not necessarily recommended) to build "stripped down" versions of
+   gdb, the following defines control selective compilation of those
+   parts of gdb which can be safely left out when necessary.  Note that
+   the default is to include everything. */
+
+#ifndef MAINTENANCE_CMDS
+#define MAINTENANCE_CMDS 1
+#endif
+
+#endif /* !defined (DEFS_H) */
diff --git a/debugger/dtest.c b/debugger/dtest.c
new file mode 100644
index 0000000..4d70008
--- /dev/null
+++ b/debugger/dtest.c
@@ -0,0 +1,96 @@
+#include <signal.h>
+#include <stdio.h>
+
+extern void wine_debug(unsigned int*);
+
+
+#ifdef linux
+#include <linux/sched.h>
+#include <asm/system.h>
+#endif
+
+struct sigaction segv_act;
+
+#ifdef linux
+
+struct sigcontext_struct {
+	unsigned short sc_gs, __gsh;
+	unsigned short sc_fs, __fsh;
+	unsigned short sc_es, __esh;
+	unsigned short sc_ds, __dsh;
+	unsigned long sc_edi;
+	unsigned long sc_esi;
+	unsigned long sc_ebp;
+	unsigned long sc_esp;
+	unsigned long sc_ebx;
+	unsigned long sc_edx;
+	unsigned long sc_ecx;
+	unsigned long sc_eax;
+	unsigned long sc_trapno;
+	unsigned long sc_err;
+	unsigned long sc_eip;
+	unsigned short sc_cs, __csh;
+	unsigned long sc_eflags;
+	unsigned long esp_at_signal;
+	unsigned short sc_ss, __ssh;
+	unsigned long i387;
+	unsigned long oldmask;
+	unsigned long cr2;
+};
+#endif
+
+#ifdef linux
+static void win_fault(int signal, struct sigcontext_struct context){
+        struct sigcontext_struct *scp = &context;
+#else
+static void win_fault(int signal, int code, struct sigcontext *scp){
+#endif
+
+	wine_debug((unsigned int *) scp);  /* Enter our debugger */
+}
+
+char realtext[] = "This is what should really be printed\n";
+
+int 
+main(){
+	char * pnt;
+#ifdef linux
+	segv_act.sa_handler = (__sighandler_t) win_fault;
+	/* Point to the top of the stack, minus 4 just in case, and make
+	   it aligned  */
+	sigaction(SIGSEGV, &segv_act, NULL);
+#endif
+#ifdef __NetBSD__
+        struct sigstack ss;
+        sigset_t sig_mask;
+        
+        ss.ss_sp = (char *) (((unsigned int)(cstack + sizeof(cstack) - 4)) & ~3);
+        ss.ss_onstack = 0;
+        if (sigstack(&ss, NULL) < 0) {
+                perror("sigstack");
+                exit(1);
+        }
+        sigemptyset(&sig_mask);
+        segv_act.sa_handler = (__sighandler_t) win_fault;
+	segv_act.sa_flags = SA_ONSTACK;
+        segv_act.sa_mask = sig_mask;
+	if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
+                perror("sigaction");
+                exit(1);
+        }
+#endif
+
+	fprintf(stderr,"%x\n", realtext);
+
+	/* Now force a segmentation fault */
+	pnt = (char *) 0xc0000000;
+
+	fprintf(stderr,"%s", pnt);
+	return 0;
+
+}
+
+
+unsigned int * wine_files = NULL;
+
+GetEntryPointFromOrdinal(int wpnt, int ordinal) {}
diff --git a/debugger/fopen-same.h b/debugger/fopen-same.h
new file mode 100644
index 0000000..0f37529
--- /dev/null
+++ b/debugger/fopen-same.h
@@ -0,0 +1,27 @@
+/* Macros for the 'type' part of an fopen, freopen or fdopen. 
+
+	<Read|Write>[Update]<Binary file|text file>
+
+   This version is for "same" systems, where text and binary files are
+   the same.  An example is Unix.  Many Unix systems could also add a
+   "b" to the string, indicating binary files, but some reject this
+   (and thereby don't conform to ANSI C, but what else is new?).
+
+   This file is designed for inclusion by host-dependent .h files.  No
+   user application should include it directly, since that would make
+   the application unable to be configured for both "same" and "binary"
+   variant systems.  */
+
+#define FOPEN_RB	"r"
+#define FOPEN_WB 	"w"
+#define FOPEN_AB 	"a"
+#define FOPEN_RUB 	"r+"
+#define FOPEN_WUB 	"w+"
+#define FOPEN_AUB 	"a+"
+
+#define FOPEN_RT	"r"
+#define FOPEN_WT 	"w"
+#define FOPEN_AT 	"a"
+#define FOPEN_RUT 	"r+"
+#define FOPEN_WUT 	"w+"
+#define FOPEN_AUT 	"a+"
diff --git a/debugger/gdbcore.h b/debugger/gdbcore.h
new file mode 100644
index 0000000..e9c8466
--- /dev/null
+++ b/debugger/gdbcore.h
@@ -0,0 +1,119 @@
+/* Machine independent variables that describe the core file under GDB.
+   Copyright 1986, 1987, 1989, 1990, 1992 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Interface routines for core, executable, etc.  */
+
+#if !defined (GDBCORE_H)
+#define GDBCORE_H 1
+
+#include "bfd.h"		/* Binary File Description */
+
+/* Return the name of the executable file as a string.
+   ERR nonzero means get error if there is none specified;
+   otherwise return 0 in that case.  */
+
+extern char *
+get_exec_file PARAMS ((int err));
+
+/* Nonzero if there is a core file.  */
+
+extern int
+have_core_file_p PARAMS ((void));
+
+/* Read "memory data" from whatever target or inferior we have. 
+   Returns zero if successful, errno value if not.  EIO is used
+   for address out of bounds.  If breakpoints are inserted, returns
+   shadow contents, not the breakpoints themselves.  From breakpoint.c.  */
+
+extern int
+read_memory_nobpt PARAMS ((CORE_ADDR memaddr, char *myaddr, unsigned len));
+
+/* Report a memory error with error().  */
+
+extern void
+memory_error PARAMS ((int status, CORE_ADDR memaddr));
+
+/* Like target_read_memory, but report an error if can't read.  */
+
+extern void
+read_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+
+/* Read an integer from debugged memory, given address and number of bytes.  */
+
+extern long
+read_memory_integer PARAMS ((CORE_ADDR memaddr, int len));
+
+/* If this is prototyped, need to deal with void* vs. char*.  */
+
+extern void
+write_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+
+/* Hook for `exec_file_command' command to call.  */
+
+extern void (*exec_file_display_hook) PARAMS ((char *filename));
+   
+extern void
+specify_exec_file_hook PARAMS ((void (*hook) (char *filename)));
+
+/* Binary File Diddlers for the exec and core files */
+extern bfd *core_bfd;
+extern bfd *exec_bfd;
+
+/* Whether to open exec and core files read-only or read-write.  */
+
+extern int write_files;
+
+extern void
+core_file_command PARAMS ((char *filename, int from_tty));
+
+extern void
+exec_file_command PARAMS ((char *filename, int from_tty));
+
+extern void
+validate_files PARAMS ((void));
+
+extern unsigned int
+register_addr PARAMS ((int regno, int blockend));
+
+extern int
+xfer_core_file PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+
+extern void
+fetch_core_registers PARAMS ((char *core_reg_sect, unsigned core_reg_size,
+			      int which, unsigned int reg_addr));
+
+extern void
+registers_fetched PARAMS ((void));
+
+#if !defined (KERNEL_U_ADDR)
+extern CORE_ADDR kernel_u_addr;
+#define KERNEL_U_ADDR kernel_u_addr
+#endif
+
+/* The target vector for core files */
+extern struct target_ops core_ops;
+
+ /* target vector functions called directly from elsewhere */
+void
+core_open PARAMS ((char *, int));
+
+void
+core_detach PARAMS ((char *, int));
+
+#endif	/* !defined (GDBCORE_H) */
diff --git a/debugger/hash.c b/debugger/hash.c
new file mode 100644
index 0000000..a6d640f
--- /dev/null
+++ b/debugger/hash.c
@@ -0,0 +1,177 @@
+/*
+ * File hash.c - generate hash tables for Wine debugger symbols
+ *
+ * Copyright (C) 1993, Eric Youngdale.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <neexe.h>
+#include <segmem.h>
+#include <prototypes.h>
+#include <wine.h>
+
+struct  name_hash{
+	struct name_hash * next;
+	unsigned int * address;
+	char * name;
+};
+
+#define NR_NAME_HASH 128
+
+static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,};
+
+static  unsigned int name_hash(const char * name){
+	unsigned int hash = 0;
+	const char * p;
+
+	p = name;
+
+	while (*p) hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++;
+	return hash % NR_NAME_HASH;
+
+}
+
+
+void add_hash(char * name, unsigned int * address){
+	struct name_hash  * new;
+	int hash;
+
+	new = (struct  name_hash *) malloc(sizeof(struct name_hash));
+	new->address = address;
+	new->name = strdup(name);
+	new->next = NULL;
+	hash = name_hash(name);
+
+	/* Now insert into the hash table */
+	new->next = name_hash_table[hash];
+	name_hash_table[hash] = new;
+}
+
+unsigned int * find_hash(char * name){
+	char buffer[256];
+	struct name_hash  * nh;
+
+	for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
+		if(strcmp(nh->name, name) == 0) return nh->address;
+
+	if(name[0] != '_'){
+		buffer[0] = '_';
+		strcpy(buffer+1, name);
+		for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
+			if(strcmp(nh->name, buffer) == 0) return nh->address;
+	};
+
+
+	return (unsigned int *) 0xffffffff;
+}
+
+
+static char name_buffer[256];
+
+char * find_nearest_symbol(unsigned int * address){
+	struct name_hash * nearest;
+	struct name_hash start;
+	struct name_hash  * nh;
+	int i;
+	
+	nearest = &start;
+	start.address = (unsigned int *) 0;
+	
+	for(i=0; i<NR_NAME_HASH; i++) {
+		for(nh = name_hash_table[i]; nh; nh = nh->next)
+			if(nh->address <= address && nh->address > nearest->address)
+				nearest = nh;
+	};
+	if((unsigned int) nearest->address == 0) return NULL;
+
+	sprintf(name_buffer, "%s+0x%x", nearest->name, ((unsigned int) address) - 
+		((unsigned int) nearest->address));
+	return name_buffer;
+}
+
+
+void
+read_symboltable(char * filename){
+	FILE * symbolfile;
+	unsigned int addr;
+	int nargs;
+	char type;
+	char * cpnt;
+	char buffer[256];
+	char name[256];
+
+	symbolfile = fopen(filename, "r");
+	if(!symbolfile) {
+		fprintf(stderr,"Unable to open symbol table %s\n", filename);
+		return;
+	};
+
+	fprintf(stderr,"Reading symbols from file %s\n", filename);
+
+
+	while (1)
+	{
+		fgets(buffer, sizeof(buffer),  symbolfile);
+		if (feof(symbolfile)) break;
+		
+		/* Strip any text after a # sign (i.e. comments) */
+		cpnt = buffer;
+		while(*cpnt){
+			if(*cpnt == '#') {*cpnt = 0; break; };
+			cpnt++;
+		};
+		
+		/* Quietly ignore any lines that have just whitespace */
+		cpnt = buffer;
+		while(*cpnt){
+			if(*cpnt != ' ' && *cpnt != '\t') break;
+			cpnt++;
+		};
+		if (!(*cpnt) || *cpnt == '\n') {
+			continue;
+		};
+		
+		nargs = sscanf(buffer, "%x %c %s", &addr, &type, name);
+		add_hash(name, (unsigned int *) addr);
+      };
+      fclose(symbolfile);
+}
+
+
+/* Load the entry points from the dynamic linking into the hash tables. 
+ * This does not work yet - something needs to be added before it scans the
+ * tables correctly 
+ */
+
+void
+load_entrypoints(){
+	char buffer[256];
+	char * cpnt;
+	int j, ordinal, len;
+	unsigned int address;
+
+	struct w_files * wpnt;
+	for(wpnt = wine_files; wpnt; wpnt = wpnt->next){
+		cpnt  = wpnt->nrname_table;
+		while(1==1){
+			if( ((int) cpnt)  - ((int)wpnt->nrname_table) >  
+			   wpnt->ne_header->nrname_tab_length)  break;
+			len = *cpnt++;
+			strncpy(buffer, cpnt, len);
+			buffer[len] = 0;
+			ordinal =  *((unsigned short *)  (cpnt +  len));
+			j = GetEntryPointFromOrdinal(wpnt, ordinal);		
+			address  = j & 0xffff;
+			j = j >> 16;
+			address |= (wpnt->selector_table[j].selector) << 16;
+			fprintf(stderr,"%s -> %x\n", buffer, address);
+			add_hash(buffer, (unsigned int *) address);
+			cpnt += len + 2;
+		};
+	};
+	return;
+}
diff --git a/debugger/i386-pinsn.c b/debugger/i386-pinsn.c
new file mode 100644
index 0000000..bd22a93
--- /dev/null
+++ b/debugger/i386-pinsn.c
@@ -0,0 +1,1905 @@
+/* Print i386 instructions for GDB, the GNU debugger.
+   Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/*
+ * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ */
+
+/*
+ * The main tables describing the instructions is essentially a copy
+ * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
+ * Programmers Manual.  Usually, there is a capital letter, followed
+ * by a small letter.  The capital letter tell the addressing mode,
+ * and the small letter tells about the operand size.  Refer to 
+ * the Intel manual for details.
+ */
+
+#include "defs.h"
+
+#include <ctype.h>
+
+/* For the GDB interface at the bottom of the file... */
+#include "gdbcore.h"
+
+#define Eb OP_E, b_mode
+#define indirEb OP_indirE, b_mode
+#define Gb OP_G, b_mode
+#define Ev OP_E, v_mode
+#define indirEv OP_indirE, v_mode
+#define Ew OP_E, w_mode
+#define Ma OP_E, v_mode
+#define M OP_E, 0
+#define Mp OP_E, 0		/* ? */
+#define Gv OP_G, v_mode
+#define Gw OP_G, w_mode
+#define Rw OP_rm, w_mode
+#define Rd OP_rm, d_mode
+#define Ib OP_I, b_mode
+#define sIb OP_sI, b_mode	/* sign extened byte */
+#define Iv OP_I, v_mode
+#define Iw OP_I, w_mode
+#define Jb OP_J, b_mode
+#define Jv OP_J, v_mode
+#define ONE OP_ONE, 0
+#define Cd OP_C, d_mode
+#define Dd OP_D, d_mode
+#define Td OP_T, d_mode
+
+#define eAX OP_REG, eAX_reg
+#define eBX OP_REG, eBX_reg
+#define eCX OP_REG, eCX_reg
+#define eDX OP_REG, eDX_reg
+#define eSP OP_REG, eSP_reg
+#define eBP OP_REG, eBP_reg
+#define eSI OP_REG, eSI_reg
+#define eDI OP_REG, eDI_reg
+#define AL OP_REG, al_reg
+#define CL OP_REG, cl_reg
+#define DL OP_REG, dl_reg
+#define BL OP_REG, bl_reg
+#define AH OP_REG, ah_reg
+#define CH OP_REG, ch_reg
+#define DH OP_REG, dh_reg
+#define BH OP_REG, bh_reg
+#define AX OP_REG, ax_reg
+#define DX OP_REG, dx_reg
+#define indirDX OP_REG, indir_dx_reg
+
+#define Sw OP_SEG, w_mode
+#define Ap OP_DIR, lptr
+#define Av OP_DIR, v_mode
+#define Ob OP_OFF, b_mode
+#define Ov OP_OFF, v_mode
+#define Xb OP_DSSI, b_mode
+#define Xv OP_DSSI, v_mode
+#define Yb OP_ESDI, b_mode
+#define Yv OP_ESDI, v_mode
+
+#define es OP_REG, es_reg
+#define ss OP_REG, ss_reg
+#define cs OP_REG, cs_reg
+#define ds OP_REG, ds_reg
+#define fs OP_REG, fs_reg
+#define gs OP_REG, gs_reg
+
+int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
+int OP_J(), OP_SEG();
+int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
+int OP_D(), OP_T(), OP_rm();
+
+static void dofloat (), putop (), append_prefix (), set_op ();
+static int get16 (), get32 ();
+
+#define b_mode 1
+#define v_mode 2
+#define w_mode 3
+#define d_mode 4
+
+#define es_reg 100
+#define cs_reg 101
+#define ss_reg 102
+#define ds_reg 103
+#define fs_reg 104
+#define gs_reg 105
+#define eAX_reg 107
+#define eCX_reg 108
+#define eDX_reg 109
+#define eBX_reg 110
+#define eSP_reg 111
+#define eBP_reg 112
+#define eSI_reg 113
+#define eDI_reg 114
+
+#define lptr 115
+
+#define al_reg 116
+#define cl_reg 117
+#define dl_reg 118
+#define bl_reg 119
+#define ah_reg 120
+#define ch_reg 121
+#define dh_reg 122
+#define bh_reg 123
+
+#define ax_reg 124
+#define cx_reg 125
+#define dx_reg 126
+#define bx_reg 127
+#define sp_reg 128
+#define bp_reg 129
+#define si_reg 130
+#define di_reg 131
+
+#define indir_dx_reg 150
+
+#define GRP1b NULL, NULL, 0
+#define GRP1S NULL, NULL, 1
+#define GRP1Ss NULL, NULL, 2
+#define GRP2b NULL, NULL, 3
+#define GRP2S NULL, NULL, 4
+#define GRP2b_one NULL, NULL, 5
+#define GRP2S_one NULL, NULL, 6
+#define GRP2b_cl NULL, NULL, 7
+#define GRP2S_cl NULL, NULL, 8
+#define GRP3b NULL, NULL, 9
+#define GRP3S NULL, NULL, 10
+#define GRP4  NULL, NULL, 11
+#define GRP5  NULL, NULL, 12
+#define GRP6  NULL, NULL, 13
+#define GRP7 NULL, NULL, 14
+#define GRP8 NULL, NULL, 15
+
+#define FLOATCODE 50
+#define FLOAT NULL, NULL, FLOATCODE
+
+struct dis386 {
+  char *name;
+  int (*op1)();
+  int bytemode1;
+  int (*op2)();
+  int bytemode2;
+  int (*op3)();
+  int bytemode3;
+};
+
+struct dis386 dis386[] = {
+  /* 00 */
+  { "addb",	Eb, Gb },
+  { "addS",	Ev, Gv },
+  { "addb",	Gb, Eb },
+  { "addS",	Gv, Ev },
+  { "addb",	AL, Ib },
+  { "addS",	eAX, Iv },
+  { "pushl",	es },
+  { "popl",	es },
+  /* 08 */
+  { "orb",	Eb, Gb },
+  { "orS",	Ev, Gv },
+  { "orb",	Gb, Eb },
+  { "orS",	Gv, Ev },
+  { "orb",	AL, Ib },
+  { "orS",	eAX, Iv },
+  { "pushl",	cs },
+  { "(bad)" },	/* 0x0f extended opcode escape */
+  /* 10 */
+  { "adcb",	Eb, Gb },
+  { "adcS",	Ev, Gv },
+  { "adcb",	Gb, Eb },
+  { "adcS",	Gv, Ev },
+  { "adcb",	AL, Ib },
+  { "adcS",	eAX, Iv },
+  { "pushl",	ss },
+  { "popl",	ss },
+  /* 18 */
+  { "sbbb",	Eb, Gb },
+  { "sbbS",	Ev, Gv },
+  { "sbbb",	Gb, Eb },
+  { "sbbS",	Gv, Ev },
+  { "sbbb",	AL, Ib },
+  { "sbbS",	eAX, Iv },
+  { "pushl",	ds },
+  { "popl",	ds },
+  /* 20 */
+  { "andb",	Eb, Gb },
+  { "andS",	Ev, Gv },
+  { "andb",	Gb, Eb },
+  { "andS",	Gv, Ev },
+  { "andb",	AL, Ib },
+  { "andS",	eAX, Iv },
+  { "(bad)" },			/* SEG ES prefix */
+  { "daa" },
+  /* 28 */
+  { "subb",	Eb, Gb },
+  { "subS",	Ev, Gv },
+  { "subb",	Gb, Eb },
+  { "subS",	Gv, Ev },
+  { "subb",	AL, Ib },
+  { "subS",	eAX, Iv },
+  { "(bad)" },			/* SEG CS prefix */
+  { "das" },
+  /* 30 */
+  { "xorb",	Eb, Gb },
+  { "xorS",	Ev, Gv },
+  { "xorb",	Gb, Eb },
+  { "xorS",	Gv, Ev },
+  { "xorb",	AL, Ib },
+  { "xorS",	eAX, Iv },
+  { "(bad)" },			/* SEG SS prefix */
+  { "aaa" },
+  /* 38 */
+  { "cmpb",	Eb, Gb },
+  { "cmpS",	Ev, Gv },
+  { "cmpb",	Gb, Eb },
+  { "cmpS",	Gv, Ev },
+  { "cmpb",	AL, Ib },
+  { "cmpS",	eAX, Iv },
+  { "(bad)" },			/* SEG DS prefix */
+  { "aas" },
+  /* 40 */
+  { "incS",	eAX },
+  { "incS",	eCX },
+  { "incS",	eDX },
+  { "incS",	eBX },
+  { "incS",	eSP },
+  { "incS",	eBP },
+  { "incS",	eSI },
+  { "incS",	eDI },
+  /* 48 */
+  { "decS",	eAX },
+  { "decS",	eCX },
+  { "decS",	eDX },
+  { "decS",	eBX },
+  { "decS",	eSP },
+  { "decS",	eBP },
+  { "decS",	eSI },
+  { "decS",	eDI },
+  /* 50 */
+  { "pushS",	eAX },
+  { "pushS",	eCX },
+  { "pushS",	eDX },
+  { "pushS",	eBX },
+  { "pushS",	eSP },
+  { "pushS",	eBP },
+  { "pushS",	eSI },
+  { "pushS",	eDI },
+  /* 58 */
+  { "popS",	eAX },
+  { "popS",	eCX },
+  { "popS",	eDX },
+  { "popS",	eBX },
+  { "popS",	eSP },
+  { "popS",	eBP },
+  { "popS",	eSI },
+  { "popS",	eDI },
+  /* 60 */
+  { "pusha" },
+  { "popa" },
+  { "boundS",	Gv, Ma },
+  { "arpl",	Ew, Gw },
+  { "(bad)" },			/* seg fs */
+  { "(bad)" },			/* seg gs */
+  { "(bad)" },			/* op size prefix */
+  { "(bad)" },			/* adr size prefix */
+  /* 68 */
+  { "pushS",	Iv },		/* 386 book wrong */
+  { "imulS",	Gv, Ev, Iv },
+  { "pushl",	sIb },		/* push of byte really pushes 4 bytes */
+  { "imulS",	Gv, Ev, Ib },
+  { "insb",	Yb, indirDX },
+  { "insS",	Yv, indirDX },
+  { "outsb",	indirDX, Xb },
+  { "outsS",	indirDX, Xv },
+  /* 70 */
+  { "jo",		Jb },
+  { "jno",	Jb },
+  { "jb",		Jb },
+  { "jae",	Jb },
+  { "je",		Jb },
+  { "jne",	Jb },
+  { "jbe",	Jb },
+  { "ja",		Jb },
+  /* 78 */
+  { "js",		Jb },
+  { "jns",	Jb },
+  { "jp",		Jb },
+  { "jnp",	Jb },
+  { "jl",		Jb },
+  { "jnl",	Jb },
+  { "jle",	Jb },
+  { "jg",		Jb },
+  /* 80 */
+  { GRP1b },
+  { GRP1S },
+  { "(bad)" },
+  { GRP1Ss },
+  { "testb",	Eb, Gb },
+  { "testS",	Ev, Gv },
+  { "xchgb",	Eb, Gb },
+  { "xchgS",	Ev, Gv },
+  /* 88 */
+  { "movb",	Eb, Gb },
+  { "movS",	Ev, Gv },
+  { "movb",	Gb, Eb },
+  { "movS",	Gv, Ev },
+  { "movw",	Ew, Sw },
+  { "leaS",	Gv, M },
+  { "movw",	Sw, Ew },
+  { "popS",	Ev },
+  /* 90 */
+  { "nop" },
+  { "xchgS",	eCX, eAX },
+  { "xchgS",	eDX, eAX },
+  { "xchgS",	eBX, eAX },
+  { "xchgS",	eSP, eAX },
+  { "xchgS",	eBP, eAX },
+  { "xchgS",	eSI, eAX },
+  { "xchgS",	eDI, eAX },
+  /* 98 */
+  { "cwtl" },
+  { "cltd" },
+  { "lcall",	Ap },
+  { "(bad)" },		/* fwait */
+  { "pushf" },
+  { "popf" },
+  { "sahf" },
+  { "lahf" },
+  /* a0 */
+  { "movb",	AL, Ob },
+  { "movS",	eAX, Ov },
+  { "movb",	Ob, AL },
+  { "movS",	Ov, eAX },
+  { "movsb",	Yb, Xb },
+  { "movsS",	Yv, Xv },
+  { "cmpsb",	Yb, Xb },
+  { "cmpsS",	Yv, Xv },
+  /* a8 */
+  { "testb",	AL, Ib },
+  { "testS",	eAX, Iv },
+  { "stosb",	Yb, AL },
+  { "stosS",	Yv, eAX },
+  { "lodsb",	AL, Xb },
+  { "lodsS",	eAX, Xv },
+  { "scasb",	AL, Xb },
+  { "scasS",	eAX, Xv },
+  /* b0 */
+  { "movb",	AL, Ib },
+  { "movb",	CL, Ib },
+  { "movb",	DL, Ib },
+  { "movb",	BL, Ib },
+  { "movb",	AH, Ib },
+  { "movb",	CH, Ib },
+  { "movb",	DH, Ib },
+  { "movb",	BH, Ib },
+  /* b8 */
+  { "movS",	eAX, Iv },
+  { "movS",	eCX, Iv },
+  { "movS",	eDX, Iv },
+  { "movS",	eBX, Iv },
+  { "movS",	eSP, Iv },
+  { "movS",	eBP, Iv },
+  { "movS",	eSI, Iv },
+  { "movS",	eDI, Iv },
+  /* c0 */
+  { GRP2b },
+  { GRP2S },
+  { "ret",	Iw },
+  { "ret" },
+  { "lesS",	Gv, Mp },
+  { "ldsS",	Gv, Mp },
+  { "movb",	Eb, Ib },
+  { "movS",	Ev, Iv },
+  /* c8 */
+  { "enter",	Iw, Ib },
+  { "leave" },
+  { "lret",	Iw },
+  { "lret" },
+  { "int3" },
+  { "int",	Ib },
+  { "into" },
+  { "iret" },
+  /* d0 */
+  { GRP2b_one },
+  { GRP2S_one },
+  { GRP2b_cl },
+  { GRP2S_cl },
+  { "aam",	Ib },
+  { "aad",	Ib },
+  { "(bad)" },
+  { "xlat" },
+  /* d8 */
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  { FLOAT },
+  /* e0 */
+  { "loopne",	Jb },
+  { "loope",	Jb },
+  { "loop",	Jb },
+  { "jCcxz",	Jb },
+  { "inb",	AL, Ib },
+  { "inS",	eAX, Ib },
+  { "outb",	Ib, AL },
+  { "outS",	Ib, eAX },
+  /* e8 */
+  { "call",	Av },
+  { "jmp",	Jv },
+  { "ljmp",	Ap },
+  { "jmp",	Jb },
+  { "inb",	AL, indirDX },
+  { "inS",	eAX, indirDX },
+  { "outb",	indirDX, AL },
+  { "outS",	indirDX, eAX },
+  /* f0 */
+  { "(bad)" },			/* lock prefix */
+  { "(bad)" },
+  { "(bad)" },			/* repne */
+  { "(bad)" },			/* repz */
+  { "hlt" },
+  { "cmc" },
+  { GRP3b },
+  { GRP3S },
+  /* f8 */
+  { "clc" },
+  { "stc" },
+  { "cli" },
+  { "sti" },
+  { "cld" },
+  { "std" },
+  { GRP4 },
+  { GRP5 },
+};
+
+struct dis386 dis386_twobyte[] = {
+  /* 00 */
+  { GRP6 },
+  { GRP7 },
+  { "larS", Gv, Ew },
+  { "lslS", Gv, Ew },  
+  { "(bad)" },
+  { "(bad)" },
+  { "clts" },
+  { "(bad)" },  
+  /* 08 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 10 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 18 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 20 */
+  /* these are all backward in appendix A of the intel book */
+  { "movl", Rd, Cd },
+  { "movl", Rd, Dd },
+  { "movl", Cd, Rd },
+  { "movl", Dd, Rd },  
+  { "movl", Rd, Td },
+  { "(bad)" },
+  { "movl", Td, Rd },
+  { "(bad)" },  
+  /* 28 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 30 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 38 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 40 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 48 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 50 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 58 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 60 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 68 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 70 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 78 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* 80 */
+  { "jo", Jv },
+  { "jno", Jv },
+  { "jb", Jv },
+  { "jae", Jv },  
+  { "je", Jv },
+  { "jne", Jv },
+  { "jbe", Jv },
+  { "ja", Jv },  
+  /* 88 */
+  { "js", Jv },
+  { "jns", Jv },
+  { "jp", Jv },
+  { "jnp", Jv },  
+  { "jl", Jv },
+  { "jge", Jv },
+  { "jle", Jv },
+  { "jg", Jv },  
+  /* 90 */
+  { "seto", Eb },
+  { "setno", Eb },
+  { "setb", Eb },
+  { "setae", Eb },
+  { "sete", Eb },
+  { "setne", Eb },
+  { "setbe", Eb },
+  { "seta", Eb },
+  /* 98 */
+  { "sets", Eb },
+  { "setns", Eb },
+  { "setp", Eb },
+  { "setnp", Eb },
+  { "setl", Eb },
+  { "setge", Eb },
+  { "setle", Eb },
+  { "setg", Eb },  
+  /* a0 */
+  { "pushl", fs },
+  { "popl", fs },
+  { "(bad)" },
+  { "btS", Ev, Gv },  
+  { "shldS", Ev, Gv, Ib },
+  { "shldS", Ev, Gv, CL },
+  { "(bad)" },
+  { "(bad)" },  
+  /* a8 */
+  { "pushl", gs },
+  { "popl", gs },
+  { "(bad)" },
+  { "btsS", Ev, Gv },  
+  { "shrdS", Ev, Gv, Ib },
+  { "shrdS", Ev, Gv, CL },
+  { "(bad)" },
+  { "imulS", Gv, Ev },  
+  /* b0 */
+  { "(bad)" },
+  { "(bad)" },
+  { "lssS", Gv, Mp },	/* 386 lists only Mp */
+  { "btrS", Ev, Gv },  
+  { "lfsS", Gv, Mp },	/* 386 lists only Mp */
+  { "lgsS", Gv, Mp },	/* 386 lists only Mp */
+  { "movzbS", Gv, Eb },
+  { "movzwS", Gv, Ew },  
+  /* b8 */
+  { "(bad)" },
+  { "(bad)" },
+  { GRP8 },
+  { "btcS", Ev, Gv },  
+  { "bsfS", Gv, Ev },
+  { "bsrS", Gv, Ev },
+  { "movsbS", Gv, Eb },
+  { "movswS", Gv, Ew },  
+  /* c0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* c8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* d0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* d8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* e0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* e8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* f0 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  /* f8 */
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
+};
+
+static char obuf[100];
+static char *obufp;
+static char scratchbuf[100];
+static unsigned char *start_codep;
+static unsigned char *codep;
+static int mod;
+static int rm;
+static int reg;
+static void oappend ();
+
+static char *names32[]={
+  "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
+};
+static char *names16[] = {
+  "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
+};
+static char *names8[] = {
+  "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
+};
+static char *names_seg[] = {
+  "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+};
+
+struct dis386 grps[][8] = {
+  /* GRP1b */
+  {
+    { "addb",	Eb, Ib },
+    { "orb",	Eb, Ib },
+    { "adcb",	Eb, Ib },
+    { "sbbb",	Eb, Ib },
+    { "andb",	Eb, Ib },
+    { "subb",	Eb, Ib },
+    { "xorb",	Eb, Ib },
+    { "cmpb",	Eb, Ib }
+  },
+  /* GRP1S */
+  {
+    { "addS",	Ev, Iv },
+    { "orS",	Ev, Iv },
+    { "adcS",	Ev, Iv },
+    { "sbbS",	Ev, Iv },
+    { "andS",	Ev, Iv },
+    { "subS",	Ev, Iv },
+    { "xorS",	Ev, Iv },
+    { "cmpS",	Ev, Iv }
+  },
+  /* GRP1Ss */
+  {
+    { "addS",	Ev, sIb },
+    { "orS",	Ev, sIb },
+    { "adcS",	Ev, sIb },
+    { "sbbS",	Ev, sIb },
+    { "andS",	Ev, sIb },
+    { "subS",	Ev, sIb },
+    { "xorS",	Ev, sIb },
+    { "cmpS",	Ev, sIb }
+  },
+  /* GRP2b */
+  {
+    { "rolb",	Eb, Ib },
+    { "rorb",	Eb, Ib },
+    { "rclb",	Eb, Ib },
+    { "rcrb",	Eb, Ib },
+    { "shlb",	Eb, Ib },
+    { "shrb",	Eb, Ib },
+    { "(bad)" },
+    { "sarb",	Eb, Ib },
+  },
+  /* GRP2S */
+  {
+    { "rolS",	Ev, Ib },
+    { "rorS",	Ev, Ib },
+    { "rclS",	Ev, Ib },
+    { "rcrS",	Ev, Ib },
+    { "shlS",	Ev, Ib },
+    { "shrS",	Ev, Ib },
+    { "(bad)" },
+    { "sarS",	Ev, Ib },
+  },
+  /* GRP2b_one */
+  {
+    { "rolb",	Eb },
+    { "rorb",	Eb },
+    { "rclb",	Eb },
+    { "rcrb",	Eb },
+    { "shlb",	Eb },
+    { "shrb",	Eb },
+    { "(bad)" },
+    { "sarb",	Eb },
+  },
+  /* GRP2S_one */
+  {
+    { "rolS",	Ev },
+    { "rorS",	Ev },
+    { "rclS",	Ev },
+    { "rcrS",	Ev },
+    { "shlS",	Ev },
+    { "shrS",	Ev },
+    { "(bad)" },
+    { "sarS",	Ev },
+  },
+  /* GRP2b_cl */
+  {
+    { "rolb",	Eb, CL },
+    { "rorb",	Eb, CL },
+    { "rclb",	Eb, CL },
+    { "rcrb",	Eb, CL },
+    { "shlb",	Eb, CL },
+    { "shrb",	Eb, CL },
+    { "(bad)" },
+    { "sarb",	Eb, CL },
+  },
+  /* GRP2S_cl */
+  {
+    { "rolS",	Ev, CL },
+    { "rorS",	Ev, CL },
+    { "rclS",	Ev, CL },
+    { "rcrS",	Ev, CL },
+    { "shlS",	Ev, CL },
+    { "shrS",	Ev, CL },
+    { "(bad)" },
+    { "sarS",	Ev, CL }
+  },
+  /* GRP3b */
+  {
+    { "testb",	Eb, Ib },
+    { "(bad)",	Eb },
+    { "notb",	Eb },
+    { "negb",	Eb },
+    { "mulb",	AL, Eb },
+    { "imulb",	AL, Eb },
+    { "divb",	AL, Eb },
+    { "idivb",	AL, Eb }
+  },
+  /* GRP3S */
+  {
+    { "testS",	Ev, Iv },
+    { "(bad)" },
+    { "notS",	Ev },
+    { "negS",	Ev },
+    { "mulS",	eAX, Ev },
+    { "imulS",	eAX, Ev },
+    { "divS",	eAX, Ev },
+    { "idivS",	eAX, Ev },
+  },
+  /* GRP4 */
+  {
+    { "incb", Eb },
+    { "decb", Eb },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* GRP5 */
+  {
+    { "incS",	Ev },
+    { "decS",	Ev },
+    { "call",	indirEv },
+    { "lcall",	indirEv },
+    { "jmp",	indirEv },
+    { "ljmp",	indirEv },
+    { "pushS",	Ev },
+    { "(bad)" },
+  },
+  /* GRP6 */
+  {
+    { "sldt",	Ew },
+    { "str",	Ew },
+    { "lldt",	Ew },
+    { "ltr",	Ew },
+    { "verr",	Ew },
+    { "verw",	Ew },
+    { "(bad)" },
+    { "(bad)" }
+  },
+  /* GRP7 */
+  {
+    { "sgdt", Ew },
+    { "sidt", Ew },
+    { "lgdt", Ew },
+    { "lidt", Ew },
+    { "smsw", Ew },
+    { "(bad)" },
+    { "lmsw", Ew },
+    { "(bad)" },
+  },
+  /* GRP8 */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "btS",	Ev, Ib },
+    { "btsS",	Ev, Ib },
+    { "btrS",	Ev, Ib },
+    { "btcS",	Ev, Ib },
+  }
+};
+
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADR 0x400
+#define PREFIX_FWAIT 0x800
+
+static int prefixes;
+
+static void
+ckprefix ()
+{
+  prefixes = 0;
+  while (1)
+    {
+      switch (*codep)
+	{
+	case 0xf3:
+	  prefixes |= PREFIX_REPZ;
+	  break;
+	case 0xf2:
+	  prefixes |= PREFIX_REPNZ;
+	  break;
+	case 0xf0:
+	  prefixes |= PREFIX_LOCK;
+	  break;
+	case 0x2e:
+	  prefixes |= PREFIX_CS;
+	  break;
+	case 0x36:
+	  prefixes |= PREFIX_SS;
+	  break;
+	case 0x3e:
+	  prefixes |= PREFIX_DS;
+	  break;
+	case 0x26:
+	  prefixes |= PREFIX_ES;
+	  break;
+	case 0x64:
+	  prefixes |= PREFIX_FS;
+	  break;
+	case 0x65:
+	  prefixes |= PREFIX_GS;
+	  break;
+	case 0x66:
+	  prefixes |= PREFIX_DATA;
+	  break;
+	case 0x67:
+	  prefixes |= PREFIX_ADR;
+	  break;
+	case 0x9b:
+	  prefixes |= PREFIX_FWAIT;
+	  break;
+	default:
+	  return;
+	}
+      codep++;
+    }
+}
+
+static int dflag;
+static int aflag;		
+
+static char op1out[100], op2out[100], op3out[100];
+static int op_address[3], op_ad, op_index[3];
+static int start_pc;
+extern void fputs_filtered ();
+
+/*
+ * disassemble the first instruction in 'inbuf'.  You have to make
+ *   sure all of the bytes of the instruction are filled in.
+ *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
+ *   (see topic "Redundant prefixes" in the "Differences from 8086"
+ *   section of the "Virtual 8086 Mode" chapter.)
+ * 'pc' should be the address of this instruction, it will
+ *   be used to print the target address if this is a relative jump or call
+ * 'outbuf' gets filled in with the disassembled instruction.  it should
+ *   be long enough to hold the longest disassembled instruction.
+ *   100 bytes is certainly enough, unless symbol printing is added later
+ * The function returns the length of this instruction in bytes.
+ */
+
+int
+i386dis (pc, inbuf, stream)
+     int pc;
+     unsigned char *inbuf;
+     FILE *stream;
+{
+  struct dis386 *dp;
+  int i;
+  int enter_instruction;
+  char *first, *second, *third;
+  int needcomma;
+  
+  obuf[0] = 0;
+  op1out[0] = 0;
+  op2out[0] = 0;
+  op3out[0] = 0;
+
+  op_index[0] = op_index[1] = op_index[2] = -1;
+  
+  start_pc = pc;
+  start_codep = inbuf;
+  codep = inbuf;
+  
+  ckprefix ();
+  
+  if (*codep == 0xc8)
+    enter_instruction = 1;
+  else
+    enter_instruction = 0;
+  
+  obufp = obuf;
+  
+  if (prefixes & PREFIX_REPZ)
+    oappend ("repz ");
+  if (prefixes & PREFIX_REPNZ)
+    oappend ("repnz ");
+  if (prefixes & PREFIX_LOCK)
+    oappend ("lock ");
+  
+  if ((prefixes & PREFIX_FWAIT)
+      && ((*codep < 0xd8) || (*codep > 0xdf)))
+    {
+      /* fwait not followed by floating point instruction */
+      fputs_filtered ("fwait", stream);
+      return (1);
+    }
+  
+  /* these would be initialized to 0 if disassembling for 8086 or 286 */
+
+  if (prefixes & PREFIX_DATA)
+    dflag ^= 1;
+  
+  if (prefixes & PREFIX_ADR)
+    {
+      aflag ^= 1;
+      oappend ("addr16 ");
+    }
+  
+  if (*codep == 0x0f)
+    dp = &dis386_twobyte[*++codep];
+  else
+    dp = &dis386[*codep];
+  codep++;
+  mod = (*codep >> 6) & 3;
+  reg = (*codep >> 3) & 7;
+  rm = *codep & 7;
+  
+  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
+    {
+      dofloat ();
+    }
+  else
+    {
+      if (dp->name == NULL)
+	dp = &grps[dp->bytemode1][reg];
+      
+      putop (dp->name);
+      
+      obufp = op1out;
+      op_ad = 2;
+      if (dp->op1)
+	(*dp->op1)(dp->bytemode1);
+      
+      obufp = op2out;
+      op_ad = 1;
+      if (dp->op2)
+	(*dp->op2)(dp->bytemode2);
+      
+      obufp = op3out;
+      op_ad = 0;
+      if (dp->op3)
+	(*dp->op3)(dp->bytemode3);
+    }
+  
+  obufp = obuf + strlen (obuf);
+  for (i = strlen (obuf); i < 6; i++)
+    oappend (" ");
+  oappend (" ");
+  fputs_filtered (obuf, stream);
+  
+  /* enter instruction is printed with operands in the
+   * same order as the intel book; everything else
+   * is printed in reverse order 
+   */
+  if (enter_instruction)
+    {
+      first = op1out;
+      second = op2out;
+      third = op3out;
+      op_ad = op_index[0];
+      op_index[0] = op_index[2];
+      op_index[2] = op_ad;
+    }
+  else
+    {
+      first = op3out;
+      second = op2out;
+      third = op1out;
+    }
+  needcomma = 0;
+  if (*first)
+    {
+      if (op_index[0] != -1)
+	print_address (op_address[op_index[0]], stream);
+      else
+	fputs_filtered (first, stream);
+      needcomma = 1;
+    }
+  if (*second)
+    {
+      if (needcomma)
+	fputs_filtered (",", stream);
+      if (op_index[1] != -1)
+	print_address (op_address[op_index[1]], stream);
+      else
+	fputs_filtered (second, stream);
+      needcomma = 1;
+    }
+  if (*third)
+    {
+      if (needcomma)
+	fputs_filtered (",", stream);
+      if (op_index[2] != -1)
+	print_address (op_address[op_index[2]], stream);
+      else
+	fputs_filtered (third, stream);
+    }
+  return (codep - inbuf);
+}
+
+char *float_mem[] = {
+  /* d8 */
+  "fadds",
+  "fmuls",
+  "fcoms",
+  "fcomps",
+  "fsubs",
+  "fsubrs",
+  "fdivs",
+  "fdivrs",
+  /*  d9 */
+  "flds",
+  "(bad)",
+  "fsts",
+  "fstps",
+  "fldenv",
+  "fldcw",
+  "fNstenv",
+  "fNstcw",
+  /* da */
+  "fiaddl",
+  "fimull",
+  "ficoml",
+  "ficompl",
+  "fisubl",
+  "fisubrl",
+  "fidivl",
+  "fidivrl",
+  /* db */
+  "fildl",
+  "(bad)",
+  "fistl",
+  "fistpl",
+  "(bad)",
+  "fldt",
+  "(bad)",
+  "fstpt",
+  /* dc */
+  "faddl",
+  "fmull",
+  "fcoml",
+  "fcompl",
+  "fsubl",
+  "fsubrl",
+  "fdivl",
+  "fdivrl",
+  /* dd */
+  "fldl",
+  "(bad)",
+  "fstl",
+  "fstpl",
+  "frstor",
+  "(bad)",
+  "fNsave",
+  "fNstsw",
+  /* de */
+  "fiadd",
+  "fimul",
+  "ficom",
+  "ficomp",
+  "fisub",
+  "fisubr",
+  "fidiv",
+  "fidivr",
+  /* df */
+  "fild",
+  "(bad)",
+  "fist",
+  "fistp",
+  "fbld",
+  "fildll",
+  "fbstp",
+  "fistpll",
+};
+
+#define ST OP_ST, 0
+#define STi OP_STi, 0
+int OP_ST(), OP_STi();
+
+#define FGRPd9_2 NULL, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1
+#define FGRPd9_5 NULL, NULL, 2
+#define FGRPd9_6 NULL, NULL, 3
+#define FGRPd9_7 NULL, NULL, 4
+#define FGRPda_5 NULL, NULL, 5
+#define FGRPdb_4 NULL, NULL, 6
+#define FGRPde_3 NULL, NULL, 7
+#define FGRPdf_4 NULL, NULL, 8
+
+struct dis386 float_reg[][8] = {
+  /* d8 */
+  {
+    { "fadd",	ST, STi },
+    { "fmul",	ST, STi },
+    { "fcom",	STi },
+    { "fcomp",	STi },
+    { "fsub",	ST, STi },
+    { "fsubr",	ST, STi },
+    { "fdiv",	ST, STi },
+    { "fdivr",	ST, STi },
+  },
+  /* d9 */
+  {
+    { "fld",	STi },
+    { "fxch",	STi },
+    { FGRPd9_2 },
+    { "(bad)" },
+    { FGRPd9_4 },
+    { FGRPd9_5 },
+    { FGRPd9_6 },
+    { FGRPd9_7 },
+  },
+  /* da */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { FGRPda_5 },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* db */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { FGRPdb_4 },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* dc */
+  {
+    { "fadd",	STi, ST },
+    { "fmul",	STi, ST },
+    { "(bad)" },
+    { "(bad)" },
+    { "fsub",	STi, ST },
+    { "fsubr",	STi, ST },
+    { "fdiv",	STi, ST },
+    { "fdivr",	STi, ST },
+  },
+  /* dd */
+  {
+    { "ffree",	STi },
+    { "(bad)" },
+    { "fst",	STi },
+    { "fstp",	STi },
+    { "fucom",	STi },
+    { "fucomp",	STi },
+    { "(bad)" },
+    { "(bad)" },
+  },
+  /* de */
+  {
+    { "faddp",	STi, ST },
+    { "fmulp",	STi, ST },
+    { "(bad)" },
+    { FGRPde_3 },
+    { "fsubp",	STi, ST },
+    { "fsubrp",	STi, ST },
+    { "fdivp",	STi, ST },
+    { "fdivrp",	STi, ST },
+  },
+  /* df */
+  {
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+    { FGRPdf_4 },
+    { "(bad)" },
+    { "(bad)" },
+    { "(bad)" },
+  },
+};
+
+
+char *fgrps[][8] = {
+  /* d9_2  0 */
+  {
+    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* d9_4  1 */
+  {
+    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
+  },
+
+  /* d9_5  2 */
+  {
+    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
+  },
+
+  /* d9_6  3 */
+  {
+    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
+  },
+
+  /* d9_7  4 */
+  {
+    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
+  },
+
+  /* da_5  5 */
+  {
+    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* db_4  6 */
+  {
+    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
+    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+  },
+
+  /* de_3  7 */
+  {
+    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+
+  /* df_4  8 */
+  {
+    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+  },
+};
+
+static void
+dofloat ()
+{
+  struct dis386 *dp;
+  unsigned char floatop;
+  
+  floatop = codep[-1];
+  
+  if (mod != 3)
+    {
+      putop (float_mem[(floatop - 0xd8) * 8 + reg]);
+      obufp = op1out;
+      OP_E (v_mode);
+      return;
+    }
+  codep++;
+  
+  dp = &float_reg[floatop - 0xd8][reg];
+  if (dp->name == NULL)
+    {
+      putop (fgrps[dp->bytemode1][rm]);
+      /* instruction fnstsw is only one with strange arg */
+      if (floatop == 0xdf && *codep == 0xe0)
+	strcpy (op1out, "%eax");
+    }
+  else
+    {
+      putop (dp->name);
+      obufp = op1out;
+      if (dp->op1)
+	(*dp->op1)(dp->bytemode1);
+      obufp = op2out;
+      if (dp->op2)
+	(*dp->op2)(dp->bytemode2);
+    }
+}
+
+/* ARGSUSED */
+int
+OP_ST (ignore)
+     int ignore;
+{
+  oappend ("%st");
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_STi (ignore)
+     int ignore;
+{
+  sprintf (scratchbuf, "%%st(%d)", rm);
+  oappend (scratchbuf);
+  return (0);
+}
+
+
+/* capital letters in template are macros */
+static void
+putop (template)
+     char *template;
+{
+  char *p;
+  
+  for (p = template; *p; p++)
+    {
+      switch (*p)
+	{
+	default:
+	  *obufp++ = *p;
+	  break;
+	case 'C':		/* For jcxz/jecxz */
+	  if (aflag == 0)
+	    *obufp++ = 'e';
+	  break;
+	case 'N':
+	  if ((prefixes & PREFIX_FWAIT) == 0)
+	    *obufp++ = 'n';
+	  break;
+	case 'S':
+	  /* operand size flag */
+	  if (dflag)
+	    *obufp++ = 'l';
+	  else
+	    *obufp++ = 'w';
+	  break;
+	}
+    }
+  *obufp = 0;
+}
+
+static void
+oappend (s)
+     char *s;
+{
+  strcpy (obufp, s);
+  obufp += strlen (s);
+  *obufp = 0;
+}
+
+static void
+append_prefix ()
+{
+  if (prefixes & PREFIX_CS)
+    oappend ("%cs:");
+  if (prefixes & PREFIX_DS)
+    oappend ("%ds:");
+  if (prefixes & PREFIX_SS)
+    oappend ("%ss:");
+  if (prefixes & PREFIX_ES)
+    oappend ("%es:");
+  if (prefixes & PREFIX_FS)
+    oappend ("%fs:");
+  if (prefixes & PREFIX_GS)
+    oappend ("%gs:");
+}
+
+int
+OP_indirE (bytemode)
+     int bytemode;
+{
+  oappend ("*");
+  OP_E (bytemode);
+  return (0);
+}
+
+int
+OP_E (bytemode)
+     int bytemode;
+{
+  int disp;
+  int havesib;
+  int base;
+  int index;
+  int scale;
+  int havebase;
+  
+  /* skip mod/rm byte */
+  codep++;
+  
+  havesib = 0;
+  havebase = 0;
+  disp = 0;
+  
+  if (mod == 3)
+    {
+      switch (bytemode)
+	{
+	case b_mode:
+	  oappend (names8[rm]);
+	  break;
+	case w_mode:
+	  oappend (names16[rm]);
+	  break;
+	case v_mode:
+	  if (dflag)
+	    oappend (names32[rm]);
+	  else
+	    oappend (names16[rm]);
+	  break;
+	default:
+	  oappend ("<bad dis table>");
+	  break;
+	}
+      return (0);
+    }
+  
+  append_prefix ();
+  if (rm == 4)
+    {
+      havesib = 1;
+      havebase = 1;
+      scale = (*codep >> 6) & 3;
+      index = (*codep >> 3) & 7;
+      base = *codep & 7;
+      codep++;
+    }
+  
+  switch (mod)
+    {
+    case 0:
+      switch (rm)
+	{
+	case 4:
+	  /* implies havesib and havebase */
+	  if (base == 5) {
+	    havebase = 0;
+	    disp = get32 ();
+	  }
+	  break;
+	case 5:
+	  disp = get32 ();
+	  break;
+	default:
+	  havebase = 1;
+	  base = rm;
+	  break;
+	}
+      break;
+    case 1:
+      disp = *(char *)codep++;
+      if (rm != 4)
+	{
+	  havebase = 1;
+	  base = rm;
+	}
+      break;
+    case 2:
+      disp = get32 ();
+      if (rm != 4)
+	{
+	  havebase = 1;
+	  base = rm;
+	}
+      break;
+    }
+  
+  if (mod != 0 || rm == 5 || (havesib && base == 5))
+    {
+      sprintf (scratchbuf, "0x%x", disp);
+      oappend (scratchbuf);
+    }
+  
+  if (havebase || havesib) 
+    {
+      oappend ("(");
+      if (havebase)
+	oappend (names32[base]);
+      if (havesib) 
+	{
+	  if (index != 4) 
+	    {
+	      sprintf (scratchbuf, ",%s", names32[index]);
+	      oappend (scratchbuf);
+	    }
+	  sprintf (scratchbuf, ",%d", 1 << scale);
+	  oappend (scratchbuf);
+	}
+      oappend (")");
+    }
+  return (0);
+}
+
+int
+OP_G (bytemode)
+     int bytemode;
+{
+  switch (bytemode) 
+    {
+    case b_mode:
+      oappend (names8[reg]);
+      break;
+    case w_mode:
+      oappend (names16[reg]);
+      break;
+    case d_mode:
+      oappend (names32[reg]);
+      break;
+    case v_mode:
+      if (dflag)
+	oappend (names32[reg]);
+      else
+	oappend (names16[reg]);
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      break;
+    }
+  return (0);
+}
+
+static int
+get32 ()
+{
+  int x = 0;
+  
+  x = *codep++ & 0xff;
+  x |= (*codep++ & 0xff) << 8;
+  x |= (*codep++ & 0xff) << 16;
+  x |= (*codep++ & 0xff) << 24;
+  return (x);
+}
+
+static int
+get16 ()
+{
+  int x = 0;
+  
+  x = *codep++ & 0xff;
+  x |= (*codep++ & 0xff) << 8;
+  return (x);
+}
+
+static void
+set_op (op)
+     int op;
+{
+  op_index[op_ad] = op_ad;
+  op_address[op_ad] = op;
+}
+
+int
+OP_REG (code)
+     int code;
+{
+  char *s;
+  
+  switch (code) 
+    {
+    case indir_dx_reg: s = "(%dx)"; break;
+	case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+	case sp_reg: case bp_reg: case si_reg: case di_reg:
+		s = names16[code - ax_reg];
+		break;
+	case es_reg: case ss_reg: case cs_reg:
+	case ds_reg: case fs_reg: case gs_reg:
+		s = names_seg[code - es_reg];
+		break;
+	case al_reg: case ah_reg: case cl_reg: case ch_reg:
+	case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+		s = names8[code - al_reg];
+		break;
+	case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+	case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+      if (dflag)
+	s = names32[code - eAX_reg];
+      else
+	s = names16[code - eAX_reg];
+      break;
+    default:
+      s = "<internal disassembler error>";
+      break;
+    }
+  oappend (s);
+  return (0);
+}
+
+int
+OP_I (bytemode)
+     int bytemode;
+{
+  int op;
+  
+  switch (bytemode) 
+    {
+    case b_mode:
+      op = *codep++ & 0xff;
+      break;
+    case v_mode:
+      if (dflag)
+	op = get32 ();
+      else
+	op = get16 ();
+      break;
+    case w_mode:
+      op = get16 ();
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      return (0);
+    }
+  sprintf (scratchbuf, "$0x%x", op);
+  oappend (scratchbuf);
+  return (0);
+}
+
+int
+OP_sI (bytemode)
+     int bytemode;
+{
+  int op;
+  
+  switch (bytemode) 
+    {
+    case b_mode:
+      op = *(char *)codep++;
+      break;
+    case v_mode:
+      if (dflag)
+	op = get32 ();
+      else
+	op = (short)get16();
+      break;
+    case w_mode:
+      op = (short)get16 ();
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      return (0);
+    }
+  sprintf (scratchbuf, "$0x%x", op);
+  oappend (scratchbuf);
+  return (0);
+}
+
+int
+OP_J (bytemode)
+     int bytemode;
+{
+  int disp;
+  int mask = -1;
+  
+  switch (bytemode) 
+    {
+    case b_mode:
+      disp = *(char *)codep++;
+      break;
+    case v_mode:
+      if (dflag)
+	disp = get32 ();
+      else
+	{
+	  disp = (short)get16 ();
+	  /* for some reason, a data16 prefix on a jump instruction
+	     means that the pc is masked to 16 bits after the
+	     displacement is added!  */
+	  mask = 0xffff;
+	}
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      return (0);
+    }
+  disp = (start_pc + codep - start_codep + disp) & mask;
+  set_op (disp);
+  sprintf (scratchbuf, "0x%x", disp);
+  oappend (scratchbuf);
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_SEG (dummy)
+     int dummy;
+{
+  static char *sreg[] = {
+    "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
+  };
+
+  oappend (sreg[reg]);
+  return (0);
+}
+
+int
+OP_DIR (size)
+     int size;
+{
+  int seg, offset;
+  
+  switch (size) 
+    {
+    case lptr:
+      if (aflag) 
+	{
+	  offset = get32 ();
+	  seg = get16 ();
+	} 
+      else 
+	{
+	  offset = get16 ();
+	  seg = get16 ();
+	}
+      sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+      oappend (scratchbuf);
+      break;
+    case v_mode:
+      if (aflag)
+	offset = get32 ();
+      else
+	offset = (short)get16 ();
+      
+      offset = start_pc + codep - start_codep + offset;
+      set_op (offset);
+      sprintf (scratchbuf, "0x%x", offset);
+      oappend (scratchbuf);
+      break;
+    default:
+      oappend ("<internal disassembler error>");
+      break;
+    }
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_OFF (bytemode)
+     int bytemode;
+{
+  int off;
+  
+  if (aflag)
+    off = get32 ();
+  else
+    off = get16 ();
+  
+  sprintf (scratchbuf, "0x%x", off);
+  oappend (scratchbuf);
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_ESDI (dummy)
+    int dummy;
+{
+  oappend ("%es:(");
+  oappend (aflag ? "%edi" : "%di");
+  oappend (")");
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_DSSI (dummy)
+    int dummy;
+{
+  oappend ("%ds:(");
+  oappend (aflag ? "%esi" : "%si");
+  oappend (")");
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_ONE (dummy)
+    int dummy;
+{
+  oappend ("1");
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_C (dummy)
+    int dummy;
+{
+  codep++; /* skip mod/rm */
+  sprintf (scratchbuf, "%%cr%d", reg);
+  oappend (scratchbuf);
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_D (dummy)
+    int dummy;
+{
+  codep++; /* skip mod/rm */
+  sprintf (scratchbuf, "%%db%d", reg);
+  oappend (scratchbuf);
+  return (0);
+}
+
+/* ARGSUSED */
+int
+OP_T (dummy)
+     int dummy;
+{
+  codep++; /* skip mod/rm */
+  sprintf (scratchbuf, "%%tr%d", reg);
+  oappend (scratchbuf);
+  return (0);
+}
+
+int
+OP_rm (bytemode)
+     int bytemode;
+{
+  switch (bytemode) 
+    {
+    case d_mode:
+      oappend (names32[rm]);
+      break;
+    case w_mode:
+      oappend (names16[rm]);
+      break;
+    }
+  return (0);
+}
+	
+#define MAXLEN 20
+
+int
+print_insn (realmemaddr, memaddr, stream, addrlen)
+     CORE_ADDR memaddr, realmemaddr;
+     FILE *stream;
+     int addrlen;
+{
+  unsigned char buffer[MAXLEN];
+  
+  if(addrlen == 32){
+	  dflag = 1;
+	  aflag = 1;
+  } else {
+	  dflag = 0;
+	  aflag = 0;
+  };  
+
+
+  read_memory (memaddr, (char *) buffer, MAXLEN);
+  
+  return (i386dis ((int)realmemaddr, buffer, stream));
+}
+
diff --git a/debugger/info.c b/debugger/info.c
new file mode 100644
index 0000000..96046e8
--- /dev/null
+++ b/debugger/info.c
@@ -0,0 +1,230 @@
+/*
+ * Wine debugger utility routines
+ * Eric Youngdale
+ * 9/93
+ */
+
+#include <stdio.h>
+#include "regpos.h"
+
+extern int * regval;
+extern unsigned int dbg_mask;
+extern unsigned int dbg_mode;
+
+extern int print_insn(char * memaddr, char * realaddr, FILE * stream, int addrlen);
+
+/* THese three helper functions eliminate the need for patching the
+module from gdb for disassembly of code */
+
+void read_memory(char * memaddr, char * buffer, int len){
+	memcpy(buffer, memaddr, len);
+}
+
+void fputs_filtered(char * buffer, FILE * outfile){
+	fputs(buffer, outfile);
+}
+
+void print_address(unsigned int addr, FILE * outfile){
+	char * name;
+	name = find_nearest_symbol(addr);
+	if(name)
+		fprintf(outfile,"0x%8.8x(%s)", addr, name);
+	else
+		fprintf(outfile,"0x%8.8x", addr);
+
+}
+
+
+void info_reg(){
+	fprintf(stderr,"Register dump:\n");
+	/* First get the segment registers out of the way */
+	fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n", 
+		SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);
+
+	/* Now dump the main registers */
+	fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n", 
+		SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);
+
+	/* And dump the regular registers */
+
+	fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n", 
+		SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));
+
+	/* Finally dump these main registers */
+	fprintf(stderr," EDI:%8.8x ESI:%8.8x\n", 
+		SC_EDI(dbg_mask), SC_ESI(dbg_mask));
+
+}
+
+void info_stack(){
+	unsigned int * dump;
+	int i;
+
+
+	fprintf(stderr,"Stack dump:\n");
+	dump = (int*) SC_EIP(dbg_mask);
+	for(i=0; i<22; i++) 
+	{
+	    fprintf(stderr," %8.8x", *dump++);
+	    if ((i % 8) == 7)
+		fprintf(stderr,"\n");
+	}
+	fprintf(stderr,"\n");
+}
+
+
+void examine_memory(int addr, int count, char format){
+	char * pnt;
+	unsigned int * dump;
+	unsigned short int * wdump;
+	int i;
+
+	if((addr & 0xffff0000) == 0 && dbg_mode == 16)
+	        addr |= (format == 'i' ? SC_CS : SC_DS) << 16;
+
+
+	if(format != 'i' && count > 1) {
+		print_address(addr, stderr);
+		fprintf(stderr,":  ");
+	};
+
+
+	switch(format){
+	case 's':
+		pnt = (char *) addr;
+		if (count == 1) count = 256;
+	        while(*pnt && count) {
+			fputc( *pnt++, stderr);
+			count--;
+		};
+		fprintf(stderr,"\n");
+		return;
+
+	case 'i':
+		for(i=0; i<count; i++) {
+			print_address(addr, stderr);
+			fprintf(stderr,":  ");
+			addr += print_insn((char *) addr, (char *) addr, stderr, dbg_mode);
+			fprintf(stderr,"\n");
+		};
+		return;
+	case 'x':
+		dump = (unsigned int *) addr;
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %8.8x", *dump++);
+			if ((i % 8) == 7) {
+				fprintf(stderr,"\n");
+				print_address((unsigned int) dump, stderr);
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'd':
+		dump = (unsigned int *) addr;
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %d", *dump++);
+			if ((i % 8) == 7) {
+				fprintf(stderr,"\n");
+				print_address((unsigned int) dump, stderr);
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'w':
+		wdump = (unsigned short int *) addr;
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %d", *wdump++);
+			if ((i % 10) == 7) {
+				fprintf(stderr,"\n");
+				print_address((unsigned int) dump, stderr);
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'c':
+		pnt = (char *) addr;
+		for(i=0; i<count; i++) 
+		{
+			if(*pnt < 0x20) {
+				fprintf(stderr,"  ");
+				pnt++;
+			} else
+				fprintf(stderr," %c", *pnt++);
+			if ((i % 32) == 7) {
+				fprintf(stderr,"\n");
+				print_address((unsigned int) dump, stderr);
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	
+	case 'b':
+		pnt = (char *) addr;
+		for(i=0; i<count; i++) 
+		{
+			fprintf(stderr," %d", *pnt++);
+			if ((i % 32) == 7) {
+				fprintf(stderr,"\n");
+				print_address((unsigned int) dump, stderr);
+				fprintf(stderr,":  ");
+			};
+		}
+		fprintf(stderr,"\n");
+		return;
+	};
+	
+	/* The rest are fairly straightforward */
+
+	fprintf(stderr,"examine mem: %x %d %c\n", addr, count, format);
+}
+
+char * helptext[] = {
+"The commands accepted by the Wine debugger are a small subset",
+"of the commands that gdb would accept.  The commands currently",
+"are:\n",
+"  info reg",
+"  info stack",
+"  help",
+"  quit",
+"  print <expr>",
+"  symbolfile <filename>",
+"  define <identifier> <expr>",
+"  x <expr>",
+"  cont",
+"  set <reg> = <expr>",
+"  set *<expr> = <expr>",
+"",
+"The 'x' command accepts repeat counts and formats (including 'i') in the",
+"same way that gdb does.",
+"",
+" The following are examples of legal expressions:",
+" $eax     $eax+0x3   0x1000   ($eip + 256)  *$eax   *($esp + 3)",
+" Also, a nm format symbol table can be read from a file using the",
+" symbolfile command.  Symbols can also be defined individually with",
+" the define command.",
+"",
+"The disassembly code seems to work most of the time, but it does get",
+"a little confused at times.  The 16 bit mode probably has not been used",
+"much so there are probably bugs.  I snagged the file from the gdb-4.7",
+"source tree, which is what was on my latest cdrom.  I should check to see",
+"if newer versions of gdb have anything substanitally different for the",
+"disassembler.",
+"",
+NULL};
+
+void dbg_help(){
+	int i;
+	i = 0;
+	while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
+}
+
diff --git a/debugger/readline/Make.os9 b/debugger/readline/Make.os9
new file mode 100644
index 0000000..c632847
--- /dev/null
+++ b/debugger/readline/Make.os9
@@ -0,0 +1,19 @@
+##  $Revision: 1.2 $
+##
+##  OS-9 makefile for editline library.
+##
+
+.SUFFIXES:
+
+RFILES	= editline.r complete.r sysos9.r
+
+%.r:		%.c
+	cc68 -r -Dstrchr=index -Dstrrchr=rindex -DNEED_STRDUP -DSYS_OS9 $*.c
+
+testit:		testit.r editline.lib
+	cc68 -f=testit testit.r -l=editline.lib
+
+$(RFILES):	$(RFILES:%.r=%.c)
+
+editline.lib:	$(RFILES)
+	cat $(RFILES) >$@
diff --git a/debugger/readline/Makefile b/debugger/readline/Makefile
new file mode 100644
index 0000000..77c6bfc
--- /dev/null
+++ b/debugger/readline/Makefile
@@ -0,0 +1,66 @@
+##  $Revision: 1.3 $
+##
+##  Unix makefile for editline library.
+##
+
+##  Set your options:
+##	-DANSI_ARROWS		ANSI arrows keys work like emacs.
+##	-DHAVE_STDLIB		Have <stdlib.h>.
+##	-DHAVE_TCGETATTR	Have tcgetattr(), tcsetattr().
+##	-DHIDE			Make static functions static (non debug).
+##	-DHIST_SIZE=n		History size.
+##	-DNEED_STRDUP		Don't have strdup().
+##	-DUNIQUE_HISTORY	Don't save command if same as last one.
+##	-DUSE_DIRENT		Use <dirent.h>, not <sys/dir.h>?
+##	-DUSE_TERMCAP		Use the termcap library for terminal size
+##				see LDFLAGS, below, if you set this.
+##	-DNEED_PERROR		Don't have perror() (used in testit)
+DEFS	= -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX
+
+##  Set your C compiler:
+WARN	= -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings \
+	-Wunused -Wcomment -Wswitch
+CC	= gcc -ansi $(WARN)
+#CC	= cc
+CFLAGS	= $(DEFS) -O -g
+
+##  If you have -DUSE_TERMCAP, set this as appropriate:
+#LDFLAGS = -ltermlib
+#LDFLAGS = -ltermcap
+
+##  Set ranlib as appropriate:
+RANLIB	= ranlib
+#RANLIB	= echo
+
+##  End of configuration.
+
+SOURCES	= editline.c complete.c sysunix.c
+OBJECTS	= editline.o complete.o sysunix.o
+SHARFILES =	README Makefile editline.3 editline.h unix.h editline.c \
+		complete.c sysunix.c testit.c \
+		Make.os9 os9.h sysos9.c
+
+all:		libedit.a
+
+testit:		testit.c libedit.a
+	$(CC) $(CFLAGS) -o testit testit.c libedit.a $(LDFLAGS)
+
+shar:		$(SHARFILES)
+	shar $(SHARFILES) >shar
+
+clean:
+	rm -f *.[oa] testit foo core tags lint lint.all a.out shar
+
+lint:		testit
+	lint -a -b -u -x $(DEFS) $(SOURCES) testit.c >lint.all
+	sed -e '/warning: function prototype not in scope/d' \
+		-e '/warning: old style argument declaration/'d \
+		-e '/mix of old and new style function declaration/'d \
+		<lint.all >lint
+
+libedit.a:	$(OBJECTS)
+	@rm -f $@
+	ar r $@ $(OBJECTS)
+	$(RANLIB) $@
+
+$(OBJECTS):	editline.h
diff --git a/debugger/readline/README b/debugger/readline/README
new file mode 100644
index 0000000..c609789
--- /dev/null
+++ b/debugger/readline/README
@@ -0,0 +1,45 @@
+$Revision: 1.5 $
+
+This is a line-editing library.  It can be linked into almost any
+program to provide command-line editing and recall.
+
+It is call-compatible with the FSF readline library, but it is a
+fraction of the size (and offers fewer features).  It does not use
+standard I/O.  It is distributed under a "C News-like" copyright.
+
+Configuration is done in the Makefile.  Type "make testit" to get
+a small slow shell for testing.
+
+An earlier version was distributed with Byron's rc.  Principal
+changes over that version include:
+	Faster.
+	Is eight-bit clean (thanks to brendan@cs.widener.edu)
+	Written in K&R C, but ANSI compliant (gcc all warnings)
+	Propagates EOF properly; rc trip test now passes
+	Doesn't need or use or provide memmove.
+	More robust
+	Calling sequence changed to be compatible with readline.
+	Test program, new manpage, better configuration
+	More system-independant; includes Unix and OS-9 support.
+
+Enjoy,
+	Rich $alz
+	<rsalz@osf.org>
+
+ Copyright 1992 Simmule Turner and Rich Salz.  All rights reserved.
+
+ This software is not subject to any license of the American Telephone
+ and Telegraph Company or of the Regents of the University of California.
+
+ Permission is granted to anyone to use this software for any purpose on
+ any computer system, and to alter it and redistribute it freely, subject
+ to the following restrictions:
+ 1. The authors are not responsible for the consequences of use of this
+    software, no matter how awful, even if they arise from flaws in it.
+ 2. The origin of this software must not be misrepresented, either by
+    explicit claim or by omission.  Since few users ever read sources,
+    credits must appear in the documentation.
+ 3. Altered versions must be plainly marked as such, and must not be
+    misrepresented as being the original software.  Since few users
+    ever read sources, credits must appear in the documentation.
+ 4. This notice may not be removed or altered.
diff --git a/debugger/readline/complete.c b/debugger/readline/complete.c
new file mode 100644
index 0000000..0cd029c
--- /dev/null
+++ b/debugger/readline/complete.c
@@ -0,0 +1,222 @@
+/*  $Revision: 1.3 $
+**
+**  History and file completion functions for editline library.
+*/
+#include "editline.h"
+
+
+#if	defined(NEED_STRDUP)
+/*
+**  Return an allocated copy of a string.
+*/
+char *
+strdup(p)
+    char	*p;
+{
+    char	*new;
+
+    if ((new = NEW(char, strlen(p) + 1)) != NULL)
+	(void)strcpy(new, p);
+    return new;
+}
+#endif	/* defined(NEED_STRDUP) */
+
+/*
+**  strcmp-like sorting predicate for qsort.
+*/
+STATIC int
+compare(p1, p2)
+    CONST void	*p1;
+    CONST void	*p2;
+{
+    CONST char	**v1;
+    CONST char	**v2;
+
+    v1 = (CONST char **)p1;
+    v2 = (CONST char **)p2;
+    return strcmp(*v1, *v2);
+}
+
+/*
+**  Fill in *avp with an array of names that match file, up to its length.
+**  Ignore . and .. .
+*/
+STATIC int
+FindMatches(dir, file, avp)
+    char	*dir;
+    char	*file;
+    char	***avp;
+{
+    char	**av;
+    char	**new;
+    char	*p;
+    DIR		*dp;
+    DIRENTRY	*ep;
+    SIZE_T	ac;
+    SIZE_T	len;
+
+    if ((dp = opendir(dir)) == NULL)
+	return 0;
+
+    av = NULL;
+    ac = 0;
+    len = strlen(file);
+    while ((ep = readdir(dp)) != NULL) {
+	p = ep->d_name;
+	if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))
+	    continue;
+	if (len && strncmp(p, file, len) != 0)
+	    continue;
+
+	if ((ac % MEM_INC) == 0) {
+	    if ((new = NEW(char*, ac + MEM_INC)) == NULL)
+		break;
+	    if (ac) {
+		COPYFROMTO(new, av, ac * sizeof (char **));
+		DISPOSE(av);
+	    }
+	    *avp = av = new;
+	}
+
+	if ((av[ac] = strdup(p)) == NULL) {
+	    if (ac == 0)
+		DISPOSE(av);
+	    break;
+	}
+	ac++;
+    }
+
+    /* Clean up and return. */
+    (void)closedir(dp);
+    if (ac)
+	qsort(av, ac, sizeof (char **), compare);
+    return ac;
+}
+
+/*
+**  Split a pathname into allocated directory and trailing filename parts.
+*/
+STATIC int
+SplitPath(path, dirpart, filepart)
+    char	*path;
+    char	**dirpart;
+    char	**filepart;
+{
+    static char	DOT[] = ".";
+    char	*dpart;
+    char	*fpart;
+
+    if ((fpart = strrchr(path, '/')) == NULL) {
+	if ((dpart = strdup(DOT)) == NULL)
+	    return -1;
+	if ((fpart = strdup(path)) == NULL) {
+	    DISPOSE(dpart);
+	    return -1;
+	}
+    }
+    else {
+	if ((dpart = strdup(path)) == NULL)
+	    return -1;
+	dpart[fpart - path] = '\0';
+	if ((fpart = strdup(++fpart)) == NULL) {
+	    DISPOSE(dpart);
+	    return -1;
+	}
+    }
+    *dirpart = dpart;
+    *filepart = fpart;
+    return 0;
+}
+
+/*
+**  Attempt to complete the pathname, returning an allocated copy.
+**  Fill in *unique if we completed it, or set it to 0 if ambiguous.
+*/
+char *
+rl_complete(pathname, unique)
+    char	*pathname;
+    int		*unique;
+{
+    char	**av;
+    char	*dir;
+    char	*file;
+    char	*new;
+    char	*p;
+    SIZE_T	ac;
+    SIZE_T	end;
+    SIZE_T	i;
+    SIZE_T	j;
+    SIZE_T	len;
+
+    if (SplitPath(pathname, &dir, &file) < 0)
+	return NULL;
+    if ((ac = FindMatches(dir, file, &av)) == 0) {
+	DISPOSE(dir);
+	DISPOSE(file);
+	return NULL;
+    }
+
+    p = NULL;
+    len = strlen(file);
+    if (ac == 1) {
+	/* Exactly one match -- finish it off. */
+	*unique = 1;
+	j = strlen(av[0]) - len + 2;
+	if ((p = NEW(char, j + 1)) != NULL) {
+	    COPYFROMTO(p, av[0] + len, j);
+	    if ((new = NEW(char, strlen(dir) + strlen(av[0]) + 2)) != NULL) {
+		(void)strcpy(new, dir);
+		(void)strcat(new, "/");
+		(void)strcat(new, av[0]);
+		rl_add_slash(new, p);
+		DISPOSE(new);
+	    }
+	}
+    }
+    else {
+	*unique = 0;
+	if (len) {
+	    /* Find largest matching substring. */
+	    for (i = len, end = strlen(av[0]); i < end; i++)
+		for (j = 1; j < ac; j++)
+		    if (av[0][i] != av[j][i])
+			goto breakout;
+  breakout:
+	    if (i > len) {
+		j = i - len + 1;
+		if ((p = NEW(char, j)) != NULL) {
+		    COPYFROMTO(p, av[0] + len, j);
+		    p[j - 1] = '\0';
+		}
+	    }
+	}
+    }
+
+    /* Clean up and return. */
+    DISPOSE(dir);
+    DISPOSE(file);
+    for (i = 0; i < ac; i++)
+	DISPOSE(av[i]);
+    DISPOSE(av);
+    return p;
+}
+
+/*
+**  Return all possible completions.
+*/
+int
+rl_list_possib(pathname, avp)
+    char	*pathname;
+    char	***avp;
+{
+    char	*dir;
+    char	*file;
+    int		ac;
+
+    if (SplitPath(pathname, &dir, &file) < 0)
+	return 0;
+    ac = FindMatches(dir, file, avp);
+    DISPOSE(dir);
+    DISPOSE(file);
+    return ac;
+}
diff --git a/debugger/readline/editline.3 b/debugger/readline/editline.3
new file mode 100644
index 0000000..1d851ed
--- /dev/null
+++ b/debugger/readline/editline.3
@@ -0,0 +1,175 @@
+.\" $Revision: 1.1 $
+.TH EDITLINE 3
+.SH NAME
+editline \- command-line editing library with history
+.SH SYNOPSIS
+.nf
+.B "char *"
+.B "readline(prompt)"
+.B "     char	*prompt;"
+
+.B "void"
+.B "add_history(line)"
+.B "    char	*line;"
+.fi
+.SH DESCRIPTION
+.I Editline
+is a library that provides an line-editing interface with text recall.
+It is intended to be compatible with the
+.I readline
+library provided by the Free Software Foundation, but much smaller.
+The bulk of this manual page describes the user interface.
+.PP
+The
+.I readline
+routine returns a line of text with the trailing newline removed.
+The data is returned in a buffer allocated with
+.IR malloc (3),
+so the space should be released with
+.IR free (3)
+when the calling program is done with it.
+Before accepting input from the user, the specified
+.I prompt
+is displayed on the terminal.
+.PP
+The
+.I add_history
+routine makes a copy of the specified
+.I line
+and adds it to the internal history list.
+.SS "User Interface"
+A program that uses this library provides a simple emacs-like editing
+interface to its users.
+A line may be edited before it is sent to the calling program by typing either
+control characters or escape sequences.
+A control character, shown as a caret followed by a letter, is typed by
+holding down the ``control'' key while the letter is typed.
+For example, ``^A'' is a control-A.
+An escape sequence is entered by typing the ``escape'' key followed by one or
+more characters.
+The escape key is abbreviated as ``ESC.''
+Note that unlike control keys, case matters in escape sequences; ``ESC\ F''
+is not the same as ``ESC\ f''.
+.PP
+An editing command may be typed anywhere on the line, not just at the
+beginning.
+In addition, a return may also be typed anywhere on the line, not just at
+the end.
+.PP
+Most editing commands may be given a repeat count,
+.IR n ,
+where
+.I n
+is a number.
+To enter a repeat count, type the escape key, the number, and then
+the command to execute.
+For example, ``ESC\ 4\ ^f'' moves forward four characters.
+If a command may be given a repeat count then the text ``[n]'' is given at the
+end of its description.
+.PP
+The following control characters are accepted:
+.RS
+.nf
+.ta \w'ESC DEL  'u
+^A	Move to the beginning of the line
+^B	Move left (backwards) [n]
+^D	Delete character [n]
+^E	Move to end of line
+^F	Move right (forwards) [n]
+^G	Ring the bell
+^H	Delete character before cursor (backspace key) [n]
+^I	Complete filename (tab key); see below
+^J	Done with line (return key)
+^K	Kill to end of line (or column [n])
+^L	Redisplay line
+^M	Done with line (alternate return key)
+^N	Get next line from history [n]
+^P	Get previous line from history [n]
+^R	Search backward (forward if [n]) through history for text;
+\&	must start line if text begins with an uparrow
+^T	Transpose characters
+^V	Insert next character, even if it is an edit command
+^W	Wipe to the mark
+^X^X	Exchange current location and mark
+^Y	Yank back last killed text
+^[	Start an escape sequence (escape key)
+^]c	Move forward to next character ``c''
+^?	Delete character before cursor (delete key) [n]
+.fi
+.RE
+.PP
+The following escape sequences are provided.
+.RS
+.nf
+.ta \w'ESC DEL  'u
+ESC\ ^H	Delete previous word (backspace key) [n]
+ESC\ DEL	Delete previous word (delete key) [n]
+ESC\ SP	Set the mark (space key); see ^X^X and ^Y above
+ESC\ \.	Get the last (or [n]'th) word from previous line
+ESC\ \?	Show possible completions; see below
+ESC\ <	Move to start of history
+ESC\ >	Move to end of history
+ESC\ b	Move backward a word [n]
+ESC\ d	Delete word under cursor [n]
+ESC\ f	Move forward a word [n]
+ESC\ l	Make word lowercase [n]
+ESC\ u	Make word uppercase [n]
+ESC\ y	Yank back last killed text
+ESC\ v	Show library version
+ESC\ w	Make area up to mark yankable
+ESC\ nn	Set repeat count to the number nn
+ESC\ C	Read from environment variable ``_C_'', where C is
+\&	an uppercase letter
+.fi
+.RE
+.PP
+The
+.I editline
+library has a small macro facility.
+If you type the escape key followed by an uppercase letter,
+.IR C ,
+then the contents of the environment variable
+.I _C_
+are read in as if you had typed them at the keyboard.
+For example, if the variable
+.I _L_
+contains the following:
+.RS
+^A^Kecho '^V^[[H^V^[[2J'^M
+.RE
+Then typing ``ESC L'' will move to the beginning of the line, kill the
+entire line, enter the echo command needed to clear the terminal (if your
+terminal is like a VT-100), and send the line back to the shell.
+.PP
+The
+.I editline
+library also does filename completion.
+Suppose the root directory has the following files in it:
+.RS
+.nf
+.ta \w'core   'u
+bin	vmunix
+core	vmunix.old
+.fi
+.RE
+If you type ``rm\ /v'' and then the tab key.
+.I Editline
+will then finish off as much of the name as possible by adding ``munix''.
+Because the name is not unique, it will then beep.
+If you type the escape key and a question mark, it will display the
+two choices.
+If you then type a period and a tab, the library will finish off the filename
+for you:
+.RS
+.nf
+.RI "rm /v[TAB]" munix .TAB old
+.fi
+.RE
+The tab key is shown by ``[TAB]'' and the automatically-entered text
+is shown in italics.
+.SH "BUGS AND LIMITATIONS"
+Cannot handle lines more than 80 columns.
+.SH AUTHORS
+Simmule R. Turner <uunet.uu.net!capitol!sysgo!simmy>
+and Rich $alz <rsalz@osf.org>.
+Original manual page by DaviD W. Sanderson <dws@ssec.wisc.edu>.
diff --git a/debugger/readline/editline.c b/debugger/readline/editline.c
new file mode 100644
index 0000000..3838de0
--- /dev/null
+++ b/debugger/readline/editline.c
@@ -0,0 +1,1378 @@
+/*  $Revision: 1.4 $
+**
+**  Main editing routines for editline library.
+*/
+#include "editline.h"
+#include <ctype.h>
+
+/*
+**  Manifest constants.
+*/
+#define SCREEN_WIDTH	80
+#define SCREEN_ROWS	24
+#define NO_ARG		(-1)
+#define DEL		127
+#define CTL(x)		((x) & 0x1F)
+#define ISCTL(x)	((x) && (x) < ' ')
+#define UNCTL(x)	((x) + 64)
+#define META(x)		((x) | 0x80)
+#define ISMETA(x)	((x) & 0x80)
+#define UNMETA(x)	((x) & 0x7F)
+#if	!defined(HIST_SIZE)
+#define HIST_SIZE	20
+#endif	/* !defined(HIST_SIZE) */
+
+/*
+**  Command status codes.
+*/
+typedef enum _STATUS {
+    CSdone, CSeof, CSmove, CSdispatch, CSstay
+} STATUS;
+
+/*
+**  The type of case-changing to perform.
+*/
+typedef enum _CASE {
+    TOupper, TOlower
+} CASE;
+
+/*
+**  Key to command mapping.
+*/
+typedef struct _KEYMAP {
+    CHAR	Key;
+    STATUS	(*Function)();
+} KEYMAP;
+
+/*
+**  Command history structure.
+*/
+typedef struct _HISTORY {
+    int		Size;
+    int		Pos;
+    CHAR	*Lines[HIST_SIZE];
+} HISTORY;
+
+/*
+**  Globals.
+*/
+int		rl_eof;
+int		rl_erase;
+int		rl_intr;
+int		rl_kill;
+
+STATIC CHAR		NIL[] = "";
+STATIC CONST CHAR	*Input = NIL;
+STATIC CHAR		*Line;
+STATIC CONST char	*Prompt;
+STATIC CHAR		*Yanked;
+STATIC char		*Screen;
+STATIC char		NEWLINE[]= CRLF;
+STATIC HISTORY		H;
+int		rl_quit;
+STATIC int		Repeat;
+STATIC int		End;
+STATIC int		Mark;
+STATIC int		OldPoint;
+STATIC int		Point;
+STATIC int		PushBack;
+STATIC int		Pushed;
+FORWARD KEYMAP		Map[33];
+FORWARD KEYMAP		MetaMap[16];
+STATIC SIZE_T		Length;
+STATIC SIZE_T		ScreenCount;
+STATIC SIZE_T		ScreenSize;
+STATIC char		*backspace;
+STATIC int		TTYwidth;
+STATIC int		TTYrows;
+
+/* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */
+int		rl_meta_chars = 1;
+
+/*
+**  Declarations.
+*/
+STATIC CHAR	*editinput();
+extern int	read();
+extern int	write();
+#if	defined(USE_TERMCAP)
+extern char	*getenv();
+extern char	*tgetstr();
+extern int	tgetent();
+#endif	/* defined(USE_TERMCAP) */
+
+/*
+**  TTY input/output functions.
+*/
+
+STATIC void
+TTYflush()
+{
+    if (ScreenCount) {
+	(void)write(1, Screen, ScreenCount);
+	ScreenCount = 0;
+    }
+}
+
+STATIC void
+TTYput(c)
+    CHAR	c;
+{
+    Screen[ScreenCount] = c;
+    if (++ScreenCount >= ScreenSize - 1) {
+	ScreenSize += SCREEN_INC;
+	RENEW(Screen, char, ScreenSize);
+    }
+}
+
+STATIC void
+TTYputs(p)
+    CHAR	*p;
+{
+    while (*p)
+	TTYput(*p++);
+}
+
+STATIC void
+TTYshow(c)
+    CHAR	c;
+{
+    if (c == DEL) {
+	TTYput('^');
+	TTYput('?');
+    }
+    else if (ISCTL(c)) {
+	TTYput('^');
+	TTYput(UNCTL(c));
+    }
+    else if (rl_meta_chars && ISMETA(c)) {
+	TTYput('M');
+	TTYput('-');
+	TTYput(UNMETA(c));
+    }
+    else
+	TTYput(c);
+}
+
+STATIC void
+TTYstring(p)
+    CHAR	*p;
+{
+    while (*p)
+	TTYshow(*p++);
+}
+
+STATIC unsigned int
+TTYget()
+{
+    CHAR	c;
+
+    TTYflush();
+    if (Pushed) {
+	Pushed = 0;
+	return PushBack;
+    }
+    if (*Input)
+	return *Input++;
+    return read(0, &c, (SIZE_T)1) == 1 ? c : EOF;
+}
+
+#define TTYback()	(backspace ? TTYputs((CHAR *)backspace) : TTYput('\b'))
+
+STATIC void
+TTYbackn(n)
+    int		n;
+{
+    while (--n >= 0)
+	TTYback();
+}
+
+STATIC void
+TTYinfo()
+{
+    static int		init;
+#if	defined(USE_TERMCAP)
+    char		*term;
+    char		buff[2048];
+    char		*bp;
+#endif	/* defined(USE_TERMCAP) */
+#if	defined(TIOCGWINSZ)
+    struct winsize	W;
+#endif	/* defined(TIOCGWINSZ) */
+
+    if (init) {
+#if	defined(TIOCGWINSZ)
+	/* Perhaps we got resized. */
+	if (ioctl(0, TIOCGWINSZ, &W) >= 0
+	 && W.ws_col > 0 && W.ws_row > 0) {
+	    TTYwidth = (int)W.ws_col;
+	    TTYrows = (int)W.ws_row;
+	}
+#endif	/* defined(TIOCGWINSZ) */
+	return;
+    }
+    init++;
+
+    TTYwidth = TTYrows = 0;
+#if	defined(USE_TERMCAP)
+    bp = &buff[0];
+    if ((term = getenv("TERM")) == NULL)
+	term = "dumb";
+    if (tgetent(buff, term) < 0) {
+       TTYwidth = SCREEN_WIDTH;
+       TTYrows = SCREEN_ROWS;
+       return;
+    }
+    backspace = tgetstr("le", &bp);
+    TTYwidth = tgetnum("co");
+    TTYrows = tgetnum("li");
+#endif	/* defined(USE_TERMCAP) */
+
+#if	defined(TIOCGWINSZ)
+    if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
+	TTYwidth = (int)W.ws_col;
+	TTYrows = (int)W.ws_row;
+    }
+#endif	/* defined(TIOCGWINSZ) */
+
+    if (TTYwidth <= 0 || TTYrows <= 0) {
+	TTYwidth = SCREEN_WIDTH;
+	TTYrows = SCREEN_ROWS;
+    }
+}
+
+
+/*
+**  Print an array of words in columns.
+*/
+STATIC void
+columns(ac, av)
+    int		ac;
+    CHAR	**av;
+{
+    CHAR	*p;
+    int		i;
+    int		j;
+    int		k;
+    int		len;
+    int		skip;
+    int		longest;
+    int		cols;
+
+    /* Find longest name, determine column count from that. */
+    for (longest = 0, i = 0; i < ac; i++)
+	if ((j = strlen((char *)av[i])) > longest)
+	    longest = j;
+    cols = TTYwidth / (longest + 3);
+
+    TTYputs((CHAR *)NEWLINE);
+    for (skip = ac / cols + 1, i = 0; i < skip; i++) {
+	for (j = i; j < ac; j += skip) {
+	    for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++)
+		TTYput(*p);
+	    if (j + skip < ac)
+		while (++len < longest + 3)
+		    TTYput(' ');
+	}
+	TTYputs((CHAR *)NEWLINE);
+    }
+}
+
+STATIC void
+reposition()
+{
+    int		i;
+    CHAR	*p;
+
+    TTYput('\r');
+    TTYputs((CHAR *)Prompt);
+    for (i = Point, p = Line; --i >= 0; p++)
+	TTYshow(*p);
+}
+
+STATIC void
+left(Change)
+    STATUS	Change;
+{
+    TTYback();
+    if (Point) {
+	if (ISCTL(Line[Point - 1]))
+	    TTYback();
+        else if (rl_meta_chars && ISMETA(Line[Point - 1])) {
+	    TTYback();
+	    TTYback();
+	}
+    }
+    if (Change == CSmove)
+	Point--;
+}
+
+STATIC void
+right(Change)
+    STATUS	Change;
+{
+    TTYshow(Line[Point]);
+    if (Change == CSmove)
+	Point++;
+}
+
+STATIC STATUS
+ring_bell()
+{
+    TTYput('\07');
+    TTYflush();
+    return CSstay;
+}
+
+STATIC STATUS
+do_macro(c)
+    unsigned int	c;
+{
+    CHAR		name[4];
+
+    name[0] = '_';
+    name[1] = c;
+    name[2] = '_';
+    name[3] = '\0';
+
+    if ((Input = (CHAR *)getenv((char *)name)) == NULL) {
+	Input = NIL;
+	return ring_bell();
+    }
+    return CSstay;
+}
+
+STATIC STATUS
+do_forward(move)
+    STATUS	move;
+{
+    int		i;
+    CHAR	*p;
+
+    i = 0;
+    do {
+	p = &Line[Point];
+	for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++)
+	    if (move == CSmove)
+		right(CSstay);
+
+	for (; Point < End && isalnum(*p); Point++, p++)
+	    if (move == CSmove)
+		right(CSstay);
+
+	if (Point == End)
+	    break;
+    } while (++i < Repeat);
+
+    return CSstay;
+}
+
+STATIC STATUS
+do_case(type)
+    CASE	type;
+{
+    int		i;
+    int		end;
+    int		count;
+    CHAR	*p;
+
+    (void)do_forward(CSstay);
+    if (OldPoint != Point) {
+	if ((count = Point - OldPoint) < 0)
+	    count = -count;
+	Point = OldPoint;
+	if ((end = Point + count) > End)
+	    end = End;
+	for (i = Point, p = &Line[i]; i < end; i++, p++) {
+	    if (type == TOupper) {
+		if (islower(*p))
+		    *p = toupper(*p);
+	    }
+	    else if (isupper(*p))
+		*p = tolower(*p);
+	    right(CSmove);
+	}
+    }
+    return CSstay;
+}
+
+STATIC STATUS
+case_down_word()
+{
+    return do_case(TOlower);
+}
+
+STATIC STATUS
+case_up_word()
+{
+    return do_case(TOupper);
+}
+
+STATIC void
+ceol()
+{
+    int		extras;
+    int		i;
+    CHAR	*p;
+
+    for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) {
+	TTYput(' ');
+	if (ISCTL(*p)) {
+	    TTYput(' ');
+	    extras++;
+	}
+	else if (rl_meta_chars && ISMETA(*p)) {
+	    TTYput(' ');
+	    TTYput(' ');
+	    extras += 2;
+	}
+    }
+
+    for (i += extras; i > Point; i--)
+	TTYback();
+}
+
+STATIC void
+clear_line()
+{
+    Point = -strlen(Prompt);
+    TTYput('\r');
+    ceol();
+    Point = 0;
+    End = 0;
+    Line[0] = '\0';
+}
+
+STATIC STATUS
+insert_string(p)
+    CHAR	*p;
+{
+    SIZE_T	len;
+    int		i;
+    CHAR	*new;
+    CHAR	*q;
+
+    len = strlen((char *)p);
+    if (End + len >= Length) {
+	if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL)
+	    return CSstay;
+	if (Length) {
+	    COPYFROMTO(new, Line, Length);
+	    DISPOSE(Line);
+	}
+	Line = new;
+	Length += len + MEM_INC;
+    }
+
+    for (q = &Line[Point], i = End - Point; --i >= 0; )
+	q[len + i] = q[i];
+    COPYFROMTO(&Line[Point], p, len);
+    End += len;
+    Line[End] = '\0';
+    TTYstring(&Line[Point]);
+    Point += len;
+
+    return Point == End ? CSstay : CSmove;
+}
+
+
+STATIC CHAR *
+next_hist()
+{
+    return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];
+}
+
+STATIC CHAR *
+prev_hist()
+{
+    return H.Pos == 0 ? NULL : H.Lines[--H.Pos];
+}
+
+STATIC STATUS
+do_insert_hist(p)
+    CHAR	*p;
+{
+    if (p == NULL)
+	return ring_bell();
+    Point = 0;
+    reposition();
+    ceol();
+    End = 0;
+    return insert_string(p);
+}
+
+STATIC STATUS
+do_hist(move)
+    CHAR	*(*move)();
+{
+    CHAR	*p;
+    int		i;
+
+    i = 0;
+    do {
+	if ((p = (*move)()) == NULL)
+	    return ring_bell();
+    } while (++i < Repeat);
+    return do_insert_hist(p);
+}
+
+STATIC STATUS
+h_next()
+{
+    return do_hist(next_hist);
+}
+
+STATIC STATUS
+h_prev()
+{
+    return do_hist(prev_hist);
+}
+
+STATIC STATUS
+h_first()
+{
+    return do_insert_hist(H.Lines[H.Pos = 0]);
+}
+
+STATIC STATUS
+h_last()
+{
+    return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);
+}
+
+/*
+**  Return zero if pat appears as a substring in text.
+*/
+STATIC int
+substrcmp(text, pat, len)
+    char	*text;
+    char	*pat;
+    int		len;
+{
+    CHAR	c;
+
+    if ((c = *pat) == '\0')
+        return *text == '\0';
+    for ( ; *text; text++)
+        if (*text == c && strncmp(text, pat, len) == 0)
+            return 0;
+    return 1;
+}
+
+STATIC CHAR *
+search_hist(search, move)
+    CHAR	*search;
+    CHAR	*(*move)();
+{
+    static CHAR	*old_search;
+    int		len;
+    int		pos;
+    int		(*match)();
+    char	*pat;
+
+    /* Save or get remembered search pattern. */
+    if (search && *search) {
+	if (old_search)
+	    DISPOSE(old_search);
+	old_search = (CHAR *)strdup((char *)search);
+    }
+    else {
+	if (old_search == NULL || *old_search == '\0')
+            return NULL;
+	search = old_search;
+    }
+
+    /* Set up pattern-finder. */
+    if (*search == '^') {
+	match = strncmp;
+	pat = (char *)(search + 1);
+    }
+    else {
+	match = substrcmp;
+	pat = (char *)search;
+    }
+    len = strlen(pat);
+
+    for (pos = H.Pos; (*move)() != NULL; )
+	if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0)
+            return H.Lines[H.Pos];
+    H.Pos = pos;
+    return NULL;
+}
+
+STATIC STATUS
+h_search()
+{
+    static int	Searching;
+    CONST char	*old_prompt;
+    CHAR	*(*move)();
+    CHAR	*p;
+
+    if (Searching)
+	return ring_bell();
+    Searching = 1;
+
+    clear_line();
+    old_prompt = Prompt;
+    Prompt = "Search: ";
+    TTYputs((CHAR *)Prompt);
+    move = Repeat == NO_ARG ? prev_hist : next_hist;
+    p = search_hist(editinput(), move);
+    clear_line();
+    Prompt = old_prompt;
+    TTYputs((CHAR *)Prompt);
+
+    Searching = 0;
+    return do_insert_hist(p);
+}
+
+STATIC STATUS
+fd_char()
+{
+    int		i;
+
+    i = 0;
+    do {
+	if (Point >= End)
+	    break;
+	right(CSmove);
+    } while (++i < Repeat);
+    return CSstay;
+}
+
+STATIC void
+save_yank(begin, i)
+    int		begin;
+    int		i;
+{
+    if (Yanked) {
+	DISPOSE(Yanked);
+	Yanked = NULL;
+    }
+
+    if (i < 1)
+	return;
+
+    if ((Yanked = NEW(CHAR, (SIZE_T)i + 1)) != NULL) {
+	COPYFROMTO(Yanked, &Line[begin], i);
+	Yanked[i] = '\0';
+    }
+}
+
+STATIC STATUS
+delete_string(count)
+    int		count;
+{
+    int		i;
+    CHAR	*p;
+
+    if (count <= 0 || End == Point)
+	return ring_bell();
+
+    if (count == 1 && Point == End - 1) {
+	/* Optimize common case of delete at end of line. */
+	End--;
+	p = &Line[Point];
+	i = 1;
+	TTYput(' ');
+	if (ISCTL(*p)) {
+	    i = 2;
+	    TTYput(' ');
+	}
+	else if (rl_meta_chars && ISMETA(*p)) {
+	    i = 3;
+	    TTYput(' ');
+	    TTYput(' ');
+	}
+	TTYbackn(i);
+	*p = '\0';
+	return CSmove;
+    }
+    if (Point + count > End && (count = End - Point) <= 0)
+	return CSstay;
+
+    if (count > 1)
+	save_yank(Point, count);
+
+    for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++)
+	p[0] = p[count];
+    ceol();
+    End -= count;
+    TTYstring(&Line[Point]);
+    return CSmove;
+}
+
+STATIC STATUS
+bk_char()
+{
+    int		i;
+
+    i = 0;
+    do {
+	if (Point == 0)
+	    break;
+	left(CSmove);
+    } while (++i < Repeat);
+
+    return CSstay;
+}
+
+STATIC STATUS
+bk_del_char()
+{
+    int		i;
+
+    i = 0;
+    do {
+	if (Point == 0)
+	    break;
+	left(CSmove);
+    } while (++i < Repeat);
+
+    return delete_string(i);
+}
+
+STATIC STATUS
+redisplay()
+{
+    TTYputs((CHAR *)NEWLINE);
+    TTYputs((CHAR *)Prompt);
+    TTYstring(Line);
+    return CSmove;
+}
+
+STATIC STATUS
+kill_line()
+{
+    int		i;
+
+    if (Repeat != NO_ARG) {
+	if (Repeat < Point) {
+	    i = Point;
+	    Point = Repeat;
+	    reposition();
+	    (void)delete_string(i - Point);
+	}
+	else if (Repeat > Point) {
+	    right(CSmove);
+	    (void)delete_string(Repeat - Point - 1);
+	}
+	return CSmove;
+    }
+
+    save_yank(Point, End - Point);
+    Line[Point] = '\0';
+    ceol();
+    End = Point;
+    return CSstay;
+}
+
+STATIC STATUS
+insert_char(c)
+    int		c;
+{
+    STATUS	s;
+    CHAR	buff[2];
+    CHAR	*p;
+    CHAR	*q;
+    int		i;
+
+    if (Repeat == NO_ARG || Repeat < 2) {
+	buff[0] = c;
+	buff[1] = '\0';
+	return insert_string(buff);
+    }
+
+    if ((p = NEW(CHAR, Repeat + 1)) == NULL)
+	return CSstay;
+    for (i = Repeat, q = p; --i >= 0; )
+	*q++ = c;
+    *q = '\0';
+    Repeat = 0;
+    s = insert_string(p);
+    DISPOSE(p);
+    return s;
+}
+
+STATIC STATUS
+meta()
+{
+    unsigned int	c;
+    KEYMAP		*kp;
+
+    if ((c = TTYget()) == EOF)
+	return CSeof;
+#if	defined(ANSI_ARROWS)
+    /* Also include VT-100 arrows. */
+    if (c == '[' || c == 'O')
+	switch (c = TTYget()) {
+	default:	return ring_bell();
+	case EOF:	return CSeof;
+	case 'A':	return h_prev();
+	case 'B':	return h_next();
+	case 'C':	return fd_char();
+	case 'D':	return bk_char();
+	}
+#endif	/* defined(ANSI_ARROWS) */
+
+    if (isdigit(c)) {
+	for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); )
+	    Repeat = Repeat * 10 + c - '0';
+	Pushed = 1;
+	PushBack = c;
+	return CSstay;
+    }
+
+    if (isupper(c))
+	return do_macro(c);
+    for (OldPoint = Point, kp = MetaMap; kp->Function; kp++)
+	if (kp->Key == c)
+	    return (*kp->Function)();
+
+    return ring_bell();
+}
+
+STATIC STATUS
+emacs(c)
+    unsigned int	c;
+{
+    STATUS		s;
+    KEYMAP		*kp;
+
+    if (ISMETA(c)) {
+	Pushed = 1;
+	PushBack = UNMETA(c);
+	return meta();
+    }
+    for (kp = Map; kp->Function; kp++)
+	if (kp->Key == c)
+	    break;
+    s = kp->Function ? (*kp->Function)() : insert_char((int)c);
+    if (!Pushed)
+	/* No pushback means no repeat count; hacky, but true. */
+	Repeat = NO_ARG;
+    return s;
+}
+
+STATIC STATUS
+TTYspecial(c)
+    unsigned int	c;
+{
+    if (ISMETA(c))
+	return CSdispatch;
+
+    if (c == rl_erase || c == DEL)
+	return bk_del_char();
+    if (c == rl_kill) {
+	if (Point != 0) {
+	    Point = 0;
+	    reposition();
+	}
+	Repeat = NO_ARG;
+	return kill_line();
+    }
+    if (c == rl_intr || c == rl_quit) {
+	Point = End = 0;
+	Line[0] = '\0';
+	return redisplay();
+    }
+    if (c == rl_eof && Point == 0 && End == 0)
+	return CSeof;
+
+    return CSdispatch;
+}
+
+STATIC CHAR *
+editinput()
+{
+    unsigned int	c;
+
+    Repeat = NO_ARG;
+    OldPoint = Point = Mark = End = 0;
+    Line[0] = '\0';
+
+    while ((c = TTYget()) != EOF)
+	switch (TTYspecial(c)) {
+	case CSdone:
+	    return Line;
+	case CSeof:
+	    return NULL;
+	case CSmove:
+	    reposition();
+	    break;
+	case CSdispatch:
+	    switch (emacs(c)) {
+	    case CSdone:
+		return Line;
+	    case CSeof:
+		return NULL;
+	    case CSmove:
+		reposition();
+		break;
+	    case CSdispatch:
+	    case CSstay:
+		break;
+	    }
+	    break;
+	case CSstay:
+	    break;
+	}
+    return NULL;
+}
+
+STATIC void
+hist_add(p)
+    CHAR	*p;
+{
+    int		i;
+
+    if ((p = (CHAR *)strdup((char *)p)) == NULL)
+	return;
+    if (H.Size < HIST_SIZE)
+	H.Lines[H.Size++] = p;
+    else {
+	DISPOSE(H.Lines[0]);
+	for (i = 0; i < HIST_SIZE - 1; i++)
+	    H.Lines[i] = H.Lines[i + 1];
+	H.Lines[i] = p;
+    }
+    H.Pos = H.Size - 1;
+}
+
+/*
+**  For compatibility with FSF readline.
+*/
+/* ARGSUSED0 */
+void
+rl_reset_terminal(p)
+    char	*p;
+{
+}
+
+void
+rl_initialize()
+{
+}
+
+char *
+readline(prompt)
+    CONST char	*prompt;
+{
+    CHAR	*line;
+
+    if (Line == NULL) {
+	Length = MEM_INC;
+	if ((Line = NEW(CHAR, Length)) == NULL)
+	    return NULL;
+    }
+
+    TTYinfo();
+    rl_ttyset(0);
+    hist_add(NIL);
+    ScreenSize = SCREEN_INC;
+    Screen = NEW(char, ScreenSize);
+    Prompt = prompt ? prompt : (char *)NIL;
+    TTYputs((CHAR *)Prompt);
+    if ((line = editinput()) != NULL) {
+	line = (CHAR *)strdup((char *)line);
+	TTYputs((CHAR *)NEWLINE);
+	TTYflush();
+    }
+    rl_ttyset(1);
+    DISPOSE(Screen);
+    DISPOSE(H.Lines[--H.Size]);
+    return (char *)line;
+}
+
+void
+add_history(p)
+    char	*p;
+{
+    if (p == NULL || *p == '\0')
+	return;
+
+#if	defined(UNIQUE_HISTORY)
+    if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0)
+        return;
+#endif	/* defined(UNIQUE_HISTORY) */
+    hist_add((CHAR *)p);
+}
+
+
+STATIC STATUS
+beg_line()
+{
+    if (Point) {
+	Point = 0;
+	return CSmove;
+    }
+    return CSstay;
+}
+
+STATIC STATUS
+del_char()
+{
+    return delete_string(Repeat == NO_ARG ? 1 : Repeat);
+}
+
+STATIC STATUS
+end_line()
+{
+    if (Point != End) {
+	Point = End;
+	return CSmove;
+    }
+    return CSstay;
+}
+
+/*
+**  Move back to the beginning of the current word and return an
+**  allocated copy of it.
+*/
+STATIC CHAR *
+find_word()
+{
+    static char	SEPS[] = "#;&|^$=`'{}()<>\n\t ";
+    CHAR	*p;
+    CHAR	*new;
+    SIZE_T	len;
+
+    for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--)
+	continue;
+    len = Point - (p - Line) + 1;
+    if ((new = NEW(CHAR, len)) == NULL)
+	return NULL;
+    COPYFROMTO(new, p, len);
+    new[len - 1] = '\0';
+    return new;
+}
+
+STATIC STATUS
+c_complete()
+{
+    CHAR	*p;
+    CHAR	*word;
+    int		unique;
+    STATUS	s;
+
+    word = find_word();
+    p = (CHAR *)rl_complete((char *)word, &unique);
+    if (word)
+	DISPOSE(word);
+    if (p && *p) {
+	s = insert_string(p);
+	if (!unique)
+	    (void)ring_bell();
+	DISPOSE(p);
+	return s;
+    }
+    return ring_bell();
+}
+
+STATIC STATUS
+c_possible()
+{
+    CHAR	**av;
+    CHAR	*word;
+    int		ac;
+
+    word = find_word();
+    ac = rl_list_possib((char *)word, (char ***)&av);
+    if (word)
+	DISPOSE(word);
+    if (ac) {
+	columns(ac, av);
+	while (--ac >= 0)
+	    DISPOSE(av[ac]);
+	DISPOSE(av);
+	return CSmove;
+    }
+    return ring_bell();
+}
+
+STATIC STATUS
+accept_line()
+{
+    Line[End] = '\0';
+    return CSdone;
+}
+
+STATIC STATUS
+transpose()
+{
+    CHAR	c;
+
+    if (Point) {
+	if (Point == End)
+	    left(CSmove);
+	c = Line[Point - 1];
+	left(CSstay);
+	Line[Point - 1] = Line[Point];
+	TTYshow(Line[Point - 1]);
+	Line[Point++] = c;
+	TTYshow(c);
+    }
+    return CSstay;
+}
+
+STATIC STATUS
+quote()
+{
+    unsigned int	c;
+
+    return (c = TTYget()) == EOF ? CSeof : insert_char((int)c);
+}
+
+STATIC STATUS
+wipe()
+{
+    int		i;
+
+    if (Mark > End)
+	return ring_bell();
+
+    if (Point > Mark) {
+	i = Point;
+	Point = Mark;
+	Mark = i;
+	reposition();
+    }
+
+    return delete_string(Mark - Point);
+}
+
+STATIC STATUS
+mk_set()
+{
+    Mark = Point;
+    return CSstay;
+}
+
+STATIC STATUS
+exchange()
+{
+    unsigned int	c;
+
+    if ((c = TTYget()) != CTL('X'))
+	return c == EOF ? CSeof : ring_bell();
+
+    if ((c = Mark) <= End) {
+	Mark = Point;
+	Point = c;
+	return CSmove;
+    }
+    return CSstay;
+}
+
+STATIC STATUS
+yank()
+{
+    if (Yanked && *Yanked)
+	return insert_string(Yanked);
+    return CSstay;
+}
+
+STATIC STATUS
+copy_region()
+{
+    if (Mark > End)
+	return ring_bell();
+
+    if (Point > Mark)
+	save_yank(Mark, Point - Mark);
+    else
+	save_yank(Point, Mark - Point);
+
+    return CSstay;
+}
+
+STATIC STATUS
+move_to_char()
+{
+    unsigned int	c;
+    int			i;
+    CHAR		*p;
+
+    if ((c = TTYget()) == EOF)
+	return CSeof;
+    for (i = Point + 1, p = &Line[i]; i < End; i++, p++)
+	if (*p == c) {
+	    Point = i;
+	    return CSmove;
+	}
+    return CSstay;
+}
+
+STATIC STATUS
+fd_word()
+{
+    return do_forward(CSmove);
+}
+
+STATIC STATUS
+fd_kill_word()
+{
+    int		i;
+
+    (void)do_forward(CSstay);
+    if (OldPoint != Point) {
+	i = Point - OldPoint;
+	Point = OldPoint;
+	return delete_string(i);
+    }
+    return CSstay;
+}
+
+STATIC STATUS
+bk_word()
+{
+    int		i;
+    CHAR	*p;
+
+    i = 0;
+    do {
+	for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--)
+	    left(CSmove);
+
+	for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--)
+	    left(CSmove);
+
+	if (Point == 0)
+	    break;
+    } while (++i < Repeat);
+
+    return CSstay;
+}
+
+STATIC STATUS
+bk_kill_word()
+{
+    (void)bk_word();
+    if (OldPoint != Point)
+	return delete_string(OldPoint - Point);
+    return CSstay;
+}
+
+STATIC int
+argify(line, avp)
+    CHAR	*line;
+    CHAR	***avp;
+{
+    CHAR	*c;
+    CHAR	**p;
+    CHAR	**new;
+    int		ac;
+    int		i;
+
+    i = MEM_INC;
+    if ((*avp = p = NEW(CHAR*, i))== NULL)
+	 return 0;
+
+    for (c = line; isspace(*c); c++)
+	continue;
+    if (*c == '\n' || *c == '\0')
+	return 0;
+
+    for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) {
+	if (isspace(*c)) {
+	    *c++ = '\0';
+	    if (*c && *c != '\n') {
+		if (ac + 1 == i) {
+		    new = NEW(CHAR*, i + MEM_INC);
+		    if (new == NULL) {
+			p[ac] = NULL;
+			return ac;
+		    }
+		    COPYFROMTO(new, p, i * sizeof (char **));
+		    i += MEM_INC;
+		    DISPOSE(p);
+		    *avp = p = new;
+		}
+		p[ac++] = c;
+	    }
+	}
+	else
+	    c++;
+    }
+    *c = '\0';
+    p[ac] = NULL;
+    return ac;
+}
+
+STATIC STATUS
+last_argument()
+{
+    CHAR	**av;
+    CHAR	*p;
+    STATUS	s;
+    int		ac;
+
+    if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL)
+	return ring_bell();
+
+    if ((p = (CHAR *)strdup((char *)p)) == NULL)
+	return CSstay;
+    ac = argify(p, &av);
+
+    if (Repeat != NO_ARG)
+	s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
+    else
+	s = ac ? insert_string(av[ac - 1]) : CSstay;
+
+    if (ac)
+	DISPOSE(av);
+    DISPOSE(p);
+    return s;
+}
+
+STATIC KEYMAP	Map[33] = {
+    {	CTL('@'),	ring_bell	},
+    {	CTL('A'),	beg_line	},
+    {	CTL('B'),	bk_char		},
+    {	CTL('D'),	del_char	},
+    {	CTL('E'),	end_line	},
+    {	CTL('F'),	fd_char		},
+    {	CTL('G'),	ring_bell	},
+    {	CTL('H'),	bk_del_char	},
+    {	CTL('I'),	c_complete	},
+    {	CTL('J'),	accept_line	},
+    {	CTL('K'),	kill_line	},
+    {	CTL('L'),	redisplay	},
+    {	CTL('M'),	accept_line	},
+    {	CTL('N'),	h_next		},
+    {	CTL('O'),	ring_bell	},
+    {	CTL('P'),	h_prev		},
+    {	CTL('Q'),	ring_bell	},
+    {	CTL('R'),	h_search	},
+    {	CTL('S'),	ring_bell	},
+    {	CTL('T'),	transpose	},
+    {	CTL('U'),	ring_bell	},
+    {	CTL('V'),	quote		},
+    {	CTL('W'),	wipe		},
+    {	CTL('X'),	exchange	},
+    {	CTL('Y'),	yank		},
+    {	CTL('Z'),	ring_bell	},
+    {	CTL('['),	meta		},
+    {	CTL(']'),	move_to_char	},
+    {	CTL('^'),	ring_bell	},
+    {	CTL('_'),	ring_bell	},
+    {	0,		NULL		}
+};
+
+STATIC KEYMAP	MetaMap[16]= {
+    {	CTL('H'),	bk_kill_word	},
+    {	DEL,		bk_kill_word	},
+    {	' ',		mk_set	},
+    {	'.',		last_argument	},
+    {	'<',		h_first		},
+    {	'>',		h_last		},
+    {	'?',		c_possible	},
+    {	'b',		bk_word		},
+    {	'd',		fd_kill_word	},
+    {	'f',		fd_word		},
+    {	'l',		case_down_word	},
+    {	'u',		case_up_word	},
+    {	'y',		yank		},
+    {	'w',		copy_region	},
+    {	0,		NULL		}
+};
diff --git a/debugger/readline/editline.h b/debugger/readline/editline.h
new file mode 100644
index 0000000..40a2025
--- /dev/null
+++ b/debugger/readline/editline.h
@@ -0,0 +1,76 @@
+/*  $Revision: 1.3 $
+**
+**  Internal header file for editline library.
+*/
+#include <stdio.h>
+#if	defined(HAVE_STDLIB)
+#include <stdlib.h>
+#include <string.h>
+#endif	/* defined(HAVE_STDLIB) */
+#if	defined(SYS_UNIX)
+#include "unix.h"
+#endif	/* defined(SYS_UNIX) */
+#if	defined(SYS_OS9)
+#include "os9.h"
+#endif	/* defined(SYS_OS9) */
+
+#if	!defined(SIZE_T)
+#define SIZE_T	unsigned int
+#endif	/* !defined(SIZE_T) */
+
+typedef unsigned char	CHAR;
+
+#if	defined(HIDE)
+#define STATIC	static
+#else
+#define STATIC	/* NULL */
+#endif	/* !defined(HIDE) */
+
+#if	!defined(CONST)
+#if	defined(__STDC__)
+#define CONST	const
+#else
+#define CONST
+#endif	/* defined(__STDC__) */
+#endif	/* !defined(CONST) */
+
+
+#define MEM_INC		64
+#define SCREEN_INC	256
+
+#define DISPOSE(p)	free((char *)(p))
+#define NEW(T, c)	\
+	((T *)malloc((unsigned int)(sizeof (T) * (c))))
+#define RENEW(p, T, c)	\
+	(p = (T *)realloc((char *)(p), (unsigned int)(sizeof (T) * (c))))
+#define COPYFROMTO(new, p, len)	\
+	(void)memcpy((char *)(new), (char *)(p), (int)(len))
+
+
+/*
+**  Variables and routines internal to this package.
+*/
+extern int	rl_eof;
+extern int	rl_erase;
+extern int	rl_intr;
+extern int	rl_kill;
+extern int	rl_quit;
+extern char	*rl_complete();
+extern int	rl_list_possib();
+extern void	rl_ttyset();
+extern void	rl_add_slash();
+
+#if	!defined(HAVE_STDLIB)
+extern char	*getenv();
+extern char	*malloc();
+extern char	*realloc();
+extern char	*memcpy();
+extern char	*strcat();
+extern char	*strchr();
+extern char	*strrchr();
+extern char	*strcpy();
+extern char	*strdup();
+extern int	strcmp();
+extern int	strlen();
+extern int	strncmp();
+#endif	/* !defined(HAVE_STDLIB) */
diff --git a/debugger/readline/os9.h b/debugger/readline/os9.h
new file mode 100644
index 0000000..7bb7cf3
--- /dev/null
+++ b/debugger/readline/os9.h
@@ -0,0 +1,10 @@
+/*  $Revision: 1.1 $
+**
+**  Editline system header file for OS-9 (on 68k).
+*/
+
+#define CRLF		"\r\l"
+#define FORWARD		extern
+
+#include <dir.h>
+typedef struct direct	DIRENTRY;
diff --git a/debugger/readline/sysos9.c b/debugger/readline/sysos9.c
new file mode 100644
index 0000000..fd23aa4
--- /dev/null
+++ b/debugger/readline/sysos9.c
@@ -0,0 +1,46 @@
+/*  $Revision: 1.1 $
+**
+**  OS-9 system-dependant routines for editline library.
+*/
+#include "editline.h"
+#include <sgstat.h>
+#include <modes.h>
+
+
+void
+rl_ttyset(Reset)
+    int			Reset;
+{
+    static struct sgbuf	old;
+    struct sgbuf	new;
+
+
+    if (Reset == 0) {
+        _gs_opt(0, &old);
+        _gs_opt(0, &new);
+        new.sg_backsp = 0;	new.sg_delete = 0;	new.sg_echo = 0;
+        new.sg_alf = 0;		new.sg_nulls = 0;	new.sg_pause = 0;
+        new.sg_page = 0;	new.sg_bspch = 0;	new.sg_dlnch = 0;
+        new.sg_eorch = 0;	new.sg_eofch = 0;	new.sg_rlnch = 0;
+        new.sg_dulnch = 0;	new.sg_psch = 0;	new.sg_kbich = 0;
+        new.sg_kbach = 0;	new.sg_bsech = 0;	new.sg_bellch = 0;
+        new.sg_xon = 0;		new.sg_xoff = 0;	new.sg_tabcr = 0;
+        new.sg_tabsiz = 0;
+        _ss_opt(0, &new);
+        rl_erase = old.sg_bspch;
+        rl_kill = old.sg_dlnch;
+        rl_eof = old.sg_eofch;
+        rl_intr = old.sg_kbich;
+        rl_quit = -1;
+    }
+    else
+        _ss_opt(0, &old);
+}
+
+void
+rl_add_slash(path, p)
+    char	*path;
+    char	*p;
+{
+    (void)strcat(p, access(path, S_IREAD | S_IFDIR) ? " " : "/");
+}
diff --git a/debugger/readline/sysunix.c b/debugger/readline/sysunix.c
new file mode 100644
index 0000000..010744e1
--- /dev/null
+++ b/debugger/readline/sysunix.c
@@ -0,0 +1,89 @@
+/*  $Revision: 1.1 $
+**
+**  Unix system-dependant routines for editline library.
+*/
+#include "editline.h"
+
+#if	defined(HAVE_TCGETATTR)
+#include <termios.h>
+
+void
+rl_ttyset(Reset)
+    int				Reset;
+{
+    static struct termios	old;
+    struct termios		new;
+
+    if (Reset == 0) {
+	(void)tcgetattr(0, &old);
+	rl_erase = old.c_cc[VERASE];
+	rl_kill = old.c_cc[VKILL];
+	rl_eof = old.c_cc[VEOF];
+	rl_intr = old.c_cc[VINTR];
+	rl_quit = old.c_cc[VQUIT];
+
+	new = old;
+	new.c_cc[VINTR] = -1;
+	new.c_cc[VQUIT] = -1;
+	new.c_lflag &= ~(ECHO | ICANON);
+	new.c_iflag &= ~(ISTRIP | INPCK);
+	new.c_cc[VMIN] = 1;
+	new.c_cc[VTIME] = 0;
+	(void)tcsetattr(0, TCSANOW, &new);
+    }
+    else
+	(void)tcsetattr(0, TCSANOW, &old);
+}
+
+#else
+#include <sgtty.h>
+
+void
+rl_ttyset(Reset)
+    int				Reset;
+{
+    static struct sgttyb	old_sgttyb;
+    static struct tchars	old_tchars;
+    struct sgttyb		new_sgttyb;
+    struct tchars		new_tchars;
+
+    if (Reset == 0) {
+	(void)ioctl(0, TIOCGETP, &old_sgttyb);
+	rl_erase = old_sgttyb.sg_erase;
+	rl_kill = old_sgttyb.sg_kill;
+
+	(void)ioctl(0, TIOCGETC, &old_tchars);
+	rl_eof = old_tchars.t_eofc;
+	rl_intr = old_tchars.t_intrc;
+	rl_quit = old_tchars.t_quitc;
+
+	new_sgttyb = old_sgttyb;
+	new_sgttyb.sg_flags &= ~ECHO;
+	new_sgttyb.sg_flags |= RAW;
+#if	defined(PASS8)
+	new_sgttyb.sg_flags |= PASS8;
+#endif	/* defined(PASS8) */
+	(void)ioctl(0, TIOCSETP, &new_sgttyb);
+
+	new_tchars = old_tchars;
+	new_tchars.t_intrc = -1;
+	new_tchars.t_quitc = -1;
+	(void)ioctl(0, TIOCSETC, &new_tchars);
+    }
+    else {
+	(void)ioctl(0, TIOCSETP, &old_sgttyb);
+	(void)ioctl(0, TIOCSETC, &old_tchars);
+    }
+}
+#endif	/* defined(HAVE_TCGETATTR) */
+
+void
+rl_add_slash(path, p)
+    char	*path;
+    char	*p;
+{
+    struct stat	Sb;
+
+    if (stat(path, &Sb) >= 0)
+	(void)strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ");
+}
diff --git a/debugger/readline/testit.c b/debugger/readline/testit.c
new file mode 100644
index 0000000..e6384b8
--- /dev/null
+++ b/debugger/readline/testit.c
@@ -0,0 +1,62 @@
+/*  $Revision: 1.2 $
+**
+**  A "micro-shell" to test editline library.
+**  If given any arguments, commands aren't executed.
+*/
+#include <stdio.h>
+#if	defined(HAVE_STDLIB)
+#include <stdlib.h>
+#endif	/* defined(HAVE_STDLIB) */
+
+const char version_string[] = "4.321"; 
+
+
+extern char	*readline();
+extern void	add_history();
+
+#if	!defined(HAVE_STDLIB)
+extern int	chdir();
+extern int	free();
+extern int	strncmp();
+extern int	system();
+extern void	exit();
+#endif	/* !defined(HAVE_STDLIB) */
+
+
+#if	defined(NEED_PERROR)
+void
+perror(s)
+    char	*s;
+{
+    extern int	errno;
+
+    (voidf)printf(stderr, "%s: error %d\n", s, errno);
+}
+#endif	/* defined(NEED_PERROR) */
+
+
+/* ARGSUSED1 */
+int
+main(ac, av)
+    int		ac;
+    char	*av[];
+{
+    char	*p;
+    int		doit;
+
+    doit = ac == 1;
+    while ((p = readline("testit> ")) != NULL) {
+	(void)printf("\t\t\t|%s|\n", p);
+	if (doit)
+	    if (strncmp(p, "cd ", 3) == 0) {
+		if (chdir(&p[3]) < 0)
+		    perror(&p[3]);
+	    }
+	    else if (system(p) != 0)
+		perror(p);
+	add_history(p);
+	free(p);
+    }
+    exit(0);
+    /* NOTREACHED */
+}
diff --git a/debugger/readline/unix.h b/debugger/readline/unix.h
new file mode 100644
index 0000000..fe6beed
--- /dev/null
+++ b/debugger/readline/unix.h
@@ -0,0 +1,22 @@
+/*  $Revision: 1.1 $
+**
+**  Editline system header file for Unix.
+*/
+
+#define CRLF		"\r\n"
+#define FORWARD		STATIC
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if	defined(USE_DIRENT)
+#include <dirent.h>
+typedef struct dirent	DIRENTRY;
+#else
+#include <sys/dir.h>
+typedef struct direct	DIRENTRY;
+#endif	/* defined(USE_DIRENT) */
+
+#if	!defined(S_ISDIR)
+#define S_ISDIR(m)		(((m) & S_IFMT) == S_IFDIR)
+#endif	/* !defined(S_ISDIR) */
diff --git a/debugger/readline/version.c b/debugger/readline/version.c
new file mode 100644
index 0000000..7b1b242
--- /dev/null
+++ b/debugger/readline/version.c
@@ -0,0 +1,6 @@
+const char version_string[] = "1.234";
+
+
+static char foobar[]="foobar";
+
+const char * foo_string = foobar;
diff --git a/debugger/regpos.h b/debugger/regpos.h
new file mode 100644
index 0000000..c3d3086
--- /dev/null
+++ b/debugger/regpos.h
@@ -0,0 +1,51 @@
+
+#ifdef linux
+/* Register numbers */
+#define  RN_GS			0
+#define  RN_FS			1
+#define  RN_ES			2
+#define  RN_DS			3
+#define  RN_EDI  		4
+#define  RN_ESI			5
+#define  RN_EBP			6
+#define  RN_ESP			7
+#define  RN_EBX			8
+#define  RN_EDX			9
+#define  RN_ECX			10
+#define  RN_EAX			11
+#define  RN_TRAPNO		12
+#define  RN_ERR			13
+#define  RN_EIP			14
+#define  RN_CS			15
+#define  RN_EFLAGS		16
+#define  RN_ESP_AT_SIGNAL	17
+#define  RN_SS			18
+#define  RN_I387		19
+#define  RN_OLDMASK		20
+#define  RN_CR2			21
+#endif
+
+
+#define  SC_GS			regval[RN_GS]
+#define  SC_FS			regval[RN_FS]
+#define  SC_ES			regval[RN_ES]
+#define  SC_DS			regval[RN_DS]
+#define  SC_EDI(dbg_mask)  	(regval[RN_EDI] & dbg_mask)
+#define  SC_ESI(dbg_mask)	(regval[RN_ESI] & dbg_mask)
+#define  SC_EBP(dbg_mask)	(regval[RN_EBP] & dbg_mask)
+#define  SC_ESP(dbg_mask)	(regval[RN_ESP] & dbg_mask)
+#define  SC_EBX(dbg_mask)	(regval[RN_EBX] & dbg_mask)
+#define  SC_EDX(dbg_mask)	(regval[RN_EDX] & dbg_mask)
+#define  SC_ECX(dbg_mask)	(regval[RN_ECX] & dbg_mask)
+#define  SC_EAX(dbg_mask)	(regval[RN_EAX] & dbg_mask)
+#define  SC_TRAPNO		regval[RN_TRAPNO]
+#define  SC_ERR			regval[RN_ERR]
+#define  SC_EIP(dbg_mask)	(regval[RN_EIP] & dbg_mask)
+#define  SC_CS			regval[RN_CS]
+#define  SC_EFLAGS		regval[RN_EFLAGS]
+#define  ESP_AT_SIGNAL		regval[RN_ESP_AT_SIGNAL]
+#define  SC_SS			regval[RN_SS]
+#define  I387			regval[RN_I387]
+#define  OLDMASK		regval[RN_OLDMASK]
+#define  CR2			regval[RN_CR2]
+
diff --git a/debugger/tm-i386v.h b/debugger/tm-i386v.h
new file mode 100644
index 0000000..bfd0e35
--- /dev/null
+++ b/debugger/tm-i386v.h
@@ -0,0 +1,324 @@
+/* Macro definitions for i386, Unix System V.
+   Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if !defined (TM_I386V_H)
+#define TM_I386V_H 1
+
+/*
+ * Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu)
+ * July 1988
+ */
+
+#define TARGET_BYTE_ORDER LITTLE_ENDIAN
+
+/* define this if you don't have the extension to coff that allows
+ * file names to appear in the string table
+ * (aux.x_file.x_foff)
+ */
+#define COFF_NO_LONG_FILE_NAMES
+
+/* turn this on when rest of gdb is ready */
+#define IEEE_FLOAT
+
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+
+/* #define NAMES_HAVE_UNDERSCORE */
+
+/* number of traps that happen between exec'ing the shell 
+ * to run an inferior, and when we finally get to 
+ * the inferior code.  This is 2 on most implementations.
+ */
+#ifndef START_INFERIOR_TRAPS_EXPECTED
+#define START_INFERIOR_TRAPS_EXPECTED 4
+#endif
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+
+#define FUNCTION_START_OFFSET 0
+
+/* Advance PC across any function entry prologue instructions
+   to reach some "real" code.  */
+
+#define SKIP_PROLOGUE(frompc)   {(frompc) = i386_skip_prologue((frompc));}
+
+extern int
+i386_skip_prologue PARAMS ((int));
+
+/* Immediately after a function call, return the saved pc.
+   Can't always go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
+#define SAVED_PC_AFTER_CALL(frame) \
+  (read_memory_integer (read_register (SP_REGNUM), 4))
+
+/* Address of end of stack space.  */
+
+#define STACK_END_ADDR 0x80000000
+
+/* Stack grows downward.  */
+
+#define INNER_THAN <
+
+/* Sequence of bytes for breakpoint instruction.  */
+
+#define BREAKPOINT {0xcc}
+
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+
+#ifndef DECR_PC_AFTER_BREAK
+#define DECR_PC_AFTER_BREAK 1
+#endif
+
+/* Nonzero if instruction at PC is a return instruction.  */
+
+#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0xc3)
+
+/* Return 1 if P points to an invalid floating point value.
+   LEN is the length in bytes -- not relevant on the 386.  */
+
+#define INVALID_FLOAT(p, len) (0)
+
+/* Say how long (ordinary) registers are.  */
+
+#define REGISTER_TYPE long
+
+/* Number of machine registers */
+
+#define NUM_REGS 16
+
+/* Initializer for an array of names of registers.
+   There should be NUM_REGS strings in this initializer.  */
+
+/* the order of the first 8 registers must match the compiler's 
+ * numbering scheme (which is the same as the 386 scheme)
+ * also, this table must match regmap in i386-pinsn.c.
+ */
+#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
+			 "esp", "ebp", "esi", "edi", \
+			 "eip", "ps", "cs", "ss", \
+			 "ds", "es", "fs", "gs", \
+			 }
+
+/* Register numbers of various important registers.
+   Note that some of these values are "real" register numbers,
+   and correspond to the general registers of the machine,
+   and some are "phony" register numbers which are too large
+   to be actual register numbers as far as the user is concerned
+   but do serve to get the desired values when passed to read_register.  */
+
+#define FP_REGNUM 5		/* Contains address of executing stack frame */
+#define SP_REGNUM 4		/* Contains address of top of stack */
+
+#define PC_REGNUM 8
+#define PS_REGNUM 9
+
+/* Total amount of space needed to store our copies of the machine's
+   register state, the array `registers'.  */
+#define REGISTER_BYTES (NUM_REGS * 4)
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+#define REGISTER_BYTE(N) ((N)*4)
+
+/* Number of bytes of storage in the actual machine representation
+   for register N.  */
+
+#define REGISTER_RAW_SIZE(N) (4)
+
+/* Number of bytes of storage in the program's representation
+   for register N. */
+
+#define REGISTER_VIRTUAL_SIZE(N) (4)
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+
+#define MAX_REGISTER_RAW_SIZE 4
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+
+#define MAX_REGISTER_VIRTUAL_SIZE 4
+
+/* Nonzero if register N requires conversion
+   from raw format to virtual format.  */
+
+#define REGISTER_CONVERTIBLE(N) (0)
+
+/* Convert data from raw format for register REGNUM
+   to virtual format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
+  {memcpy ((TO), (FROM), 4);}
+
+/* Convert data from virtual format for register REGNUM
+   to raw format for register REGNUM.  */
+
+#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
+  {memcpy ((TO), (FROM), 4);}
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+/* Perhaps si and di should go here, but potentially they could be
+   used for things other than address.  */
+#define REGISTER_VIRTUAL_TYPE(N) \
+  ((N) == PC_REGNUM || (N) == FP_REGNUM || (N) == SP_REGNUM ?         \
+   lookup_pointer_type (builtin_type_void) : builtin_type_int)
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function. */
+
+#define STORE_STRUCT_RETURN(ADDR, SP) \
+  { (SP) -= sizeof (ADDR);		\
+    write_memory ((SP), (char *) &(ADDR), sizeof (ADDR)); }
+
+/* Extract from an array REGBUF containing the (raw) register state
+   a function return value of type TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+  memcpy ((VALBUF), (REGBUF), TYPE_LENGTH (TYPE))
+
+/* Write into appropriate registers a function return value
+   of type TYPE, given in virtual format.  */
+
+#define STORE_RETURN_VALUE(TYPE,VALBUF) \
+  write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
+
+/* Extract from an array REGBUF containing the (raw) register state
+   the address in which a function should return its structure value,
+   as a CORE_ADDR (or an expression that can be used as one).  */
+
+#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
+
+
+/* Describe the pointer in each stack frame to the previous stack frame
+   (its caller).  */
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer. */
+
+#define FRAME_CHAIN(thisframe) \
+  (!inside_entry_file ((thisframe)->pc) ? \
+   read_memory_integer ((thisframe)->frame, 4) :\
+   0)
+
+/* Define other aspects of the stack frame.  */
+
+/* A macro that tells us whether the function invocation represented
+   by FI does not have a frame on the stack associated with it.  If it
+   does not, FRAMELESS is set to 1, else 0.  */
+#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
+  (FRAMELESS) = frameless_look_for_prologue(FI)
+
+#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
+
+#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
+
+#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
+
+/* Return number of args passed to a frame.
+   Can return -1, meaning no way to tell.  */
+
+#define FRAME_NUM_ARGS(numargs, fi) (numargs) = i386_frame_num_args(fi)
+
+#ifdef __STDC__		/* Forward decl's for prototypes */
+struct frame_info;
+struct frame_saved_regs;
+#endif
+
+extern int
+i386_frame_num_args PARAMS ((struct frame_info *));
+
+/* Return number of bytes at start of arglist that are not really args.  */
+
+#define FRAME_ARGS_SKIP 8
+
+/* Put here the code to store, into a struct frame_saved_regs,
+   the addresses of the saved registers of frame described by FRAME_INFO.
+   This includes special registers such as pc and fp saved in special
+   ways in the stack frame.  sp is even more special:
+   the address we return for it IS the sp for the next frame.  */
+
+#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
+{ i386_frame_find_saved_regs ((frame_info), &(frame_saved_regs)); }
+
+extern void
+i386_frame_find_saved_regs PARAMS ((struct frame_info *,
+				    struct frame_saved_regs *));
+
+
+/* Things needed for making the inferior call functions.  */
+
+/* Push an empty stack frame, to record the current PC, etc.  */
+
+#define PUSH_DUMMY_FRAME { i386_push_dummy_frame (); }
+
+extern void
+i386_push_dummy_frame PARAMS ((void));
+
+/* Discard from the stack the innermost frame, restoring all registers.  */
+
+#define POP_FRAME  { i386_pop_frame (); }
+
+extern void
+i386_pop_frame PARAMS ((void));
+
+/* this is 
+ *   call 11223344 (32 bit relative)
+ *   int3
+ */
+
+#define CALL_DUMMY { 0x223344e8, 0xcc11 }
+
+#define CALL_DUMMY_LENGTH 8
+
+#define CALL_DUMMY_START_OFFSET 0  /* Start execution at beginning of dummy */
+
+/* Insert the specified number of args and function address
+   into a call sequence of the above form stored at DUMMYNAME.  */
+
+#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
+{ \
+	int from, to, delta, loc; \
+	loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH); \
+	from = loc + 5; \
+	to = (int)(fun); \
+	delta = to - from; \
+	*((char *)(dummyname) + 1) = (delta & 0xff); \
+	*((char *)(dummyname) + 2) = ((delta >> 8) & 0xff); \
+	*((char *)(dummyname) + 3) = ((delta >> 16) & 0xff); \
+	*((char *)(dummyname) + 4) = ((delta >> 24) & 0xff); \
+}
+
+extern void
+print_387_control_word PARAMS ((unsigned int));
+
+extern void
+print_387_status_word PARAMS ((unsigned int));
+
+/* Offset from SP to first arg on stack at first instruction of a function */
+
+#define SP_ARG0 (1 * 4)
+
+#endif	/* !defined (TM_I386V_H) */
diff --git a/debugger/tm.h b/debugger/tm.h
new file mode 100644
index 0000000..f36505f
--- /dev/null
+++ b/debugger/tm.h
@@ -0,0 +1,27 @@
+/* Macro definitions for linux.
+   Copyright (C) 1992 Free Software Foundation, Inc.
+This file is part of GDB.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+This program 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 General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#if !defined (TM_LINUX_H)
+#define TM_LINUX_H 1
+/* number of traps that happen between exec'ing the shell
+ * to run an inferior, and when we finally get to
+ * the inferior code.  This is 2 on most implementations.
+ */
+#define START_INFERIOR_TRAPS_EXPECTED 2
+#include "tm-i386v.h"
+/* Define this if the C compiler puts an underscore at the front
+   of external names before giving them to the linker.  */
+#define NAMES_HAVE_UNDERSCORE
+#endif		/* !defined (TM_LINUX_H) */
diff --git a/debugger/xm-i386v.h b/debugger/xm-i386v.h
new file mode 100644
index 0000000..cff2319
--- /dev/null
+++ b/debugger/xm-i386v.h
@@ -0,0 +1,45 @@
+/* Host support for i386.
+   Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
+   Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's
+Sys V/386 3.2.
+
+On some machines, gdb crashes when it's starting up while calling the
+vendor's termio tgetent() routine.  It always works when run under
+itself (actually, under 3.2, it's not an infinitely recursive bug.)
+After some poking around, it appears that depending on the environment
+size, or whether you're running YP, or the phase of the moon or something,
+the stack is not always long-aligned when main() is called, and tgetent()
+takes strong offense at that.  On some machines this bug never appears, but
+on those where it does, it occurs quite reliably.  */
+#define ALIGN_STACK_ON_STARTUP
+
+/* define USG if you are using sys5 /usr/include's */
+#define USG
+
+#define HAVE_TERMIO
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+
+#define KERNEL_U_ADDR 0xe0000000
+
diff --git a/debugger/xm.h b/debugger/xm.h
new file mode 100644
index 0000000..f265c73
--- /dev/null
+++ b/debugger/xm.h
@@ -0,0 +1,26 @@
+/* Native support for linux, for GDB, the GNU debugger.
+   Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "xm-i386v.h"
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+#undef KERNEL_U_ADDR
+#define KERNEL_U_ADDR 0x0
+#define PSIGNAL_IN_SIGNAL_H
diff --git a/if1632/callback.c b/if1632/callback.c
index dd5d035..3c35e88 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -135,17 +135,22 @@
 LONG CallWindowProc( FARPROC func, HWND hwnd, WORD message,
 		     WORD wParam, LONG lParam )
 {
-    if ((unsigned int)func & 0xffff0000)
+    if (Is16bitAddress(func))
     {	
 	PushOn16( CALLBACK_SIZE_WORD, hwnd );
 	PushOn16( CALLBACK_SIZE_WORD, message );
 	PushOn16( CALLBACK_SIZE_WORD, wParam );
 	PushOn16( CALLBACK_SIZE_LONG, lParam );
+
+	printf("%8.8x(%4.4x, %4.4x, %4.4x, %8.8x)\n", func, hwnd, message, wParam, lParam);
+
 	return CallTo16((unsigned int) func, 
 			FindDataSegmentForCode((unsigned long) func));   
     }
     else
-	return WIDGETS_Call32WndProc( func, hwnd, message, wParam, lParam );
+    {
+	return (*func)(hwnd, message, wParam, lParam);
+    }
 }
 
 /**********************************************************************
@@ -153,9 +158,16 @@
  */
 void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam)
 {
-    PushOn16( CALLBACK_SIZE_WORD, xPos );
-    PushOn16( CALLBACK_SIZE_WORD, yPos );
-    PushOn16( CALLBACK_SIZE_LONG, lParam );
-    CallTo16((unsigned int) func, 
-	     FindDataSegmentForCode((unsigned long) func));   
+    if (Is16bitAddress(func))
+    {
+	PushOn16( CALLBACK_SIZE_WORD, xPos );
+	PushOn16( CALLBACK_SIZE_WORD, yPos );
+	PushOn16( CALLBACK_SIZE_LONG, lParam );
+	CallTo16((unsigned int) func, 
+		 FindDataSegmentForCode((unsigned long) func));   
+    }
+    else
+    {
+	(*func)(xPos, yPos, lParam);
+    }
 }
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index bfeb1b4..63eb008 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -32,11 +32,19 @@
 50  pascal GetProcAddress(word ptr) GetProcAddress(1 2)
 51  pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2)
 52  pascal FreeProcInstance(ptr) FreeProcInstance(1)
+59  pascal WriteProfileString(ptr ptr ptr) WriteProfileString(1 2 3)
+60  pascal FindResource(word ptr ptr) FindResource(1 2 3)
+61  pascal LoadResource(word word) LoadResource(1 2)
+62  pascal LockResource(word) LockResource(1)
+63  pascal FreeResource(word) FreeResource(1)
 74  pascal OpenFile(ptr ptr word) KERNEL_OpenFile(1 2 3)
 81  pascal _lclose(word) KERNEL__lclose(1)
 82  pascal _lread(word ptr word) KERNEL__lread(1 2 3)
 85  pascal _lopen(ptr word) KERNEL__lopen(1 2)
 86  pascal _lwrite(word ptr word) KERNEL__lwrite(1 2 3)
+88  pascal lstrcpy(ptr ptr) lstrcpy(1 2)
+89  pascal lstrcat(ptr ptr) lstrcat(1 2)
+90  pascal lstrlen(ptr) lstrcpy(1)
 91  register InitTask(word word word word word
 		      word word word word word) 
 	     KERNEL_InitTask()
@@ -51,6 +59,8 @@
 	   GetPrivateProfileInt(1 2 3 4)
 128 pascal GetPrivateProfileString(ptr ptr ptr ptr s_word ptr)
 	   GetPrivateProfileString(1 2 3 4 5 6)
+129 pascal WritePrivateProfileString(ptr ptr ptr ptr)
+	   WritePrivateProfileString(1 2 3 4)
 131 pascal GetDOSEnvironment() GetDOSEnvironment()
 132 return GetWinFlags 0 0x413
 154 return GlobalNotify 4 0
@@ -66,3 +76,4 @@
 57  pascal GetProfileInt(ptr ptr word) GetProfileInt(1 2 3)
 58  pascal GetProfileString(ptr ptr ptr ptr word) GetProfileString(1 2 3 4 5)
 199 pascal SetHandleCount(word) SetHandleCount(1)
+353 pascal lstrcpyn(ptr ptr word) lstrcpyn(1 2 3)
diff --git a/if1632/relay.c b/if1632/relay.c
index cf93fe7..9bf6b12 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -107,11 +107,6 @@
 	    IF1632_Saved16_ss  == 0x0097)
 	    printf("ACK!!\n");
 
-#if 0
-	IF1632_Saved16_esp &= 0x0000ffff;
-	IF1632_Saved16_ebp &= 0x0000ffff;
-#endif
-
 #ifdef DEBUG_STACK
 	stack_p = (unsigned short *) seg_off;
 	for (i = 0; i < 24; i++, stack_p++)
diff --git a/if1632/sound.spec b/if1632/sound.spec
index 0e7d012..be0a2f4 100644
--- a/if1632/sound.spec
+++ b/if1632/sound.spec
@@ -1,4 +1,4 @@
-# $Id: win87em.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
+# $Id: sound.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	sound
 id	7
diff --git a/if1632/user.spec b/if1632/user.spec
index 1da0c4d..4a32a6a 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -17,11 +17,14 @@
 19  pascal ReleaseCapture() ReleaseCapture()
 31  pascal IsIconic(word) IsIconic(1)
 33  pascal GetClientRect(word ptr) GetClientRect(1 2)
+36  pascal GetWindowText(word ptr word) GetWindowText(1 2 3)
+38  pascal GetWindowTextLength(word) GetWindowTextLength(1)
 39  pascal BeginPaint(word ptr) BeginPaint(1 2)
 40  pascal EndPaint(word ptr) EndPaint(1 2)
 41  pascal CreateWindow(ptr ptr long s_word s_word s_word s_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)
+46  pascal GetParent(word) GetParent(1)
 53  pascal DestroyWindow(word) DestroyWindow(1)
 57  pascal RegisterClass(ptr) RegisterClass(1)
 66  pascal GetDC(word) GetDC(1)
@@ -37,6 +40,7 @@
 80  pascal UnionRect(ptr ptr ptr) UnionRect(1 2 3)
 81  pascal FillRect(word ptr word) FillRect(1 2 3)
 82  pascal InvertRect(word ptr) InvertRect(1 2)
+83  pascal FrameRect(word ptr word) FrameRect(1 2 3)
 85  pascal DrawText(word ptr s_word ptr word) DrawText(1 2 3 4 5)
 102 pascal AdjustWindowRect(ptr long word) AdjustWindowRect(1 2 3)
 104 pascal MessageBeep(word) MessageBeep(1)
@@ -60,6 +64,10 @@
 130 pascal SetClassWord(word s_word word) SetClassWord(1 2 3)
 131 pascal GetClassLong(word s_word) GetClassLong(1 2)
 132 pascal SetClassLong(word s_word long) SetClassLong(1 2 3)
+133 pascal GetWindowWord(word s_word) GetWindowWord(1 2)
+134 pascal SetWindowWord(word s_word word) SetWindowWord(1 2 3)
+135 pascal GetWindowLong(word s_word) GetWindowLong(1 2)
+136 pascal SetWindowLong(word s_word long) SetWindowLong(1 2 3)
 150 pascal LoadMenu(word ptr) LoadMenu(1 2)
 151 pascal CreateMenu() CreateMenu()
 154 pascal CheckMenu(word word word) CheckMenu(1 2 3)
@@ -69,12 +77,32 @@
 174 pascal LoadIcon(word ptr) LoadIcon(1 2)
 175 pascal LoadBitmap(word ptr) LoadBitmap(1 2)
 176 pascal LoadString(word word ptr s_word) LoadString(1 2 3 4)
+177 pascal LoadAccelerators(word ptr) LoadAccelerators(1 2)
 179 pascal GetSystemMetrics(word) GetSystemMetrics(1)
+180 pascal GetSysColor(word) GetSysColor(1)
+181 pascal SetSysColors(word ptr ptr) SetSysColors(1 2 3)
+430 pascal lstrcmp(ptr ptr) lstrcmp(1 2)
+431 pascal AnsiUpper(ptr) AnsiUpper(1)
+432 pascal AnsiLower(ptr) AnsiLower(1)
+433 pascal IsCharAlpha(byte) IsCharAlpha(1)
+434 pascal IsCharAlphanumeric(byte) IsCharAlphanumeric(1)
+435 pascal IsCharUpper(byte) IsCharUpper(1)
+436 pascal IsCharLower(byte) IsCharLower(1)
+437 pascal AnsiUpperBuff(ptr word) AnsiUpperBuff(1 2)
+438 pascal AnsiLowerBuff(ptr word) AnsiLowerBuff(1 2)
+471 pascal lstrcmpi(ptr ptr) lstrcmpi(1 2)
+472 pascal AnsiNext(ptr) AnsiNext(1 )
+473 pascal AnsiPrev(ptr ptr) AnsiPrev(1 2)
+
+
+
+
 182 pascal KillSystemTimer(word word) KillSystemTimer(1 2)
 190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3)
 237 pascal GetUpdateRgn(word word word) GetUpdateRgn(1 2 3)
 244 pascal EqualRect(ptr ptr) EqualRect(1 2)
 266 pascal SetMessageQueue(word) SetMessageQueue(1)
+286 pascal GetDesktopWindow() GetDesktopWindow()
 288 pascal GetMessageExtraInfo() GetMessageExtraInfo()
 324 pascal FillWindow(word word word word) FillWindow(1 2 3 4)
 325 pascal PaintRect(word word word word ptr) PaintRect(1 2 3 4 5)
@@ -83,5 +111,4 @@
 373 pascal SubtractRect(ptr ptr ptr) SubtractRect(1 2 3)
 403 pascal UnregisterClass(ptr word) UnregisterClass(1 2)
 411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4)
-177 pascal LoadAccelerators(word ptr) LoadAccelerators(1 2)
 421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3)
diff --git a/include/class.h b/include/class.h
index f2cc80a..9ab50e4 100644
--- a/include/class.h
+++ b/include/class.h
@@ -17,7 +17,7 @@
     HCLASS       hNext;         /* Next class */
     WORD         wMagic;        /* Magic number (must be CLASS_MAGIC) */
     ATOM         atomName;      /* Name of the class */
-    HANDLE       hDCE;          /* Class DC Entry (if CS_CLASSDC) */
+    HDC          hdc;           /* Class DC (if CS_CLASSDC) */
     WORD         cWindows;      /* Count of existing windows of this class */
     WNDCLASS     wc __attribute__ ((packed));  /* Class information */
     WORD         wExtra[1];     /* Class extra bytes */
diff --git a/include/segmem.h b/include/segmem.h
index 5775cdc..6c4f7c5 100644
--- a/include/segmem.h
+++ b/include/segmem.h
@@ -32,4 +32,11 @@
 #define GLOBAL_FLAGS_EXECUTEONLY	0x00020000
 #define GLOBAL_FLAGS_READONLY		0x00020000
 
+#define FIRST_SELECTOR	8
+
+static __inline__ int Is16bitAddress(void *address)
+{
+    return ((int) address >= (((FIRST_SELECTOR << 3) | 0x0007) << 16));
+}
+
 #endif /* SEGMEM_H */
diff --git a/include/win.h b/include/win.h
index 5c7c235..894da98 100644
--- a/include/win.h
+++ b/include/win.h
@@ -32,9 +32,11 @@
     HWND         hwndLastActive; /* Last active popup hwnd */
     FARPROC      lpfnWndProc;    /* Window procedure */
     DWORD        dwStyle;        /* Window style (from CreateWindow) */
-    HANDLE       hDCE;           /* Window DC Entry (if CS_OWNDC) */
+    DWORD        dwExStyle;      /* Extended style (from CreateWindowEx) */
+    HDC          hdc;            /* Window DC (if CS_OWNDC) */
     HMENU        hmenuSystem;    /* System menu */
     WORD         wIDmenu;        /* ID or hmenu (from CreateWindow) */
+    HANDLE       hText;          /* Handle of window text */
     WORD         flags;          /* Misc. flags */
     Widget       shellWidget;    /* For top-level windows */
     Widget       winWidget;      /* For all windows */
@@ -47,10 +49,9 @@
 #define WIN_ERASE_UPDATERGN       1   /* Update region needs erasing */
 
 
- /* The caller must GlobalUnlock the pointer returned 
-  * by this function (except when NULL).
-  */
+  /* Window functions */
 WND * WIN_FindWndPtr( HWND hwnd );
+HWND WIN_FindWinToRepaint( HWND hwnd );
 
 
 #endif  /* WIN_H */
diff --git a/include/windows.h b/include/windows.h
index 278770b..9c8e0d2 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -105,7 +105,7 @@
 #define GCW_STYLE           (-26)
 #define GCW_ATOM            (-32)
 
-
+  /* Windows */
 
 typedef struct {
     void *    lpCreateParams;
@@ -122,6 +122,17 @@
     DWORD     dwExStyle __attribute__ ((packed));
 } CREATESTRUCT, *LPCREATESTRUCT;
 
+  /* Offsets for GetWindowLong() and GetWindowWord() */
+#define GWL_EXSTYLE         (-20)
+#define GWL_STYLE           (-16)
+#define GWW_ID              (-12)
+#define GWW_HWNDPARENT      (-8)
+#define GWW_HINSTANCE       (-6)
+#define GWL_WNDPROC         (-4)
+#define DWL_MSGRESULT	    0
+#define DWL_DLGPROC	    4
+#define DWL_USER	    8
+
 
 typedef struct { short x, y; } POINT;
 typedef POINT *PPOINT;
@@ -134,6 +145,7 @@
     short cy;
 } SIZE, *LPSIZE;
 
+#define MAKEPOINT(l) (*((POINT *)&(l)))
 
 typedef struct tagMSG
 {
@@ -1452,7 +1464,7 @@
 Fc(void,OemToAnsiBuff,LPSTR,a,LPSTR,b,int,c)
 Fc(void,OffsetRect,LPRECT,a,short,b,short,c)
 Fc(void,SetDlgItemText,HWND,a,int,b,LPSTR,c)
-Fc(void,SetSysColors,int,a,LPINT,b,LONG*,c)
+Fc(void,SetSysColors,int,a,LPINT,b,COLORREF*,c)
 Fc(void,ShowScrollBar,HWND,a,WORD,b,BOOL,c)
 Fc(void,SwitchStackTo,WORD,a,WORD,b,WORD,c)
 Fd(BOOL,AppendMenu,HMENU,a,WORD,b,WORD,c,LPSTR,d)
diff --git a/include/wine.h b/include/wine.h
index 621fcdb..afe11d6 100644
--- a/include/wine.h
+++ b/include/wine.h
@@ -15,8 +15,12 @@
   char * lookup_table;
   char * nrname_table;
   char * rname_table;
+  unsigned short hinstance;
 };
 
 extern struct  w_files * wine_files;
 
+extern char *GetFilenameFromInstance(unsigned short instance);
+extern struct w_files *GetFileInfo(unsigned short instance);
+
 #endif
diff --git a/loader/resource.c b/loader/resource.c
index 4a3c60e..fcc1af3 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -3,12 +3,47 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "prototypes.h"
 #include "neexe.h"
 #include "windows.h"
 #include "gdi.h"
+#include "wine.h"
 
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
+
+static int ResourceFd = -1;
+static HANDLE ResourceInst = 0;
+static struct w_files *ResourceFileInfo = NULL;
+
+
+/**********************************************************************
+ *					OpenResourceFile
+ */
+int
+OpenResourceFile(HANDLE instance)
+{
+    struct w_files *w;
+    
+    if (ResourceInst == instance)
+	return ResourceFd;
+    
+    w = GetFileInfo(instance);
+    if (w == NULL)
+	return -1;
+    
+    if (ResourceFd >= 0)
+	close(ResourceFd);
+    
+    ResourceInst = instance;
+    ResourceFileInfo = w;
+    ResourceFd = open(w->filename, O_RDONLY);
+    
+    return ResourceFd;
+}
 
 /**********************************************************************
  *					ConvertCoreBitmap
@@ -88,17 +123,19 @@
     struct resource_nameinfo_s nameinfo;
     unsigned short size_shift;
     int i;
+    off_t rtoff;
 
     /*
      * Move to beginning of resource table.
      */
-    lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
-			  CurrentNEHeader->resource_tab_offset), SEEK_SET);
+    rtoff = (ResourceFileInfo->mz_header->ne_offset +
+	     ResourceFileInfo->ne_header->resource_tab_offset);
+    lseek(ResourceFd, rtoff, SEEK_SET);
     
     /*
      * Read block size.
      */
-    if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) != 
+    if (read(ResourceFd, &size_shift, sizeof(size_shift)) != 
 	sizeof(size_shift))
     {
 	return -1;
@@ -110,7 +147,7 @@
     typeinfo.type_id = 0xffff;
     while (typeinfo.type_id != 0)
     {
-	if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
+	if (read(ResourceFd, &typeinfo, sizeof(typeinfo)) !=
 	    sizeof(typeinfo))
 	{
 	    return -1;
@@ -119,7 +156,7 @@
 	{
 	    for (i = 0; i < typeinfo.count; i++)
 	    {
-		if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) != 
+		if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) != 
 		    sizeof(nameinfo))
 		{
 		    return -1;
@@ -159,17 +196,19 @@
     unsigned char nbytes;
     char name[256];
     int i;
+    off_t rtoff;
 
     /*
      * Move to beginning of resource table.
      */
-    lseek(CurrentNEFile, (CurrentMZHeader->ne_offset +
-			  CurrentNEHeader->resource_tab_offset), SEEK_SET);
+    rtoff = (ResourceFileInfo->mz_header->ne_offset +
+	     ResourceFileInfo->ne_header->resource_tab_offset);
+    lseek(ResourceFd, rtoff, SEEK_SET);
     
     /*
      * Read block size.
      */
-    if (read(CurrentNEFile, &size_shift, sizeof(size_shift)) != 
+    if (read(ResourceFd, &size_shift, sizeof(size_shift)) != 
 	sizeof(size_shift))
     {
 	return -1;
@@ -181,7 +220,7 @@
     typeinfo.type_id = 0xffff;
     while (typeinfo.type_id != 0)
     {
-	if (read(CurrentNEFile, &typeinfo, sizeof(typeinfo)) !=
+	if (read(ResourceFd, &typeinfo, sizeof(typeinfo)) !=
 	    sizeof(typeinfo))
 	{
 	    return -1;
@@ -190,7 +229,7 @@
 	{
 	    for (i = 0; i < typeinfo.count; i++)
 	    {
-		if (read(CurrentNEFile, &nameinfo, sizeof(nameinfo)) != 
+		if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) != 
 		    sizeof(nameinfo))
 		{
 		    return -1;
@@ -199,14 +238,12 @@
 		if (nameinfo.id & 0x8000)
 		    continue;
 		
-		old_pos = lseek(CurrentNEFile, 0, SEEK_CUR);
-		new_pos = (CurrentMZHeader->ne_offset +
-			   CurrentNEHeader->resource_tab_offset +
-			   nameinfo.id);
-		lseek(CurrentNEFile, new_pos, SEEK_SET);
-		read(CurrentNEFile, &nbytes, 1);
-		read(CurrentNEFile, name, nbytes);
-		lseek(CurrentNEFile, old_pos, SEEK_SET);
+		old_pos = lseek(ResourceFd, 0, SEEK_CUR);
+		new_pos = rtoff + nameinfo.id;
+		lseek(ResourceFd, new_pos, SEEK_SET);
+		read(ResourceFd, &nbytes, 1);
+		read(ResourceFd, name, nbytes);
+		lseek(ResourceFd, old_pos, SEEK_SET);
 		name[nbytes] = '\0';
 
 		if (strcasecmp(name, resource_name) == 0)
@@ -222,53 +259,6 @@
 }
 
 /**********************************************************************
- *					LoadString
- */
-int
-LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
-{
-    struct resource_nameinfo_s nameinfo;
-    unsigned short target_id;
-    unsigned char string_length;
-    int size_shift;
-    int string_num;
-    int i;
-
-#ifdef DEBUG_RESOURCE
-    printf("LoadString: instance = %04x, id = %d, "
-	   "buffer = %08x, length = %d\n",
-	   instance, resource_id, buffer, buflen);
-#endif
-    
-    /*
-     * Find string entry.
-     */
-    target_id = (resource_id >> 4) + 0x8001;
-    string_num = resource_id & 0x000f;
-
-    size_shift = FindResourceByNumber(&nameinfo, NE_RSCTYPE_STRING, target_id);
-    if (size_shift == -1)
-	return 0;
-    
-    lseek(CurrentNEFile, (int) nameinfo.offset << size_shift, SEEK_SET);
-
-    for (i = 0; i < string_num; i++)
-    {
-	read(CurrentNEFile, &string_length, 1);
-	lseek(CurrentNEFile, string_length, SEEK_CUR);
-    }
-			
-    read(CurrentNEFile, &string_length, 1);
-    i = MIN(string_length, buflen - 1);
-    read(CurrentNEFile, buffer, i);
-    buffer[i] = '\0';
-#ifdef DEBUG_RESOURCE
-    printf("            '%s'\n", buffer);
-#endif
-    return i;
-}
-
-/**********************************************************************
  *					LoadIcon
  */
 HICON
@@ -297,6 +287,43 @@
   fprintf(stderr,"LoadAccelerators: (%d),%d\n",instance,lpTableName);
     return 0;
 }
+
+/**********************************************************************
+ *				FindResource	[KERNEL.60]
+ */
+HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name)
+{
+    fprintf(stderr,"FindResource: (%d),%d\n",instance, resource_name, type_name);
+    return 0;
+}
+
+/**********************************************************************
+ *				LoadResource	[KERNEL.61]
+ */
+HANDLE LoadResource(HANDLE instance, HANDLE hResInfo)
+{
+    fprintf(stderr,"LoadResource: (%d),%d\n",instance, hResInfo);
+    return ;
+}
+
+/**********************************************************************
+ *				LockResource	[KERNEL.62]
+ */
+LPSTR LockResource(HANDLE hResData)
+{
+    fprintf(stderr,"LockResource: %d\n", hResData);
+    return ;
+}
+
+/**********************************************************************
+ *				FreeResource	[KERNEL.63]
+ */
+BOOL FreeResource(HANDLE hResData)
+{
+    fprintf(stderr,"FreeResource: %d\n", hResData);
+    return ;
+}
+
 
 /**********************************************************************
  *					RSC_LoadResource
@@ -317,10 +344,13 @@
     {
 	return 0;
     }
+    else if (OpenResourceFile(instance) < 0)
+	return 0;
+    
     /*
      * Get resource by ordinal
      */
-    else if (((int) rsc_name & 0xffff0000) == 0)
+    if (((int) rsc_name & 0xffff0000) == 0)
     {
 	size_shift = FindResourceByNumber(&nameinfo, type,
 					  (int) rsc_name | 0x8000);
@@ -338,7 +368,7 @@
     /*
      * Read resource.
      */
-    lseek(CurrentNEFile, ((int) nameinfo.offset << size_shift), SEEK_SET);
+    lseek(ResourceFd, ((int) nameinfo.offset << size_shift), SEEK_SET);
 
     image_size = nameinfo.length << size_shift;
     if (image_size_ret != NULL)
@@ -346,7 +376,7 @@
     
     hmem = GlobalAlloc(GMEM_MOVEABLE, image_size);
     image = GlobalLock(hmem);
-    if (image == NULL || read(CurrentNEFile, image, image_size) != image_size)
+    if (image == NULL || read(ResourceFd, image, image_size) != image_size)
     {
 	GlobalFree(hmem);
 	return 0;
@@ -357,6 +387,46 @@
 }
 
 /**********************************************************************
+ *					LoadString
+ */
+int
+LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
+{
+    HANDLE hmem;
+    int rsc_size;
+    unsigned char *p;
+    int string_num;
+    int i;
+
+#ifdef DEBUG_RESOURCE
+    printf("LoadString: instance = %04x, id = %d, "
+	   "buffer = %08x, length = %d\n",
+	   instance, resource_id, buffer, buflen);
+#endif
+
+    hmem = RSC_LoadResource(instance, (char *) (resource_id >> 4),
+			    NE_RSCTYPE_STRING, &rsc_size);
+    if (hmem == 0)
+	return 0;
+    
+    p = GlobalLock(hmem);
+    string_num = resource_id & 0x000f;
+    for (i = 0; i < resource_id; i++)
+	p += *p;
+    
+    i = MIN(buflen - 1, *p);
+    memcpy(buffer, p + 1, i);
+    buffer[i] = '\0';
+
+    GlobalFree(hmem);
+
+#ifdef DEBUG_RESOURCE
+    printf("            '%s'\n", buffer);
+#endif
+    return i;
+}
+
+/**********************************************************************
  *					RSC_LoadMenu
  */
 HANDLE
@@ -403,3 +473,5 @@
     ReleaseDC( 0, hdc );
     return hbitmap;
 }
+
+
diff --git a/loader/selector.c b/loader/selector.c
index 4ecb448..489dfd6 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -47,7 +47,7 @@
 unsigned char ran_out = 0;
 unsigned short SelectorOwners[MAX_SELECTORS];
 
-static int next_unused_selector = 8;
+static int next_unused_selector = FIRST_SELECTOR;
 extern void KERNEL_Ordinal_102();
 extern void UNIXLIB_Ordinal_0();
 
diff --git a/loader/signal.c b/loader/signal.c
index 39f4080..a240104 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -6,9 +6,15 @@
 #include <syscall.h>
 #include <signal.h>
 #include <errno.h>
+#ifdef linux
 #include <linux/sched.h>
 #include <asm/system.h>
+#endif
  
+char * cstack[4096];
+struct sigaction segv_act;
+
+#ifdef linux
 extern void ___sig_restore();
 extern void ___masksig_restore();
 
@@ -26,33 +32,36 @@
 	return -1;
 }
 
-char * cstack[4096];
-struct sigaction segv_act;
-
 struct sigcontext_struct {
-	unsigned short gs, __gsh;
-	unsigned short fs, __fsh;
-	unsigned short es, __esh;
-	unsigned short ds, __dsh;
-	unsigned long edi;
-	unsigned long esi;
-	unsigned long ebp;
-	unsigned long esp;
-	unsigned long ebx;
-	unsigned long edx;
-	unsigned long ecx;
-	unsigned long eax;
-	unsigned long trapno;
-	unsigned long err;
-	unsigned long eip;
-	unsigned short cs, __csh;
-	unsigned long eflags;
+	unsigned short sc_gs, __gsh;
+	unsigned short sc_fs, __fsh;
+	unsigned short sc_es, __esh;
+	unsigned short sc_ds, __dsh;
+	unsigned long sc_edi;
+	unsigned long sc_esi;
+	unsigned long sc_ebp;
+	unsigned long sc_esp;
+	unsigned long sc_ebx;
+	unsigned long sc_edx;
+	unsigned long sc_ecx;
+	unsigned long sc_eax;
+	unsigned long sc_trapno;
+	unsigned long sc_err;
+	unsigned long sc_eip;
+	unsigned short sc_cs, __csh;
+	unsigned long sc_eflags;
 	unsigned long esp_at_signal;
-	unsigned short ss, __ssh;
+	unsigned short sc_ss, __ssh;
 	unsigned long i387;
 	unsigned long oldmask;
 	unsigned long cr2;
 };
+#endif
+
+#ifdef __NetBSD__
+#define sigcontext_struct sigcontext
+#define HZ 100
+#endif
 
 static void
 GetTimeDate(int time_flag, struct sigcontext_struct * context)
@@ -64,15 +73,15 @@
     now = localtime(&ltime);
     if (time_flag)
     {
-	 context->ecx = (now->tm_hour << 8) | now->tm_min;
-	 context->edx = now->tm_sec << 8;
+	 context->sc_ecx = (now->tm_hour << 8) | now->tm_min;
+	 context->sc_edx = now->tm_sec << 8;
     }
     else
     {
-	context->ecx = now->tm_year + 1900;
-	context->edx = ((now->tm_mon + 1) << 8) | now->tm_mday;
-	context->eax &= 0xff00;
-	context->eax |= now->tm_wday;
+	context->sc_ecx = now->tm_year + 1900;
+	context->sc_edx = ((now->tm_mon + 1) << 8) | now->tm_mday;
+	context->sc_eax &= 0xff00;
+	context->sc_eax |= now->tm_wday;
     }
 }
 
@@ -82,12 +91,12 @@
 
 static int
 do_int21(struct sigcontext_struct * context){
-	fprintf(stderr,"Doing int21 %x   ", (context->eax >> 8) & 0xff);
-	switch((context->eax >> 8) & 0xff){
+	fprintf(stderr,"Doing int21 %x   ", (context->sc_eax >> 8) & 0xff);
+	switch((context->sc_eax >> 8) & 0xff){
 	case 0x30:
-		context->eax = 0x0303;  /* Hey folks, this is DOS V3.3! */
-		context->ebx = 0;
-		context->ecx = 0;
+		context->sc_eax = 0x0303;  /* Hey folks, this is DOS V3.3! */
+		context->sc_ebx = 0;
+		context->sc_ecx = 0;
 		break;
 	
 		/* Ignore any attempt to set a segment vector */
@@ -96,8 +105,8 @@
 
 	case 0x35:  /* Return a NULL segment selector - this will bomb
 		       if anyone ever tries to use it */
-		context->es = 0;
-		context->ebx = 0;
+		context->sc_es = 0;
+		context->sc_ebx = 0;
 		break;
 		
 	case 0x2a:
@@ -109,11 +118,11 @@
 		/* Function does not return */
 
 	case 0x4c:
-		exit(context->eax & 0xff);
+		exit(context->sc_eax & 0xff);
 		
 
 	default:
-		fprintf(stderr,"Unable to handle int 0x21 %x\n", context->eax);
+		fprintf(stderr,"Unable to handle int 0x21 %x\n", context->sc_eax);
 		return 1;
 	};
 	return 1;
@@ -124,41 +133,53 @@
 	time_t ltime;
 	int ticks;
 
-	switch((context->eax >> 8) & 0xff){
+	switch((context->sc_eax >> 8) & 0xff){
 	case 0:
 		ltime = time(NULL);
 		ticks = (int) (ltime * HZ);
-		context->ecx = ticks >> 16;
-		context->edx = ticks & 0x0000FFFF;
-		context->eax = 0;  /* No midnight rollover */
+		context->sc_ecx = ticks >> 16;
+		context->sc_edx = ticks & 0x0000FFFF;
+		context->sc_eax = 0;  /* No midnight rollover */
 		break;
 	
 	default:
-		fprintf(stderr,"Unable to handle int 0x1A %x\n", context->eax);
+		fprintf(stderr,"Unable to handle int 0x1A %x\n", context->sc_eax);
 		return 1;
 	};
 	return 1;
 }
 
-static void win_segfault(int signal, struct sigcontext_struct context){
+#ifdef linux
+static void win_fault(int signal, struct sigcontext_struct context){
+        struct sigcontext_struct *scp = &context;
+#else
+static void win_fault(int signal, int code, struct sigcontext *scp){
+#endif
 	unsigned char * instr;
 	unsigned char intno;
 	unsigned int * dump;
 	int i;
 
 	/* First take care of a few preliminaries */
+#ifdef linux
 	if(signal != SIGSEGV) exit(1);
-	if((context.cs & 7) != 7){
+	if((scp->sc_cs & 7) != 7){
+#endif
+#ifdef __NetBSD__
+/*         set_es(0x27); set_ds(0x27); */
+	if(signal != SIGBUS) exit(1);
+	if(scp->sc_cs == 0x1f){
+#endif
 		fprintf(stderr,
 			"Segmentation fault in Wine program (%x:%x)."
 			"  Please debug\n",
-			context.cs, context.eip);
+			scp->sc_cs, scp->sc_eip);
 		goto oops;
 	};
 
 	/*  Now take a look at the actual instruction where the program
 	    bombed */
-	instr = (char *) ((context.cs << 16) | (context.eip & 0xffff));
+	instr = (char *) ((scp->sc_cs << 16) | (scp->sc_eip & 0xffff));
 
 	if(*instr != 0xcd) {
 		fprintf(stderr,
@@ -175,10 +196,10 @@
 	intno = *instr;
 	switch(intno){
 	case 0x21:
-		if(!do_int21(&context)) goto oops;
+		if(!do_int21(scp)) goto oops;
 		break;
 	case 0x1A:
-		if(!do_int1A(&context)) goto oops;
+		if(!do_int1A(scp)) goto oops;
 		break;
 	default:
 		fprintf(stderr,"Unexpected Windows interrupt %x\n", intno);
@@ -187,13 +208,16 @@
 
 	/* OK, done handling the interrupt */
 
-	context.eip += 2;  /* Bypass the int instruction */
+	scp->sc_eip += 2;  /* Bypass the int instruction */
 	return;
 
  oops:
-	fprintf(stderr,"In win_segfault %x:%x\n", context.cs, context.eip);
-	fprintf(stderr,"Stack: %x:%x\n", context.ss, context.esp_at_signal);
-	dump = (int*) &context;
+	fprintf(stderr,"In win_fault %x:%x\n", scp->sc_cs, scp->sc_eip);
+#ifdef linux
+	wine_debug(scp);  /* Enter our debugger */
+#else
+	fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
+	dump = (int*) scp;
 	for(i=0; i<22; i++) 
 	{
 	    fprintf(stderr," %8.8x", *dump++);
@@ -202,15 +226,37 @@
 	}
 	fprintf(stderr,"\n");
 	exit(1);
+#endif
 }
 
 int
 init_wine_signals(){
-	segv_act.sa_handler = (__sighandler_t) win_segfault;
+#ifdef linux
+	segv_act.sa_handler = (__sighandler_t) win_fault;
 	/* Point to the top of the stack, minus 4 just in case, and make
 	   it aligned  */
 	segv_act.sa_restorer = 
 		(void (*)()) (((unsigned int)(cstack + sizeof(cstack) - 4)) & ~3);
 	wine_sigaction(SIGSEGV, &segv_act, NULL);
+#endif
+#ifdef __NetBSD__
+        struct sigstack ss;
+        sigset_t sig_mask;
+        
+        ss.ss_sp = (char *) (((unsigned int)(cstack + sizeof(cstack) - 4)) & ~3);
+        ss.ss_onstack = 0;
+        if (sigstack(&ss, NULL) < 0) {
+                perror("sigstack");
+                exit(1);
+        }
+        sigemptyset(&sig_mask);
+        segv_act.sa_handler = (__sighandler_t) win_fault;
+	segv_act.sa_flags = SA_ONSTACK;
+        segv_act.sa_mask = sig_mask;
+	if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
+                perror("sigaction");
+                exit(1);
+        }
+#endif
 }
 
diff --git a/loader/wine.c b/loader/wine.c
index ad26824..1cd77a0 100644
--- a/loader/wine.c
+++ b/loader/wine.c
@@ -63,8 +63,38 @@
     exit(1);
 }
 
+/**********************************************************************
+ *					GetFilenameFromInstance
+ */
+char *
+GetFilenameFromInstance(unsigned short instance)
+{
+    register struct w_files *w = wine_files;
 
-/* Load one NE format executable into memory */
+    while (w && w->hinstance != instance)
+	w = w->next;
+    
+    if (w)
+	return w->filename;
+    else
+	return NULL;
+}
+
+struct w_files *
+GetFileInfo(unsigned short instance)
+{
+    register struct w_files *w = wine_files;
+
+    while (w && w->hinstance != instance)
+	w = w->next;
+    
+    return w;
+}
+
+/**********************************************************************
+ *					LoadImage
+ * Load one NE format executable into memory
+ */
 LoadImage(char * filename,  char * modulename)
 {
     unsigned int read_size;
@@ -143,6 +173,9 @@
     if (read(wpnt->fd, wpnt->seg_table, read_size) != read_size)
 	myerror("Unable to read segment table header from file");
     wpnt->selector_table = CreateSelectors(wpnt);
+    wpnt->hinstance 
+	= wpnt->
+	    selector_table[wine_files->ne_header->auto_data_seg-1].selector;
 
     /* Get the lookup  table.  This is used for looking up the addresses
        of functions that are exported */
diff --git a/misc/Makefile b/misc/Makefile
index faeeeb6..0d5fa81 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -1,7 +1,7 @@
 CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
 
 OBJS=dos.o kernel.o user.o xt.o rect.o file.o sound.o emulate.o \
-     keyboard.o profile.o
+     keyboard.o profile.o lstr.o
 
 default: misc.o
 
diff --git a/misc/file.c b/misc/file.c
index 2a1388a..559fac0 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -25,6 +25,8 @@
 #include <string.h>
 #include <limits.h>
 
+#define OPEN_MAX 256
+
 /***************************************************************************
  This structure stores the infomation needed for a single DOS drive
  ***************************************************************************/
diff --git a/misc/keyboard.c b/misc/keyboard.c
index b01b69f..cc4b017 100644
--- a/misc/keyboard.c
+++ b/misc/keyboard.c
@@ -11,6 +11,8 @@
   return -1;
 }
 
+#ifdef  BOGUS_ANSI_OEM
+
 int AnsiToOem(LPSTR lpAnsiStr, LPSTR lpOemStr)
 {
   printf("AnsiToOem (%s)\n",lpAnsiStr);
@@ -25,6 +27,8 @@
   return -1;
 }
 
+#endif
+
 DWORD OemKeyScan(WORD wOemChar)
 {
   printf("*OemKeyScan (%d)\n",wOemChar);
@@ -84,6 +88,8 @@
   return 0;
 }
 
+#ifdef  BOGUS_ANSI_OEM
+
 void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, int nLength)
 {
   printf("AnsiToOemBuff(%s,<ptr>,%d)\n",lpAnsiStr,nLength);
@@ -96,6 +102,7 @@
   strncpy(lpAnsiStr,lpOemStr,nLength);  /* should translate... */
 }
 
+#endif
 
 
 
diff --git a/misc/lstr.c b/misc/lstr.c
new file mode 100644
index 0000000..7bf2250
--- /dev/null
+++ b/misc/lstr.c
@@ -0,0 +1,213 @@
+static char Copyright[] = "Copyright  Yngvi Sigurjonsson (yngvi@hafro.is), 1993";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "prototypes.h"
+#include "regfunc.h"
+#include "windows.h"
+
+
+#define LPCSTR LPSTR  /* I think this should be const char **/
+typedef  unsigned short UINT;
+
+  /* Funny to divide them between user and kernel. */
+
+/* KERNEL.89 */
+LPSTR lstrcat(LPSTR target,LPCSTR source)
+{
+  fprintf(stderr,"lstrcat(%s,%s)\n",target,source);
+  return strcat(target,source);
+}
+
+/* USER.430 */
+int lstrcmp(LPCSTR str1,LPCSTR str2)
+{
+  return strcmp(str1,str2);
+}
+
+/* USER.471 */
+int lstrcmpi(LPCSTR str1,LPCSTR str2)
+{
+  int i;
+  i=0;
+  while((toupper(str1[i])==toupper(str2[i]))&&(str1[i]!=0))
+    i++;
+  return toupper(str1[i])-toupper(str2[i]);
+}
+
+/* KERNEL.88 */
+LPSTR lstrcpy(LPSTR target,LPCSTR source)
+{
+  return strcpy(target,source);
+}
+
+/* KERNEL.353 */
+LPSTR lstrcpyn(LPSTR target,LPCSTR source,int n)
+{
+  return strncpy(target,source,n);
+}
+
+/* KERNEL.90 */
+int lstrlen(LPCSTR str)
+{
+  strlen(str);
+}
+
+/* AnsiUpper USER.431 */
+char FAR* AnsiUpper(char FAR* strOrChar)
+{
+  /* I am not sure if the locale stuff works with toupper, but then again 
+     I am not sure if the Linux libc locale stuffs works at all */
+  if((int)strOrChar<256)
+    return (char FAR*) toupper((int)strOrChar);
+  else {
+    int i;
+    for(i=0;(i<65536)&&strOrChar[i];i++)
+      strOrChar[i]=toupper(strOrChar[i]);
+    return strOrChar;	
+  }
+}
+
+/* AnsiLower USER.432 */
+char FAR* AnsiLower(char FAR* strOrChar)
+{
+  /* I am not sure if the locale stuff works with tolower, but then again 
+     I am not sure if the Linux libc locale stuffs works at all */
+  if((int)strOrChar<256)
+    return (char FAR*)tolower((int)strOrChar);
+  else {
+    int i;
+    for(i=0;(i<65536)&&strOrChar[i];i++)
+      strOrChar[i]=tolower(strOrChar[i]);
+    return strOrChar;	
+  }
+}
+
+/* AnsiUpperBuff USER.437 */
+UINT AnsiUpperBuff(LPSTR str,UINT len)
+{
+  int i;
+  len=(len==0)?65536:len;
+
+  for(i=0;i<len;i++)
+    str[i]=toupper(str[i]);
+  return i;	
+}
+
+/* AnsiLowerBuff USER.438 */
+UINT AnsiLowerBuff(LPSTR str,UINT len)
+{
+  int i;
+  len=(len==0)?65536:len;
+  i=0;
+
+  for(i=0;i<len;i++)
+    str[i]=tolower(str[i]);
+ 
+  return i;	
+}
+
+/* AnsiNext USER.472 */
+LPSTR AnsiNext(LPCSTR current)
+{
+  return (*current)?current+1:current;
+}
+
+/* AnsiPrev USER.473 */
+char FAR*  AnsiPrev(/*const*/ char FAR* start,char FAR* current)
+{
+  return (current==start)?start:current-1;
+}
+
+/* IsCharAlpha USER 433 */
+BOOL IsCharAlpha(char ch)
+{
+  return isalpha(ch);   /* This is probably not right for NLS */
+}
+/* IsCharAlphanumeric USER 434 */
+BOOL IsCharAlphanumeric(char ch)
+{
+  return (ch<'0')?0:(ch<'9');
+}
+
+/* IsCharUpper USER 435 */
+BOOL IsCharUpper(char ch)
+{
+  return isupper(ch);
+}
+
+/* IsCharUpper USER 436 */
+BOOL IsCharLower(char ch)
+{
+  return islower(ch);
+}
+
+static char Oem2Ansi[256];
+static char Ansi2Oem[256];
+
+void InitOemAnsiTranslations()
+{
+  static int inited=0; /* should called called in some init function*/
+  int transfile,i;
+  if(inited) return;
+  if(transfile=open("oem2ansi.trl",O_RDONLY)){
+    read(transfile,Oem2Ansi,256);
+    close(transfile);
+  }
+  else {  /* sets up passive translations if it does not find the file */
+    for(i=0;i<256;i++)  /* Needs some fixing */
+      Oem2Ansi[i]=i;  
+  }
+  if(transfile=open("ansi2oem.trl",O_RDONLY)){
+    read(transfile,Ansi2Oem,256);
+    close(transfile);
+  }
+  else {  /* sets up passive translations if it does not find the file */
+    for(i=0;i<256;i++)  /* Needs some fixing */
+      Ansi2Oem[i]=i;  
+  }
+  inited=1;
+}
+
+/* AnsiToOem Keyboard.5 */
+int AnsiToOem(LPSTR lpAnsiStr, LPSTR lpOemStr)   /* why is this int ??? */
+{
+  InitOemAnsiTranslations(); /* should called called in some init function*/
+  while(*lpAnsiStr){
+    *lpOemStr++=Ansi2Oem[*lpAnsiStr++];
+  }
+  return -1;
+}
+
+/* OemToAnsi Keyboard.6 */
+BOOL OemToAnsi(LPSTR lpOemStr, LPSTR lpAnsiStr)   /* why is this BOOL ???? */
+{
+  InitOemAnsiTranslations(); /* should called called in some init function*/
+  while(*lpOemStr){
+    *lpAnsiStr++=Oem2Ansi[*lpOemStr++];
+  }
+  return -1;
+}
+
+/* AnsiToOemBuff Keyboard.134 */
+void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, int nLength)
+{
+  int i;
+  InitOemAnsiTranslations(); /* should called called in some init function*/
+  for(i=0;i<nLength;i++)
+    lpOemStr[i]=Ansi2Oem[lpAnsiStr[i]];  
+}
+
+/* OemToAnsi Keyboard.135 */
+void OemToAnsiBuff(LPSTR lpOemStr, LPSTR lpAnsiStr, int nLength)
+{
+  int i;
+  InitOemAnsiTranslations(); /* should called called in some init function*/
+  for(i=0;i<nLength;i++)
+    lpAnsiStr[i]=Oem2Ansi[lpOemStr[i]];
+}
diff --git a/misc/profile.c b/misc/profile.c
index 2924bd6..b38c6f8 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -1,40 +1,322 @@
-static char RCSId[] = "$Id: profile.c,v 1.1 1993/09/13 16:42:32 scott Exp $";
-static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+/*
+ * Initialization-File Functions.
+ *
+ * Copyright (c) 1993 Miguel de Icaza
+ *
+ */
 
-#include "prototypes.h"
+static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza";
+
+#include <stdio.h>
+#include <string.h>
 #include "windows.h"
 
+#define INIFILE "win.ini"
+#define STRSIZE 255
+#define xmalloc(x) malloc(x)
+#define overflow (next == &CharBuffer [STRSIZE-1])
 
-WORD GetPrivateProfileInt( LPSTR section, LPSTR entry,
-			   short defval, LPSTR filename )
+enum { FirstBrace, OnSecHeader, IgnoreToEOL, KeyDef, KeyValue };
+
+typedef struct TKeys {
+    char *KeyName;
+    char *Value;
+    struct TKeys *link;
+} TKeys;
+
+typedef struct TSecHeader {
+    char *AppName;
+    TKeys *Keys;
+    struct TSecHeader *link;
+} TSecHeader;
+    
+typedef struct TProfile {
+    char *FileName;
+    TSecHeader *Section;
+    struct TProfile *link;
+} TProfile;
+
+TProfile *Current = 0;
+TProfile *Base = 0;
+
+static TSecHeader *is_loaded (char *FileName)
 {
-    printf( "GetPrivateProfileInt: %s %s %d %s\n", section, entry, defval, filename );
-    return defval;
+    TProfile *p = Base;
+    
+    while (p){
+	if (!strcasecmp (FileName, p->FileName)){
+	    Current = p;
+	    return p->Section;
+	}
+	p = p->link;
+    }
+    return 0;
 }
 
-short GetPrivateProfileString( LPSTR section, LPSTR entry, LPSTR defval,
-			       LPSTR buffer, short count, LPSTR filename )
+static TSecHeader *load (char *file)
 {
-    printf( "GetPrivateProfileString: %s %s %s %d %s\n", section, entry, defval, count, filename );
-    strncpy( buffer, defval, count );
-    buffer[count-1] = 0;
-    return strlen(buffer);
+    FILE *f;
+    int state;
+    TSecHeader *SecHeader = 0;
+    char CharBuffer [STRSIZE];
+    char *next;
+    char c;
+    
+    if ((f = fopen (file, "r"))==NULL)
+	return NULL;
+
+    state = FirstBrace;
+    while ((c = getc (f)) != EOF){
+	if (c == '\r')		/* Ignore Carriage Return */
+	    continue;
+	
+	switch (state){
+
+	case OnSecHeader:
+	    if (c == ']' || overflow){
+		*next = '\0';
+		next = CharBuffer;
+		SecHeader->AppName = strdup (CharBuffer);
+		state = IgnoreToEOL;
+	    } else
+		*next++ = c;
+	    break;
+
+	case IgnoreToEOL:
+	    if (c == '\n'){
+		state = KeyDef;
+		next = CharBuffer;
+	    }
+	    break;
+
+	case FirstBrace:
+	case KeyDef:
+	    if (c == '['){
+		TSecHeader *temp;
+		
+		temp = SecHeader;
+		SecHeader = (TSecHeader *) xmalloc (sizeof (TSecHeader));
+		SecHeader->link = temp;
+		SecHeader->Keys = 0;
+		state = OnSecHeader;
+		next = CharBuffer;
+		break;
+	    }
+	    if (state == FirstBrace) /* On first pass, don't allow dangling keys */
+		break;
+	    
+	    if (c == ' ' || c == '\t')
+		break;
+	    
+	    if (c == '\n' || overflow) /* Abort Definition */
+		next = CharBuffer;
+	    
+	    if (c == '=' || overflow){
+		TKeys *temp;
+
+		temp = SecHeader->Keys;
+		*next = '\0';
+		SecHeader->Keys = (TKeys *) xmalloc (sizeof (TKeys));
+		SecHeader->Keys->link = temp;
+		SecHeader->Keys->KeyName = strdup (CharBuffer);
+		state = KeyValue;
+		next = CharBuffer;
+	    } else
+		*next++ = c;
+	    break;
+
+	case KeyValue:
+	    if (overflow || c == '\n'){
+		*next = '\0';
+		SecHeader->Keys->Value = strdup (CharBuffer);
+		state = c == '\n' ? KeyDef : IgnoreToEOL;
+		next = CharBuffer;
+#ifdef DEBUG
+		printf ("[%s] (%s)=%s\n", SecHeader->AppName,
+			SecHeader->Keys->KeyName, SecHeader->Keys->Value);
+#endif
+	    } else
+		*next++ = c;
+	    break;
+	    
+	} /* switch */
+	
+    } /* while ((c = getc (f)) != EOF) */
+    return SecHeader;
 }
 
-
-WORD GetProfileInt( LPSTR lpAppName, LPSTR lpKeyName, int nDefault)
+static new_key (TSecHeader *section, char *KeyName, char *Value)
 {
-  printf("GetProfileInt: %s %s %d\n",lpAppName,lpKeyName,nDefault);
-  return nDefault;
+    TKeys *key;
+    
+    key = (TKeys *) xmalloc (sizeof (TKeys));
+    key->KeyName = strdup (KeyName);
+    key->Value   = strdup (Value);
+    key->link = section->Keys;
+    section->Keys = key;
 }
 
-int GetProfileString(LPSTR lpAppName, LPSTR lpKeyName, LPSTR lpDefault,
-		       LPSTR lpReturnedString, int nSize)
-{
-    printf( "GetProfileString: %s %s %s %d \n", lpAppName,lpKeyName,
-	                                          lpDefault, nSize );
-    strncpy( lpReturnedString,lpDefault,nSize );
-    lpReturnedString[nSize-1] = 0;
-    return strlen(lpReturnedString);
+static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName,
+		     LPSTR Default, LPSTR ReturnedString, short Size,
+		     LPSTR FileName)
 
+{
+    TProfile   *New;
+    TSecHeader *section;
+    TKeys      *key;
+    
+    if (!(section = is_loaded (FileName))){
+	New = (TProfile *) xmalloc (sizeof (TProfile));
+	New->link = Base;
+	New->FileName = strdup (FileName);
+	New->Section = load (FileName);
+	Base = New;
+	section = New->Section;
+	Current = New;
+    }
+    
+    /* Start search */
+    for (; section; section = section->link){
+	if (strcasecmp (section->AppName, AppName))
+	    continue;
+	for (key = section->Keys; key; key = key->link){
+	    if (strcasecmp (key->KeyName, KeyName))
+		continue;
+	    if (set){
+		free (key->Value);
+		key->Value = strdup (Default);
+		return 1;
+	    }
+	    ReturnedString [Size-1] = 0;
+	    strncpy (ReturnedString, key->Value, Size-1);
+	    return 1;
+	}
+	/* If Getting the information, then don't write the information
+	   to the INI file, need to run a couple of tests with windog */
+	/* No key found */
+	if (set)
+	    new_key (section, KeyName, Default);
+        else {
+            ReturnedString [Size-1] = 0;
+            strncpy (ReturnedString, Default, Size-1);
+	}
+	return 1;
+    }
+    /* Non existent section */
+    if (set){
+	section = (TSecHeader *) xmalloc (sizeof (TSecHeader));
+	section->AppName = strdup (AppName);
+	section->Keys = 0;
+	new_key (section, KeyName, Default);
+	section->link = Current->Section;
+	Current->Section = section;
+    } else {
+	ReturnedString [Size-1] = 0;
+	strncpy (ReturnedString, Default, Size-1);
+    }
+    return 1;
 }
+
+short GetPrivateProfileString (LPSTR AppName, LPSTR KeyName,
+			       LPSTR Default, LPSTR ReturnedString,
+			       short Size, LPSTR FileName)
+{
+    return (GetSetProfile (0, AppName, KeyName, Default, ReturnedString, Size, FileName));
+}
+
+int GetProfileString (LPSTR AppName, LPSTR KeyName, LPSTR Default, 
+		      LPSTR ReturnedString, int Size)
+{
+    return GetPrivateProfileString (AppName, KeyName, Default,
+				    ReturnedString, Size, INIFILE);
+}
+
+WORD GetPrivateProfileInt (LPSTR AppName, LPSTR KeyName, short Default,
+			   LPSTR File)
+{
+    static char IntBuf [5];
+    static char buf [5];
+
+    sprintf (buf, "%d", Default);
+    
+    /* Check the exact semantic with the SDK */
+    GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 5, File);
+    if (!strcasecmp (IntBuf, "true"))
+	return 1;
+    if (!strcasecmp (IntBuf, "yes"))
+	return 1;
+    return atoi (IntBuf);
+}
+
+WORD GetProfileInt (LPSTR AppName, LPSTR KeyName, int Default)
+{
+    return GetPrivateProfileInt (AppName, KeyName, Default, INIFILE);
+}
+
+BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String,
+				LPSTR FileName)
+{
+    return GetSetProfile (1, AppName, KeyName, String, "", 0, FileName);
+}
+
+BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String)
+{
+    return (WritePrivateProfileString (AppName, KeyName, String, INIFILE));
+}
+
+static void dump_keys (FILE *profile, TKeys *p)
+{
+    if (!p)
+	return;
+    dump_keys (profile, p->link);
+    fprintf (profile, "%s=%s\r\n", p->KeyName, p->Value);
+}
+
+static void dump_sections (FILE *profile, TSecHeader *p)
+{
+    if (!p)
+	return;
+    dump_sections (profile, p->link);
+    fprintf (profile, "\r\n[%s]\r\n", p->AppName);
+    dump_keys (profile, p->Keys);
+}
+
+static void dump_profile (TProfile *p)
+{
+    FILE *profile;
+    
+    if (!p)
+	return;
+    dump_profile (p->link);
+    if ((profile = fopen (p->FileName, "w")) != NULL){
+	dump_sections (profile, p->Section);
+	fclose (profile);
+    }
+}
+
+void sync_profiles ()
+{
+    dump_profile (Base);
+}
+
+#ifdef DUMBTEST
+main ()
+{
+    char r [100], app [100], key [100], valor [100];
+    
+    while (1){
+	printf ("Dame, Aplicacion, llave\n");
+	gets (app);
+	if (!app [0]){
+	    sync_profiles ();
+	    return;
+	}
+	gets (key);
+	gets (valor);
+	GetProfileString (app, key, "1No_Encontrado", r, sizeof (r));
+	printf ("(%d)\n", GetProfileInt (app, key, 5));
+	printf ("%s\n", r);
+	WriteProfileString (app, key, valor);
+    }
+}
+#endif
diff --git a/misc/rect.c b/misc/rect.c
index fb96fd6..4fd7be4 100644
--- a/misc/rect.c
+++ b/misc/rect.c
@@ -78,6 +78,8 @@
  */
 void InflateRect( LPRECT rect, short x, short y )
 {
+    rect->left   -= x;
+    rect->top 	 -= y;
     rect->right  += x;
     rect->bottom += y;
 }
diff --git a/misc/user.c b/misc/user.c
index a75bd42..476d861 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -39,6 +39,9 @@
 {
       /* GDI initialisation */
     if (!GDI_Init()) return 0;
+
+      /* Initialize system colors */
+    SYSCOLOR_Init();
     
       /* Create USER heap */
     if (!USER_HeapInit()) return 0;
diff --git a/misc/xt.c b/misc/xt.c
index 3bb98bb..5756d39 100644
--- a/misc/xt.c
+++ b/misc/xt.c
@@ -19,6 +19,7 @@
 #include "win.h"
 #include "class.h"
 #include "gdi.h"
+#include "user.h"
 
 #ifdef __NetBSD__
 #define HZ 100
@@ -56,6 +57,8 @@
 {
     WND * wndPtr;
     CLASS * classPtr;
+    LPSTR textPtr;
+    int len;
     
 #ifdef DEBUG_MESSAGE
     printf( "DefWindowProc: %d %d %d %08x\n", hwnd, msg, wParam, lParam );
@@ -89,6 +92,41 @@
 	    GlobalUnlock( hwnd );
 	    return 0;
 	}
+
+    case WM_GETTEXT:
+	{
+	    if (wParam)
+	    {
+		wndPtr = WIN_FindWndPtr(hwnd);
+		if (wndPtr->hText)
+		{
+		    textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
+		    if ((int)wParam > (len = strlen(textPtr)))
+		    {
+			strcpy((LPSTR)lParam, textPtr);
+			GlobalUnlock(hwnd);
+			return (DWORD)len;
+		    }
+		}
+		((LPSTR)lParam)[0] = NULL;
+	    }
+	    GlobalUnlock(hwnd);
+	    return (0L);
+	}
+
+    case WM_GETTEXTLENGTH:
+	{
+	    wndPtr = WIN_FindWndPtr(hwnd);
+	    if (wndPtr->hText)
+	    {
+		textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
+		len = strlen(textPtr);
+		GlobalUnlock(hwnd);
+		return (DWORD)len;
+	    }
+	    GlobalUnlock(hwnd);
+	    return (0L);
+	}
     }
     return 0;
 }
@@ -108,7 +146,7 @@
 
 void MessageBeep( WORD i )
 {
-    printf( "MessageBeep: %d\n", i );
+    XBell(XT_display, 100);
 }
 
 WORD RegisterWindowMessage( LPSTR str )
@@ -123,7 +161,7 @@
 DWORD GetTickCount()
 {
     struct tms dummy;
-    return times(&dummy) / (1000 / HZ);
+    return (times(&dummy) * 1000) / HZ;
 }
 
 
diff --git a/objects/Makefile b/objects/Makefile
index ad4d119..f1dcd06 100644
--- a/objects/Makefile
+++ b/objects/Makefile
@@ -1,7 +1,7 @@
 CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
 
 OBJS=bitmap.o brush.o font.o gdiobj.o palette.o pen.o dib.o region.o \
-	text.o dcvalues.o clipping.o bitblt.o linedda.o
+	text.o dcvalues.o clipping.o bitblt.o linedda.o color.o
 
 default: objects.o
 
diff --git a/objects/color.c b/objects/color.c
new file mode 100644
index 0000000..a57b46e
--- /dev/null
+++ b/objects/color.c
@@ -0,0 +1,124 @@
+/*
+ * Color functions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
+
+#include <stdlib.h>
+#include <X11/Xlib.h>
+
+#include "windows.h"
+
+extern Display * XT_display;
+extern Screen * XT_screen;
+
+
+/* 
+ * We try to use a private color map if possible, because Windows programs
+ * assume that palette(0) == Black and palette(max-1) == White.
+ */
+
+Colormap COLOR_WinColormap = 0;
+
+
+  /* System colors */
+
+static const char * SysColors[] = 
+{
+      /* Low pixel values (0..7) */
+
+    "black", "red4", "green4", "yellow4",
+    "blue4", "magenta4", "cyan4", "gray50",
+
+      /* High pixel values (max-7..max) */
+
+    "gray75", "red", "green", "yellow",
+    "blue", "magenta", "cyan", "white"
+};
+
+#define NB_SYS_COLORS   (sizeof(SysColors) / sizeof(SysColors[0]))
+
+
+/***********************************************************************
+ *           COLOR_FillDefaultMap
+ *
+ * Try to allocate colors from default screen map (used when we
+ * don't want to or can't use a private map).
+ */
+static int COLOR_FillDefaultMap()
+{
+    XColor color;
+    int i, total = 0;
+
+    for (i = 0; i < NB_SYS_COLORS; i++)
+    {
+	if (XParseColor( XT_display, DefaultColormapOfScreen( XT_screen ),
+			 SysColors[i], &color ))
+	{
+	    if (XAllocColor( XT_display, DefaultColormapOfScreen( XT_screen ), 
+			     &color ))
+		total++;
+	}
+    }
+    return total;
+}
+
+
+/***********************************************************************
+ *           COLOR_BuildMap
+ *
+ * Fill the private colormap.
+ */
+static BOOL COLOR_BuildMap( Colormap map, int depth, int size )
+{
+    XColor color;
+    int i;
+
+    for (i = 0; i < NB_SYS_COLORS; i++)
+    {
+	if (!XParseColor( XT_display, map, SysColors[i], &color ))
+	    color.red = color.green = color.blue = color.flags = 0;
+	if (i < NB_SYS_COLORS/2) color.pixel = i;
+	else color.pixel = (1 << depth) - NB_SYS_COLORS + i;
+	if (color.pixel < size) XStoreColor( XT_display, map, &color );
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           COLOR_Init
+ */
+BOOL COLOR_Init()
+{
+    Visual * visual = DefaultVisual( XT_display, DefaultScreen(XT_display) );
+    
+    switch(visual->class)
+    {
+      case GrayScale:
+      case PseudoColor:
+      case DirectColor:
+
+#ifdef USE_PRIVATE_MAP
+	COLOR_WinColormap = XCreateColormap( XT_display,
+					     DefaultRootWindow(XT_display),
+					     visual, AllocAll );
+	if (COLOR_WinColormap)
+	    COLOR_BuildMap(COLOR_WinColormap,
+			   DefaultDepth(XT_display, DefaultScreen(XT_display)),
+			   visual->map_entries );
+	else COLOR_FillDefaultMap();
+	break;
+#endif  /* USE_PRIVATE_MAP */
+
+      case StaticGray:
+      case StaticColor:
+      case TrueColor:
+	COLOR_FillDefaultMap();
+	COLOR_WinColormap = CopyFromParent;
+	break;	
+    }
+    return TRUE;
+}
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 55237c3..32bb4b8 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -150,13 +150,14 @@
 
       /* Create GDI heap */
 
-    s = GetNextSegment( 0, 0x10000 );
+    s = (struct segment_descriptor_s *)GetNextSegment( 0, 0x10000 );
     if (s == NULL) return FALSE;
     HEAP_Init( &GDI_Heap, s->base_addr, GDI_HEAP_SIZE );
     free(s);
 
       /* Create default palette */
 
+    COLOR_Init();
     PALETTE_Init();
     StockObjects[DEFAULT_PALETTE] = PALETTE_systemPalette;
 
diff --git a/objects/palette.c b/objects/palette.c
index 887f1de..ec69700 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -21,65 +21,42 @@
 extern Display * XT_display;
 extern Screen * XT_screen;
 
-
-#define NB_RESERVED_COLORS  17
-static char * ReservedColors[NB_RESERVED_COLORS] =
-{
-    "black",
-    "gray25",
-    "gray50",
-    "gray75",
-    "white",
-    "red1",
-    "red4",
-    "green1",
-    "green4",
-    "blue1",
-    "blue4",
-    "cyan1",
-    "cyan4",
-    "magenta1",
-    "magenta4",
-    "yellow1",
-    "yellow4"
-};
+extern Colormap COLOR_WinColormap;
 
 GDIOBJHDR * PALETTE_systemPalette;
 
-static int SysColorPixels[NB_RESERVED_COLORS];
-
 
 /***********************************************************************
  *           PALETTE_Init
  */
 BOOL PALETTE_Init()
 {
-    int i, size, pixel;
-    XColor serverColor, exactColor;
+    int i, size;
+    XColor color;
+    Colormap map;
     HPALETTE hpalette;
     LOGPALETTE * palPtr;
 
-    size = DefaultVisual(XT_display,DefaultScreen(XT_display))->map_entries;
+    size = DefaultVisual( XT_display, DefaultScreen(XT_display) )->map_entries;
     palPtr = malloc( sizeof(LOGPALETTE) + (size-1)*sizeof(PALETTEENTRY) );
     if (!palPtr) return FALSE;
     palPtr->palVersion = 0x300;
     palPtr->palNumEntries = size;
     memset( palPtr->palPalEntry, 0xff, size*sizeof(PALETTEENTRY) );
-    
-    for (i = 0; i < NB_RESERVED_COLORS; i++)
+
+    if ((map = COLOR_WinColormap) == CopyFromParent)
+	map = DefaultColormapOfScreen( XT_screen );
+
+    for (i = 0; i < size; i++)
     {
-	if (XAllocNamedColor( XT_display,
-			      DefaultColormapOfScreen( XT_screen ),
-			      ReservedColors[i], 
-			      &serverColor, &exactColor ))
-	{
-	    pixel = serverColor.pixel;
-	    palPtr->palPalEntry[pixel].peRed   = serverColor.red >> 8;
-	    palPtr->palPalEntry[pixel].peGreen = serverColor.green >> 8;
-	    palPtr->palPalEntry[pixel].peBlue  = serverColor.blue >> 8;
-	    palPtr->palPalEntry[pixel].peFlags = 0;
-	}
+	color.pixel = i;
+	XQueryColor( XT_display, map, &color );
+	palPtr->palPalEntry[i].peRed   = color.red >> 8;
+	palPtr->palPalEntry[i].peGreen = color.green >> 8;
+	palPtr->palPalEntry[i].peBlue  = color.blue >> 8;
+	palPtr->palPalEntry[i].peFlags = 0;	
     }
+
     hpalette = CreatePalette( palPtr );
     PALETTE_systemPalette = (GDIOBJHDR *) GDI_HEAP_ADDR( hpalette );
     free( palPtr );
@@ -158,10 +135,18 @@
     
     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
     if (!palPtr) return 0;
+
+    if (COLOR_WinColormap && (hpalette == STOCK_DEFAULT_PALETTE))
+    {
+	if ((color & 0xffffff) == 0) return 0;  /* Entry 0 is black */
+	if ((color & 0xffffff) == 0xffffff)     /* Max entry is white */
+	    return palPtr->logpalette.palNumEntries - 1;
+    }
     
     r = GetRValue(color);
     g = GetGValue(color);
     b = GetBValue(color);
+
     entry = palPtr->logpalette.palPalEntry;
     for (i = 0, minDist = MAXINT; i < palPtr->logpalette.palNumEntries; i++)
     {
diff --git a/objects/region.c b/objects/region.c
index 2c22ee4..08274ca 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -539,17 +539,20 @@
       case RGN_AND:
 	res = IntersectRect( &region->box, &src1Obj->region.box,
 			     &src2Obj->region.box );
+	region->type = COMPLEXREGION;
 	break;
 
       case RGN_OR:
       case RGN_XOR:
 	res = UnionRect( &region->box, &src1Obj->region.box,
 			 &src2Obj->region.box );
+	region->type = COMPLEXREGION;
 	break;
 
       case RGN_DIFF:
 	res = SubtractRect( &region->box, &src1Obj->region.box,
 			    &src2Obj->region.box );
+	region->type = COMPLEXREGION;
 	break;
 
       case RGN_COPY:
@@ -582,7 +585,7 @@
 	  REGION_CopyIntersection( region, &src1Obj->region );
 	  XSetFunction( XT_display, regionGC, GXand );
 	  REGION_CopyIntersection( region, &src2Obj->region );
-	  return COMPLEXREGION;
+	  break;
 
       case RGN_OR:
       case RGN_XOR:
@@ -592,7 +595,7 @@
 	  XSetFunction( XT_display, regionGC, (mode == RGN_OR) ? GXor : GXxor);
 	  REGION_CopyIntersection( region, &src1Obj->region );
 	  REGION_CopyIntersection( region, &src2Obj->region );
-	  return COMPLEXREGION;
+	  break;
 	  
       case RGN_DIFF:
 	  XSetFunction( XT_display, regionGC, GXclear );
@@ -602,13 +605,13 @@
 	  REGION_CopyIntersection( region, &src1Obj->region );
 	  XSetFunction( XT_display, regionGC, GXandInverted );
 	  REGION_CopyIntersection( region, &src2Obj->region );
-	  return COMPLEXREGION;
+	  break;
 	  
       case RGN_COPY:
 	  XSetFunction( XT_display, regionGC, GXcopy );
 	  XCopyArea( XT_display, src1Obj->region.pixmap, region->pixmap,
 		     regionGC, 0, 0, width, height, 0, 0 );
-	  return region->type;
+	  break;
     }
-    return ERROR;
+    return region->type;
 }
diff --git a/oem2ansi.trl b/oem2ansi.trl
new file mode 100755
index 0000000..20ab9f4
--- /dev/null
+++ b/oem2ansi.trl
Binary files differ
diff --git a/oemansi.exe b/oemansi.exe
new file mode 100755
index 0000000..46c907f
--- /dev/null
+++ b/oemansi.exe
Binary files differ
diff --git a/test/hyperoid/blank.bmp b/test/hyperoid/blank.bmp
new file mode 100644
index 0000000..11840af
--- /dev/null
+++ b/test/hyperoid/blank.bmp
Binary files differ
diff --git a/test/hyperoid/bomb.bmp b/test/hyperoid/bomb.bmp
new file mode 100644
index 0000000..5fcde4a
--- /dev/null
+++ b/test/hyperoid/bomb.bmp
Binary files differ
diff --git a/test/hyperoid/copying.txt b/test/hyperoid/copying.txt
new file mode 100644
index 0000000..2d64ec5
--- /dev/null
+++ b/test/hyperoid/copying.txt
@@ -0,0 +1,292 @@
+ 

+                    GNU GENERAL PUBLIC LICENSE

+                     Version 1, February 1989

+

+ Copyright (C) 1989 Free Software Foundation, Inc.

+                    675 Mass Ave, Cambridge, MA 02139, USA

+ Everyone is permitted to copy and distribute verbatim copies

+ of this license document, but changing it is not allowed.

+

+                            Preamble

+

+  The license agreements of most software companies try to keep users

+at the mercy of those companies.  By contrast, our General Public

+License is intended to guarantee your freedom to share and change free

+software--to make sure the software is free for all its users.  The

+General Public License applies to the Free Software Foundation's

+software and to any other program whose authors commit to using it.

+You can use it for your programs, too.

+

+  When we speak of free software, we are referring to freedom, not

+price.  Specifically, the General Public License is designed to make

+sure that you have the freedom to give away or sell copies of free

+software, that you receive source code or can get it if you want it,

+that you can change the software or use pieces of it in new free

+programs; and that you know you can do these things.

+

+  To protect your rights, we need to make restrictions that forbid

+anyone to deny you these rights or to ask you to surrender the rights.

+These restrictions translate to certain responsibilities for you if you

+distribute copies of the software, or if you modify it.

+

+  For example, if you distribute copies of a such a program, whether

+gratis or for a fee, you must give the recipients all the rights that

+you have.  You must make sure that they, too, receive or can get the

+source code.  And you must tell them their rights.

+

+  We protect your rights with two steps: (1) copyright the software, and

+(2) offer you this license which gives you legal permission to copy,

+distribute and/or modify the software.

+

+  Also, for each author's protection and ours, we want to make certain

+that everyone understands that there is no warranty for this free

+software.  If the software is modified by someone else and passed on, we

+want its recipients to know that what they have is not the original, so

+that any problems introduced by others will not reflect on the original

+authors' reputations.

+

+  The precise terms and conditions for copying, distribution and

+modification follow.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+                    GNU GENERAL PUBLIC LICENSE

+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+

+  0. This License Agreement applies to any program or other work which

+contains a notice placed by the copyright holder saying it may be

+distributed under the terms of this General Public License.  The

+"Program", below, refers to any such program or work, and a "work based

+on the Program" means either the Program or any work containing the

+Program or a portion of it, either verbatim or with modifications.  Each

+licensee is addressed as "you".

+

+  1. You may copy and distribute verbatim copies of the Program's source

+code as you receive it, in any medium, provided that you conspicuously and

+appropriately publish on each copy an appropriate copyright notice and

+disclaimer of warranty; keep intact all the notices that refer to this

+General Public License and to the absence of any warranty; and give any

+other recipients of the Program a copy of this General Public License

+along with the Program.  You may charge a fee for the physical act of

+transferring a copy.

+

+  2. You may modify your copy or copies of the Program or any portion of

+it, and copy and distribute such modifications under the terms of Paragraph

+1 above, provided that you also do the following:

+

+    a) cause the modified files to carry prominent notices stating that

+    you changed the files and the date of any change; and

+

+    b) cause the whole of any work that you distribute or publish, that

+    in whole or in part contains the Program or any part thereof, either

+    with or without modifications, to be licensed at no charge to all

+    third parties under the terms of this General Public License (except

+    that you may choose to grant warranty protection to some or all

+    third parties, at your option).

+

+    c) If the modified program normally reads commands interactively when

+    run, you must cause it, when started running for such interactive use

+    in the simplest and most usual way, to print or display an

+    announcement including an appropriate copyright notice and a notice

+    that there is no warranty (or else, saying that you provide a

+    warranty) and that users may redistribute the program under these

+    conditions, and telling the user how to view a copy of this General

+    Public License.

+

+    d) You may charge a fee for the physical act of transferring a

+    copy, and you may at your option offer warranty protection in

+    exchange for a fee.

+

+Mere aggregation of another independent work with the Program (or its

+derivative) on a volume of a storage or distribution medium does not bring

+the other work under the scope of these terms.

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+  3. You may copy and distribute the Program (or a portion or derivative of

+it, under Paragraph 2) in object code or executable form under the terms of

+Paragraphs 1 and 2 above provided that you also do one of the following:

+

+    a) accompany it with the complete corresponding machine-readable

+    source code, which must be distributed under the terms of

+    Paragraphs 1 and 2 above; or,

+

+    b) accompany it with a written offer, valid for at least three

+    years, to give any third party free (except for a nominal charge

+    for the cost of distribution) a complete machine-readable copy of the

+    corresponding source code, to be distributed under the terms of

+    Paragraphs 1 and 2 above; or,

+

+    c) accompany it with the information you received as to where the

+    corresponding source code may be obtained.  (This alternative is

+    allowed only for noncommercial distribution and only if you

+    received the program in object code or executable form alone.)

+

+Source code for a work means the preferred form of the work for making

+modifications to it.  For an executable file, complete source code means

+all the source code for all modules it contains; but, as a special

+exception, it need not include source code for modules which are standard

+libraries that accompany the operating system on which the executable

+file runs, or for standard header files or definitions files that

+accompany that operating system.

+

+  4. You may not copy, modify, sublicense, distribute or transfer the

+Program except as expressly provided under this General Public License.

+Any attempt otherwise to copy, modify, sublicense, distribute or transfer

+the Program is void, and will automatically terminate your rights to use

+the Program under this License.  However, parties who have received

+copies, or rights to use copies, from you under this General Public

+License will not have their licenses terminated so long as such parties

+remain in full compliance.

+

+  5. By copying, distributing or modifying the Program (or any work based

+on the Program) you indicate your acceptance of this license to do so,

+and all its terms and conditions.

+

+  6. Each time you redistribute the Program (or any work based on the

+Program), the recipient automatically receives a license from the original

+licensor to copy, distribute or modify the Program subject to these

+terms and conditions.  You may not impose any further restrictions on the

+recipients' exercise of the rights granted herein.

+

+

+

+  7. The Free Software Foundation may publish revised and/or new versions

+of the General Public License from time to time.  Such new versions will

+be similar in spirit to the present version, but may differ in detail to

+address new problems or concerns.

+

+Each version is given a distinguishing version number.  If the Program

+specifies a version number of the license which applies to it and "any

+later version", you have the option of following the terms and conditions

+either of that version or of any later version published by the Free

+Software Foundation.  If the Program does not specify a version number of

+the license, you may choose any version ever published by the Free Software

+Foundation.

+

+  8. If you wish to incorporate parts of the Program into other free

+programs whose distribution conditions are different, write to the author

+to ask for permission.  For software which is copyrighted by the Free

+Software Foundation, write to the Free Software Foundation; we sometimes

+make exceptions for this.  Our decision will be guided by the two goals

+of preserving the free status of all derivatives of our free software and

+of promoting the sharing and reuse of software generally.

+

+                            NO WARRANTY

+

+  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY

+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN

+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES

+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED

+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS

+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE

+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,

+REPAIR OR CORRECTION.

+

+  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING

+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR

+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,

+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING

+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED

+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY

+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER

+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE

+POSSIBILITY OF SUCH DAMAGES.

+

+                     END OF TERMS AND CONDITIONS

+

+

+

+

+        Appendix: How to Apply These Terms to Your New Programs

+

+  If you develop a new program, and you want it to be of the greatest

+possible use to humanity, the best way to achieve this is to make it

+free software which everyone can redistribute and change under these

+terms.

+

+  To do so, attach the following notices to the program.  It is safest to

+attach them to the start of each source file to most effectively convey

+the exclusion of warranty; and each file should have at least the

+"copyright" line and a pointer to where the full notice is found.

+

+    <one line to give the program's name and a brief idea of what it does.>

+    Copyright (C) 19yy  <name of author>

+

+    This program is free software; you can redistribute it and/or modify

+    it under the terms of the GNU General Public License as published by

+    the Free Software Foundation; either version 1, or (at your option)

+    any later version.

+

+    This program 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 General Public License for more details.

+

+    You should have received a copy of the GNU General Public License

+    along with this program; if not, write to the Free Software

+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

+

+Also add information on how to contact you by electronic and paper mail.

+

+If the program is interactive, make it output a short notice like this

+when it starts in an interactive mode:

+

+    Gnomovision version 69, Copyright (C) 19xx name of author

+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.

+    This is free software, and you are welcome to redistribute it

+    under certain conditions; type `show c' for details.

+

+The hypothetical commands `show w' and `show c' should show the

+appropriate parts of the General Public License.  Of course, the

+commands you use may be called something other than `show w' and `show

+c'; they could even be mouse-clicks or menu items--whatever suits your

+program.

+

+You should also get your employer (if you work as a programmer) or your

+school, if any, to sign a "copyright disclaimer" for the program, if

+necessary.  Here a sample; alter the names:

+

+  Yoyodyne, Inc., hereby disclaims all copyright interest in the

+  program `Gnomovision' (a program to direct compilers to make passes

+  at assemblers) written by James Hacker.

+

+  <signature of Ty Coon>, 1 April 1989

+  Ty Coon, President of Vice

+

+That's all there is to it!

+ 

diff --git a/test/hyperoid/hyperoid.c b/test/hyperoid/hyperoid.c
new file mode 100644
index 0000000..f396d55
--- /dev/null
+++ b/test/hyperoid/hyperoid.c
@@ -0,0 +1,1851 @@
+//

+// HYPEROID - a neato game

+//

+// Version: 1.1  Copyright (C) 1990,91 Hutchins Software

+//      This software is licenced under the GNU General Public Licence

+//      Please read the associated legal documentation

+// Author: Edward Hutchins

+// Internet: eah1@cec1.wustl.edu

+// USNail: c/o Edward Hutchins, 63 Ridgemoor Dr., Clayton, MO, 63105

+// Revisions:

+// 10/31/91 made game better/harder - Ed.

+//

+// Music: R.E.M./The Cure/Ministry/Front 242/The Smiths/New Order/Hendrix...

+// Beers: Bass Ale, Augsberger Dark

+//

+

+#include "hyperoid.h"

+

+//

+// imports

+//

+

+IMPORT POINT        LetterPart[] FROM( roidsupp.c );

+IMPORT NPSTR        szNumberDesc[] FROM( roidsupp.c );

+IMPORT NPSTR        szLetterDesc[] FROM( roidsupp.c );

+

+//

+// globals

+//

+

+GLOBAL CHAR         szAppName[32];

+GLOBAL HANDLE       hAppInst;

+GLOBAL HWND         hAppWnd;

+GLOBAL HPALETTE     hAppPalette;

+GLOBAL INT          nDrawDelay;

+GLOBAL INT          nLevel;

+GLOBAL INT          nSafe;

+GLOBAL INT          nShield;

+GLOBAL INT          nBomb;

+GLOBAL INT          nBadGuys;

+GLOBAL LONG         lScore;

+GLOBAL LONG         lLastLife;

+GLOBAL LONG         lHighScore;

+GLOBAL BOOL         bRestart;

+GLOBAL BOOL         bPaused;

+GLOBAL BOOL         bBW;

+GLOBAL INT          vkShld;

+GLOBAL INT          vkClkw;

+GLOBAL INT          vkCtrClkw;

+GLOBAL INT          vkThrst;

+GLOBAL INT          vkRvThrst;

+GLOBAL INT          vkFire;

+GLOBAL INT          vkBomb;

+GLOBAL NPOBJ        npPlayer;

+GLOBAL LIST         FreeList;

+GLOBAL LIST         RoidList;

+GLOBAL LIST         ShotList;

+GLOBAL LIST         FlameList;

+GLOBAL LIST         SpinnerList;

+GLOBAL LIST         HunterList;

+GLOBAL LIST         HunterShotList;

+GLOBAL LIST         SwarmerList;

+GLOBAL LIST         LetterList;

+GLOBAL LIST         BonusList;

+GLOBAL INT          nCos[DEGREE_SIZE];

+GLOBAL INT          nSin[DEGREE_SIZE];

+GLOBAL HPEN         hPen[PALETTE_SIZE];

+GLOBAL OBJ          Obj[MAX_OBJS];

+GLOBAL HBITMAP      hBitmap[IDB_MAX];

+

+//

+// locals

+//

+

+LOCAL DWORD         dwSeed;

+LOCAL INT           nScoreLen;

+LOCAL CHAR          szScore[40];

+LOCAL RECT          rectScoreClip;

+LOCAL RECT          rectShotClip;

+LOCAL POINT         Player[] =

+{ {0, 0}, {160, 150}, {0, 250}, {96, 150}, {0, 0} };

+LOCAL POINT         Spinner[] =

+{ {160, 150}, {224, 100}, {96, 100}, {32, 150}, {160, 150} };

+LOCAL POINT         Swarmer[] =

+{ {0, 100}, {64, 100}, {128, 100}, {192, 100}, {0, 100} };

+LOCAL POINT         Hunter[] =

+{

+	{160, 150}, {0, 250}, {192, 30}, {64, 30},

+	{0, 250}, {96, 150}, {128, 150}, {160, 150}

+};

+LOCAL POINT         Bonus[] =

+{ {0, 150}, {102, 150}, {205, 150}, {51, 150}, {154, 150}, {0, 150} };

+

+//

+// KillBadGuy - kill off a badguy (made into a macro)

+//

+

+#define KillBadGuy() \

+((--nBadGuys <= 0)?(SetRestart( RESTART_NEXTLEVEL ),TRUE):FALSE)

+

+//

+// arand - pseudorandom number from 0 to x-1 (thanks antman!)

+//

+

+INT NEAR PASCAL arand( INT x )

+{

+	dwSeed = dwSeed * 0x343fd + 0x269ec3;

+	return( (INT)(((dwSeed >> 16) & 0x7fff) * x >> 15) );

+}

+

+//

+// AddHead - add an object to the head of a list

+//

+

+VOID NEAR PASCAL AddHead( NPLIST npList, NPNODE npNode )

+{

+	if (npList->npHead)

+	{

+		npNode->npNext = npList->npHead;

+		npNode->npPrev = NULL;

+		npList->npHead = (npList->npHead->npPrev = npNode);

+	}

+	else // add to an empty list

+	{

+		npList->npHead = npList->npTail = npNode;

+		npNode->npNext = npNode->npPrev = NULL;

+	}

+}

+

+//

+// RemHead - remove the first element in a list

+//

+

+NPNODE NEAR PASCAL RemHead( NPLIST npList )

+{

+	if (npList->npHead)

+	{

+		NPNODE npNode = npList->npHead;

+		if (npList->npTail != npNode)

+		{

+			npList->npHead = npNode->npNext;

+			npNode->npNext->npPrev = NULL;

+		}

+		else npList->npHead = npList->npTail = NULL;

+		return( npNode );

+	}

+	else return( NULL );

+}

+

+//

+// Remove - remove an arbitrary element from a list

+//

+

+VOID NEAR PASCAL Remove( NPLIST npList, NPNODE npNode )

+{

+	if (npNode->npPrev) npNode->npPrev->npNext = npNode->npNext;

+	else npList->npHead = npNode->npNext;

+	if (npNode->npNext) npNode->npNext->npPrev = npNode->npPrev;

+	else npList->npTail = npNode->npPrev;

+}

+

+//

+// DrawObject - draw a single object

+//

+

+VOID NEAR PASCAL DrawObject( HDC hDC, NPOBJ npObj )

+{

+	INT             nCnt;

+	INT             nDir = (npObj->nDir += npObj->nSpin);

+	INT             x = (npObj->Pos.x += npObj->Vel.x);

+	INT             y = (npObj->Pos.y += npObj->Vel.y);

+	POINT           Pts[MAX_PTS];

+

+	if (x < -CLIP_COORD) npObj->Pos.x = x = CLIP_COORD;

+	else if (x > CLIP_COORD) npObj->Pos.x = x = -CLIP_COORD;

+	if (y < -CLIP_COORD) npObj->Pos.y = y = CLIP_COORD;

+	else if (y > CLIP_COORD) npObj->Pos.y = y = -CLIP_COORD;

+

+	for (nCnt = npObj->byPts - 1; nCnt >= 0; --nCnt)

+	{

+		WORD wDeg = DEG( npObj->Pts[nCnt].x + nDir );

+		INT nLen = npObj->Pts[nCnt].y;

+		Pts[nCnt].x = x + MULDEG( nLen, nCos[wDeg] );

+		Pts[nCnt].y = y + MULDEG( nLen, nSin[wDeg] );

+	}

+

+	if (npObj->byPts > 1)

+	{

+		SelectObject( hDC, hPen[BLACK] );

+		Polyline( hDC, npObj->Old, npObj->byPts );

+		if (npObj->nCount > 0)

+		{

+			SelectObject( hDC, hPen[npObj->byColor] );

+			Polyline( hDC, Pts, npObj->byPts );

+			for (nCnt = npObj->byPts - 1; nCnt >= 0; --nCnt)

+				npObj->Old[nCnt] = Pts[nCnt];

+		}

+	}

+	else // just a point

+	{

+		SetPixel( hDC, npObj->Old[0].x, npObj->Old[0].y, PALETTEINDEX( BLACK ) );

+		if (npObj->nCount > 0)

+		{

+			SetPixel( hDC, Pts[0].x, Pts[0].y, PALETTEINDEX( npObj->byColor ) );

+			npObj->Old[0] = Pts[0];

+		}

+	}

+}

+

+//

+// SetRestart - set the restart timer

+//

+

+VOID NEAR PASCAL SetRestart( RESTART_MODE Restart )

+{

+	POINT           Pt;

+	CHAR            szBuff[32];

+

+	if (bRestart) return;

+	SetTimer( hAppWnd, RESTART_TIMER, RESTART_DELAY, NULL );

+	bRestart = TRUE;

+

+	Pt.x = Pt.y = 0;

+	switch (Restart)

+	{

+	case RESTART_GAME:

+		SpinLetters( "GAME OVER", Pt, Pt, RED, 400 );

+		break;

+	case RESTART_LEVEL:

+		PrintLetters( "GET READY", Pt, Pt, BLUE, 300 );

+		break;

+	case RESTART_NEXTLEVEL:

+		wsprintf( szBuff, "LEVEL %u", nLevel + 1 );

+		PrintLetters( szBuff, Pt, Pt, BLUE, 300 );

+		break;

+	}

+}

+

+//

+// PrintPlayerMessage - show the player a status message

+//

+

+VOID NEAR PASCAL PrintPlayerMessage( NPSTR npszText )

+{

+	POINT Pos, Vel;

+

+	Pos = npPlayer->Pos;

+	Pos.y -= 400;

+	Vel.x = 0;

+	Vel.y = -50;

+	PrintLetters( npszText, Pos, Vel, GREEN, 150 );

+}

+

+//

+// AddExtraLife - give the player another life

+//

+

+VOID NEAR PASCAL AddExtraLife( VOID )

+{

+	PrintPlayerMessage( "EXTRA LIFE" );

+	++npPlayer->nCount;

+	npPlayer->byColor = (BYTE)(BLACK + npPlayer->nCount);

+	if (npPlayer->byColor > WHITE) npPlayer->byColor = WHITE;

+}

+

+//

+// Hit - something hit an object, do fireworks

+//

+

+VOID NEAR PASCAL Hit( HDC hDC, NPOBJ npObj )

+{

+	INT             nCnt;

+

+	for (nCnt = 0; nCnt < 6; ++nCnt)

+	{

+		NPOBJ npFlame = RemHeadObj( &FreeList );

+		if (!npFlame) return;

+		npFlame->Pos.x = npObj->Pos.x;

+		npFlame->Pos.y = npObj->Pos.y;

+		npFlame->Vel.x = npObj->Vel.x;

+		npFlame->Vel.y = npObj->Vel.y;

+		npFlame->nDir = npObj->nDir + (nCnt * DEGREE_SIZE) / 6;

+		npFlame->nSpin = 0;

+		npFlame->nCount = 10 + arand( 8 );

+		npFlame->byColor = YELLOW;

+		npFlame->byPts = 1;

+		npFlame->Pts[0].x = npFlame->Pts[0].y = 0;

+		ACCEL( npFlame, npFlame->nDir, 50 - npFlame->nCount );

+		AddHeadObj( &FlameList, npFlame );

+	}

+}

+

+//

+// Explode - explode an object

+//

+

+VOID NEAR PASCAL Explode( HDC hDC, NPOBJ npObj )

+{

+	INT             nCnt, nSize = npObj->byPts;

+

+	DrawObject( hDC, npObj );

+	for (nCnt = 0; nCnt < nSize; ++nCnt)

+	{

+		NPOBJ npFlame;

+		if (arand( 2 )) continue;

+		if (!(npFlame = RemHeadObj( &FreeList ))) return;

+		npFlame->Pos.x = npObj->Pos.x;

+		npFlame->Pos.y = npObj->Pos.y;

+		npFlame->Vel.x = npObj->Vel.x;

+		npFlame->Vel.y = npObj->Vel.y;

+		npFlame->nDir = npObj->nDir + nCnt * DEGREE_SIZE / nSize + arand( 32 );

+		npFlame->nSpin = arand( 31 ) - 15;

+		npFlame->nCount = 25 + arand( 16 );

+		npFlame->byColor = npObj->byColor;

+		npFlame->byPts = 2;

+		npFlame->Pts[0] = npObj->Pts[nCnt];

+		if (nCnt == nSize - 1) npFlame->Pts[1] = npObj->Pts[0];

+		else npFlame->Pts[1] = npObj->Pts[nCnt + 1];

+		ACCEL( npFlame, npFlame->nDir, 60 - npFlame->nCount );

+		AddHeadObj( &FlameList, npFlame );

+	}

+	Hit( hDC, npObj );

+}

+

+//

+// HitPlayer - blow up the player

+//

+

+BOOL NEAR PASCAL HitPlayer( HDC hDC, NPOBJ npObj )

+{

+	POINT           Vel;

+	INT             nMass, nSpin;

+

+	if (nSafe || (npPlayer->nCount <= 0)) return( FALSE );

+

+	// rumble and shake both objects

+	nMass = npPlayer->nMass + npObj->nMass;

+

+	nSpin = npPlayer->nSpin + npObj->nSpin;

+	npObj->nSpin -= MulDiv( nSpin, npPlayer->nMass, nMass );

+	npPlayer->nSpin -= MulDiv( nSpin, npObj->nMass, nMass );

+

+	Vel.x = npPlayer->Vel.x - npObj->Vel.x;

+	Vel.y = npPlayer->Vel.y - npObj->Vel.y;

+	npObj->Vel.x += MulDiv( Vel.x, npPlayer->nMass, nMass );

+	npObj->Vel.y += MulDiv( Vel.y, npPlayer->nMass, nMass );

+	npPlayer->Vel.x -= MulDiv( Vel.x, npObj->nMass, nMass );

+	npPlayer->Vel.y -= MulDiv( Vel.y, npObj->nMass, nMass );

+

+	if (--npPlayer->nCount)

+	{

+		npPlayer->byColor = (BYTE)(BLACK + npPlayer->nCount);

+		if (npPlayer->byColor > WHITE) npPlayer->byColor = WHITE;

+		Hit( hDC, npPlayer );

+		return( TRUE );

+	}

+

+	// final death

+	npPlayer->byColor = WHITE;

+	Explode( hDC, npPlayer );

+	SetRestart( RESTART_GAME );

+	return( FALSE );

+}

+

+//

+// CreateLetter - make a new letter object

+//

+

+NPOBJ FAR PASCAL CreateLetter( CHAR cLetter, INT nSize )

+{

+	NPOBJ           npLtr;

+	INT             nCnt;

+	NPSTR           npDesc;

+

+	if (cLetter >= '0' && cLetter <= '9') npDesc = szNumberDesc[cLetter - '0'];

+	else if (cLetter >= 'A' && cLetter <= 'Z') npDesc = szLetterDesc[cLetter - 'A'];

+	else if (cLetter >= 'a' && cLetter <= 'z') npDesc = szLetterDesc[cLetter - 'a'];

+	else if (cLetter == '.') npDesc = "l";

+	else return( NULL );

+

+	if (npLtr = RemHeadObj( &FreeList ))

+	{

+		npLtr->nMass = 1;

+		npLtr->nDir = 0;

+		npLtr->nSpin = 0;

+		npLtr->nCount = 40;

+		npLtr->byColor = WHITE;

+		npLtr->byPts = (BYTE)(nCnt = strlen( npDesc ));

+		while (nCnt--)

+		{

+			npLtr->Pts[nCnt] = LetterPart[npDesc[nCnt] - 'a'];

+			npLtr->Pts[nCnt].y = MulDiv( npLtr->Pts[nCnt].y, nSize, LETTER_MAX );

+		}

+		AddHeadObj( &LetterList, npLtr );

+	}

+	return( npLtr );

+}

+

+//

+// DrawLetters - draw letters and such

+//

+

+VOID NEAR PASCAL DrawLetters( HDC hDC )

+{

+	NPOBJ           npLtr, npNext;

+

+	for (npLtr = HeadObj( &LetterList ); npLtr; npLtr = npNext)

+	{

+		npNext = NextObj( npLtr );

+		switch (--npLtr->nCount)

+		{

+		case 3:

+			--npLtr->byColor;

+			break;

+		case 0:

+			RemoveObj( &LetterList, npLtr );

+			AddHeadObj( &FreeList, npLtr );

+			break;

+		}

+		DrawObject( hDC, npLtr );

+	}

+}

+

+//

+// CreateBonus - make a new bonus object

+//

+

+VOID NEAR PASCAL CreateBonus( VOID )

+{

+	NPOBJ           npBonus;

+	INT             nCnt;

+

+	if (npBonus = RemHeadObj( &FreeList ))

+	{

+		npBonus->Pos.x = arand( CLIP_COORD * 2 ) - CLIP_COORD;

+		npBonus->Pos.y = -CLIP_COORD;

+		npBonus->Vel.x = npBonus->Vel.y = 0;

+		npBonus->nDir = arand( DEGREE_SIZE );

+		npBonus->nSpin = (arand( 2 ) ? 12 : -12);

+		npBonus->nCount = arand( 4 ) + 1;

+		npBonus->nDelay = 64 + arand( 128 );

+		npBonus->nMass = 1;

+		npBonus->byColor = (BYTE)(WHITE + (npBonus->nCount * 2));

+		npBonus->byPts = DIM(Bonus);

+		for (nCnt = 0; nCnt < DIM(Bonus); ++nCnt)

+			npBonus->Pts[nCnt] = Bonus[nCnt];

+		ACCEL( npBonus, npBonus->nDir, 30 + nLevel * 2 );

+		AddHeadObj( &BonusList, npBonus );

+	}

+}

+

+//

+// DrawBonuses - process and draw the bonus list

+//

+

+VOID NEAR PASCAL DrawBonuses( HDC hDC )

+{

+	NPOBJ           npBonus, npNext;

+	LOCAL INT       nNextBonus = 1000;

+

+	if (nBadGuys && (--nNextBonus < 0))

+	{

+		CreateBonus();

+		nNextBonus = 1000;

+	}

+

+	for (npBonus = HeadObj( &BonusList ); npBonus; npBonus = npNext)

+	{

+		NPOBJ           npShot;

+		INT             nDelta;

+		RECT            rect;

+

+		npNext = NextObj( npBonus );

+

+		MKRECT( &rect, npBonus->Pos, 150 );

+

+		if (PTINRECT( &rect, npPlayer->Pos ))

+		{

+			if (npPlayer->nCount > 0) switch (npBonus->nCount)

+			{

+			case 1:

+				{

+					CHAR szBuff[32];

+					LONG lBonus = 1000L * nLevel;

+					if (lBonus == 0) lBonus = 500;

+					lScore += lBonus;

+					wsprintf( szBuff, "%ld", lBonus );

+					PrintPlayerMessage( szBuff );

+				}

+				break;

+			case 2:

+				nSafe = 15;

+				++nShield;

+				npPlayer->byColor = GREEN;

+				PrintPlayerMessage( "EXTRA SHIELD" );

+				break;

+			case 3:

+				++nBomb;

+				PrintPlayerMessage( "EXTRA BOMB" );

+				break;

+			case 4:

+				AddExtraLife();

+				break;

+			}

+			npBonus->nCount = 0;

+			Explode( hDC, npBonus );

+			RemoveObj( &BonusList, npBonus );

+			AddHeadObj( &FreeList, npBonus );

+		}

+		else if (INTRECT(&rect, &rectShotClip))

+		{

+			for (npShot = HeadObj( &ShotList ); npShot; npShot = NextObj( npShot ))

+			{

+				if (!PTINRECT( &rect, npShot->Pos )) continue;

+				npShot->nCount = 1;

+				npBonus->nCount = 0;

+				Explode( hDC, npBonus );

+				RemoveObj( &BonusList, npBonus );

+				AddHeadObj( &FreeList, npBonus );

+			}

+		}

+		if (npBonus->nCount && --npBonus->nDelay <= 0)

+		{

+			--npBonus->nCount;

+			npBonus->nDelay = 64 + arand( 128 );

+			npBonus->byColor = (BYTE)(WHITE + (npBonus->nCount * 2));

+			if (npBonus->nCount == 0)

+			{

+				Explode( hDC, npBonus );

+				RemoveObj( &BonusList, npBonus );

+				AddHeadObj( &FreeList, npBonus );

+			}

+		}

+		nDelta = npPlayer->Pos.x - npBonus->Pos.x;

+		while (nDelta < -16 || nDelta > 16) nDelta /= 2;

+		npBonus->Vel.x += nDelta - npBonus->Vel.x / 16;

+		nDelta = npPlayer->Pos.y - npBonus->Pos.y;

+		while (nDelta < -16 || nDelta > 16) nDelta /= 2;

+		npBonus->Vel.y += nDelta - npBonus->Vel.y / 16;

+		DrawObject( hDC, npBonus );

+	}

+}

+

+//

+// DrawHunterShots - process and draw the hunter shot list

+//

+

+VOID NEAR PASCAL DrawHunterShots( HDC hDC )

+{

+	NPOBJ           npShot, npNext;

+

+	for (npShot = HeadObj( &HunterShotList ); npShot; npShot = npNext)

+	{

+		RECT            rect;

+

+		npNext = NextObj( npShot );

+

+		MKRECT( &rect, npShot->Pos, 200 );

+

+		if (PTINRECT( &rect, npPlayer->Pos ))

+		{

+			HitPlayer( hDC, npShot );

+			npShot->nCount = 1;

+		}

+		switch (--npShot->nCount)

+		{

+		case 7:

+			npShot->byColor = DKGREEN;

+			break;

+		case 0:

+			RemoveObj( &HunterShotList, npShot );

+			AddHeadObj( &FreeList, npShot );

+			break;

+		}

+		DrawObject( hDC, npShot );

+	}

+}

+

+//

+// FireHunterShot - fire a hunter bullet

+//

+

+VOID NEAR PASCAL FireHunterShot( NPOBJ npHunt )

+{

+	NPOBJ           npShot;

+

+	if (npShot = RemHeadObj( &FreeList ))

+	{

+		npShot->Pos.x = npHunt->Pos.x;

+		npShot->Pos.y = npHunt->Pos.y;

+		npShot->Vel.x = npHunt->Vel.x;

+		npShot->Vel.y = npHunt->Vel.y;

+		npShot->nMass = 8;

+		npShot->nDir = npHunt->nDir + arand( 5 ) - 2;

+		npShot->nSpin = (arand( 2 ) ? 10 : -10);

+		npShot->nCount = 16 + arand( 8 );

+		npShot->byColor = GREEN;

+		npShot->byPts = 2;

+		npShot->Pts[0].x = 128;

+		npShot->Pts[0].y = 50;

+		npShot->Pts[1].x = 0;

+		npShot->Pts[1].y = 50;

+		ACCEL( npShot, npShot->nDir, 200 + npShot->nCount );

+		AddHeadObj( &HunterShotList, npShot );

+	}

+}

+

+//

+// CreateHunter - make a new hunter

+//

+

+VOID NEAR PASCAL CreateHunter( VOID )

+{

+	NPOBJ           npHunt;

+	INT             nCnt;

+

+	if (npHunt = RemHeadObj( &FreeList ))

+	{

+		npHunt->Pos.x = arand( CLIP_COORD * 2 ) - CLIP_COORD;

+		npHunt->Pos.y = -CLIP_COORD;

+		npHunt->Vel.x = npHunt->Vel.y = 0;

+		npHunt->nMass = 256;

+		npHunt->nDir = arand( DEGREE_SIZE );

+		npHunt->nSpin = 0;

+		npHunt->nCount = 1 + arand( nLevel );

+		npHunt->nDelay = 2 + arand( 10 );

+		npHunt->byColor = CYAN;

+		npHunt->byPts = DIM(Hunter);

+		for (nCnt = 0; nCnt < DIM(Hunter); ++nCnt)

+			npHunt->Pts[nCnt] = Hunter[nCnt];

+		ACCEL( npHunt, npHunt->nDir, 30 + nLevel * 2 );

+		AddHeadObj( &HunterList, npHunt );

+		++nBadGuys;

+	}

+}

+

+//

+// DrawHunters - process and draw the hunter list

+//

+

+VOID NEAR PASCAL DrawHunters( HDC hDC )

+{

+	NPOBJ           npHunt, npNext;

+	LOCAL INT       nNextHunter = 200;

+

+	if (nBadGuys && (--nNextHunter < 0))

+	{

+		CreateHunter();

+		nNextHunter = 1000 + arand( 1000 ) - nLevel * 8;

+	}

+

+	for (npHunt = HeadObj( &HunterList ); npHunt; npHunt = npNext)

+	{

+		NPOBJ           npShot;

+		RECT            rect;

+

+		npNext = NextObj( npHunt );

+

+		MKRECT( &rect, npHunt->Pos, 200 );

+

+		if (PTINRECT( &rect, npPlayer->Pos ))

+		{

+			HitPlayer( hDC, npHunt );

+			--npHunt->nCount;

+			if (npHunt->nCount < 1)

+			{

+				KillBadGuy();

+				npHunt->byColor = CYAN;

+				Explode( hDC, npHunt );

+				RemoveObj( &HunterList, npHunt );

+				AddHeadObj( &FreeList, npHunt );

+			}

+			else if (npHunt->nCount == 1) npHunt->byColor = DKCYAN;

+		}

+		else if (INTRECT(&rect, &rectShotClip))

+		{

+			for (npShot = HeadObj( &ShotList ); npShot; npShot = NextObj( npShot ))

+			{

+				if (!PTINRECT( &rect, npShot->Pos )) continue;

+				npShot->nCount = 1;

+				lScore += npHunt->nCount * 1000;

+				if (--npHunt->nCount < 1)

+				{

+					KillBadGuy();

+					npHunt->byColor = CYAN;

+					Explode( hDC, npHunt );

+					RemoveObj( &HunterList, npHunt );

+					AddHeadObj( &FreeList, npHunt );

+				}

+				else

+				{

+					if (npHunt->nCount == 1) npHunt->byColor = DKCYAN;

+					Hit( hDC, npHunt );

+				}

+				break;

+			}

+		}

+		ACCEL( npHunt, npHunt->nDir, 8 );

+		npHunt->Vel.x -= npHunt->Vel.x / 16;

+		npHunt->Vel.y -= npHunt->Vel.y / 16;

+		if (--npHunt->nDelay <= 0)

+		{

+			npHunt->nDelay = arand( 10 );

+			npHunt->nSpin = arand( 11 ) - 5;

+			FireHunterShot( npHunt );

+		}

+		DrawObject( hDC, npHunt );

+	}

+}

+

+//

+// CreateSwarmer - make a new swarmer

+//

+

+VOID NEAR PASCAL CreateSwarmer( POINT Pos, INT nDir, INT nCount )

+{

+	NPOBJ           npSwarm;

+	INT             nCnt;

+

+	if (npSwarm = RemHeadObj( &FreeList ))

+	{

+		npSwarm->Pos = Pos;

+		npSwarm->Vel.x = npSwarm->Vel.y = 0;

+		npSwarm->nDir = nDir;

+		npSwarm->nSpin = arand( 31 ) - 15;

+		npSwarm->nCount = nCount;

+		npSwarm->nDelay = 64 + arand( 64 );

+		npSwarm->nMass = 32;

+		npSwarm->byColor = DKGREEN;

+		npSwarm->byPts = DIM(Swarmer);

+		for (nCnt = 0; nCnt < DIM(Swarmer); ++nCnt)

+		{

+			npSwarm->Pts[nCnt] = Swarmer[nCnt];

+			npSwarm->Pts[nCnt].y += nCount * 10;

+		}

+		ACCEL( npSwarm, npSwarm->nDir, 30 + nLevel * 2 );

+		AddHeadObj( &SwarmerList, npSwarm );

+		++nBadGuys;

+	}

+}

+

+//

+// DrawSwarmers - process and draw the swarmer list

+//

+

+VOID NEAR PASCAL DrawSwarmers( HDC hDC )

+{

+	NPOBJ           npSwarm, npNext;

+	LOCAL INT       nNextSwarmer = 1000;

+

+	if (nBadGuys && (--nNextSwarmer < 0))

+	{

+		POINT Pos;

+		Pos.x = arand( CLIP_COORD * 2 ) - CLIP_COORD;

+		Pos.y = -CLIP_COORD;

+		CreateSwarmer( Pos, arand( DEGREE_SIZE ), 8 + nLevel * 2 );

+		nNextSwarmer = 1000 + arand( 500 ) - nLevel * 4;

+	}

+

+	for (npSwarm = HeadObj( &SwarmerList ); npSwarm; npSwarm = npNext)

+	{

+		NPOBJ           npShot;

+		RECT            rect;

+

+		npNext = NextObj( npSwarm );

+

+		MKRECT( &rect, npSwarm->Pos, 150 + npSwarm->nCount * 10 );

+

+		if (PTINRECT( &rect, npPlayer->Pos ))

+		{

+			HitPlayer( hDC, npSwarm );

+			npSwarm->nCount = 0;

+		}

+		else if (INTRECT(&rect, &rectShotClip))

+		{

+			for (npShot = HeadObj( &ShotList ); npShot; npShot = NextObj( npShot ))

+			{

+				if (!PTINRECT( &rect, npShot->Pos )) continue;

+				npShot->nCount = 1;

+				lScore += npSwarm->nCount * 25;

+				npSwarm->nCount = 0;

+				break;

+			}

+		}

+		if (npSwarm->nCount <= 0)

+		{

+			npSwarm->byColor = GREEN;

+			KillBadGuy();

+			Explode( hDC, npSwarm );

+			RemoveObj( &SwarmerList, npSwarm );

+			AddHeadObj( &FreeList, npSwarm );

+		}

+		else

+		{

+			if ((npSwarm->nCount > 1) && (--npSwarm->nDelay <= 0))

+			{

+				INT nDir = arand( DEGREE_SIZE );

+				INT nCount = npSwarm->nCount / 2;

+				CreateSwarmer( npSwarm->Pos, nDir, nCount );

+				nCount = npSwarm->nCount - nCount;

+				CreateSwarmer( npSwarm->Pos, nDir + 128, nCount );

+				npSwarm->nCount = 0;

+			}

+			DrawObject( hDC, npSwarm );

+		}

+	}

+}

+

+//

+// CreateSpinner - make a new spinner

+//

+

+VOID NEAR PASCAL CreateSpinner( VOID )

+{

+	NPOBJ           npSpin;

+	INT             nCnt;

+

+	if (npSpin = RemHeadObj( &FreeList ))

+	{

+		npSpin->Pos.x = arand( CLIP_COORD * 2 ) - CLIP_COORD;

+		npSpin->Pos.y = -CLIP_COORD;

+		npSpin->Vel.x = npSpin->Vel.y = 0;

+		npSpin->nDir = arand( DEGREE_SIZE );

+		npSpin->nSpin = -12;

+		npSpin->nCount = 1 + arand( nLevel );

+		npSpin->nMass = 64 + npSpin->nCount * 32;

+		npSpin->byColor = (BYTE)(MAGENTA - npSpin->nCount);

+		npSpin->byPts = DIM(Spinner);

+		for (nCnt = 0; nCnt < DIM(Spinner); ++nCnt)

+			npSpin->Pts[nCnt] = Spinner[nCnt];

+		ACCEL( npSpin, npSpin->nDir, 30 + nLevel * 2 );

+		AddHeadObj( &SpinnerList, npSpin );

+		++nBadGuys;

+	}

+}

+

+//

+// DrawSpinners - process and draw the spinner list

+//

+

+VOID NEAR PASCAL DrawSpinners( HDC hDC )

+{

+	NPOBJ           npSpin, npNext;

+	LOCAL INT       nNextSpinner = 1000;

+

+	if (nBadGuys && (--nNextSpinner < 0))

+	{

+		CreateSpinner();

+		nNextSpinner = 100 + arand( 900 ) - nLevel * 2;

+	}

+

+	for (npSpin = HeadObj( &SpinnerList ); npSpin; npSpin = npNext)

+	{

+		NPOBJ           npShot;

+		INT             nDelta;

+		RECT            rect;

+

+		npNext = NextObj( npSpin );

+

+		MKRECT( &rect, npSpin->Pos, 150 );

+

+		if (PTINRECT( &rect, npPlayer->Pos ))

+		{

+			HitPlayer( hDC, npSpin );

+			--npSpin->nCount;

+			npSpin->byColor = (BYTE)(MAGENTA - npSpin->nCount);

+			if (npSpin->nCount < 1)

+			{

+				KillBadGuy();

+				Explode( hDC, npSpin );

+				RemoveObj( &SpinnerList, npSpin );

+				AddHeadObj( &FreeList, npSpin );

+			}

+		}

+		else if (INTRECT(&rect, &rectShotClip))

+		{

+			for (npShot = HeadObj( &ShotList ); npShot; npShot = NextObj( npShot ))

+			{

+				if (!PTINRECT( &rect, npShot->Pos )) continue;

+				npShot->nCount = 1;

+				lScore += npSpin->nCount * 500;

+				npSpin->byColor = (BYTE)(MAGENTA - (--npSpin->nCount));

+				if (npSpin->nCount < 1)

+				{

+					KillBadGuy();

+					Explode( hDC, npSpin );

+					RemoveObj( &SpinnerList, npSpin );

+					AddHeadObj( &FreeList, npSpin );

+				}

+				else Hit( hDC, npSpin );

+				break;

+			}

+		}

+		nDelta = npPlayer->Pos.x - npSpin->Pos.x;

+		while (nDelta < -16 || nDelta > 16) nDelta /= 2;

+		npSpin->Vel.x += nDelta - npSpin->Vel.x / 16;

+		nDelta = npPlayer->Pos.y - npSpin->Pos.y;

+		while (nDelta < -16 || nDelta > 16) nDelta /= 2;

+		npSpin->Vel.y += nDelta - npSpin->Vel.y / 16;

+		DrawObject( hDC, npSpin );

+	}

+}

+

+//

+// CreateRoid - make a new asteroid

+//

+

+VOID NEAR PASCAL CreateRoid( POINT Pos, POINT Vel, INT nSides, BYTE byColor,

+							 INT nDir, INT nSpeed, INT nSpin )

+{

+	NPOBJ           npRoid;

+	INT             nCnt;

+

+	if (npRoid = RemHeadObj( &FreeList ))

+	{

+		npRoid->Pos = Pos;

+		npRoid->Vel = Vel;

+		npRoid->nMass = nSides * 128;

+		npRoid->nDir = nDir;

+		npRoid->nSpin = nSpin + arand( 11 ) - 5;

+		npRoid->nCount = nSides * 100;

+		npRoid->byColor = byColor;

+		npRoid->byPts = (BYTE)(nSides + 1);

+		for (nCnt = 0; nCnt < nSides; ++nCnt)

+		{

+			npRoid->Pts[nCnt].x = nCnt * DEGREE_SIZE / nSides + arand( 30 );

+			npRoid->Pts[nCnt].y = (nSides - 1) * 100 + 20 + arand( 80 );

+		}

+		npRoid->Pts[nSides] = npRoid->Pts[0];

+		ACCEL( npRoid, nDir, nSpeed );

+		AddHeadObj( &RoidList, npRoid );

+		++nBadGuys;

+	}

+}

+

+//

+// BreakRoid - break up an asteroid

+//

+

+VOID NEAR PASCAL BreakRoid( HDC hDC, NPOBJ npRoid, NPOBJ npShot )

+{

+	INT             nCnt, nNew;

+

+	lScore += npRoid->nCount;

+	if (npShot) npShot->nCount = 1;

+	switch (npRoid->byPts)

+	{

+	case 8:

+		nNew = 2 + arand( 3 );

+		break;

+	case 7:

+		nNew = 1 + arand( 3 );

+		break;

+	case 6:

+		nNew = 1 + arand( 2 );

+		break;

+	case 5:

+		nNew = arand( 2 );

+		break;

+	default:

+		nNew = 0;

+		break;

+	}

+	if (nNew == 1) // don't explode outward

+	{

+		POINT Pt = npRoid->Pos;

+		Pt.x += arand( 301 ) - 150; Pt.y += arand( 301 ) - 150;

+		CreateRoid( Pt, npRoid->Vel, npRoid->byPts - (nNew + 1),

+					npRoid->byColor, npShot->nDir, 8, npRoid->nSpin );

+	}

+	else if (nNew > 0)

+	{

+		INT nSpeed = npRoid->nSpin * npRoid->nSpin * nNew + 16;

+		for (nCnt = 0; nCnt < nNew; ++nCnt)

+		{

+			POINT Pt = npRoid->Pos;

+			Pt.x += arand( 601 ) - 300; Pt.y += arand( 601 ) - 300;

+			CreateRoid( Pt, npRoid->Vel, npRoid->byPts - (nNew + 1),

+						npRoid->byColor,

+						npRoid->nDir + nCnt * DEGREE_SIZE / nNew + arand( 32 ),

+						nSpeed + arand( nLevel * 4 ),

+						npRoid->nSpin / 2 );

+		}

+	}

+	KillBadGuy();

+	++npRoid->byColor;

+	npRoid->nCount = 0;

+	if (nNew)

+	{

+		Hit( hDC, npRoid );

+		DrawObject( hDC, npRoid );

+	}

+	else Explode( hDC, npRoid );

+	RemoveObj( &RoidList, npRoid );

+	AddHeadObj( &FreeList, npRoid );

+}

+

+//

+// DrawRoids - process and draw the asteroid list

+//

+

+VOID NEAR PASCAL DrawRoids( HDC hDC )

+{

+	NPOBJ           npRoid, npNext;

+

+	for (npRoid = HeadObj( &RoidList ); npRoid; npRoid = npNext)

+	{

+		INT             nSize = npRoid->nCount;

+		NPOBJ           npShot;

+		RECT            rect;

+

+		npNext = NextObj( npRoid );

+

+		DrawObject( hDC, npRoid );

+

+		MKRECT( &rect, npRoid->Pos, nSize );

+

+		if (PTINRECT( &rect, npPlayer->Pos ) && HitPlayer( hDC, npRoid ))

+		{

+			npPlayer->nCount = -npPlayer->nCount;

+			npPlayer->byColor = WHITE;

+			Explode( hDC, npPlayer );

+			BreakRoid( hDC, npRoid, NULL );

+			if (nBadGuys) SetRestart( RESTART_LEVEL );

+			else SetRestart( RESTART_NEXTLEVEL );

+		}

+		else if (INTRECT(&rect, &rectShotClip))

+		{

+			for (npShot = HeadObj( &ShotList ); npShot; npShot = NextObj( npShot ))

+			{

+				if (!PTINRECT( &rect, npShot->Pos )) continue;

+				BreakRoid( hDC, npRoid, npShot );

+				break;

+			}

+		}

+	}

+}

+

+//

+// DrawShots - process and draw the player shot list

+//

+

+VOID NEAR PASCAL DrawShots( HDC hDC )

+{

+	NPOBJ           npShot, npNext;

+

+	if (npShot = HeadObj( &ShotList ))

+	{

+		rectShotClip.left = rectShotClip.right = npShot->Pos.x;

+		rectShotClip.top = rectShotClip.bottom = npShot->Pos.y;

+		while (npShot)

+		{

+			npNext = NextObj( npShot );

+			switch (--npShot->nCount)

+			{

+			case 10:

+				npShot->byColor = DKCYAN;

+				break;

+			case 5:

+				npShot->byColor = DKBLUE;

+				break;

+			case 0:

+				RemoveObj( &ShotList, npShot );

+				AddHeadObj( &FreeList, npShot );

+				break;

+			}

+			DrawObject( hDC, npShot );

+			if (npShot->Pos.x < rectShotClip.left) rectShotClip.left = npShot->Pos.x;

+			else if (npShot->Pos.x > rectShotClip.right) rectShotClip.right = npShot->Pos.x;

+			if (npShot->Pos.y < rectShotClip.top) rectShotClip.top = npShot->Pos.y;

+			else if (npShot->Pos.y > rectShotClip.bottom) rectShotClip.bottom = npShot->Pos.y;

+			npShot = npNext;

+		}

+	}

+	else rectShotClip.left = rectShotClip.right = rectShotClip.top = rectShotClip.bottom = 32767;

+}

+

+//

+// DrawFlames - process and draw the flame list

+//

+

+VOID NEAR PASCAL DrawFlames( HDC hDC )

+{

+	NPOBJ           npFlame, npNext;

+

+	for (npFlame = HeadObj( &FlameList ); npFlame; npFlame = npNext)

+	{

+		npNext = NextObj( npFlame );

+		switch (--npFlame->nCount)

+		{

+		case 7:

+			npFlame->byColor = RED;

+			break;

+		case 3:

+			npFlame->byColor = DKRED;

+			break;

+		case 0:

+			RemoveObj( &FlameList, npFlame );

+			AddHeadObj( &FreeList, npFlame );

+			break;

+		}

+		DrawObject( hDC, npFlame );

+	}

+}

+

+//

+// FireShot - fire a bullet

+//

+

+VOID NEAR PASCAL FireShot( VOID )

+{

+	NPOBJ           npShot;

+

+	if (npShot = RemHeadObj( &FreeList ))

+	{

+		npShot->Pos.x = npPlayer->Pos.x;

+		npShot->Pos.y = npPlayer->Pos.y;

+		npShot->Vel.x = npPlayer->Vel.x;

+		npShot->Vel.y = npPlayer->Vel.y;

+		npShot->nMass = 8;

+		npShot->nDir = npPlayer->nDir + arand( 5 ) - 2;

+		npShot->nSpin = 0;

+		npShot->nCount = 16 + arand( 8 );

+		npShot->byColor = CYAN;

+		npShot->byPts = 2;

+		npShot->Pts[0].x = 128;

+		npShot->Pts[0].y = 50;

+		npShot->Pts[1].x = 0;

+		npShot->Pts[1].y = 50;

+		ACCEL( npShot, npShot->nDir, 200 + npShot->nCount );

+		AddHeadObj( &ShotList, npShot );

+	}

+}

+

+//

+// AccelPlayer - move the player forward

+//

+

+VOID NEAR PASCAL AccelPlayer( INT nDir, INT nAccel )

+{

+	NPOBJ           npFlame;

+

+	nDir += npPlayer->nDir;

+	if (nAccel) ACCEL( npPlayer, nDir, nAccel );

+	if (npFlame = RemHeadObj( &FreeList ))

+	{

+		npFlame->Pos.x = npPlayer->Pos.x;

+		npFlame->Pos.y = npPlayer->Pos.y;

+		npFlame->Vel.x = npPlayer->Vel.x;

+		npFlame->Vel.y = npPlayer->Vel.y;

+		npFlame->nDir = nDir + 100 + arand( 57 );

+		npFlame->nSpin = 0;

+		npFlame->nCount = nAccel + arand( 7 );

+		npFlame->byColor = YELLOW;

+		npFlame->byPts = 1;

+		npFlame->Pts[0].x = npFlame->Pts[0].y = 0;

+		ACCEL( npFlame, npFlame->nDir, 50 + arand( 10 ) );

+		AddHeadObj( &FlameList, npFlame );

+	}

+}

+

+//

+// DrawPlayer - process and draw the player

+//

+

+VOID NEAR PASCAL DrawPlayer( HDC hDC )

+{

+	LOCAL INT       nBombing = 0;

+	LOCAL INT       nShotDelay = 0;

+

+	if (npPlayer->nCount <= 0) return;

+

+	if (nSafe > 0)

+	{

+		if (--nSafe == 0)

+		{

+			npPlayer->byColor = (BYTE)(BLACK + npPlayer->nCount);

+			if (npPlayer->byColor > WHITE) npPlayer->byColor = WHITE;

+		}

+	}

+	else if (IsKeyDown( vkShld ) && nShield > 0)

+	{

+		nSafe = 15;

+		if (--nShield > 0) npPlayer->byColor = GREEN;

+		else npPlayer->byColor = DKGREEN;

+	}

+

+	if (nBombing > 0)

+	{

+		if (--nBombing == 0)

+		{

+			ExplodeBadguys( hDC, &SpinnerList );

+			ExplodeBadguys( hDC, &SwarmerList );

+			ExplodeBadguys( hDC, &HunterList );

+		}

+		else

+		{

+			HitList( hDC, &SpinnerList );

+			HitList( hDC, &SwarmerList );

+			HitList( hDC, &HunterList );

+		}

+	}

+	else if (nBomb && IsKeyDown( vkBomb )) --nBomb, nBombing = 5;

+

+	if (IsKeyDown( vkClkw )) npPlayer->nSpin += 8;

+	if (IsKeyDown( vkCtrClkw )) npPlayer->nSpin -= 8;

+	if (IsKeyDown( vkThrst )) AccelPlayer( 0, 12 );

+	if (IsKeyDown( vkRvThrst )) AccelPlayer( 128, 12 );

+	if (nShotDelay) --nShotDelay;

+	else if (IsKeyDown( vkFire )) FireShot(), nShotDelay = 2;

+	DrawObject( hDC, npPlayer );

+	npPlayer->nSpin /= 2;

+}

+

+//

+// GetHyperoidDC - get the correct DC for hyperoid rendering

+//

+

+HDC NEAR PASCAL GetHyperoidDC( HWND hWnd )

+{

+	HDC             hDC;

+	INT             cx, cy;

+	RECT            rect;

+

+	GetClientRect( hWnd, &rect );

+	cx = rect.right - rect.left;

+	cy = rect.bottom - rect.top;

+

+	hDC = GetDC( hWnd );

+

+	// set up the mapping mode

+	SetMapMode( hDC, MM_ISOTROPIC );

+	SetWindowExt( hDC, MAX_COORD, MAX_COORD );

+	SetViewportExt( hDC, cx / 2, -cy / 2 );

+	SetViewportOrg( hDC, cx / 2, cy / 2 );

+

+	// realize the palette

+	SelectPalette( hDC, hAppPalette, 0 );

+	RealizePalette( hDC );

+

+	return( hDC );

+}

+

+//

+// DrawObjects - transform and redraw everything in the system

+//

+

+VOID NEAR PASCAL DrawObjects( HWND hWnd )

+{

+	HDC             hDC = GetHyperoidDC( hWnd );

+

+	// move and draw things (I don't think the order is important...)

+	DrawPlayer( hDC );

+	DrawFlames( hDC );

+	DrawShots( hDC );

+	DrawRoids( hDC );

+	DrawSpinners( hDC );

+	DrawSwarmers( hDC );

+	DrawHunters( hDC );

+	DrawHunterShots( hDC );

+	DrawLetters( hDC );

+	DrawBonuses( hDC );

+	// (...but I'm not changing it!!! :-)

+

+	ReleaseDC( hWnd, hDC );

+}

+

+//

+// SetIndicator - set a quantity indicator

+//

+

+INT NEAR PASCAL SetIndicator( NPSTR npBuff, CHAR IDBitmap, INT nQuant )

+{

+	if (nQuant > 5)

+	{

+		*npBuff++ = IDBitmap; *npBuff++ = IDBitmap;

+		*npBuff++ = IDBitmap; *npBuff++ = IDBitmap;

+		*npBuff++ = IDB_plus;

+	}

+	else

+	{

+		INT nBlank = 5 - nQuant;

+		while (nQuant--) *npBuff++ = IDBitmap;

+		while (nBlank--) *npBuff++ = IDB_blank;

+	}

+	return( 5 );

+}

+

+//

+// CheckScore - show the score and such stuff

+//

+

+VOID NEAR PASCAL CheckScore( HWND hWnd )

+{

+	CHAR            szBuff[sizeof(szScore)];

+	NPSTR           npBuff = szBuff;

+	INT             nLives, nLen, nCnt, x, y;

+	HBITMAP         hbmOld;

+	HDC             hDC, hDCMem;

+

+	if (IsIconic( hWnd )) return;

+	if (lScore - lLastLife > EXTRA_LIFE)

+	{

+		AddExtraLife();

+		lLastLife = lScore;

+	}

+	nLives = ((npPlayer->nCount > 0) ? npPlayer->nCount : -npPlayer->nCount);

+

+	*npBuff++ = IDB_level;

+	wsprintf( npBuff, "%2.2u", nLevel );

+	while (isdigit( *npBuff ))

+		*npBuff = (CHAR)(*npBuff + IDB_num0 - '0'), ++npBuff;

+	*npBuff++ = IDB_blank; *npBuff++ = IDB_score;

+	wsprintf( npBuff, "%7.7lu", lScore );

+	while (isdigit( *npBuff ))

+		*npBuff = (CHAR)(*npBuff + IDB_num0 - '0'), ++npBuff;

+	*npBuff++ = IDB_blank;

+	npBuff += SetIndicator( npBuff, IDB_life, nLives );

+	npBuff += SetIndicator( npBuff, IDB_shield, nShield );

+	npBuff += SetIndicator( npBuff, IDB_bomb, nBomb );

+	nLen = npBuff - szBuff;

+

+	hDC = GetWindowDC( hWnd );

+	IntersectClipRect( hDC, rectScoreClip.left, rectScoreClip.top,

+							rectScoreClip.right, rectScoreClip.bottom );

+	hDCMem = CreateCompatibleDC( hDC );

+	hbmOld = SelectObject( hDCMem, hBitmap[0] );

+	x = rectScoreClip.left;

+	y = rectScoreClip.top;

+

+	for (nCnt = 0; nCnt < nLen; ++nCnt)

+	{

+		if (szBuff[nCnt] != szScore[nCnt])

+		{

+			SelectObject( hDCMem, hBitmap[szBuff[nCnt] - IDB_blank] );

+			BitBlt( hDC, x, y, CX_BITMAP, CY_BITMAP, hDCMem, 0, 0, SRCCOPY );

+			szScore[nCnt] = szBuff[nCnt];

+		}

+		x += CX_BITMAP;

+	}

+	if (nCnt < nScoreLen)

+	{

+		SelectObject( hDCMem, hBitmap[0] );

+		do {

+			if (szScore[nCnt] != IDB_blank)

+			{

+				BitBlt( hDC, x, y, CX_BITMAP, CY_BITMAP, hDCMem, 0, 0, SRCCOPY );

+				szScore[nCnt] = IDB_blank;

+			}

+			x += CX_BITMAP;

+		} while (++nCnt < nScoreLen);

+	}

+	nScoreLen = nLen;

+

+	SelectObject( hDCMem, hbmOld );

+	DeleteDC( hDCMem );

+	ReleaseDC( hWnd, hDC );

+}

+

+//

+// HitList - Hit() a list of things

+//

+

+VOID NEAR PASCAL HitList( HDC hDC, NPLIST npList )

+{

+	NPOBJ           npObj;

+

+	for (npObj = HeadObj( npList ); npObj; npObj = NextObj( npObj ))

+		if (npObj->nCount) Hit( hDC, npObj );

+}

+

+//

+// ExplodeBadguys - explode a list of badguys

+//

+

+VOID NEAR PASCAL ExplodeBadguys( HDC hDC, NPLIST npList )

+{

+	NPOBJ           npObj;

+

+	while (npObj = HeadObj( npList ))

+	{

+		KillBadGuy();

+		npObj->nCount = 0;

+		Explode( hDC, npObj );

+		RemoveObj( npList, npObj );

+		AddHeadObj( &FreeList, npObj );

+	}

+}

+

+//

+// NewGame - start a new game

+//

+

+VOID NEAR PASCAL NewGame( HWND hWnd )

+{

+	HDC             hDC = GetHyperoidDC( hWnd );

+

+	npPlayer->nCount = 0;

+	npPlayer->byColor = WHITE;

+	Explode( hDC, npPlayer );

+	SetRestart( RESTART_GAME );

+	ExplodeBadguys( hDC, &RoidList );

+	ExplodeBadguys( hDC, &SpinnerList );

+	ExplodeBadguys( hDC, &SwarmerList );

+	ExplodeBadguys( hDC, &HunterList );

+

+	ReleaseDC( hWnd, hDC );

+}

+

+//

+// RestartHyperoid - set up a game!

+//

+

+VOID NEAR PASCAL RestartHyperoid( VOID )

+{

+	if (npPlayer->nCount == 0)

+	{

+		POINT Pos, Vel;

+		Pos.x = 0;

+		Pos.y = -CLIP_COORD / 2;

+		Vel.x = 0;

+		Vel.y = 150;

+		PrintLetters( szAppName, Pos, Vel, YELLOW, 800 );

+		npPlayer->nCount = 3;

+		if (lHighScore < lScore) lHighScore = lScore;

+		lLastLife = lScore = 0;

+		nLevel = 0;

+		nShield = nBomb = 3;

+	}

+	else if (npPlayer->nCount < 0)

+	{

+		// cheesy way of restarting after a major collision

+		npPlayer->nCount = -npPlayer->nCount;

+		nShield = nBomb = 3;

+	}

+

+	npPlayer->Pos.x = npPlayer->Pos.y = 0;

+	npPlayer->Vel.x = npPlayer->Vel.y = 0;

+	npPlayer->nDir = 64;

+	npPlayer->nSpin = 0;

+	npPlayer->byColor = GREEN;

+	nSafe = 30;

+

+	if (ShotList.npHead)

+	{

+		NPOBJ npShot;

+		for (npShot = HeadObj( &ShotList ); npShot; npShot = NextObj( npShot ))

+			npShot->nCount = 1;

+	}

+

+	// reseed the asteroid field

+	if (nBadGuys == 0)

+	{

+		INT nCnt;

+		++nLevel;

+		for (nCnt = 5 + nLevel; nCnt; --nCnt)

+		{

+			POINT Pos, Vel;

+			Pos.x = arand( MAX_COORD * 2 ) - MAX_COORD;

+			Pos.y = arand( MAX_COORD * 2 ) - MAX_COORD;

+			Vel.x = Vel.y = 0;

+			CreateRoid( Pos, Vel, 6 + arand( 2 ),

+						(BYTE)(arand( 2 ) ? DKYELLOW : DKGREY),

+						arand( DEGREE_MAX ), 30 + arand( nLevel * 8 ), 0 );

+		}

+	}

+}

+

+//

+// Panic - boss key (or just pause)

+//

+

+VOID NEAR PASCAL Panic( BOOL bPanic )

+{

+	if (bPanic && !bPaused)

+	{

+		bPaused = TRUE;

+		KillTimer( hAppWnd, DRAW_TIMER );

+		SetWindowText( hAppWnd, "Program Manager Help - PROGMAN.HLP" );

+		ShowWindow( hAppWnd, SW_SHOWMINNOACTIVE );

+		InvalidateRect( hAppWnd, NULL, TRUE );

+	}

+	else if (bPaused) // double-panic == normal

+	{

+		bPaused = FALSE;

+		SetWindowText( hAppWnd, szAppName );

+		if (bPanic) ShowWindow( hAppWnd, SW_RESTORE );

+		SetTimer( hAppWnd, DRAW_TIMER, nDrawDelay, NULL );

+	}

+}

+

+//

+// PaintHyperoid - paint the hyperoid window

+//

+

+VOID NEAR PASCAL PaintHyperoid( HWND hWnd )

+{

+	PAINTSTRUCT     ps;

+

+	BeginPaint( hWnd, &ps );

+	if (bPaused) DrawIcon( ps.hdc, 2, 2, LoadIcon( hAppInst, INTRES(IDI_PANIC) ) );

+	EndPaint( hWnd, &ps );

+}

+

+//

+// EraseHyperoidBkgnd - fill in the background

+//

+

+BOOL NEAR PASCAL EraseHyperoidBkgnd( HWND hWnd, HDC hDC )

+{

+	HBRUSH          hbr;

+	RECT            rect;

+

+	GetClientRect( hWnd, &rect );

+

+	if (bPaused)

+	{

+		SetBrushOrg( hDC, 0, 0 );

+		hbr = CreateSolidBrush( GetSysColor( COLOR_BACKGROUND ) );

+	}

+	else

+	{

+		SelectPalette( hDC, hAppPalette, 0 );

+		RealizePalette( hDC );

+		hbr = CreateSolidBrush( PALETTEINDEX( BLACK ) );

+	}

+

+	FillRect( hDC, &rect, hbr );

+	DeleteObject( hbr );

+	return( TRUE );

+}

+

+//

+// DrawShadowRect - draw a shaded rectangle around an object

+//

+

+VOID NEAR PASCAL DrawShadowRect( HDC hDC, NPRECT npRect, HPEN hHi, HPEN hLo )

+{

+	SelectObject( hDC, hHi );

+	MoveTo( hDC, npRect->right, npRect->top );

+	LineTo( hDC, npRect->left, npRect->top );

+	LineTo( hDC, npRect->left, npRect->bottom );

+	SelectObject( hDC, hLo );

+	LineTo( hDC, npRect->right, npRect->bottom );

+	LineTo( hDC, npRect->right, npRect->top );

+}

+

+//

+// NCPaintHyperoid - paint a custom frame

+//

+

+VOID NEAR PASCAL NCPaintHyperoid( HWND hWnd )

+{

+	HDC             hDC, hDCMem;

+	INT             cx, cy, cyCap, h;

+	HPEN            hpenHi, hpenLo;

+	HBRUSH          hbr;

+	HBITMAP         hbm, hbmOld;

+	BITMAP          bm;

+	RECT            rect;

+

+	if (IsIconic( hWnd )) return;

+	hDC = GetWindowDC( hWnd );

+	GetWindowRect( hWnd, &rect );

+	rect.right -= rect.left, rect.left = 0;

+	rect.bottom -= rect.top, rect.top = 0;

+	cx = GetSystemMetrics( SM_CXFRAME );

+	cy = GetSystemMetrics( SM_CYFRAME );

+	cyCap = cy + GetSystemMetrics( SM_CYCAPTION ) - 1;

+	h = rect.bottom - (cyCap + cy);

+

+	SelectPalette( hDC, hAppPalette, 0 );

+	RealizePalette( hDC );

+	if (bBW)

+	{

+		hbr = SelectObject( hDC, CreateSolidBrush( PALETTEINDEX( WHITE ) ) );

+		hpenHi = hPen[BLACK];

+		hpenLo = hPen[BLACK];

+	}

+	else

+	{

+		hbr = SelectObject( hDC, CreateSolidBrush( PALETTEINDEX( GREY ) ) );

+		hpenHi = hPen[WHITE];

+		hpenLo = hPen[DKGREY];

+	}

+

+	PatBlt( hDC, 0, 0, rect.right, cyCap, PATCOPY );

+	PatBlt( hDC, 0, rect.bottom - cy, rect.right, rect.bottom, PATCOPY );

+	PatBlt( hDC, 0, cyCap, cx, h, PATCOPY );

+	PatBlt( hDC, rect.right - cx, cyCap, cx, h, PATCOPY );

+

+	--rect.bottom; --rect.right;

+	DrawShadowRect( hDC, &rect, hpenHi, hpenLo );

+	--cx; --cy;

+	rect.left += cx; rect.top += cy;

+	rect.right -= cx; rect.bottom -= cy;

+	if (!bBW) DrawShadowRect( hDC, &rect, hpenLo, hpenHi );

+

+	// get the title bar rect

+	++rect.left; ++rect.top; --rect.right;

+	rect.bottom = rect.top + cyCap - (cy + 2);

+	DrawShadowRect( hDC, &rect, hpenHi, hpenLo );

+	++rect.right; // for zoom/restore bitmap

+

+	hDCMem = CreateCompatibleDC( hDC );

+

+	hbm = LoadBitmap( NULL, INTRES(OBM_CLOSE) );

+	GetObject( hbm, sizeof(bm), (LPSTR)&bm );

+	bm.bmWidth /= 2; // they packed two images in here!

+	hbmOld = SelectObject( hDCMem, hbm );

+	BitBlt( hDC, rect.left, rect.top, bm.bmWidth, bm.bmHeight, hDCMem, 0, 0, SRCCOPY );

+	rect.left += bm.bmWidth;

+

+	if (IsZoomed( hWnd )) hbm = LoadBitmap( NULL, INTRES(OBM_RESTORE) );

+	else hbm = LoadBitmap( NULL, INTRES(OBM_ZOOM) );

+	GetObject( hbm, sizeof(bm), (LPSTR)&bm );

+	SelectObject( hDCMem, hbm );

+	rect.right -= bm.bmWidth;

+	BitBlt( hDC, rect.right, rect.top, bm.bmWidth, bm.bmHeight, hDCMem, 0, 0, SRCCOPY );

+

+	hbm = LoadBitmap( NULL, INTRES(OBM_REDUCE) );

+	GetObject( hbm, sizeof(bm), (LPSTR)&bm );

+	SelectObject( hDCMem, hbm );

+	rect.right -= bm.bmWidth;

+	BitBlt( hDC, rect.right, rect.top, bm.bmWidth, bm.bmHeight, hDCMem, 0, 0, SRCCOPY );

+

+	--rect.right;

+	DrawShadowRect( hDC, &rect, hpenHi, hpenLo );

+

+	// clip the score to the free titlebar area

+	++rect.left; ++rect.top;

+	rectScoreClip = rect;

+

+	DeleteObject( SelectObject( hDCMem, hbmOld ) );

+	DeleteObject( SelectObject( hDC, hbr ) );

+	DeleteDC( hDCMem );

+	ReleaseDC( hWnd, hDC );

+

+	// make sure the score gets redrawn

+	for (cx = 0; cx < nScoreLen; ++cx) szScore[cx] = '\0';

+}

+

+//

+// HyperoidWndProc - the main window proc for Hyperoid

+//

+

+LONG FAR PASCAL EXPORT HyperoidWndProc( HWND hWnd, unsigned message,

+										WORD wParam, LONG lParam )

+{

+	switch (message)

+	{

+	case WM_CREATE:

+		RestartHyperoid();

+		SetTimer( hWnd, DRAW_TIMER, nDrawDelay, NULL );

+		NCPaintHyperoid( hWnd );

+		break;

+

+	case WM_TIMER:

+		switch (wParam)

+		{

+		case DRAW_TIMER:

+			CheckScore( hWnd );

+			DrawObjects( hWnd );

+			return( 0 );

+

+		case RESTART_TIMER:

+			KillTimer( hWnd, RESTART_TIMER );

+			bRestart = FALSE;

+			RestartHyperoid();

+			return( 0 );

+		}

+		break;

+

+	case WM_SYSCOMMAND:

+		switch (wParam)

+		{

+		case IDM_NEW:

+			NewGame( hWnd );

+			break;

+

+		case IDM_ABOUT:

+			AboutHyperoid( hWnd );

+			break;

+

+		default:

+			return( DefWindowProc( hWnd, message, wParam, lParam ) );

+		}

+		break;

+

+	case WM_QUERYOPEN:

+		Panic( FALSE );

+		return( DefWindowProc( hWnd, message, wParam, lParam ) );

+

+	case WM_CHAR:

+		if (wParam == VK_ESCAPE) Panic( TRUE );

+		break;

+

+	case WM_SYSKEYDOWN:

+	case WM_SYSKEYUP:

+	case WM_SYSCHAR:

+		if (lParam & (1L<<29)) // alt key is down

+		{

+			return( DefWindowProc( hWnd, message, wParam, lParam ) );

+		}

+		switch (wParam)

+		{

+		case VK_ESCAPE:

+			if (message == WM_SYSKEYDOWN) Panic( TRUE );

+			return( 0 );

+		case VK_SPACE:

+		case VK_TAB:

+			return( 0 );

+		default:

+			return( DefWindowProc( hWnd, message, wParam, lParam ) );

+		}

+		break;

+

+	case WM_ERASEBKGND:

+		return( EraseHyperoidBkgnd( hWnd, (HDC)wParam ) );

+

+	case WM_NCACTIVATE:

+	case WM_NCPAINT:

+		NCPaintHyperoid( hWnd );

+		return( TRUE );

+

+	case WM_PAINT:

+		PaintHyperoid( hWnd );

+		break;

+

+	case WM_QUERYNEWPALETTE:

+		{

+			HDC hDC = GetDC( hWnd );

+			SelectPalette( hDC, hAppPalette, 0 );

+			RealizePalette( hDC );

+			ReleaseDC( hWnd, hDC );

+		}

+		return( TRUE );

+

+    case WM_DESTROY:

+		KillTimer( hWnd, DRAW_TIMER );

+		KillTimer( hWnd, RESTART_TIMER );

+		SaveHyperoidWindowPos( hWnd );

+		PostQuitMessage( 0 );

+        break;

+

+	default:

+		return( DefWindowProc( hWnd, message, wParam, lParam ) );

+    }

+	return( 0 );

+}

+

+//

+// InitHyperoid - initialize everything

+//

+

+BOOL NEAR PASCAL InitHyperoid( VOID )

+{

+	DOUBLE          dRad;

+	INT             nCnt;

+

+	// allocate the logical palette

+	hAppPalette = CreateHyperoidPalette();

+	if (!hAppPalette) return( FALSE );

+	for (nCnt = 0; nCnt < PALETTE_SIZE; ++nCnt)

+	{

+		hPen[nCnt] = CreatePen( PS_SOLID, 1, PALETTEINDEX( nCnt ) );

+		if (!hPen[nCnt]) return( FALSE );

+	}

+	for (nCnt = 0; nCnt < IDB_MAX; ++nCnt)

+	{

+		hBitmap[nCnt] = LoadBitmap( hAppInst, INTRES(IDB_blank + nCnt) );

+		if (!hPen[nCnt]) return( FALSE );

+	}

+

+	// seed the randomizer

+	dwSeed = GetCurrentTime();

+

+	// create the lookup table (should use resources)

+	for (nCnt = 0; nCnt < DEGREE_SIZE; ++nCnt)

+	{

+		dRad = nCnt * 6.2831855 / DEGREE_SIZE;

+		nCos[nCnt] = (INT)(DEGREE_MAX * cos( dRad ));

+		nSin[nCnt] = (INT)(DEGREE_MAX * sin( dRad ));

+	}

+

+	// get the initialization file info

+	GetHyperoidIni();

+

+	// allocate all objects as free

+	for (nCnt = 0; nCnt < MAX_OBJS; ++nCnt)

+		AddHeadObj( &FreeList, &(Obj[nCnt]) );

+

+	// set up the player

+	npPlayer = RemHeadObj( &FreeList );

+	npPlayer->byPts = DIM(Player);

+	npPlayer->nMass = 256;

+	for (nCnt = 0; nCnt < DIM(Player); ++nCnt)

+		npPlayer->Pts[nCnt] = Player[nCnt];

+

+	return( TRUE );

+}

+

+//

+// ExitHyperoid - quit the damn game already!

+//

+

+VOID NEAR PASCAL ExitHyperoid( VOID )

+{

+	INT             nCnt;

+

+	if (hAppPalette) DeleteObject( hAppPalette );

+	for (nCnt = 0; nCnt < PALETTE_SIZE; ++nCnt)

+		if (hPen[nCnt]) DeleteObject( hPen[nCnt] );

+	for (nCnt = 0; nCnt < IDB_MAX; ++nCnt)

+		if (hBitmap[nCnt]) DeleteObject( hBitmap[nCnt] );

+}

+

+//

+// WinMain - everybody has to have one

+//

+

+INT FAR PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,

+						LPSTR lpszCmdLine, INT nCmdShow )

+{

+	MSG         msg;

+

+	hAppInst = hInstance;

+	if (!hPrevInstance)

+	{

+		// create the class if we're first

+		if (!CreateHyperoidClass()) return( FALSE );

+	}

+	else

+	{

+		// Copy data from previous instance

+		GetInstanceData( hPrevInstance, (PSTR)szAppName, sizeof(szAppName) );

+	}

+	if (!InitHyperoid()) goto Abort; // I LOVE GOTOS! REALLY I DO!

+	hAppWnd = CreateHyperoidWindow( lpszCmdLine, nCmdShow );

+	if (!hAppWnd) return( FALSE );

+

+	while (GetMessage( &msg, NULL, 0, 0 ))

+	{

+		TranslateMessage( &msg );

+		DispatchMessage( &msg );

+	}

+

+Abort:

+	ExitHyperoid();

+	return( msg.wParam );

+}

diff --git a/test/hyperoid/hyperoid.def b/test/hyperoid/hyperoid.def
new file mode 100644
index 0000000..3309007
--- /dev/null
+++ b/test/hyperoid/hyperoid.def
@@ -0,0 +1,15 @@
+NAME                    Hyperoid

+DESCRIPTION             'Hyperoid Copyright (C) 1990,91 Hutchins Software'

+EXETYPE                 WINDOWS

+STUB                    'WINSTUB.EXE'

+STACKSIZE               4096

+HEAPSIZE                32768

+DATA                    MOVEABLE MULTIPLE

+CODE                    LOADONCALL MOVEABLE DISCARDABLE

+SEGMENTS

+	HYPEROID            LOADONCALL MOVEABLE DISCARDABLE

+	ROIDSUPP            LOADONCALL MOVEABLE DISCARDABLE

+

+EXPORTS

+	HyperoidWndProc     @1

+	HyperoidAboutDlg    @2

diff --git a/test/hyperoid/hyperoid.exe b/test/hyperoid/hyperoid.exe
new file mode 100644
index 0000000..0f34f62
--- /dev/null
+++ b/test/hyperoid/hyperoid.exe
Binary files differ
diff --git a/test/hyperoid/hyperoid.h b/test/hyperoid/hyperoid.h
new file mode 100644
index 0000000..e16b057
--- /dev/null
+++ b/test/hyperoid/hyperoid.h
@@ -0,0 +1,241 @@
+//

+// HYPEROID.H - hyperoid internal header information

+//

+// Version: 1.1  Copyright (C) 1990,91 Hutchins Software

+//      This software is licenced under the GNU General Public Licence

+//      Please read the associated legal documentation

+// Author: Edward Hutchins

+// Revisions:

+//

+

+#ifndef RC_INVOKED

+

+#include <stdlib.h>

+#include <string.h>

+#include <ctype.h>

+#include <math.h>

+#include <limits.h>

+#define OEMRESOURCE

+#include <winext.h>

+

+//

+// typedefs and defines

+//

+

+// color stuff

+#define PALETTE_SIZE 16

+typedef enum

+{

+	BLACK, DKGREY, GREY, WHITE,

+	DKRED, RED, DKGREEN, GREEN, DKBLUE, BLUE,

+	DKYELLOW, YELLOW, DKCYAN, CYAN, DKMAGENTA, MAGENTA

+} COLORS;

+

+// degrees scaled to integer math

+#define DEGREE_SIZE 256

+#define DEGREE_MASK 255

+#define DEGREE_MAX 0x4000

+

+// object limits

+#define MAX_PTS 8

+#define MAX_OBJS 100

+#define MAX_COORD 0x2000

+#define CLIP_COORD (MAX_COORD+300)

+

+// timer stuff

+#define DRAW_TIMER 1

+#define DRAW_DELAY 50

+#define RESTART_TIMER 2

+#define RESTART_DELAY 5000

+

+// restart modes

+typedef enum { RESTART_GAME, RESTART_LEVEL, RESTART_NEXTLEVEL } RESTART_MODE;

+

+// letter scaling

+#define LETTER_MAX 256

+

+// extra life every

+#define EXTRA_LIFE 100000

+

+// list node

+typedef struct tagNODE

+{

+	struct tagNODE  *npNext, *npPrev;

+} NODE;

+pointerdef( NODE );

+

+// list header

+typedef struct

+{

+	NPNODE          npHead, npTail;

+} LIST;

+pointerdef( LIST );

+

+// object descriptor

+typedef struct

+{

+	NODE            Link;               // for object list

+	POINT           Pos;                // position of center of object

+	POINT           Vel;                // velocity in logical units/update

+	INT             nMass;              // mass of object

+	INT             nDir;               // direction in degrees

+	INT             nSpin;              // angular momentum degrees/update

+	INT             nCount;             // used by different objects

+	INT             nDelay;             // used by different objects

+	BYTE            byColor;            // palette color

+	BYTE            byPts;              // number of points in object

+	POINT           Pts[MAX_PTS];       // points making up an object

+	POINT           Old[MAX_PTS];       // last plotted location

+} OBJ;

+pointerdef( OBJ );

+

+//

+// inline macro functions

+//

+

+// function aliases

+#define AddHeadObj(l,o) AddHead((l),((NPNODE)o))

+#define RemHeadObj(l) ((NPOBJ)RemHead(l))

+#define RemoveObj(l,o) Remove((l),((NPNODE)o))

+#define HeadObj(l) ((NPOBJ)((l)->npHead))

+#define NextObj(o) ((NPOBJ)((o)->Link.npNext))

+

+// real-time check of the keyboard

+#define IsKeyDown(x) (GetAsyncKeyState(x)<0)

+

+// I HATE typing this allatime!

+#define INTRES(x) MAKEINTRESOURCE(x)

+

+// size of an array

+#define DIM(x) (sizeof(x)/sizeof((x)[0]))

+

+// faster than MulDiv!

+#define MULDEG(x,y) ((INT)(((LONG)(x)*(y))/DEGREE_MAX))

+

+// DEG - convert an integer into a degree lookup index

+#define DEG(x) ((WORD)(x)&DEGREE_MASK)

+

+// ACCEL - accelerate an object in a given direction

+#define ACCEL(o,d,s) \

+(((o)->Vel.x += MULDEG((s),nCos[DEG(d)])), \

+((o)->Vel.y += MULDEG((s),nSin[DEG(d)])))

+

+// PTINRECT - a faster PtInRect

+#define PTINRECT(r,p) \

+(((r)->left <= (p).x) && ((r)->right > (p).x) && \

+((r)->top <= (p).y) && ((r)->bottom > (p).y))

+

+// INTRECT - a faster IntersectRect that just returns the condition

+#define INTRECT(r1,r2) \

+(((r1)->right >= (r2)->left) && \

+((r1)->left < (r2)->right) && \

+((r1)->bottom >= (r2)->top) && \

+((r1)->top < (r2)->bottom))

+

+// MKRECT - make a rect around a point

+#define MKRECT(r,p,s) \

+(((r)->left = ((p).x-(s))), ((r)->right = ((p).x+(s))), \

+((r)->top = ((p).y-(s))), ((r)->bottom = ((p).y+(s))))

+

+//

+// prototypes

+//

+

+// hyperoid.c

+INT NEAR PASCAL arand( INT x );

+VOID NEAR PASCAL AddHead( NPLIST npList, NPNODE npNode );

+NPNODE NEAR PASCAL RemHead( NPLIST npList );

+VOID NEAR PASCAL Remove( NPLIST npList, NPNODE npNode );

+VOID NEAR PASCAL DrawObject( HDC hDC, NPOBJ npObj );

+VOID NEAR PASCAL SetRestart( BOOL bGameOver );

+VOID NEAR PASCAL AddExtraLife( VOID );

+VOID NEAR PASCAL Hit( HDC hDC, NPOBJ npObj );

+VOID NEAR PASCAL Explode( HDC hDC, NPOBJ npObj );

+BOOL NEAR PASCAL HitPlayer( HDC hDC, NPOBJ npObj );

+NPOBJ FAR PASCAL CreateLetter( CHAR cLetter, INT nSize );

+VOID NEAR PASCAL DrawLetters( HDC hDC );

+VOID NEAR PASCAL DrawHunterShots( HDC hDC );

+VOID NEAR PASCAL FireHunterShot( NPOBJ npHunt );

+VOID NEAR PASCAL CreateHunter( VOID );

+VOID NEAR PASCAL DrawHunters( HDC hDC );

+VOID NEAR PASCAL CreateSpinner( VOID );

+VOID NEAR PASCAL DrawSpinners( HDC hDC );

+VOID NEAR PASCAL CreateRoid( POINT Pos, POINT Vel, INT nSides, BYTE byColor, INT nDir, INT nSpeed, INT nSpin );

+VOID NEAR PASCAL BreakRoid( HDC hDC, NPOBJ npRoid, NPOBJ npShot );

+VOID NEAR PASCAL DrawRoids( HDC hDC );

+VOID NEAR PASCAL DrawShots( HDC hDC );

+VOID NEAR PASCAL DrawFlames( HDC hDC );

+VOID NEAR PASCAL FireShot( VOID );

+VOID NEAR PASCAL AccelPlayer( INT nDir, INT nAccel );

+VOID NEAR PASCAL DrawPlayer( HDC hDC );

+VOID NEAR PASCAL DrawObjects( HWND hWnd );

+VOID NEAR PASCAL CheckScore( HWND hWnd );

+VOID NEAR PASCAL HitList( HDC hDC, NPLIST npList );

+VOID NEAR PASCAL ExplodeBadguys( HDC hDC, NPLIST npList );

+VOID NEAR PASCAL NewGame( HWND hWnd );

+VOID NEAR PASCAL RestartHyperoid( VOID );

+VOID NEAR PASCAL Panic( BOOL bPanic );

+VOID NEAR PASCAL PaintHyperoid( HWND hWnd );

+VOID NEAR PASCAL DisableHyperoidInput( HWND hWnd, BOOL bCapture );

+LONG FAR PASCAL EXPORT HyperoidWndProc( HWND hWnd, unsigned message, WORD wParam, LONG lParam );

+BOOL NEAR PASCAL InitHyperoid( VOID );

+VOID NEAR PASCAL ExitHyperoid( VOID );

+INT FAR PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, INT nCmdShow );

+

+// roidsupp.c

+VOID FAR PASCAL PrintLetters( NPSTR npszText, POINT Pos, POINT Vel, BYTE byColor, INT nSize );

+VOID FAR PASCAL SpinLetters( NPSTR npszText, POINT Pos, POINT Vel, BYTE byColor, INT nSize );

+HPALETTE FAR PASCAL CreateHyperoidPalette( VOID );

+BOOL FAR PASCAL CreateHyperoidClass( VOID );

+VOID NEAR PASCAL SetHyperoidMenu( HWND hWnd, INT nFirstID, INT nLastID );

+HWND FAR PASCAL CreateHyperoidWindow( LPSTR lpszCmd, INT nCmdShow );

+VOID FAR PASCAL SaveHyperoidWindowPos( HWND hWnd );

+VOID FAR PASCAL GetHyperoidIni( VOID );

+VOID FAR PASCAL HyperoidHelp( HWND hWnd );

+BOOL FAR PASCAL EXPORT HyperoidAboutDlg( HWND hDlg, WORD mess, WORD wParam, LONG lParam );

+VOID FAR PASCAL AboutHyperoid( HWND hWnd );

+

+#endif // RC_INVOKED //

+

+//

+// resource IDs

+//

+

+// icons and bitmaps

+#define IDI_HYPEROID    10

+#define IDI_PANIC       20

+

+// bitmaps

+#define IDB_blank       50

+#define IDB_bomb        51

+#define IDB_level       52

+#define IDB_life        53

+#define IDB_num0        54

+#define IDB_num1        55

+#define IDB_num2        56

+#define IDB_num3        57

+#define IDB_num4        58

+#define IDB_num5        59

+#define IDB_num6        60

+#define IDB_num7        61

+#define IDB_num8        62

+#define IDB_num9        63

+#define IDB_plus        64

+#define IDB_score       65

+#define IDB_shield      66

+// additional bitmap stuff

+#define IDB_MAX         17

+#define CX_BITMAP       16

+#define CY_BITMAP       16

+

+// strings

+#define IDS_NAME        100

+

+// menus

+#define IDM_NEW         200

+#define IDM_ABOUT       201

+

+// about box

+#define IDD_ABOUT       500

+#define IDD_A_HELP      501

+#define IDD_A_HISCORE   502

diff --git a/test/hyperoid/hyperoid.ico b/test/hyperoid/hyperoid.ico
new file mode 100644
index 0000000..6641a83
--- /dev/null
+++ b/test/hyperoid/hyperoid.ico
Binary files differ
diff --git a/test/hyperoid/hyperoid.mak b/test/hyperoid/hyperoid.mak
new file mode 100644
index 0000000..c885a1b
--- /dev/null
+++ b/test/hyperoid/hyperoid.mak
@@ -0,0 +1,35 @@
+PROJ	=HYPEROID

+DEBUG	=1

+CC	=qcl

+CFLAGS_G	= /AM /W3 /Ze 

+CFLAGS_D	= /Zi /Od 

+CFLAGS_R	= /O /Ol /Gs /DNDEBUG 

+CFLAGS	=$(CFLAGS_G) $(CFLAGS_D)

+LFLAGS_G	= /CP:0xffff /NOI /SE:0x80 /ST:0x2000 

+LFLAGS_D	= /CO /M 

+LFLAGS_R	= 

+LFLAGS	=$(LFLAGS_G) $(LFLAGS_D)

+RUNFLAGS	=

+OBJS_EXT = 	

+LIBS_EXT = 	

+

+all:	$(PROJ).exe

+

+hyperoid.obj:	hyperoid.c

+

+roidsupp.obj:	roidsupp.c

+

+$(PROJ).exe:	hyperoid.obj roidsupp.obj $(OBJS_EXT)

+	echo >NUL @<<$(PROJ).crf

+hyperoid.obj +

+roidsupp.obj +

+$(OBJS_EXT)

+$(PROJ).exe

+

+$(LIBS_EXT);

+<<

+	ilink -a -e "link $(LFLAGS) @$(PROJ).crf" $(PROJ)

+

+run: $(PROJ).exe

+	$(PROJ) $(RUNFLAGS)

+

diff --git a/test/hyperoid/hyperoid.map b/test/hyperoid/hyperoid.map
new file mode 100644
index 0000000..34edf19
--- /dev/null
+++ b/test/hyperoid/hyperoid.map
@@ -0,0 +1,671 @@
+Stack Allocation = 8192 bytes

+

+ hyperoid

+

+ Start     Length     Name                   Class

+ 0001:0000 022D8H     HYPEROID               CODE

+ 0001:22D8 006E8H     ROIDSUPP               CODE

+ 0001:29C0 02834H     _TEXT                  CODE

+ 0001:5200 026F0H     EMULATOR_TEXT          CODE

+ 0001:78F0 00000H     C_ETEXT                ENDCODE

+ 0002:0000 00170H     EMULATOR_DATA          FAR_DATA

+ 0003:0000 00042H     NULL                   BEGDATA

+ 0003:0042 00A00H     _DATA                  DATA

+ 0003:0A42 00002H     XIQC                   DATA

+ 0003:0A44 0000EH     DBDATA                 DATA

+ 0003:0A52 0000EH     CDATA                  DATA

+ 0003:0A60 00000H     XIFB                   DATA

+ 0003:0A60 00000H     XIF                    DATA

+ 0003:0A60 00000H     XIFE                   DATA

+ 0003:0A60 00000H     XIB                    DATA

+ 0003:0A60 0000CH     XI                     DATA

+ 0003:0A6C 00000H     XIE                    DATA

+ 0003:0A6C 00000H     XPB                    DATA

+ 0003:0A6C 00000H     XP                     DATA

+ 0003:0A6C 00000H     XPE                    DATA

+ 0003:0A6C 00000H     XCB                    DATA

+ 0003:0A6C 00000H     XC                     DATA

+ 0003:0A6C 00000H     XCE                    DATA

+ 0003:0A6C 00000H     XCFB                   DATA

+ 0003:0A6C 00000H     XCF                    DATA

+ 0003:0A6C 00000H     XCFE                   DATA

+ 0003:0A6C 00018H     CONST                  CONST

+ 0003:0A84 00008H     HDR                    MSG

+ 0003:0A8C 001DDH     MSG                    MSG

+ 0003:0C69 00002H     PAD                    MSG

+ 0003:0C6B 00001H     EPAD                   MSG

+ 0003:0C6C 0006EH     _BSS                   BSS

+ 0003:0CDA 00000H     XOB                    BSS

+ 0003:0CDA 00000H     XO                     BSS

+ 0003:0CDA 00000H     XOE                    BSS

+ 0003:0CE0 02616H     c_common               BSS

+ 0003:3300 02000H     STACK                  STACK

+

+ Origin   Group

+ 0003:0   DGROUP

+

+ Address   Export                  Alias

+

+ 0001:28D9 HYPEROIDABOUTDLG        HYPEROIDABOUTDLG

+ 0001:1ECA HYPEROIDWNDPROC         HYPEROIDWNDPROC

+

+  Address         Publics by Name

+

+ 0001:3B44       $I10_OUTPUT

+ 0001:382E       $i8_output

+ 0001:3AEF       $i8_tpwr10

+ 0001:296C       ABOUTHYPEROID

+ 0001:029D       ACCELERATE

+ 0001:18B6       ACCELPLAYER

+ 0001:006B       ADDHEAD

+ 0001:0000       ARAND

+ 0001:13D9       BREAKROID

+ 0001:1B94       CHECKSCORE

+ 0001:0C8A       CREATEHUNTER

+ 0001:2595       CREATEHYPEROIDCLASS

+ 0001:23AC       CREATEHYPEROIDPALETTE

+ 0001:268F       CREATEHYPEROIDWINDOW

+ 0001:08E8       CREATELETTER

+ 0001:12D3       CREATEROID

+ 0001:0F98       CREATESPINNER

+ 0001:1754       DRAWFLAMES

+ 0001:0D5E       DRAWHUNTERS

+ 0001:0AD2       DRAWHUNTERSHOTS

+ 0001:0A44       DRAWLETTERS

+ 0001:02F2       DRAWOBJECT

+ 0001:1AB6       DRAWOBJECTS

+ 0001:198E       DRAWPLAYER

+ 0001:15AC       DRAWROIDS

+ 0001:16C5       DRAWSHOTS

+ 0001:107D       DRAWSPINNERS

+ 0001:1E41       ERASEHYPEROIDBKGND

+ 0001:21CC       EXITHYPEROID

+ 0001:0630       EXPLODE

+ 0001:3552       fFYTOX

+ 0000:FE32  Abs  FIARQQ

+ 0000:0E32  Abs  FICRQQ

+ 0000:5C32  Abs  FIDRQQ

+ 0000:1632  Abs  FIERQQ

+ 0001:0BAC       FIREHUNTERSHOT

+ 0001:17E3       FIRESHOT

+ 0000:0632  Abs  FISRQQ

+ 0000:A23D  Abs  FIWRQQ

+ 0000:4000  Abs  FJARQQ

+ 0000:C000  Abs  FJCRQQ

+ 0000:8000  Abs  FJSRQQ

+ 0001:0547       HIT

+ 0001:0787       HITPLAYER

+ 0001:28D9       HYPEROIDABOUTDLG

+ 0001:28AA       HYPEROIDHELP

+ 0001:1ECA       HYPEROIDWNDPROC

+ 0001:214C       INITHYPEROID

+ 0001:0195       INITOBJECTS

+ 0001:1DF2       PAINTHYPEROID

+ 0001:1D51       PANIC

+ 0003:0CE4       PLOCALHEAP

+ 0001:22D8       PRINTLETTERS

+ 0001:00D0       REMHEAD

+ 0001:0136       REMOVE

+ 0001:1C13       RESTARTHYPEROID

+ 0001:2790       SAVEHYPEROIDWINDOWPOS

+ 0001:2616       SETHYPEROIDMENU

+ 0001:0513       SETRESTART

+ 0001:2222       WINMAIN

+ 0001:317C       _atof

+ 0001:3178       _atoi

+ 0003:32C6       _bPaused

+ 0003:32BE       _bRestart

+ 0001:4AE4       _cos

+ 0003:0C6C       _edata

+ 0003:3300       _end

+ 0003:06AF       _environ

+ 0003:0688       _errno

+ 0001:2B8D       _exit

+ 0003:3086       _FlameList

+ 0003:32C2       _FreeList

+ 0003:30AE       _hAppInst

+ 0003:32D2       _hAppPalette

+ 0003:32C0       _hAppWnd

+ 0003:308E       _hPen

+ 0003:0A38       _HUGE

+ 0003:30B0       _HunterList

+ 0003:0CE8       _HunterShotList

+ 0003:0CE0       _LetterList

+ 0003:0250       _LetterPart

+ 0003:30B8       _lScore

+ 0001:2F34       _malloc

+ 0001:4E30       _matherr

+ 0001:32F4       _memmove

+ 0001:333C       _memset

+ 0003:32BC       _nBadGuys

+ 0003:0CEE       _nCos

+ 0003:32C8       _nGravity

+ 0003:308C       _nLevel

+ 0003:0CEC       _npPlayer

+ 0003:0CE6       _nSafe

+ 0003:32F4       _nShield

+ 0003:30BC       _nSin

+ 0003:0EEE       _Obj

+ 0003:32CE       _RoidList

+ 0003:32CA       _ShotList

+ 0001:4ADE       _sin

+ 0003:30B4       _SpinnerList

+ 0001:3130       _strcmp

+ 0001:30FE       _strcpy

+ 0001:315C       _strlen

+ 0003:32D4       _szAppName

+ 0003:0298       _szLetterDesc

+ 0003:0284       _szNumberDesc

+ 0001:4AE9       _tan

+ 0003:308A       _wTick

+ 0003:09A4       __80x87

+ 0003:066C       __acfinfo

+ 0000:9876  Abs  __acrtmsg

+ 0000:9876  Abs  __acrtused

+ 0000:D6D6  Abs  __aDBdoswp

+ 0003:06BE       __adbgmsg

+ 0003:0650       __aexit_rtn

+ 0001:4AF4       __aFCIcos

+ 0001:4AEE       __aFCIsin

+ 0001:4AF9       __aFCItan

+ 0001:4D08       __aFftol

+ 0001:3386       __aFldiv

+ 0001:3420       __aFlmul

+ 0001:3420       __aFulmul

+ 0003:067A       __aintdiv

+ 0003:06C6       __amblksiz

+ 0001:2AA3       __amsg_exit

+ 0003:0042       __anullsize

+ 0003:0668       __aseghi

+ 0003:066A       __aseglo

+ 0003:0652       __asizds

+ 0003:06E4       __asizeC

+ 0003:06E5       __asizeD

+ 0001:29D0       __astart

+ 0001:51D0       __atold

+ 0003:064E       __atopsp

+ 0001:31C2       __catox

+ 0001:2B9C       __cexit

+ 0001:4A64       __cfltcvt

+ 0003:06C8       __cfltcvt_tab

+ 0001:474E       __cftoe

+ 0001:489C       __cftof

+ 0001:49B2       __cftog

+ 0003:06B6       __child

+ 0001:2AC8       __cinit

+ 0001:2A93       __cintDIV

+ 0001:4BA2       __cintrindisp1

+ 0001:4B79       __cintrindisp2

+ 0001:517A       __cldcvt

+ 0001:4E40       __cldtoe

+ 0001:4FCE       __cldtof

+ 0001:510C       __cldtog

+ 0003:08E2       __cosjmptab

+ 0003:0912       __cotanjmptab

+ 0003:07FC       __cpower

+ 0001:4656       __cropzeros

+ 0001:2C10       __ctermsub

+ 0001:4BD7       __ctrandisp1

+ 0001:4BC4       __ctrandisp2

+ 0003:06E6       __ctype

+ 0003:06E6       __ctype_

+ 0001:2BA6       __c_exit

+ 0001:2AC5       __dataseg

+ 0001:32BB       __DOSCREATECSALIAS

+ 0001:3286       __DOSDEVCONFIG

+ 0003:0693       __doserrno

+ 0001:32D1       __DOSFREESEG

+ 0001:329D       __DOSGETMACHINEMODE

+ 0001:32B2       __DOSSETVEC

+ 0003:0690       __dosvermajor

+ 0003:0691       __dosverminor

+ 0001:32DA       __DOSWRITE

+ 0001:5200       __EmDataSeg

+ 0001:2B94       __exit

+ 0003:08A0       __expjmptab

+ 0003:067E       __fac

+ 0001:46F2       __fassign

+ 0001:36D7       __fFCOS

+ 0001:355E       __fFEXP

+ 0001:3686       __ffexpm1

+ 0001:360B       __fFLN

+ 0001:36F0       __fFSIN

+ 0001:2C50       __FF_MSGBANNER

+ 0001:30DD       __findlast

+ 0001:4D3C       __fltin

+ 0001:4D92       __fltout

+ 0000:9876  Abs  __fltused

+ 0001:45EE       __forcdecpt

+ 0001:5A7F       __fpemulator

+ 0001:5210       __fpemulatorbegin

+ 0001:786F       __fpemulatorend

+ 0001:54DE       __FPEXCEPTION87

+ 0003:0A54       __fpinit

+ 0001:787A       __FPINSTALL87

+ 0001:523A       __fpmath

+ 0001:4DD8       __fpsignal

+ 0002:0169       __fptaskdata

+ 0001:78A9       __FPTERMINATE87

+ 0001:3216       __fptostr

+ 0001:2C72       __fptrap

+ 0001:4D08       __ftol

+ 0001:3000       __growseg

+ 0001:308C       __incseg

+ 0003:07E8       __indefinite

+ 0003:080E       __infinity

+ 0001:4AFE       __Init80x87

+ 0003:06B9       __intno

+ 0001:40DF       __LD12MULT

+ 0001:400A       __LD12MULTTENPOWER

+ 0003:0888       __lnjmptab

+ 0003:0818       __logemax

+ 0003:0870       __logjmptab

+ 0001:4264       __MANTOLD12

+ 0003:0A40       __matherr_flag

+ 0001:2F0E       __myalloc

+ 0003:0695       __nfile

+ 0001:2F3A       __nfree

+ 0003:0654       __nheap_desc

+ 0001:2F5B       __nmalloc

+ 0001:2EAC       __NMSG_TEXT

+ 0001:2ED7       __NMSG_WRITE

+ 0001:2C78       __nullcheck

+ 0003:0693       __oserr

+ 0003:0697       __osfile

+ 0003:0690       __osmajor

+ 0003:0691       __osminor

+ 0003:0692       __osmode

+ 0003:0690       __osversion

+ 0003:06B8       __ovlflag

+ 0003:06BA       __ovlvec

+ 0003:06B1       __pgmptr

+ 0003:07F2       __piby2

+ 0001:46C4       __positive

+ 0003:068E       __psp

+ 0003:068C       __pspadr

+ 0001:351A       __rtbignan

+ 0001:3549       __rtchsifneg

+ 0001:3540       __rtifprojnpop

+ 0001:3521       __rtifprojpop

+ 0001:352B       __rtindfnpop

+ 0001:3528       __rtindfpop

+ 0001:366B       __rtinfnpop

+ 0001:35FE       __rtinfnpopse

+ 0001:3668       __rtinfpop

+ 0001:35FB       __rtinfpopse

+ 0001:34FD       __rtnospop

+ 0001:3501       __rtnospopde

+ 0001:3513       __rtonenpop

+ 0001:3510       __rtonepop

+ 0001:3500       __rttosnpop

+ 0001:3539       __rttosnpopde

+ 0001:34FA       __rttospop

+ 0001:34F7       __rttospopde

+ 0001:3509       __rtzeronpop

+ 0001:3506       __rtzeropop

+ 0001:2F84       __searchseg

+ 0001:2C9C       __setargv

+ 0001:2E2E       __setenvp

+ 0003:06E2       __sigintoff

+ 0003:06E0       __sigintseg

+ 0003:08CA       __sinjmptab

+ 0001:431E       __STRINGTOD

+ 0001:4386       __STRINGTOLD

+ 0003:08FA       __tanjmptab

+ 0001:3452       __trandisp1

+ 0001:3494       __trandisp2

+ 0003:068A       __umaskval

+ 0001:336A       __wrt2err

+ 0003:0840       __ytoxjmptab

+ 0003:0A4A       ___aDBexit

+ 0003:0A50       ___aDBptrchk

+ 0003:0A48       ___aDBrterr

+ 0003:0A46       ___aDBswpchk

+ 0003:0A44       ___aDBswpflg

+ 0003:06AB       ___argc

+ 0003:06AD       ___argv

+ 0003:0A42       ___qczrinit

+

+  Address         Publics by Value

+

+ 0000:0632  Abs  FISRQQ

+ 0000:0E32  Abs  FICRQQ

+ 0000:1632  Abs  FIERQQ

+ 0000:4000  Abs  FJARQQ

+ 0000:5C32  Abs  FIDRQQ

+ 0000:8000  Abs  FJSRQQ

+ 0000:9876  Abs  __acrtmsg

+ 0000:9876  Abs  __acrtused

+ 0000:9876  Abs  __fltused

+ 0000:A23D  Abs  FIWRQQ

+ 0000:C000  Abs  FJCRQQ

+ 0000:D6D6  Abs  __aDBdoswp

+ 0000:FE32  Abs  FIARQQ

+ 0001:0000       ARAND

+ 0001:006B       ADDHEAD

+ 0001:00D0       REMHEAD

+ 0001:0136       REMOVE

+ 0001:0195       INITOBJECTS

+ 0001:029D       ACCELERATE

+ 0001:02F2       DRAWOBJECT

+ 0001:0513       SETRESTART

+ 0001:0547       HIT

+ 0001:0630       EXPLODE

+ 0001:0787       HITPLAYER

+ 0001:08E8       CREATELETTER

+ 0001:0A44       DRAWLETTERS

+ 0001:0AD2       DRAWHUNTERSHOTS

+ 0001:0BAC       FIREHUNTERSHOT

+ 0001:0C8A       CREATEHUNTER

+ 0001:0D5E       DRAWHUNTERS

+ 0001:0F98       CREATESPINNER

+ 0001:107D       DRAWSPINNERS

+ 0001:12D3       CREATEROID

+ 0001:13D9       BREAKROID

+ 0001:15AC       DRAWROIDS

+ 0001:16C5       DRAWSHOTS

+ 0001:1754       DRAWFLAMES

+ 0001:17E3       FIRESHOT

+ 0001:18B6       ACCELPLAYER

+ 0001:198E       DRAWPLAYER

+ 0001:1AB6       DRAWOBJECTS

+ 0001:1B94       CHECKSCORE

+ 0001:1C13       RESTARTHYPEROID

+ 0001:1D51       PANIC

+ 0001:1DF2       PAINTHYPEROID

+ 0001:1E41       ERASEHYPEROIDBKGND

+ 0001:1ECA       HYPEROIDWNDPROC

+ 0001:214C       INITHYPEROID

+ 0001:21CC       EXITHYPEROID

+ 0001:2222       WINMAIN

+ 0001:22D8       PRINTLETTERS

+ 0001:23AC       CREATEHYPEROIDPALETTE

+ 0001:2595       CREATEHYPEROIDCLASS

+ 0001:2616       SETHYPEROIDMENU

+ 0001:268F       CREATEHYPEROIDWINDOW

+ 0001:2790       SAVEHYPEROIDWINDOWPOS

+ 0001:28AA       HYPEROIDHELP

+ 0001:28D9       HYPEROIDABOUTDLG

+ 0001:296C       ABOUTHYPEROID

+ 0001:29D0       __astart

+ 0001:2A93       __cintDIV

+ 0001:2AA3       __amsg_exit

+ 0001:2AC5       __dataseg

+ 0001:2AC8       __cinit

+ 0001:2B8D       _exit

+ 0001:2B94       __exit

+ 0001:2B9C       __cexit

+ 0001:2BA6       __c_exit

+ 0001:2C10       __ctermsub

+ 0001:2C50       __FF_MSGBANNER

+ 0001:2C72       __fptrap

+ 0001:2C78       __nullcheck

+ 0001:2C9C       __setargv

+ 0001:2E2E       __setenvp

+ 0001:2EAC       __NMSG_TEXT

+ 0001:2ED7       __NMSG_WRITE

+ 0001:2F0E       __myalloc

+ 0001:2F34       _malloc

+ 0001:2F3A       __nfree

+ 0001:2F5B       __nmalloc

+ 0001:2F84       __searchseg

+ 0001:3000       __growseg

+ 0001:308C       __incseg

+ 0001:30DD       __findlast

+ 0001:30FE       _strcpy

+ 0001:3130       _strcmp

+ 0001:315C       _strlen

+ 0001:3178       _atoi

+ 0001:317C       _atof

+ 0001:31C2       __catox

+ 0001:3216       __fptostr

+ 0001:3286       __DOSDEVCONFIG

+ 0001:329D       __DOSGETMACHINEMODE

+ 0001:32B2       __DOSSETVEC

+ 0001:32BB       __DOSCREATECSALIAS

+ 0001:32D1       __DOSFREESEG

+ 0001:32DA       __DOSWRITE

+ 0001:32F4       _memmove

+ 0001:333C       _memset

+ 0001:336A       __wrt2err

+ 0001:3386       __aFldiv

+ 0001:3420       __aFulmul

+ 0001:3420       __aFlmul

+ 0001:3452       __trandisp1

+ 0001:3494       __trandisp2

+ 0001:34F7       __rttospopde

+ 0001:34FA       __rttospop

+ 0001:34FD       __rtnospop

+ 0001:3500       __rttosnpop

+ 0001:3501       __rtnospopde

+ 0001:3506       __rtzeropop

+ 0001:3509       __rtzeronpop

+ 0001:3510       __rtonepop

+ 0001:3513       __rtonenpop

+ 0001:351A       __rtbignan

+ 0001:3521       __rtifprojpop

+ 0001:3528       __rtindfpop

+ 0001:352B       __rtindfnpop

+ 0001:3539       __rttosnpopde

+ 0001:3540       __rtifprojnpop

+ 0001:3549       __rtchsifneg

+ 0001:3552       fFYTOX

+ 0001:355E       __fFEXP

+ 0001:35FB       __rtinfpopse

+ 0001:35FE       __rtinfnpopse

+ 0001:360B       __fFLN

+ 0001:3668       __rtinfpop

+ 0001:366B       __rtinfnpop

+ 0001:3686       __ffexpm1

+ 0001:36D7       __fFCOS

+ 0001:36F0       __fFSIN

+ 0001:382E       $i8_output

+ 0001:3AEF       $i8_tpwr10

+ 0001:3B44       $I10_OUTPUT

+ 0001:400A       __LD12MULTTENPOWER

+ 0001:40DF       __LD12MULT

+ 0001:4264       __MANTOLD12

+ 0001:431E       __STRINGTOD

+ 0001:4386       __STRINGTOLD

+ 0001:45EE       __forcdecpt

+ 0001:4656       __cropzeros

+ 0001:46C4       __positive

+ 0001:46F2       __fassign

+ 0001:474E       __cftoe

+ 0001:489C       __cftof

+ 0001:49B2       __cftog

+ 0001:4A64       __cfltcvt

+ 0001:4ADE       _sin

+ 0001:4AE4       _cos

+ 0001:4AE9       _tan

+ 0001:4AEE       __aFCIsin

+ 0001:4AF4       __aFCIcos

+ 0001:4AF9       __aFCItan

+ 0001:4AFE       __Init80x87

+ 0001:4B79       __cintrindisp2

+ 0001:4BA2       __cintrindisp1

+ 0001:4BC4       __ctrandisp2

+ 0001:4BD7       __ctrandisp1

+ 0001:4D08       __aFftol

+ 0001:4D08       __ftol

+ 0001:4D3C       __fltin

+ 0001:4D92       __fltout

+ 0001:4DD8       __fpsignal

+ 0001:4E30       _matherr

+ 0001:4E40       __cldtoe

+ 0001:4FCE       __cldtof

+ 0001:510C       __cldtog

+ 0001:517A       __cldcvt

+ 0001:51D0       __atold

+ 0001:5200       __EmDataSeg

+ 0001:5210       __fpemulatorbegin

+ 0001:523A       __fpmath

+ 0001:54DE       __FPEXCEPTION87

+ 0001:5A7F       __fpemulator

+ 0001:786F       __fpemulatorend

+ 0001:787A       __FPINSTALL87

+ 0001:78A9       __FPTERMINATE87

+ 0002:0169       __fptaskdata

+ 0003:0042       __anullsize

+ 0003:0250       _LetterPart

+ 0003:0284       _szNumberDesc

+ 0003:0298       _szLetterDesc

+ 0003:064E       __atopsp

+ 0003:0650       __aexit_rtn

+ 0003:0652       __asizds

+ 0003:0654       __nheap_desc

+ 0003:0668       __aseghi

+ 0003:066A       __aseglo

+ 0003:066C       __acfinfo

+ 0003:067A       __aintdiv

+ 0003:067E       __fac

+ 0003:0688       _errno

+ 0003:068A       __umaskval

+ 0003:068C       __pspadr

+ 0003:068E       __psp

+ 0003:0690       __osversion

+ 0003:0690       __dosvermajor

+ 0003:0690       __osmajor

+ 0003:0691       __osminor

+ 0003:0691       __dosverminor

+ 0003:0692       __osmode

+ 0003:0693       __oserr

+ 0003:0693       __doserrno

+ 0003:0695       __nfile

+ 0003:0697       __osfile

+ 0003:06AB       ___argc

+ 0003:06AD       ___argv

+ 0003:06AF       _environ

+ 0003:06B1       __pgmptr

+ 0003:06B6       __child

+ 0003:06B8       __ovlflag

+ 0003:06B9       __intno

+ 0003:06BA       __ovlvec

+ 0003:06BE       __adbgmsg

+ 0003:06C6       __amblksiz

+ 0003:06C8       __cfltcvt_tab

+ 0003:06E0       __sigintseg

+ 0003:06E2       __sigintoff

+ 0003:06E4       __asizeC

+ 0003:06E5       __asizeD

+ 0003:06E6       __ctype_

+ 0003:06E6       __ctype

+ 0003:07E8       __indefinite

+ 0003:07F2       __piby2

+ 0003:07FC       __cpower

+ 0003:080E       __infinity

+ 0003:0818       __logemax

+ 0003:0840       __ytoxjmptab

+ 0003:0870       __logjmptab

+ 0003:0888       __lnjmptab

+ 0003:08A0       __expjmptab

+ 0003:08CA       __sinjmptab

+ 0003:08E2       __cosjmptab

+ 0003:08FA       __tanjmptab

+ 0003:0912       __cotanjmptab

+ 0003:09A4       __80x87

+ 0003:0A38       _HUGE

+ 0003:0A40       __matherr_flag

+ 0003:0A42       ___qczrinit

+ 0003:0A44       ___aDBswpflg

+ 0003:0A46       ___aDBswpchk

+ 0003:0A48       ___aDBrterr

+ 0003:0A4A       ___aDBexit

+ 0003:0A50       ___aDBptrchk

+ 0003:0A54       __fpinit

+ 0003:0C6C       _edata

+ 0003:0CE0       _LetterList

+ 0003:0CE4       PLOCALHEAP

+ 0003:0CE6       _nSafe

+ 0003:0CE8       _HunterShotList

+ 0003:0CEC       _npPlayer

+ 0003:0CEE       _nCos

+ 0003:0EEE       _Obj

+ 0003:3086       _FlameList

+ 0003:308A       _wTick

+ 0003:308C       _nLevel

+ 0003:308E       _hPen

+ 0003:30AE       _hAppInst

+ 0003:30B0       _HunterList

+ 0003:30B4       _SpinnerList

+ 0003:30B8       _lScore

+ 0003:30BC       _nSin

+ 0003:32BC       _nBadGuys

+ 0003:32BE       _bRestart

+ 0003:32C0       _hAppWnd

+ 0003:32C2       _FreeList

+ 0003:32C6       _bPaused

+ 0003:32C8       _nGravity

+ 0003:32CA       _ShotList

+ 0003:32CE       _RoidList

+ 0003:32D2       _hAppPalette

+ 0003:32D4       _szAppName

+ 0003:32F4       _nShield

+ 0003:3300       _end

+

+Program entry point at 0001:29D0

+

+ : error L2029: 'ENDDIALOG' : unresolved external

+ : error L2029: 'ISZOOMED' : unresolved external

+ : error L2029: '_main' : unresolved external

+ : error L2029: 'GETPRIVATEPROFILEINT' : unresolved external

+ : error L2029: 'SELECTPALETTE' : unresolved external

+ : error L2029: 'CREATEWINDOW' : unresolved external

+ : error L2029: 'SETBRUSHORG' : unresolved external

+ : error L2029: 'MULDIV' : unresolved external

+ : error L2029: 'MULDIV' : unresolved external

+ : error L2029: '_wsprintf' : unresolved external

+ : error L2029: '_wsprintf' : unresolved external

+ : error L2029: 'GETPRIVATEPROFILESTRING' : unresolved external

+ : error L2029: 'GETASYNCKEYSTATE' : unresolved external

+ : error L2029: 'RELEASEDC' : unresolved external

+ : error L2029: 'DELETEDC' : unresolved external

+ : error L2029: 'POSTQUITMESSAGE' : unresolved external

+ : error L2029: 'MESSAGEBOX' : unresolved external

+ : error L2029: 'UPDATEWINDOW' : unresolved external

+ : error L2029: 'LOADSTRING' : unresolved external

+ : error L2029: 'GETDC' : unresolved external

+ : error L2029: 'MAKEPROCINSTANCE' : unresolved external

+ : error L2029: 'GETCURRENTTIME' : unresolved external

+ : error L2029: 'FREEPROCINSTANCE' : unresolved external

+ : error L2029: 'CREATEIC' : unresolved external

+ : error L2029: 'SETMAPMODE' : unresolved external

+ : error L2029: 'FILLRECT' : unresolved external

+ : error L2029: 'LOADICON' : unresolved external

+ : error L2029: 'REGISTERCLASS' : unresolved external

+ : error L2029: 'LOADCURSOR' : unresolved external

+ : error L2029: 'GETSYSTEMMENU' : unresolved external

+ : error L2029: 'WRITEPRIVATEPROFILESTRING' : unresolved external

+ : error L2029: 'DRAWICON' : unresolved external

+ : error L2029: 'CREATEPEN' : unresolved external

+ : error L2029: 'CREATESOLIDBRUSH' : unresolved external

+ : error L2029: 'SETVIEWPORTORG' : unresolved external

+ : error L2029: 'ENDPAINT' : unresolved external

+ : error L2029: 'TRANSLATEMESSAGE' : unresolved external

+ : error L2029: 'GETMESSAGE' : unresolved external

+ : error L2029: 'SETWINDOWEXT' : unresolved external

+ : error L2029: 'PTINRECT' : unresolved external

+ : error L2029: 'GETDEVICECAPS' : unresolved external

+ : error L2029: 'DELETEOBJECT' : unresolved external

+ : error L2029: 'KILLTIMER' : unresolved external

+ : error L2029: 'DISPATCHMESSAGE' : unresolved external

+ : error L2029: 'SETVIEWPORTEXT' : unresolved external

+ : error L2029: 'DEFWINDOWPROC' : unresolved external

+ : error L2029: 'SHOWWINDOW' : unresolved external

+ : error L2029: 'SHOWWINDOW' : unresolved external

+ : error L2029: 'GETCLIENTRECT' : unresolved external

+ : error L2029: 'INVALIDATERECT' : unresolved external

+ : error L2029: 'SELECTOBJECT' : unresolved external

+ : error L2029: 'GETINSTANCEDATA' : unresolved external

+ : error L2029: 'SETTIMER' : unresolved external

+ : error L2029: 'BEGINPAINT' : unresolved external

+ : error L2029: 'CHANGEMENU' : unresolved external

+ : error L2029: 'GETWINDOWRECT' : unresolved external

+ : error L2029: 'CREATEPALETTE' : unresolved external

+ : error L2029: 'POLYLINE' : unresolved external

+ : error L2029: 'DIALOGBOX' : unresolved external

+ : error L2029: 'REALIZEPALETTE' : unresolved external

+ : error L2029: 'SETPIXEL' : unresolved external

+ : error L2029: 'GETSYSCOLOR' : unresolved external

+ : error L2029: 'SETWINDOWTEXT' : unresolved external

+

diff --git a/test/hyperoid/hyperoid.rc b/test/hyperoid/hyperoid.rc
new file mode 100644
index 0000000..4f8afb7
--- /dev/null
+++ b/test/hyperoid/hyperoid.rc
@@ -0,0 +1,59 @@
+//

+// HYPEROID.RC - orbiter resources

+//

+

+#include <windows.h>

+#include "hyperoid.h"

+

+IDI_HYPEROID ICON "hyperoid.ico"

+IDI_PANIC ICON "panic.ico"

+

+STRINGTABLE

+{

+	IDS_NAME, "Hyperoid"

+	IDM_NEW, "New Game&!"

+	IDM_ABOUT, "&About..."

+}

+

+//

+// About box

+//

+

+IDD_ABOUT DIALOG LOADONCALL MOVEABLE DISCARDABLE 30, 30, 150, 120

+CAPTION "About"

+STYLE WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SYSMENU | WS_VISIBLE | DS_MODALFRAME | WS_POPUP

+{

+	CTEXT           "Hyperoid",                         -1, 0, 10, 150, 8

+	CTEXT           "The classic game",                 -1, 0, 20, 150, 8

+	CTEXT           "Version 1.1",                      -1, 0, 30, 150, 8

+	CTEXT           "Copyright © 1991 Hutchins Software", -1, 0, 45, 150, 8

+	CTEXT           "This program is freeware",         -1, 0, 55, 150, 8

+	CTEXT           "Author: Edward Hutchins",          -1, 0, 65, 150, 8

+	CTEXT           "eah1@cec1.wustl.edu",              -1, 0, 75, 150, 8

+	CTEXT           "",                                 IDD_A_HISCORE, 0, 85, 150, 8

+	ICON            IDI_HYPEROID,                       -1, 10, 16, 0, 0

+	DEFPUSHBUTTON   "Ok!", IDOK,                        20, 100, 40, 12

+	CONTROL         "&Help", IDD_A_HELP,                "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 90, 100, 40, 12

+}

+

+//

+// bitmaps

+//

+

+IDB_blank   BITMAP DISCARDABLE  "blank.bmp"

+IDB_bomb    BITMAP DISCARDABLE  "bomb.bmp"

+IDB_level   BITMAP DISCARDABLE  "level.bmp"

+IDB_life    BITMAP DISCARDABLE  "life.bmp"

+IDB_num0    BITMAP DISCARDABLE  "num0.bmp"

+IDB_num1    BITMAP DISCARDABLE  "num1.bmp"

+IDB_num2    BITMAP DISCARDABLE  "num2.bmp"

+IDB_num3    BITMAP DISCARDABLE  "num3.bmp"

+IDB_num4    BITMAP DISCARDABLE  "num4.bmp"

+IDB_num5    BITMAP DISCARDABLE  "num5.bmp"

+IDB_num6    BITMAP DISCARDABLE  "num6.bmp"

+IDB_num7    BITMAP DISCARDABLE  "num7.bmp"

+IDB_num8    BITMAP DISCARDABLE  "num8.bmp"

+IDB_num9    BITMAP DISCARDABLE  "num9.bmp"

+IDB_plus    BITMAP DISCARDABLE  "plus.bmp"

+IDB_score   BITMAP DISCARDABLE  "score.bmp"

+IDB_shield  BITMAP DISCARDABLE  "shield.bmp"

diff --git a/test/hyperoid/level.bmp b/test/hyperoid/level.bmp
new file mode 100644
index 0000000..eb1f03e
--- /dev/null
+++ b/test/hyperoid/level.bmp
Binary files differ
diff --git a/test/hyperoid/life.bmp b/test/hyperoid/life.bmp
new file mode 100644
index 0000000..70fd623
--- /dev/null
+++ b/test/hyperoid/life.bmp
Binary files differ
diff --git a/test/hyperoid/list.c b/test/hyperoid/list.c
new file mode 100644
index 0000000..e427064
--- /dev/null
+++ b/test/hyperoid/list.c
@@ -0,0 +1,61 @@
+//

+// LIST - list processing functions for orbiter

+//

+// Version: 1.0  Copyright (C) 1990, Hutchins Software

+// Author: Edward Hutchins

+// Revisions:

+//

+

+#include "orbiter.h"

+

+//

+// AddHead - add an object to the head of a list

+//

+

+VOID FAR PASCAL AddHead( NPLIST npList, NPNODE npNode )

+{

+	if (npList->npHead)

+	{

+		npNode->npNext = npList->npHead;

+		npNode->npPrev = NULL;

+		npList->npHead = (npList->npHead->npPrev = npNode);

+	}

+	else // add to an empty list

+	{

+		npList->npHead = npList->npTail = npNode;

+		npNode->npNext = npNode->npPrev = NULL;

+	}

+}

+

+//

+// RemHead - remove the first element in a list

+//

+

+NPNODE FAR PASCAL RemHead( NPLIST npList )

+{

+	if (npList->npHead)

+	{

+		NPNODE npNode = npList->npHead;

+		if (npList->npTail != npNode)

+		{

+			npList->npHead = npNode->npNext;

+			npNode->npNext->npPrev = NULL;

+		}

+		else npList->npHead = npList->npTail = NULL;

+		return( npNode );

+	}

+	else return( NULL );

+}

+

+//

+// Remove - remove an arbitrary element from a list

+//

+

+VOID FAR PASCAL Remove( NPLIST npList, NPNODE npNode )

+{

+	if (npNode->npPrev) npNode->npPrev->npNext = npNode->npNext;

+	else npList->npHead = npNode->npNext;

+	if (npNode->npNext) npNode->npNext->npPrev = npNode->npPrev;

+	else npList->npTail = npNode->npPrev;

+}

+

diff --git a/test/hyperoid/makefile.mk b/test/hyperoid/makefile.mk
new file mode 100644
index 0000000..61c3938
--- /dev/null
+++ b/test/hyperoid/makefile.mk
@@ -0,0 +1,26 @@
+########################################################

+#

+#   hyperoid makefile

+#

+#   Copyright (C) 1988-1990 Lantern Corp.

+#

+########################################################

+

+# This is just a teaser to show how little you have to do to make projects

+# under Lantern Corp.'s software engineering system. To make Hyperoid on

+# your system, make sure <winext.h> is in your include path and set up your

+# makefile like you normally do for your own stuff.

+# I'll (hopefully) post the 100k of stuff you need for this makefile to

+# be usefull. I'll have to talk to my boss first...

+# P.S. The system only works for the Mircosoft C6.0 compiler, but its easy

+# enough to change.

+# P.P.S. I hate every integrated environment I've run across so far, thus

+# the system is run from a command prompt.

+

+PROJ = hyperoid

+OBJS = hyperoid.obj roidsupp.obj

+RESS = hyperoid.res

+LIBS =

+

+!include <windows.mk>

+

diff --git a/test/hyperoid/num0.bmp b/test/hyperoid/num0.bmp
new file mode 100644
index 0000000..9dfa846
--- /dev/null
+++ b/test/hyperoid/num0.bmp
Binary files differ
diff --git a/test/hyperoid/num1.bmp b/test/hyperoid/num1.bmp
new file mode 100644
index 0000000..302d0f9
--- /dev/null
+++ b/test/hyperoid/num1.bmp
Binary files differ
diff --git a/test/hyperoid/num2.bmp b/test/hyperoid/num2.bmp
new file mode 100644
index 0000000..c1b70fa
--- /dev/null
+++ b/test/hyperoid/num2.bmp
Binary files differ
diff --git a/test/hyperoid/num3.bmp b/test/hyperoid/num3.bmp
new file mode 100644
index 0000000..f8b9971
--- /dev/null
+++ b/test/hyperoid/num3.bmp
Binary files differ
diff --git a/test/hyperoid/num4.bmp b/test/hyperoid/num4.bmp
new file mode 100644
index 0000000..4ce4a6c
--- /dev/null
+++ b/test/hyperoid/num4.bmp
Binary files differ
diff --git a/test/hyperoid/num5.bmp b/test/hyperoid/num5.bmp
new file mode 100644
index 0000000..ce2ca46
--- /dev/null
+++ b/test/hyperoid/num5.bmp
Binary files differ
diff --git a/test/hyperoid/num6.bmp b/test/hyperoid/num6.bmp
new file mode 100644
index 0000000..af200bd
--- /dev/null
+++ b/test/hyperoid/num6.bmp
Binary files differ
diff --git a/test/hyperoid/num7.bmp b/test/hyperoid/num7.bmp
new file mode 100644
index 0000000..d5eaf6c
--- /dev/null
+++ b/test/hyperoid/num7.bmp
Binary files differ
diff --git a/test/hyperoid/num8.bmp b/test/hyperoid/num8.bmp
new file mode 100644
index 0000000..3a9eeb0
--- /dev/null
+++ b/test/hyperoid/num8.bmp
Binary files differ
diff --git a/test/hyperoid/num9.bmp b/test/hyperoid/num9.bmp
new file mode 100644
index 0000000..d2b18d2
--- /dev/null
+++ b/test/hyperoid/num9.bmp
Binary files differ
diff --git a/test/hyperoid/panic.ico b/test/hyperoid/panic.ico
new file mode 100644
index 0000000..6be4492
--- /dev/null
+++ b/test/hyperoid/panic.ico
Binary files differ
diff --git a/test/hyperoid/plus.bmp b/test/hyperoid/plus.bmp
new file mode 100644
index 0000000..4beda94
--- /dev/null
+++ b/test/hyperoid/plus.bmp
Binary files differ
diff --git a/test/hyperoid/read.me b/test/hyperoid/read.me
new file mode 100644
index 0000000..65f70db
--- /dev/null
+++ b/test/hyperoid/read.me
@@ -0,0 +1,109 @@
+****************************************************************************

+LEGAL JUNK:

+

+	Hyperoid - a game for Mircosoft Windows (tm)

+	Copyright (C) 1991 Edward Hutchins

+	internet: eah1@cec1.wustl.edu

+	usnail: c/o Edward Hutchins, 63 Ridgemoor Dr., Clayton, MO 63105

+

+	This program is free software; you can redistribute it and/or modify

+	it under the terms of the GNU General Public License as published by

+	the Free Software Foundation; either version 1, or (at your option)

+	any later version.

+

+	This program 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 General Public License for more details.

+

+	You should have received a copy of the GNU General Public License

+	along with this program; if not, write to the Free Software

+	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

+

+Note: Windows is a trademark of Microsoft Corp. (Duh)

+

+With this aside,

+****************************************************************************

+

+Hello, and Welcome to Hyperoid version 1.1!

+

+The object of the game is intuitive---shoot everything! (Well, almost

+everything, heh heh!). If the keyboard buffer overflows in all the

+excitement, ignore the beeps you hear and they'll go away.

+

+Hyperoids uses the palette manager, so if you have a palette-capable display

+(and you read the on-line help pages) you should be able to set up better

+colors than the Windows defaults. I have tested hyperoids on a monochrome

+'286, and it seems to work fine. If you want to re-map the keys, look at

+Appendix A (or the Windows SDK) for some non-ASCII virtual key codes.

+

+The source is available through the same channel that you got the executable

+through, as per the GNU general public licence. Please read the licence if

+you have any questions, or contact me at the above addresses (email

+preferred).

+

+If you make modifications/bug fixes to Hyperoid, please use me as a clearing

+house to prevent versions flooding out into the universe. (You don't have to,

+but I'd appreciate it :-). If you write the world's greatest game using some

+of my source, please send me note telling what it is and where it's available.

+

+Changes since 1.0:

+	Explosion processing a little faster

+	Swarmers (little green guys) no longer flood the system

+	Scoring is better

+	Extra lives every 100,000 points (not 50,000)

+	Firepower reduced a little (hey, the game was too darn easy)

+	Spinning Game Over (Oooooh...)

+

+Look for:

+  ls - *nix ls command with MUCHO bells&whistles (couldn't live w/out it!)

+  blitfix - util that sets the CS_BYTEALIGNCLIENT bit on all top windows

+			(speeds up my 1024x768 display by a factor of 3)

+  eyecon - xeyes clone (may have to be renamed)

+  ilbm - Amiga IFF bitmap viewer (supports HAM mode and palettes!)

+  life - 7 blit life with a few bells&whistles

+  loadmon - nifty system performance monitor

+  mbrot - mandelbrot hack that runs in the background

+  yow - Zippy the Pinhead in his very own icon, telling it like it is

+  (more games... stuff... junk...)

+Coming real soon now to a (net,BBS,Wherever this stuff ends up) near YOU!

+

+Appendix A: Virtual Key Codes

+-----------------------------

+

+	VK_TAB              9 = default shields

+	VK_RETURN           13

+	VK_SHIFT            16

+	VK_CONTROL          17

+	VK_CAPITAL          20 - useful for autofire!

+	VK_ESCAPE           27 = default boss key

+	VK_SPACE            32 = default fire key

+	VK_PRIOR            33

+	VK_NEXT             34

+	VK_END              35

+	VK_HOME             36

+	VK_LEFT             37 = default counter-clockwise key

+	VK_UP               38 = default reverse thrust key

+	VK_RIGHT            39 = default clockwise key

+	VK_DOWN             40 = default thrust key

+	VK_INSERT           45

+	VK_DELETE           46

+	VK_A-VK_Z           64-90, 83 = default smartbomb key (ASCII 'S')

+	VK_NUMPAD0          96

+	VK_NUMPAD1          97

+	VK_NUMPAD2          98

+	VK_NUMPAD3          99

+	VK_NUMPAD4          100

+	VK_NUMPAD5          101

+	VK_NUMPAD6          102

+	VK_NUMPAD7          103

+	VK_NUMPAD8          104

+	VK_NUMPAD9          105

+	VK_MULTIPLY         106

+	VK_ADD              107

+	VK_SEPARATOR        108

+	VK_SUBTRACT         109

+	VK_DECIMAL          110

+	VK_DIVIDE           111

+	VK_F1-VK_F16        112-127

+

diff --git a/test/hyperoid/roidsupp.c b/test/hyperoid/roidsupp.c
new file mode 100644
index 0000000..3da30f1
--- /dev/null
+++ b/test/hyperoid/roidsupp.c
@@ -0,0 +1,497 @@
+//

+// ROIDSUPP - hyperoid support functions

+//

+// Version: 1.1  Copyright (C) 1991, Hutchins Software

+//      This software is licenced under the GNU General Public Licence

+//      Please read the associated legal documentation

+// Author: Edward Hutchins

+// Revisions:

+// 11/01/91 added GNU General Public License - Ed.

+//

+

+#include "hyperoid.h"

+

+//

+// defines

+//

+

+// you may ask, "why did he embed all these string constants instead of

+// using the resource file?". Good question. The answer is: I feel better

+// knowing this stuff is part of the executable, and not part of the resource

+// file (which can be changed by sneaky people). Or maybe I wuz lazy.

+// If you don't like it, then YOU can change it!

+

+#define NL "\x0d\x0a"

+

+#define HYPEROID_HELP \

+"The following keys control your ship:" NL NL \

+"  Left, Right Arrow .... spin left or right" NL \

+"  Down, Up Arrow ..... forward or reverse thrust" NL \

+"  Space Bar .............. fire!" NL \

+"  Tab ......................... shields" NL \

+"  S ............................. smartbomb" NL \

+"  Esc ......................... pause/boss key" NL NL \

+"Note: You have 3 lives, unlimited fuel and firepower, 3 shields and 3 " \

+"smartbombs. Your ship gets darker when you lose a life, but you keep on " \

+"playing (unless you hit an asteroid). You get an extra life every 100,000 " \

+"points. When you lose the game, you start over immediately and can finish " \

+"off the current level (which should now be 0) before starting over at " \

+"level 1 (There is no waiting around between games)."

+

+#define HYPEROID_HELP2 \

+"The HYPEROID.INI file can be created/modified to change default settings " \

+"in Hyperoid. Here are some of the items you can set:" NL \

+NL "[Hyperoid]" NL "Max=<0/1>" NL "{X,Y,W,H}=<n>" NL "Mono=<0/1>" NL \

+"DrawDelay=<ms> ;microseconds/frame" NL \

+NL "[Palette]" NL \

+"{Black,DkGrey,Grey,White," NL \

+" DkRed,Red,DkGreen,Green,DkBlue,Blue," NL \

+" DkYellow,Yellow,DkCyan,Cyan," NL \

+" DkMagenta,Magenta}=<r>,<g>,<b>" NL \

+NL "[Keys]" NL \

+"{Shield,Clockwise,CtrClockwise," NL \

+" Thrust,RevThrust,Fire,Bomb}=<virtual keycode>" NL NL \

+"Note: Virtual keycodes usually match the key's ASCII value."

+

+#define HYPEROID_HELPSTYLE (MB_OK | MB_ICONASTERISK)

+

+// this is the part I especially want in the executable image

+

+#define HYPEROID_LICENSE \

+"This program is free software; you can redistribute it and/or modify " \

+"it under the terms of the GNU General Public License as published by " \

+"the Free Software Foundation; either version 1, or (at your option) " \

+"any later version. " \

+NL NL \

+"This program 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 General Public License for more details. " \

+NL NL \

+"You should have received a copy of the GNU General Public License " \

+"along with this program; if not, write to the Free Software " \

+"Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. "

+

+//

+// imports

+//

+

+IMPORT CHAR         szAppName[32] FROM( hyperoid.c );

+IMPORT HANDLE       hAppInst FROM( hyperoid.c );

+IMPORT BOOL         bBW FROM( hyperoid.c );

+IMPORT INT          nDrawDelay FROM( hyperoid.c );

+IMPORT INT          vkShld FROM( hyperoid.c );

+IMPORT INT          vkClkw FROM( hyperoid.c );

+IMPORT INT          vkCtrClkw FROM( hyperoid.c );

+IMPORT INT          vkThrst FROM( hyperoid.c );

+IMPORT INT          vkRvThrst FROM( hyperoid.c );

+IMPORT INT          vkFire FROM( hyperoid.c );

+IMPORT INT          vkBomb FROM( hyperoid.c );

+IMPORT LONG         lHighScore FROM( hyperoid.c );

+

+//

+// globals

+//

+

+// these parts map to "abcdefghijklm"

+GLOBAL POINT        LetterPart[] =

+{

+	{83, 572}, {64, 512}, {45, 572}, {96, 362}, {32, 362},

+	{128, 256}, {0, 0}, {0, 256},

+	{160, 362}, {224, 362}, {173, 572}, {192, 512}, {211, 572}

+};

+// here's the vector font

+GLOBAL NPSTR        szNumberDesc[] =

+{

+	"cakmck",       // 0

+	"dbl",          // 1

+	"abekm",        // 2

+	"abegjlk",      // 3

+	"mcfh",         // 4

+	"cbfgjlk",      // 5

+	"bdiljgi",      // 6

+	"acgl",         // 7

+	"bdjlieb",      // 8

+	"ljebdge"       // 9

+};

+GLOBAL NPSTR        szLetterDesc[] =

+{

+	"kdbemhf",      // A

+	"kabegjlk",     // B

+	"cbflm",        // C

+	"kabejlk",      // D

+	"cafgfkm",      // E

+	"cafgfk",       // F

+	"bdiljhg",      // G

+	"kafhcm",       // H

+	"bl",           // I

+	"cjli",         // J

+	"akcgm",        // K

+	"akm",          // L

+	"kagcm",        // M

+	"kamc",         // N

+	"bdiljeb",      // O

+	"kabegf",       // P

+	"mlidbejl",     // Q

+	"kabegfgm",     // R

+	"ebdjli",       // S

+	"lbac",         // T

+	"ailjc",        // U

+	"alc",          // V

+	"akgmc",        // W

+	"amgkc",        // X

+	"aglgc",        // Y

+	"ackm"          // Z

+};

+

+//

+// locals

+//

+

+LOCAL CHAR          szIni[] = "HYPEROID.INI";

+LOCAL CHAR          szLicense[] = "LicenseRead";

+LOCAL CHAR          szDrawDelay[] = "DrawDelay";

+LOCAL CHAR          szMax[] = "Max";

+LOCAL CHAR          szX[] = "X";

+LOCAL CHAR          szY[] = "Y";

+LOCAL CHAR          szW[] = "W";

+LOCAL CHAR          szH[] = "H";

+LOCAL CHAR          szBW[] = "Mono";

+LOCAL CHAR          szPalette[] = "Palette";

+LOCAL CHAR          szKeys[] = "Keys";

+LOCAL CHAR          szShield[] = "Shield";

+LOCAL CHAR          szClockwise[] = "Clockwise";

+LOCAL CHAR          szCtrClockwise[] = "CtrClockwise";

+LOCAL CHAR          szThrust[] = "Thrust";

+LOCAL CHAR          szRevThrust[] = "RevThrust";

+LOCAL CHAR          szFire[] = "Fire";

+LOCAL CHAR          szBomb[] = "Bomb";

+LOCAL CHAR          szHi[] = "Hi";

+LOCAL CHAR          *szColorName[] =

+{

+	"Black", "DkGrey", "Grey", "White",

+	"DkRed", "Red",  "DkGreen", "Green", "DkBlue", "Blue",

+	"DkYellow", "Yellow", "DkCyan", "Cyan", "DkMagenta", "Magenta"

+};

+LOCAL DWORD         dwColors[] =

+{

+	RGB(0,0,0), RGB(128,128,128),

+	RGB(192,192,192), RGB(255,255,255),

+	RGB(128,0,0), RGB(255,0,0),

+	RGB(0,128,0), RGB(0,255,0),

+	RGB(0,0,128), RGB(0,0,255),

+	RGB(128,128,0), RGB(255,255,0),

+	RGB(0,128,128), RGB(0,255,255),

+	RGB(128,0,128), RGB(255,0,255),

+};

+

+//

+// PrintLetters - create letter objects from a string

+//

+

+VOID FAR PASCAL PrintLetters( NPSTR npszText, POINT Pos, POINT Vel,

+							  BYTE byColor, INT nSize )

+{

+	INT             nLen = strlen( npszText );

+	INT             nCnt = nLen;

+	INT             nSpace = nSize + nSize / 2;

+	INT             nBase = (nLen - 1) * nSpace;

+	INT             nBaseStart = Pos.x + nBase / 2;

+

+	while (nCnt--)

+	{

+		NPOBJ npLtr = CreateLetter( npszText[nCnt], nSize / 2 );

+		if (npLtr)

+		{

+			npLtr->Pos.x = nBaseStart;

+			npLtr->Pos.y = Pos.y;

+			npLtr->Vel = Vel;

+			npLtr->byColor = byColor;

+		}

+		nBaseStart -= nSpace;

+	}

+}

+

+//

+// SpinLetters - spin letter objects away from center for effect

+//

+

+VOID FAR PASCAL SpinLetters( NPSTR npszText, POINT Pos, POINT Vel,

+							 BYTE byColor, INT nSize )

+{

+	INT             nLen = strlen( npszText );

+	INT             nCnt = nLen;

+	INT             nSpace = nSize + nSize / 2;

+	INT             nBase = (nLen - 1) * nSpace;

+	INT             nBaseStart = Pos.x + nBase / 2;

+

+	while (nCnt--)

+	{

+		NPOBJ npLtr = CreateLetter( npszText[nCnt], nSize / 2 );

+		if (npLtr)

+		{

+			INT nSpin = (nCnt - nLen / 2) * 2;

+			npLtr->Pos.x = nBaseStart;

+			npLtr->Pos.y = Pos.y;

+			npLtr->Vel = Vel;

+			npLtr->Vel.x += nSpin * 16;

+			npLtr->nSpin = -nSpin;

+			npLtr->byColor = byColor;

+		}

+		nBaseStart -= nSpace;

+	}

+}

+

+//

+// CreateHyperoidPalette - create a logical palette

+//

+

+HPALETTE FAR PASCAL CreateHyperoidPalette( VOID )

+{

+	HPALETTE        hPalette;

+	HDC             hIC = CreateIC( "DISPLAY", NULL, NULL, NULL );

+	INT             t;

+	PALETTEENTRY    Pal[PALETTE_SIZE + 2];

+	NPLOGPALETTE    npLogPalette = (NPLOGPALETTE)Pal;

+

+	// are we forced into using b&w?

+	bBW = FALSE;

+	if (GetDeviceCaps( hIC, NUMCOLORS ) < 8) bBW = TRUE;

+	DeleteDC( hIC );

+	if (GetPrivateProfileInt( szAppName, szBW, FALSE, szIni )) bBW = TRUE;

+

+	npLogPalette->palVersion = 0x0300;

+	npLogPalette->palNumEntries = PALETTE_SIZE;

+

+	for (t = 0; t < PALETTE_SIZE; ++t)

+	{

+		DWORD           dwColor = dwColors[t];

+		CHAR            szBuff[32];

+

+		GetPrivateProfileString( szPalette, szColorName[t], "",

+								 szBuff, sizeof(szBuff), szIni );

+		if (szBuff[0])

+		{

+			INT r, g, b;

+			NPSTR npBuff = szBuff;

+			r = g = b = 255;

+			while (*npBuff == ' ') ++npBuff;

+			r = atoi( npBuff );

+			while (*npBuff && *npBuff != ',') ++npBuff;

+			if (*npBuff == ',') g = atoi( ++npBuff );

+			while (*npBuff && *npBuff != ',') ++npBuff;

+			if (*npBuff == ',') b = atoi( ++npBuff );

+			dwColor = RGB( r, g, b );

+		}

+		if (bBW) dwColor = ((dwColor == RGB(0,0,0)) ? RGB(0,0,0) : RGB(255,255,255));

+		npLogPalette->palPalEntry[t].peRed = GetRValue( dwColor );

+		npLogPalette->palPalEntry[t].peGreen = GetGValue( dwColor );

+		npLogPalette->palPalEntry[t].peBlue = GetBValue( dwColor );

+		npLogPalette->palPalEntry[t].peFlags = 0;

+	}

+

+	hPalette = CreatePalette( npLogPalette );

+	return( hPalette );

+}

+

+//

+// CreateHyperoidClass - create the class of Hyperoid's window

+//

+

+BOOL FAR PASCAL CreateHyperoidClass( VOID )

+{

+	WNDCLASS        Class;

+

+	// load the name from the resource file

+	LoadString( hAppInst, IDS_NAME, szAppName, sizeof(szAppName) );

+

+	Class.style = CS_HREDRAW | CS_VREDRAW;

+	Class.lpfnWndProc = HyperoidWndProc;

+	Class.cbClsExtra = 0;

+	Class.cbWndExtra = 0;

+	Class.hInstance = hAppInst;

+	Class.hIcon = NULL;

+	Class.hCursor = LoadCursor( NULL, IDC_CROSS );

+	Class.hbrBackground = HNULL;

+	Class.lpszMenuName = szAppName;

+	Class.lpszClassName = szAppName;

+

+	return( RegisterClass( &Class ) );

+}

+

+//

+// SetHyperoidMenu - add Hyperoid's menu items to the system menu

+//

+

+VOID NEAR PASCAL SetHyperoidMenu( HWND hWnd, INT nFirstID, INT nLastID )

+{

+	CHAR            szMenuName[40];

+	HMENU           hMenu;

+

+	hMenu = GetSystemMenu( hWnd, TRUE );

+	if (hMenu == HNULL) hMenu = GetSystemMenu( hWnd, FALSE );

+	if (hMenu == HNULL) return;

+

+	while (nFirstID <= nLastID)

+	{

+		LoadString( hAppInst, nFirstID, szMenuName, sizeof(szMenuName) );

+		ChangeMenu( hMenu, 0, szMenuName, nFirstID, MF_APPEND );

+		++nFirstID;

+	}

+}

+

+//

+// CreateHyperoidWindow - open the Hyperoid window

+//

+

+HWND FAR PASCAL CreateHyperoidWindow( LPSTR lpszCmd, INT nCmdShow )

+{

+	HWND            hWnd;

+	INT             x, y, w, h;

+	CHAR            szBuff[32];

+

+	// get the highscore profile here for lack of a better place...

+	GetPrivateProfileString( szAppName, szHi, "0", szBuff, sizeof(szBuff), szIni );

+	lHighScore = atol( szBuff );

+

+	x = GetPrivateProfileInt( szAppName, szX, CW_USEDEFAULT, szIni );

+	y = GetPrivateProfileInt( szAppName, szY, CW_USEDEFAULT, szIni );

+	w = GetPrivateProfileInt( szAppName, szW, CW_USEDEFAULT, szIni );

+	h = GetPrivateProfileInt( szAppName, szH, CW_USEDEFAULT, szIni );

+	if (GetPrivateProfileInt( szAppName, szMax, FALSE, szIni ) &&

+		nCmdShow == SW_NORMAL) nCmdShow = SW_SHOWMAXIMIZED;

+

+	hWnd = CreateWindow( szAppName, szAppName, WS_OVERLAPPEDWINDOW,

+						 x, y, w, h, HNULL, HNULL, hAppInst, NULL );

+	if (hWnd == HNULL) return( HNULL );

+

+	ShowWindow( hWnd, nCmdShow );

+	UpdateWindow( hWnd );

+	SetHyperoidMenu( hWnd, IDM_NEW, IDM_ABOUT );

+

+	// show the license...

+	if (!GetPrivateProfileInt( szAppName, szLicense, FALSE, szIni ))

+	{

+		MessageBeep( HYPEROID_HELPSTYLE );

+		MessageBox( hWnd, HYPEROID_LICENSE, "Hyperoid License", HYPEROID_HELPSTYLE );

+		// ...and never show it again (unless they want to see it)

+		WritePrivateProfileString( szAppName, szLicense, "1", szIni );

+	}

+

+	return( hWnd );

+}

+

+//

+// SaveHyperoidWindowPos - write out the .ini information

+//

+

+VOID FAR PASCAL SaveHyperoidWindowPos( HWND hWnd )

+{

+	RECT            rect;

+	CHAR            szBuff[32];

+

+	// save the highscore profile here for lack of a better place...

+	if (lHighScore)

+	{

+		wsprintf( szBuff, "%lu", lHighScore );

+		WritePrivateProfileString( szAppName, szHi, szBuff, szIni );

+	}

+

+	if (IsIconic( hWnd )) return;

+	if (IsZoomed( hWnd ))

+	{

+		WritePrivateProfileString( szAppName, szMax, "1", szIni );

+		return;

+	}

+	else WritePrivateProfileString( szAppName, szMax, NULL, szIni );

+

+	GetWindowRect( hWnd, &rect );

+	wsprintf( szBuff, "%d", rect.left );

+	WritePrivateProfileString( szAppName, szX, szBuff, szIni );

+	wsprintf( szBuff, "%d", rect.top );

+	WritePrivateProfileString( szAppName, szY, szBuff, szIni );

+	wsprintf( szBuff, "%d", rect.right - rect.left );

+	WritePrivateProfileString( szAppName, szW, szBuff, szIni );

+	wsprintf( szBuff, "%d", rect.bottom - rect.top );

+	WritePrivateProfileString( szAppName, szH, szBuff, szIni );

+}

+

+//

+// GetHyperoidIni - load the ini file information

+//

+

+VOID FAR PASCAL GetHyperoidIni( VOID )

+{

+	nDrawDelay = GetPrivateProfileInt( szAppName, szDrawDelay, DRAW_DELAY, szIni );

+	vkShld = GetPrivateProfileInt( szKeys, szShield, VK_TAB, szIni );

+	vkClkw = GetPrivateProfileInt( szKeys, szClockwise, VK_LEFT, szIni );

+	vkCtrClkw = GetPrivateProfileInt( szKeys, szCtrClockwise, VK_RIGHT, szIni );

+	vkThrst = GetPrivateProfileInt( szKeys, szThrust, VK_DOWN, szIni );

+	vkRvThrst = GetPrivateProfileInt( szKeys, szRevThrust, VK_UP, szIni );

+	vkFire = GetPrivateProfileInt( szKeys, szFire, VK_SPACE, szIni );

+	vkBomb = GetPrivateProfileInt( szKeys, szBomb, 'S', szIni );

+}

+

+//

+// HyperoidHelp - show help

+//

+

+VOID FAR PASCAL HyperoidHelp( HWND hWnd )

+{

+	MessageBox( hWnd, HYPEROID_HELP, "Hyperoid help", HYPEROID_HELPSTYLE );

+	MessageBox( hWnd, HYPEROID_HELP2, "Hyperoid.ini help", HYPEROID_HELPSTYLE );

+}

+

+//

+// HyperoidAboutDlg - the about box proc

+//

+

+BOOL FAR PASCAL EXPORT HyperoidAboutDlg( HWND hDlg, WORD mess,

+										 WORD wParam, LONG lParam )

+{

+	switch (mess)

+	{

+	case WM_INITDIALOG:

+		if (lHighScore)

+		{

+			CHAR szBuff[40];

+			wsprintf( szBuff, "High Score: %7.7lu", lHighScore );

+			SetDlgItemText( hDlg, IDD_A_HISCORE, szBuff );

+		}

+		break;

+

+	case WM_COMMAND:

+		switch (wParam)

+		{

+		case IDD_A_HELP:

+			HyperoidHelp( hDlg );

+			// fall through...

+		case IDOK:

+			EndDialog( hDlg, 0 );

+			break;

+

+		default:

+			return( FALSE );

+		}

+		break;

+

+	case WM_CLOSE:

+		EndDialog( hDlg, FALSE );

+		break;

+

+	default:

+		return( FALSE );

+	}

+	return( TRUE );

+}

+

+//

+// AboutHyperoid - show the about box

+//

+

+VOID FAR PASCAL AboutHyperoid( HWND hWnd )

+{

+	FARPROC lpprocAbout = MakeProcInstance( HyperoidAboutDlg, hAppInst );

+	DialogBox( hAppInst, INTRES( IDD_ABOUT ), hWnd, lpprocAbout );

+	FreeProcInstance( lpprocAbout );

+}

diff --git a/test/hyperoid/score.bmp b/test/hyperoid/score.bmp
new file mode 100644
index 0000000..73a35f1
--- /dev/null
+++ b/test/hyperoid/score.bmp
Binary files differ
diff --git a/test/hyperoid/shield.bmp b/test/hyperoid/shield.bmp
new file mode 100644
index 0000000..d61606b
--- /dev/null
+++ b/test/hyperoid/shield.bmp
Binary files differ
diff --git a/test/hyperoid/winext.h b/test/hyperoid/winext.h
new file mode 100644
index 0000000..5694920
--- /dev/null
+++ b/test/hyperoid/winext.h
@@ -0,0 +1,109 @@
+#if !defined(WINEXT_H)

+#define WINEXT_H

+

+#if defined(__cplusplus)

+extern "C" {

+#endif // __cplusplus

+

+//

+// WINEXT.H - additional windows definitions

+//

+// Version 1.0  03/21/89  Copyright (C) 1989,90,91 Lantern Coroporation.

+// Author: Edward Hutchins

+// Status: Freeware

+// Revisions:

+// 06/06/90 modified HUGE to LARGE to preserve compatibility with math.h

+//          also nested windows.h include to prevent modifications on the

+//          actual source file - Ed.

+// 10/01/90 added CONST and CONSTP,NP,LP,HP and a few comments - Ed.

+// 08/28/91 added EXPORT and SEGMENT - Ed.

+// 10/28/91 added DLLEXP - Ed.

+// 11/02/91 posted on Compuserve - Ed.

+//

+

+//

+// include WINDOWS.H, if needed

+//

+

+#if !defined(WINDOWS_H)

+	#if defined(NULL)

+		#undef NULL

+	#endif

+	#include <windows.h>

+	#if !defined(NULL)

+		#define NULL 0

+	#endif

+	#define WINDOWS_H

+#endif // WINDOWS_H

+

+//

+// extra data types and defines

+//

+

+#define LARGE huge

+#define CDECL cdecl

+#define CONST const

+#define HNULL (0)

+#define LPNULL (0L)

+

+typedef char        CHAR;

+typedef int         INT;

+typedef float       FLOAT;

+typedef double      DOUBLE;

+typedef long double LDOUBLE;

+

+// extend the string type

+typedef CHAR LARGE  *HPSTR;

+

+// useful macros for typedefing pointers to objects //

+#define npointerdef(o) typedef o NEAR * NP ## o

+#define lpointerdef(o) typedef o FAR * LP ## o

+#define hpointerdef(o) typedef o LARGE * HP ## o

+#define pointerdef(o) npointerdef(o); lpointerdef(o); hpointerdef(o)

+

+// define the different kinds of pointers to things //

+pointerdef( BOOL );

+npointerdef( BYTE ); hptrdef( BYTE );

+pointerdef( CHAR );

+npointerdef( INT ); hpointerdef( INT );

+npointerdef( WORD ); hpointerdef( WORD );

+npointerdef( LONG ); hpointerdef( LONG );

+npointerdef( DWORD ); hpointerdef( DWORD );

+pointerdef( FLOAT );

+pointerdef( DOUBLE );

+pointerdef( LDOUBLE );

+npointerdef( HANDLE ); hpointerdef( HANDLE );

+npointerdef( VOID ); hpointerdef( VOID );

+

+// these are here for compatibility - use NPVOID etc...

+typedef VOID NEAR *NPMEM;

+typedef VOID FAR *LPMEM;

+

+// window proc function pointer

+typedef LONG (FAR PASCAL *WNDPROC)( HWND, unsigned, WORD, LONG );

+

+//

+// scope protocol definitions

+//

+

+#define GLOBAL      // GLOBAL

+#define LOCAL       static

+#define IMPORT      extern

+#define FROM(where) // FROM where

+#define PROTO       // PROTOTYPE

+

+#define EXPORT _export

+#define SEGMENT _segment

+

+#if defined(__cplusplus)

+}

+#endif // __cplusplus

+

+// c++ class export type

+#if defined(__DLL__)

+#define DLLEXP EXPORT

+#else

+#define DLLEXP LARGE

+#endif

+

+#endif // WINEXT_H

diff --git a/tools/build.c b/tools/build.c
index 00a550f..d13c717 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -606,6 +606,8 @@
 
     fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
     fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
+    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
     fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
     fprintf(fp, "\tjmp\t_CallTo32\n\n");
 
@@ -617,8 +619,10 @@
 	if (!odp->valid)
 	{
 	    fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+#ifdef BOB_SAYS_NO
 	    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
 	    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+#endif
 	    fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 	    fprintf(fp, "\tpushw\t$0\n");
 	    fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
@@ -684,8 +688,10 @@
 
 	      case FUNCTYPE_PASCAL:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+#ifdef BOB_SAYS_NO
 		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
 		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+#endif
 		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 		fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
@@ -694,8 +700,10 @@
 	      case FUNCTYPE_C:
 	      default:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+#ifdef BOB_SAYS_NO
 		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
 		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+#endif
 		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
 		fprintf(fp, "\tpushw\t$0\n");
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
diff --git a/windows/Makefile b/windows/Makefile
index 2dc7616..f7de172 100644
--- a/windows/Makefile
+++ b/windows/Makefile
@@ -1,7 +1,7 @@
 CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
 
 OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \
-    	clipping.o mapping.o painting.o keyboard.o utility.o
+    	clipping.o mapping.o painting.o keyboard.o utility.o syscolor.o
 
 default: windows.o
 
diff --git a/windows/class.c b/windows/class.c
index 17d36e0..23a2c49 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -66,10 +66,13 @@
     newClass->hNext      = firstClass;
     newClass->wMagic     = CLASS_MAGIC;
     newClass->atomName   = handle;  /* Should be an atom */
-    newClass->hDCE       = 0;  /* Should allocate a DCE if needed */
     newClass->cWindows   = 0;  
     newClass->wc         = *class;
-        
+
+    if (newClass->wc.style & CS_CLASSDC)
+	newClass->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL );
+    else newClass->hdc = 0;
+
       /* Class name should also be set to zero. For now we need the
        * name because we don't have atoms.
        */
@@ -113,7 +116,10 @@
 	}
 	prevClassPtr->hNext = classPtr->hNext;
     }
-    
+
+      /* Delete the class */
+    if (classPtr->hdc) DeleteDC( classPtr->hdc );
+    if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
     USER_HEAP_FREE( class );
     return TRUE;
 }
@@ -135,16 +141,13 @@
 {
     CLASS * classPtr;
     WND * wndPtr;
-    WORD retval = 0;
+    WORD *ptr, retval = 0;
     
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
-    {
-	WORD * ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
-	retval = *ptr;
-	*ptr = newval;
-    }
-    GlobalUnlock( hwnd );
+    if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
+    ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
+    retval = *ptr;
+    *ptr = newval;
     return retval;
 }
 
@@ -156,13 +159,10 @@
 {
     CLASS * classPtr;
     WND * wndPtr;
-    LONG retval = 0;
     
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
-	retval = *(LONG *)(((char *)classPtr->wExtra) + offset);
-    GlobalUnlock( hwnd );
-    return retval;
+    if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
+    return *(LONG *)(((char *)classPtr->wExtra) + offset);
 }
 
 
@@ -173,15 +173,12 @@
 {
     CLASS * classPtr;
     WND * wndPtr;
-    LONG retval = 0;
+    LONG *ptr, retval = 0;
     
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
-    {
-	LONG * ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
-	retval = *ptr;
-	*ptr = newval;
-    }
-    GlobalUnlock( hwnd );
+    if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
+    ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
+    retval = *ptr;
+    *ptr = newval;
     return retval;
 }
diff --git a/windows/clipping.c b/windows/clipping.c
index 80b19d2..2126c28 100644
--- a/windows/clipping.c
+++ b/windows/clipping.c
@@ -107,12 +107,9 @@
  */
 BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
 {
-    BOOL retval;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return FALSE;
 
-    retval = (wndPtr->hrgnUpdate != 0);
-
     if (rect)
     {
         if (wndPtr->hrgnUpdate) GetRgnBox( wndPtr->hrgnUpdate, rect );
@@ -127,8 +124,7 @@
 	    }
 	}
     }
-    GlobalUnlock( hwnd );
-    return retval;
+    return (wndPtr->hrgnUpdate != 0);
 }
 
 
@@ -137,7 +133,6 @@
  */
 int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
 {
-    int retval;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return ERROR;
 
@@ -150,7 +145,5 @@
 	    ReleaseDC( hwnd, hdc );
 	}
     }
-    retval = CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
-    GlobalUnlock( hwnd );
-    return retval;    
+    return CombineRgn( hrgn, wndPtr->hrgnUpdate, 0, RGN_COPY );
 }
diff --git a/windows/dce.c b/windows/dce.c
index d0019b2..aaea4b0 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -7,8 +7,10 @@
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
 #include "dce.h"
+#include "class.h"
 #include "win.h"
 #include "gdi.h"
+#include "user.h"
 
 
 #define NB_DCE    5  /* Number of DCEs created at startup */
@@ -31,14 +33,13 @@
         
     for (i = 0; i < NB_DCE; i++)
     {
-	handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(DCE) );
+	handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) );
 	if (!handle) return;
-	dce = (DCE *) GlobalLock( handle );
+	dce = (DCE *) USER_HEAP_ADDR( handle );
 	dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL );
 	if (!dce->hdc)
 	{
-	    GlobalUnlock( handle );
-	    GlobalFree( handle );
+	    USER_HEAP_FREE( handle );
 	    return;
 	}
 	dce->hwndCurrent = 0;
@@ -49,7 +50,6 @@
 	dce->hNext = firstDCE;
 	firstDCE = handle;
 	if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc );
-	GlobalUnlock( handle );
     }
 }
 
@@ -59,58 +59,54 @@
  */
 HDC GetDC( HWND hwnd )
 {
-    HANDLE hdce, next;
-    HDC hdc;
+    HANDLE hdce;
+    HDC hdc = 0;
     DCE * dce;
     DC * dc;
     WND * wndPtr = NULL;
+    CLASS * classPtr;
     
     if (hwnd)
     {
-	wndPtr = WIN_FindWndPtr( hwnd );
-	if (!wndPtr) return 0;
+	if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+	if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
+	if (wndPtr->hdc) hdc = wndPtr->hdc;
+	else if (classPtr->hdc) hdc = classPtr->hdc;
     }
         
-    for (hdce = firstDCE; (hdce); hdce = next)
+    if (!hdc)
     {
-	dce = (DCE *) GlobalLock( hdce );
-	if (!dce) return 0;
-	if (!dce->inUse) break;
-	next = dce->hNext;
-	GlobalUnlock( hdce );
-    }
-
-    if (!hdce)
-    {
-	if (hwnd) GlobalUnlock( hwnd );
-	return 0;
+	for (hdce = firstDCE; (hdce); hdce = dce->hNext)
+	{
+	    dce = (DCE *) USER_HEAP_ADDR( hdce );
+	    if (!dce) return 0;
+	    if (!dce->inUse) break;
+	}
+	if (!hdce) return 0;
+	dce->hwndCurrent = hwnd;
+	dce->inUse       = TRUE;
+	hdc = dce->hdc;
     }
     
       /* Initialize DC */
     
-    dc = (DC *) GDI_GetObjPtr( dce->hdc, DC_MAGIC );
-    if (!dc)
-    {
-	if (hwnd) GlobalUnlock( hwnd );
-	return 0;
-    }
+    if (!(dc = (DC *) GDI_GetObjPtr( dce->hdc, DC_MAGIC ))) return 0;
+
     if (wndPtr)
     {
 	dc->u.x.drawable = XtWindow( wndPtr->winWidget );
     	dc->u.x.widget   = wndPtr->winWidget;
+	if (wndPtr->dwStyle & WS_CLIPCHILDREN)
+	    XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren );
+	else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors);
     }
     else
     {
 	dc->u.x.drawable = DefaultRootWindow( XT_display );
 	dc->u.x.widget   = 0;
+	XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors );    
     }   
-    SetDCState( dce->hdc, defaultDCstate );
 
-    dce->hwndCurrent = hwnd;
-    dce->inUse       = TRUE;
-    hdc = dce->hdc;
-    GlobalUnlock( hdce );
-    if (hwnd) GlobalUnlock( hwnd );
 #ifdef DEBUG_WIN
     printf( "GetDC(%d): returning %d\n", hwnd, hdc );
 #endif
@@ -126,6 +122,7 @@
     HANDLE hdce, next;
     DCE * dce;
     WND * wndPtr = NULL;
+    CLASS * classPtr;
     
 #ifdef DEBUG_WIN
     printf( "ReleaseDC: %d %d\n", hwnd, hdc );
@@ -133,25 +130,22 @@
         
     if (hwnd)
     {
-	wndPtr = WIN_FindWndPtr( hwnd );
-	if (!wndPtr) return 0;
+	if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+	if (wndPtr->hdc && (wndPtr->hdc == hdc)) return 1;
+	if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
+	if (classPtr->hdc && (classPtr->hdc == hdc)) return 1;
     }
 
-    for (hdce = firstDCE; (hdce); hdce = next)
+    for (hdce = firstDCE; (hdce); hdce = dce->hNext)
     {
-	dce = (DCE *) GlobalLock( hdce );
-	if (!dce) return 0;
+	if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
 	if (dce->inUse && (dce->hdc == hdc)) break;
-	next = dce->hNext;
-	GlobalUnlock( hdce );
     }
 
-    if (hdce) 
+    if (hdce)
     {
+	SetDCState( dce->hdc, defaultDCstate );
 	dce->inUse = FALSE;
-    	GlobalUnlock( hdce );
-    }
-
-    if (hwnd) GlobalUnlock( hwnd );
+    }    
     return (hdce != 0);
 }
diff --git a/windows/event.c b/windows/event.c
index ea0bfc4..138f057 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -12,6 +12,7 @@
 
 #include "windows.h"
 #include "win.h"
+#include "class.h"
 
 
 #define NB_BUTTONS      3     /* Windows can handle 3 buttons */
@@ -175,7 +176,15 @@
     {  /* Check if double-click */
 	prevTime = lastClickTime[buttonNum];
 	lastClickTime[buttonNum] = event->time;
-	type = (event->time - prevTime < DBLCLICK_TIME) ? 2 : 0;
+	if (event->time - prevTime < DBLCLICK_TIME)
+	{
+	    WND * wndPtr;
+	    CLASS * classPtr;
+	    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
+	    if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return;
+	    type = (classPtr->wc.style & CS_DBLCLKS) ? 2 : 0;
+	}
+	else type = 0;
     }	
     
     msg.hwnd    = hwnd;
@@ -237,7 +246,6 @@
 		       ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
 		       GrabModeAsync, GrabModeSync, None, None, CurrentTime);
 
-    GlobalUnlock(wnd);
     if (rv == GrabSuccess)
     {
 	captureWnd = wnd;
@@ -263,6 +271,5 @@
     
     XtUngrabPointer(wnd_p->winWidget, CurrentTime);
 
-    GlobalUnlock(captureWnd);
     captureWnd = 0;
 }
diff --git a/windows/graphics.c b/windows/graphics.c
index cf339b9..338733a 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -226,6 +226,34 @@
 
 
 /***********************************************************************
+ *           FrameRect    (USER.83)
+ */
+int FrameRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
+{
+    HBRUSH prevBrush;
+    int left, top, right, bottom;
+
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) return FALSE;
+
+    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
+    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
+    
+    left   = XLPTODP( dc, rect->left );
+    top    = YLPTODP( dc, rect->top );
+    right  = XLPTODP( dc, rect->right );
+    bottom = YLPTODP( dc, rect->bottom );
+    
+    if (DC_SetupGCForBrush( dc ))
+	XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
+		        left, top, right-left-1, bottom-top-1 );
+	    
+    SelectObject( hdc, prevBrush );
+    return 1;
+}
+
+
+/***********************************************************************
  *           SetPixel    (GDI.31)
  */
 COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color )
@@ -242,6 +270,7 @@
     GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
     
     XSetForeground( XT_display, dc->u.x.gc, pixel );
+    XSetFunction( XT_display, dc->u.x.gc, GXcopy );
     XDrawPoint( XT_display, dc->u.x.drawable, dc->u.x.gc, x, y );
 
     return RGB( entry.peRed, entry.peGreen, entry.peBlue );
diff --git a/windows/message.c b/windows/message.c
index a1288c5..7307461 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -350,15 +350,9 @@
  */
 LONG SendMessage( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
 {
-    LONG retval = 0;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (wndPtr)
-    {
-	retval = CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg, 
-				 wParam, lParam );
-	GlobalUnlock( hwnd );
-    }
-    return retval;
+    if (!wndPtr) return 0;
+    return CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam );
 }
 
 
@@ -386,7 +380,6 @@
  */
 LONG DispatchMessage( LPMSG msg )
 {
-    LONG retval = 0;
     WND * wndPtr = WIN_FindWndPtr( msg->hwnd );
 
 #ifdef DEBUG_MSG
@@ -394,13 +387,9 @@
 	    msg->hwnd, msg->message, msg->wParam, msg->lParam, 
 	    msg->time, msg->pt.x, msg->pt.y );
 #endif
-    if (wndPtr) 
-    {
-	retval = CallWindowProc(wndPtr->lpfnWndProc, msg->hwnd, msg->message,
-				msg->wParam, msg->lParam );
-	GlobalUnlock( msg->hwnd );
-    }
-    return retval;
+    if (!wndPtr)  return 0;
+    return CallWindowProc( wndPtr->lpfnWndProc, msg->hwnd, msg->message,
+			   msg->wParam, msg->lParam );
 }
 
 
diff --git a/windows/painting.c b/windows/painting.c
index 050a5cb..4f21b13 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -44,7 +44,6 @@
     if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE;
     else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
 
-    GlobalUnlock( hwnd );
     return lps->hdc;
 }
 
@@ -71,7 +70,6 @@
     rect.right  = wndPtr->rectClient.right - wndPtr->rectClient.left;
     rect.bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
     PaintRect( hwndParent, hwnd, hdc, hbrush, &rect );
-    GlobalUnlock( hwnd );
 }
 
 
diff --git a/windows/syscolor.c b/windows/syscolor.c
new file mode 100644
index 0000000..7594fd1
--- /dev/null
+++ b/windows/syscolor.c
@@ -0,0 +1,122 @@
+/*
+ * Support for system colors
+ *
+ * Copyright  David W. Metcalfe, 1993
+ *
+ */
+
+static char Copyright[] = "Copyright  David W. Metcalfe, 1993";
+
+#include <stdlib.h>
+#include <X11/Xlib.h>
+
+#include "windows.h"
+#include "gdi.h"
+
+/* Default system colors - loosely based on Windows default color set */
+static const char *DefSysColors[] =
+{
+    "gray80",              /* COLOR_SCROLLBAR           */
+    "gray60",              /* COLOR_BACKGROUND          */
+    "blue4",               /* COLOR_ACTIVECAPTION       */
+    "white",               /* COLOR_INACTIVECAPTION     */
+    "white",               /* COLOR_MENU                */
+    "white",               /* COLOR_WINDOW              */
+    "black",               /* COLOR_WINDOWFRAME         */
+    "black",               /* COLOR_MENUTEXT            */
+    "black",               /* COLOR_WINDOWTEXT          */
+    "white",               /* COLOR_CAPTIONTEXT         */
+    "gray40",              /* COLOR_ACTIVEBORDER        */
+    "white",               /* COLOR_INACTIVEBORDER      */
+    "gray60",              /* COLOR_APPWORKSPACE        */
+    "black",               /* COLOR_HIGHLIGHT           */
+    "white",               /* COLOR_HIGHLIGHTTEXT       */
+    "gray70",              /* COLOR_BTNFACE             */
+    "gray30",              /* COLOR_BTNSHADOW           */
+    "gray70",              /* COLOR_GRAYTEXT            */
+    "black",               /* COLOR_BTNTEXT             */
+    "black",               /* COLOR_INACTIVECAPTIONTEXT */
+    "white",               /* COLOR_BTNHIGHLIGHT        */
+};
+
+#define NUM_SYS_COLORS     (sizeof(DefSysColors) / sizeof(DefSysColors[0]))
+
+static COLORREF SysColors[NUM_SYS_COLORS];
+
+extern Colormap COLOR_WinColormap;
+
+
+void SYSCOLOR_Init()
+{
+    Colormap map;
+    XColor color;
+    int i;
+
+    if ((map == COLOR_WinColormap) == CopyFromParent)
+	map = DefaultColormapOfScreen(XT_screen);
+
+    for (i = 0; i < NUM_SYS_COLORS; i++)
+    {
+	if (XParseColor(XT_display, map, DefSysColors[i], &color))
+	{
+	    if (XAllocColor(XT_display, map, &color))
+	    {
+		SysColors[i] = RGB(color.red >> 8, color.green >> 8,
+				                    color.blue >> 8);
+	    }
+	}
+    }
+}
+
+
+/*************************************************************************
+ *             GetSysColor           (USER.180)
+ */
+
+COLORREF GetSysColor(short nIndex)
+{
+#ifdef DEBUG_SYSCOLOR
+    printf("System Color %d = %6x\n", nIndex, SysColors[nIndex]);
+#endif
+    return SysColors[nIndex];
+}
+
+
+/*************************************************************************
+ *             SetSysColors          (USER.181)
+ */
+
+void SetSysColors(int nChanges, LPINT lpSysColor, COLORREF *lpColorValues)
+{
+    Colormap map;
+    XColor color;
+    char colorStr[8];
+    int i;
+
+    if ((map == COLOR_WinColormap) == CopyFromParent)
+	map = DefaultColormapOfScreen(XT_screen);
+
+    for (i = 0; i < nChanges; i++)
+    {
+	sprintf(colorStr, "#%2.2x%2.2x%2.2x", GetRValue(lpColorValues[i]),
+		GetGValue(lpColorValues[i]), GetBValue(lpColorValues[i]));
+
+	if (XParseColor(XT_display, map, colorStr, &color))
+	{
+	    if (XAllocColor(XT_display, map, &color))
+	    {
+		SysColors[lpSysColor[i]] = RGB(color.red >> 8, 
+						color.green >> 8,
+						color.blue >> 8);
+	    }
+	}
+    }
+
+    /* Send WM_SYSCOLORCHANGE message to all windows */
+
+    /* ................ */
+
+    /* Repaint affected portions of all visible windows */
+
+    /* ................ */
+}
diff --git a/windows/win.c b/windows/win.c
index 6e2361e..4d517d3 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -14,10 +14,10 @@
 
 #include "class.h"
 #include "win.h"
-#include "heap.h"
+#include "user.h"
 
 extern Display * XT_display;
-
+extern Colormap COLOR_WinColormap;
 
 static HWND firstWindow = 0;
 
@@ -28,19 +28,14 @@
  *           WIN_FindWndPtr
  *
  * Return a pointer to the WND structure corresponding to a HWND.
- * The caller must GlobalUnlock the pointer.
  */
 WND * WIN_FindWndPtr( HWND hwnd )
 {
     WND * ptr;
     
     if (!hwnd) return NULL;
-    ptr = (WND *) GlobalLock( hwnd );
-    if (ptr->dwMagic != WND_MAGIC)
-    {
-	GlobalUnlock( hwnd );
-	return NULL;
-    }
+    ptr = (WND *) USER_HEAP_ADDR( hwnd );
+    if (ptr->dwMagic != WND_MAGIC) return NULL;
     return ptr;
 }
 
@@ -84,7 +79,7 @@
     CREATESTRUCT *createStruct;
     HANDLE hcreateStruct;
     int wmcreate;
-    Widget parentWidget = 0;
+    LPSTR textPtr;
 
 #ifdef DEBUG_WIN
     printf( "CreateWindow: %s %s %d,%d %dx%d\n", className, windowName, x, y, width, height );
@@ -106,23 +101,16 @@
     else if (style & WS_CHILD) return 0;  /* WS_CHILD needs a parent */
 
     if (!(class = CLASS_FindClassByName( className, &classPtr )))
-    {
-	GlobalUnlock( parent );
 	return 0;
-    }
     
       /* Create the window structure */
 
-    hwnd = GlobalAlloc( GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra );
-    if (!hwnd)
-    {
-	GlobalUnlock( parent );
-	return 0;
-    }
+    hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
+    if (!hwnd) return 0;
 
       /* Fill the structure */
 
-    wndPtr = (WND *) GlobalLock( hwnd );
+    wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
     wndPtr->hwndNext   = 0;
     wndPtr->hwndChild  = 0;
     wndPtr->dwMagic    = WND_MAGIC;
@@ -139,14 +127,23 @@
     wndPtr->hwndLastActive    = 0;
     wndPtr->lpfnWndProc       = classPtr->wc.lpfnWndProc;
     wndPtr->dwStyle           = style;
-    wndPtr->hDCE              = 0;
+    wndPtr->dwExStyle         = 0;
     wndPtr->hmenuSystem       = 0;
     wndPtr->wIDmenu           = menu;
     wndPtr->flags             = 0;
+
     if (classPtr->wc.cbWndExtra)
 	memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
+    if (classPtr->wc.style & CS_OWNDC)
+	wndPtr->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL);
+    else wndPtr->hdc = 0;
     classPtr->cWindows++;
 
+      /* Create buffer for window text */
+    wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(windowName) + 1);
+    textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
+    strcpy(textPtr, windowName);
+
       /* Insert the window in the linked list */
 
     if (parent)
@@ -162,15 +159,11 @@
     
       /* Create the widgets */
 
-    if (!strcasecmp(className, "BUTTON"))
+    if (style & WS_CHILD)
     {
-	BUTTON_CreateButton(className, windowName, hwnd);
-    }
-    else
-    {
-	if (style & WS_CHILD)
-	{
-	    wndPtr->shellWidget = 0;
+	wndPtr->shellWidget = 0;
+	if (style & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME))
+	{ 
 	    wndPtr->winWidget = XtVaCreateManagedWidget(className,
 						    coreWidgetClass,
 						    parentPtr->winWidget,
@@ -182,38 +175,54 @@
 	}
 	else
 	{
-	    wndPtr->shellWidget = XtVaAppCreateShell(className, 
+	    wndPtr->winWidget = XtVaCreateManagedWidget(className,
+						    coreWidgetClass,
+						    parentPtr->winWidget,
+						    XtNx, x,
+						    XtNy, y,
+						    XtNwidth, width,
+						    XtNheight, height,
+						    XtNborderWidth, 0,
+						    NULL );
+	}
+    }
+    else
+    {
+	wndPtr->shellWidget = XtVaAppCreateShell(className, 
 						 windowName,
 						 topLevelShellWidgetClass,
 						 XT_display,
 						 XtNx, x,
 						 XtNy, y,
+#ifdef USE_PRIVATE_MAP
+						 XtNcolormap, COLOR_WinColormap,
+#endif
 						 NULL );
-	    wndPtr->compositeWidget = XtVaCreateManagedWidget(className,
+	wndPtr->compositeWidget = XtVaCreateManagedWidget(className,
 						    formWidgetClass,
 						    wndPtr->shellWidget,
 						    NULL );
-	    if (wndPtr->wIDmenu == 0)
-	    {
-		wndPtr->menuBarPtr = 
+	if (wndPtr->wIDmenu == 0)
+	{
+	    wndPtr->menuBarPtr = 
 		    MENU_CreateMenuBar(wndPtr->compositeWidget,
 				       instance, hwnd,
 				       classPtr->wc.lpszMenuName,
 				       width);
-		if (wndPtr->menuBarPtr)
+	    if (wndPtr->menuBarPtr)
 		    wndPtr->wIDmenu = 
 			GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem);
-	    }
-	    else
-	    {
-		wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget,
+	}
+	else
+	{
+	    wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget,
 						  instance, hwnd,
 						  wndPtr->wIDmenu, width);
-	    }
+	}
 
-	    if (wndPtr->menuBarPtr != NULL)
-	    {
-		wndPtr->winWidget = 
+	if (wndPtr->menuBarPtr != NULL)
+	{
+	    wndPtr->winWidget = 
 		    XtVaCreateManagedWidget(className,
 					    compositeWidgetClass,
 					    wndPtr->compositeWidget,
@@ -223,17 +232,16 @@
 					    wndPtr->menuBarPtr->menuBarWidget,
 					    XtNvertDistance, 4,
 					    NULL );
-	    }
-	    else
-	    {
-		wndPtr->winWidget = 
+	}
+	else
+	{
+	    wndPtr->winWidget = 
 		    XtVaCreateManagedWidget(className,
 					compositeWidgetClass,
 					wndPtr->compositeWidget,
 					XtNwidth, width,
 					XtNheight, height,
 					NULL );
-	    }
 	}
     }
 
@@ -264,18 +272,13 @@
 	  /* Abort window creation */
 	if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
 	else XtDestroyWidget( wndPtr->winWidget );
-	GlobalUnlock( parent );
-	GlobalUnlock( hwnd );
-	GlobalFree( hwnd );
+	USER_HEAP_FREE( hwnd );
 	return 0;
     }
     
     EVENT_AddHandlers( wndPtr->winWidget, hwnd );
 
     if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
-    
-    GlobalUnlock( parent );
-    GlobalUnlock( hwnd );
     return hwnd;
 }
 
@@ -318,10 +321,10 @@
 
     if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
     else XtDestroyWidget( wndPtr->winWidget );
+    if (wndPtr->hdc) DeleteDC( wndPtr->hdc );
     classPtr->cWindows--;
-    if (wndPtr->hwndParent) GlobalUnlock( wndPtr->hwndParent );
-    GlobalUnlock( hwnd );
-    GlobalFree( hwnd );
+    USER_HEAP_FREE(wndPtr->hText);
+    USER_HEAP_FREE( hwnd );
     return TRUE;
 }
 
@@ -341,7 +344,6 @@
 		      XtNwidth, &width,
 		      XtNheight, &height,
 		      NULL );
-	GlobalUnlock( hwnd );
 	rect->right  = width & 0xffff;
 	rect->bottom = height & 0xffff;
     }
@@ -359,7 +361,6 @@
     if (wndPtr) 
     {
 	if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget );
-	GlobalUnlock( hwnd );
 	XtVaGetValues(wndPtr->winWidget, 
 		      XtNwidth, &width,
 		      XtNheight, &height,
@@ -386,17 +387,10 @@
  */
 HMENU GetMenu( HWND hwnd ) 
 { 
-    WND *wndPtr;
-    HMENU hmenu;
-    
-    wndPtr = WIN_FindWndPtr(hwnd);
+    WND * wndPtr = WIN_FindWndPtr(hwnd);
     if (wndPtr == NULL)
 	return 0;
-
-    hmenu = wndPtr->wIDmenu;
-    
-    GlobalUnlock(hwnd);
-    return hmenu;
+    return wndPtr->wIDmenu;
 }
 
 /**********************************************************************
@@ -410,11 +404,7 @@
     if (wndPtr == NULL)
 	return FALSE;
 
-    if (wndPtr->dwStyle & WS_CHILD)
-    {
-	GlobalUnlock(hwnd);
-	return FALSE;
-    }
+    if (wndPtr->dwStyle & WS_CHILD) return FALSE;
 
     if (wndPtr->menuBarPtr != NULL)
     {
@@ -444,11 +434,145 @@
 					      wndPtr->rectClient.right -
 					      wndPtr->rectClient.left);
 	}
-	
-	GlobalUnlock(hwnd);
 	return FALSE;
     }
 
-    GlobalUnlock(hwnd);
     return TRUE;
 }
+
+
+/**********************************************************************
+ *           GetDesktopWindow        (USER.286)
+ */
+HWND GetDesktopWindow()
+{
+    return 0;
+}
+
+
+
+/**********************************************************************
+ *	     GetWindowWord    (USER.133)
+ */
+WORD GetWindowWord( HWND hwnd, short offset )
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return 0;
+    if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
+    switch(offset)
+    {
+	case GWW_ID:         return wndPtr->wIDmenu;
+	case GWW_HWNDPARENT: return wndPtr->hwndParent;
+	case GWW_HINSTANCE:  return wndPtr->hInstance;
+    }
+    return 0;
+}
+
+
+/**********************************************************************
+ *	     SetWindowWord    (USER.134)
+ */
+WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
+{
+    WORD *ptr, retval;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return 0;
+    if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
+    else switch(offset)
+    {
+	case GWW_ID: ptr = &wndPtr->wIDmenu;
+	case GWW_HINSTANCE: ptr = &wndPtr->hInstance;
+	default: return 0;
+    }
+    retval = *ptr;
+    *ptr = newval;
+    return retval;
+}
+
+
+/**********************************************************************
+ *	     GetWindowLong    (USER.135)
+ */
+LONG GetWindowLong( HWND hwnd, short offset )
+{
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return 0;
+    if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
+    switch(offset)
+    {
+	case GWL_STYLE:   return wndPtr->dwStyle;
+        case GWL_EXSTYLE: return wndPtr->dwExStyle;
+	case GWL_WNDPROC: return wndPtr->lpfnWndProc;
+    }
+    return 0;
+}
+
+
+/**********************************************************************
+ *	     SetWindowLong    (USER.136)
+ */
+LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
+{
+    LONG *ptr, retval;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return 0;
+    if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
+    else switch(offset)
+    {
+	case GWL_STYLE:   ptr = &wndPtr->dwStyle;
+        case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle;
+	case GWL_WNDPROC: ptr = &wndPtr->lpfnWndProc;
+	default: return 0;
+    }
+    retval = *ptr;
+    *ptr = newval;
+    return retval;
+}
+
+
+/*****************************************************************
+ *         GetParent              (USER.46)
+ */
+
+HWND GetParent(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    HWND hwndParent = wndPtr->hwndParent;
+    GlobalUnlock(hwnd);
+    return hwndParent;
+}
+
+/****************************************************************
+ *         GetDlgCtrlID           (USER.277)
+ */
+
+int GetDlgCtrlID(HWND hwnd)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    int ctrlID = wndPtr->wIDmenu;
+    GlobalUnlock(hwnd);
+    return ctrlID;
+}
+
+
+/*******************************************************************
+ *         GetWindowText          (USER.36)
+ */
+
+int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
+{
+    return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount, 
+			                      (DWORD)lpString);
+}
+
+/*******************************************************************
+ *         GetWindowTextLength    (USER.38)
+ */
+
+int GetWindowTextLength(HWND hwnd)
+{
+    return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL, 
+			                            (DWORD)NULL);
+}
+
+