#include "tv80_env.h"
|
#include "tv80_env.h"
|
|
|
/*
|
/*
|
* This test covers interrupt handling routines. The actual interrupt code
|
* This test covers interrupt handling routines. The actual interrupt code
|
* is in assembly, in bintr_crt0.asm.
|
* is in assembly, in bintr_crt0.asm.
|
*
|
*
|
* The test generates five interrupts, and clears the interrupt after
|
* The test generates five interrupts, and clears the interrupt after
|
* each one.
|
* each one.
|
*
|
*
|
* The isr routine uses the two writes to intr_cntdwn to first clear
|
* The isr routine uses the two writes to intr_cntdwn to first clear
|
* assertion of the current interrupt and then disable the countdown
|
* assertion of the current interrupt and then disable the countdown
|
* timer.
|
* timer.
|
*/
|
*/
|
|
|
unsigned char foo;
|
unsigned char foo;
|
volatile unsigned char test_pass;
|
volatile unsigned char test_pass;
|
static unsigned char triggers;
|
static unsigned char triggers;
|
int phase;
|
int phase;
|
|
int loop;
|
char done;
|
char done;
|
char nmi_trig;
|
char nmi_trig;
|
|
|
void nmi_isr (void)
|
void nmi_isr (void)
|
{
|
{
|
nmi_trig++;
|
nmi_trig++;
|
|
|
switch (phase) {
|
switch (phase) {
|
// nmi test
|
// nmi test
|
case 1 :
|
case 1 :
|
if (nmi_trig > 5) {
|
if (nmi_trig > 5) {
|
phase += 1;
|
phase += 1;
|
nmi_trig = 0;
|
nmi_trig = 0;
|
//intr_cntdwn = 255;
|
//intr_cntdwn = 255;
|
//intr_cntdwn = 0;
|
//intr_cntdwn = 0;
|
|
print ("Final interrupt\n");
|
intr_cntdwn = 32;
|
intr_cntdwn = 32;
|
nmi_cntdwn = 0;
|
nmi_cntdwn = 0;
|
} else
|
} else
|
nmi_cntdwn = 32;
|
nmi_cntdwn = 32;
|
break;
|
break;
|
|
|
// just trigger once, and disable interrupt
|
|
case 3 :
|
|
nmi_cntdwn = 0;
|
|
nmi_trig_opcode = 0; // pop AF opcode
|
|
break;
|
|
}
|
}
|
}
|
}
|
|
|
void isr (void)
|
void isr (void)
|
{
|
{
|
int i;
|
|
triggers++;
|
triggers++;
|
|
|
switch (phase) {
|
switch (phase) {
|
// int test
|
// int test
|
case 0 :
|
case 0 :
|
if (triggers > 5) {
|
if (triggers > 5) {
|
phase += 1;
|
phase += 1;
|
triggers = 0;
|
triggers = 0;
|
intr_cntdwn = 0;
|
intr_cntdwn = 0;
|
|
print ("Starting NMIs\n");
|
nmi_cntdwn = 64;
|
nmi_cntdwn = 64;
|
} else {
|
} else {
|
intr_cntdwn = 32;
|
intr_cntdwn = 32;
|
|
|
}
|
}
|
break;
|
break;
|
|
|
|
|
// int / nmi interaction
|
|
// in this phase set up interrupt call
|
|
// which will be interrupted by an nmi
|
|
case 2 :
|
case 2 :
|
phase += 1;
|
|
triggers = 0;
|
|
nmi_trig = 0;
|
|
intr_cntdwn = 20;
|
|
nmi_trig_opcode = 0xF1; // pop AF opcode
|
|
|
|
break;
|
|
|
|
// wait for a while while servicing interrupt
|
|
// nmi should interrupt us and increment nmi_trig
|
|
// if test pass is true when we are done then exit
|
|
case 3 :
|
|
intr_cntdwn = 0;
|
intr_cntdwn = 0;
|
if (nmi_trig == 1)
|
|
test_pass = 1;
|
test_pass = 1;
|
break;
|
break;
|
|
|
}
|
}
|
}
|
}
|
|
|
int main ()
|
int main ()
|
{
|
{
|
int i;
|
//int i;
|
unsigned char check;
|
unsigned char check;
|
|
|
test_pass = 0;
|
test_pass = 0;
|
triggers = 0;
|
triggers = 0;
|
nmi_trig = 0;
|
nmi_trig = 0;
|
|
|
phase = 0;
|
phase = 0;
|
|
|
// start interrupt countdown
|
// start interrupt countdown
|
|
print ("Starting interrupts\n");
|
intr_cntdwn = 64;
|
intr_cntdwn = 64;
|
set_timeout (50000);
|
set_timeout (50000);
|
|
|
for (i=0; i<1024; i++) {
|
for (loop=0; loop<1024; loop++) {
|
if (test_pass)
|
if (test_pass)
|
break;
|
break;
|
check = sim_ctl_port;
|
check = sim_ctl_port;
|
}
|
}
|
|
|
if (test_pass)
|
if (test_pass)
|
sim_ctl (SC_TEST_PASSED);
|
sim_ctl (SC_TEST_PASSED);
|
else
|
else
|
sim_ctl (SC_TEST_FAILED);
|
sim_ctl (SC_TEST_FAILED);
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|