| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743 | diff -Nur binutils-gdb.orig/gdb/h8300-tdep.c binutils-gdb/gdb/h8300-tdep.c--- binutils-gdb.orig/gdb/h8300-tdep.c	2015-11-16 11:55:54.522178529 +0100+++ binutils-gdb/gdb/h8300-tdep.c	2015-11-16 11:52:52.474025949 +0100@@ -1248,8 +1248,8 @@ h8300_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, 			  int *lenptr) {-  /*static unsigned char breakpoint[] = { 0x7A, 0xFF }; *//* ??? */-  static unsigned char breakpoint[] = { 0x01, 0x80 };	/* Sleep */+  static unsigned char breakpoint[] = { 0x7A, 0xFF };   /* ??? */+  /*static unsigned char breakpoint[] = { 0x01, 0x80 };*/	/* Sleep */    *lenptr = sizeof (breakpoint);   return breakpoint;diff -Nur binutils-gdb.orig/sim/h8300/Makefile.in binutils-gdb/sim/h8300/Makefile.in--- binutils-gdb.orig/sim/h8300/Makefile.in	2015-11-16 11:55:55.634179462 +0100+++ binutils-gdb/sim/h8300/Makefile.in	2015-11-16 11:53:33.474060312 +0100@@ -17,7 +17,7 @@  ## COMMON_PRE_CONFIG_FRAG -SIM_OBJS = compile.o \+SIM_OBJS = compile.o io.o \ 	$(SIM_NEW_COMMON_OBJS)  ## COMMON_POST_CONFIG_FRAG@@ -27,3 +27,5 @@ 	   $(srcdir)/../../include/opcode/h8300.h \ 	   $(srcdir)/../../include/gdb/remote-sim.h \ 	   $(srcdir)/../../include/gdb/callback.h++io.o: io.c sim-main.hdiff -Nur binutils-gdb.orig/sim/h8300/compile.c binutils-gdb/sim/h8300/compile.c--- binutils-gdb.orig/sim/h8300/compile.c	2015-11-16 11:55:55.634179462 +0100+++ binutils-gdb/sim/h8300/compile.c	2015-11-16 11:52:52.502025971 +0100@@ -41,11 +41,14 @@ #endif  int debug;+int h8300_interrupt_mode;  host_callback *sim_callback;  static SIM_OPEN_KIND sim_kind; static char *myname;+static int verbose_interrupt = 0;+static int logging = 0;  /* FIXME: Needs to live in header file.    This header should also include the things in remote-sim.h.@@ -578,10 +581,8 @@ static int cmdline_location() {-  if (h8300smode && !h8300_normal_mode)-    return 0xffff00L;-  else if (h8300hmode && !h8300_normal_mode)-    return 0x2ff00L;+  if ((h8300hmode || h8300smode) && !h8300_normal_mode)+    return 0xff0000L;   else     return 0xff00L; }@@ -1037,12 +1038,15 @@  			    /* 8-bit ABS is displacement from SBR. 			       16 and 32-bit ABS are displacement from ZERO.-			       (SBR will always be zero except for h8/sx)+			       (SBR will always be 0xffff00 except for h8/sx) 			    */ 			    if ((x & SIZE) == L_8) 			      p->reg = SBR_REGNUM; 			    else-			      p->reg = ZERO_REGNUM;;+			      p->reg = ZERO_REGNUM;+			    /* address extend for @x:16 */+			    if ((x & SIZE) == L_16U)+			      p->literal += (p->literal >= 0x8000)?0xff0000:0x000000; 			  } 			else if ((x & MODE) == MEMIND || 				 (x & MODE) == VECIND)@@ -1253,6 +1257,39 @@   h8_set_cache_idx (sd, pc, idx); } +enum mem_access_type {MEM_RL,MEM_RW,MEM_RB,MEM_WL,MEM_WW,MEM_WB};++struct memlog {+  unsigned long pc;+  unsigned long addr;+  unsigned long data;+  enum mem_access_type type;+};++static struct memlog *memlog_buffer;+static int memlogtail;+static int memlogsize;++static add_memlog(unsigned long pc, unsigned long addr, +		  enum mem_access_type type, unsigned long data)+{+  if (!logging)+    return;+  if (memlogsize == memlogtail) {+         memlog_buffer = (struct memlog *)realloc(memlog_buffer, +                                                 (memlogsize * sizeof(struct memlog) + 65536));+         memlogsize += 65536 / sizeof(struct memlog);+  }+  if (memlog_buffer) {+    memlog_buffer[memlogtail].pc = pc;+    memlog_buffer[memlogtail].addr = addr;+    memlog_buffer[memlogtail].type = type;+    memlog_buffer[memlogtail].data = data;+    memlogtail++;+  }+}++static int pc;  static unsigned char  *breg[32]; static unsigned short *wreg[16];@@ -1265,33 +1302,46 @@ #define GET_L_REG(X)     h8_get_reg (sd, X) #define SET_L_REG(X, Y)  h8_set_reg (sd, X, Y) -#define GET_MEMORY_L(X) \-  ((X) < memory_size \-   ? ((h8_get_memory (sd, (X)+0) << 24) | (h8_get_memory (sd, (X)+1) << 16)  \-    | (h8_get_memory (sd, (X)+2) <<  8) | (h8_get_memory (sd, (X)+3) <<  0)) \-   : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 24) \-    | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 16) \-    | (h8_get_eightbit (sd, ((X)+2) & 0xff) <<  8) \-    | (h8_get_eightbit (sd, ((X)+3) & 0xff) <<  0)))--#define GET_MEMORY_W(X) \-  ((X) < memory_size \-   ? ((h8_get_memory   (sd, (X)+0) << 8) \-    | (h8_get_memory   (sd, (X)+1) << 0)) \-   : ((h8_get_eightbit (sd, ((X)+0) & 0xff) << 8) \-    | (h8_get_eightbit (sd, ((X)+1) & 0xff) << 0)))---#define GET_MEMORY_B(X) \-  ((X) < memory_size ? (h8_get_memory   (sd, (X))) \-                     : (h8_get_eightbit (sd, (X) & 0xff)))+#define GET_MEMORY_L(X) _get_memory_l(sd, X)++static inline unsigned long _get_memory_l(SIM_DESC sd, unsigned long addr)+{+  unsigned long result;+  result =+    ((h8_get_memory (sd, addr+0) << 24) | (h8_get_memory (sd, addr+1) << 16)+     | (h8_get_memory (sd, addr+2) <<  8) | (h8_get_memory (sd, addr+3) <<  0));+  add_memlog(pc, addr, MEM_RL, result);+  return result;+}++#define GET_MEMORY_W(X) _get_memory_w(sd, X)++static inline unsigned short _get_memory_w(SIM_DESC sd, unsigned long addr)+{+  unsigned short result;+  result =+     (h8_get_memory (sd, addr+0) <<  8) | (h8_get_memory (sd, addr+1) <<  0);+  add_memlog(pc, addr, MEM_RW, result);+  return result;+}++#define GET_MEMORY_B(X) _get_memory_b(sd, X) +static inline unsigned short _get_memory_b(SIM_DESC sd, unsigned long addr)+{+  unsigned short result;+  result = h8_get_memory (sd, addr+0);+  add_memlog(pc, addr, MEM_RB, result);+  return result;+}+  #define SET_MEMORY_L(X, Y)  \ {  register unsigned char *_p; register int __y = (Y); \    _p = ((X) < memory_size ? h8_get_memory_buf   (sd) +  (X) : \                              h8_get_eightbit_buf (sd) + ((X) & 0xff)); \    _p[0] = __y >> 24; _p[1] = __y >> 16; \    _p[2] = __y >>  8; _p[3] = __y >>  0; \+   add_memlog(pc, X, MEM_WL, Y);	 \ }  #define SET_MEMORY_W(X, Y) \@@ -1299,11 +1349,13 @@    _p = ((X) < memory_size ? h8_get_memory_buf   (sd) +  (X) : \                              h8_get_eightbit_buf (sd) + ((X) & 0xff)); \    _p[0] = __y >> 8; _p[1] = __y; \+   add_memlog(pc, X, MEM_WW, Y); \ }  #define SET_MEMORY_B(X, Y) \   ((X) < memory_size ? (h8_set_memory   (sd, (X), (Y))) \-                     : (h8_set_eightbit (sd, (X) & 0xff, (Y))))+		     : (h8_set_eightbit (sd, (X) & 0xff, (Y))));	\+   add_memlog(pc, X, MEM_WB, Y)  /* Simulate a memory fetch.    Return 0 for success, -1 for failure.@@ -1779,15 +1831,13 @@ 	free (h8_get_memory_buf (sd));       if (h8_get_cache_idx_buf (sd)) 	free (h8_get_cache_idx_buf (sd));-      if (h8_get_eightbit_buf (sd))-	free (h8_get_eightbit_buf (sd));        h8_set_memory_buf (sd, (unsigned char *)  			 calloc (sizeof (char), memory_size));       h8_set_cache_idx_buf (sd, (unsigned short *)  			    calloc (sizeof (short), memory_size));       sd->memory_size = memory_size;-      h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));+      h8_set_eightbit_buf (sd, (unsigned char *)h8_get_memory_buf(sd) + 0xffff00);        h8_set_mask (sd, memory_size - 1); @@ -1865,6 +1915,105 @@   goto next;					\ } +static unsigned long *trace_buffer;+static unsigned long tracesize;+static unsigned long tracetail;++static void add_trace(unsigned long pc)+{+  static unsigned long last_pc = 0xfffffff;++  if (pc == last_pc || logging == 0)+    return;+  last_pc = pc;+  if (tracesize == tracetail) {+         trace_buffer = (unsigned long *)realloc(trace_buffer, +                                                 (tracesize * sizeof(unsigned long) + 65536));+    tracesize += 65536 / sizeof(unsigned long);+  }+  if (trace_buffer)+    trace_buffer[tracetail++] = pc;+}++static void init_history(void)+{+  if(trace_buffer) {+    free(trace_buffer);+    trace_buffer = NULL;+  }+  tracesize = tracetail = 0;+  if(memlog_buffer) {+    free(memlog_buffer);+    memlog_buffer = NULL;+  }+  memlogsize = memlogtail = 0;+}++static int intlevel(SIM_DESC sd)+{+  if(h8300smode && (h8300_interrupt_mode == 2)) {+    return  h8_get_ccr (sd) & 0x80?0x100:h8_get_exr (sd) << 8;+  } else if (h8300_interrupt_mode == 1) {+    switch((h8_get_ccr (sd) >> 6) & 3) {+    case 0:+    case 1:+      return -1;+    case 2:+      return 1 << 8;+    case 3:+      return 0x100 << 8;+    }+  } else {+    return h8_get_ccr (sd) & 0x80?0x100 << 8:-1;+  }+}++int iosimulation(SIM_DESC, int);++#define exception(vector, pri)					\+do {									\+  unsigned int ccr;							\+  unsigned long vbr = 0;						\+  int tmp;								\+  if (verbose_interrupt)						\+    (*sim_callback->printf_filtered)					\+      (sim_callback, "sim_resume: interrupt occured %d\n", (vector));	\+  BUILDSR (sd);								\+  ccr = h8_get_ccr (sd);						\+  tmp = h8_get_reg (sd, SP_REGNUM);					\+  tmp -= 4;								\+  if (h8300sxmode)							\+    vbr = h8_get_vbr(sd);						\+  if (!h8300hmode || h8300_normal_mode)					\+    {									\+      SET_MEMORY_W (tmp, (ccr << 8) | ccr);				\+      SET_MEMORY_W (tmp, pc);						\+      pc = GET_MEMORY_W (vbr + (vector) * 2) & 0xffff;			\+    }									\+  else									\+    {									\+      SET_MEMORY_L (tmp, (ccr << 24) | pc);				\+      pc=GET_MEMORY_L(vbr + (vector) * 4) & 0xffffff;			\+    }									\+  if (h8300smode && (h8300_interrupt_mode == 2))			\+    {									\+      int exr;								\+      exr = h8_get_exr (sd);						\+      tmp -= 2;								\+      SET_MEMORY_W (tmp, exr << 8);					\+      if ((pri) >= 0)							\+	{								\+	  exr = pri;							\+	  h8_set_exr (sd, exr);						\+	  intMask = pri;						\+	}								\+    }									\+  h8_set_reg (sd, SP_REGNUM, tmp);					\+  ccr |= (h8300_interrupt_mode == 1)?0xc0:0x80;				\+  h8_set_ccr (sd, ccr);							\+  GETSR(sd);								\+ } while(0)+ void sim_resume (SIM_DESC sd, int step, int siggnal) {@@ -1878,12 +2027,12 @@   int rd;   int ea;   int bit;-  int pc;   int c, nz, v, n, u, h, ui, intMaskBit;   int trace, intMask;   int oldmask;   enum sim_stop reason;   int sigrc;+  int vector;    init_pointers (sd); @@ -1908,7 +2057,7 @@   /* Get Status Register (flags).  */   GETSR (sd); -  if (h8300smode)	/* Get exr.  */+  if (h8300smode && h8300_interrupt_mode)	/* Get exr.  */     {       trace = (h8_get_exr (sd) >> 7) & 1;       intMask = h8_get_exr (sd) & 7;@@ -1923,6 +2072,7 @@       decoded_inst *code;      top:+      add_trace(pc);       cidx = h8_get_cache_idx (sd, pc);       if (cidx == (unsigned short) -1 || 	  cidx >= sd->sim_cache_size)@@ -1943,6 +2093,15 @@ 	{ 	  cycles += code->cycles; 	  insts++;+	  add_trace(pc);+	  if ((vector = iosimulation (sd, cycles)) && +	      (intlevel(sd) < (vector & 0xff00)))+	    {+	      if (code->opcode == O (O_SLEEP, SN))+		pc += 2;+	      exception(vector & 0xff, (vector & 0xff00) >> 8);+	      goto end;+	    } 	}        switch (code->opcode)@@ -3253,7 +3412,7 @@ 	    goto end;  	  if (code->src.type == X (OP_IMM, SB))-	    fetch (sd, &code->src, &ea);+ 	    fetch (sd, &code->src, &ea); 	  else 	    ea = 1; @@ -3548,16 +3707,20 @@ 	  /* Pops exr and ccr before pc -- otherwise identical to rts.  */ 	  tmp = h8_get_reg (sd, SP_REGNUM); -	  if (h8300smode)			/* pop exr */+	  if (h8300smode && (h8300_interrupt_mode == 2))	/* pop exr */ 	    {-	      h8_set_exr (sd, GET_MEMORY_L (tmp));-	      tmp += 4;+	      unsigned char exr;+	      exr = GET_MEMORY_W (tmp) >> 8;+	      h8_set_exr (sd, exr);+	      intMask = exr & 7;+	      trace = exr & 0x80;+	      tmp += 2; 	    } 	  if (h8300hmode && !h8300_normal_mode) 	    {-	      h8_set_ccr (sd, GET_MEMORY_L (tmp));-	      tmp += 4; 	      pc = GET_MEMORY_L (tmp);+	      h8_set_ccr (sd, pc >> 24);+	      pc &= 0x00ffffff; 	      tmp += 4; 	    } 	  else@@ -3614,49 +3777,25 @@ 	      sim_engine_set_run_state (sd, sim_stopped,  					SIM_WSTOPSIG (h8_get_reg (sd, 0))); 	    }-#endif 	  else 	    { 	      /* Treat it as a sigtrap.  */ 	      sim_engine_set_run_state (sd, sim_stopped, SIGTRAP); 	    }+#else+	  else+	    sleep(0);+#endif 	  goto end; -	case O (O_TRAPA, SB):		/* trapa */+	case O (O_TRAPA, SB):	{	/* trapa */ 	  if (fetch (sd, &code->src, &res))    	    goto end;			/* res is vector number.  */-  -   	  tmp = h8_get_reg (sd, SP_REGNUM);-   	  if(h8300_normal_mode)-   	    {-   	      tmp -= 2;-   	      SET_MEMORY_W (tmp, code->next_pc);-   	      tmp -= 2;-   	      SET_MEMORY_W (tmp, h8_get_ccr (sd));-   	    }-   	  else-   	    {-   	      tmp -= 4;-   	      SET_MEMORY_L (tmp, code->next_pc);-   	      tmp -= 4;-   	      SET_MEMORY_L (tmp, h8_get_ccr (sd));-   	    }-   	  intMaskBit = 1;-   	  BUILDSR (sd);- -	  if (h8300smode)-	    {-	      tmp -= 4;-	      SET_MEMORY_L (tmp, h8_get_exr (sd));-	    }--	  h8_set_reg (sd, SP_REGNUM, tmp);--	  if(h8300_normal_mode)-	    pc = GET_MEMORY_L (0x10 + res * 2); /* Vector addresses are 0x10,0x12,0x14 and 0x16 */-	  else-	    pc = GET_MEMORY_L (0x20 + res * 4);+	  res += 8;+	  pc += 2;+	  exception(res, -1); 	  goto end;+	}  	case O (O_BPT, SN): 	  sim_engine_set_run_state (sd, sim_stopped, SIGTRAP);@@ -5005,15 +5144,13 @@     free (h8_get_memory_buf (sd));   if (h8_get_cache_idx_buf (sd))     free (h8_get_cache_idx_buf (sd));-  if (h8_get_eightbit_buf (sd))-    free (h8_get_eightbit_buf (sd));    h8_set_memory_buf (sd, (unsigned char *)  		     calloc (sizeof (char), memory_size));   h8_set_cache_idx_buf (sd, (unsigned short *)  			calloc (sizeof (short), memory_size));   sd->memory_size = memory_size;-  h8_set_eightbit_buf (sd, (unsigned char *) calloc (sizeof (char), 256));+  h8_set_eightbit_buf (sd, (unsigned char *)h8_get_memory_buf(sd) + 0xffff00);    /* `msize' must be a power of two.  */   if ((memory_size & (memory_size - 1)) != 0)@@ -5024,6 +5161,8 @@     }   h8_set_mask (sd, memory_size - 1); +  init_history();+  init_ioregs(sd);   if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd, 		     sim_kind == SIM_OPEN_DEBUG, 		     0, sim_write)@@ -5074,3 +5213,187 @@      return SIM_RC_OK; }++static void show_trace(int lines)+{+  unsigned long idx;+  idx = tracetail - lines;+  for (; lines > 0; --lines)+    {+      if (trace_buffer[idx] != -1)+	(*sim_callback->printf_filtered) (sim_callback,+					  "0x%06x\n", trace_buffer[idx]);+      idx++;+    }+  (*sim_callback->printf_filtered) (sim_callback, "\n");+}++static void save_trace(const char *filename)+{+  FILE *fp;+  unsigned long idx;+  fp = fopen(filename, "w");+  if (!fp)+    {+      (*sim_callback->printf_filtered) (sim_callback,+					"save-history: file open failed.\n");+      return ;+    }+  for (idx = 0; idx < tracetail; idx++)+    fprintf(fp, "0x%06x\n", trace_buffer[idx]);+  fclose(fp);+}++static const char *memtype_str[]={"RL","RW","RB","WL","WW","WB"};++static void show_memlog(int lines)+{+  unsigned long idx;+  idx = memlogtail - lines;+  if (memlog_buffer == NULL)+    {+      (*sim_callback->printf_filtered) (sim_callback, "no memlog\n");+      return;+    }+  for (; lines > 0; --lines)+    {+      (*sim_callback->printf_filtered) (sim_callback,+					"0x%06x 0x%06x %s %08x\n",+					memlog_buffer[idx].pc,+					memlog_buffer[idx].addr,+					memtype_str[memlog_buffer[idx].type],+					memlog_buffer[idx].data);+      idx++;+    }+  (*sim_callback->printf_filtered) (sim_callback, "\n");+}++static void save_memlog(const char *filename)+{+  FILE *fp;+  unsigned long idx;+  if (memlog_buffer == NULL)+    {+      (*sim_callback->printf_filtered) (sim_callback, "no memlog\n");+      return;+    }+  fp = fopen(filename, "w");+  if (!fp)+    {+      (*sim_callback->printf_filtered) (sim_callback,+					"save-history: file open failed.\n");+      return ;+    }+  for (idx = 0; idx < memlogtail; idx++)+    fprintf(fp, "0x%06x 0x%06x %s %08x\n",+	    memlog_buffer[idx].pc,+	    memlog_buffer[idx].addr,+	    memtype_str[memlog_buffer[idx].type],+	    memlog_buffer[idx].data);+  fclose(fp);+}++void+sim_do_command (SIM_DESC sd, const char *cmd)+{+  if (cmd == NULL || *cmd == '\0')+    cmd = "help";+  if (strncmp(cmd, "show-trace", 10) == 0)+    {+      int lines = 16;+      cmd += 10;+      if (*cmd)+       lines = atoi(cmd);+      if (lines > 0)+       show_trace(lines);+      else+       (*sim_callback->printf_filtered) (sim_callback,+                                         "Invalid lines\n");+      return;+    }+  else if (strncmp(cmd, "save-trace", 10) == 0)+    {+      cmd += 10;+      while(isspace(*cmd))+	cmd++;++      if (*cmd)+	save_trace(cmd);+      else+	(*sim_callback->printf_filtered) (sim_callback,+					  "Invalid filename\n");+    }+  else if (strncmp(cmd, "show-mem", 8) == 0)+    {+      int lines = 16;+      cmd += 8;+      if (*cmd)+	lines = atoi(cmd);+      if (lines > 0)+	show_memlog(lines);+      else+	(*sim_callback->printf_filtered) (sim_callback,+					  "Invalid lines\n");+      return;+    }+  else if (strncmp(cmd, "save-mem", 8) == 0)+    {+      cmd += 8;+      while(isspace(*cmd))+       cmd++;+      if (*cmd)+       save_memlog(cmd);+      else+       (*sim_callback->printf_filtered) (sim_callback,+                                         "Invalid filename\n");+    }+  else if (strncmp (cmd, "sci", 3) == 0)+    {+      cmd += 3;+      while(isspace(*cmd)) cmd++;+      if (strncmp (cmd, "pty", 3) == 0)+	sci_open_pty(sim_callback);+      else if (strncmp(cmd, "net", 3) == 0)+	{+	  cmd += 3;+	  while(isspace(*cmd)) cmd++;+	  sci_open_net(sim_callback, atoi(cmd));+	}+    }+  else if (strncmp (cmd, "verbose-int", 11) == 0)+    {+      cmd += 11;+      while(isspace(*cmd)) cmd++;+      verbose_interrupt = atoi(cmd);+    }+  else if (strncmp(cmd, "help", 4) == 0)+    (*sim_callback->printf_filtered) (sim_callback,+				      "List of H8/300 Simulator commands\n\n"+				      "show-trace <n> -- show trace history\n"+				      "save-trace filename -- save trace history\n"+				      "show-mem <n> -- show memory access log\n"+				      "save-mem filename -- save memory access log\n"+				      "sci [pty|net port] -- open sci port\n"+				      "intmode mode -- set interrupt mode\n"+				      "verbose-int -- verbose interrupt\n"+				      "trace [on|off] -- trace switch\n"+	    );+  else if (strncmp(cmd, "intmode", 7) == 0)+    {+      cmd += 7;+      while(isspace(*cmd)) cmd++;+      h8300_interrupt_mode = atoi(cmd);+    }+  else if (strncmp (cmd, "trace", 5) == 0)+    {+      cmd += 5;+      while(isspace(*cmd)) cmd++;+      if (strncmp (cmd, "on", 2) == 0)+	logging = 1;+      else if (strncmp(cmd, "off", 3) == 0)+	logging = 0;+    }+  else+    (*sim_callback->printf_filtered) (sim_callback,+				      "Error: Unknown \"%s\" command\n", cmd);+}diff -Nur binutils-gdb.orig/sim/h8300/io.c binutils-gdb/sim/h8300/io.c--- binutils-gdb.orig/sim/h8300/io.c	1970-01-01 01:00:00.000000000 +0100+++ binutils-gdb/sim/h8300/io.c	2015-11-16 11:52:52.502025971 +0100@@ -0,0 +1,1058 @@+/*+ H8 simulator Internal Peripheral Support+*/++#include <unistd.h>+#include <errno.h>+#include <fcntl.h>+#include <sys/time.h>+#include <string.h>+#define _XOPEN_SOURCE+#include <stdlib.h>+#include <sys/socket.h>+#include <netinet/in.h>++#include "sim-main.h"+#undef CSIZE+#include <termios.h>++#define MAX_SCI_CH 3++#define SMR(ch) (STATE_CPU(sd, 0)->eightbit[sci_base[ch]+0])+#define BRR(ch) (STATE_CPU(sd, 0)->eightbit[sci_base[ch]+1])+#define SCR(ch) (STATE_CPU(sd, 0)->eightbit[sci_base[ch]+2])+#define TDR(ch) (STATE_CPU(sd, 0)->eightbit[sci_base[ch]+3])+#define SSR(ch) (STATE_CPU(sd, 0)->eightbit[sci_base[ch]+4])+#define RDR(ch) (STATE_CPU(sd, 0)->eightbit[sci_base[ch]+5])++#define TCR8(ch)   (STATE_CPU(sd, 0)->eightbit[timer8_base[ch] + 0])+#define TCSR8(ch)  (STATE_CPU(sd, 0)->eightbit[timer8_base[ch] + 2])+#define TCORA8(ch) (STATE_CPU(sd, 0)->eightbit[timer8_base[ch] + 4])+#define TCORB8(ch) (STATE_CPU(sd, 0)->eightbit[timer8_base[ch] + 6])+#define TCNT8(ch)  (STATE_CPU(sd, 0)->eightbit[timer8_base[ch] + 8])++#define TSTR16 (STATE_CPU(sd, 0)->eightbit[0x60])+#define TISRA16  (STATE_CPU(sd, 0)->eightbit[0x64])+#define TISRB16  (STATE_CPU(sd, 0)->eightbit[0x65])+#define TISRC16  (STATE_CPU(sd, 0)->eightbit[0x66])+#define TCR16(ch) (STATE_CPU(sd, 0)->eightbit[0x68 + (ch) * 8])+#define TCNT16H(ch) (STATE_CPU(sd, 0)->eightbit[0x6a + (ch) * 8])+#define TCNT16L(ch) (STATE_CPU(sd, 0)->eightbit[0x6b + (ch) * 8])+#define GRA16H(ch) (STATE_CPU(sd, 0)->eightbit[0x6c + (ch) * 8])+#define GRA16L(ch) (STATE_CPU(sd, 0)->eightbit[0x6d + (ch) * 8])+#define GRB16H(ch) (STATE_CPU(sd, 0)->eightbit[0x6e + (ch) * 8])+#define GRB16L(ch) (STATE_CPU(sd, 0)->eightbit[0x6f + (ch) * 8])++#define TPU_CH 6+#define TPU_TSTR (STATE_CPU(sd, 0)->eightbit[0xc0])+#define TPU_TCR(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 0])+#define TPU_TSR(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 5])+#define TPU_TCNTH(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 6])+#define TPU_TCNTL(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 7])+#define TPU_GRAH(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 8])+#define TPU_GRAL(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 9])+#define TPU_GRBH(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 10])+#define TPU_GRBL(ch) (STATE_CPU(sd, 0)->memory[tpubase[ch] + 11])++#define IPRA_H8300H 0xfee018+#define IPRB_H8300H 0xfee019++#define IPRA_H8300S 0xfffe00++struct int_list_t {+  int vector;+  unsigned int  isr_adr;+  unsigned char isr_mask;+  unsigned int  ier_adr;+  unsigned char ier_mask;+};++static const unsigned char *sci_base;+static unsigned char ssr[MAX_SCI_CH];+static const unsigned char *timer8_base;+static const struct int_list_t *int_table;++static const unsigned char h8300h_timer8_base[] = {0x80,0x81,0x90,0x91,0};+static const unsigned char h8300s_timer8_base[] = {0xb0,0xb1,0};+static const unsigned int tpubase[] = {0xffffd0,0xffffe0,0xfffff0,+				       0xfffe80,0xfffe90,0xfffea0};+static const unsigned char h8300h_sci_base[] = {0xb0,0xb8,0xc0};+static const unsigned char h8300s_sci_base[] = {0x78,0x80,0x88};+static const unsigned char h8300sx_sci_base[] = {0x80,0x88,0x60};++extern int h8300hmode;+extern int h8300smode;+extern int h8300sxmode;++static const struct int_list_t h8300h_int_table[]= {+  {24,0xffff64,0x01,0xffff64,0x10},	/* IMIA0 */+  {25,0xffff65,0x01,0xffff65,0x10},	/* IMIB0 */+  {26,0xffff66,0x01,0xffff66,0x10},	/* OVI0  */+  {28,0xffff64,0x02,0xffff64,0x20},	/* IMIA1 */+  {29,0xffff65,0x02,0xffff65,0x20},	/* IMIB1 */+  {30,0xffff66,0x02,0xffff66,0x20},	/* OVI1  */+  {32,0xffff64,0x04,0xffff64,0x40},	/* IMIA2 */+  {33,0xffff65,0x04,0xffff65,0x40},	/* IMIB2 */+  {34,0xffff66,0x04,0xffff66,0x40},	/* OVI2  */+  {36,0xffff82,0x40,0xffff80,0x40},	/* CMIA0 */+  {37,0xffff82,0x80,0xffff80,0x80},	/* CMIB0 */+  {38,0xffff83,0x40,0xffff81,0x40},	/* CMIA1 */+  {38,0xffff83,0x80,0xffff81,0x40},	/* CMIB1 */+  {39,0xffff82,0x20,0xffff80,0x20},	/* TOVI0 */+  {39,0xffff83,0x20,0xffff81,0x20},	/* TOVI1 */+  {40,0xffff92,0x40,0xffff90,0x40},	/* CMIA2 */+  {41,0xffff92,0x80,0xffff90,0x80},	/* CMIB2 */+  {42,0xffff93,0x40,0xffff91,0x40},	/* CMIA3 */+  {42,0xffff93,0x80,0xffff91,0x40},	/* CMIB3 */+  {43,0xffff92,0x20,0xffff90,0x20},	/* TOVI2 */+  {43,0xffff93,0x20,0xffff91,0x20},	/* TOVI3 */+  {52,0xffffb4,0x38,0xffffb2,0x40},	/* ERI0 */+  {53,0xffffb4,0x40,0xffffb2,0x40},	/* RXI0 */+  {54,0xffffb4,0x80,0xffffb2,0x80},	/* TXI0 */+  {55,0xffffb4,0x04,0xffffb2,0x04},	/* TEI0 */+  {56,0xffffbc,0x38,0xffffba,0x40},	/* ERI1 */+  {57,0xffffbc,0x40,0xffffba,0x40},	/* RXI1 */+  {58,0xffffbc,0x80,0xffffba,0x80},	/* TXI1 */+  {59,0xffffbc,0x04,0xffffba,0x04},	/* TEI1 */+  {60,0xffffc4,0x38,0xffffc2,0x40},	/* ERI2 */+  {61,0xffffc4,0x40,0xffffc2,0x40},	/* RXI2 */+  {62,0xffffc4,0x80,0xffffc2,0x80},	/* TXI2 */+  {63,0xffffc4,0x04,0xffffc2,0x04},	/* TEI2 */+  {-1,0,0,0,0}+};++static const struct int_list_t h8300s_int_table[]= {+  {40,0xffffd5,0x01,0xffffd4,0x01},	/* TGI0A */+  {41,0xffffd5,0x02,0xffffd4,0x02},	/* TGI0B */+  {43,0xffffd5,0x10,0xffffd4,0x10},	/* TGI0V */+  {48,0xffffe5,0x01,0xffffe4,0x01},	/* TGI1A */+  {49,0xffffe5,0x01,0xffffe4,0x02},	/* TGI1B */+  {50,0xffffe5,0x10,0xffffe4,0x10},	/* TGI1V */+  {52,0xfffff5,0x01,0xfffff4,0x01},	/* TGI2A */+  {53,0xfffff5,0x02,0xfffff4,0x02},	/* TGI2B */+  {54,0xfffff5,0x10,0xfffff4,0x10},	/* TGI2V */+  {56,0xfffe85,0x01,0xfffe84,0x01},	/* TGI3A */+  {57,0xfffe85,0x02,0xfffe84,0x02},	/* TGI3B */+  {60,0xfffe85,0x10,0xfffe84,0x10},	/* TGI3V */+  {64,0xfffe95,0x01,0xfffe94,0x01},	/* TGI4A */+  {65,0xfffe95,0x02,0xfffe94,0x02},	/* TGI4B */+  {66,0xfffe95,0x10,0xfffe94,0x10},	/* TGI4V */+  {68,0xfffea5,0x01,0xfffea4,0x01},	/* TGI5A */+  {69,0xfffea5,0x02,0xfffea4,0x02},	/* TGI5B */+  {70,0xfffea5,0x10,0xfffea4,0x10},	/* TGI5V */+  {72,0xffffb2,0x40,0xffffb0,0x40},	/* CMIA0 */+  {73,0xffffb2,0x80,0xffffb0,0x80},	/* CMIB0 */+  {74,0xffffb2,0x20,0xffffb0,0x20},	/* CMIA1 */+  {76,0xffffb3,0x40,0xffffb1,0x40},	/* CMIB1 */+  {77,0xffffb3,0x80,0xffffb1,0x40},	/* TOVI0 */+  {78,0xffffb3,0x20,0xffffb1,0x20},	/* TOVI1 */+  {88,0xffff7c,0x38,0xffff7a,0x40},	/* ERI0 */+  {89,0xffff7c,0x40,0xffff7a,0x40},	/* RXI0 */+  {90,0xffff7c,0x80,0xffff7a,0x80},	/* TXI0 */+  {91,0xffff7c,0x04,0xffff7a,0x04}, 	/* TEI0 */+  {92,0xffff84,0x38,0xffff82,0x40},	/* ERI1 */+  {93,0xffff84,0x40,0xffff82,0x40},	/* RXI1 */+  {94,0xffff84,0x80,0xffff82,0x80},	/* TXI1 */+  {95,0xffff84,0x04,0xffff82,0x04}, 	/* TEI1 */+  {96,0xffff8c,0x38,0xffff8a,0x40},	/* ERI2 */+  {97,0xffff8c,0x40,0xffff8a,0x40},	/* RXI2 */+  {98,0xffff8c,0x80,0xffff8a,0x80},	/* TXI2 */+  {99,0xffff8c,0x04,0xffff8a,0x04}, 	/* TEI2 */+  {-1,0,0,0,0}+};+static const struct int_list_t h8300sx_int_table[]= {+  {88,0xffffd5,0x01,0xffffd4,0x01},	/* TGI0A */+  {89,0xffffd5,0x02,0xffffd4,0x02},	/* TGI0B */+  {90,0xffffd5,0x01,0xffffd4,0x01},	/* TGI0C */+  {91,0xffffd5,0x02,0xffffd4,0x02},	/* TGI0D */+  {93,0xffffe5,0x01,0xffffe4,0x01},	/* TGI1A */+  {94,0xffffe5,0x01,0xffffe4,0x02},	/* TGI1B */+  {95,0xffffe5,0x10,0xffffe4,0x10},	/* TGI1V */+  {96,0xffffe5,0x10,0xffffe4,0x10},	/* TGI1U */+  {97,0xfffff5,0x01,0xfffff4,0x01},	/* TGI2A */+  {98,0xfffff5,0x02,0xfffff4,0x02},	/* TGI2B */+  {99,0xfffff5,0x10,0xfffff4,0x10},	/* TGI2V */+  {100,0xfffff5,0x10,0xfffff4,0x10},	/* TGI2U */+  {101,0xfffe85,0x01,0xfffe84,0x01},	/* TGI3A */+  {102,0xfffe85,0x02,0xfffe84,0x02},	/* TGI3B */+  {103,0xfffe85,0x01,0xfffe84,0x01},	/* TGI3A */+  {104,0xfffe85,0x02,0xfffe84,0x02},	/* TGI3B */+  {105,0xfffe85,0x10,0xfffe84,0x10},	/* TGI3V */+  {106,0xfffe95,0x01,0xfffe94,0x01},	/* TGI4A */+  {107,0xfffe95,0x02,0xfffe94,0x02},	/* TGI4B */+  {108,0xfffe95,0x10,0xfffe94,0x10},	/* TGI4V */+  {109,0xfffe95,0x10,0xfffe94,0x10},	/* TGI4U */+  {110,0xfffea5,0x01,0xfffea4,0x01},	/* TGI5A */+  {111,0xfffea5,0x02,0xfffea4,0x02},	/* TGI5B */+  {112,0xfffea5,0x10,0xfffea4,0x10},	/* TGI5V */+  {113,0xfffea5,0x10,0xfffea4,0x10},	/* TGI5V */+  {116,0xffffb2,0x40,0xffffb0,0x40},	/* CMIA0 */+  {117,0xffffb2,0x80,0xffffb0,0x80},	/* CMIB0 */+  {118,0xffffb3,0x80,0xffffb1,0x40},	/* OVI0 */+  {119,0xffffb2,0x20,0xffffb0,0x20},	/* CMIA1 */+  {120,0xffffb3,0x40,0xffffb1,0x40},	/* CMIB1 */+  {121,0xffffb3,0x20,0xffffb1,0x20},	/* OVI1 */+  {144,0xffff7c,0x38,0xffff7a,0x40},	/* ERI0 */+  {145,0xffff7c,0x40,0xffff7a,0x40},	/* RXI0 */+  {146,0xffff7c,0x80,0xffff7a,0x80},	/* TXI0 */+  {147,0xffff7c,0x04,0xffff7a,0x04}, 	/* TEI0 */+  {148,0xffff84,0x38,0xffff82,0x40},	/* ERI1 */+  {149,0xffff84,0x40,0xffff82,0x40},	/* RXI1 */+  {150,0xffff84,0x80,0xffff82,0x80},	/* TXI1 */+  {151,0xffff84,0x04,0xffff82,0x04}, 	/* TEI1 */+  {152,0xffff8c,0x38,0xffff8a,0x40},	/* ERI2 */+  {153,0xffff8c,0x40,0xffff8a,0x40},	/* RXI2 */+  {154,0xffff8c,0x80,0xffff8a,0x80},	/* TXI2 */+  {155,0xffff8c,0x04,0xffff8a,0x04}, 	/* TEI2 */+  {-1,0,0,0,0}+};++void +timer8(SIM_DESC sd, unsigned int cycles_diff)+{+  static int prescale[3]={8,64,8192};+  const int prescale_div[3]={8,64,8192};+  static unsigned char tcsr[4]={0x00,0x00,0x00,0x00};+  int tm, cnt, pcnt, cor;+  for (pcnt = 0; pcnt < 3; pcnt++)+    {+      prescale[pcnt] -= cycles_diff;+      +      if (prescale[pcnt]<=0) +	{+	  /* input time pulse */+	  for(tm=0; timer8_base[tm] != 0; tm++)+	    {+	      if ((TCR8(tm) & 0x07) == 0)+		continue;+	      /* internal TCSR status clear */+	      tcsr[tm] &= (TCSR8(tm) & 0xf0);+	      +	      if ((TCR8(tm & 2) & 0x7) == 0x04)+		{+		  /* 16bit mode */+		  if (tm & 1)+		    continue;+		  tcsr[tm+1] &= (TCSR8(tm+1) & 0xf0);+		  cnt = TCNT8(tm) << 8 | TCNT8(tm+1);+		  cnt++;+		  if (cnt >= 0x10000)+		    {+		      tcsr[tm] |= 0x20;+		      cnt = 0;+		    }+		  TCNT8(tm) = cnt >> 8;+		  TCNT8(tm-1) = cnt & 0xff;+		  /* TCORA compare match check */+		  cor = TCORA8(tm) << 8 | TCORA8(tm+1);+		  if (cnt >= cor)+		    {+		      tcsr[tm]|=0x40;+		      if ((TCR8(tm) & 0x18) == 0x08)+			cnt = 0;+		    }+		  if ((cnt & 0xff) >= (cor & 0xff))+		    tcsr[tm+1]|=0x40;+		  /* TCORB compare match check */+		  cor = TCORB8(tm) << 8 | TCORB8(tm+1);+		  if (cnt >= cor)+		    {+		      tcsr[tm]|=0x80;+		      if ((TCR8(tm) & 0x18) == 0x10)+			cnt = 0;+		    }+		  if ((cnt & 0xff) >= (cor & 0xff))+		    tcsr[tm+1]|=0x80;+		  TCNT8(tm) = cnt >> 8;+		  TCNT8(tm+1) = cnt & 0xff;+		  /* update TSCR */+		  TCSR8(tm) &= 0x1f;+		  TCSR8(tm) |= (tcsr[tm] & 0xe0);+		  TCSR8(tm+1) &= 0x1f;+		  TCSR8(tm+1) |= (tcsr[tm+1] & 0xe0);+		}+	      else+		{+		  /* 8bit mode */+		  /* update counter */+		  if ((TCR8(tm) & 0x07) == (pcnt+1))+		    {+		      cnt = ++TCNT8(tm);+		      if (cnt>=0x100)+			{+			  tcsr[tm] |= 0x20;+			  cnt = 0;+			}+		    }+		  /* TCORA compare match check*/+		  if (cnt >= TCORA8(tm))+		    {+		      tcsr[tm]|=0x40;+		      if ((TCR8(tm) & 0x18) == 0x08)+			cnt = 0;+		    }+		  /* TCORB compare match check*/+		  if (cnt >= TCORB8(tm))+		    {+		      tcsr[tm]|=0x80;+		      if ((TCR8(tm) & 0x18) == 0x10)+			cnt = 0;+		    }+		  TCNT8(tm) = cnt;+		  /* update TSCR */+		  TCSR8(tm) &= 0x1f;+		  TCSR8(tm) |= (tcsr[tm] & 0xe0);+		}+	    }+	  prescale[pcnt]+=prescale_div[pcnt];+	}+    }+}++static void +h8300sx_timer16(SIM_DESC sd, unsigned int cycles_diff)+{+  static int prescale[4]={1,4,16,64};+  const int prescale_div[4]={1,4,16,64};+  static int tsr[TPU_CH];+  int tm, cnt, pcnt, gr, pulse;+  for (pcnt = 0; pcnt < 4; pcnt++) {+    prescale[pcnt] -= cycles_diff;+    pulse = -prescale[pcnt] / prescale_div[cnt] + 1;+    if (prescale[pcnt]<=0) +    {+      /* input time pulse */+      for(tm=0; tm < TPU_CH; tm++) {++	/* Timer enable check */+	if (!(TPU_TSTR & (1 << tm)))+	  continue;++	/* internal TCSR status clear */+	tsr[tm] &= TPU_TSR(tm);+	/* update counter */+        if ((TPU_TCR(tm) & 0x07) == pcnt)+          {+            cnt = ((TPU_TCNTH(tm) << 8) | TPU_TCNTL(tm));+	    cnt += pulse;++	    /* CNT overflow check */+            if (cnt>=0x10000)+              {+                tsr[tm] |= 0x10;+                cnt = 0;+              }++	    /* GRA compare match check*/+	    gr = (TPU_GRAH(tm) << 8) | TPU_GRAL(tm);+	    if (cnt >= gr)+	      {+                tsr[tm] |= 0x1;+		if ((TPU_TCR(tm) & 0x60) == 0x20)+		  cnt = 0;+	      }++	    /* GRB compare match check*/+	    gr = (TPU_GRBH(tm) << 8) | TPU_GRBL(tm);+	    if (cnt >= gr)+	      {+                tsr[tm] |= 0x2;+		if ((TPU_TCR(tm) & 0x60) == 0x20)+		  cnt = 0;+	      }++	    /* update TCNT */+            TPU_TCNTH(tm) = (cnt >> 8);+	    TPU_TCNTL(tm) = cnt & 0xff;+          }++      }+      prescale[pcnt]+=prescale_div[pcnt];+      /* update TSR */+      TPU_TSR(tm) |= tsr[tm];+    }+  }+}++static void +h8300s_timer16(SIM_DESC sd, unsigned int cycles_diff)+{+  static int prescale[4]={1,4,16,64};+  const int prescale_div[4]={1,4,16,64};+  static int tsr[TPU_CH];+  int tm, cnt, pcnt, gr, pulse;+  for (pcnt = 0; pcnt < 4; pcnt++) {+    prescale[pcnt] -= cycles_diff;+    pulse = -prescale[pcnt] / prescale_div[pcnt] + 1;+    if (prescale[pcnt]<=0) +    {+      /* input time pulse */+      for(tm=0; tm < TPU_CH; tm++) {++	/* Timer enable check */+	if (!(TPU_TSTR & (1 << tm)))+	  continue;++	/* internal TCSR status clear */+	tsr[tm] &= TPU_TSR(tm);+	/* update counter */+        if ((TPU_TCR(tm) & 0x0f) == pcnt)+          {+            cnt = ((TPU_TCNTH(tm) << 8) | TPU_TCNTL(tm));+	    cnt += pulse;++	    /* CNT overflow check */+            if (cnt>=0x10000)+              {+		int cascade_low = tm % 3;+                tsr[tm] |= 0x10;+                cnt -= 0x10000;+		if (cascade_low == 2)+		  {+		    int cascade_high = tm - cascade_low + 1;+		    if (TPU_TCR(cascade_high) & 0x0f == 0x0f)+		      {+			int cascade_cnt;+			cascade_cnt = ((TPU_TCNTH(cascade_high) << 8) | +				       TPU_TCNTL(cascade_high));+			cascade_cnt++;+			TPU_TCNTH(cascade_high) = (cascade_cnt >> 8);+			TPU_TCNTL(cascade_high) = cascade_cnt & 0xff;+		      }+		  }+              }++	    /* GRA compare match check*/+	    gr = (TPU_GRAH(tm) << 8) | TPU_GRAL(tm);+	    if (cnt >= gr)+	      {+                tsr[tm] |= 0x1;+		if ((TPU_TCR(tm) & 0xe0) == 0x20)+		  cnt = 0;+	      }++	    /* GRB compare match check*/+	    gr = (TPU_GRBH(tm) << 8) | TPU_GRBL(tm);+	    if (cnt >= gr)+	      {+                tsr[tm] |= 0x2;+		if ((TPU_TCR(tm) & 0xe0) == 0x40)+		  cnt = 0;+	      }++	    /* update TCNT */+            TPU_TCNTH(tm) = (cnt >> 8);+	    TPU_TCNTL(tm) = cnt & 0xff;+          }++      }+      prescale[pcnt]+=prescale_div[pcnt];+      /* update TSR */+      TPU_TSR(tm) |= tsr[tm];+    }+  }+}++static void +h8300h_timer16(SIM_DESC sd, unsigned int cycles_diff)+{+  static int prescale[4]={1,2,4,8};+  const int prescale_div[4]={1,2,4,8};+  static int tisra, tisrb, tisrc;+  int tm, cnt, pcnt, gr, pulse;+  for (pcnt = 0; pcnt < 4; pcnt++) {+    prescale[pcnt] -= cycles_diff;+    if (prescale[pcnt]<=0) +    {+      pulse = -prescale[pcnt] / prescale_div[pcnt] + 1;+      prescale[pcnt]+=prescale_div[pcnt];+      /* input time pulse */+      for(tm=0; tm < 3; tm++) {++	/* Timer enable check */+	if (!(TSTR16 & (1 << tm)))+	  continue;++	/* internal TCSR status clear */+	tisra &= (0x07 & (TISRA16 & (1 << tm)));+	tisrb &= (0x07 & (TISRB16 & (1 << tm)));+	tisrc &= (0x07 & (TISRC16 & (1 << tm)));+	/* update counter */+        if ((TCR16(tm) & 0x07) == pcnt)+          {+            cnt = ((TCNT16H(tm) << 8) | TCNT16L(tm));+	    cnt += pulse;++	    /* CNT overflow check */+            if (cnt>=0x10000)+              {+                tisrc |= (1 << tm);+                cnt = 0;+              }++	    /* GRA compare match check*/+	    gr = (GRA16H(tm) << 8) | GRA16L(tm);+	    if (cnt >= gr)+	      {+                tisra |= (1 << tm);+		if ((TCR16(tm) & 0x60) == 0x20)+		  cnt = 0;+	      }++	    /* GRB compare match check*/+	    gr = (GRB16H(tm) << 8) | GRB16L(tm);+	    if (cnt >= gr)+	      {+                tisrb |= (1 << tm);+		if ((TCR16(tm) & 0x60) == 0x40)+		  cnt = 0;+	      }+	    /* update TCNT */+            TCNT16H(tm) = (cnt >> 8);+	    TCNT16L(tm) = cnt & 0xff;+          }++      }+      /* update TSCR */+      TISRA16 &= 0x70;+      TISRA16 |= tisra;+      TISRB16 &= 0x70;+      TISRB16 |= tisrb;+      TISRC16 &= 0x70;+      TISRC16 |= tisrc;+    }+  }+}++static struct {+  int fd;+  int socket;+  int iac;+  unsigned char cmd;+  struct sockaddr_in local;+  struct sockaddr_in remote;+  struct termios old_attr;+} sci_port[MAX_SCI_CH];++enum {PORT_NONE, PORT_PTY,PORT_NET};+static int sci_port_type = PORT_NONE;++static unsigned int +sci_complete_time(SIM_DESC sd, int ch)+{+  int length;+  int div[]={1,4,16,64};+  length = (SMR(ch) & 0x40)?7:8;+  length += (SMR(ch) & 0x20)?1:0;+  length += (SMR(ch) & 0x08)?1:0;+  length += 2;+  return length * 32 * div[SMR(ch) & 0x03] * BRR(ch);+}++static void +sci_send_data(int ch, int txd)+{+  char dt = txd;+  if (sci_port[ch].fd >= 0) {+    if (write(sci_port[ch].fd, &dt, 1) > 0)+      fsync(sci_port[ch].fd);+    else+      if (errno != EAGAIN)+	sci_port[ch].fd = -1;+  }+}++static void+telnet_escape(int ch, char rd)+{+  unsigned char cmd = sci_port[ch].cmd;+  unsigned char rep[3];+  switch(sci_port[ch].iac)+    {+    case 1:+      sci_port[ch].cmd = rd;+      sci_port[ch].iac++;+      break;+    case 2:+      if ((rd == 1 || rd == 3) && cmd == 0xfd)+	{+	  sci_port[ch].iac = 0;+	  return;+	}+      else if (rd == 1 || rd == 3)+	{+	  if (cmd == 0xfb) +	    cmd = 0xfd;+	  else if (cmd == 0xfd)+	    cmd = 0xfb;+	} +      else+	{+	  if (cmd == 0xfb) +	    cmd = 0xfe;+	  else if (cmd == 0xfd)+	  cmd = 0xfc;+	}+      rep[0] = 0xff;+      rep[1] = cmd;+      rep[2] = rd;+      write(sci_port[ch].fd, rep, sizeof(rep));+      sci_port[ch].iac = 0;+      break;+    }+}++static void+telnet_request(int fd)+{+  static unsigned char req[6] = {0xff, 0xfb, 0x03, 0xff, 0xfb, 0x01};+  write(fd, req, sizeof(req));+}+++int+sci_rcv_data(int ch, int *rxd)+{+  unsigned char rd;+  if (sci_port[ch].fd >= 0)+    {+      if( read(sci_port[ch].fd, &rd , 1) > 0 )+	{+	  if (sci_port_type == PORT_NET)+	    {+	      if (sci_port[ch].iac > 0)+		{+		  telnet_escape(ch, rd);+		  return 0;+		}+	      else+		if (rd == 0xff)+		  {+		    sci_port[ch].iac = 1;+		    return 0;+		  }+	    }+	  *rxd = rd;+	  return 1;+	}+      else+	{+	  if (errno == EAGAIN)+	    {+	      return 0;+	    }+	  else+	    {+	      close(sci_port[ch].fd);+	      sci_port[ch].fd = -1;+	    }+	}+    }+  return 0;+}++static int net_accept(void)+{+  int ch;+  for (ch = 0; ch < MAX_SCI_CH; ch++)+    {+      if(sci_port[ch].fd == -1)+	{+	  int connectfd;+	  socklen_t rem_size = sizeof(sci_port[ch].remote);+	  connectfd = accept(sci_port[ch].socket, +			     (struct sockaddr *)&sci_port[ch].remote, +			     &rem_size);+	  if (connectfd > 0)+	    {+	      unsigned char rd;+	      int flag;+	      sci_port[ch].fd = connectfd;+	      telnet_request(connectfd);+	      sci_port[ch].iac = 0;+	      flag = fcntl(sci_port[ch].fd, F_GETFL, 0);+	      fcntl(sci_port[ch].fd, F_SETFL, flag | O_NONBLOCK);+	      +	      while ( read(sci_port[ch].fd, &rd , 1) > 0 )+		{+		  if (sci_port[ch].iac > 0)+		    {+		      telnet_escape(ch, rd);+		      return 1;+		    }+		  else+		    if (rd == 0xff)+		      {+			sci_port[ch].iac = 1;+			return 1;+		      }+		}+	    }+	}+    }+  return 0;+}++static void+sci(SIM_DESC sd, unsigned int cycles_diff)+{+  static int tx_end_time[MAX_SCI_CH];+  static int rx_end_time[MAX_SCI_CH];+  static int txstate = 0;+  int data;+  int ch;++  if (sci_port_type == PORT_NET && net_accept())+    return;++  for (ch = 0; ch < MAX_SCI_CH; ch++)+    {+      /* clear internal ssr */+      ssr[ch] &= SSR(ch);++      /* Tx request */+      if((SCR(ch) & 0x20) && !(ssr[ch] & 0x80) && (txstate == 0))+	{+	  sci_send_data(ch,TDR(ch));+	  ssr[ch] &= ~0x04;+	  /* TSR shift time */+	  tx_end_time[ch] = 1;+	  txstate = 1;+	}+      tx_end_time[ch] -= cycles_diff;+      /* Tx complete check */+      if(((ssr[ch] & 0x84) != 0x84) && (tx_end_time[ch] <= 0))+	if (!(ssr[ch] & 0x80))+	  {+	    ssr[ch] |= 0x80;+	    tx_end_time[ch] = sci_complete_time(sd, ch);+	    txstate = 0;+	  } +	else+	  ssr[ch] |= 0x04; /* All data transmit done */+      rx_end_time[ch] -= cycles_diff;+      /* Rx check */+      if (rx_end_time[ch] <= 0)+	/* RSR free & Rx Enabled */+	if ((SCR(ch) & 0x10) && sci_rcv_data(ch, &data))+	  {+	    /* Rx Overrun */+	    if(ssr[ch] & 0x40)+	      ssr[ch] |= 0x20;+	    else+	  /* Rx ok */+	      {+		RDR(ch)=data;+		ssr[ch] |= 0x40;+	      }+	    /* RSR shift time */+	    rx_end_time[ch] = sci_complete_time(sd, ch);+	  }++      /* update SSR */+      SSR(ch) = ssr[ch];+    }+}++static int+get_priority(SIM_DESC sd, int vec)+{+  const static int ipr_bit[] = {+    -1, -1, -1, -1, -1, -1, -1, -1,+    -1, -1, -1, -1,  7,  6,  5,  5,+     4,  4,  4,  4,  3,  3,  3,  3,+     2,  2,  2,  2,  1,  1,  1,  1,+     0,  0,  0,  0, 15, 15, 15, 15,+    14, 14, 14, 14, 13, 13, 13, 13,+    -1, -1, -1, -1, 11, 11, 11, 11,+    10, 10, 10, 10,  9,  9,  9,  9,+  };+  const static unsigned char ipr_table[] = {+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 8 - 15 */+    0x03, 0x02, 0x01, 0x00, 0x13, 0x12, 0x11, 0x10, /* 16 - 23 */+    0x23, 0x22, 0x21, 0x20, 0x33, 0x32, 0x31, 0x30, /* 24 - 31 */+    0x43, 0x42, 0x41, 0x40, 0x53, 0x53, 0x52, 0x52, /* 32 - 39 */+    0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, /* 40 - 47 */+    0x50, 0x50, 0x50, 0x50, 0x63, 0x63, 0x63, 0x63, /* 48 - 55 */+    0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, /* 56 - 63 */+    0x61, 0x61, 0x61, 0x61, 0x60, 0x60, 0x60, 0x60, /* 64 - 71 */+    0x73, 0x73, 0x73, 0x73, 0x72, 0x72, 0x72, 0x72, /* 72 - 79 */+    0x71, 0x71, 0x71, 0x71, 0x70, 0x83, 0x82, 0x81, /* 80 - 87 */+    0x80, 0x80, 0x80, 0x80, 0x93, 0x93, 0x93, 0x93, /* 88 - 95 */+    0x92, 0x92, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, /* 96 - 103 */+    0x90, 0x90, 0x90, 0x90, 0xa3, 0xa3, 0xa3, 0xa3, /* 104 - 111 */+    0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa1, 0xa1, 0xa1, /* 112 - 119 */+    0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, /* 120 - 127 */+  };+++  if (h8300smode)+    {+      unsigned short ipr;+      int pos;+      if ((pos = ipr_table[vec]) == 0xff)+	return 0;+      ipr = (STATE_CPU(sd, 0)->memory[IPRA_H8300S + ((pos & 0xf0) >> 3)] << 8) |+	    (STATE_CPU(sd, 0)->memory[IPRA_H8300S + ((pos & 0xf0) >> 3) + 1]);+      return  vec + ((ipr >> ((pos & 0x0f) * 4)) & 7) * 0x100;+    }+  else if (h8300hmode)+    {+      int b;+      unsigned char ipr;+      if ((b = ipr_bit[vec]) < 0)+	return 0;+      ipr = (b < 8)?STATE_CPU(sd, 0)->memory[IPRA_H8300H]:+	            STATE_CPU(sd, 0)->memory[IPRB_H8300H];+      b = 1 << (b & 7);+      if (ipr & b)+	return vec + 0x100;+      else+	return vec;+    }+}++static int +intcont(SIM_DESC sd)+{+  int irqno;+  for (irqno=0; int_table[irqno].vector > 0; irqno++)+    {+      if((STATE_CPU(sd, 0)->memory[int_table[irqno].ier_adr] & +	  int_table[irqno].ier_mask) &&+	 (STATE_CPU(sd, 0)->memory[int_table[irqno].isr_adr] & +	  int_table[irqno].isr_mask))+	return get_priority(sd, int_table[irqno].vector);+    }+  return 0;+}++int +iosimulation(SIM_DESC sd, int cycles)+{+  static unsigned int prev_cycles = 0;+  unsigned int cycles_diff;+  cycles_diff = (cycles < prev_cycles)?cycles:(cycles - prev_cycles);+  prev_cycles = cycles;+  timer8(sd, cycles_diff);+  if (h8300smode)+    h8300s_timer16(sd, cycles_diff);+  else if (h8300hmode)+    h8300h_timer16(sd, cycles_diff);+  sci(sd, cycles_diff);+  return intcont(sd);+}++void init_ioregs(SIM_DESC sd)+{+  struct INITTABLE {+    unsigned char addr;+    unsigned char data;+  };+  const struct INITTABLE h8300h_reg_ini[] = {+    0x80,0x00,+    0x81,0x00,+    0x82,0x00,+    0x83,0x00,+    0x84,0xff,+    0x85,0xff,+    0x86,0xff,+    0x87,0xff,+    0x88,0x00,+    0x89,0x00,+    0x90,0x00,+    0x91,0x00,+    0x92,0x00,+    0x93,0x00,+    0x94,0xff,+    0x95,0xff,+    0x96,0xff,+    0x97,0xff,+    0x98,0x00,+    0x99,0x00,+    0xb0,0x00,+    0xb1,0xff,+    0xb2,0x00,+    0xb3,0xff,+    0xb4,0x84,+    0xb8,0x00,+    0xb9,0xff,+    0xba,0x00,+    0xbb,0xff,+    0xbc,0x84,+    0xc0,0x00,+    0xc1,0xff,+    0xc2,0x00,+    0xc3,0xff,+    0xc4,0x84,+  };+  const struct INITTABLE h8300s_reg_ini[] = {+    0xb0,0x00,+    0xb1,0x00,+    0xb2,0x00,+    0xb3,0x00,+    0xb4,0xff,+    0xb5,0xff,+    0xb6,0xff,+    0xb7,0xff,+    0xb8,0x00,+    0xb9,0x00,+    0x78,0x00,+    0x79,0xff,+    0x7a,0x00,+    0x7b,0xff,+    0x7c,0x84,+    0x80,0x00,+    0x81,0xff,+    0x82,0x00,+    0x83,0xff,+    0x84,0x84,+    0x88,0x00,+    0x89,0xff,+    0x8a,0x00,+    0x8b,0xff,+    0x8c,0x84,+  };+  const struct INITTABLE h8300sx_reg_ini[] = {+    0xb0,0x00,+    0xb1,0x00,+    0xb2,0x00,+    0xb3,0x00,+    0xb4,0xff,+    0xb5,0xff,+    0xb6,0xff,+    0xb7,0xff,+    0xb8,0x00,+    0xb9,0x00,+    0x80,0x00,+    0x81,0xff,+    0x82,0x00,+    0x83,0xff,+    0x84,0x84,+    0x88,0x00,+    0x89,0xff,+    0x8a,0x00,+    0x8b,0xff,+    0x8c,0x84,+    0x60,0x00,+    0x61,0xff,+    0x62,0x00,+    0x63,0xff,+    0x64,0x84,+  };+  int c;+  if (h8300sxmode) {+    sci_base = h8300sx_sci_base;+    timer8_base = h8300s_timer8_base;+    int_table = h8300sx_int_table;+    for(c=0;c<sizeof(h8300sx_reg_ini)/sizeof(struct INITTABLE);c++)+      STATE_CPU(sd, 0)->eightbit[h8300sx_reg_ini[c].addr]=h8300sx_reg_ini[c].data;+  }+  else if (h8300smode) {+    sci_base = h8300s_sci_base;+    timer8_base = h8300s_timer8_base;+    int_table = h8300s_int_table;+    for(c=0;c<sizeof(h8300s_reg_ini)/sizeof(struct INITTABLE);c++)+      STATE_CPU(sd, 0)->eightbit[h8300s_reg_ini[c].addr]=h8300s_reg_ini[c].data;+  }+  else if (h8300hmode) {+    sci_base = h8300h_sci_base;+    timer8_base = h8300h_timer8_base;+    int_table = h8300h_int_table;+    for(c=0;c<sizeof(h8300h_reg_ini)/sizeof(struct INITTABLE);c++)+      STATE_CPU(sd, 0)->eightbit[h8300h_reg_ini[c].addr]=h8300h_reg_ini[c].data;+  }+  for(c = 0; c< MAX_SCI_CH; c++)+    ssr[c] = 0x84;+}++static char *openpty(int ch)+{+  const char nm[]="0123456789ABCDEF";+  static char ptyname[16];+  int c1,c2,fd;+  struct termios attr;+  fd = open("/dev/ptmx",O_RDWR|O_NONBLOCK);+  if(fd >= 0) {+    grantpt(fd);+    unlockpt(fd);+    ptsname_r(fd, ptyname, sizeof(ptyname));+  } else {+    for(c1='a';c1<='z';c1++)+      for(c2=0;c2<sizeof(nm)-1;c2++) {+	sprintf(ptyname,"/dev/pty%c%c",c1,nm[c2]);+	fd=open(ptyname,O_RDWR|O_NONBLOCK);+	if(fd != -1)+	  break ;+      }+    ptyname[5]='t';+  }+  if (fd >= 0) {+    sci_port[ch].fd = fd;+    tcgetattr(fd, &attr);+    memcpy(&sci_port[ch].old_attr, &attr, sizeof(struct termios));+    attr.c_lflag &= ~ICANON;+    attr.c_cc[VMIN] = 0;+    attr.c_cc[VTIME] =0;+    tcsetattr(fd, TCSAFLUSH, &attr);+    return ptyname;+  } else {+    sci_port[ch].fd = -1;+    return NULL;+  }+}++void sci_open_pty(struct host_callback_struct *callback)+{+  int ch;+  int max_ch;+  char *pty;+  for (ch = 0; ch < MAX_SCI_CH; ch++)+    {+      pty = openpty(ch);+      if (pty)+	(*callback->printf_filtered) (callback, "SCI%d = %s\n",ch ,pty);+    }+}++void sci_open_net(struct host_callback_struct *callback, int port)+{+  int c;+  int flag;+  int socketfd;+  sci_port_type = PORT_NET;+  for (c = 0; c < MAX_SCI_CH; c++) {+    memset(&sci_port[c].local, 0, sizeof(sci_port[c].local));+    sci_port[c].local.sin_family = AF_INET;+    sci_port[c].local.sin_addr.s_addr = htonl(INADDR_ANY);+    sci_port[c].local.sin_port = htons(port + c);+    sci_port[c].fd = -1;+    socketfd = socket(AF_INET, SOCK_STREAM, 0);+    if (socketfd >= 0)+      {+	bind(socketfd, (struct sockaddr *)&sci_port[c].local, sizeof(sci_port[c].local));+	flag = fcntl(socketfd, F_GETFL, 0);+	fcntl(socketfd, F_SETFL, flag | O_NONBLOCK);+	listen(socketfd, 1);+	sci_port[c].socket = socketfd;+	(*callback->printf_filtered) (callback, "SCI%d = %d\n",c ,port+c);+      }+  }+}++void sci_close(void)+{+  int ch;+  if (sci_port_type == PORT_NONE)+    return;+  for (ch = 0; ch < MAX_SCI_CH; ch++) {+    if(sci_port[ch].fd != -1) {+      if (sci_port_type == PORT_PTY)+	tcsetattr(sci_port[ch].fd, TCSAFLUSH, &sci_port[ch].old_attr);+      close(sci_port[ch].fd);+      if (sci_port_type == PORT_NET)+	close(sci_port[ch].socket);+    }+  }+}
 |