// Copyright Notice
// ================
// BOCHS is Copyright 1994-1999 by Kevin P. Lawton.
//
// BOCHS is commercial software.
//
// For more information, read the file 'LICENSE' included in the bochs
// distribution.  If you don't have access to this file, or have questions
// regarding the licensing policy, the author may be contacted via:
//
//     US Mail:  Kevin Lawton
//               439 Marrett Rd.
//               Lexington, MA 02421-7714
//
//     EMail:    bochs@world.std.com





#include "bochs.h"



static Bit16u *aaa[8] = {
  & BX,
  & BX,
  & BP,
  & BP,
  & SI,
  & DI,
  & BP,
  & BX,
  };

static Bit16u *bbb[8] = {
  & SI,
  & DI,
  & SI,
  & DI,
  (Bit16u *) & BX_CPU_THIS_PTR empty_register,
  (Bit16u *) & BX_CPU_THIS_PTR empty_register,
  (Bit16u *) & BX_CPU_THIS_PTR empty_register,
  (Bit16u *) & BX_CPU_THIS_PTR empty_register
  };




  void
BX_CPU_C::decode_exgx16(unsigned modrm)
{
  Bit8u  displ8;
  Bit16u displ16;
  unsigned mod, rm;

#if BX_WEIRDISMS
    i->seg_reg = NULL;
#endif

  // |  76 | 543 | 210
  // | mod | ttt |  rm

  BX_INSTR_MODRM16(modrm);
  i->nnn = (modrm>>3) & 0x07;
  mod = modrm & 0xc0;
  rm = modrm & 0x07;

  if (mod == 0xc0) {
    i->rm_addr = rm;
    BX_CPU_THIS_PTR rm_type = BX_REGISTER_REF;
    return;
    }
  else { // mod != 3
    BX_CPU_THIS_PTR rm_type = BX_MEMORY_REF;

    if (mod == 0x40) {
      displ8 = fetch_next_byte();
      i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm] + (Bit8s) displ8);
      if (i->seg_reg == NULL)
        i->seg_reg = BX_CPU_THIS_PTR sreg_mod01_rm16[rm];
      else
        i->seg_reg = i->seg_reg;
      return;
      }
    if (mod == 0x80) {
      displ16 = fetch_next_word();
      i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm] + (Bit16s) displ16);
      if (i->seg_reg == NULL)
        i->seg_reg = BX_CPU_THIS_PTR sreg_mod10_rm16[rm];
      else
        i->seg_reg = i->seg_reg;
      return;
      }

    // mod == 0x00
    if (rm==6)
      i->rm_addr = fetch_next_word();
    else
      i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm]);

    if (i->seg_reg == NULL)
      i->seg_reg = BX_CPU_THIS_PTR sreg_mod00_rm16[rm];
    else
      i->seg_reg = i->seg_reg;
    return;
    }
}
