/* 
 * DANG_BEGIN_MODULE
 * 
 * Contains the routines that dump CPU information
 *
 * DANG_END_MODULE
 *
 * DANG_BEGIN_CHANGELOG
 *
 * $Date: $
 * $Source: $
 * $Revision: $
 * $State: $
 *
 * $Log: $
 *
 * DANG_END_CHANGELOG
 */

#include "dosemu.h"
#include "base/memory.h"
#include "base/cpu.h"
#include "base/int.h"

void show_regs(const char *file, int line)
{
  Bit32u i;
  Bit8u *sp;
  Bit8u *cp = SEG_ADR((Bit8u *), cs, ip);

  if (!cp) {
    g_printf("Ain't gonna do it, cs=0x%x, eip=0x%x\n",REG(cs),LWORD(eip));
    return;
  }

  if (!_SP)
    sp = (SEG_ADR((Bit8u *), ss, sp)) + 0x8000;
  else
    sp = SEG_ADR((Bit8u *), ss, sp);

  g_printf("\nProgram=%s, Line=%d\n", file, line);
  g_printf("EIP: %04x:%08lx", _CS, _EIP);
  g_printf(" ESP: %04x:%08lx", _SS, _ESP);
  g_printf("  VFLAGS(b): ");
  for (i = (1 << 0x14); i > 0; i = (i >> 1)) {
    g_printf((vflags & i) ? "1" : "0");
    if (i & 0x10100) g_printf(" ");
  }

  g_printf("\nEAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx VFLAGS(h): %08lx",
	      _EAX, _EBX, _ECX, _EDX, (Bit32u)vflags);
  g_printf("\nESI: %08lx EDI: %08lx EBP: %08lx", _ESI, _EDI, _EBP);
  g_printf(" DS: %04x ES: %04x FS: %04x GS: %04x\n", _DS, _ES, _FS, _GS);

  /* display vflags symbolically...the #f "stringizes" the macro name */
#define PFLAG(f)  if (REG(eflags)&(f)) g_printf(#f" ")

  g_printf("FLAGS: ");
  PFLAG(CF);
  PFLAG(PF);
  PFLAG(AF);
  PFLAG(ZF);
  PFLAG(SF);
  PFLAG(TF);
  PFLAG(IF);
  PFLAG(DF);
  PFLAG(OF);
  PFLAG(NT);
  PFLAG(RF);
  PFLAG(VM);
  PFLAG(AC);
  PFLAG(VIF);
  PFLAG(VIP);
  g_printf(" IOPL: %lu\n", ((vflags & IOPL_MASK) >> 12));

  /* display the 10 bytes before and after CS:EIP.  the -> points
   * to the byte at address CS:EIP
   */
  g_printf("STACK: ");
  sp -= 10;
  for (i = 0; i < 10; i++)
    g_printf("%02x ", *sp++);
  g_printf("-> ");
  for (i = 0; i < 10; i++)
    g_printf("%02x ", *sp++);
  g_printf("\n");
  g_printf("OPS  : ");
  cp -= 10;
  for (i = 0; i < 10; i++)
    g_printf("%02x ", *cp++);
  g_printf("-> ");
  for (i = 0; i < 10; i++)
    g_printf("%02x ", *cp++);
  g_printf("\n");
}

void show_ints(int min, int max)
{
  int i, b;

  max = (max - min) / 3;
  for (i = 0, b = min; i <= max; i++, b += 3) {
    g_printf("%02x| %04x:%04x->%05x    ", b, INT_READ_SEG(b),
	     INT_READ_OFS(b), INT_READ_VEC(b));
    g_printf("%02x| %04x:%04x->%05x    ", b+1, INT_READ_SEG(b+1),
	     INT_READ_OFS(b+1),	INT_READ_VEC(b+1));
    g_printf("%02x| %04x:%04x->%05x\n", b+2, INT_READ_SEG(b+2),
	     INT_READ_OFS(b+2),	INT_READ_VEC(b+2));
  }
}

