/* 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 */