/*
Copyright Notice
================
BOCHS is Copyright 1994 by Kevin P. Lawton.

BOCHS is shareware for PERSONAL USE only.

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
              528 Lexington St.
              Waltham, MA 02154

    EMail:    bochs@tiac.net
*/








#include "bx_bochs.h"

  Bit16u
bx_read_segment_register(Bit32u index)
{
  switch (index) {
    case BX_SEG_REG_ES:
      return(bx_cpu.es.selector.value);
    case BX_SEG_REG_CS:
      return(bx_cpu.cs.selector.value);
    case BX_SEG_REG_SS:
      return(bx_cpu.ss.selector.value);
    case BX_SEG_REG_DS:
      return(bx_cpu.ds.selector.value);
    case BX_SEG_REG_FS:
      return(bx_cpu.fs.selector.value);
    case BX_SEG_REG_GS:
      return(bx_cpu.gs.selector.value);
    }
  bx_printf(1, "bx_read_segment_register() undefined segment register!\n");
  return(0); /* keep compiler from complaining */
}

  void
bx_write_segment_register(Bit32u index, Bit16u value)
{
  switch (index) {
    case BX_SEG_REG_ES:
      bx_load_seg_reg(&bx_cpu.es, value);
      return;
    case BX_SEG_REG_CS:
      bx_load_seg_reg(&bx_cpu.cs, value);
      return;
    case BX_SEG_REG_SS:
      bx_load_seg_reg(&bx_cpu.ss, value);
      return;
    case BX_SEG_REG_DS:
      bx_load_seg_reg(&bx_cpu.ds, value);
      return;
    case BX_SEG_REG_FS:
      bx_load_seg_reg(&bx_cpu.fs, value);
      return;
    case BX_SEG_REG_GS:
      bx_load_seg_reg(&bx_cpu.gs, value);
      return;
    }
  bx_printf(1, "bx_write_segment_register() undefined segment register!\n");
}

  void
bx_load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
{
  seg->selector.value = new_value;

#if 0
  switch (seg_reg) {
    case BX_SEG_REG_CS:
      if (bx_32bit_addrsize) {
        bx_printf(1, "32bit addressing not yet supported!\n");
	}
      else { /* 16 bit address mode */
        bx_CS.selector.index =
        bx_CS.selector.ti    =
        bx_CS.selector.rpl   = 0;
	bx_CS.base =
        bx_CS.limit =
        bx_CS.attributes.d
        bx_CS.attributes.p
        bx_CS.attributes.dpl
        bx_CS.attributes.s
        bx_CS.attributes.type
        }
      break;
    case BX_SEG_REG_DS:
      break;
    case BX_SEG_REG_ES:
      break;
    case BX_SEG_REG_SS:
      break;
      }
#endif /* if 0 ... */
}



  void
bx_LES_GvMp()
{
  Bit32u reg_addr, mem_addr;
  Bit16u reg_16, es;
  int mem_type;
  bx_segment_reg_t *mem_seg_reg;

  bx_decode_exgx(&reg_addr, &mem_addr, &mem_type, &mem_seg_reg);
  
  if (bx_32bit_addrsize) {
    bx_printf(1, "do not know how to do LES in 32bit address mode!\n");
    }
  else { /* 16 bit mode */
    if (mem_type == BX_MEMORY_REF) {
      bx_access_virtual(mem_seg_reg, mem_addr, 2, BX_READ, &reg_16);
      bx_access_virtual(mem_seg_reg, mem_addr + 2, 2, BX_READ, &es);
      bx_load_seg_reg(&bx_cpu.es, es);
      BX_WRITE_16BIT_REG(reg_addr, reg_16);
      }
    else {
      bx_printf(1, "invalid use of LES, must use memory reference!\n");
      }
    }
}

  void
bx_LDS_GvMp()
{
  Bit32u reg_addr, mem_addr;
  Bit16u reg_16, ds;
  int mem_type;
  bx_segment_reg_t *mem_seg_reg;

  bx_decode_exgx(&reg_addr, &mem_addr, &mem_type, &mem_seg_reg);
  
  if (bx_32bit_addrsize) {
    bx_printf(1, "do not know how to do LDS in 32bit address mode!\n");
    }
  else { /* 16 bit mode */
    if (mem_type == BX_MEMORY_REF) {
      bx_access_virtual(mem_seg_reg, mem_addr, 2, BX_READ, &reg_16);
      bx_access_virtual(mem_seg_reg, mem_addr + 2, 2, BX_READ, &ds);
      bx_load_seg_reg(&bx_cpu.ds, ds);
      BX_WRITE_16BIT_REG(reg_addr, reg_16);
      }
    else {
      bx_printf(1, "invalid use of LDS, must use memory reference!\n");
      }
    }
}

void bx_LFS_Mp() {bx_invalid_instruction();}
void bx_LGS_Mp() {bx_invalid_instruction();}
void bx_LSS_Mp() {bx_invalid_instruction();}
