#include <string.h>
#include <setjmp.h>
#define COND_BR_MASK 0xff00
#define UCOND_DBR_MASK 0xe000
#define UCOND_RBR_MASK 0xf0df
#define TRAPA_MASK 0xff00
#define COND_DISP 0x00ff
#define UCOND_DISP 0x0fff
#define UCOND_REG 0x0f00
#define BF_INSTR 0x8b00
#define BT_INSTR 0x8900
#define BRA_INSTR 0xa000
#define BSR_INSTR 0xb000
#define JMP_INSTR 0x402b
#define JSR_INSTR 0x400b
#define RTS_INSTR 0x000b
#define RTE_INSTR 0x002b
#define TRAPA_INSTR 0xc300
#define SSTEP_INSTR 0xc3ff
#define T_BIT_MASK 0x0001
#define BUFMAX 1024
#define NUMREGBYTES 112
typedef void (*Function) ();
static int hex (char);
static char *mem2hex (char *, char *, int);
static char *hex2mem (char *, char *, int);
static int hexToInt (char **, int *);
static unsigned char *getpacket (void);
static void putpacket (char *);
static void handle_buserror (void);
static int computeSignal (int exceptionVector);
static void handle_exception (int exceptionVector);
void init_serial();
void putDebugChar (char);
char getDebugChar (void);
void catch_exception_4 (void);
void catch_exception_6 (void);
void catch_exception_9 (void);
void catch_exception_10 (void);
void catch_exception_11 (void);
void catch_exception_32 (void);
void catch_exception_33 (void);
void catch_exception_255 (void);
#define catch_exception_random catch_exception_255
void breakpoint (void);
#define init_stack_size 8*1024
#define stub_stack_size 8*1024
int init_stack[init_stack_size] __attribute__ ((section ("stack"))) = {0};
int stub_stack[stub_stack_size] __attribute__ ((section ("stack"))) = {0};
void INIT ();
void BINIT ();
#define CPU_BUS_ERROR_VEC 9
#define DMA_BUS_ERROR_VEC 10
#define NMI_VEC 11
#define INVALID_INSN_VEC 4
#define INVALID_SLOT_VEC 6
#define TRAP_VEC 32
#define IO_VEC 33
#define USER_VEC 255
char in_nmi;
int dofault;
int *stub_sp;
int remote_debug;
jmp_buf remcomEnv;
enum regnames
{
R0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, R11, R12, R13, R14,
R15, PC, PR, GBR, VBR, MACH, MACL, SR,
TICKS, STALLS, CYCLES, INSTS, PLR
};
typedef struct
{
short *memAddr;
short oldInstr;
}
stepData;
int registers[NUMREGBYTES / 4];
stepData instrBuffer;
char stepped;
static const char hexchars[] = "0123456789abcdef";
static char remcomInBuffer[BUFMAX];
static char remcomOutBuffer[BUFMAX];
char highhex(int x)
{
return hexchars[(x >> 4) & 0xf];
}
char lowhex(int x)
{
return hexchars[x & 0xf];
}
#define BREAKPOINT() asm("trapa #0x20"::);
static int
hex (char ch)
{
if ((ch >= 'a') && (ch <= 'f'))
return (ch - 'a' + 10);
if ((ch >= '0') && (ch <= '9'))
return (ch - '0');
if ((ch >= 'A') && (ch <= 'F'))
return (ch - 'A' + 10);
return (-1);
}
static char *
mem2hex (char *mem, char *buf, int count)
{
int i;
int ch;
for (i = 0; i < count; i++)
{
ch = *mem++;
*buf++ = highhex (ch);
*buf++ = lowhex (ch);
}
*buf = 0;
return (buf);
}
static char *
hex2mem (char *buf, char *mem, int count)
{
int i;
unsigned char ch;
for (i = 0; i < count; i++)
{
ch = hex (*buf++) << 4;
ch = ch + hex (*buf++);
*mem++ = ch;
}
return (mem);
}
static int
hexToInt (char **ptr, int *intValue)
{
int numChars = 0;
int hexValue;
*intValue = 0;
while (**ptr)
{
hexValue = hex (**ptr);
if (hexValue >= 0)
{
*intValue = (*intValue << 4) | hexValue;
numChars++;
}
else
break;
(*ptr)++;
}
return (numChars);
}
char *
getpacket (void)
{
unsigned char *buffer = &remcomInBuffer[0];
unsigned char checksum;
unsigned char xmitcsum;
int count;
char ch;
while (1)
{
while ((ch = getDebugChar ()) != '$')
;
retry:
checksum = 0;
xmitcsum = -1;
count = 0;
while (count < BUFMAX)
{
ch = getDebugChar ();
if (ch == '$')
goto retry;
if (ch == '#')
break;
checksum = checksum + ch;
buffer[count] = ch;
count = count + 1;
}
buffer[count] = 0;
if (ch == '#')
{
ch = getDebugChar ();
xmitcsum = hex (ch) << 4;
ch = getDebugChar ();
xmitcsum += hex (ch);
if (checksum != xmitcsum)
{
putDebugChar ('-');
}
else
{
putDebugChar ('+');
if (buffer[2] == ':')
{
putDebugChar (buffer[0]);
putDebugChar (buffer[1]);
return &buffer[3];
}
return &buffer[0];
}
}
}
}
static void
putpacket (char *buffer)
{
int checksum;
int count;
do
{
char *src = buffer;
putDebugChar ('$');
checksum = 0;
while (*src)
{
int runlen;
for (runlen = 0; runlen < 100; runlen ++)
{
if (src[0] != src[runlen])
{
if (runlen > 3)
{
int encode;
putDebugChar (*src);
checksum += *src;
putDebugChar ('*');
checksum += '*';
checksum += (encode = runlen + ' ' - 4);
putDebugChar (encode);
src += runlen;
}
else
{
putDebugChar (*src);
checksum += *src;
src++;
}
break;
}
}
}
putDebugChar ('#');
putDebugChar (highhex(checksum));
putDebugChar (lowhex(checksum));
}
while (getDebugChar() != '+');
}
void
handle_buserror (void)
{
longjmp (remcomEnv, 1);
}
static int
computeSignal (int exceptionVector)
{
int sigval;
switch (exceptionVector)
{
case INVALID_INSN_VEC:
sigval = 4;
break;
case INVALID_SLOT_VEC:
sigval = 4;
break;
case CPU_BUS_ERROR_VEC:
sigval = 10;
break;
case DMA_BUS_ERROR_VEC:
sigval = 10;
break;
case NMI_VEC:
sigval = 2;
break;
case TRAP_VEC:
case USER_VEC:
sigval = 5;
break;
default:
sigval = 7;
break;
}
return (sigval);
}
void
doSStep (void)
{
short *instrMem;
int displacement;
int reg;
unsigned short opcode;
instrMem = (short *) registers[PC];
opcode = *instrMem;
stepped = 1;
if ((opcode & COND_BR_MASK) == BT_INSTR)
{
if (registers[SR] & T_BIT_MASK)
{
displacement = (opcode & COND_DISP) << 1;
if (displacement & 0x80)
displacement |= 0xffffff00;
instrMem = (short *) (registers[PC] + displacement + 4);
}
else
instrMem += 1;
}
else if ((opcode & COND_BR_MASK) == BF_INSTR)
{
if (registers[SR] & T_BIT_MASK)
instrMem += 1;
else
{
displacement = (opcode & COND_DISP) << 1;
if (displacement & 0x80)
displacement |= 0xffffff00;
instrMem = (short *) (registers[PC] + displacement + 4);
}
}
else if ((opcode & UCOND_DBR_MASK) == BRA_INSTR)
{
displacement = (opcode & UCOND_DISP) << 1;
if (displacement & 0x0800)
displacement |= 0xfffff000;
instrMem = (short *) (registers[PC] + displacement + 4);
}
else if ((opcode & UCOND_RBR_MASK) == JSR_INSTR)
{
reg = (char) ((opcode & UCOND_REG) >> 8);
instrMem = (short *) registers[reg];
}
else if (opcode == RTS_INSTR)
instrMem = (short *) registers[PR];
else if (opcode == RTE_INSTR)
instrMem = (short *) registers[15];
else if ((opcode & TRAPA_MASK) == TRAPA_INSTR)
instrMem = (short *) ((opcode & ~TRAPA_MASK) << 2);
else
instrMem += 1;
instrBuffer.memAddr = instrMem;
instrBuffer.oldInstr = *instrMem;
*instrMem = SSTEP_INSTR;
}
void
undoSStep (void)
{
if (stepped)
{ short *instrMem;
instrMem = instrBuffer.memAddr;
*instrMem = instrBuffer.oldInstr;
}
stepped = 0;
}
void
gdb_handle_exception (int exceptionVector)
{
int sigval, stepping;
int addr, length;
char *ptr;
sigval = computeSignal (exceptionVector);
remcomOutBuffer[0] = 'S';
remcomOutBuffer[1] = highhex(sigval);
remcomOutBuffer[2] = lowhex (sigval);
remcomOutBuffer[3] = 0;
putpacket (remcomOutBuffer);
if (exceptionVector == 0xff
|| exceptionVector == 0x20)
registers[PC] -= 2;
undoSStep ();
stepping = 0;
while (1)
{
remcomOutBuffer[0] = 0;
ptr = getpacket ();
switch (*ptr++)
{
case '?':
remcomOutBuffer[0] = 'S';
remcomOutBuffer[1] = highhex (sigval);
remcomOutBuffer[2] = lowhex (sigval);
remcomOutBuffer[3] = 0;
break;
case 'd':
remote_debug = !(remote_debug);
break;
case 'g':
mem2hex ((char *) registers, remcomOutBuffer, NUMREGBYTES);
break;
case 'G':
hex2mem (ptr, (char *) registers, NUMREGBYTES);
strcpy (remcomOutBuffer, "OK");
break;
case 'm':
if (setjmp (remcomEnv) == 0)
{
dofault = 0;
if (hexToInt (&ptr, &addr))
if (*(ptr++) == ',')
if (hexToInt (&ptr, &length))
{
ptr = 0;
mem2hex ((char *) addr, remcomOutBuffer, length);
}
if (ptr)
strcpy (remcomOutBuffer, "E01");
}
else
strcpy (remcomOutBuffer, "E03");
dofault = 1;
break;
case 'M':
if (setjmp (remcomEnv) == 0)
{
dofault = 0;
if (hexToInt (&ptr, &addr))
if (*(ptr++) == ',')
if (hexToInt (&ptr, &length))
if (*(ptr++) == ':')
{
hex2mem (ptr, (char *) addr, length);
ptr = 0;
strcpy (remcomOutBuffer, "OK");
}
if (ptr)
strcpy (remcomOutBuffer, "E02");
}
else
strcpy (remcomOutBuffer, "E03");
dofault = 1;
break;
case 's':
stepping = 1;
case 'c':
{
if (hexToInt (&ptr, &addr))
registers[PC] = addr;
if (stepping)
doSStep ();
}
return;
break;
case 'k':
break;
}
putpacket (remcomOutBuffer);
}
}
#define GDBCOOKIE 0x5ac
static int ingdbmode;
void handle_exception(int exceptionVector)
{
#ifdef MONITOR
if (ingdbmode != GDBCOOKIE)
monitor_handle_exception (exceptionVector);
else
#endif
gdb_handle_exception (exceptionVector);
}
void
gdb_mode (void)
{
ingdbmode = GDBCOOKIE;
breakpoint();
}
void
breakpoint (void)
{
BREAKPOINT ();
}
#if defined(__sh1__) || defined(__sh2__)
typedef struct
{
void (*func_cold) ();
int *stack_cold;
void (*func_warm) ();
int *stack_warm;
void (*(handler[256 - 4])) ();
}
vec_type;
const vec_type vectable =
{
&BINIT,
init_stack + init_stack_size,
&BINIT,
init_stack + init_stack_size,
{
&catch_exception_4,
&catch_exception_random,
&catch_exception_6,
&catch_exception_random,
&catch_exception_random,
&catch_exception_9,
&catch_exception_10,
&catch_exception_11,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_32,
&catch_exception_33,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_random,
&catch_exception_255}};
#define BCR (*(volatile short *)(0x05FFFFA0))
#define BAS (0x800)
#define WCR1 (*(volatile short *)(0x05ffffA2))
asm ("_BINIT: mov.l L1,r15");
asm ("bra _INIT");
asm ("nop");
asm ("L1: .long _init_stack + 8*1024*4");
void
INIT (void)
{
WCR1 = 0;
BCR = BAS;
init_serial();
#ifdef MONITOR
reset_hook ();
#endif
in_nmi = 0;
dofault = 1;
stepped = 0;
stub_sp = stub_stack + stub_stack_size;
breakpoint ();
while (1)
;
}
static void sr()
{
asm (".global _Reset
.global _WarmReset
_Reset:
_WarmReset:
mov.l L_sp,r15
bra _INIT
nop
.align 2
L_sp: .long _init_stack + 8000");
asm("saveRegisters:
mov.l @(L_reg, pc), r0
mov.l @r15+, r1 ! pop R0
mov.l r2, @(0x08, r0) ! save R2
mov.l r1, @r0 ! save R0
mov.l @r15+, r1 ! pop R1
mov.l r3, @(0x0c, r0) ! save R3
mov.l r1, @(0x04, r0) ! save R1
mov.l r4, @(0x10, r0) ! save R4
mov.l r5, @(0x14, r0) ! save R5
mov.l r6, @(0x18, r0) ! save R6
mov.l r7, @(0x1c, r0) ! save R7
mov.l r8, @(0x20, r0) ! save R8
mov.l r9, @(0x24, r0) ! save R9
mov.l r10, @(0x28, r0) ! save R10
mov.l r11, @(0x2c, r0) ! save R11
mov.l r12, @(0x30, r0) ! save R12
mov.l r13, @(0x34, r0) ! save R13
mov.l r14, @(0x38, r0) ! save R14
mov.l @r15+, r4 ! save arg to handleException
add #8, r15 ! hide PC/SR values on stack
mov.l r15, @(0x3c, r0) ! save R15
add #-8, r15 ! save still needs old SP value
add #92, r0 ! readjust register pointer
mov r15, r2
add #4, r2
mov.l @r2, r2 ! R2 has SR
mov.l @r15, r1 ! R1 has PC
mov.l r2, @-r0 ! save SR
sts.l macl, @-r0 ! save MACL
sts.l mach, @-r0 ! save MACH
stc.l vbr, @-r0 ! save VBR
stc.l gbr, @-r0 ! save GBR
sts.l pr, @-r0 ! save PR
mov.l @(L_stubstack, pc), r2
mov.l @(L_hdl_except, pc), r3
mov.l @r2, r15
jsr @r3
mov.l r1, @-r0 ! save PC
mov.l @(L_stubstack, pc), r0
mov.l @(L_reg, pc), r1
bra restoreRegisters
mov.l r15, @r0 ! save __stub_stack
.align 2
L_reg:
.long _registers
L_stubstack:
.long _stub_sp
L_hdl_except:
.long _handle_exception");
}
static void rr()
{
asm("
.align 2
.global _resume
_resume:
mov r4,r1
restoreRegisters:
add #8, r1 ! skip to R2
mov.l @r1+, r2 ! restore R2
mov.l @r1+, r3 ! restore R3
mov.l @r1+, r4 ! restore R4
mov.l @r1+, r5 ! restore R5
mov.l @r1+, r6 ! restore R6
mov.l @r1+, r7 ! restore R7
mov.l @r1+, r8 ! restore R8
mov.l @r1+, r9 ! restore R9
mov.l @r1+, r10 ! restore R10
mov.l @r1+, r11 ! restore R11
mov.l @r1+, r12 ! restore R12
mov.l @r1+, r13 ! restore R13
mov.l @r1+, r14 ! restore R14
mov.l @r1+, r15 ! restore programs stack
mov.l @r1+, r0
add #-8, r15 ! uncover PC/SR on stack
mov.l r0, @r15 ! restore PC onto stack
lds.l @r1+, pr ! restore PR
ldc.l @r1+, gbr ! restore GBR
ldc.l @r1+, vbr ! restore VBR
lds.l @r1+, mach ! restore MACH
lds.l @r1+, macl ! restore MACL
mov.l @r1, r0
add #-88, r1 ! readjust reg pointer to R1
mov.l r0, @(4, r15) ! restore SR onto stack+4
mov.l r2, @-r15
mov.l L_in_nmi, r0
mov #0, r2
mov.b r2, @r0
mov.l @r15+, r2
mov.l @r1+, r0 ! restore R0
rte
mov.l @r1, r1 ! restore R1
");
}
static __inline__ void code_for_catch_exception(int n)
{
asm(" .globl _catch_exception_%O0" : : "i" (n) );
asm(" _catch_exception_%O0:" :: "i" (n) );
asm(" add #-4, r15 ! reserve spot on stack ");
asm(" mov.l r1, @-r15 ! push R1 ");
if (n == NMI_VEC)
{
asm(" mov.l r0, @-r15 ! push R0");
asm(" mov.l L_in_nmi, r0");
asm(" tas.b @r0 ! Fend off against addtnl NMIs");
asm(" bt noNMI");
asm(" mov.l @r15+, r0");
asm(" mov.l @r15+, r1");
asm(" add #4, r15");
asm(" rte");
asm(" nop");
asm(".align 2");
asm("L_in_nmi: .long _in_nmi");
asm("noNMI:");
}
else
{
if (n == CPU_BUS_ERROR_VEC)
{
asm("mov.l L_dofault,r1");
asm("mov.l @r1,r1");
asm("tst r1,r1");
asm("bf faultaway");
asm("bsr _handle_buserror");
asm(".align 2");
asm("L_dofault: .long _dofault");
asm("faultaway:");
}
asm(" mov #15<<4, r1 ");
asm(" ldc r1, sr ! disable interrupts ");
asm(" mov.l r0, @-r15 ! push R0 ");
}
asm(" mov r15, r0 ");
asm(" add #8, r0 ");
asm(" mov %0,r1" :: "i" (n) );
asm(" extu.b r1,r1 ");
asm(" bra saveRegisters ! save register values ");
asm(" mov.l r1, @r0 ! save exception # ");
}
static void
exceptions (void)
{
code_for_catch_exception (CPU_BUS_ERROR_VEC);
code_for_catch_exception (DMA_BUS_ERROR_VEC);
code_for_catch_exception (INVALID_INSN_VEC);
code_for_catch_exception (INVALID_SLOT_VEC);
code_for_catch_exception (NMI_VEC);
code_for_catch_exception (TRAP_VEC);
code_for_catch_exception (USER_VEC);
code_for_catch_exception (IO_VEC);
}
#define SMR0 (*(volatile char *)(0x05FFFEC0))
#define BRR0 (*(volatile char *)(0x05FFFEC1))
#define SCR0 (*(volatile char *)(0x05FFFEC2))
#define TDR0 (*(volatile char *)(0x05FFFEC3))
#define SSR0 (*(volatile char *)(0x05FFFEC4))
#define RDR0 (*(volatile char *)(0x05FFFEC5))
#define SMR1 (*(volatile char *)(0x05FFFEC8))
#define BRR1 (*(volatile char *)(0x05FFFEC9))
#define SCR1 (*(volatile char *)(0x05FFFECA))
#define TDR1 (*(volatile char *)(0x05FFFECB))
#define SSR1 (*(volatile char *)(0x05FFFECC))
#define RDR1 (*(volatile char *)(0x05FFFECD))
#define SYNC_MODE 0x80
#define SEVEN_BIT_DATA 0x40
#define PARITY_ON 0x20
#define ODD_PARITY 0x10
#define STOP_BITS_2 0x08
#define ENABLE_MULTIP 0x04
#define PHI_64 0x03
#define PHI_16 0x02
#define PHI_4 0x01
#define SCI_TIE 0x80
#define SCI_RIE 0x40
#define SCI_TE 0x20
#define SCI_RE 0x10
#define SCI_MPIE 0x08
#define SCI_TEIE 0x04
#define SCI_CKE1 0x02
#define SCI_CKE0 0x01
#define SCI_TDRE 0x80
#define SCI_RDRF 0x40
#define SCI_ORER 0x20
#define SCI_FER 0x10
#define SCI_PER 0x08
#define SCI_TEND 0x04
#define SCI_MPB 0x02
#define SCI_MPBT 0x01
#define PBIOR (*(volatile char *)(0x05FFFFC6))
#define PB15IOR 0x8000
#define PB14IOR 0x4000
#define PB13IOR 0x2000
#define PB12IOR 0x1000
#define PB11IOR 0x0800
#define PB10IOR 0x0400
#define PB9IOR 0x0200
#define PB8IOR 0x0100
#define PB7IOR 0x0080
#define PB6IOR 0x0040
#define PB5IOR 0x0020
#define PB4IOR 0x0010
#define PB3IOR 0x0008
#define PB2IOR 0x0004
#define PB1IOR 0x0002
#define PB0IOR 0x0001
#define PBCR1 (*(volatile short *)(0x05FFFFCC))
#define PB15MD1 0x8000
#define PB15MD0 0x4000
#define PB14MD1 0x2000
#define PB14MD0 0x1000
#define PB13MD1 0x0800
#define PB13MD0 0x0400
#define PB12MD1 0x0200
#define PB12MD0 0x0100
#define PB11MD1 0x0080
#define PB11MD0 0x0040
#define PB10MD1 0x0020
#define PB10MD0 0x0010
#define PB9MD1 0x0008
#define PB9MD0 0x0004
#define PB8MD1 0x0002
#define PB8MD0 0x0001
#define PB15MD PB15MD1|PB14MD0
#define PB14MD PB14MD1|PB14MD0
#define PB13MD PB13MD1|PB13MD0
#define PB12MD PB12MD1|PB12MD0
#define PB11MD PB11MD1|PB11MD0
#define PB10MD PB10MD1|PB10MD0
#define PB9MD PB9MD1|PB9MD0
#define PB8MD PB8MD1|PB8MD0
#define PB_TXD1 PB11MD1
#define PB_RXD1 PB10MD1
#define PB_TXD0 PB9MD1
#define PB_RXD0 PB8MD1
#define PBCR2 0x05FFFFCE
#define PB7MD1 0x8000
#define PB7MD0 0x4000
#define PB6MD1 0x2000
#define PB6MD0 0x1000
#define PB5MD1 0x0800
#define PB5MD0 0x0400
#define PB4MD1 0x0200
#define PB4MD0 0x0100
#define PB3MD1 0x0080
#define PB3MD0 0x0040
#define PB2MD1 0x0020
#define PB2MD0 0x0010
#define PB1MD1 0x0008
#define PB1MD0 0x0004
#define PB0MD1 0x0002
#define PB0MD0 0x0001
#define PB7MD PB7MD1|PB7MD0
#define PB6MD PB6MD1|PB6MD0
#define PB5MD PB5MD1|PB5MD0
#define PB4MD PB4MD1|PB4MD0
#define PB3MD PB3MD1|PB3MD0
#define PB2MD PB2MD1|PB2MD0
#define PB1MD PB1MD1|PB1MD0
#define PB0MD PB0MD1|PB0MD0
#ifdef MHZ
#define BPS 32 * 9600 * MHZ / ( BAUD * 10)
#else
#define BPS 32
#endif
void handleError (char theSSR);
void
nop (void)
{
}
void
init_serial (void)
{
int i;
SCR1 &= ~(SCI_TE | SCI_RE);
SMR1 = 0;
BRR1 = BPS;
SCR1 &= ~(SCI_CKE1 | SCI_CKE0);
for (i = 0; i < 1000; i++)
nop ();
SCR1 |= SCI_RE | SCI_TE;
PBCR1 &= ~(PB_TXD1 | PB_RXD1);
PBCR1 |= PB_TXD1 | PB_RXD1;
}
int
getDebugCharReady (void)
{
char mySSR;
mySSR = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
if ( mySSR )
handleError ( mySSR );
return SSR1 & SCI_RDRF ;
}
char
getDebugChar (void)
{
char ch;
char mySSR;
while ( ! getDebugCharReady())
;
ch = RDR1;
SSR1 &= ~SCI_RDRF;
mySSR = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
if (mySSR)
handleError (mySSR);
return ch;
}
int
putDebugCharReady (void)
{
return (SSR1 & SCI_TDRE);
}
void
putDebugChar (char ch)
{
while (!putDebugCharReady())
;
TDR1 = ch;
SSR1 &= ~SCI_TDRE;
}
void
handleError (char theSSR)
{
SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
}
#endif