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