www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1997/06/10/20:29:52

Date: Wed, 11 Jun 1997 12:29:19 -0700
From: Bill Currie <billc AT blackmagic DOT tait DOT co DOT nz>
Subject: stubinfo_minkeep patches
To: djgpp-workers AT delorie DOT com
Reply-to: billc AT blackmagic DOT tait DOT co DOT nz
Message-id: <339EFC8F.33C3@blackmagic.tait.co.nz>
Organization: Tait Electronics NZ
MIME-version: 1.0

This is a multi-part message in MIME format.

--------------52677CEB33EE
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Here are the patches to convert stubinfo_minkeep from bytes to
paragraphs (to allow larger transfer buffers).  Full backwards
compatability is maintained in both stubedit and libc.

Known problems:
o  getchar() (or printf after printing) aborts if minkeep==64k (65k ok)
o  v2load.c still has the older stubinfo hardcoded.

I'll be looking into the first problem, and I don't know if the second
is worth fixing.

Bill
-- 
Leave others their otherness.

--------------52677CEB33EE
Content-Type: text/plain; charset=us-ascii; name="CRT1C.PAT"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="CRT1C.PAT"

*** crt1.c.~	Sun Sep  1 20:52:34 1996
--- crt1.c	Wed Jun 11 11:52:18 1997
***************
*** 13,18 ****
--- 13,19 ----
  #include <libc/bss.h>
  #include <fcntl.h>
  #include <libc/environ.h>
+ #include <ctype.h>
  
  /* Global variables */
  
***************
*** 75,82 ****
--- 76,95 ----
    __dpmi_get_version(&ver);
  
    _go32_info_block.size_of_this_structure_in_bytes = sizeof(_go32_info_block);
+   _go32_info_block.stubinfo_version=(_stubinfo->magic[12]-'0')*0x0100+
+ 				    (_stubinfo->magic[14]-'0')*0x0010+
+ 				    (_stubinfo->magic[15]-'0')*0x0001;
+   if (isdigit(_stubinfo->magic[11]))
+   {
+     _go32_info_block.stubinfo_version+=(_stubinfo->magic[11]-'0')*0x1000;
+   }
    __tb = _stubinfo->ds_segment * 16;
    _go32_info_block.size_of_transfer_buffer = _stubinfo->minkeep;
+   if (_go32_info_block.stubinfo_version>=0x0201)
+   {
+     /* convert from paragraphs to bytes */
+     _go32_info_block.size_of_transfer_buffer<<=4;
+   }
    _go32_info_block.pid = _stubinfo->psp_selector;
    _go32_info_block.master_interrupt_controller_base = ver.master_pic;
    _go32_info_block.slave_interrupt_controller_base = ver.slave_pic;

--------------52677CEB33EE
Content-Type: text/plain; charset=us-ascii; name="DJASMY.PAT"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="DJASMY.PAT"

*** djasm.y.~	Mon Aug 12 22:43:10 1996
--- djasm.y	Wed Jun 11 10:39:50 1997
***************
*** 9,14 ****
--- 9,16 ----
  #include <coff.h>
  #include <fcntl.h>
  #include <time.h>
+ #include <ctype.h>
+ #include <unistd.h>
  
  #define SMALL_EXE_HEADER 0
  #if SMALL_EXE_HEADER
***************
*** 98,103 ****
--- 100,106 ----
  #define REL_abs32	1
  #define REL_16		2
  #define REL_8		3
