File gpsim.P18F4620.patch of Package gpsim
Common subdirectories: gpsim/src//dspic and gpsim.P18F4620/src//dspic
diff -u gpsim/src//eeprom.cc gpsim.P18F4620/src//eeprom.cc
--- gpsim/src//eeprom.cc 2010-09-05 20:23:55.249756099 +0200
+++ gpsim.P18F4620/src//eeprom.cc 2010-09-02 18:04:05.996827866 +0200
@@ -611,3 +611,106 @@
EEPROM::initialize(new_rom_size);
}
+
+//------------------------------------------------------------------------
+EEPROM_LONG::EEPROM_LONG(Processor *pCpu, PIR *pPir)
+ : EEPROM_PIR(pCpu,pPir),
+ eeadrh(pCpu, "eeadrh", "EE Address High byte")
+{
+}
+
+EEPROM_LONG::~EEPROM_LONG()
+{
+
+}
+
+void EEPROM_LONG::start_write()
+{
+
+ get_cycles().set_break(get_cycles().get() + EPROM_WRITE_TIME, this);
+
+ wr_adr = eeadr.value.get() + (eeadrh.value.get() << 8);
+ wr_data = eedata.value.get();
+
+ eecon2.start_write();
+}
+
+void EEPROM_LONG::start_program_memory_read()
+{
+
+ rd_adr = eeadr.value.get() | (eeadrh.value.get() << 8);
+
+ get_cycles().set_break(get_cycles().get() + 2, this);
+
+}
+
+void EEPROM_LONG::callback()
+{
+ //cout << "eeprom call back\n";
+
+
+ switch(eecon2.get_eestate()) {
+ case EECON2::EEREAD:
+ //cout << "eeread\n";
+
+ eecon2.unarm();
+ if(eecon1.value.get() & EECON1::EEPGD) {
+ // read program memory
+
+ int opcode = cpu->pma->get_opcode(rd_adr);
+ eedata.value.put(opcode & 0xff);
+
+ } else {
+ if ((eeadr.value.get() + (eeadrh.value.get() << 8))< rom_size)
+ eedata.value.put(rom[eeadr.value.get() + (eeadrh.value.get() << 8)]->get());
+ else
+ {
+ cout << "LONG_EEPROM read adrress is out of range " << hex << eeadr.value.get() + (eeadrh.value.get() << 8) << '\n';
+ bp.halt();
+ }
+ }
+
+ eecon1.value.put(eecon1.value.get() & (~EECON1::RD));
+ break;
+
+ case EECON2::EEWRITE_IN_PROGRESS:
+ //cout << "eewrite\n";
+
+ if(eecon1.value.get() & EECON1::EEPGD) // write program memory
+ {
+ cpu->init_program_memory_at_index(wr_adr, wr_data);
+ }
+ else // read eeprom memory
+ {
+ if(wr_adr < rom_size)
+ {
+ rom[wr_adr]->value.put(wr_data);
+ }
+ else
+ {
+ cout << "LONG_EEPROM write address is out of range " << hex << wr_adr << '\n';
+ bp.halt();
+ }
+ }
+
+ write_is_complete();
+
+ if (eecon1.value.get() & eecon1.WREN)
+ eecon2.unready();
+ else
+ eecon2.unarm();
+ break;
+
+ default:
+ cout << "EEPROM_LONG::callback() bad eeprom state " << eecon2.get_eestate() << '\n';
+ bp.halt();
+ }
+}
+
+void EEPROM_LONG::initialize(unsigned int new_rom_size)
+{
+
+ eeadrh.set_eeprom(this);
+
+ EEPROM::initialize(new_rom_size);
+}
diff -u gpsim/src//eeprom.h gpsim.P18F4620/src//eeprom.h
--- gpsim/src//eeprom.h 2010-09-05 20:23:55.301756702 +0200
+++ gpsim.P18F4620/src//eeprom.h 2010-09-02 18:04:38.807827621 +0200
@@ -258,5 +258,23 @@
EEADR eeadrh;
};
+class EEPROM_LONG : public EEPROM_PIR
+{
+public:
+ EEPROM_LONG(Processor *pCpu, PIR *);
+ ~EEPROM_LONG();
+
+ virtual void start_write();
+ virtual void callback();
+ virtual void callback_print(){ cout << " EEPROM_LONG\n";}
+ virtual void start_program_memory_read();
+ virtual void initialize(unsigned int new_rom_size);
+
+ inline virtual EEADR *get_reg_eeadrh() { return (&eeadrh); }
+
+ //protected:
+ EEADR eeadrh;
+};
+
#endif /* EEPROM_H */
diff -u gpsim/src//p18x.cc gpsim.P18F4620/src//p18x.cc
--- gpsim/src//p18x.cc 2010-09-05 20:23:55.290756349 +0200
+++ gpsim.P18F4620/src//p18x.cc 2010-09-02 19:41:35.635827681 +0200
@@ -43,12 +43,15 @@
: ConfigWord("CONFIG3H", ~def_val & 0xfff, "Config Reg 3H", pCpu, addr)
{
set(def_val);
+ if (verbose)
+ cout << "Config3H_2x21\n";
}
virtual void set(gint64 v)
{
gint64 i64;
get(i64);
+ _16bit_compat_adc *m_pCpu_adc=(_16bit_compat_adc *) m_pCpu;
int diff = (i64 ^ v) &0xfff;
Integer::set(v);
@@ -56,6 +59,11 @@
{
if (diff & MCLRE)
(v & MCLRE) ? m_pCpu->assignMCLRPin(1) : m_pCpu->unassignMCLRPin();
+ if(m_pCpu_adc->adcon1) {
+ unsigned int cval=m_pCpu_adc->adcon1->get();
+ unsigned int pcfg=(v & PBADEN)?0:(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2);
+ m_pCpu_adc->adcon1->por_value=RegisterValue(cval | pcfg,0);
+ }
}
}
@@ -2224,4 +2232,114 @@
return p;
}
+//------------------------------------------------------------------------
+//
+// P18F4620
+//
+
+P18F4620::P18F4620(const char *_name, const char *desc)
+ : P18F4x21(_name,desc)
+{
+
+ if(verbose)
+ cout << "18F4620 constructor, type = " << isa() << '\n';
+
+}
+
+void P18F4620::create()
+{
+ EEPROM_LONG *e;
+
+ if(verbose)
+ cout << " 18F4620 create \n";
+
+ e = new EEPROM_LONG(this,&pir2);
+
+ e->initialize(1024);
+ //e->set_pir_set(&pir_set_def);
+ e->set_intcon(&intcon);
+
+ // assign this eeprom to the processor
+ set_eeprom_pir(e);
+
+ P18F2x21::create();
+ add_sfr_register(get_eeprom()->get_reg_eeadrh(), 0xfaa);
+
+ set_osc_pin_Number(0, 13, &(*m_porta)[7]);
+ set_osc_pin_Number(1,14, &(*m_porta)[6]);
+ m_configMemory->addConfigWord(CONFIG1H-CONFIG1L,new Config1H_4bits(this, CONFIG1H, 0x07));
+
+}
+
+Processor * P18F4620::construct(const char *name)
+{
+
+ P18F4620 *p = new P18F4620(name);
+
+ if(verbose)
+ cout << " 18F4620 construct\n";
+
+ p->create();
+ p->create_invalid_registers();
+ p->create_symbols();
+
+ if(verbose&2)
+ cout << " 18F4620 construct completed\n";
+ return p;
+}
+
+void P18F4620::osc_mode(unsigned int value)
+{
+ IOPIN *m_pin;
+ unsigned int pin_Number = get_osc_pin_Number(0);
+
+
+ set_int_osc(false);
+ if (pin_Number < 253)
+ {
+ m_pin = package->get_pin(pin_Number);
+ if (value == 7 || value == 8)
+ {
+ set_int_osc(true);
+ clr_clk_pin(pin_Number, get_osc_PinMonitor(0));
+ }
+ else
+ {
+ set_clk_pin(pin_Number, get_osc_PinMonitor(0), "OSC1", true);
+ }
+ }
+ if ( (pin_Number = get_osc_pin_Number(1)) < 253 &&
+ (m_pin = package->get_pin(pin_Number)))
+ {
+ pll_factor = 0;
+ switch(value)
+ {
+ case 6:
+ pll_factor = 2;
+ case 0:
+ case 1:
+ case 2:
+ set_clk_pin(pin_Number, get_osc_PinMonitor(1), "OSC2", true);
+ break;
+
+ case 3:
+ case 4:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ cout << "CLKO not simulated\n";
+ set_clk_pin(pin_Number, get_osc_PinMonitor(1) , "CLKO", false);
+ break;
+
+ default:
+ clr_clk_pin(pin_Number, get_osc_PinMonitor(1));
+ break;
+ }
+ }
+
+}
diff -u gpsim/src//p18x.h gpsim.P18F4620/src//p18x.h
--- gpsim/src//p18x.h 2010-09-05 20:23:55.221756418 +0200
+++ gpsim.P18F4620/src//p18x.h 2010-09-02 19:13:12.556828278 +0200
@@ -480,4 +480,29 @@
};
+/***
+PIC18F4620
+Not implemented:
+ OSCFIF bit in perifiral interrupt register 2 (PIR2v2 pir2)(And Enable Bit)
+
+***/
+class P18F4620 : public P18F4x21
+{
+ public:
+ virtual PROCESSOR_TYPE isa(){return _P18F4620_;};
+ P18F4620(const char *_name=0, const char *desc=0);
+ static Processor *construct(const char *name);
+ void create();
+
+ virtual unsigned int program_memory_size() const { return 0x8000; };
+ virtual unsigned int last_actual_register () const { return 0x0F7F;};
+ //Actually there are 18 more at unused sfr, unsure how to implement
+ virtual void osc_mode(unsigned int value);
+ virtual void set_eeprom_pir(EEPROM_LONG *ep) { eeprom = ep; }
+ virtual EEPROM_LONG *get_eeprom() { return ((EEPROM_LONG *)eeprom); }
+
+};
+
+
+
#endif
diff -u gpsim/src//pic-processor.cc gpsim.P18F4620/src//pic-processor.cc
--- gpsim/src//pic-processor.cc 2010-09-05 20:23:55.251756315 +0200
+++ gpsim.P18F4620/src//pic-processor.cc 2010-09-02 19:14:46.454827578 +0200
@@ -330,6 +330,8 @@
"__18F4455", "pic18f4455", "p18f4455", "18f4455");
ProcessorConstructor pP18F6520(P18F6520::construct,
"__18F6520", "pic18f6520", "p18f6520", "18f6520");
+ProcessorConstructor pP18F4620(P18F4620::construct,
+ "__18F4620", "pic18f4620", "p18f4620", "18f4620");
//========================================================================
diff -u gpsim/src//pic-processor.h gpsim.P18F4620/src//pic-processor.h
--- gpsim/src//pic-processor.h 2010-09-05 20:23:55.287756023 +0200
+++ gpsim.P18F4620/src//pic-processor.h 2010-09-02 19:15:29.591826931 +0200
@@ -139,6 +139,7 @@
_P18F2321_,
_P18F4321_,
_P18F6520_,
+ _P18F4620_,
};
// Configuration modes. DELETE THIS...
Common subdirectories: gpsim/src//.svn and gpsim.P18F4620/src//.svn