#define SCREENSHOT_ADDR  0x281d
#define SCREENSHOT_YY    0x281e
#define SCREENSHOT 0x2c00    

static void hex1(int x)
{
  Serial.print("0123456789abcdef"[x & 0xf]);
}
static void hex2(int x)
{
  hex1(x >> 4);
  hex1(x);
}
static void hex4(int x)
{
  hex2(highByte(x));
  hex2(lowByte(x));
}
static void dump(unsigned int addr, unsigned int c)
{
  unsigned int limit;
  
  for (limit = addr + c; addr < limit; addr++) {
    if ((addr & 0xf) == 0) {
      hex4(addr);
      Serial.print(": ");
    }
    hex2(GD.rd(addr));
    Serial.print(' ');
    if ((addr & 0xf) == 0xf) {
      Serial.println("");
    }
  }
}

static void bdump(int addr, int c)
{
  int limit;
  static char msg[3];
  
  for (limit = addr + 2*c; addr < limit; addr += 2) {
    unsigned int v = GD.rd16(addr);
    msg[0] = '0' + (v & 0xf);
    msg[1] = '0' + ((v >> 4) & 0x1f);
    msg[2] = 0;
    Serial.print(msg);
  }
}

static void binary(int addr, int c)
{
  int limit;
  static char msg[3];
  
  for (limit = addr + 2*c; addr < limit; addr += 2) {
    unsigned int v = GD.rd16(addr);
    Serial.write(lowByte(v));
    Serial.write(highByte(v));
  }
}

static int frames;
static void screenshot()
{
  int yy;

  if (1) {
    Serial.write(0x55);   // sync byte
    Serial.write(lowByte(frames));
    Serial.write(highByte(frames));
    frames++;

    for (yy = 0; yy < 600; yy += 2) {
      GD.wr16(SCREENSHOT_YY, yy);
      GD.waitvblank();
      GD.waitvblank();
      binary(SCREENSHOT, 400);
    }
  } else {
    frames++;
  } 
}

static void soundshot()
{
  dump(SCREENSHOT, 1024);
}
