#include <vectrex.h>


#define signed8 int

#define unsigned8 unsigned int


#define joybit Joy_Digital

#define tstat (*((volatile unsigned8 *) 0xc856))


#define pot0 (*((volatile signed8 *) 0xc81b))

#define pot1 (*((volatile signed8 *) 0xc81c))

#define pot2 (*((volatile signed8 *) 0xc81d))

#define pot3 (*((volatile signed8 *) 0xc81e))


#define epot0 (*((volatile unsigned8 *) 0xc81f))

#define epot1 (*((volatile unsigned8 *) 0xc820))

#define epot2 (*((volatile unsigned8 *) 0xc821))

#define epot3 (*((volatile unsigned8 *) 0xc822))


#define t1lolc (*((volatile unsigned8 *) 0xd004))


#define read_ram(x) (*((volatile signed8 *) x))


#define joystick1_button1 (signed8)(read_ram(0xC80F) & 1U) /* A */

#define joystick1_button2 (signed8)(read_ram(0xC80F) & 2U) /* S */

#define joystick1_button3 (signed8)(read_ram(0xC80F) & 4U) /* D */

#define joystick1_button4 (signed8)(read_ram(0xC80F) & 8U) /* F */


static signed8 XJoy, YJoy, button1, button2, button3, button4;

static void poll_joystick(void)
{
  joybit();
  if (pot0 < -10) {
    // Left

    XJoy = -1;
  } else if (pot0 > 10) {
	// Right

	XJoy = 1;
  } else {
    XJoy = 0;
  }
  if (pot1 < -10) {
	// Down

	YJoy = -1;
  } else if (pot1 > 10) {
    // Up

	YJoy = 1;
  } else {
    YJoy = 0;
  }
  asm("pshs x,y,u,dp");
  asm("lda  #0");
  asm("jsr  0HF1B4 ; read_btns_mask":::"a","b","d");
  asm("puls dp,u,y,x");
  button1 = joystick1_button1;
  button2 = joystick1_button2;
  button3 = joystick1_button3;
  button4 = joystick1_button4;
}

static void init_hardware(void)
{
	// setup joystick read function to read only joystick 1

	epot0 = 1;
	epot1 = 3;
	epot2 = 0;
	epot3 = 0;
}

static int y, debugging;
static long addr, line, base;
static char text[26];

void hex(unsigned int val, int offset) {
  unsigned int nib1 = (val>>4)&15;
  unsigned int nib2 = val&15;
  text[offset] += nib1; text[offset+1] += nib2;
  if (nib1 > 9) text[offset] += 7;
  if (nib2 > 9) text[offset+1] += 7;
}

static void printline(void) {
  int i;
  // "0000:0000 0000 0000 0000\x80"

  for (i = 0; i < 25; i++) text[i] = '0';
  text[4] = ':'; text[9] = text[14] = text[19] = ' ';
  text[24] = 0x80;
  hex((unsigned int)(line>>8),0); hex((unsigned int)line, 2);
  hex(*((char *)line), 5);        hex(*((char *)(line+1L)), 7);
  hex(*((char *)(line+2L)), 10);  hex(*((char *)(line+3L)), 12);
  hex(*((char *)(line+4L)), 15);  hex(*((char *)(line+5L)), 17);
  hex(*((char *)(line+6L)), 20);  hex(*((char *)(line+7L)), 22);
  Print_Str_d(y, -127, text); y-= 17;
}

static void DEBUG(void) {
  if (debugging) {
    int i, byte;
    base = addr; line = 0;
//    for (;;) {


      y = 127;
      Intensity_7F();
      for (i = 0; i < 16; i++) {
        byte = (int) *((char *)(addr+(long)i));
        if ((unsigned int)byte == 0x80U) text[i] = '?';
        else if ((unsigned int)byte < 32U) text[i] = '?';
        else text[i] = (char)byte;
      }
      text[16] = 0x80;
      Print_Str_d(y, -80, text); y-= 17;
      Intensity_3F();
      for (line = base; line != base+0x68; line += 8) {
        if (line == addr) Intensity_7F();
        printline();
        if (line == addr) Intensity_3F();
      }
//    }

  }
}

int main(void)
{
  init_hardware();
  addr = (long)0xc000;
  debugging = 1;
  for (;;) {
    Wait_Recal();
    poll_joystick();
    if (button1) {
      addr += 0x10; base += 0x10;
      while (button1) {
        Wait_Recal();
        poll_joystick();
        DEBUG();
      }
    } else if (button2) {
      addr -= 0x10; base -= 0x10;
      while (button2) {
        Wait_Recal();
        poll_joystick();
        DEBUG();
      }
    } else if (button3) {
      addr += 0x0800; base += 0x0800;
      while (button3) {
        Wait_Recal();
        poll_joystick();
        DEBUG();
      }
    } else if (button4) {
      addr -= 0x0800; base -= 0x0800;
      while (button4) {
        Wait_Recal();
        poll_joystick();
        DEBUG();
      }
    } else DEBUG();
  }
  // if return value is <= 0, then a warm reset will be performed,

  // otherwise a cold reset will be performed

  return 0;
}