/* Copyright (C) 1998-2000 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 gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __PIC_PROCESSORS_H__ #define __PIC_PROCESSORS_H__ #include <glib.h> #include <stdio.h> #include "gpsim_classes.h" #include "modules.h" #include "processor.h" #include "program_files.h" #include "14bit-registers.h" #include "trigger.h" class EEPROM; class instruction; class Register; class sfr_register; class pic_register; class ConfigMemory; enum PROCESSOR_TYPE { _PIC_PROCESSOR_, _14BIT_PROCESSOR_, _12BIT_PROCESSOR_, _16BIT_PROCESSOR_, _P10F200_, _P10F202_, _P12C508_, _P12C509_, _P16C84_, _P16CR83_, _P16CR84_, _P12CE518_, _P12CE519_, _P16F83_, _P16F84_, _P16C71_, _P16C712_, _P16C716_, _P16C54_, _P16C55_, _P16C56_, _P16C61_, _P16C62_, _P16C62A_, _P16CR62_, _P16F627_, _P16F628_, _P16F648_, _P16C63_, _P16C64_, _P16C64A_, _P16CR64_, _P16C65_, _P16C65A_, _P16C72_, _P16C73_, _P16C74_, _P16F73_, _P16F74_, _P16F87_, _P16F88_, _P16F871_, _P16F873_, _P16F873A_, _P16F874_, _P16F874A_, _P16F876_, _P16F876A_, _P16F877_, _P16F877A_, _P17C7xx_, _P17C75x_, _P17C752_, _P17C756_, _P17C756A_, _P17C762_, _P17C766_, _P18Cxx2_, _P18C2x2_, _P18C242_, _P18F242_, _P18F248_, _P18F448_, _P18C252_, _P18F252_, _P18C442_, _P18C452_, _P18F442_, _P18F452_, _P18F1220_, _P18F1320_ }; // Configuration modes. // The configuration mode bits are the config word bits remapped. // The remapping removes processor dependent bit definitions. class ConfigMode { public: enum { CM_FOSC0 = 1<<0, // FOSC0 and FOSC1 together define the PIC clock CM_FOSC1 = 1<<1, // All PICs todate have these two bits, but the // ones with internal oscillators use them differently CM_WDTE = 1<<2, // Watch dog timer enable CM_CP0 = 1<<3, // Code Protection CM_CP1 = 1<<4, CM_PWRTE = 1<<5, // Power on/Reset timer enable CM_BODEN = 1<<6, // Brown out detection enable CM_CPD = 1<<7, CM_MCLRE = 1<<8, // MCLR enable CM_FOSC1x = 1<<9, // Hack for internal oscillators }; int config_mode; int valid_bits; ConfigMode() { config_mode = 0xffff; valid_bits = CM_FOSC0 | CM_FOSC1 | CM_WDTE; }; virtual void set_config_mode(int new_value) { config_mode = new_value & valid_bits;}; virtual void set_valid_bits(int new_value) { valid_bits = new_value;}; void set_fosc0(){config_mode |= CM_FOSC0;}; void clear_fosc0(){config_mode &= ~CM_FOSC0;}; bool get_fosc0(){return (config_mode & CM_FOSC0);}; void set_fosc1(){config_mode |= CM_FOSC1;}; void clear_fosc1(){config_mode &= ~CM_FOSC1;}; bool get_fosc1(){return (0 != (config_mode & CM_FOSC1));}; bool get_fosc1x(){return (0 != (config_mode & CM_FOSC1x));}; void set_cp0() {config_mode |= CM_CP0; valid_bits |= CM_CP0;}; void clear_cp0(){config_mode &= ~CM_CP0; valid_bits |= CM_CP0;}; bool get_cp0() {return (0 != (config_mode & CM_CP0));}; void set_cp1() {config_mode |= CM_CP1; valid_bits |= CM_CP1;}; void clear_cp1(){config_mode &= ~CM_CP1; valid_bits |= CM_CP1;}; bool get_cp1() {return (0 != (config_mode & CM_CP1));}; void enable_wdt() {config_mode |= CM_WDTE;}; void disable_wdt() {config_mode &= ~CM_WDTE;}; bool get_wdt() {return (0 != (config_mode & CM_WDTE));}; void enable_mclre() {config_mode |= CM_MCLRE;}; void disable_mclre() {config_mode &= ~CM_MCLRE;}; bool get_mclre() {return (0 != (config_mode & CM_MCLRE));}; void enable_pwrte() {config_mode |= CM_PWRTE; valid_bits |= CM_PWRTE;}; void disable_pwrte() {config_mode &= ~CM_PWRTE; valid_bits |= CM_PWRTE;}; bool get_pwrte() {return (0 != (config_mode & CM_PWRTE));}; bool is_valid_pwrte() {return (0 != (valid_bits & CM_PWRTE));}; virtual void print(); }; //--------------------------------------------------------- // Watch Dog Timer // class WDT : public TriggerObject { public: WDT(pic_processor *, double _timeout); void put(unsigned int new_value); virtual void initialize(bool enable); void set_timeout(double); virtual void reset(); void clear(); virtual void callback(); virtual void start_sleep(); virtual void new_prescale(); virtual void update(); virtual void callback_print(); void set_breakpoint(unsigned int bpn); bool hasBreak() { return breakpoint != 0;} protected: pic_processor *cpu; // The cpu to which this wdt belongs. unsigned int value, breakpoint, prescale; guint64 future_cycle; double timeout; // When no prescaler is assigned bool wdte; bool warned; }; /*================================================================== * FIXME - move these global references somewhere else */ #include "cmd_gpsim.h" extern guint64 gui_update_rate; // The rate (in simulation cycles) at which the gui is updated /*================================================================== * * Here are the base class declarations for the pic processors */ /* * First, forward-declare a few class references */ enum IOPIN_TYPES { INPUT_ONLY, // e.g. MCLR BI_DIRECTIONAL, // most iopins BI_DIRECTIONAL_PU, // same as bi_directional, but with pullup resistor. e.g. portb OPEN_COLLECTOR // bit4 in porta on the 18 pin midrange devices. }; /* * Define a base class processor for the pic processor family * * All pic processors are derived from this class. */ class pic_processor : public Processor { public: unsigned int config_word; // as read from hex or cod file ConfigMode *config_modes; // processor dependent configuration bits. unsigned int pll_factor; // 2^pll_factor is the speed boost the PLL adds // to the instruction execution rate. WDT wdt; INDF *indf; FSR *fsr; Stack *stack; Status_register *status; WREG *W; OPTION_REG option_reg; PCL *pcl; PCLATH *pclath; TMR0 tmr0; int num_of_gprs; EEPROM *eeprom; // set to NULL for PIC's that don't have a data EEPROM bool LoadProgramFile(const char *pFilename, FILE *pFile, const char *pProcessorName ); void add_sfr_register(Register *reg, unsigned int addr, RegisterValue por_value=RegisterValue(0,0),const char *new_name=0); void init_program_memory(unsigned int memory_size); void build_program_memory(int *memory,int minaddr, int maxaddr); virtual instruction * disasm ( unsigned int address,unsigned int inst)=0; virtual void create_config_memory() = 0; virtual void tris_instruction(unsigned int tris_register) {return;}; virtual void create_symbols(); virtual void create_stack() {stack = new Stack;}; virtual void run(bool refresh=true); virtual void finish(); void sleep(); virtual void enter_sleep(); void step(unsigned int steps,bool refresh=true); void step_over(bool refresh=true); virtual void step_one(bool refresh=true) { program_memory[pc->value]->execute(); } // Take a snap shot of the internal state. virtual void save_state(); virtual void interrupt() { return; }; void pm_write(); virtual bool set_config_word(unsigned int address, unsigned int cfg_word); virtual unsigned int get_config_word(unsigned int address); virtual unsigned int config_word_address() const {return 0x2007;}; virtual ConfigMode *create_ConfigMode() { return new ConfigMode; }; virtual void reset(RESET_TYPE r); virtual void por(); virtual void create(); virtual PROCESSOR_TYPE isa(){return _PIC_PROCESSOR_;}; virtual PROCESSOR_TYPE base_isa(){return _PIC_PROCESSOR_;}; /* The program_counter class calls these two functions to get the upper bits of the PC * for branching (e.g. goto) or modify PCL instructions (e.g. addwf pcl,f) */ virtual unsigned int get_pclath_branching_jump()=0; virtual unsigned int get_pclath_branching_modpcl()=0; virtual void option_new_bits_6_7(unsigned int)=0; virtual void set_eeprom(EEPROM *e); virtual EEPROM *get_eeprom() { return (eeprom); } pic_processor(const char *_name=0, const char *desc=0); virtual ~pic_processor(); protected: ConfigMemory **m_configMemory; }; #define cpu_pic ( (pic_processor *)cpu) //------------------------------------------------------------------------ // Base Class for configuration memory // // The configuration memory is only a tiny portion of the overall processor // program memory space (only 1-word on the mid range devices). So, explicit // attributes are created for each memory configuration word. Since the meaning // of configuration memory varies from processor to processor, it is up to // each process to derive from this class. class ConfigMemory : public Integer { public: ConfigMemory(const char *_name, unsigned int default_val, const char *desc, pic_processor *pCpu, unsigned int addr); protected: pic_processor *m_pCpu; unsigned int m_addr; }; #endif