# Target: H8300 with HMS monitor and H8 simulator
-TDEPFILES= exec.o h8300-tdep.o remote-hms.o remote-sim.o ../h8300sim/code.o
+TDEPFILES= exec.o h8300-tdep.o remote-hms.o remote-sim.o ../h8300sim/code.o ../h8300sim/perifs.o
TM_FILE= tm-h8300.h
get_reg_name (regno)
int regno;
{
- static char *rn[NUM_REGS] = REGISTER_NAMES;
+ static char *rn[] = REGISTER_NAMES;
return rn[regno];
}
}
}
+ expect("emory>");
hms_write_cr (" ");
expect_prompt ();
return len;
#define REGISTER_TYPE unsigned short
-# define NUM_REGS 10
-# define REGISTER_BYTES (10*2)
+# define NUM_REGS 10 /* 20 for fake HW support */
+# define REGISTER_BYTES (NUM_REGS*2)
/* Index within `registers' of the first byte of the space for
Entries beyond the first NUM_REGS are ignored. */
#define REGISTER_NAMES \
- {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp","ccr","pc"}
+ {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp",\
+ "ccr","pc","cycles","hcheck","tier","tcsr","frc","ocra","ocrb","tcr","tocr","icra"}
/* Register numbers of various important registers.
all: run
-run: code.o run.o
- $(CC) -o run code.o run.o ../bfd/libbfd.a ../libiberty/libiberty.a
+run: code.o run.o perifs.o
+ $(CC) -o run code.o perifs.o run.o ../bfd/libbfd.a ../libiberty/libiberty.a
code.c:p1.c p2.c p3.c
cat $(VPATH)/p1.c p2.c $(VPATH)/p3.c | cb >code.c
writecode:writecode.c
- $(CC_FOR_BUILD) -o writecode -g $(CSEARCH) $(srcdir)/writecode.c
+ $(CC) -o writecode -g $(CSEARCH) $(srcdir)/writecode.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
-
-#define SET_WORD_MEM(x,y) {mem[x] = (y)>>8;mem[x+1] = y;}
-#define SET_BYTE_MEM(x,y) mem[x]=y
-
-#define WORD_MEM(x) ((mem[x]<<8) | (mem[x+1]))
-#define BYTE_MEM(x) mem[x]
-
-
-#define PC 9
-#define CCR 8
-
-struct state
-{
- int cycles;
- unsigned short int reg[10];
- unsigned char *(bregp[16]);
- unsigned char *(bregp_NNNNxxxx[256]);
- unsigned char *(bregp_xxxxNNNN[256]);
- unsigned short int *(wregp_xNNNxxxx[256]);
- unsigned short int *(wregp_xxxxxNNN[256]);
-}
-
-saved_state;
+#include "state.h"
#define V (v!=0)
#define C (c!=0)
#define N (n!=0)
#define Z (z!=0)
-#define SET_CCR(x) n = x & 0x8; v = x & 0x2; z = x & 0x4; c = x & 0x1;
-#define GET_CCR() ((N << 3) | (Z<<2) | (V<<1) | C)
-
-int exception;
+#define SET_CCR(x) n = x & 0x8; v = x & 0x2; z = x & 0x4; c = x & 0x1;saved_state.ienable=x&0x80;
+#define GET_CCR() ((N << 3) | (Z<<2) | (V<<1) | C) | ((!saved_state.ienable)<<7)
-static unsigned char *mem;
static union
static void
meminit ()
{
- if (!mem)
+ if (!saved_state.mem)
{
int tmp;
- mem = calloc (1024, 64);
+ saved_state.mem = calloc (1024, 64);
littleendian.i = 1;
/* initialze the array of pointers to byte registers */
for (tmp = 0; tmp < 8; tmp++)
{
saved_state.bregp[tmp] = (unsigned char *) (saved_state.reg + tmp);
saved_state.bregp[tmp + 8] = saved_state.bregp[tmp] + 1;
+ if (HOST_IS_LITTLE_ENDIAN)
+ abort();
}
else
{
saved_state.bregp[tmp + 8] = (unsigned char *) (saved_state.reg + tmp);
saved_state.bregp[tmp] = saved_state.bregp[tmp + 8] + 1;
+ if (!HOST_IS_LITTLE_ENDIAN)
+ abort();
}
}
saved_state.wregp_xxxxxNNN[tmp] = &saved_state.reg[tmp & 0x7];
}
+ saved_state.reg[HCHECK] = 10000000; /* don't check the hardware
+ often */
}
+
}
char *scp;
char *addr;
{
- exception = SIGINT;
+ saved_state.exception = SIGINT;
}
void
char *from;
int len;
{
+ int i;
meminit ();
- memcpy (mem + to, from, len);
+
+ for ( i = 0; i < len; i++)
+ SET_BYTE_MEM(to + i, from[i]);
}
void
int len;
{
+ int i;
meminit ();
- memcpy (to, mem + from, len);
+ for (i = 0; i < len; i++) {
+ to[i] = BYTE_MEM(from + i);
+ }
}
int
sim_stop_signal ()
{
- return exception;
+ return saved_state.exception;
+}
+
+ void
+load_timer_state_from_mem()
+{
+
+ saved_state.reg[TIER] = BYTE_MEM(0xff90);
+ saved_state.reg[TCSR] = BYTE_MEM(0xff91);
+ saved_state.reg[FRC] = WORD_MEM(0xff92);
+ saved_state.reg[TCR] = BYTE_MEM(0xff96);
+ saved_state.reg[TOCR] = BYTE_MEM(0xff97);
+
+
+ if ((saved_state.reg[TOCR] & OCRS) == 0)
+ {
+ saved_state.reg[OCRA] = WORD_MEM(0xff94);
+ }
+ else
+ {
+ saved_state.reg[OCRB] = WORD_MEM(0xff94);
+ }
+}
+
+void
+store_timer_state_to_mem()
+{
+
+ BYTE_MEM(0xff91) = saved_state.reg[TCSR];
+ SET_WORD_MEM(0xff92, saved_state.reg[FRC]);
}
void
int tmp;
int b0;
int b1;
+ int checkfreq;
+ int ni; /* Number of insts to execute before checking hw state */
unsigned char **blow;
unsigned char **bhigh;
unsigned short **wlow;
unsigned short **whigh;
- unsigned char *npc;
+ unsigned short *npc;
int rn;
unsigned short int *reg;
unsigned char **bregp;
void (*prev) ();
- unsigned char *pc;
+ unsigned short *pc;
int srca;
int srcb;
int dst;
- int cycles = saved_state.cycles;
+ int cycles ;
int n;
int v;
int z;
int c;
- SET_CCR (saved_state.reg[CCR]);
- pc = saved_state.reg[PC] + mem;
+/* Set up pointers to areas */
reg = saved_state.reg;
bregp = saved_state.bregp;
blow = saved_state.bregp_xxxxNNNN;
wlow = saved_state.wregp_xxxxxNNN;
whigh = saved_state.wregp_xNNNxxxx;
+
prev = signal (SIGINT, control_c);
meminit();
+LOAD_INTERPRETER_STATE();
if (step)
- exception = SIGTRAP;
+ saved_state.exception = SIGTRAP;
else
{
- exception = sig;
+ saved_state.exception = sig;
}
do
{
- b0 = pc[0];
- b1 = pc[1];
+ b1 = pc[0];
+ b0 = b1>> 8;
+ b1 &= 0xff;
+
goto next;
setflags:;
SET_CCR(tmp);
-break;
+ goto next;
logflags:
shiftflags:
v = 0;
goto next;
next: ;
pc = npc;
+if (ni > checkfreq)
+{
+ ni = 0;
+ SAVE_INTERPRETER_STATE();
+ perifs();
+ LOAD_INTERPRETER_STATE();
#ifdef __GO32__
-if (kbhit())
- exception = SIGINT;
+ if (kbhit())
+ saved_state.exception = SIGINT;
#endif
-} while (!exception);
+}
+ni++;
+} while (!saved_state.exception);
+
-saved_state.cycles = cycles;
-saved_state.reg[PC] = pc - mem;
-saved_state.reg[CCR] = GET_CCR();
+SAVE_INTERPRETER_STATE();
}
--- /dev/null
+
+/* Fake peripherals for the H8/330 */
+#include "state.h"
+perifs( )
+/* This routine is called every few instructions to see if some sort
+ of hardware event is needed */
+{
+ int interrupt = 0;
+ int lval;
+ int tmp;
+ /* What to do about the 16 bit timer */
+
+
+ /* Free running counter same as reg a */
+ if (saved_state.reg[OCRA] == saved_state.reg[FRC])
+ {
+ /* Set the counter A overflow bit */
+ saved_state.reg[TCSR] |= OCFA;
+
+ if (saved_state.reg[TCSR] & CCLRA)
+ {
+ saved_state.reg[FRC] = 0;
+ }
+
+ if (saved_state.reg[TIER] & OCIEA)
+ {
+ interrupt = 16;
+ }
+ }
+
+ /* Free running counter same as reg b */
+ if (saved_state.reg[OCRB] == saved_state.reg[FRC])
+ {
+ saved_state.reg[TCSR] |= OCFB;
+ if (saved_state.reg[TIER] & OCIEB)
+ {
+ interrupt = 17;
+ }
+ }
+
+ /* inc free runnning counter */
+ saved_state.reg[FRC]++;
+
+ if (saved_state.reg[FRC] == 0)
+ {
+ /* Must have overflowed */
+ saved_state.reg[TCSR] |= OVF;
+ if (BYTE_MEM(TIER) & OVIE)
+ interrupt = 18;
+ }
+
+ /* If we've had an interrupt and the bit is on */
+ if (interrupt && saved_state.ienable)
+ {
+
+ int ccr;
+
+ saved_state.ienable = 0;
+ ccr = saved_state.reg[CCR];
+ lval = WORD_MEM((interrupt)<<1);
+ lval = WORD_MEM(lval);
+ {
+ /* Push PC */
+ saved_state.reg[7] -= 2;
+ tmp = saved_state.reg[7];
+ SET_WORD_MEM (tmp, saved_state.reg[PC]);
+ /* Push CCR twice */
+ saved_state.reg[7] -=2 ;
+ tmp = saved_state.reg[7];
+ SET_BYTE_MEM(tmp,ccr);
+ SET_BYTE_MEM(tmp+1,ccr);
+
+ /* Set pc to point to first instruction of i vector */
+ saved_state.reg[PC] = lval;
+ }
+ }
+
+}
"(b0&0xf)",
"((b1>>4)&0xf)",
"((b1)&0xf)",
- "((pc[2]>>4)&0xf)",
- "((pc[2])&0xf)",
- "((pc[3]>>4)&0xf)",
- "((pc[3])&0xf)",
+ "((pc[1]>>12)&0xf)",
+ "((pc[1]>>8)&0xf)",
+ "((pc[1]>>4)&0xf)",
+ "((pc[1])&0xf)",
0, 0};
/* how to get at the 3 bit immediate in the instruction */
char *imm3[] =
{"foo",
"foo",
- "((pc[1]>>4)&0x7)",
+ "((b1>>4)&0x7)",
"foo",
"foo",
"foo",
- "((pc[3]>>4)&0x7)"};
+ "(pc[1]>>4)&0x7"};
/* How to get at a byte register from an index in the instruction at
nibble n */
case MEMIND:
if (fetch)
{
- printf ("lval = ((pc[2]<<8)|pc[3]);\n");
+ printf ("lval = pc[1];\n");
}
break;
case RDDEC:
break;
case IMM16:
if (fetch)
- printf ("srca =( pc[2] << 8) | pc[3];\n");
+ printf ("srca =( pc[1]);\n");
break;
case ABS8SRC:
if (fetch)
case ABS16SRC:
if (fetch)
{
- printf ("lval = ((pc[2] << 8) + pc[3]);\n");
+ printf ("lval = pc[1];\n");
printf ("srca = %s_MEM(lval);\n", size == 8 ? "BYTE" : "WORD");
}
break;
case DISPSRC:
if (fetch)
{
- printf ("lval = 0xffff&((pc[2] << 8) + pc[3] +reg[rn]);\n");
+ printf ("lval = 0xffff&(pc[1] +reg[rn]);\n");
printf ("srca = %s_MEM(lval);\n", size == 8 ? "BYTE" : "WORD");
}
break;
case DISPDST:
if (fetch)
{
- printf ("lval = 0xffff&((pc[2] << 8) + pc[3] +reg[rn]);\n");
+ printf ("lval = 0xffff&(pc[1] +reg[rn]);\n");
printf ("srcb = %s_MEM(lval);\n", size == 8 ? "BYTE" : "WORD");
}
else
case ABS16DST:
if (fetch)
{
- printf ("lval = ((pc[2] << 8) + pc[3]);\n");
+ printf ("lval = (pc[1]);\n");
printf ("srcb = %s_MEM(lval);\n", ss);
}
else
default:
if (p->data.nib[i] > HexF)
{
- printf ("exception = SIGILL;\n");
+ printf ("saved_state.exception = SIGILL;\n");
}
}
}
static void
esleep ()
{
- printf ("exception = SIGSTOP;\n");
+ printf ("saved_state.exception = SIGSTOP;\n");
}
static void
struct h8_opcode *p;
char *a;
{
- printf ("if (%s) npc += (((char *)pc)[1]);\n", a);
+ printf ("if (%s) npc += ((char )b1)>>1;\n", a);
}
static void
{
printf ("reg[7]-=2;\n");
printf ("tmp = reg[7];\n");
- printf ("SET_WORD_MEM(tmp, npc-mem);\n");
- printf ("npc += (((char *)pc)[1]);\n");
+ printf ("SET_WORD_MEM(tmp, (npc-saved_state.mem)*2);\n");
+ printf ("npc += (((char *)pc)[1])>>1;\n");
}
static void
printf ("else {\n");
printf ("reg[7]-=2;\n");
printf ("tmp = reg[7];\n");
- printf ("SET_WORD_MEM(tmp, npc-mem);\n");
- printf ("npc = lval + mem;\n");
+ printf ("SET_WORD_MEM(tmp, (npc-saved_state.mem)*2);\n");
+ printf ("npc = (lval>>1) + saved_state.mem;\n");
printf ("}");
}
char *a;
int s;
{
- printf ("npc = lval + mem;\n");
+ printf ("npc = (lval>>1) + saved_state.mem;\n");
}
static void
{
printf ("tmp = reg[7];\n");
printf ("reg[7]+=2;\n");
- printf ("npc = mem + WORD_MEM(tmp);\n");
+ printf ("npc = saved_state.mem + (WORD_MEM(tmp)>>1);\n");
+}
+
+static void
+rte (p, a, s)
+ struct h8_opcode *p;
+ char *a;
+ int s;
+{
+ printf ("reg[7]+=2;\n");
+ printf ("tmp = reg[7];\n");
+ printf ("reg[7]+=2;\n");
+ printf ("SET_CCR(tmp);\n");
+ printf("npc = saved_state.mem + (WORD_MEM(tmp)>>1);\n");
}
static void
char *a;
int s;
{
- printf ("exception = SIGTRAP;\n");
+ printf ("saved_state.exception = SIGTRAP;\n");
printf ("npc = pc;\n");
}
{ nx, 1, "jsr", jsr, 0, 0 } ,
{ nx, 1, "jmp", jmp, 0, 0 } ,
{ nx, 0, "rts", rts, 0, 0 } ,
+ { nx, 0, "rte", rte, 0, 0 } ,
{ nx, 1, "andc", andc, 0, 0 } ,
{ sf, 1, "shal", shal, 0, 0 } ,
{ sf, 1, "shar", shar, 0, 0 } ,
if (table[i].decode)
decode (p, 1, table[i].size);
printf ("cycles += %d;\n", p->time);
- printf ("npc = pc + %d;\n", p->length);
+ printf ("npc = pc + %d;\n", p->length/2);
table[i].func (p, table[i].arg, table[i].size);
if (table[i].decode)
decode (p, 0, table[i].size);
}
}
printf ("%s not found %s\n", cs, ce);
- printf ("exception = SIGILL;\n");
+ printf ("saved_state.exception = SIGILL;\n");
printf ("break;\n");
}
{
if (mask0[c] | mask1[c])
{
+ int sh;
if (needand)
printf ("\n&&");
- printf ("((pc[%d]&0x%02x)==0x%x)",
- c, mask0[c] | mask1[c], mask1[c]);
+ if (c & 1) sh = 0;else sh = 8;
+ if (c/2 == 0 && sh == 0)
+ printf("((b1&0x%x)==0x%x)", mask0[c]| mask1[c],
+ mask1[c]);
+ else {
+ printf ("((pc[%d]&(0x%02x<<%d))==(0x%x<<%d))",
+ c/2, mask0[c] | mask1[c],sh,
+ mask1[c],sh);
+ }
+
needand = 1;
}
}