Merge branch ucsim-034-pre3 to main trunk; new version 0.4
[fw/sdcc] / sim / ucsim / s51.src / uc51r.cc
index f3f9da630ff64ca83d320676b233e437a14fef22..44a2c9950ebb7a8f94d2eafc7ad4ed7c6ef95aa5 100644 (file)
@@ -32,6 +32,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 // local
 #include "uc51rcl.h"
 #include "regs51.h"
+#include "types51.h"
+#include "wdtcl.h"
 
 
 /*
@@ -49,6 +51,17 @@ t_uc51r::t_uc51r(int Itype, int Itech, class cl_sim *asim):
 }
 
 
+void
+t_uc51r::mk_hw_elements(void)
+{
+  class cl_hw *h;
+
+  t_uc52::mk_hw_elements();
+  hws->add(h= new cl_wdt(this, 0x3fff));
+  h->init();
+}
+
+
 /*
  * Resetting of the microcontroller
  *
@@ -59,9 +72,6 @@ void
 t_uc51r::reset(void)
 {
   t_uc52::reset();
-  WDT= -1; // Disable WDT
-  wdtrst= 0;
-  //MEM(MEM_SFR)[SADDR]= MEM(MEM_SFR)[SADEN]= 0;
   sfr->set(SADDR, 0);
   sfr->set(SADEN, 0);
 }
@@ -93,293 +103,24 @@ t_uc51r::xram2eram(void)
 }
 
 
-/*
- * Processing write operation of SFR
- *
- * Inherited method is extended with WDT handling.
- */
-
-void
-t_uc51r::proc_write(uchar *addr)
-{
-  t_uc52::proc_write(addr);
-  // Handling WDT
-  if (addr == &(/*MEM(MEM_SFR)*/sfr->umem8[WDTRST]))
-    {
-      if ((wdtrst == 0x1e) &&
-         (*addr == 0xe1))
-       {
-         WDT= 0;
-         sim->app->get_commander()->
-           debug("%g sec (%d tick): Watchdog timer enabled/reset PC= 0x%06x"
-                 "\n", get_rtime(), ticks->ticks, PC);
-       }
-      wdtrst= *addr;
-    }
-}
-
-
-/*
- * Simulating timers
- *
- * Calling inherited method to simulate timer #0 and #1 and then 
- * simulating timer #2.
- */
-
-int
-t_uc51r::do_timers(int cycles)
-{
-  int res;
-
-  if ((res= t_uc51::do_timers(cycles)) != resGO)
-    return(res);
-  return(do_timer2(cycles));
-}
-
-
-/*
- * Simulating timer 2
- *
- * It is something wrong: T2MOD is not implemented in 52?!
- */
-
-int
-t_uc51r::do_timer2(int cycles)
-{
-  bool nocount= DD_FALSE;
-  uint t2mod= get_mem(MEM_SFR, T2MOD);
-  uint t2con= get_mem(MEM_SFR, T2CON);
-  uint p1= get_mem(MEM_SFR, P1);
-
-  exf2it->activate();
-  if (!(t2con & bmTR2))
-    /* Timer OFF */
-    return(resGO);
-
-  if (t2mod & bmT2OE)
-    return(do_t2_clockout(cycles));
-
-  if (t2con & (bmRCLK | bmTCLK))
-    return(do_t2_baud(cycles));
-
-  /* Determining nr of input clocks */
-  if (!(t2con & bmTR2))
-    nocount= DD_TRUE; // Timer OFF
-  else
-    if (t2con & bmC_T2)
-      {
-       // Counter mode, falling edge on P1.0 (T2)
-       if ((prev_p1 & bmT2) &&
-           !(p1 & port_pins[1] & bmT2))
-         cycles= 1;
-       else
-         nocount= DD_TRUE;
-      }
-  /* Counting */
-  while (cycles--)
-    {
-      if (t2con & bmCP_RL2)
-       do_t2_capture(&cycles, nocount);
-      else
-       {
-         int overflow;
-         overflow= 0;
-         /* Auto-Relode mode */
-         if (t2mod & bmDCEN)
-           {
-             /* DCEN= 1 */
-             exf2it->deactivate();
-             if (nocount)
-               cycles= 0;
-             else
-               {
-                 if (p1 & port_pins[1] & bmT2EX)
-                   {
-                     // UP
-                     if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1))
-                       if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1))
-                         {
-                           overflow++;
-                           //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
-                           sfr->set(TH2, sfr->get(RCAP2H));
-                           //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
-                           sfr->set(TL2, sfr->get(RCAP2L));
-                           mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
-                         }
-                   }
-                 else
-                   {
-                     // DOWN
-                     //MEM(MEM_SFR)[TL2]--;
-                     if (/*MEM(MEM_SFR)[TL2]*/sfr->add(TL2, -1) == 0xff)
-                       /*MEM(MEM_SFR)[TH2]--*/sfr->add(TH2, -1);
-                     /*if (MEM(MEM_SFR)[TH2] == MEM(MEM_SFR)[RCAP2H] &&
-                       MEM(MEM_SFR)[TL2] == MEM(MEM_SFR)[RCAP2L])*/
-                     if (sfr->get(TH2) == sfr->get(RCAP2H) &&
-                         sfr->get(TL2) == sfr->get(RCAP2L))
-                       {
-                         overflow++;
-                         //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[TL2]= 0xff;
-                         sfr->set(TH2, 0xff);
-                         sfr->set(TL2, 0xff);
-                         mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
-                       }
-                   }
-                 while (overflow--)
-                   //MEM(MEM_SFR)[P1]^= bmEXF2;
-                   sfr->set(P1, sfr->get(P1) ^ bmEXF2);
-               }
-           }
-         else
-           /* DCEN= 0 */
-           do_t2_reload(&cycles, nocount);
-       }
-    }// while cycles
-
-  return(resGO);
-}
-
-
-/*
- * Clock out mode of Timer #2
- */
-
-int
-t_uc51r::do_t2_clockout(int cycles)
-{
-  uint t2con= get_mem(MEM_SFR, T2CON);
-  uint p1= get_mem(MEM_SFR, P1);
-
-  /* Programmable Clock Out Mode */
-  if ((prev_p1 & bmT2EX) &&
-      !(p1 & port_pins[1] & bmT2EX) &&
-      (t2con & bmEXEN2))
-    mem(MEM_SFR)->set_bit1(T2CON, bmEXF2);
-  if (t2con & bmCP_RL2)
-    return(resGO);
-  if (t2con & bmC_T2)
-    {
-      if ((prev_p1 & bmT2) &&
-         !(p1 & port_pins[1] & bmT2))
-       cycles= 1;
-      else
-       cycles= 0;
-    }
-  else
-    cycles*= 6;
-  if (t2con & bmTR2)
-    while (cycles--)
-      {
-       if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1))
-         if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1))
-           {
-             //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
-             sfr->set(TH2, sfr->get(RCAP2H));
-             //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
-             sfr->set(TL2, sfr->get(RCAP2L));
-             clock_out++;
-             if (!(t2con & bmC_T2))
-               {
-                 SET_BIT((clock_out&1), P1, bmT2);
-               }
-           }
-      }
-  return(resGO);
-}
-
-
-/*
- * Handling serial line
- */
-
-int
-t_uc51r::serial_bit_cnt(int mode)
-{
-  int divby= 12;
-  int *tr_src= 0, *rec_src= 0;
-
-  switch (mode)
-    {
-    case 0:
-      divby  = 12;
-      tr_src = &s_tr_tick;
-      rec_src= &s_rec_tick;
-      break;
-    case 1:
-    case 3:
-      divby  = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32;
-      tr_src = (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_tr_t2):(&s_tr_t1);
-      rec_src= (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_rec_t2):(&s_rec_t1);
-      break;
-    case 2:
-      divby  = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32;
-      tr_src = &s_tr_tick;
-      rec_src= &s_rec_tick;
-      break;
-    }
-  if (s_sending)
-    {
-      while (*tr_src >= divby)
-       {
-         (*tr_src)-= divby;
-         s_tr_bit++;
-       }
-    }
-  if (s_receiving)
-    {
-      while (*rec_src >= divby)
-       {
-         (*rec_src)-= divby;
-         s_rec_bit++;
-       }
-    }
-  return(0);
-}
-
 void
 t_uc51r::received(int c)
 {
-  uint br= get_mem(MEM_SFR, SADDR) | get_mem(MEM_SFR, SADEN);
-  int scon= get_mem(MEM_SFR, SCON);
+  t_mem br= sfr->get(SADDR) | sfr->get(SADEN);
+  int scon= sfr->get(SCON);
 
   if ((0 < scon >> 6) &&
       (scon & bmSM2))
     {
-      if (
-         /* Check for individual address */
-         ((get_mem(MEM_SFR, SADDR) & get_mem(MEM_SFR, SADEN)) ==
-         (c & get_mem(MEM_SFR, SADEN)))
+      if (/* Check for individual address */
+         ((sfr->get(SADDR) & sfr->get(SADEN)) == (c & sfr->get(SADEN)))
          ||
          /* Check for broadcast address */
-         (br == (br & c))
-         )
-       mem(MEM_SFR)->set_bit1(SCON, bmRI);
+         (br == (br & c)))
+       sfr->set_bit1(SCON, bmRI);
       return;
     }
-  mem(MEM_SFR)->set_bit1(SCON, bmRI);
-}
-
-
-/*
- * Handling WDT
- */
-
-int
-t_uc51r::do_wdt(int cycles)
-{
-  if (WDT >= 0)
-    {
-      WDT+= cycles;
-      if (WDT & ~(0x3fff))
-       {
-         sim->app->get_commander()->
-           debug("%g sec (%d ticks): Watchdog timer resets the CPU, "
-                 "PC= 0x%06x\n", get_rtime(), ticks->ticks, PC);
-         reset();
-         return(resWDTRESET);
-       }
-    }
-  return(resGO);
+  sfr->set_bit1(SCON, bmRI);
 }
 
 