+ #define REL_abs8	4
  
  typedef struct Patch {
    struct Patch *next;
***************
*** 114,127 ****
  struct {
    int regs;
    int offset;
    int nsyms;
    Symbol *syms[10];
! } _modrm = { 0, 0, 0 };
  
  unsigned char sreg_overrides[] = {
    0x26, 0x2e, 0x36, 0x3e, 0x64, 0x65
  };
  
  void emit(void *v, int len);
  void emitb(int b);
  void emitw(int w);
--- 117,135 ----
  struct {
    int regs;
    int offset;
+   int addr16;
+   int addr32;
    int nsyms;
    Symbol *syms[10];
! } _modrm = { 0, 0, 0, 0, 0 };
  
  unsigned char sreg_overrides[] = {
    0x26, 0x2e, 0x36, 0x3e, 0x64, 0x65
  };
  
+ int yylex(void);
+ int yylex1(void);
+ 
  void emit(void *v, int len);
  void emitb(int b);
  void emitw(int w);
***************
*** 129,134 ****
--- 137,143 ----
  void emits(Symbol *s, int offset, int rel);
  void modrm(int mod, int reg, int rm);
  void reg(int reg);
+ void addr32(int sib);
  void sortsyms();
  
  int istemp(char *symname, char which);
***************
*** 159,165 ****
  
  %type <sym> ID
  %type <relsym> constID
! %type <i> const offset
  
  %token <sym> KID UID
  
--- 168,174 ----
  
  %type <sym> ID
  %type <relsym> constID
! %type <i> const offset scaledindex
  
  %token <sym> KID UID
  
***************
*** 178,194 ****
  %token <i> SHIFT SHLRD
  %token <i> ONEBYTE TWOBYTE ASCADJ
  %token <i> BITTEST GROUP3 GROUP3B GROUP3D GROUP3W GROUP6 GROUP7
! %token ALIGN
! %token BSS
  %token CALL CALLF COPYRIGHT
! %token DB DD DEC DECB DECD DECW DUP DW
  %token IN INC INCB INCD INCW INT INCLUDE
  %token JMPW JMPB JMPF
! %token LINKCOFF
  %token MOV MOVB MOVD MOVW
  %token IMUL IMULB IMULD IMULW
  %token ORG OUT
! %token POP POPW POPD PUSH PUSHW PUSHD
  %token RCS_ID RET RETF RETD RETFD
  %token STACK START
  %token TEST TESTB TESTD TESTW TYPE
--- 187,203 ----
  %token <i> SHIFT SHLRD
  %token <i> ONEBYTE TWOBYTE ASCADJ
  %token <i> BITTEST GROUP3 GROUP3B GROUP3D GROUP3W GROUP6 GROUP7
! %token ALIGN ARPL
! %token BOUND BSS BSF BSR
  %token CALL CALLF COPYRIGHT
! %token DB DD DEC DECB DECD DECW DUP DW ENTER
  %token IN INC INCB INCD INCW INT INCLUDE
  %token JMPW JMPB JMPF
! %token LAR LEA LINKCOFF LSL
  %token MOV MOVB MOVD MOVW
  %token IMUL IMULB IMULD IMULW
  %token ORG OUT
! %token POP POPW POPD PUSH PUSHW PUSHB PUSHD
  %token RCS_ID RET RETF RETD RETFD
  %token STACK START
  %token TEST TESTB TESTD TESTW TYPE
***************
*** 204,572 ****
  };
  
  struct opcode opcodes[] = {
!   "aaa", ONEBYTE, 0x37,
!   "aad", ASCADJ, 0xd5,
!   "aam", ASCADJ, 0xd4,
!   "aas", ONEBYTE, 0x3f,
!   "cbw", ONEBYTE, 0x98,
!   "cwde", TWOBYTE, 0x6698,
!   "clc", ONEBYTE, 0xf8,
!   "cld", ONEBYTE, 0xfc,
!   "cli", ONEBYTE, 0xfa,
!   "clts", TWOBYTE, 0x0f06,
!   "cmc", ONEBYTE, 0xf5,
!   "cmpsb", ONEBYTE, 0xa6,
!   "cmpsw", ONEBYTE, 0xa7,
!   "cmpsd", TWOBYTE, 0x66a7,
!   "cpuid", TWOBYTE, 0x0fa2,
!   "cwd", ONEBYTE, 0x99,
!   "cdq", TWOBYTE, 0x6699,
!   "daa", ONEBYTE, 0x27,
!   "das", ONEBYTE, 0x2f,
!   "hlt", ONEBYTE, 0xf4,
!   "insb", ONEBYTE, 0x6c,
!   "insw", ONEBYTE, 0x6d,
!   "insd", TWOBYTE, 0x666d,
!   "into", ONEBYTE, 0xce,
!   "iret", ONEBYTE, 0xcf,
!   "iretd", TWOBYTE, 0x66cf,
!   "lahf", ONEBYTE, 0x9f,
!   "leave", ONEBYTE, 0xc9,
!   "lock", ONEBYTE, 0xf0,
!   "lodsb", ONEBYTE, 0xac,
!   "lodsw", ONEBYTE, 0xad,
!   "lodsd", TWOBYTE, 0x66ad,
!   "movsb", ONEBYTE, 0xa4,
!   "movsw", ONEBYTE, 0xa5,
!   "movsd", TWOBYTE, 0x66a5,
!   "nop", ONEBYTE, 0x90,
!   "outsb", ONEBYTE, 0x6e,
!   "outsw", ONEBYTE, 0x6f,
!   "outsd", TWOBYTE, 0x666f,
!   "popa", ONEBYTE, 0x61,
!   "popad", TWOBYTE, 0x6661,
!   "popf", ONEBYTE, 0x9d,
!   "popfd", TWOBYTE, 0x669d,
!   "pusha", ONEBYTE, 0x60,
!   "pushad", TWOBYTE, 0x6660,
!   "pushf", ONEBYTE, 0x9c,
!   "pushfd", TWOBYTE, 0x669c,
!   "rep", ONEBYTE, 0xf3,
!   "repe", ONEBYTE, 0xf3,
!   "repz", ONEBYTE, 0xf3,
!   "repne", ONEBYTE, 0xf2,
!   "repnz", ONEBYTE, 0xf2,
!   "sahf", ONEBYTE, 0x9e,
!   "scasb", ONEBYTE, 0xae,
!   "scasw", ONEBYTE, 0xaf,
!   "scasd", TWOBYTE, 0x66af,
!   "stc", ONEBYTE, 0xf9,
!   "std", ONEBYTE, 0xfd,
!   "sti", ONEBYTE, 0xfb,
!   "stosb", ONEBYTE, 0xaa,
!   "stosw", ONEBYTE, 0xab,
!   "stosd", TWOBYTE, 0x66ab,
!   "wait", ONEBYTE, 0x9b,
!   "fwait", ONEBYTE, 0x9b,
!   "xlat", ONEBYTE, 0xd7,
!   "xlatb", ONEBYTE, 0xd7,
! 
!   ".addrsize", ONEBYTE, 0x67,
!   ".opsize", ONEBYTE, 0x66,
!   ".segcs", ONEBYTE, 0x2e,
!   ".segds", ONEBYTE, 0x3e,
!   ".seges", ONEBYTE, 0x26,
!   ".segss", ONEBYTE, 0x36,
!   ".segfs", ONEBYTE, 0x64,
!   ".seggs", ONEBYTE, 0x65,
! 
!   ".align", ALIGN, NO_ATTR,
!   ".bss", BSS, NO_ATTR,
!   ".copyright", COPYRIGHT, NO_ATTR,
!   ".db", DB, NO_ATTR,
!   ".dd", DD, NO_ATTR,
!   ".dup", DUP, NO_ATTR,
!   ".dw", DW, NO_ATTR,
!   ".id", RCS_ID, NO_ATTR,
!   ".include", INCLUDE, NO_ATTR,
!   ".linkcoff", LINKCOFF, NO_ATTR,
!   ".org", ORG, NO_ATTR,
!   ".stack", STACK, NO_ATTR,
!   ".start", START, NO_ATTR,
!   ".type", TYPE, NO_ATTR,
! 
!   "adc", ARITH2, 2,
!   "adcb", ARITH2B, 2,
!   "adcd", ARITH2D, 2,
!   "adcw", ARITH2W, 2,
!   "add", ARITH2, 0,
!   "addb", ARITH2B, 0,
!   "addd", ARITH2D, 0,
!   "addw", ARITH2W, 0,
!   "and", ARITH2, 4,
!   "andb", ARITH2B, 4,
!   "andd", ARITH2D, 4,
!   "andw", ARITH2W, 4,
!   "bt", BITTEST, 4,
!   "btc", BITTEST, 7,
!   "btr", BITTEST, 6,
!   "bts", BITTEST, 5,
!   "call", CALL, NO_ATTR,
!   "callf", CALLF, NO_ATTR,
!   "cmp", ARITH2, 7,
!   "cmpb", ARITH2B, 7,
!   "cmpd", ARITH2D, 7,
!   "cmpw", ARITH2W, 7,
!   "dec", DEC, NO_ATTR,
!   "decb", DECB, NO_ATTR,
!   "decd", DECD, NO_ATTR,
!   "decw", DECW, NO_ATTR,
!   "div", GROUP3, 6,
!   "divb", GROUP3B, 6,
!   "divd", GROUP3D, 6,
!   "divw", GROUP3W, 6,
!   "idiv", GROUP3, 7,
!   "idivb", GROUP3B, 7,
!   "idivd", GROUP3D, 7,
!   "idivw", GROUP3W, 7,
!   "imul", IMUL, NO_ATTR,
!   "imulb", IMULB, NO_ATTR,
!   "imuld", IMULD, NO_ATTR,
!   "imulw", IMULW, NO_ATTR,
!   "in", IN, NO_ATTR,
!   "inc", INC, NO_ATTR,
!   "incb", INCB, NO_ATTR,
!   "incd", INCD, NO_ATTR,
!   "incw", INCW, NO_ATTR,
!   "int", INT, NO_ATTR,
! 
!   "jo", JCC, 0,
!   "jno", JCC, 1,
!   "jb", JCC, 2,
!   "jc", JCC, 2,
!   "jnae", JCC, 2,
!   "jnb", JCC, 3,
!   "jnc", JCC, 3,
!   "jae", JCC, 3,
!   "jz", JCC, 4,
!   "je", JCC, 4,
!   "jnz", JCC, 5,
!   "jne", JCC, 5,
!   "jbe", JCC, 6,
!   "jna", JCC, 6,
!   "jnbe", JCC, 7,
!   "ja", JCC, 7,
!   "js", JCC, 8,
!   "jns", JCC, 9,
!   "jp", JCC, 10,
!   "jpe", JCC, 10,
!   "jnp", JCC, 11,
!   "jpo", JCC, 11,
!   "jl", JCC, 12,
!   "jnge", JCC, 12,
!   "jnl", JCC, 13,
!   "jge", JCC, 13,
!   "jle", JCC, 14,
!   "jng", JCC, 14,
!   "jnle", JCC, 15,
!   "jg", JCC, 15,
! 
!   "jol", JCCL, 0,
!   "jnol", JCCL, 1,
!   "jbl", JCCL, 2,
!   "jcl", JCCL, 2,
!   "jnael", JCCL, 2,
!   "jnbl", JCCL, 3,
!   "jncl", JCCL, 3,
!   "jael", JCCL, 3,
!   "jzl", JCCL, 4,
!   "jel", JCCL, 4,
!   "jnzl", JCCL, 5,
!   "jnel", JCCL, 5,
!   "jbel", JCCL, 6,
!   "jnal", JCCL, 6,
!   "jnbel", JCCL, 7,
!   "jal", JCCL, 7,
!   "jsl", JCCL, 8,
!   "jnsl", JCCL, 9,
!   "jpl", JCCL, 10,
!   "jpel", JCCL, 10,
!   "jnpl", JCCL, 11,
!   "jpol", JCCL, 11,
!   "jll", JCCL, 12,
!   "jngel", JCCL, 12,
!   "jnll", JCCL, 13,
!   "jgel", JCCL, 13,
!   "jlel", JCCL, 14,
!   "jngl", JCCL, 14,
!   "jnlel", JCCL, 15,
!   "jgl", JCCL, 15,
! 
!   "jcxz", JCXZ, 0,
!   "jecxz", JCXZ, 1,
! 
!   "jmp", JMPB, NO_ATTR,
!   "jmpf", JMPF, NO_ATTR,
!   "jmpl", JMPW, NO_ATTR,
!   "lds", LXS, 0xc5,
!   "les", LXS, 0xc4,
!   "lfs", LXS, 0x0fb4,
!   "lgs", LXS, 0x0fb5,
!   "lss", LXS, 0x0fb2,
!   "lgdt", GROUP7, 2,
!   "lidt", GROUP7, 3,
!   "lldt", GROUP6, 2,
!   "lmsw", GROUP7, 6,
!   "loop", LOOP, 0xe2,
!   "loope", LOOP, 0xe1,
!   "loopne", LOOP, 0xe0,
!   "loopnz", LOOP, 0xe0,
!   "loopz", LOOP, 0xe1,
!   "ltr", GROUP6, 3,
!   "mov", MOV, NO_ATTR,
!   "movb", MOVB, NO_ATTR,
!   "movd", MOVD, NO_ATTR,
!   "movw", MOVW, NO_ATTR,
!   "movsx", MOVSZX, 0xbe,
!   "movzx", MOVSZX, 0xb6,
!   "mul", GROUP3, 4,
!   "mulb", GROUP3B, 4,
!   "muld", GROUP3D, 4,
!   "mulw", GROUP3W, 4,
!   "not", GROUP3, 2,
!   "neg", GROUP3, 3,
!   "or", ARITH2, 1,
!   "orb", ARITH2B, 1,
!   "ord", ARITH2D, 1,
!   "orw", ARITH2W, 1,
!   "out", OUT, NO_ATTR,
!   "pop", POP, NO_ATTR,
!   "popw", POPW, NO_ATTR,
!   "popd", POPD, NO_ATTR,
!   "push", PUSH, NO_ATTR,
!   "pushw", PUSHW, NO_ATTR,
!   "pushd", PUSHD, NO_ATTR,
!   "rcl", SHIFT, 2,
!   "rcr", SHIFT, 3,
!   "ret", RET, NO_ATTR,
!   "retd", RETD, NO_ATTR,
!   "retf", RETF, NO_ATTR,
!   "retfd", RETFD, NO_ATTR,
!   "rol", SHIFT, 0,
!   "ror", SHIFT, 1,
!   "sar", SHIFT, 7,
!   "sbb", ARITH2, 3,
!   "sbbb", ARITH2B, 3,
!   "sbbd", ARITH2D, 3,
!   "sbbw", ARITH2W, 3,
! 
!   "seto", SETCC, 0,
!   "setno", SETCC, 1,
!   "setb", SETCC, 2,
!   "setc", SETCC, 2,
!   "setnae", SETCC, 2,
!   "setnb", SETCC, 3,
!   "setnc", SETCC, 3,
!   "setae", SETCC, 3,
!   "setz", SETCC, 4,
!   "sete", SETCC, 4,
!   "setnz", SETCC, 5,
!   "setne", SETCC, 5,
!   "setbe", SETCC, 6,
!   "setna", SETCC, 6,
!   "setnbe", SETCC, 7,
!   "seta", SETCC, 7,
!   "sets", SETCC, 8,
!   "setns", SETCC, 9,
!   "setp", SETCC, 10,
!   "setpe", SETCC, 10,
!   "setnp", SETCC, 11,
!   "setpo", SETCC, 11,
!   "setl", SETCC, 12,
!   "setnge", SETCC, 12,
!   "setnl", SETCC, 13,
!   "setge", SETCC, 13,
!   "setle", SETCC, 14,
!   "setng", SETCC, 14,
!   "setnle", SETCC, 15,
!   "setg", SETCC, 15,
! 
!   "sgdt", GROUP7, 0,
!   "sidt", GROUP7, 1,
!   "sldt", GROUP6, 0,
!   "sal", SHIFT, 4,
!   "shl", SHIFT, 4,
!   "shld", SHLRD, 0xa4,
!   "shr", SHIFT, 5,
!   "shrd", SHLRD, 0xac,
!   "smsw", GROUP7, 4,
!   "str", GROUP6, 1,
!   "sub", ARITH2, 5,
!   "subb", ARITH2B, 5,
!   "subd", ARITH2D, 5,
!   "subw", ARITH2W, 5,
!   "test", TEST, NO_ATTR,
!   "testb", TESTB, NO_ATTR,
!   "testw", TESTW, NO_ATTR,
!   "testd", TESTD, NO_ATTR,
!   "verr", GROUP6, 4,
!   "verw", GROUP6, 5,
!   "xchg", XCHG, NO_ATTR,
!   "xor", ARITH2, 6,
!   "xorb", ARITH2B, 6,
!   "xord", ARITH2D, 6,
!   "xorw", ARITH2W, 6,
! 
!   "al", REG8, 0,
!   "cl", REG8, 1,
!   "dl", REG8, 2,
!   "bl", REG8, 3,
!   "ah", REG8, 4,
!   "ch", REG8, 5,
!   "dh", REG8, 6,
!   "bh", REG8, 7,
! 
!   "es", SREG, 0,
!   "cs", SREG, 1,
!   "ss", SREG, 2,
!   "ds", SREG, 3,
!   "fs", SREG, 4,
!   "gs", SREG, 5,
! 
!   "ax", REG16, 0,
!   "cx", REG16, 1,
!   "dx", REG16, 2,
!   "bx", REG16, 3,
!   "sp", REG16, 4,
!   "bp", REG16, 5,
!   "si", REG16, 6,
!   "di", REG16, 7,
! 
!   "eax", REG32, 0,
!   "ecx", REG32, 1,
!   "edx", REG32, 2,
!   "ebx", REG32, 3,
!   "esp", REG32, 4,
!   "ebp", REG32, 5,
!   "esi", REG32, 6,
!   "edi", REG32, 7,
! 
!   "cr0", CRREG, 0,
!   "cr2", CRREG, 2,
!   "cr3", CRREG, 3,
! 
!   "dr0", DRREG, 0,
!   "dr1", DRREG, 1,
!   "dr2", DRREG, 2,
!   "dr3", DRREG, 3,
!   "dr6", DRREG, 6,
!   "dr7", DRREG, 7,
! 
!   "tr3", TRREG, 3,
!   "tr4", TRREG, 4,
!   "tr5", TRREG, 5,
!   "tr6", TRREG, 6,
!   "tr7", TRREG, 7};
  %}
  
  %start lines
