Line 31... |
Line 31... |
//
|
//
|
//
|
//
|
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
//
|
//
|
|
#include "zipcpu.h"
|
#include "zipsys.h"
|
#include "zipsys.h"
|
#include "artyboard.h"
|
#include "artyboard.h"
|
|
|
#ifndef NULL
|
#ifndef NULL
|
#define NULL (void *)0
|
#define NULL (void *)0
|
#endif
|
#endif
|
|
|
static volatile int *const UARTTX = &((IOSPACE *)0x0100)->io_uart_tx,
|
static volatile int *const UARTTX = &((IOSPACE *)0x0100)->io_uart_tx,
|
*const UART_CTRL = &((IOSPACE *)0x0100)->io_auxsetup;
|
*const UART_CTRL = &((IOSPACE *)0x0100)->io_auxsetup;
|
static volatile int * const PIC = (volatile int *)0xc0000000;
|
static volatile int * const PIC = (volatile int *)0xff000000;
|
static const int INT_UARTTX = SYSINT_UARTTX; // 0x2000;
|
static const int INT_UARTTX = SYSINT_UARTTX; // 0x2000;
|
static volatile int *const COUNTER = &((ZIPSYS *)ZIPSYS_ADDR)->m.ck;
|
static volatile int *const COUNTER = &((ZIPSYS *)ZIPSYS_ADDR)->z_m.ac_ck;
|
|
|
#define HAVE_COUNTER
|
#define HAVE_COUNTER
|
#define HAVE_SCOPE
|
#define HAVE_SCOPE
|
#define SCOPEc sys->io_scope[0].s_ctrl
|
#define SCOPEc sys->io_scope[0].s_ctrl
|
#define SCOPE_DELAY 4
|
#define SCOPE_DELAY 4
|
#define TRIGGER_SCOPE_NOW (SCOPE_TRIGGER|SCOPE_DELAY)
|
#define TRIGGER_SCOPE_NOW (SCOPE_TRIGGER|SCOPE_DELAY)
|
#define PREPARE_SCOPE SCOPE_DELAY
|
#define PREPARE_SCOPE SCOPE_DELAY
|
|
|
unsigned zip_ucc(void);
|
unsigned zip_ucc(void);
|
|
unsigned zip_cc(void);
|
void zip_save_context(int *);
|
void zip_save_context(int *);
|
void zip_halt(void);
|
void zip_halt(void);
|
|
|
|
|
void txchr(char v);
|
void txchr(char v);
|
Line 117... |
Line 119... |
"\tMOV\tR3,uR6\n"
|
"\tMOV\tR3,uR6\n"
|
"\tMOV\tR3,uR7\n"
|
"\tMOV\tR3,uR7\n"
|
"\tMOV\tR3,uR8\n"
|
"\tMOV\tR3,uR8\n"
|
"\tMOV\tR3,uR9\n"
|
"\tMOV\tR3,uR9\n"
|
"\tMOV\tR3,uR10\n"
|
"\tMOV\tR3,uR10\n"
|
"\tMOV\tR3,uR11\n" // uR11 = pc
|
"\tMOV\tR3,uR11\n"
|
"\tMOV\tR3,uR12\n" // uR12 = pc
|
"\tMOV\tR3,uR12\n"
|
"\tMOV\tR2,uSP\n" // uSP = stack
|
"\tMOV\tR2,uSP\n" // uSP = stack
|
"\tMOV\t0x20+R3,uCC\n" // Clear uCC of all but the GIE bit
|
"\tMOV\t0x20+R3,uCC\n" // Clear uCC of all but the GIE bit
|
"\tMOV\tR1,uPC\n" // uPC = pc
|
"\tMOV\tR1,uPC\n" // uPC = pc
|
"\tRTU\n"
|
"\tRTU\n"
|
"test_return:\n"
|
"test_return:\n"
|
Line 178... |
Line 180... |
"break_two:\n"
|
"break_two:\n"
|
"\tLDI\t0,R1\n"
|
"\tLDI\t0,R1\n"
|
"\tJMP\tR0\n"
|
"\tJMP\tR0\n"
|
"\tBREAK\n");
|
"\tBREAK\n");
|
|
|
|
void break_three(void);
|
|
// Can we jump to a break, and still have the uPC match
|
|
asm("\t.text\n\t.global\tbreak_three\n"
|
|
"\t.type\tbreak_three,@function\n"
|
|
// R1 = 0 by default from calling. This will return as though
|
|
// we had succeeded.
|
|
"break_three:\n"
|
|
"\tBREAK\n");
|
|
|
void early_branch_test(void);
|
void early_branch_test(void);
|
asm("\t.text\n\t.global\tearly_branch_test\n"
|
asm("\t.text\n\t.global\tearly_branch_test\n"
|
"\t.type\tearly_branch_test,@function\n"
|
"\t.type\tearly_branch_test,@function\n"
|
"early_branch_test:\n"
|
"early_branch_test:\n"
|
"\tLDI\t1,R1\n"
|
"\tLDI\t1,R1\n"
|
Line 1135... |
Line 1146... |
txreg("uSP : ", context[13]);
|
txreg("uSP : ", context[13]);
|
txreg("uCC : ", context[14]);
|
txreg("uCC : ", context[14]);
|
txreg("uPC : ", context[15]);
|
txreg("uPC : ", context[15]);
|
txstr("\r\n\r\n");
|
txstr("\r\n\r\n");
|
|
|
|
// While previous versions of cputest.c called zip_busy(), here we
|
|
// reject that notion for the simple reason that zip_busy may not
|
|
// necessarily halt any Verilator simulation. Instead, we try to
|
|
// halt the CPU.
|
while(1)
|
while(1)
|
zip_halt();
|
zip_halt();
|
}
|
}
|
|
|
void testid(const char *str) {
|
void testid(const char *str) {
|
Line 1201... |
Line 1216... |
testid("Break test #2"); MARKSTART;
|
testid("Break test #2"); MARKSTART;
|
if ((run_test(break_two, user_stack_ptr))||(zip_ucc()&0x1d90))
|
if ((run_test(break_two, user_stack_ptr))||(zip_ucc()&0x1d90))
|
test_fails(start_time, &testlist[tnum]);
|
test_fails(start_time, &testlist[tnum]);
|
txstr("Pass\r\n"); testlist[tnum++] = 0; // #1
|
txstr("Pass\r\n"); testlist[tnum++] = 0; // #1
|
|
|
|
// Test break instruction in user mode
|
|
// Make sure that a decision on the clock prior won't still cause a
|
|
// break condition
|
|
testid("Break test #3"); MARKSTART;
|
|
run_test(break_three, user_stack_ptr);
|
|
if ((context[15] != (int)break_three) // Insist we stop at the break
|
|
||(0==(zip_ucc()&0x80)) // insn, that the break flag is
|
|
||(zip_ucc()&0x01d10)) // set, and no other excpt flags
|
|
test_fails(start_time, &testlist[tnum]);
|
|
txstr("Pass\r\n"); testlist[tnum++] = 0; // 0
|
|
|
// LJMP test ... not (yet) written
|
// LJMP test ... not (yet) written
|
|
|
// Test the early branching capability
|
// Test the early branching capability
|
// Does it successfully clear whatever else is in the pipeline?
|
// Does it successfully clear whatever else is in the pipeline?
|
testid("Early Branch test"); MARKSTART;
|
testid("Early Branch test"); MARKSTART;
|