#include "pokey.h"
#include "a6502.h"
//#include "gita.h"
//#include "antic.h"
#include <conio.h>
#include <stdlib.h>
#include <string.h>

#define LB	0x1f

extern m6502 cpu;
//extern ANTIC pf;
//extern GITA pm;
extern POKEY snd;
//extern PIA ext;


POKEY::POKEY(void)
{

   caudf1 = caudf2 = caudf3 = caudf4 = 0;
   ktog = 0;
   tog1 = tog2 = tog3 = tog4 = 0;
   randomize();
   cpu.ram[IRQST] = 0xff;
   cpu.ram[SKSTAT] = 0xff;
}

void POKEY::key_setup(void)
{
   Word atox(char *);
   char str[3], str2[5] = "0x  ";
   //read in keyboard translation file
   FILE *fin;
   fin = fopen("keytrans.dat", "rb");
   if (fin == NULL) {puts("need keytrans.dat file"); exit(1);}
   //read only the first number on each line
   for (int i=0;i<256;i++)
   {
      fscanf(fin, "%2s", str);
      strcpy(&str2[2],str);
      ktab[i] = atox(str2);
   }
}
void POKEY::update(Word addr, Byte data)
{
   ram[addr&LB] = data;

   //reset all timers
   if (addr == STIMER)
   {
      caudf1 = ram[AUDF1&LB];
      caudf2 = ram[AUDF2&LB];
      caudf3 = ram[AUDF3&LB];
      caudf4 = ram[AUDF4&LB];
   }
   if (addr==IRQEN) cpu.ram[IRQEN] |= ~data;
   if (addr==SKRES) cpu.ram[SKSTAT] |= 0x70;
}

//******************keyboard()*****************************************
//*                                                                   *
//*   This routine checks if a key was pressed and calls              *
//*   the atrai interupt routine in needed.                           *
//*   This routine is called every horizontal sync                    *
//*********************************************************************
void POKEY::keyboard(void)
{
   Byte tch;
   if (kbhit()==0)
   {
      if (ktog) cpu.ram[SKSTAT] &= ~b2;
      else cpu.ram[SKSTAT] |= b2;
      ktog = 0;
      return;  //return if no keystroke available
   }
   ktog = 1;
   if ((ram[IRQEN&LB]&b6)==0) return; //return if no int enabled
   Byte ch = getch();

   cpu.ram[CONSOL] &= 0x07;
   switch (ch)
   {
//   case 0x3b:  nmiflag = 1; cpu.ram[NMIST] |= b5; break;
     case 0x3b: cpu.print_reg(); cpu.print_opcode(); exit(0);
     case 0x3c:  cpu.ram[CONSOL] &= ~b2; return;
     case 0x3d:  cpu.ram[CONSOL] &= ~b1; return;
     case 0x3e:  cpu.ram[CONSOL] &= ~b0; return;
     default:;
   }

   tch = ktab[ch];
   cpu.ram[KBCODE] = tch;

   if (tch&b6) cpu.ram[SKSTAT] &= ~b3;
   else cpu.ram[SKSTAT] |= b3;

   cpu.ram[IRQST] = (ch == 0x03)?(~b7):(~b6);
   cpu.interrupt_();
}

void POKEY::timers(void)
{
   //If time delay interrupts are enabled, the timer automatically
   // times out.
   Byte irq = ram[IRQEN&LB]&0x07;
   if (irq)
   {
      cpu.ram[IRQST] &= (~irq);
      cpu.interrupt_();
   }

   if (ram[AUDC1&LB]&0x7) {--caudf1; tog1 = (tog1==0);}
   else tog1 = 0;
   if (ram[AUDC2&LB]&0x7) {--caudf2; tog2 = (tog2==0);}
   else tog2 = 0;
   if (ram[AUDC3&LB]&0x7) {--caudf3; tog3 = (tog3==0);}
   else tog3 = 0;
   if (ram[AUDC4&LB]&0x7) {--caudf4; tog4 = (tog4==0);}
   else tog4 = 0;

   //put sound out speaker (64k clocks only)
   outportb(97,inportb(97)&0xfc + 2*(tog1|tog2|tog3|tog4));
   cpu.ram[RANDOM] = Byte(rand());
}
