// local
#include "uc51rcl.h"
#include "regs51.h"
+#include "types51.h"
+#include "wdtcl.h"
/*
* Making an 8051r CPU object
*/
-t_uc51r::t_uc51r(int Itype, int Itech, class cl_sim *asim):
- t_uc52(Itype, Itech, asim)
+cl_uc51r::cl_uc51r(int Itype, int Itech, class cl_sim *asim):
+ cl_uc52(Itype, Itech, asim)
{
- int i;
-
+ /* int i;
for (i= 0; i < ERAM_SIZE; i++)
- ERAM[i]= 0;
+ ERAM[i]= 0;*/
clock_out= 0;
}
-/*
- * Resetting of the microcontroller
- *
- * Original method is extended with handling of WDT.
- */
-
-void
-t_uc51r::reset(void)
-{
- t_uc52::reset();
- WDT= -1; // Disable WDT
- wdtrst= 0;
- MEM(MEM_SFR)[SADDR]= MEM(MEM_SFR)[SADEN]= 0;
-}
-
-
-/*
- * Copying ERAM to XRAM and vice versa
- *
- * This two methods are used by command interpreter to make ERAM and
- * beginning of XRAM to be equivalent.
- */
-
-void
-t_uc51r::eram2xram(void)
-{
- int i;
-
- for (i= 0; i < ERAM_SIZE; i++)
- set_mem(MEM_XRAM, i, ERAM[i]);
-}
-
void
-t_uc51r::xram2eram(void)
+cl_uc51r::mk_hw_elements(void)
{
- int i;
+ class cl_hw *h;
- for (i= 0; i < ERAM_SIZE; i++)
- ERAM[i]= get_mem(MEM_XRAM, i);
+ cl_uc52::mk_hw_elements();
+ hws->add(h= new cl_wdt(this, 0x3fff));
+ h->init();
+ hws->add(h= new cl_uc51r_dummy_hw(this));
+ h->init();
}
-/*
- * 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)[WDTRST]))
- {
- if ((wdtrst == 0x1e) &&
- (*addr == 0xe1))
- {
- WDT= 0;
- sim->cmd->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)
+cl_uc51r::make_memories(void)
{
- int res;
-
- if ((res= t_uc51::do_timers(cycles)) != resGO)
- return(res);
- return(do_timer2(cycles));
+ class cl_address_space *as;
+
+ rom= as= new cl_address_space("rom", 0, 0x10000, 8);
+ as->init();
+ address_spaces->add(as);
+ iram= as= new cl_address_space("iram", 0, 0x100, 8);
+ as->init();
+ address_spaces->add(as);
+ sfr= as= new cl_address_space("sfr", 0x80, 0x80, 8);
+ as->init();
+ address_spaces->add(as);
+ xram= as= new cl_address_space("xram", 0, 0x10000, 8);
+ as->init();
+ address_spaces->add(as);
+
+ class cl_address_decoder *ad;
+ class cl_memory_chip *chip;
+
+ chip= new cl_memory_chip("rom_chip", 0x10000, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("rom"), chip, 0, 0xffff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+
+ chip= new cl_memory_chip("iram_chip", 0x100, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("iram"), chip, 0, 0xff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+
+ chip= new cl_memory_chip("xram_chip", 0x10000, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("xram"), chip, 0, 0xffff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+ chip= new cl_memory_chip("eram_chip", 0x100, 8);
+ chip->init();
+ memchips->add(chip);
+
+ chip= new cl_memory_chip("sfr_chip", 0x80, 8);
+ chip->init();
+ memchips->add(chip);
+ ad= new cl_address_decoder(as= address_space("sfr"), chip, 0x80, 0xff, 0);
+ ad->init();
+ as->decoders->add(ad);
+ ad->activate(0);
+
+ acc= sfr->get_cell(ACC);
+ psw= sfr->get_cell(PSW);
}
/*
- * Simulating timer 2
+ * Resetting of the microcontroller
*
- * It is something wrong: T2MOD is not implemented in 52?!
+ * Original method is extended with handling of WDT.
*/
-int
-t_uc51r::do_timer2(int cycles)
+void
+cl_uc51r::reset(void)
{
- 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]))
- if (!++(MEM(MEM_SFR)[TH2]))
- {
- overflow++;
- MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
- MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
- mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
- }
- }
- else
- {
- // DOWN
- MEM(MEM_SFR)[TL2]--;
- if (MEM(MEM_SFR)[TL2] == 0xff)
- MEM(MEM_SFR)[TH2]--;
- if (MEM(MEM_SFR)[TH2] == MEM(MEM_SFR)[RCAP2H] &&
- MEM(MEM_SFR)[TL2] == MEM(MEM_SFR)[RCAP2L])
- {
- overflow++;
- MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[TL2]= 0xff;
- mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
- }
- }
- while (overflow--)
- MEM(MEM_SFR)[P1]^= bmEXF2;
- }
- }
- else
- /* DCEN= 0 */
- do_t2_reload(&cycles, nocount);
- }
- }// while cycles
-
- return(resGO);
+ cl_uc52::reset();
+ sfr->write(SADDR, 0);
+ sfr->write(SADEN, 0);
+ sfr->write(AUXR, 0);
}
-
-/*
- * Clock out mode of Timer #2
- */
-
-int
-t_uc51r::do_t2_clockout(int cycles)
+void
+cl_uc51r::clear_sfr(void)
{
- 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]))
- if (!++(MEM(MEM_SFR)[TH2]))
- {
- MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
- MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
- clock_out++;
- if (!(t2con & bmC_T2))
- {
- SET_BIT((clock_out&1), P1, bmT2);
- }
- }
- }
- return(resGO);
+ cl_uc52::clear_sfr();
+ sfr->write(SADDR, 0);
+ sfr->write(SADEN, 0);
+ sfr->write(AUXR, 0);
+ sfr->write(IPH, 0);
}
-/*
- * 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)
+cl_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);
+ sfr->set_bit1(SCON, bmRI);
}
/*
- * Handling WDT
*/
+cl_uc51r_dummy_hw::cl_uc51r_dummy_hw(class cl_uc *auc):
+ cl_hw(auc, HW_DUMMY, 0, "_51r_dummy")
+{}
+
int
-t_uc51r::do_wdt(int cycles)
+cl_uc51r_dummy_hw::init(void)
{
- if (WDT >= 0)
+ class cl_address_space *sfr= uc->address_space(MEM_SFR_ID);
+ if (!sfr)
{
- WDT+= cycles;
-fprintf(stderr,"WDT=%d\n",WDT);
- if (WDT & ~(0x3fff))
- {
- sim->cmd->debug("%g sec (%d ticks): "
- "Watchdog timer resets the CPU, PC= 0x%06x\n",
- get_rtime(), ticks->ticks, PC);
- reset();
- return(resWDTRESET);
- }
+ fprintf(stderr, "No SFR to register %s[%d] into\n", id_string, id);
}
- return(resGO);
-}
-
-
-/*
- * 0xe0 1 24 MOVX A,@DPTR
- *____________________________________________________________________________
- *
- */
-
-int
-t_uc51r::inst_movx_a_$dptr(uchar code)
-{
- if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
- MEM(MEM_SFR)[DPH])
- MEM(MEM_SFR)[event_at.ws= ACC]= read_mem(MEM_XRAM,
- event_at.rx=
- MEM(MEM_SFR)[DPH]*256+
- MEM(MEM_SFR)[DPL]);
- else
- MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= MEM(MEM_SFR)[DPL]];
- tick(1);
- return(resGO);
+ //use_cell(sfr, PSW, &cell_psw, wtd_restore);
+ register_cell(sfr, AUXR, &cell_auxr, wtd_restore);
+ return(0);
}
-
-/*
- * 0xe2-0xe3 1 24 MOVX A,@Ri
- *____________________________________________________________________________
- *
- */
-
-int
-t_uc51r::inst_movx_a_$ri(uchar code)
+void
+cl_uc51r_dummy_hw::write(class cl_memory_cell *cell, t_mem *val)
{
- 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);
- else
- MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= *addr];
- tick(1);
- return(res);
+ if (cell == cell_auxr)
+ {
+ class cl_address_space *xram= uc->address_space(MEM_XRAM_ID);
+ class cl_memory_chip *eram=
+ dynamic_cast<class cl_memory_chip *>(uc->memory("eram_chip"));
+ class cl_address_decoder *d;
+ if (eram &&
+ xram)
+ {
+ if (*val & bmEXTRAM)
+ d= new cl_address_decoder(xram, uc->memory("xram_chip"), 0,0xff,0);
+ else
+ d= new cl_address_decoder(xram, eram, 0, 0xff, 0);
+ d->init();
+ xram->decoders->add(d);
+ d->activate(0);
+ }
+ }
+ /*else if (cell == cell_pcon)
+ {
+ printf("PCON write 0x%x (PC=0x%x)\n", *val, uc->PC);
+ uc->sim->stop(0);
+ }*/
}
-
-/*
- * 0xf0 1 24 MOVX @DPTR,A
- *____________________________________________________________________________
- *
- */
-
-int
-t_uc51r::inst_movx_$dptr_a(uchar code)
+/*void
+cl_uc51r_dummy_hw::happen(class cl_hw *where, enum hw_event he, void *params)
{
- if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
- MEM(MEM_SFR)[DPH])
- write_mem(MEM_XRAM,
- event_at.wx= MEM(MEM_SFR)[DPH]*256+MEM(MEM_SFR)[DPL],
- MEM(MEM_SFR)[event_at.rs= ACC]);
- else
- ERAM[event_at.wx= MEM(MEM_SFR)[DPL]]= MEM(MEM_SFR)[event_at.rs= ACC];
- return(resGO);
-}
-
+ struct ev_port_changed *ep= (struct ev_port_changed *)params;
-/*
- * 0xf2-0xf3 1 24 MOVX @Ri,A
- *____________________________________________________________________________
- *
- */
-
-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] & port_pins[2])*256 + *addr,
- MEM(MEM_SFR)[ACC]);
- else
- ERAM[event_at.wx= *addr]= MEM(MEM_SFR)[ACC];
- tick(1);
- return(res);
-}
+ if (where->cathegory == HW_PORT &&
+ he == EV_PORT_CHANGED &&
+ ep->id == 3)
+ {
+ t_mem p3o= ep->pins & ep->prev_value;
+ t_mem p3n= ep->new_pins & ep->new_value;
+ if ((p3o & bm_INT0) &&
+ !(p3n & bm_INT0))
+ uc51->p3_int0_edge++;
+ if ((p3o & bm_INT1) &&
+ !(p3n & bm_INT1))
+ uc51->p3_int1_edge++;
+ }
+}*/
/* End of s51.src/uc51r.cc */