--- 213,591 ----
  };
  
  struct opcode opcodes[] = {
!   {"aaa", ONEBYTE, 0x37},
!   {"aad", ASCADJ, 0xd5},
!   {"aam", ASCADJ, 0xd4},
!   {"aas", ONEBYTE, 0x3f},
!   {"cbw", ONEBYTE, 0x98},
!   {"cwde", TWOBYTE, 0x6698},
!   {"clc", ONEBYTE, 0xf8},
!   {"cld", ONEBYTE, 0xfc},
!   {"cli", ONEBYTE, 0xfa},
!   {"clts", TWOBYTE, 0x0f06},
!   {"cmc", ONEBYTE, 0xf5},
!   {"cmpsb", ONEBYTE, 0xa6},
!   {"cmpsw", ONEBYTE, 0xa7},
!   {"cmpsd", TWOBYTE, 0x66a7},
!   {"cpuid", TWOBYTE, 0x0fa2},
!   {"cwd", ONEBYTE, 0x99},
!   {"cdq", TWOBYTE, 0x6699},
!   {"daa", ONEBYTE, 0x27},
!   {"das", ONEBYTE, 0x2f},
!   {"hlt", ONEBYTE, 0xf4},
!   {"insb", ONEBYTE, 0x6c},
!   {"insw", ONEBYTE, 0x6d},
!   {"insd", TWOBYTE, 0x666d},
!   {"into", ONEBYTE, 0xce},
!   {"iret", ONEBYTE, 0xcf},
!   {"iretd", TWOBYTE, 0x66cf},
!   {"lahf", ONEBYTE, 0x9f},
!   {"leave", ONEBYTE, 0xc9},
!   {"lock", ONEBYTE, 0xf0},
!   {"lodsb", ONEBYTE, 0xac},
!   {"lodsw", ONEBYTE, 0xad},
!   {"lodsd", TWOBYTE, 0x66ad},
!   {"movsb", ONEBYTE, 0xa4},
!   {"movsw", ONEBYTE, 0xa5},
!   {"movsd", TWOBYTE, 0x66a5},
!   {"nop", ONEBYTE, 0x90},
!   {"outsb", ONEBYTE, 0x6e},
!   {"outsw", ONEBYTE, 0x6f},
!   {"outsd", TWOBYTE, 0x666f},
!   {"popa", ONEBYTE, 0x61},
!   {"popad", TWOBYTE, 0x6661},
!   {"popf", ONEBYTE, 0x9d},
!   {"popfd", TWOBYTE, 0x669d},
!   {"pusha", ONEBYTE, 0x60},
!   {"pushad", TWOBYTE, 0x6660},
!   {"pushf", ONEBYTE, 0x9c},
!   {"pushfd", TWOBYTE, 0x669c},
!   {"rep", ONEBYTE, 0xf3},
!   {"repe", ONEBYTE, 0xf3},
!   {"repz", ONEBYTE, 0xf3},
!   {"repne", ONEBYTE, 0xf2},
!   {"repnz", ONEBYTE, 0xf2},
!   {"sahf", ONEBYTE, 0x9e},
!   {"scasb", ONEBYTE, 0xae},
!   {"scasw", ONEBYTE, 0xaf},
!   {"scasd", TWOBYTE, 0x66af},
!   {"stc", ONEBYTE, 0xf9},
!   {"std", ONEBYTE, 0xfd},
!   {"sti", ONEBYTE, 0xfb},
!   {"stosb", ONEBYTE, 0xaa},
!   {"stosw", ONEBYTE, 0xab},
!   {"stosd", TWOBYTE, 0x66ab},
!   {"wait", ONEBYTE, 0x9b},
!   {"fwait", ONEBYTE, 0x9b},
!   {"xlat", ONEBYTE, 0xd7},
!   {"xlatb", ONEBYTE, 0xd7},
! 
!   {".addrsize", ONEBYTE, 0x67},
!   {".opsize", ONEBYTE, 0x66},
!   {".segcs", ONEBYTE, 0x2e},
!   {".segds", ONEBYTE, 0x3e},
!   {".seges", ONEBYTE, 0x26},
!   {".segss", ONEBYTE, 0x36},
!   {".segfs", ONEBYTE, 0x64},
!   {".seggs", ONEBYTE, 0x65},
! 
!   {".align", ALIGN, NO_ATTR},
!   {".bss", BSS, NO_ATTR},
!   {".copyright", COPYRIGHT, NO_ATTR},
!   {".db", DB, NO_ATTR},
!   {".dd", DD, NO_ATTR},
!   {".dup", DUP, NO_ATTR},
!   {".dw", DW, NO_ATTR},
!   {".id", RCS_ID, NO_ATTR},
!   {".include", INCLUDE, NO_ATTR},
!   {".linkcoff", LINKCOFF, NO_ATTR},
!   {".org", ORG, NO_ATTR},
!   {".stack", STACK, NO_ATTR},
!   {".start", START, NO_ATTR},
!   {".type", TYPE, NO_ATTR},
! 
!   {"adc", ARITH2, 2},
!   {"adcb", ARITH2B, 2},
!   {"adcd", ARITH2D, 2},
!   {"adcw", ARITH2W, 2},
!   {"add", ARITH2, 0},
!   {"addb", ARITH2B, 0},
!   {"addd", ARITH2D, 0},
!   {"addw", ARITH2W, 0},
!   {"and", ARITH2, 4},
!   {"andb", ARITH2B, 4},
!   {"andd", ARITH2D, 4},
!   {"andw", ARITH2W, 4},
!   {"arpl", ARPL, NO_ATTR},
!   {"bound", BOUND, NO_ATTR},
!   {"bsf", BSF, NO_ATTR},
!   {"bsr", BSR, NO_ATTR},
!   {"bt", BITTEST, 4},
!   {"btc", BITTEST, 7},
!   {"btr", BITTEST, 6},
!   {"bts", BITTEST, 5},
!   {"call", CALL, NO_ATTR},
!   {"callf", CALLF, NO_ATTR},
!   {"cmp", ARITH2, 7},
!   {"cmpb", ARITH2B, 7},
!   {"cmpd", ARITH2D, 7},
!   {"cmpw", ARITH2W, 7},
!   {"dec", DEC, NO_ATTR},
!   {"decb", DECB, NO_ATTR},
!   {"decd", DECD, NO_ATTR},
!   {"decw", DECW, NO_ATTR},
!   {"div", GROUP3, 6},
!   {"divb", GROUP3B, 6},
!   {"divd", GROUP3D, 6},
!   {"divw", GROUP3W, 6},
!   {"enter", ENTER, NO_ATTR},
!   {"idiv", GROUP3, 7},
!   {"idivb", GROUP3B, 7},
!   {"idivd", GROUP3D, 7},
!   {"idivw", GROUP3W, 7},
!   {"imul", IMUL, NO_ATTR},
!   {"imulb", IMULB, NO_ATTR},
!   {"imuld", IMULD, NO_ATTR},
!   {"imulw", IMULW, NO_ATTR},
!   {"in", IN, NO_ATTR},
!   {"inc", INC, NO_ATTR},
!   {"incb", INCB, NO_ATTR},
!   {"incd", INCD, NO_ATTR},
!   {"incw", INCW, NO_ATTR},
!   {"int", INT, NO_ATTR},
! 
!   {"jo", JCC, 0},
!   {"jno", JCC, 1},
!   {"jb", JCC, 2},
!   {"jc", JCC, 2},
!   {"jnae", JCC, 2},
!   {"jnb", JCC, 3},
!   {"jnc", JCC, 3},
!   {"jae", JCC, 3},
!   {"jz", JCC, 4},
!   {"je", JCC, 4},
!   {"jnz", JCC, 5},
!   {"jne", JCC, 5},
!   {"jbe", JCC, 6},
!   {"jna", JCC, 6},
!   {"jnbe", JCC, 7},
!   {"ja", JCC, 7},
!   {"js", JCC, 8},
!   {"jns", JCC, 9},
!   {"jp", JCC, 10},
!   {"jpe", JCC, 10},
!   {"jnp", JCC, 11},
!   {"jpo", JCC, 11},
!   {"jl", JCC, 12},
!   {"jnge", JCC, 12},
!   {"jnl", JCC, 13},
!   {"jge", JCC, 13},
!   {"jle", JCC, 14},
!   {"jng", JCC, 14},
!   {"jnle", JCC, 15},
!   {"jg", JCC, 15},
! 
!   {"jol", JCCL, 0},
!   {"jnol", JCCL, 1},
!   {"jbl", JCCL, 2},
!   {"jcl", JCCL, 2},
!   {"jnael", JCCL, 2},
!   {"jnbl", JCCL, 3},
!   {"jncl", JCCL, 3},
!   {"jael", JCCL, 3},
!   {"jzl", JCCL, 4},
!   {"jel", JCCL, 4},
!   {"jnzl", JCCL, 5},
!   {"jnel", JCCL, 5},
!   {"jbel", JCCL, 6},
!   {"jnal", JCCL, 6},
!   {"jnbel", JCCL, 7},
!   {"jal", JCCL, 7},
!   {"jsl", JCCL, 8},
!   {"jnsl", JCCL, 9},
!   {"jpl", JCCL, 10},
!   {"jpel", JCCL, 10},
!   {"jnpl", JCCL, 11},
!   {"jpol", JCCL, 11},
!   {"jll", JCCL, 12},
!   {"jngel", JCCL, 12},
!   {"jnll", JCCL, 13},
!   {"jgel", JCCL, 13},
!   {"jlel", JCCL, 14},
!   {"jngl", JCCL, 14},
!   {"jnlel", JCCL, 15},
!   {"jgl", JCCL, 15},
! 
!   {"jcxz", JCXZ, 0},
!   {"jecxz", JCXZ, 1},
! 
!   {"jmp", JMPB, NO_ATTR},
!   {"jmpf", JMPF, NO_ATTR},
!   {"jmpl", JMPW, NO_ATTR},
!   {"lar", LAR, NO_ATTR},
!   {"lds", LXS, 0xc5},
!   {"lea", LEA, NO_ATTR},
!   {"les", LXS, 0xc4},
!   {"lfs", LXS, 0x0fb4},
!   {"lgs", LXS, 0x0fb5},
!   {"lsl", LSL, NO_ATTR},
!   {"lss", LXS, 0x0fb2},
!   {"lgdt", GROUP7, 2},
!   {"lidt", GROUP7, 3},
!   {"lldt", GROUP6, 2},
!   {"lmsw", GROUP7, 6},
!   {"loop", LOOP, 0xe2},
!   {"loope", LOOP, 0xe1},
!   {"loopne", LOOP, 0xe0},
!   {"loopnz", LOOP, 0xe0},
!   {"loopz", LOOP, 0xe1},
!   {"ltr", GROUP6, 3},
!   {"mov", MOV, NO_ATTR},
!   {"movb", MOVB, NO_ATTR},
!   {"movd", MOVD, NO_ATTR},
!   {"movw", MOVW, NO_ATTR},
!   {"movsx", MOVSZX, 0xbe},
!   {"movzx", MOVSZX, 0xb6},
!   {"mul", GROUP3, 4},
!   {"mulb", GROUP3B, 4},
!   {"muld", GROUP3D, 4},
!   {"mulw", GROUP3W, 4},
!   {"not", GROUP3, 2},
!   {"neg", GROUP3, 3},
!   {"or", ARITH2, 1},
!   {"orb", ARITH2B, 1},
!   {"ord", ARITH2D, 1},
!   {"orw", ARITH2W, 1},
!   {"out", OUT, NO_ATTR},
!   {"pop", POP, NO_ATTR},
!   {"popw", POPW, NO_ATTR},
!   {"popd", POPD, NO_ATTR},
!   {"push", PUSH, NO_ATTR},
!   {"pushb", PUSHB, NO_ATTR},
!   {"pushw", PUSHW, NO_ATTR},
!   {"pushd", PUSHD, NO_ATTR},
!   {"rcl", SHIFT, 2},
!   {"rcr", SHIFT, 3},
!   {"ret", RET, NO_ATTR},
!   {"retd", RETD, NO_ATTR},
!   {"retf", RETF, NO_ATTR},
!   {"retfd", RETFD, NO_ATTR},
!   {"rol", SHIFT, 0},
!   {"ror", SHIFT, 1},
!   {"sar", SHIFT, 7},
!   {"sbb", ARITH2, 3},
!   {"sbbb", ARITH2B, 3},
!   {"sbbd", ARITH2D, 3},
!   {"sbbw", ARITH2W, 3},
! 
!   {"seto", SETCC, 0},
!   {"setno", SETCC, 1},
!   {"setb", SETCC, 2},
!   {"setc", SETCC, 2},
!   {"setnae", SETCC, 2},
!   {"setnb", SETCC, 3},
!   {"setnc", SETCC, 3},
!   {"setae", SETCC, 3},
!   {"setz", SETCC, 4},
!   {"sete", SETCC, 4},
!   {"setnz", SETCC, 5},
!   {"setne", SETCC, 5},
!   {"setbe", SETCC, 6},
!   {"setna", SETCC, 6},
!   {"setnbe", SETCC, 7},
!   {"seta", SETCC, 7},
!   {"sets", SETCC, 8},
!   {"setns", SETCC, 9},
!   {"setp", SETCC, 10},
!   {"setpe", SETCC, 10},
!   {"setnp", SETCC, 11},
!   {"setpo", SETCC, 11},
!   {"setl", SETCC, 12},
!   {"setnge", SETCC, 12},
!   {"setnl", SETCC, 13},
!   {"setge", SETCC, 13},
!   {"setle", SETCC, 14},
!   {"setng", SETCC, 14},
!   {"setnle", SETCC, 15},
!   {"setg", SETCC, 15},
! 
!   {"sgdt", GROUP7, 0},
!   {"sidt", GROUP7, 1},
!   {"sldt", GROUP6, 0},
!   {"sal", SHIFT, 4},
!   {"shl", SHIFT, 4},
!   {"shld", SHLRD, 0xa4},
!   {"shr", SHIFT, 5},
!   {"shrd", SHLRD, 0xac},
!   {"smsw", GROUP7, 4},
!   {"str", GROUP6, 1},
!   {"sub", ARITH2, 5},
!   {"subb", ARITH2B, 5},
!   {"subd", ARITH2D, 5},
!   {"subw", ARITH2W, 5},
!   {"test", TEST, NO_ATTR},
!   {"testb", TESTB, NO_ATTR},
!   {"testw", TESTW, NO_ATTR},
!   {"testd", TESTD, NO_ATTR},
!   {"verr", GROUP6, 4},
!   {"verw", GROUP6, 5},
!   {"xchg", XCHG, NO_ATTR},
!   {"xor", ARITH2, 6},
!   {"xorb", ARITH2B, 6},
!   {"xord", ARITH2D, 6},
!   {"xorw", ARITH2W, 6},
! 
!   {"al", REG8, 0},
!   {"cl", REG8, 1},
!   {"dl", REG8, 2},
!   {"bl", REG8, 3},
!   {"ah", REG8, 4},
!   {"ch", REG8, 5},
!   {"dh", REG8, 6},
!   {"bh", REG8, 7},
! 
!   {"es", SREG, 0},
!   {"cs", SREG, 1},
!   {"ss", SREG, 2},
!   {"ds", SREG, 3},
!   {"fs", SREG, 4},
!   {"gs", SREG, 5},
! 
!   {"ax", REG16, 0},
!   {"cx", REG16, 1},
!   {"dx", REG16, 2},
!   {"bx", REG16, 3},
!   {"sp", REG16, 4},
!   {"bp", REG16, 5},
!   {"si", REG16, 6},
!   {"di", REG16, 7},
! 
!   {"eax", REG32, 0},
!   {"ecx", REG32, 1},
!   {"edx", REG32, 2},
!   {"ebx", REG32, 3},
!   {"esp", REG32, 4},
!   {"ebp", REG32, 5},
!   {"esi", REG32, 6},
!   {"edi", REG32, 7},
! 
!   {"cr0", CRREG, 0},
!   {"cr2", CRREG, 2},
!   {"cr3", CRREG, 3},
! 
!   {"dr0", DRREG, 0},
!   {"dr1", DRREG, 1},
!   {"dr2", DRREG, 2},
!   {"dr3", DRREG, 3},
!   {"dr6", DRREG, 6},
!   {"dr7", DRREG, 7},
! 
!   {"tr3", TRREG, 3},
!   {"tr4", TRREG, 4},
!   {"tr5", TRREG, 5},
!   {"tr6", TRREG, 6},
!   {"tr7", TRREG, 7},
! };
  %}
  
  %start lines