@@ -392,20 +133,13 @@ t_uc51r::do_wdt(int cycles)
 int
 t_uc51r::inst_movx_a_$dptr(uchar code)
 {
-  if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
-      /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH))
-    /*MEM(MEM_SFR)[event_at.ws= ACC]= read_mem(MEM_XRAM,
-                                            event_at.rx=
-                                            MEM(MEM_SFR)[DPH]*256+
-                                            MEM(MEM_SFR)[DPL]);*/
-    sfr->set(event_at.ws= ACC, read_mem(MEM_XRAM,
-                                       event_at.rx=
-                                       /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256+
-                                       /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)));
+  if ((sfr->get(AUXR) & bmEXTRAM) ||
+      sfr->get(DPH))
+    acc->write(read_mem(MEM_XRAM,
+                       sfr->read(DPH)*256+
+                       sfr->read(DPL)));
   else
-    //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= MEM(MEM_SFR)[DPL]];
-    sfr->set(event_at.ws= ACC, ERAM[event_at.rx=
-                                  /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]);
+    acc->write(ERAM[sfr->read(DPL)]);
   tick(1);
   return(resGO);
 }
@@ -420,23 +154,17 @@ t_uc51r::inst_movx_a_$dptr(uchar code)
 int
 t_uc51r::inst_movx_a_$ri(uchar code)
 {
-  uchar *addr;
-  int res;
-
-  addr= get_indirect(*(get_reg(code & 0x01)), &res);
-  if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
-    /*MEM(MEM_SFR)[event_at.ws= ACC]=
-      read_mem(MEM_XRAM,
-      event_at.rx= (MEM(MEM_SFR)[P2]&port_pins[2])*256+*addr);*/
-    sfr->set(event_at.ws= ACC,
-            read_mem(MEM_XRAM,
-                     event_at.rx=
-                     (/*MEM(MEM_SFR)[P2]*/sfr->get(P2)&port_pins[2])*256+*addr));
+  class cl_cell *cell;
+  t_mem d= 0;
+
+  cell= iram->get_cell(get_reg(code & 0x01)->read());
+  d= cell->read();
+  if (sfr->get(AUXR) & bmEXTRAM)
+    acc->write(read_mem(MEM_XRAM, sfr->read(P2)*256+d));
   else
-    //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= *addr];
-    sfr->set(event_at.ws= ACC, ERAM[event_at.rx= *addr]);
+    acc->write(ERAM[d]);
   tick(1);
-  return(res);
+  return(resGO);
 }
 
 
