X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fs51.src%2Fuc51r.cc;h=cecb2469b50fc3a7963de137dde79d263d982c1a;hb=0896ad01516dd8b11172b8a9c11cc906039dae19;hp=f3f9da630ff64ca83d320676b233e437a14fef22;hpb=6ba6105dc5975c3b0cc0d1ce53f47a1ddf4be9cf;p=fw%2Fsdcc diff --git a/sim/ucsim/s51.src/uc51r.cc b/sim/ucsim/s51.src/uc51r.cc index f3f9da63..cecb2469 100644 --- a/sim/ucsim/s51.src/uc51r.cc +++ b/sim/ucsim/s51.src/uc51r.cc @@ -32,459 +32,212 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA // 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; - sfr->set(SADDR, 0); - sfr->set(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)*/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) +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])*/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); + 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])*/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); + 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; - 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); - } + 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]*/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))); - 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)]); - 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);*/ - 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)); - else - //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= *addr]; - sfr->set(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(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]*/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)); - else - ERAM[event_at.wx= /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]= - /*MEM(MEM_SFR)[*/sfr->get(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]*/sfr->get(P2) & port_pins[2])*256 + *addr, - /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC)); - else - ERAM[event_at.wx= *addr]= /*MEM(MEM_SFR)[ACC]*/sfr->get(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 */