***************
*** 607,617 ****
  	| ARITH2 REG8 ',' regmem	{ emitb($1*8+2); reg($2); }
  
  	| ARITH2W regmem ',' constID	{ emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); }
! 	| ARITH2 REG16 ',' constID	{ if ($2)
! 					      {emitb(0x81); modrm(3, $1, $2);}
! 					  else
  					      modrm (0,$1,5);
! 					  emits($4.sym,$4.ofs,REL_abs);
  					}
  	| ARITH2 REG16 ',' REG16	{ emitb($1*8+1); modrm(3, $4, $2); }
  	| ARITH2 regmem ',' REG16	{ emitb($1*8+1); reg($4); }
--- 626,644 ----
  	| ARITH2 REG8 ',' regmem	{ emitb($1*8+2); reg($2); }
  
  	| ARITH2W regmem ',' constID	{ emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); }
! 	| ARITH2 REG16 ',' constID	{ if ($2) {
! 					      int v=$4.ofs+$4.sym->value;
! 					      if ($4.sym->defined && v>=-128 && v<=127) {
! 						  emitb(0x83); modrm(3, $1, $2);
! 						  emits($4.sym,$4.ofs,REL_abs8);
! 					      } else {
! 						  emitb(0x81); modrm(3, $1, $2);
! 						  emits($4.sym,$4.ofs,REL_abs);
! 					      }
! 					  } else {
  					      modrm (0,$1,5);
! 					      emits($4.sym,$4.ofs,REL_abs);
! 					  }
  					}
  	| ARITH2 REG16 ',' REG16	{ emitb($1*8+1); modrm(3, $4, $2); }
  	| ARITH2 regmem ',' REG16	{ emitb($1*8+1); reg($4); }