@@ -449,15 +177,11 @@ t_uc51r::inst_movx_a_$ri(uchar code)
 int
 t_uc51r::inst_movx_$dptr_a(uchar code)
 {
-  if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
-      /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH))
-    write_mem(MEM_XRAM,
-             event_at.wx= /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256 +
-                          /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL),
-             /*MEM(MEM_SFR)[event_at.rs= ACC]*/sfr->get(event_at.rs= ACC));
+  if ((sfr->get(AUXR) & bmEXTRAM) ||
+      sfr->get(DPH))
+    write_mem(MEM_XRAM, sfr->read(DPH)*256 + sfr->read(DPL), acc->read());
   else
-    ERAM[event_at.wx= /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]=
-      /*MEM(MEM_SFR)[*/sfr->get(event_at.rs= ACC)/*]*/;
+    ERAM[sfr->read(DPL)]= acc->read();
   return(resGO);
 }
 
@@ -471,19 +195,17 @@ t_uc51r::inst_movx_$dptr_a(uchar code)
 int
 t_uc51r::inst_movx_$ri_a(uchar code)
 {
-  uchar *addr;
-  int res;
-
-  addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res);
-  if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
-    write_mem(MEM_XRAM,
-             event_at.wx=
-             (/*MEM(MEM_SFR)[P2]*/sfr->get(P2) & port_pins[2])*256 + *addr,
-             /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC));
+  class cl_cell *cell;
+  t_mem d= 0;
+
+  cell= iram->get_cell(get_reg(code & 0x01)->read());
+  d= cell->read();
+  if (sfr->get(AUXR) & bmEXTRAM)
+    write_mem(MEM_XRAM, sfr->read(P2)*256 + d, acc->read());
   else
-    ERAM[event_at.wx= *addr]= /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC);
+    ERAM[d]= acc->read();
   tick(1);
-  return(res);
+  return(resGO);
 }