diff --git a/ALPHA-pl13.diff b/ALPHA-pl13.diff deleted file mode 100644 index 6f675a5bb71..00000000000 --- 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+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 -+ -+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; ip_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 - #include - --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 - #include - --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 -+#include -+ - #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 -+ - /* - * 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 - #include - #include - #include -@@ -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 -+#include - - #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< - #include - #include -+#include - - 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 - - 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 -+#include - - #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 - #include - --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 - #include - -+/* 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 - #include -+#include - - /* - * 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 - #include - #include -+#include - - #include - #include -@@ -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 - #include - #include -+#include - - #include - #include -@@ -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 - #include - #include -+#include - - #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 - #include - #include -+#include - - #include - #include -@@ -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 - #include - #include -+#include -+ - #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;ji_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 - #include - --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 - #include - --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 - #include - #include -+#include - -+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 - #include - --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<>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 - #include -@@ -23,6 +23,14 @@ - #include - #include - #include -+ -+#ifndef PRE_PL13 -+#include -+#else -+#define snarf_region(base,extent) do {;}while(0) -+#define check_region(base,extent) (0) -+#endif -+ - /*#include */ - #include - #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 . */ - #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 --#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 -+#include - - #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, ð3_dev, ethif_probe }; -+static struct device eth1_dev = { -+ "eth1", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, ð2_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, ð1_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 (ð0_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 - #include -+#include - #include - #include - #include -@@ -29,6 +30,7 @@ - #include - #include - #include -+#include - #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 - #include -@@ -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 - #include -@@ -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, - * Fred N. van Kempen, -+ * Donald Becker, - * - * 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 - #include -@@ -22,6 +23,7 @@ - /*#include */ - #include - #include -+#include - #include - #include - /*#include */ -@@ -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, - * Fred N. van Kempen, -+ * Donald Becker, - * - * 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 - #include - #include -+#include /* 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 - #include - #include -+#include - #include - #include - #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 - #include - #include -+#include - #include - #include - #include -@@ -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 . Puredata seem to do software -+ Mike Jagdis . 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 0ff96cb3a8f..18ff63d93fc 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 ea2caf166b7..b6d32369dae 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 7b8666f3ec6..bdc28e2d3f7 100644 --- a/README +++ b/README @@ -7,14 +7,13 @@ INSTALLATION: 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 @@ Grab a copy of Windows sol.exe (Solitaire) and run it with the command: 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 00000000000..2f6ff990016 --- /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 + +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 00000000000..c27b49d7092 --- /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 00000000000..2805bb3ddd8 Binary files /dev/null and b/ansi2oem.trl differ diff --git a/bsdmake.patch b/bsdmake.patch index 42f0ea1f8b6..7be2893c227 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 dc3c1878bc5..46a93ba7815 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 59773cedf73..00000000000 --- 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 -#include -#include -#include -#include -#include "WinButtonP.h" -#include - -#define DEFAULT_HIGHLIGHT_THICKNESS 0 -#define DEFAULT_SHAPE_HIGHLIGHT 32767 - -/**************************************************************** - * - * Full class record constant - * - ****************************************************************/ - -/* Private Data */ - -static char defaultTranslations[] = - ": highlight() \n\ - : reset() \n\ - : set() \n\ - : 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 54dee6a8732..00000000000 --- 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 207f19ac3e9..00000000000 --- 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 3a65bc027fa..f843beb30ac 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 -#include -#include "WinButton.h" -#include "windows.h" -#include "heap.h" +#include #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 951fc749015..2d22115fa0d 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -141,7 +141,7 @@ MENU_SelectionCallback(Widget w, XtPointer client_data, XtPointer call_data) 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 @@ MENU_SelectionCallback(Widget w, XtPointer client_data, XtPointer call_data) 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 3c68d9cc782..90272e506cd 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -10,8 +10,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #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 LONG WIDGETS_StaticWndProc( HWND hwnd, WORD message, 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 @@ BOOL WIDGETS_Init() 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; @@ -60,39 +57,6 @@ LONG WIDGETS_Call32WndProc( FARPROC func, HWND hwnd, WORD message, } -/*********************************************************************** - * 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 */ diff --git a/debugger/Makefile b/debugger/Makefile new file mode 100644 index 00000000000..493297ae8e1 --- /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 00000000000..5715339e646 --- /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 00000000000..54de7a62b65 --- /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 00000000000..68e4d7547ec --- /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 00000000000..430b0abc4bd --- /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 -fnf */ +typedef enum bfd_boolean {false, true} boolean; + +/* A pointer to a position in a file. */ +/* FIXME: This should be using off_t from . + For now, try to avoid breaking stuff by not including 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 <>. 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 + <> | <>, a debug section could be + <> */ + +#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; <> in <>. The value + is the offset into the section of the data. */ +#define BSF_LOCAL 0x01 + + /* The symbol has global scope; initialized data in <>. 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. <> in <>. The value has + no meaning. */ +#define BSF_UNDEFINED_OBS 0x10 + + /* The symbol is common, initialized to zero; default in + <>. The value is the size of the object in bytes. */ +#define BSF_FORT_COMM_OBS 0x20 + + /* A normal C symbol would be one of: + <>, <>, <> or + <> */ + + /* 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 <> symbol + which is also <> 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 `<>', 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 00000000000..80e8d34fca4 --- /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 +#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 00000000000..dac7d3f2a38 --- /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 +#include +#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 00000000000..e789dd3be12 --- /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 + +/* 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 /* 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 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 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 +#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 /* 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 00000000000..4d70008d4dd --- /dev/null +++ b/debugger/dtest.c @@ -0,0 +1,96 @@ +#include +#include + +extern void wine_debug(unsigned int*); + + +#ifdef linux +#include +#include +#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 00000000000..0f37529d33e --- /dev/null +++ b/debugger/fopen-same.h @@ -0,0 +1,27 @@ +/* Macros for the 'type' part of an fopen, freopen or fdopen. + + [Update] + + 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 00000000000..e9c8466be3e --- /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 00000000000..a6d640f0906 --- /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 +#include +#include +#include +#include +#include +#include +#include + +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; inext) + 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 00000000000..bd22a93632d --- /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 + +/* 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 (""); + 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 (""); + 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 = ""; + 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 (""); + 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 (""); + 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 (""); + 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 (""); + 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 00000000000..96046e89a3d --- /dev/null +++ b/debugger/info.c @@ -0,0 +1,230 @@ +/* + * Wine debugger utility routines + * Eric Youngdale + * 9/93 + */ + +#include +#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", +" symbolfile ", +" define ", +" x ", +" cont", +" set = ", +" set * = ", +"", +"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 00000000000..c63284748fe --- /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 00000000000..77c6bfcfe2b --- /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 . +## -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 , not ? +## -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 + +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 00000000000..c6097894cb5 --- /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 + + + 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 00000000000..0cd029c58eb --- /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 00000000000..1d851ede0fd --- /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 +and Rich $alz . +Original manual page by DaviD W. Sanderson . diff --git a/debugger/readline/editline.c b/debugger/readline/editline.c new file mode 100644 index 00000000000..3838de029a6 --- /dev/null +++ b/debugger/readline/editline.c @@ -0,0 +1,1378 @@ +/* $Revision: 1.4 $ +** +** Main editing routines for editline library. +*/ +#include "editline.h" +#include + +/* +** 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 00000000000..40a20258bd0 --- /dev/null +++ b/debugger/readline/editline.h @@ -0,0 +1,76 @@ +/* $Revision: 1.3 $ +** +** Internal header file for editline library. +*/ +#include +#if defined(HAVE_STDLIB) +#include +#include +#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 00000000000..7bb7cf3c096 --- /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 +typedef struct direct DIRENTRY; diff --git a/debugger/readline/sysos9.c b/debugger/readline/sysos9.c new file mode 100644 index 00000000000..fd23aa4d4fc --- /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 +#include + + +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 00000000000..010744e1c4a --- /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 + +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 + +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 00000000000..e6384b8adb7 --- /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 +#if defined(HAVE_STDLIB) +#include +#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 00000000000..fe6beedcec2 --- /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 +#include + +#if defined(USE_DIRENT) +#include +typedef struct dirent DIRENTRY; +#else +#include +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 00000000000..7b1b2428619 --- /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 00000000000..c3d30867fa2 --- /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 00000000000..bfd0e35daa2 --- /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 00000000000..f36505f5ac1 --- /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 00000000000..cff23190cdf --- /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 00000000000..f265c737678 --- /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 dd5d03511a0..3c35e88f5f2 100644 --- a/if1632/callback.c +++ b/if1632/callback.c @@ -135,17 +135,22 @@ void FreeProcInstance(FARPROC func) 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 @@ LONG CallWindowProc( FARPROC func, HWND hwnd, WORD message, */ 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 bfeb1b4a7ae..63eb008479a 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -32,11 +32,19 @@ length 415 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 @@ length 415 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 @@ length 415 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 cf93fe74997..9bf6b127b1f 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -107,11 +107,6 @@ DLLRelay(unsigned int func_num, unsigned int seg_off) 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 0e7d0126e34..be0a2f4cc6f 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 1da0c4d0198..4a32a6a5a28 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -17,11 +17,14 @@ length 540 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 @@ length 540 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 @@ length 540 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 @@ length 540 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 @@ length 540 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 f2cc80a3a1a..9ab50e4e2f5 100644 --- a/include/class.h +++ b/include/class.h @@ -17,7 +17,7 @@ typedef struct tagCLASS 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 5775cdc4b5d..6c4f7c5588b 100644 --- a/include/segmem.h +++ b/include/segmem.h @@ -32,4 +32,11 @@ struct segment_descriptor_s #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 5c7c235997a..894da98ff12 100644 --- a/include/win.h +++ b/include/win.h @@ -32,9 +32,11 @@ typedef struct tagWND 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 @@ typedef struct tagWND #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 278770b7540..9c8e0d22993 100644 --- a/include/windows.h +++ b/include/windows.h @@ -105,7 +105,7 @@ typedef struct { #define GCW_STYLE (-26) #define GCW_ATOM (-32) - + /* Windows */ typedef struct { void * lpCreateParams; @@ -122,6 +122,17 @@ typedef struct { 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 @@ typedef struct short cy; } SIZE, *LPSIZE; +#define MAKEPOINT(l) (*((POINT *)&(l))) typedef struct tagMSG { @@ -1452,7 +1464,7 @@ Fc(void,InvalidateRgn,HWND,a,HRGN,b,BOOL,c) 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 621fcdb4d16..afe11d6a964 100644 --- a/include/wine.h +++ b/include/wine.h @@ -15,8 +15,12 @@ struct w_files{ 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 4a3c60eef9c..fcc1af3108b 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -3,12 +3,47 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include +#include +#include +#include +#include #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 @@ FindResourceByNumber(struct resource_nameinfo_s *result_p, 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 @@ FindResourceByNumber(struct resource_nameinfo_s *result_p, 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 @@ FindResourceByNumber(struct resource_nameinfo_s *result_p, { 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 @@ FindResourceByName(struct resource_nameinfo_s *result_p, 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 @@ FindResourceByName(struct resource_nameinfo_s *result_p, 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 @@ FindResourceByName(struct resource_nameinfo_s *result_p, { 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 @@ FindResourceByName(struct resource_nameinfo_s *result_p, 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) @@ -221,53 +258,6 @@ FindResourceByName(struct resource_nameinfo_s *result_p, return -1; } -/********************************************************************** - * 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 */ @@ -297,6 +287,43 @@ LoadAccelerators(HANDLE instance, LPSTR lpTableName) 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 @@ RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret) { 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 @@ RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret) /* * 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 @@ RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret) 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; @@ -356,6 +386,46 @@ RSC_LoadResource(int instance, char *rsc_name, int type, int *image_size_ret) return hmem; } +/********************************************************************** + * 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 */ @@ -403,3 +473,5 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) ReleaseDC( 0, hdc ); return hbitmap; } + + diff --git a/loader/selector.c b/loader/selector.c index 4ecb448f58f..489dfd6833f 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -47,7 +47,7 @@ unsigned short PSPSelector; 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 39f4080b6bf..a240104c227 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -6,9 +6,15 @@ #include #include #include +#ifdef linux #include #include +#endif +char * cstack[4096]; +struct sigaction segv_act; + +#ifdef linux extern void ___sig_restore(); extern void ___masksig_restore(); @@ -26,33 +32,36 @@ wine_sigaction(int sig,struct sigaction * new, struct sigaction * old) 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 @@ GetTimeDate(int time_flag, struct sigcontext_struct * context) now = localtime(<ime); 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 @@ GetTimeDate(int time_flag, struct sigcontext_struct * context) 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 @@ do_int21(struct sigcontext_struct * context){ 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 @@ do_int21(struct sigcontext_struct * context){ /* 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 @@ do_int1A(struct sigcontext_struct * context){ 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 @@ static void win_segfault(int signal, struct sigcontext_struct context){ 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 @@ static void win_segfault(int signal, struct sigcontext_struct context){ /* 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 @@ static void win_segfault(int signal, struct sigcontext_struct context){ } 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 ad268249201..1cd77a03639 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -63,8 +63,38 @@ myerror(const char *s) 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 @@ LoadImage(char * filename, char * modulename) 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 faeeeb60880..0d5fa816d9f 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 2a1388a8365..559fac09cd3 100644 --- a/misc/file.c +++ b/misc/file.c @@ -25,6 +25,8 @@ #include #include +#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 b01b69f34d5..cc4b01740b8 100644 --- a/misc/keyboard.c +++ b/misc/keyboard.c @@ -11,6 +11,8 @@ int ToAscii(WORD wVirtKey, WORD wScanCode, LPSTR lpKeyState, return -1; } +#ifdef BOGUS_ANSI_OEM + int AnsiToOem(LPSTR lpAnsiStr, LPSTR lpOemStr) { printf("AnsiToOem (%s)\n",lpAnsiStr); @@ -25,6 +27,8 @@ BOOL OemToAnsi(LPSTR lpOemStr, LPSTR lpAnsiStr) return -1; } +#endif + DWORD OemKeyScan(WORD wOemChar) { printf("*OemKeyScan (%d)\n",wOemChar); @@ -84,6 +88,8 @@ int GetKeyNameText(LONG lParam, LPSTR lpBuffer, int nSize) return 0; } +#ifdef BOGUS_ANSI_OEM + void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, int nLength) { printf("AnsiToOemBuff(%s,,%d)\n",lpAnsiStr,nLength); @@ -96,6 +102,7 @@ void OemToAnsiBuff(LPSTR lpOemStr, LPSTR lpAnsiStr, int nLength) strncpy(lpAnsiStr,lpOemStr,nLength); /* should translate... */ } +#endif diff --git a/misc/lstr.c b/misc/lstr.c new file mode 100644 index 00000000000..7bf2250727b --- /dev/null +++ b/misc/lstr.c @@ -0,0 +1,213 @@ +static char Copyright[] = "Copyright Yngvi Sigurjonsson (yngvi@hafro.is), 1993"; + +#include +#include +#include +#include +#include +#include + +#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 +#include #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 fb96fd608fe..4fd7be4ec3c 100644 --- a/misc/rect.c +++ b/misc/rect.c @@ -78,6 +78,8 @@ void OffsetRect( LPRECT rect, short x, short y ) */ 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 a75bd424f6e..476d86124c4 100644 --- a/misc/user.c +++ b/misc/user.c @@ -39,6 +39,9 @@ USER_InitApp(int hInstance) { /* 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 3bb98bbd9e7..5756d39aaf8 100644 --- a/misc/xt.c +++ b/misc/xt.c @@ -19,6 +19,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "win.h" #include "class.h" #include "gdi.h" +#include "user.h" #ifdef __NetBSD__ #define HZ 100 @@ -56,6 +57,8 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { 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 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) 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 @@ int MessageBox( HWND hwnd, LPSTR str, LPSTR title, WORD type ) void MessageBeep( WORD i ) { - printf( "MessageBeep: %d\n", i ); + XBell(XT_display, 100); } WORD RegisterWindowMessage( LPSTR str ) @@ -123,7 +161,7 @@ WORD RegisterWindowMessage( LPSTR str ) DWORD GetTickCount() { struct tms dummy; - return times(&dummy) / (1000 / HZ); + return (times(&dummy) * 1000) / HZ; } diff --git a/objects/Makefile b/objects/Makefile index ad4d119887d..f1dcd067ebc 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 00000000000..a57b46e5d81 --- /dev/null +++ b/objects/color.c @@ -0,0 +1,124 @@ +/* + * Color functions + * + * Copyright 1993 Alexandre Julliard + */ + +static char Copyright[] = "Copyright Alexandre Julliard, 1993"; + +#include +#include + +#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 55237c378bc..32bb4b8ae01 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -150,13 +150,14 @@ BOOL GDI_Init() /* 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 887f1defccd..ec697002a45 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -21,65 +21,42 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; 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 @@ WORD GetNearestPaletteIndex( HPALETTE hpalette, COLORREF color ) 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 2c22ee412c4..08274ca08aa 100644 --- a/objects/region.c +++ b/objects/region.c @@ -539,17 +539,20 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) case RGN_AND: res = IntersectRect( ®ion->box, &src1Obj->region.box, &src2Obj->region.box ); + region->type = COMPLEXREGION; break; case RGN_OR: case RGN_XOR: res = UnionRect( ®ion->box, &src1Obj->region.box, &src2Obj->region.box ); + region->type = COMPLEXREGION; break; case RGN_DIFF: res = SubtractRect( ®ion->box, &src1Obj->region.box, &src2Obj->region.box ); + region->type = COMPLEXREGION; break; case RGN_COPY: @@ -582,7 +585,7 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) 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 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) 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 @@ int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) 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 00000000000..20ab9f40bb2 Binary files /dev/null and b/oem2ansi.trl differ diff --git a/oemansi.exe b/oemansi.exe new file mode 100755 index 00000000000..46c907f0211 Binary files /dev/null and b/oemansi.exe differ diff --git a/test/hyperoid/blank.bmp b/test/hyperoid/blank.bmp new file mode 100644 index 00000000000..11840afa37b Binary files /dev/null and b/test/hyperoid/blank.bmp differ diff --git a/test/hyperoid/bomb.bmp b/test/hyperoid/bomb.bmp new file mode 100644 index 00000000000..5fcde4a8efc Binary files /dev/null and b/test/hyperoid/bomb.bmp differ diff --git a/test/hyperoid/copying.txt b/test/hyperoid/copying.txt new file mode 100644 index 00000000000..2d64ec5395a --- /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. + + + Copyright (C) 19yy + + 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. + + , 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 00000000000..f396d55dbd8 --- /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 00000000000..3309007f6ca --- /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 00000000000..0f34f629909 Binary files /dev/null and b/test/hyperoid/hyperoid.exe differ diff --git a/test/hyperoid/hyperoid.h b/test/hyperoid/hyperoid.h new file mode 100644 index 00000000000..e16b057712c --- /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 +#include +#include +#include +#include +#define OEMRESOURCE +#include + +// +// 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 00000000000..6641a8319ce Binary files /dev/null and b/test/hyperoid/hyperoid.ico differ diff --git a/test/hyperoid/hyperoid.mak b/test/hyperoid/hyperoid.mak new file mode 100644 index 00000000000..c885a1b66e6 --- /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 00000000000..34edf19048c --- /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 00000000000..4f8afb74a90 --- /dev/null +++ b/test/hyperoid/hyperoid.rc @@ -0,0 +1,59 @@ +// +// HYPEROID.RC - orbiter resources +// + +#include +#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 00000000000..eb1f03e4365 Binary files /dev/null and b/test/hyperoid/level.bmp differ diff --git a/test/hyperoid/life.bmp b/test/hyperoid/life.bmp new file mode 100644 index 00000000000..70fd6235a0c Binary files /dev/null and b/test/hyperoid/life.bmp differ diff --git a/test/hyperoid/list.c b/test/hyperoid/list.c new file mode 100644 index 00000000000..e427064b176 --- /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 00000000000..61c393830bf --- /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 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 + diff --git a/test/hyperoid/num0.bmp b/test/hyperoid/num0.bmp new file mode 100644 index 00000000000..9dfa846e16f Binary files /dev/null and b/test/hyperoid/num0.bmp differ diff --git a/test/hyperoid/num1.bmp b/test/hyperoid/num1.bmp new file mode 100644 index 00000000000..302d0f9bbb3 Binary files /dev/null and b/test/hyperoid/num1.bmp differ diff --git a/test/hyperoid/num2.bmp b/test/hyperoid/num2.bmp new file mode 100644 index 00000000000..c1b70faf0e7 Binary files /dev/null and b/test/hyperoid/num2.bmp differ diff --git a/test/hyperoid/num3.bmp b/test/hyperoid/num3.bmp new file mode 100644 index 00000000000..f8b9971d255 Binary files /dev/null and b/test/hyperoid/num3.bmp differ diff --git a/test/hyperoid/num4.bmp b/test/hyperoid/num4.bmp new file mode 100644 index 00000000000..4ce4a6c565d Binary files /dev/null and b/test/hyperoid/num4.bmp differ diff --git a/test/hyperoid/num5.bmp b/test/hyperoid/num5.bmp new file mode 100644 index 00000000000..ce2ca461f34 Binary files /dev/null and b/test/hyperoid/num5.bmp differ diff --git a/test/hyperoid/num6.bmp b/test/hyperoid/num6.bmp new file mode 100644 index 00000000000..af200bdd09c Binary files /dev/null and b/test/hyperoid/num6.bmp differ diff --git a/test/hyperoid/num7.bmp b/test/hyperoid/num7.bmp new file mode 100644 index 00000000000..d5eaf6ca0cc Binary files /dev/null and b/test/hyperoid/num7.bmp differ diff --git a/test/hyperoid/num8.bmp b/test/hyperoid/num8.bmp new file mode 100644 index 00000000000..3a9eeb027c9 Binary files /dev/null and b/test/hyperoid/num8.bmp differ diff --git a/test/hyperoid/num9.bmp b/test/hyperoid/num9.bmp new file mode 100644 index 00000000000..d2b18d20a50 Binary files /dev/null and b/test/hyperoid/num9.bmp differ diff --git a/test/hyperoid/panic.ico b/test/hyperoid/panic.ico new file mode 100644 index 00000000000..6be44921517 Binary files /dev/null and b/test/hyperoid/panic.ico differ diff --git a/test/hyperoid/plus.bmp b/test/hyperoid/plus.bmp new file mode 100644 index 00000000000..4beda944c3e Binary files /dev/null and b/test/hyperoid/plus.bmp differ diff --git a/test/hyperoid/read.me b/test/hyperoid/read.me new file mode 100644 index 00000000000..65f70db951f --- /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 00000000000..3da30f18e74 --- /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}=" NL "Mono=<0/1>" NL \ +"DrawDelay= ;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}=,," NL \ +NL "[Keys]" NL \ +"{Shield,Clockwise,CtrClockwise," NL \ +" Thrust,RevThrust,Fire,Bomb}=" 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 00000000000..73a35f199d5 Binary files /dev/null and b/test/hyperoid/score.bmp differ diff --git a/test/hyperoid/shield.bmp b/test/hyperoid/shield.bmp new file mode 100644 index 00000000000..d61606b825a Binary files /dev/null and b/test/hyperoid/shield.bmp differ diff --git a/test/hyperoid/winext.h b/test/hyperoid/winext.h new file mode 100644 index 00000000000..5694920cbab --- /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 + #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 00a550f139b..d13c71750d9 100644 --- a/tools/build.c +++ b/tools/build.c @@ -606,6 +606,8 @@ main(int argc, char **argv) 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 @@ main(int argc, char **argv) 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 @@ main(int argc, char **argv) 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 @@ main(int argc, char **argv) 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 2dc7616a137..f7de172440e 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 17d36e06fae..23a2c495764 100644 --- a/windows/class.c +++ b/windows/class.c @@ -66,10 +66,13 @@ ATOM RegisterClass( LPWNDCLASS class ) 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 @@ BOOL UnregisterClass( LPSTR className, HANDLE instance ) } 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 @@ WORD SetClassWord( HWND hwnd, short offset, WORD newval ) { 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 @@ LONG GetClassLong( HWND hwnd, short offset ) { 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 @@ LONG SetClassLong( HWND hwnd, short offset, LONG newval ) { 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 80b19d29dd7..2126c287333 100644 --- a/windows/clipping.c +++ b/windows/clipping.c @@ -107,12 +107,9 @@ void ValidateRect( HWND hwnd, LPRECT rect ) */ 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 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) } } } - GlobalUnlock( hwnd ); - return retval; + return (wndPtr->hrgnUpdate != 0); } @@ -137,7 +133,6 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) */ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) { - int retval; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return ERROR; @@ -150,7 +145,5 @@ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) 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 d0019b2b186..aaea4b012c1 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 @@ void DCE_Init() 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 @@ void DCE_Init() dce->hNext = firstDCE; firstDCE = handle; if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc ); - GlobalUnlock( handle ); } } @@ -59,58 +59,54 @@ void DCE_Init() */ 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 @@ int ReleaseDC( HWND hwnd, HDC hdc ) HANDLE hdce, next; DCE * dce; WND * wndPtr = NULL; + CLASS * classPtr; #ifdef DEBUG_WIN printf( "ReleaseDC: %d %d\n", hwnd, hdc ); @@ -133,25 +130,22 @@ int ReleaseDC( HWND hwnd, HDC hdc ) 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 ea0bfc48573..138f0579c81 100644 --- a/windows/event.c +++ b/windows/event.c @@ -12,6 +12,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" #include "win.h" +#include "class.h" #define NB_BUTTONS 3 /* Windows can handle 3 buttons */ @@ -175,7 +176,15 @@ static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event, { /* 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 @@ HWND SetCapture(HWND wnd) ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeSync, None, None, CurrentTime); - GlobalUnlock(wnd); if (rv == GrabSuccess) { captureWnd = wnd; @@ -263,6 +271,5 @@ void ReleaseCapture() XtUngrabPointer(wnd_p->winWidget, CurrentTime); - GlobalUnlock(captureWnd); captureWnd = 0; } diff --git a/windows/graphics.c b/windows/graphics.c index cf339b973d0..338733af26b 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -225,6 +225,34 @@ void InvertRect( HDC hdc, LPRECT rect ) } +/*********************************************************************** + * 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) */ @@ -242,6 +270,7 @@ COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color ) 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 a1288c5c54c..7307461d99d 100644 --- a/windows/message.c +++ b/windows/message.c @@ -350,15 +350,9 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) */ 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 @@ BOOL TranslateMessage( LPMSG msg ) */ LONG DispatchMessage( LPMSG msg ) { - LONG retval = 0; WND * wndPtr = WIN_FindWndPtr( msg->hwnd ); #ifdef DEBUG_MSG @@ -394,13 +387,9 @@ LONG DispatchMessage( LPMSG msg ) 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 050a5cb71d2..4f21b13b0a5 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -44,7 +44,6 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) 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 @@ void FillWindow( HWND hwndParent, HWND hwnd, HDC hdc, HBRUSH hbrush ) 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 00000000000..7594fd17ac6 --- /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 +#include + +#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 6e2361eb1e3..4d517d38d84 100644 --- a/windows/win.c +++ b/windows/win.c @@ -14,10 +14,10 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #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 @@ void BUTTON_CreateButton(LPSTR className, LPSTR buttonLabel, HWND hwnd); * 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 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, 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 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, 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 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, 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 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, /* 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 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, } 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 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, 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 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, /* 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 @@ BOOL DestroyWindow( HWND hwnd ) 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 @@ void GetClientRect( HWND hwnd, LPRECT rect ) XtNwidth, &width, XtNheight, &height, NULL ); - GlobalUnlock( hwnd ); rect->right = width & 0xffff; rect->bottom = height & 0xffff; } @@ -359,7 +361,6 @@ BOOL ShowWindow( HWND hwnd, int cmd ) if (wndPtr) { if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); - GlobalUnlock( hwnd ); XtVaGetValues(wndPtr->winWidget, XtNwidth, &width, XtNheight, &height, @@ -386,17 +387,10 @@ void UpdateWindow( HWND hwnd ) */ 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 @@ BOOL SetMenu(HWND hwnd, HMENU hmenu) 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 @@ BOOL SetMenu(HWND hwnd, HMENU hmenu) 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); +} + +