***************
*** 619,639 ****
  
  	| ARITH2D regmem ',' constID	{ emitb(0x66); emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); emitw($4.ofs >> 16); }
  	| ARITH2 REG32 ',' constID	{ emitb(0x66);
! 					  if ($2)
! 					      {emitb(0x81); modrm(3, $1, $2);}
! 					  else
  					      modrm (0,$1,5);
! 					  emits($4.sym,$4.ofs,REL_abs);	emitw($4.ofs >>	16); }
  	| ARITH2 REG32 ',' REG32	{ emitb(0x66); emitb($1*8+1); modrm(3, $4, $2); }
  	| ARITH2 regmem ',' REG32	{ emitb(0x66); emitb($1*8+1); reg($4); }
  	| ARITH2 REG32 ',' regmem	{ emitb(0x66); emitb($1*8+3); reg($2); }
  
  	| ASCADJ			{ emitb($1); emitb(0x0a); }
  	| ASCADJ const			{ emitb($1); emitb($2); }
  
  	| ALIGN const			{ do_align($2,0x90); }
  	| ALIGN const ',' const		{ do_align($2,$4); }
  
  	| BITTEST REG16 ',' REG16	{ emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
  	| BITTEST regmem ',' REG16	{ emitb(0x0f); emitb($1*8+0x83); reg($4); }
  	| BITTEST REG32 ',' REG32	{ emitb(0x66); emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
--- 646,681 ----
  
  	| ARITH2D regmem ',' constID	{ emitb(0x66); emitb(0x81); reg($1); emits($4.sym,$4.ofs,REL_abs); emitw($4.ofs >> 16); }
  	| ARITH2 REG32 ',' constID	{ emitb(0x66);
! 					  if ($2) {
! 					      int v=$4.ofs+$4.sym->value;
! 					      if ($4.sym->defined && v>=-128 && v<=127) {
! 						  emitb(0x83); modrm(3, $1, $2);
! 						  emits($4.sym,$4.ofs,REL_abs8);
! 					      } else {
! 						  emitb(0x81); modrm(3, $1, $2);
! 						  emits($4.sym,$4.ofs,REL_abs32);
! 					      }
! 					  } else {
  					      modrm (0,$1,5);
! 					      emits($4.sym,$4.ofs,REL_abs32);
! 					  }
! 					}
  	| ARITH2 REG32 ',' REG32	{ emitb(0x66); emitb($1*8+1); modrm(3, $4, $2); }
  	| ARITH2 regmem ',' REG32	{ emitb(0x66); emitb($1*8+1); reg($4); }

  	| ARITH2 REG32 ',' regmem	{ emitb(0x66); emitb($1*8+3); reg($2); }
  
+ 	| ARPL REG16 ',' REG16		{ emitb(0x63); modrm(3,$4,$2); }
+ 	| ARPL regmem ',' REG16		{ emitb(0x63); reg($4); }
+ 
  	| ASCADJ			{ emitb($1); emitb(0x0a); }
  	| ASCADJ const			{ emitb($1); emitb($2); }
  
  	| ALIGN const			{ do_align($2,0x90); }
  	| ALIGN const ',' const		{ do_align($2,$4); }
  
+ 	| BOUND REG16 ',' regmem	{ emitb(0x62); reg($2); }
+ 	| BOUND REG32 ',' regmem	{ emitb(0x66); emitb(0x62); reg($2); }
+ 
  	| BITTEST REG16 ',' REG16	{ emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
  	| BITTEST regmem ',' REG16	{ emitb(0x0f); emitb($1*8+0x83); reg($4); }
  	| BITTEST REG32 ',' REG32	{ emitb(0x66); emitb(0x0f); emitb($1*8+0x83); modrm(3, $4, $2); }
***************
*** 642,649 ****
--- 684,702 ----
  	| BITTEST regmem ',' const	{ emitb(0x0f); emitb(0xba); reg($1); emitb($4); }
  	| BITTEST REG32 ',' const	{ emitb(0x66); emitb(0x0f); emitb(0xba); modrm(3, $1, $2); emitb($4); }
  
+ 	| BSF REG16 ',' REG16		{ emitb(0x0f); emitb(0xbc); modrm(3, $4, $2); }
+ 	| BSF REG16 ',' regmem		{ emitb(0x0f); emitb(0xbc); reg($2); }
+ 	| BSF REG32 ',' REG32		{ emitb(0x66); emitb(0x0f); emitb(0xbc); modrm(3, $4, $2); }
+ 	| BSF REG32 ',' regmem		{ emitb(0x66); emitb(0x0f); emitb(0xbc); reg($2); }
+ 
+ 	| BSR REG16 ',' REG16		{ emitb(0x0f); emitb(0xbd); modrm(3, $4, $2); }
+ 	| BSR REG16 ',' regmem		{ emitb(0x0f); emitb(0xbd); reg($2); }
+ 	| BSR REG32 ',' REG32		{ emitb(0x66); emitb(0x0f); emitb(0xbd); modrm(3, $4, $2); }
+ 	| BSR REG32 ',' regmem		{ emitb(0x66); emitb(0x0f); emitb(0xbd); reg($2); }
+ 
  	| CALL ID			{ emitb(0xe8); emits($2,0,REL_16); $2->type |= SYM_code; }
  	| CALLF regmem			{ emitb(0xff); reg(3); }
+ 	| CALLF const ':' constID	{ emitb(0x9a); emits($4.sym,$4.ofs,REL_abs); emitw($2); }
  
  	| COPYRIGHT STRING		{ strbuf[strbuflen] = 0; add_copyright(strbuf); }
  	| RCS_ID			{ strbuf[strbuflen] = 0; add_rcs_ident(strbuf); }
***************
*** 659,664 ****
--- 712,719 ----
  	| DECW regmem			{ emitb(0xff); reg(1); }
  	| DECD regmem			{ emitb(0x66); emitb(0xff); reg(1); }
  
+ 	| ENTER const ',' const		{ emitb(0xc8); emitw($2); emitb($4); }
+ 
  	| IN REG8 ',' const		{ emitb(0xe4); emitb($4); }
  	| IN REG16 ',' const		{ emitb(0xe5); emitb($4); }
  	| IN REG32 ',' const		{ emitb(0x66); emitb(0xe5); emitb($4);}
***************
*** 729,737 ****
--- 784,801 ----
  	| JMPF regmem			{ emitb(0xff); reg(5); }
  	| JMPF const ':' constID	{ emitb(0xea); emits($4.sym,$4.ofs,REL_abs); emitw($2); }
  
+ 	| LAR REG16 ',' REG16		{ emitb(0x0f); emitb(0x02); modrm(3, $4, $2); }
+ 	| LAR REG16 ',' regmem		{ emitb(0x0f); emitb(0x02); reg($2); }
+ 
+ 	| LEA REG16 ',' regmem		{ emitb(0x8d); reg($2); }
+ 	| LEA REG32 ',' regmem		{ emitb(0x66); emitb(0x8d); reg($2); }
+ 
  	| LINKCOFF STRING		{ strbuf[strbuflen]=0; do_linkcoff(strbuf); }
  	| LOOP ID			{ emitb($1); emits($2,0,REL_8); }
  
+ 	| LSL REG16 ',' REG16		{ emitb(0x0f); emitb(0x03); modrm(3, $4, $2); }
+ 	| LSL REG16 ',' regmem		{ emitb(0x0f); emitb(0x03); reg($2); }
+ 
  	| LXS REG16 ',' regmem		{ if ($1>>8) emitb($1>>8); emitb($1 & 0xff); reg($2); }
  	| LXS REG32 ',' regmem		{ emitb(0x66); if ($1>>8) emitb($1>>8); emitb($1 & 0xff); reg($2); }
  
***************
*** 818,823 ****
--- 882,888 ----
  	| PUSH SREG			{ do_sreg_push($2); }
  	| PUSHW regmem			{ emitb(0xff); reg(6); }
  	| PUSHD regmem			{ emitb(0x66); emitb(0xff); reg(6); }
+ 	| PUSHB const			{ emitb(0x6a); emitb($2); }
  	| PUSHW constID			{ emitb(0x68); emits($2.sym,$2.ofs,REL_abs); }
  	| PUSHD constID			{ emitb(0x66); emitb(0x68); emits($2.sym,$2.ofs,REL_abs); emitw($2.ofs >> 16); }
  
***************
*** 937,947 ****
  
  regmemitem
  	: SREG ':' regmemitem		{ emitb(sreg_overrides[$1]); }
! 	| REG16				{ _modrm.regs |= (1<<$1); }
  	| UID				{ _modrm.syms[_modrm.nsyms++] = $1; }
  	| const				{ _modrm.offset += $1; }
  	;
  
  const
  	: NUMBER			{ $$ = $1; }
  	| KID				{ $$ = $1->value; }
--- 1002,1045 ----
  
  regmemitem
  	: SREG ':' regmemitem		{ emitb(sreg_overrides[$1]); }
! 	| REG16				{ if (_modrm.addr32) {
! 					      _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
! 					      yyerror("Cannot mix 16 and 32 bit addressing");
! 					  } else {
! 					      _modrm.regs |= (1<<$1);
! 					      _modrm.addr16=1;
! 					  }
! 					}
! 	| REG32				{ addr32((1<<$1)|0x100); }
! 	| scaledindex			{ addr32($1); }
  	| UID				{ _modrm.syms[_modrm.nsyms++] = $1; }
  	| const				{ _modrm.offset += $1; }
  	;
  
+ scaledindex
+ 	: REG32 '*' const		{ if ($3==1 || $3==2 || $3==4 || $3==8)
+ 					      $$ = (1<<($1)) | ($3<<8);
+ 					  else {
+ 					      _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+ 					      yyerror("Scale must be 1,2,4 or 8");
+ 					  }
+ 					}
+ 	| const '*' REG32		{ if ($1==1 || $1==2 || $1==4 || $1==8)
+ 					      $$ = (1<<($3)) | ($1<<8);
+ 					  else {
+ 					      _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+ 					      yyerror("Scale must be 1,2,4 or 8");
+ 					  }
+ 					}
+ 	| REG32 OP_SHL const		{ if ($3>=0 && $3<=3)
+ 					      $$ = (1<<($1)) | (0x100<<$3);
+ 					  else {
+ 					      _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+ 					      yyerror("Shift must be 0,1,2 or 3");
+ 					  }
+ 					}
+ 	;
+ 
  const
  	: NUMBER			{ $$ = $1; }
  	| KID				{ $$ = $1->value; }
***************
*** 1014,1020 ****
    return strcmp (((struct opcode *)e1)->name, ((struct opcode *)e2)->name);
  }
  
! main(int argc, char **argv)
  {
    Symbol *s;
    Patch *p;
--- 1112,1118 ----
    return strcmp (((struct opcode *)e1)->name, ((struct opcode *)e2)->name);
  }
  
! int main(int argc, char **argv)
  {
    Symbol *s;
    Patch *p;
***************
*** 1222,1248 ****
          leader = INC_LEADER;
        else
          leader = S_LEADER;
        if (image_type == OUT_exe)
          for (i=0; i<EXE_HEADER_SIZE; i++)
          {
- 	  if ((i%15) == 0)
- 	    fputs(leader, outfile);
            fprintf(outfile, "0x%02x", exe[i]);
            if ((i&15) == 15)
            {
              fputc('\n', outfile);
            }
            else
              fputc(',', outfile);
          }
        for (i=((image_type==OUT_com)?0x100:0); i<bsspc; i++)
        {
- 	if ((i&15) == 0)
- 	  fputs(leader, outfile);
          fprintf(outfile, "0x%02x", outbin[i]);
          if ((i&15) == 15)
          {
            fputc('\n', outfile);
          }
          else
            if (i<bsspc-1)
--- 1320,1345 ----
          leader = INC_LEADER;
        else
          leader = S_LEADER;
+       fputs(leader, outfile);
        if (image_type == OUT_exe)
          for (i=0; i<EXE_HEADER_SIZE; i++)
          {
            fprintf(outfile, "0x%02x", exe[i]);
            if ((i&15) == 15)
            {
              fputc('\n', outfile);
+             fputs(leader, outfile);
            }
            else
              fputc(',', outfile);
          }
        for (i=((image_type==OUT_com)?0x100:0); i<bsspc; i++)
        {
          fprintf(outfile, "0x%02x", outbin[i]);
          if ((i&15) == 15)
          {
            fputc('\n', outfile);
+           fputs(leader, outfile);
          }
          else
            if (i<bsspc-1)
***************
*** 1284,1296 ****
      fputc('\n', mapfile);
      fclose(mapfile);
    }
  }
  
  void yyerror(char *s)
  {
    fprintf(stderr, "%s:%d: %s\n", inname, lineno, s);
    strbuf[strbuflen] = 0;
!   fprintf(stderr, "Last token was `%s' (%s)\n", last_token, yytname[yytranslate[last_tret]]);
    total_errors++;
  }
  
--- 1381,1394 ----
      fputc('\n', mapfile);
      fclose(mapfile);
    }
+   return 0;
  }
  
  void yyerror(char *s)
  {
    fprintf(stderr, "%s:%d: %s\n", inname, lineno, s);
    strbuf[strbuflen] = 0;
!   fprintf(stderr, "Last token was `%s' (%s)\n", last_token, yytname[(unsigned char)yytranslate[last_tret]]);
    total_errors++;
  }
  
***************
*** 1325,1331 ****
    s->defined = 1;
    while (s->patches)
    {
!     int v, o;
      unsigned char *cp;
      Patch *p = s->patches;
      s->patches = s->patches->next;
--- 1423,1429 ----
    s->defined = 1;
    while (s->patches)
    {
!     int v=0, o=0;
      unsigned char *cp;
      Patch *p = s->patches;
      s->patches = s->patches->next;
***************
*** 1452,1457 ****
--- 1550,1559 ----
        v = s->value + offset;
        emitw(v);
        break;
+     case REL_abs8:
+       v = s->value + offset;
+       emitb(v);
+       break;
      case REL_16:
        v = s->value - pc - 2 + offset;
        emitw(v);
***************
*** 1499,1504 ****
--- 1601,1636 ----
    emitb((mod<<6) | (reg<<3) | rm);
  }
  
+ int findreg(int regbits)
+ {
+   int i=0;
+   while (regbits) {
+     regbits>>=1;
+     i++;
+   }
+   return i?i-1:4;
+ }
+ 
+ int findscl(int sclbits)
+ {
+   static int bits[]={0,0,1,0,2,0,0,0,3};
+   return bits[sclbits];
+ }
+ 
+ int nooffset(int mbyte, int needsib)
+ {
+     if (_modrm.offset == 0 && _modrm.nsyms == 0) {
+       emitb(mbyte);
+       if (needsib)
+ 	emitb(mbyte>>8);
+       if (mbyte&0100)
+         emitb(0);
+       _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
+       return 1;
+     }
+     return 0;
+ }
+ 
  int reg2mbyte[] = { 0x48, 0x88, 0x60, 0xa0, 0x40, 0x80, 0x20, 0x08 };
  
  void reg(int which)
***************
*** 1506,1542 ****
    int i;
    int v;
    int mbyte = which << 3;
  
!   if (_modrm.regs == 0)
!   {
!     emitb(movacc ? movacc : mbyte + 6);
      movacc=0;
!   }
!   else if (_modrm.regs == 0x20 && _modrm.offset == 0 && _modrm.nsyms == 0)
!   {
!     emitb(mbyte + 0x86);
!   }
!   else
!   {
!     for (i=0; i<8; i++)
!       if (reg2mbyte[i] == _modrm.regs)
        {
!         mbyte |= i;
!         break;
        }
-     if (i == 8)
-     {
-       printf("%s:%s: Invalid registers in R/M\n", inname, lineno);
-       total_errors ++;
      }
!     if (_modrm.offset == 0 && _modrm.nsyms == 0)
!     {
!       emitb(mbyte);
!       _modrm.nsyms = _modrm.regs = _modrm.offset = 0;
        return;
!     }
!     emitb(mbyte + 0x80);
    }
    v = _modrm.offset;
    for (i=0; i<_modrm.nsyms; i++)
    {
--- 1638,1709 ----
    int i;
    int v;
    int mbyte = which << 3;
+   int needsib = 0;
  
!   if (_modrm.regs == 0) {
!     /* This handles the case of displacement only addressing (no register
!      * ofsets)
!      */
!     mbyte=movacc ? movacc : mbyte + (_modrm.addr32 ? 5 : 6);
      movacc=0;
!   } else if (_modrm.regs == 0x20 && _modrm.offset == 0 && _modrm.nsyms == 0) {
!     /* [bp+0] */
!     nooffset(mbyte|0106,0);
!     return;
!   } else {
!     if (_modrm.addr32) {
!       if (_modrm.addr32&0xff) {
! 	int sib= findreg( _modrm.addr32     &0xff)    |
! 	        (findreg((_modrm.addr32>>8 )&0xff)<<3)|
! 	        (findscl((_modrm.addr32>>16)&0x0f)<<6);
! 	if (sib==045 && _modrm.offset == 0 && _modrm.nsyms == 0) {
! 	  /* [ebp+0] */
! 	  nooffset(mbyte|0104|(045<<8),1);
! 	  return;
! 	} else if (sib==044) {
! 	  /* [esp] */
! 	  mbyte|=(sib<<8)|004;
! 	  needsib=1;
! 	} else if ((sib&070)==0040) {
! 	  /* no index */
! 	  mbyte|=sib&007;
! 	} else if ((sib&007)==0005) {
! 	  /* ebp is base */
! 	  mbyte|=(sib<<8)|004;
! 	  needsib=1;
! 	  if (nooffset(mbyte|0100,1))
! 	    return;
! 	} else {
! 	  mbyte|=(sib<<8)|004;
! 	  needsib=1;
! 	}
!       } else {
! 	int sib=(005				     )|
! 	        (findreg((_modrm.addr32>>8 )&0xff)<<3)|
! 		(findscl((_modrm.addr32>>16)&0x0f)<<6);
! 	mbyte|=(sib<<8)|004;
! 	if (nooffset(mbyte|0200,1))
! 	  return;
!       }
!     } else {
!       /* 16 bit addressing */
!       for (i=0; i<8; i++)
! 	if (reg2mbyte[i] == _modrm.regs)
! 	{
! 	  mbyte |= i;
! 	  break;
! 	}
!       if (i == 8)
        {
! 	printf("%s:%d: Invalid registers in R/M\n", inname, lineno);
! 	total_errors ++;
        }
      }
!     if (nooffset(mbyte,needsib))
        return;
!     mbyte|=0200;
    }
+ 
    v = _modrm.offset;
    for (i=0; i<_modrm.nsyms; i++)
    {
***************
*** 1549,1564 ****
        p = (Patch *)malloc(sizeof(Patch));
        p->next = s->patches;
        s->patches = p;
!       p->location = pc;
        p->lineno = lineno;
!       p->rel = REL_abs;
      }
!   }   
!   emitw(v);
!   _modrm.nsyms = _modrm.regs = _modrm.offset = 0;
  }
  
! int yylex()
  {
    last_tret = yylex1();
    return last_tret;
--- 1716,1790 ----
        p = (Patch *)malloc(sizeof(Patch));
        p->next = s->patches;
        s->patches = p;
!       p->location = pc+1; /* ALL bytes emitted below, accounts for yet to be emitted mbyte */
        p->lineno = lineno;
!       p->rel = _modrm.addr32 ? REL_abs32 : REL_abs;
!       _modrm.regs=0; /* force offset field to be full size (2/4 bytes rather than 1) */
      }
!   }
!   if (_modrm.regs && v>=-128 && v<=127) {
!     emitb(mbyte^0300); /* change mod from 2/4 ((d)word offset) to 1 (byte offset) */
!     if (needsib)
!       emitb(mbyte>>8);
!     emitb(v);
!   } else {
!     emitb(mbyte);
!     if (needsib)
!       emitb(mbyte>>8);
!     if (_modrm.addr32)
!       emitd(v);
!     else
!       emitw(v);
!   }
! 
!   _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
  }
  
