/*  File XCInts.h  */

/* File XCP.c    */

#asm
	LOF LCG;		Turn off listing of printf.c 
#endasm
#include "printf.c"
#include "header.h"

#asm
	LON LG;		Turn it back on
#endasm

/* define PIO if using the Motorola PIO's */
#define PIO

/* define NMI if we want non-maskable interrupts */
/* #define NMI  */
/* define MODE1 if want mode-one interrupts */
/* #define MODE1 */
/* define  MODE2 if want mode two interrupts */
#define MODE2

#ifdef NMI 
#define INTLOC 0X0066
#endif
#ifdef MODE1
#define INTLOC 0X0038
#endif
#ifdef MODE2
#define INTLOC 0XC9FE
/*	AGETSADDR: A <-- 0C9.  The C9 must be the high-order byte of INTLOC. */
#define AGETSADDR DB 03EH,0C9H
/*	LD←I←A is   I reg <-- A reg. */
#define LD←I←A DB 0EDH,047H
#define IM2 DB 0EDH,05EH
#endif

#define TRUE 1
#define FALSE 0
#define call6502 0XFF58
#define IM1 DB 0EDH,056H
#define RETI DB 0EDH,04DH
#define EI DB 0FBH
#define JMP 0X0C3

/*	PIO card definitions		*/
/* HiEnable enables interrupts on positive transitions of that signal */
#ifdef PIO
#define HiEnable 0X03
#define LoEnable 0X01
#define IRQ1 0X80
#define PERREG 0X04	

static char *CReg1A = 0XE501;	/* Control Register PIO1, reg A */
static char *CReg1B = 0XE503;
static char *CReg2A = 0XE505;
static char *CReg2B = 0XE507;
static char *CReg3A = 0XE511;
static char *CReg3B = 0XE513;
static char *PDR1A = 0XE500;	/* Peripheral OR Data register */
static char *PDR1B = 0XE502;	/* Peripheral OR Data Register for B */
static char *PDR2A = 0XE504;
static char *PDR2B = 0XE506;
static char *PDR3A = 0XE510;
static char *PDR3B = 0XE512;




#endif

/*static char storejmp = JMP;	/* see if we can eliminate the indir here */
static char *jmpvector = INTLOC;
static unsigned *intvector = INTLOC+1;
static unsigned Aints;
static unsigned Bints;
static unsigned introutine;
static unsigned appleReturn;	/* when calling apple, store its ret PC here */
				/* Communication loc for 6502. */
static int *avecp = 0XF3D0;	/*  poke this loc with apple rom addr to call*/
static int *apStack = 0XF049;	/* 6502 stack pointer on exit from subr */

signon(){
        printf("\n\t Starting test.\n");
}	

startInterrupts(foo)
unsigned foo;
{
#ifdef PIO
/* Clear the PIO control registers */
	*CReg3B = *CReg3A = *CReg2B = *CReg2A = *CReg1B = *CReg1A = '\0';
/*  Not doing anything yet about setting the data directions of the reg's */
	*CReg1A = LoEnable;	/* enable interrupts for neg trans */
	*CReg1B = LoEnable;	/* this watches zero clock */
#endif
	*jmpvector = JMP;
	*intvector = foo;

#ifdef MODE2			/* tell Z80 which page to vector to */
#asm
	IM2
	PUSH PSW		/* gonna smash it */
	AGETSADDR		/* A <- high byte of int addr */
	LD←I←A			/* I <-- contents of A */
	POP PSW
	EI
#endasm
#endif

#ifdef MODE1
#asm/*	enable interrupts (mode 1) */
	IM1/*		mode 1	*/
	EI/*		enable interrupts */
#endasm
#endif
}
inthandle(){
	static char BData = '\0';
	static char AData = '\0';
	static char *zcpu = 0XF3DE;

#asm
	PUSH PSW
	PUSH B			/*Save all registers */
	PUSH H
	PUSH D
#endasm
/* Do the interrupt processing before re-enabling the 6502 */
	if (IRQ1 & *CReg1B)	/* get status of IRQB1: the zero clock */
	  { /* Read data register to clear the interrupt */
	   *CReg1B = PERREG;	/* Select the Peripheral Register */
	   BData = *PDR1B;	/* get the data.  Throw away for now */
	   *CReg1B = LoEnable;	/* Enable interrupts on B again */
	   ++Bints;
	  }
	else if(IRQ1 & *CReg1A)
	  {*CReg1A = PERREG;
	   AData = *PDR1A;
	   *CReg1A = LoEnable;
	   ++Aints;
	  }

	appleReturn = *apStack;	/*Get 6502's return PC (if it was in subrtn)*/
	*avecp = call6502;	/*Have 6502 call this routine when started */
				/* it will have the 6502 return from int. */
	*zcpu = '\0';		/*Send a 0 to softcard address (starts 6502) */
	*apStack = appleReturn;	/* restore the 6502's return PC */

#asm
	POP D
	POP H
	POP B
	POP PSW
	EI
#endasm
}


main() {
static char response = ' ';
	Aints = Bints = 0;

	signon();
	startInterrupts(inthandle);

	while (response != 'Q' && response != 'q')
	if (CtlCk())	{
			response = getchar();
			if (response =='Q' || response == 'q')
  				break;
			printf("\nChannel A Interrupts received: %d\n", Aints);
			printf("\nChannel B Interrupts received: %d\n", Bints);
			Bints = Aints = 0;
			}

}/*end of main */