Rewrite for H8/300-H
This commit is contained in:
parent
357992027a
commit
7ecaa5af33
|
@ -29,12 +29,9 @@ ChangeLog
|
|||
Makefile.in
|
||||
configure.in
|
||||
h8300.mt
|
||||
writecode.c
|
||||
compile.c
|
||||
run.c
|
||||
p1.c
|
||||
p3.c
|
||||
perifs.c
|
||||
state.h
|
||||
inst.h
|
||||
|
||||
Things-to-lose:
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#define DEBUG
|
||||
|
||||
#define MPOWER 16
|
||||
#define MSIZE (1<<MPOWER)
|
||||
#define CSIZE 1000
|
||||
/* Local register names */
|
||||
typedef enum
|
||||
{
|
||||
R0, R1, R2, R3, R4, R5, R6, R7,
|
||||
R_ZERO,
|
||||
R_PC,
|
||||
R_CCR,
|
||||
R_HARD_0,
|
||||
R_LAST,
|
||||
} reg_type;
|
||||
|
||||
|
||||
/* Structure used to describe addressing */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int reg;
|
||||
int literal;
|
||||
} ea_type;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ea_type src;
|
||||
ea_type dst;
|
||||
int opcode;
|
||||
int next_pc;
|
||||
int oldpc;
|
||||
int cycles;
|
||||
#ifdef DEBUG
|
||||
struct h8_opcode *op;
|
||||
#endif
|
||||
}
|
||||
|
||||
decoded_inst;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int exception;
|
||||
unsigned int regs[9];
|
||||
int pc;
|
||||
int ccr;
|
||||
|
||||
|
||||
unsigned char *memory;
|
||||
unsigned short *cache_idx;
|
||||
int cache_top;
|
||||
int maximum;
|
||||
int csize;
|
||||
int mask;
|
||||
|
||||
decoded_inst *cache;
|
||||
int cycles;
|
||||
int insts;
|
||||
int ticks;
|
||||
int compiles;
|
||||
#ifdef ADEBUG
|
||||
int stats[O_LAST];
|
||||
#endif
|
||||
}
|
||||
|
||||
cpu_state_type;
|
246
sim/h8300/p1.c
246
sim/h8300/p1.c
|
@ -1,246 +0,0 @@
|
|||
/* Interpreter fragment for the Hitachi H8/300 architecture simulator.
|
||||
|
||||
Written by Steve Chamberlain of Cygnus Support.
|
||||
sac@cygnus.com
|
||||
|
||||
This file is part of H8/300 sim
|
||||
|
||||
|
||||
THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
|
||||
Cygnus offers the following for use in the public domain. Cygnus
|
||||
makes no warranty with regard to the software or it's performance
|
||||
and the user accepts the software "AS IS" with all faults.
|
||||
|
||||
CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
|
||||
THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#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;saved_state.ienable=x&0x80;
|
||||
#define GET_CCR() ((N << 3) | (Z<<2) | (V<<1) | C) | ((!saved_state.ienable)<<7)
|
||||
|
||||
|
||||
|
||||
static union
|
||||
{
|
||||
short int i;
|
||||
struct
|
||||
{
|
||||
char low;
|
||||
char high;
|
||||
}
|
||||
|
||||
u;
|
||||
}
|
||||
|
||||
littleendian;
|
||||
|
||||
static void
|
||||
meminit ()
|
||||
{
|
||||
if (saved_state.mem == 0)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
saved_state.mem = (unsigned short *)calloc (1024, 64);
|
||||
littleendian.i = 1;
|
||||
/* initialze the array of pointers to byte registers */
|
||||
for (tmp = 0; tmp < 8; tmp++)
|
||||
{
|
||||
if (littleendian.u.high)
|
||||
{
|
||||
saved_state.bregp[tmp] = (unsigned char *) (saved_state.reg + tmp);
|
||||
saved_state.bregp[tmp + 8] = saved_state.bregp[tmp] + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
saved_state.bregp[tmp + 8] = (unsigned char *) (saved_state.reg + tmp);
|
||||
saved_state.bregp[tmp] = saved_state.bregp[tmp + 8] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* we keep two 256 sized pointers to byte regs, one for when we
|
||||
want to look at the reg descibed by bits NNNNxxxx and one for
|
||||
when we want to look at xxxxNNNN */
|
||||
for (tmp = 0; tmp < 256; tmp++)
|
||||
{
|
||||
saved_state.bregp_NNNNxxxx[tmp] = saved_state.bregp[(tmp >> 4) & 0xf];
|
||||
saved_state.bregp_xxxxNNNN[tmp] = saved_state.bregp[tmp & 0xf];
|
||||
}
|
||||
/* We keep two 256 sized pointers to word regs, one for regs in
|
||||
xNNNxxxx and one for regs in xxxxxNNNN */
|
||||
for (tmp = 0; tmp < 256; tmp++)
|
||||
{
|
||||
saved_state.wregp_xNNNxxxx[tmp] = &saved_state.reg[(tmp >> 4) & 0x7];
|
||||
saved_state.wregp_xxxxxNNN[tmp] = &saved_state.reg[tmp & 0x7];
|
||||
}
|
||||
|
||||
saved_state.reg[HCHECK] = 10000000; /* don't check the hardware
|
||||
often */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
control_c (sig, code, scp, addr)
|
||||
int sig;
|
||||
int code;
|
||||
char *scp;
|
||||
char *addr;
|
||||
{
|
||||
saved_state.exception = SIGINT;
|
||||
}
|
||||
|
||||
void
|
||||
sim_store_register (reg, val)
|
||||
int reg;
|
||||
int val;
|
||||
{
|
||||
saved_state.reg[reg] = val;
|
||||
}
|
||||
|
||||
void
|
||||
sim_fetch_register (reg, buf)
|
||||
int reg;
|
||||
char *buf;
|
||||
{
|
||||
meminit();
|
||||
buf[0] = saved_state.reg[reg] >> 8;
|
||||
buf[1] = saved_state.reg[reg];
|
||||
}
|
||||
|
||||
void
|
||||
sim_write (to, from, len)
|
||||
int to;
|
||||
char *from;
|
||||
int len;
|
||||
{
|
||||
int i;
|
||||
meminit ();
|
||||
|
||||
for ( i = 0; i < len; i++)
|
||||
SET_BYTE_MEM(to + i, from[i]);
|
||||
}
|
||||
|
||||
void
|
||||
sim_read (from, to, len)
|
||||
int from;
|
||||
char *to;
|
||||
|
||||
int len;
|
||||
{
|
||||
int i;
|
||||
meminit ();
|
||||
for (i = 0; i < len; i++) {
|
||||
to[i] = BYTE_MEM(from + i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sim_stop_signal ()
|
||||
{
|
||||
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
|
||||
sim_resume (step, sig)
|
||||
int step;
|
||||
int sig;
|
||||
{
|
||||
int lval;
|
||||
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 short *npc;
|
||||
int rn;
|
||||
unsigned short int *reg;
|
||||
unsigned char **bregp;
|
||||
void (*prev) ();
|
||||
unsigned short *pc;
|
||||
|
||||
int srca;
|
||||
int srcb;
|
||||
int dst;
|
||||
int cycles ;
|
||||
|
||||
int n;
|
||||
int v;
|
||||
int z;
|
||||
int c;
|
||||
|
||||
|
||||
/* Set up pointers to areas */
|
||||
reg = saved_state.reg;
|
||||
bregp = saved_state.bregp;
|
||||
blow = saved_state.bregp_xxxxNNNN;
|
||||
bhigh = saved_state.bregp_NNNNxxxx;
|
||||
|
||||
wlow = saved_state.wregp_xxxxxNNN;
|
||||
whigh = saved_state.wregp_xNNNxxxx;
|
||||
|
||||
|
||||
prev = signal (SIGINT, control_c);
|
||||
meminit();
|
||||
LOAD_INTERPRETER_STATE();
|
||||
if (step)
|
||||
saved_state.exception = SIGTRAP;
|
||||
else
|
||||
{
|
||||
saved_state.exception = sig;
|
||||
}
|
||||
do
|
||||
{
|
||||
b1 = pc[0];
|
||||
b0 = b1>> 8;
|
||||
b1 &= 0xff;
|
||||
|
||||
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/* Interpreter fragment for the Hitachi H8/300 architecture simulator.
|
||||
|
||||
Written by Steve Chamberlain of Cygnus Support.
|
||||
sac@cygnus.com
|
||||
|
||||
This file is part of H8/300 sim
|
||||
|
||||
|
||||
THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
|
||||
Cygnus offers the following for use in the public domain. Cygnus
|
||||
makes no warranty with regard to the software or it's performance
|
||||
and the user accepts the software "AS IS" with all faults.
|
||||
|
||||
CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
|
||||
THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
*/
|
||||
|
||||
movflags8:
|
||||
n = dst & 0x80;
|
||||
z = !(dst & 0xff);
|
||||
v = 0;
|
||||
goto next;
|
||||
movflags16:
|
||||
n = dst & 0x8000;
|
||||
z = !(dst & 0xffff);
|
||||
v = 0;
|
||||
goto next;
|
||||
aluflags8:
|
||||
n = dst & 0x80;
|
||||
z = !(dst & 0xff);
|
||||
v = ((srca & 0x80) == (srcb & 0x80)) && ((srca & 0x80) != (dst & 0x80));
|
||||
c = dst & 0x100;
|
||||
goto next;
|
||||
aluflags16:
|
||||
n = dst & 0x8000;
|
||||
z = !(dst & 0xffff);
|
||||
v = ((srca & 0x8000) == (srcb & 0x8000)) && ((srca & 0x8000) != (dst & 0x8000));
|
||||
c = dst & 0x10000;
|
||||
goto next;
|
||||
setflags:;
|
||||
SET_CCR(tmp);
|
||||
goto next;
|
||||
logflags:
|
||||
shiftflags:
|
||||
v = 0;
|
||||
incflags:
|
||||
z = !(dst & 0xff);
|
||||
n = dst & 0x80;
|
||||
goto next;
|
||||
next: ;
|
||||
pc = npc;
|
||||
if (ni > checkfreq)
|
||||
{
|
||||
ni = 0;
|
||||
SAVE_INTERPRETER_STATE();
|
||||
perifs();
|
||||
LOAD_INTERPRETER_STATE();
|
||||
#ifdef __GO32__
|
||||
if (kbhit())
|
||||
saved_state.exception = SIGINT;
|
||||
#endif
|
||||
}
|
||||
ni++;
|
||||
} while (!saved_state.exception);
|
||||
|
||||
|
||||
SAVE_INTERPRETER_STATE();
|
||||
}
|
||||
|
||||
|
||||
sim_info()
|
||||
{
|
||||
int cycles = saved_state.reg[CYCLES];
|
||||
printf("cycles (v approximate) %10d\n", cycles);
|
||||
}
|
|
@ -35,6 +35,18 @@ main (ac, av)
|
|||
char *name = "";
|
||||
for (i = 1; i < ac; i++)
|
||||
{
|
||||
<<<<<<< run.c
|
||||
verbose ++;
|
||||
}
|
||||
else if (strcmp(av[i],"-t") == 0)
|
||||
{
|
||||
trace = 1;
|
||||
}
|
||||
else if (strcmp(av[i],"-c") == 0)
|
||||
{
|
||||
sim_csize(atoi(av[i+1]));
|
||||
i++;
|
||||
=======
|
||||
if (strcmp (av[i], "-v") == 0)
|
||||
{
|
||||
verbose = 1;
|
||||
|
@ -48,15 +60,55 @@ main (ac, av)
|
|||
{
|
||||
name = av[i];
|
||||
}
|
||||
>>>>>>> 1.4
|
||||
}
|
||||
<<<<<<< run.c
|
||||
else
|
||||
=======
|
||||
if (verbose)
|
||||
>>>>>>> 1.4
|
||||
{
|
||||
<<<<<<< run.c
|
||||
name = av[i];
|
||||
=======
|
||||
printf ("run %s\n", name);
|
||||
>>>>>>> 1.4
|
||||
}
|
||||
<<<<<<< run.c
|
||||
}
|
||||
if (verbose)
|
||||
{
|
||||
printf("run %s\n", name);
|
||||
}
|
||||
abfd = bfd_openr(name,"coff-h8300");
|
||||
=======
|
||||
abfd = bfd_openr (name, "coff-h8300");
|
||||
>>>>>>> 1.4
|
||||
|
||||
<<<<<<< run.c
|
||||
if (abfd)
|
||||
=======
|
||||
if (abfd)
|
||||
>>>>>>> 1.4
|
||||
{
|
||||
<<<<<<< run.c
|
||||
if (bfd_check_format(abfd, bfd_object))
|
||||
{
|
||||
|
||||
for (s = abfd->sections; s; s=s->next)
|
||||
{
|
||||
char *buffer = malloc(bfd_section_size(abfd,s));
|
||||
bfd_get_section_contents(abfd, s, buffer, 0, bfd_section_size(abfd,s));
|
||||
sim_write(s->vma, buffer, bfd_section_size(abfd,s));
|
||||
}
|
||||
|
||||
start_address = bfd_get_start_address(abfd);
|
||||
sim_store_register(
|
||||
9,start_address);
|
||||
sim_resume(0,0);
|
||||
if (verbose)
|
||||
sim_info (verbose);
|
||||
=======
|
||||
if (bfd_check_format (abfd, bfd_object))
|
||||
{
|
||||
|
||||
|
@ -73,9 +125,14 @@ main (ac, av)
|
|||
sim_resume (0, 0);
|
||||
if (verbose)
|
||||
sim_info ();
|
||||
>>>>>>> 1.4
|
||||
|
||||
<<<<<<< run.c
|
||||
return 0;
|
||||
=======
|
||||
return 0;
|
||||
}
|
||||
>>>>>>> 1.4
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
Written by Steve Chamberlain of Cygnus Support.
|
||||
sac@cygnus.com
|
||||
|
||||
This file is part of H8/300 sim
|
||||
|
||||
|
||||
THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
|
||||
Cygnus offers the following for use in the public domain. Cygnus
|
||||
makes no warranty with regard to the software or it's performance
|
||||
and the user accepts the software "AS IS" with all faults.
|
||||
|
||||
CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
|
||||
THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
*/
|
||||
#include "../endian.h"
|
||||
#define SET_WORD_MEM(x,y) {saved_state.mem[(x)>>1] = y;}
|
||||
#define SET_BYTE_MEM(x,y) {BYTE_MEM(x)=y;}
|
||||
|
||||
#define WORD_MEM(x) (saved_state.mem[(x)>>1])
|
||||
#define BYTE_MEM(x) (*(((char *)(saved_state.mem))+((x)^HOST_IS_LITTLE_ENDIAN)))
|
||||
|
||||
#define CCR 8
|
||||
#define PC 9
|
||||
#define CYCLES 10
|
||||
#define HCHECK 11
|
||||
#define TIER 12
|
||||
#define TCSR 13
|
||||
#define FRC 14
|
||||
#define OCRA 15
|
||||
#define OCRB 16
|
||||
#define TCR 17
|
||||
#define TOCR 18
|
||||
#define ICRA 19
|
||||
#define NREG 20
|
||||
struct state
|
||||
{
|
||||
unsigned short int reg[NREG];
|
||||
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]);
|
||||
int exception;
|
||||
int ienable;
|
||||
unsigned short *mem;
|
||||
}
|
||||
|
||||
saved_state;
|
||||
|
||||
|
||||
|
||||
#define OCFA (1<<3)
|
||||
#define OCFB (1<<2)
|
||||
#define CCLRA (1<<0)
|
||||
/* TCR bits */
|
||||
#define OCIEA (1<<3)
|
||||
#define OCIEB (1<<2)
|
||||
#define OVIE (1<<1)
|
||||
#define OVF (1<<1)
|
||||
|
||||
/* TOCR bits */
|
||||
#define OCRS (1<<4)
|
||||
|
||||
|
||||
#ifdef LITTLE_ENDIAN_HOST
|
||||
#define HOST_IS_LITTLE_ENDIAN 1
|
||||
#else
|
||||
#define HOST_IS_LITTLE_ENDIAN 0
|
||||
#endif
|
||||
|
||||
#define SAVE_INTERPRETER_STATE() \
|
||||
saved_state.reg[CYCLES] = cycles; \
|
||||
saved_state.reg[PC] = (pc - saved_state.mem) <<1; \
|
||||
saved_state.reg[CCR] = GET_CCR(); \
|
||||
store_timer_state_to_mem();
|
||||
|
||||
#define LOAD_INTERPRETER_STATE() \
|
||||
SET_CCR (saved_state.reg[CCR]); \
|
||||
checkfreq = saved_state.reg[HCHECK]; \
|
||||
pc = (saved_state.reg[PC]>>1) + saved_state.mem; \
|
||||
load_timer_state_from_mem(); \
|
||||
cycles=saved_state.reg[CYCLES];
|
Loading…
Reference in New Issue