! void addr32(int sib)
! {
!   char *err=0;
! 
!   if (_modrm.addr16) {
!     err="Cannot mix 16 and 32 bit addressing";
!   } else {
!     if (!_modrm.addr32) emitb(0x67);
!     _modrm.addr32|=0x1000000;
!     if ((sib&0xf00)>0x100) {
!       if ((sib&0xff)==0x10) {
! 	err="esp cannot be scaled";
!       } else if (_modrm.addr32&0xff00) {
! 	err="scaled index already used";
!       } else {
! 	_modrm.addr32|=sib<<8;
!       }
!     } else {
!       if (!(_modrm.addr32&0xff)) {
! 	_modrm.addr32|=(sib&0xff)|0x1000000;
!       } else if (!(_modrm.addr32&0xff00)) {
! 	if ((sib&0xff)==0x10) {
! 	  if ((_modrm.addr32&0xff)==0x10) {
! 	    err="esp cannot be the index";
! 	  } else {
! 	    _modrm.addr32=(_modrm.addr32&0xff)<<8;
! 	    _modrm.addr32|=(sib&0xff)|0x1010000;
! 	  }
! 	} else {
! 	  _modrm.addr32|=sib<<8;
! 	}
!       } else {
! 	err="scaled index already used";
!       }
!     }
!   }
!   if (err) {
!     yyerror(err);
!     _modrm.nsyms = _modrm.addr32 = _modrm.addr16 = _modrm.offset = _modrm.regs = 0;
!   } else {
!     _modrm.regs=-1;
!   }
! }
! 
! int yylex(void)
  {
    last_tret = yylex1();
    return last_tret;
***************
*** 1568,1584 ****
    char c1, c2;
    int token;
  } twochars[] = {
!   '=', '=', '=',
!   '>', '=', OP_GE,
!   '<', '=', OP_LE,
!   '<', '>', OP_NE,
!   '!', '=', OP_NE,
!   '&', '&', OP_AND,
!   '|', '|', OP_OR,
!   '<', '<', OP_SHL,
!   '>', '>', OP_SHR};
  
