/* Copyright (C) 1998 T. Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpasm; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // // p16x7x // // This file supports: // P16C71 // P16C712 // P16C716 // P16C72 // P16C73 // P16C74 #include #include #include #include "../config.h" #include "symbol.h" #include "p16x7x.h" #include "pic-ioports.h" #include "stimuli.h" #include "pm_rd.h" //#define DEBUG_AD //------------------------------------------------------ class P16C71::PIR_16C71 : public PIR_SET { public: PIR_16C71(ADCON0 *adcon0) : m_adcon0(adcon0) { } virtual bool interrupt_status() { return m_adcon0->getADIF(); } private: ADCON0 *m_adcon0; }; //------------------------------------------------------------------------ // P16C71::P16C71(const char *_name, const char *desc) : P16C61(_name, desc) { if(verbose) cout << "c71 constructor, type = " << isa() << '\n'; m_pir = new PIR_16C71(&adcon0); } void P16C71::create_sfr_map() { if(verbose) cout << "creating c71 registers \n"; add_sfr_register(&adcon0, 0x08, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x88, RegisterValue(0,0)); add_sfr_register(&adres, 0x89, RegisterValue(0,0)); add_sfr_register(&adres, 0x09, RegisterValue(0,0)); adres.new_name("adres"); adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1,0); adcon1.setNumberOfChannels(4); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setChannelConfiguration(0, 0x0f); adcon1.setChannelConfiguration(1, 0x0f); adcon1.setChannelConfiguration(2, 0x03); adcon1.setChannelConfiguration(3, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setA2DBits(8); intcon = &intcon_reg; intcon_reg.set_pir_set(m_pir); } void P16C71::create_symbols() { pic_processor::create_symbols(); } void P16C71::create() { P16C61::create(); create_sfr_map(); } Processor * P16C71::construct(const char *name) { P16C71 *p = new P16C71(name); if(verbose) cout << " c71 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } //-------------------------------------- void P16C712::create_sfr_map() { if(verbose) cout << "creating c712/6 registers \n"; /* Extra timers and Capture/Compare are like in 16x63 => 16X6X code */ P16X6X_processor::create_sfr_map(); /* The A/D section is similar to 16x71, but not equal */ add_sfr_register(&adcon0, 0x1F, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9F, RegisterValue(0,0)); add_sfr_register(&adres, 0x1E, RegisterValue(0,0)); //1adcon0.analog_port = porta; adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.setChannel_Mask(3); adcon0.setA2DBits(8); intcon = &intcon_reg; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1| ADCON1::PCFG2,0); adcon1.setNumberOfChannels(4); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setChannelConfiguration(0, 0x0f); adcon1.setChannelConfiguration(1, 0x0f); adcon1.setChannelConfiguration(2, 0x0f); adcon1.setChannelConfiguration(3, 0x0f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon0.new_name("adcon0"); adcon1.new_name("adcon1"); adres.new_name("adres"); } void P16C712::create() { if(verbose) cout << " c712/6 create \n"; create_iopin_map(); /* 14 bits 18 pins connections */ _14bit_processor::create(); create_sfr_map(); //1ccp1con.iopin = portb->pins[2]; } Processor * P16C712::construct(const char *name) { P16C712 *p = new P16C712(name); if(verbose) cout << " c712 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } P16C712::P16C712(const char *_name, const char *desc) : P16C62(_name, desc) { if(verbose) cout << "c712 constructor, type = " << isa() << '\n'; } //-------------------------------------- Processor * P16C716::construct(const char *name) { P16C716 *p = new P16C716(name); if(verbose) cout << " c716 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } P16C716::P16C716(const char *_name, const char *desc) : P16C712(_name, desc) { if(verbose) cout << "c716 constructor, type = " << isa() << '\n'; } //-------------------------------------- void P16C72::create_sfr_map() { if(verbose) cout << "creating c72 registers \n"; // Parent classes just set PIR version 1 pir_set_2_def.set_pir1(&pir1_2_reg); pir_set_2_def.set_pir2(&pir2_2_reg); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); // adcon0.pir_set = get_pir_set(); adcon0.pir_set = &pir_set_2_def; adcon0.setChannel_Mask(7); // even though there are only 5 inputs... adcon0.setA2DBits(8); intcon = &intcon_reg; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1| ADCON1::PCFG2, 0); adcon1.setNumberOfChannels(5); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setChannelConfiguration(0, 0x1f); adcon1.setChannelConfiguration(1, 0x1f); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon0.new_name("adcon0"); adcon1.new_name("adcon1"); adres.new_name("adres"); // Link the A/D converter to the Capture Compare Module ccp2con.setADCON(&adcon0); } void P16C72::create_symbols() { if(verbose) cout << "c72 create symbols\n"; pic_processor::create_symbols(); } void P16C72::create() { P16C62::create(); P16C72::create_sfr_map(); } Processor * P16C72::construct(const char *name) { P16C72 *p = new P16C72(name); if(verbose) cout << " c72 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } P16C72::P16C72(const char *_name, const char *desc) : P16C62(_name, desc), pir1_2_reg(&intcon_reg,&pie1), pir2_2_reg(&intcon_reg,&pie2) { if(verbose) cout << "c72 constructor, type = " << isa() << '\n'; pir1 = &pir1_2_reg; pir2 = &pir2_2_reg; } //-------------------------------------- void P16C73::create_sfr_map() { if(verbose) cout << "creating c73 registers \n"; // Parent classes just set PIR version 1 pir_set_2_def.set_pir1(&pir1_2_reg); pir_set_2_def.set_pir2(&pir2_2_reg); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); //1adcon0.analog_port = porta; //2adcon0.analog_port2 = 0; adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); // adcon0.pir_set = get_pir_set(); adcon0.pir_set = &pir_set_2_def; adcon0.setChannel_Mask(7); // even though there are only 5 inputs... adcon0.setA2DBits(8); intcon = &intcon_reg; //1adcon1.analog_port = porta; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1| ADCON1::PCFG2, 0); adcon1.setNumberOfChannels(5); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setChannelConfiguration(0, 0x1f); adcon1.setChannelConfiguration(1, 0x1f); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon0.new_name("adcon0"); adcon1.new_name("adcon1"); adres.new_name("adres"); // Link the A/D converter to the Capture Compare Module ccp2con.setADCON(&adcon0); } void P16C73::create_symbols() { if(verbose) cout << "c73 create symbols\n"; pic_processor::create_symbols(); } void P16C73::create() { P16C63::create(); P16C73::create_sfr_map(); } Processor * P16C73::construct(const char *name) { P16C73 *p = new P16C73(name); if(verbose) cout << " c73 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } P16C73::P16C73(const char *_name, const char *desc) : P16C63(_name, desc), pir1_2_reg(&intcon_reg,&pie1), pir2_2_reg(&intcon_reg,&pie2) { if(verbose) cout << "c73 constructor, type = " << isa() << '\n'; pir1 = &pir1_2_reg; pir2 = &pir2_2_reg; } //------------------------------------------------------------ void P16F73::create_sfr_map() { if(verbose) cout << "creating f73 registers \n"; add_sfr_register(pm_rd.get_reg_pmadr(), 0x10d); add_sfr_register(pm_rd.get_reg_pmadrh(), 0x10f); add_sfr_register(pm_rd.get_reg_pmdata(), 0x10c); add_sfr_register(pm_rd.get_reg_pmdath(), 0x10e); add_sfr_register(pm_rd.get_reg_pmcon1(), 0x18c); alias_file_registers(0x80,0x80,0x80); alias_file_registers(0x01,0x01,0x100); alias_file_registers(0x82,0x84,0x80); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x8a,0x8b,0x80); alias_file_registers(0x100,0x100,0x80); alias_file_registers(0x81,0x81,0x100); alias_file_registers(0x102,0x104,0x80); alias_file_registers(0x86,0x86,0x100); alias_file_registers(0x10a,0x10b,0x80); alias_file_registers(0x20,0x7f,0x100); alias_file_registers(0xa0,0xff,0x100); } void P16F73::create_symbols() { if(verbose) cout << "f73 create symbols\n"; pic_processor::create_symbols(); } void P16F73::create() { P16C73::create(); pm_rd.set_cpu(this); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F73::create_sfr_map(); } Processor * P16F73::construct(const char *name) { P16F73 *p = new P16F73(name); if(verbose) cout << " f73 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } P16F73::P16F73(const char *_name, const char *desc) : P16C73(_name, desc) { if(verbose) cout << "f73 constructor, type = " << isa() << '\n'; } //------------------------------------------------------------ // // 16C74 // void P16C74::create_sfr_map() { if(verbose) cout << "creating c74 registers \n"; // Parent classes just set PIR version 1 pir_set_2_def.set_pir1(&pir1_2_reg); pir_set_2_def.set_pir2(&pir2_2_reg); add_sfr_register(&adcon0, 0x1f, RegisterValue(0,0)); add_sfr_register(&adcon1, 0x9f, RegisterValue(0,0)); add_sfr_register(&adres, 0x1e, RegisterValue(0,0)); //1adcon0.analog_port = porta; //1adcon0.analog_port2 = porte; adcon0.setAdres(&adres); adcon0.setAdresLow(0); adcon0.setAdcon1(&adcon1); adcon0.setIntcon(&intcon_reg); adcon0.pir_set = &pir_set_2_def; adcon0.setChannel_Mask(7); adcon0.setA2DBits(8); intcon = &intcon_reg; adcon1.setValidCfgBits(ADCON1::PCFG0 | ADCON1::PCFG1 | ADCON1::PCFG2, 0); adcon1.setNumberOfChannels(8); adcon1.setIOPin(0, &(*m_porta)[0]); adcon1.setIOPin(1, &(*m_porta)[1]); adcon1.setIOPin(2, &(*m_porta)[2]); adcon1.setIOPin(3, &(*m_porta)[3]); adcon1.setIOPin(4, &(*m_porta)[5]); adcon1.setIOPin(5, &(*m_porte)[0]); adcon1.setIOPin(6, &(*m_porte)[1]); adcon1.setIOPin(7, &(*m_porte)[2]); adcon1.setChannelConfiguration(0, 0xff); adcon1.setChannelConfiguration(1, 0xff); adcon1.setChannelConfiguration(2, 0x1f); adcon1.setChannelConfiguration(3, 0x1f); adcon1.setChannelConfiguration(4, 0x0b); adcon1.setChannelConfiguration(5, 0x0b); adcon1.setChannelConfiguration(6, 0x00); adcon1.setChannelConfiguration(7, 0x00); adcon1.setVrefHiConfiguration(1, 3); adcon1.setVrefHiConfiguration(3, 3); adcon1.setVrefHiConfiguration(5, 3); adcon0.new_name("adcon0"); adcon1.new_name("adcon1"); adres.new_name("adres"); // Link the A/D converter to the Capture Compare Module ccp2con.setADCON(&adcon0); } void P16C74::create_symbols() { if(verbose) cout << "c74 create symbols\n"; Pic14Bit::create_symbols(); } void P16C74::create() { P16C65::create(); P16C74::create_sfr_map(); } Processor * P16C74::construct(const char *name) { P16C74 *p = new P16C74(name);; if(verbose) cout << " c74 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } P16C74::P16C74(const char *_name, const char *desc) : P16C65(_name, desc) , pir1_2_reg(&intcon_reg,&pie1), pir2_2_reg(&intcon_reg,&pie2) { if(verbose) cout << "c74 constructor, type = " << isa() << '\n'; pir1 = &pir1_2_reg; pir2 = &pir2_2_reg; } //------------------------------------------------------------ void P16F74::create_sfr_map() { if(verbose) cout << "creating f74 registers \n"; add_sfr_register(pm_rd.get_reg_pmadr(), 0x10d); add_sfr_register(pm_rd.get_reg_pmadrh(), 0x10f); add_sfr_register(pm_rd.get_reg_pmdata(), 0x10c); add_sfr_register(pm_rd.get_reg_pmdath(), 0x10e); add_sfr_register(pm_rd.get_reg_pmcon1(), 0x18c); alias_file_registers(0x80,0x80,0x80); alias_file_registers(0x01,0x01,0x100); alias_file_registers(0x82,0x84,0x80); alias_file_registers(0x06,0x06,0x100); alias_file_registers(0x8a,0x8b,0x80); alias_file_registers(0x100,0x100,0x80); alias_file_registers(0x81,0x81,0x100); alias_file_registers(0x102,0x104,0x80); alias_file_registers(0x86,0x86,0x100); alias_file_registers(0x10a,0x10b,0x80); alias_file_registers(0x20,0x7f,0x100); alias_file_registers(0xa0,0xff,0x100); } void P16F74::create_symbols() { if(verbose) cout << "f74 create symbols\n"; pic_processor::create_symbols(); } void P16F74::create() { P16C74::create(); pm_rd.set_cpu(this); status->rp_mask = 0x60; // rp0 and rp1 are valid. indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100 indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100 P16F74::create_sfr_map(); } Processor * P16F74::construct(const char *name) { P16F74 *p = new P16F74(name); if(verbose) cout << " f74 construct\n"; p->create(); p->create_invalid_registers (); p->create_symbols(); symbol_table.add_module(p,p->name().c_str()); return p; } P16F74::P16F74(const char *_name, const char *desc) : P16C74(_name, desc) { if(verbose) cout << "f74 constructor, type = " << isa() << '\n'; }