/* Copyright (C) 1998-2003 Scott Dattalo 2003 Mike Durian 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 gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef EEPROM_H #define EEPROM_H #include #include "gpsim_classes.h" #include "registers.h" #include "breakpoints.h" class pic_processor; class EEPROM; class PIR_SET; class INTCON; class PIR; //--------------------------------------------------------- // EECON1 - EE control register 1 // class EECON1 : public sfr_register { public: enum { RD = (1<<0), WR = (1<<1), WREN = (1<<2), WRERR = (1<<3), EEIF = (1<<4), EEPGD = (1<<7) }; EECON1(void); void put(unsigned int new_value); unsigned int get(void); inline void set_eeprom(EEPROM *ee) { eeprom = ee; } inline void set_valid_bits(unsigned int vb) { valid_bits = valid_bits; } inline unsigned int get_valid_bits(void) { return (valid_bits); } inline void set_bits(unsigned int b) { valid_bits |= b; } inline void clear_bits(unsigned int b) { valid_bits &= ~b; } //private: unsigned int valid_bits; EEPROM *eeprom; }; const unsigned int EECON1_VALID_BITS = (EECON1::RD | EECON1::WR | EECON1::WREN | EECON1::EEIF); // // EECON2 - EE control register 2 // class EECON2 : public sfr_register { public: enum EE_STATES { EENOT_READY, EEHAVE_0x55, EEREADY_FOR_WRITE, EEWRITE_IN_PROGRESS, EEUNARMED, EEREAD }; EECON2(void); void put(unsigned int new_value); unsigned int get(void); void ee_reset(void) { eestate = EENOT_READY;}; inline virtual void set_eeprom(EEPROM *ee) { eeprom = ee; } inline enum EE_STATES get_eestate(void) { return (eestate); } inline void unarm(void) { eestate = EEUNARMED; } inline void unready(void) { eestate = EENOT_READY; } inline void read(void) { eestate = EEREAD; } inline void start_write(void) { eestate = EEWRITE_IN_PROGRESS; } inline bool is_unarmed(void) { return (eestate == EEUNARMED); } inline bool is_not_ready(void) { return (eestate == EENOT_READY); } inline bool is_ready_for_write(void) { return (eestate == EEREADY_FOR_WRITE); } inline bool is_writing(void) { return (eestate == EEWRITE_IN_PROGRESS); } //private: EEPROM *eeprom; enum EE_STATES eestate; }; // // EEDATA - EE data register // class EEDATA : public sfr_register { public: EEDATA(void); void put(unsigned int new_value); unsigned int get(void); virtual void set_eeprom(EEPROM *ee) { eeprom = ee; } //private: EEPROM *eeprom; }; // // EEADR - EE address register // class EEADR : public sfr_register { public: EEADR(void); void put(unsigned int new_value); unsigned int get(void); virtual void set_eeprom(EEPROM *ee) { eeprom = ee; } //private: EEPROM *eeprom; }; //------------------------------------------------------------------------ //------------------------------------------------------------------------ const int EPROM_WRITE_TIME = 20; class EEPROM : public TriggerObject { public: EEPROM(void); void reset(RESET_TYPE); virtual void set_cpu(pic_processor *p) { cpu = p; } virtual void set_intcon(INTCON *ic); virtual void callback(void); virtual void start_write(void); virtual void write_is_complete(void); virtual void start_program_memory_read(void); virtual void initialize(unsigned int new_rom_size); virtual Register *get_register(unsigned int address); virtual void save_state(); inline virtual void change_rom(unsigned int offset, unsigned int val) { assert(offset < rom_size); rom[offset]->value.put(val); } inline virtual unsigned int get_rom_size(void) { return (rom_size); } // XXX might want to make get_rom a friend only to cli_dump inline virtual Register **get_rom(void) { return (rom); } inline virtual EECON1 *get_reg_eecon1(void) { return (&eecon1); } inline virtual EECON2 *get_reg_eecon2(void) { return (&eecon2); } inline virtual EEDATA *get_reg_eedata(void) { return (&eedata); } inline virtual EEADR *get_reg_eeadr(void) { return (&eeadr); } void dump(void); //protected: char *name_str; pic_processor *cpu; INTCON *intcon; EECON1 eecon1; // The EEPROM consists of 4 control registers EECON2 eecon2; // on the F84 and 6 on the F877 EEDATA eedata; EEADR eeadr; Register **rom; // and the data area. RegisterCollection *m_UiAccessOfRom; // User access to the rom. unsigned int rom_size; unsigned int wr_adr,wr_data; // latched adr and data for eewrites. unsigned int rd_adr; // latched adr for eereads. unsigned int abp; // break point number that's set during eewrites }; class EEPROM_PIR : public EEPROM { public: EEPROM_PIR(PIR *); // virtual void set_pir_set(PIR_SET *p); // the 16f628 eeprom is identical to the 16f84 eeprom except // for the size and the location of EEIF. The size is taken // care of when the '628 is constructed, the EEIF is taken // care of here: virtual void write_is_complete(); protected: PIR *m_pir; }; class EEPROM_WIDE : public EEPROM_PIR { public: EEPROM_WIDE(PIR *); virtual void start_write(void); virtual void callback(void); virtual void start_program_memory_read(void); virtual void initialize(unsigned int new_rom_size); inline virtual EEDATA *get_reg_eedatah(void) { return (&eedatah); } inline virtual EEADR *get_reg_eeadrh(void) { return (&eeadrh); } //protected: EEDATA eedatah; EEADR eeadrh; }; #endif /* EEPROM_H */