diff options
-rw-r--r-- | gdb/config/h8300hms.mt | 2 | ||||
-rw-r--r-- | gdb/remote-hms.c | 3 | ||||
-rw-r--r-- | gdb/tm-h8300.h | 7 | ||||
-rw-r--r-- | sim/h8300/Makefile.in | 6 | ||||
-rw-r--r-- | sim/h8300/p1.c | 108 | ||||
-rw-r--r-- | sim/h8300/p3.c | 21 | ||||
-rw-r--r-- | sim/h8300/perifs.c | 78 | ||||
-rw-r--r-- | sim/h8300/writecode.c | 75 |
8 files changed, 216 insertions, 84 deletions
diff --git a/gdb/config/h8300hms.mt b/gdb/config/h8300hms.mt index 01ada98..71213ea 100644 --- a/gdb/config/h8300hms.mt +++ b/gdb/config/h8300hms.mt @@ -1,3 +1,3 @@ # 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 diff --git a/gdb/remote-hms.c b/gdb/remote-hms.c index 0cb42f6..9e6ef54 100644 --- a/gdb/remote-hms.c +++ b/gdb/remote-hms.c @@ -793,7 +793,7 @@ static char * get_reg_name (regno) int regno; { - static char *rn[NUM_REGS] = REGISTER_NAMES; + static char *rn[] = REGISTER_NAMES; return rn[regno]; } @@ -1217,6 +1217,7 @@ hms_read_inferior_memory (memaddr, myaddr, len) } } + expect("emory>"); hms_write_cr (" "); expect_prompt (); return len; diff --git a/gdb/tm-h8300.h b/gdb/tm-h8300.h index 5678c4a..ba1e883 100644 --- a/gdb/tm-h8300.h +++ b/gdb/tm-h8300.h @@ -102,8 +102,8 @@ UNSIGNED_SHORT(read_memory_integer (read_register (SP_REGNUM), 2)) #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 @@ -154,7 +154,8 @@ UNSIGNED_SHORT(read_memory_integer (read_register (SP_REGNUM), 2)) 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. diff --git a/sim/h8300/Makefile.in b/sim/h8300/Makefile.in index 4a5f7af..281ca99 100644 --- a/sim/h8300/Makefile.in +++ b/sim/h8300/Makefile.in @@ -61,8 +61,8 @@ DEP = mkdep 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 @@ -73,7 +73,7 @@ p2.c:writecode writecode:writecode.c - $(CC_FOR_BUILD) -o writecode -g $(CSEARCH) $(srcdir)/writecode.c + $(CC) -o writecode -g $(CSEARCH) $(srcdir)/writecode.c diff --git a/sim/h8300/p1.c b/sim/h8300/p1.c index 9c9d16c..4297e7b 100644 --- a/sim/h8300/p1.c +++ b/sim/h8300/p1.c @@ -22,41 +22,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #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 @@ -76,11 +51,11 @@ littleendian; 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++) @@ -89,11 +64,15 @@ meminit () { 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(); } } @@ -113,7 +92,10 @@ meminit () saved_state.wregp_xxxxxNNN[tmp] = &saved_state.reg[tmp & 0x7]; } + saved_state.reg[HCHECK] = 10000000; /* don't check the hardware + often */ } + } @@ -124,7 +106,7 @@ control_c (sig, code, scp, addr) char *scp; char *addr; { - exception = SIGINT; + saved_state.exception = SIGINT; } void @@ -151,8 +133,11 @@ sim_write (to, from, len) 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 @@ -162,14 +147,46 @@ sim_read (from, to, len) 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 @@ -181,30 +198,31 @@ int sig; 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; @@ -213,17 +231,21 @@ int sig; 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; + diff --git a/sim/h8300/p3.c b/sim/h8300/p3.c index 0eb5543..d0fa908 100644 --- a/sim/h8300/p3.c +++ b/sim/h8300/p3.c @@ -22,7 +22,7 @@ goto next; goto next; setflags:; SET_CCR(tmp); -break; + goto next; logflags: shiftflags: v = 0; @@ -32,13 +32,20 @@ break; 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(); } diff --git a/sim/h8300/perifs.c b/sim/h8300/perifs.c new file mode 100644 index 0000000..7380464 --- /dev/null +++ b/sim/h8300/perifs.c @@ -0,0 +1,78 @@ + +/* 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; + } + } + +} diff --git a/sim/h8300/writecode.c b/sim/h8300/writecode.c index 0f8408a..45570dc 100644 --- a/sim/h8300/writecode.c +++ b/sim/h8300/writecode.c @@ -44,21 +44,21 @@ char *nibs[] = "(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 */ @@ -225,7 +225,7 @@ decode (p, fetch, size) case MEMIND: if (fetch) { - printf ("lval = ((pc[2]<<8)|pc[3]);\n"); + printf ("lval = pc[1];\n"); } break; case RDDEC: @@ -246,7 +246,7 @@ decode (p, fetch, size) break; case IMM16: if (fetch) - printf ("srca =( pc[2] << 8) | pc[3];\n"); + printf ("srca =( pc[1]);\n"); break; case ABS8SRC: if (fetch) @@ -276,7 +276,7 @@ decode (p, fetch, size) 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; @@ -288,14 +288,14 @@ decode (p, fetch, size) 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 @@ -306,7 +306,7 @@ decode (p, fetch, size) 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 @@ -322,7 +322,7 @@ decode (p, fetch, size) default: if (p->data.nib[i] > HexF) { - printf ("exception = SIGILL;\n"); + printf ("saved_state.exception = SIGILL;\n"); } } } @@ -332,7 +332,7 @@ decode (p, fetch, size) static void esleep () { - printf ("exception = SIGSTOP;\n"); + printf ("saved_state.exception = SIGSTOP;\n"); } static void @@ -387,7 +387,7 @@ bra (p, a) 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 @@ -397,8 +397,8 @@ bsr (p, a) { 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 @@ -425,8 +425,8 @@ jsr (p, a, s) 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 ("}"); } @@ -436,7 +436,7 @@ jmp (p, a, s) char *a; int s; { - printf ("npc = lval + mem;\n"); + printf ("npc = (lval>>1) + saved_state.mem;\n"); } static void @@ -447,7 +447,20 @@ rts (p, a, s) { 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 @@ -466,7 +479,7 @@ bpt (p, a, s) char *a; int s; { - printf ("exception = SIGTRAP;\n"); + printf ("saved_state.exception = SIGTRAP;\n"); printf ("npc = pc;\n"); } @@ -675,6 +688,7 @@ table [] = { 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 } , @@ -727,7 +741,7 @@ edo (p) 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); @@ -740,7 +754,7 @@ edo (p) } } printf ("%s not found %s\n", cs, ce); - printf ("exception = SIGILL;\n"); + printf ("saved_state.exception = SIGILL;\n"); printf ("break;\n"); } @@ -834,10 +848,19 @@ owrite (i) { 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; } } |