! int yylex1()
  {
    int c, c2, i, oldc;
    struct opcode *opp, op;
--- 1794,1811 ----
    char c1, c2;
    int token;
  } twochars[] = {
!   {'=', '=', '='},
!   {'>', '=', OP_GE},
!   {'<', '=', OP_LE},
!   {'<', '>', OP_NE},
!   {'!', '=', OP_NE},
!   {'&', '&', OP_AND},
!   {'|', '|', OP_OR},
!   {'<', '<', OP_SHL},
!   {'>', '>', OP_SHR}
! };
  
! int yylex1(void)
  {
    int c, c2, i, oldc;
    struct opcode *opp, op;
***************
*** 1922,1933 ****
    SCNHDR *f_thdr;		/* Text section header */
    SCNHDR *f_dhdr;		/* Data section header */
    SCNHDR *f_bhdr;		/* Bss section header */
!   AOUTHDR f_ohdr;		/* Optional file header (a.out) */
    SYMENT *symbol;
    RELOC *rp;
    int cnt, i;
    void *base;
!   int textbase, database, bssbase, delta;
    char smallname[9];
  
    f = open (filename, O_RDONLY | O_BINARY);
--- 2149,2160 ----
    SCNHDR *f_thdr;		/* Text section header */
    SCNHDR *f_dhdr;		/* Data section header */
    SCNHDR *f_bhdr;		/* Bss section header */
! /*  AOUTHDR f_ohdr;*/		/* Optional file header (a.out) */
    SYMENT *symbol;
    RELOC *rp;
    int cnt, i;
    void *base;
!   int textbase, database, bssbase/*, delta*/;
    char smallname[9];
  
    f = open (filename, O_RDONLY | O_BINARY);
***************
*** 2000,2006 ****
  	      break;
  	    case N_UNDEF:
  	      if (symbol->e_value == 0)
! 		0;  /* Nothing -- external reference.  */
  	      else if (!get_symbol (p, 0))
  		{
  		  /* New common variable.  */
--- 2227,2233 ----
  	      break;
  	    case N_UNDEF:
  	      if (symbol->e_value == 0)
! 		/*0*/;  /* Nothing -- external reference.  */
  	      else if (!get_symbol (p, 0))
  		{
  		  /* New common variable.  */
***************
*** 2028,2034 ****
  
        for (; cnt > 0; cnt--, rp++)
  	{
! 	  Symbol *s;
  	  int delta;
  
  	  if (symbol[rp->r_symndx].e.e.e_zeroes == 0)
--- 2255,2261 ----
  
        for (; cnt > 0; cnt--, rp++)
  	{
! 	  Symbol *s=0;
  	  int delta;
  
  	  if (symbol[rp->r_symndx].e.e.e_zeroes == 0)

--------------52677CEB33EE
Content-Type: text/plain; charset=us-ascii; name="GO32H.PAT"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="GO32H.PAT"

*** go32.h.~	Thu May 25 02:44:06 1995
--- go32.h	Wed Jun 11 11:28:40 1997
***************
*** 32,37 ****
--- 32,38 ----
    unsigned long  linear_address_of_original_psp;
    unsigned short run_mode;
    unsigned short run_mode_info;
+   unsigned short stubinfo_version;
  } __Go32_Info_Block;
  
  extern __Go32_Info_Block _go32_info_block;

--------------52677CEB33EE
Content-Type: text/plain; charset=us-ascii; name="STUBASM.PAT"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="STUBASM.PAT"

*** stub.asm.~	Wed Jun 11 09:43:38 1997
--- stub.asm	Wed Jun 11 10:57:04 1997
***************
*** 67,73 ****
  	.org	0			; just in case
  stubinfo:
  stubinfo_magic:				; char [16]
! 	.db	"go32stub, v 2.00"	; version may change, [0..7] won't
  stubinfo_size:				; unsigned long
  	.dd	stubinfo_end		; bytes in structure
  stubinfo_minstack:			; unsigned long
--- 67,73 ----
  	.org	0			; just in case
  stubinfo:
  stubinfo_magic:				; char [16]
! 	.db	"go32stub, v 2.01"	; version may change, [0..7] won't
  stubinfo_size:				; unsigned long
  	.dd	stubinfo_end		; bytes in structure
  stubinfo_minstack:			; unsigned long
***************
*** 77,83 ****
  stubinfo_initial_size:			; unsigned long
  	.dd	0			; size of initial segment
  stubinfo_minkeep:			; unsigned short
! 	.dw	16384			; amount of automatic real-mode buffer
  stubinfo_ds_selector:			; unsigned short
  	.dw	0			; our DS selector (used for transfer buffer)
  stubinfo_ds_segment:			; unsigned short
--- 77,83 ----
  stubinfo_initial_size:			; unsigned long
  	.dd	0			; size of initial segment
  stubinfo_minkeep:			; unsigned short
! 	.dw	1024			; amount of automatic real-mode buffer in paragraphs
  stubinfo_ds_selector:			; unsigned short
  	.dw	0			; our DS selector (used for transfer buffer)
  stubinfo_ds_segment:			; unsigned short
***************
*** 126,146 ****
  
  resize_again:
  	mov	bx, end_of_memory	; does not include PSP
  	mov	ax, [stubinfo_minkeep]
  	cmp	bx, ax			; is our program big enough to hold it?
  	jae	@f1
  	mov	bx, ax
  @f1:
  	mov	[stubinfo_minkeep], bx	; store for reference
! 	inc	bh			; add 256 bytes for PSP
! 	mov	cx, 0xff04		; 0xff is for below
! 	shr	bx, cl			; bytes to paragraphs
  
  	mov	ah, 0x4a		; ES = PSP segment from above
  	int	0x21			; resize our memory block
  	jnc	@f1			; did it work?
! 	shl	bx,cl			; calculate smaller [keep] value
! 	dec	bh
  	mov	[stubinfo_minkeep], bx
  	jmp	resize_again		; and try again
  @f1:
--- 126,148 ----
  
  resize_again:
  	mov	bx, end_of_memory	; does not include PSP
+ 	mov	cx, 0xff04		; 0xff is for below
+ 	shr	bx, cl			; bytes to paragraphs
  	mov	ax, [stubinfo_minkeep]
  	cmp	bx, ax			; is our program big enough to hold it?
  	jae	@f1
  	mov	bx, ax
  @f1:
  	mov	[stubinfo_minkeep], bx	; store for reference
! ;	inc	bh			; add 256 bytes for PSP
! 	add	bx,0x10
  
  	mov	ah, 0x4a		; ES = PSP segment from above
  	int	0x21			; resize our memory block
  	jnc	@f1			; did it work?
! ;	shl	bx,cl			; calculate smaller [keep] value
! ;	dec	bh
! 	sub	bx,0x10
  	mov	[stubinfo_minkeep], bx
  	jmp	resize_again		; and try again
  @f1:

--------------52677CEB33EE
Content-Type: text/plain; charset=us-ascii; name="STUBEDIT.PAT"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="STUBEDIT.PAT"

*** stubedit.c.~	Sat Oct 26 10:09:48 1996
--- stubedit.c	Wed Jun 11 11:57:58 1997
***************
*** 13,18 ****
--- 13,19 ----
  
  unsigned long size_of_stubinfo = 0;
  char *client_stub_info;
+ unsigned short stubinfo_version=0;
  
  void find_info(char *filename)
  {  
***************
*** 37,42 ****
--- 38,51 ----
      exit(1);
    }
  
+   stubinfo_version=(test_magic[12]-'0')*0x0100+
+ 	       (test_magic[14]-'0')*0x0010+
+ 	       (test_magic[15]-'0')*0x0001;
+   if (isdigit(test_magic[11]))
+   {
+     stubinfo_version+=(test_magic[11]-'0')*0x1000;
+   }
+ 
    fread(header, 4, 1, f);
    size_of_stubinfo = (header[0]) | (header[1]<<8)
                     | (header[2])<<16 | (header[3]<<24);
***************
*** 126,131 ****
--- 135,146 ----
    sprintf(buf, "%#lx (%dk)", v, v / 1024L);
  }
  
+ void num_p2s(void *addr, char *buf)
+ {
+   unsigned long v = (*(unsigned short *)addr)*(stubinfo_version>=0x201?16:1);
+   sprintf(buf, "%#lx (%dk)", v, v / 1024L);
+ }
+ 
  void num_s2v(void *addr, char *buf)
  {
    unsigned long r = 0;
***************
*** 145,150 ****
--- 160,184 ----
    *(unsigned long *)addr = r;
  }
  
+ void num_s2p(void *addr, char *buf)
+ {
+   unsigned long r = 0;
+   char s = 0;
+   sscanf(buf, "%i%c", &r, &s);
+   switch (s)
+   {
+     case 'k':
+     case 'K':
+       r *= 1024L;
+       break;
+     case 'm':
+     case 'M':
+       r *= 1048576L;
+       break;
+   }
+   *(unsigned short *)addr = (r+15)/(stubinfo_version>=0x201?16:1);
+ }
+ 
  struct {
    char *short_name;
    char *long_name;
***************
*** 162,168 ****
      "bufsize",
      "Size of real-memory transfer buffer (bytes/K/M)",
      STUBINFO_MINKEEP,
!     num_v2s, num_s2v
    },
    {
      "runfile",
--- 196,202 ----
      "bufsize",
      "Size of real-memory transfer buffer (bytes/K/M)",
      STUBINFO_MINKEEP,
!     num_p2s, num_s2p
    },
    {
      "runfile",
***************
*** 220,225 ****
--- 254,262 ----
      give_help();
  
    find_info(argv[1]);
+   if (argc <= 2)
+ 	fprintf(stderr, "stubinfo version %x.%02x\n",stubinfo_version>>8,
+ 						     stubinfo_version&0xff);
  
    if (view_only)
    {

--------------52677CEB33EE--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019