/*
Copyright (C) 2006 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. */
#include "dspic-processors.h"
#include "dspic-registers.h"
#include <stdio.h>
#include "../symbol.h"
#include "../program_files.h"
#include "../packages.h"
#include "../trace.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Globals
//
using namespace dspic;
using namespace dspic_registers;
ProcessorConstructor pdsPic30F6010(dsPic30F6010::construct ,
"__30f6010", "dspic30f6010", "30f6010", "30f610");
namespace dspic {
Trace *gTrace=0; // Points to gpsim's global trace object.
Cycle_Counter *gCycles=0; // Points to gpsim's global cycle counter.
//-------------------------------------------------------------------
//
// dsPicProcessor -- constructor.
dsPicProcessor::dsPicProcessor(const char *_name, const char *desc)
: Processor(_name, desc)
{
gTrace = &get_trace();
gCycles = &get_cycles();
pcl = new PCL();
pc = new dsPicProgramCounter(this,pcl);
m_stack.init(this);
}
//-------------------------------------------------------------------
//
// create
//
// Build the basic dsPicProcessor elements.
void dsPicProcessor::create()
{
init_program_memory (program_memory_size());
pc->memory_size_mask = program_memory_size()-1;
init_register_memory (register_memory_size()/2);
create_sfr_map();
create_invalid_registers();
}
//-------------------------------------------------------------------
//
void dsPicProcessor::add_sfr_register(dspic_registers::dsPicRegister *pReg,
unsigned int addr, const char *pName,
RegisterValue *rv
)
{
if (!pReg)
return;
printf("adding sfr %s\n",pReg->name().c_str());
pReg->set_cpu(this);
if (addr < register_memory_size()) {
registers[map_rm_address2index(addr)] = pReg;
if (pName)
pReg->new_name(pName);
pReg->address = addr;
pReg->alias_mask = 0;
get_symbol_table().add_register(pReg);
if (rv) {
pReg->value = *rv;
pReg->por_value = *rv;
}
RegisterValue rv = getWriteTT(addr);
pReg->set_write_trace(rv);
rv = getReadTT(addr);
pReg->set_read_trace(rv);
}
}
//-------------------------------------------------------------------
//
// load_hex
//
bool dsPicProcessor::LoadProgramFile(const char *pFilename, FILE *pFile, const char *pProcessorName)
{
Processor * pProcessor = this;
ProgramFileType *pPFT = ProgramFileTypeList::GetList()[0]; // IntelHexProgramFileType
if (pPFT)
return pPFT->LoadProgramFile(&pProcessor, pFilename, pFile, pProcessorName);
return false;
}
//------------------------------------------------------------------------
void dsPicProcessor::create_sfr_map()
{
unsigned int j;
// Initialize the General Purpose Registers:
//add_file_registers(0xf80, 0xf7f, 0);
unsigned int start_address = 0x0800/2;
unsigned int end_address = 0x27ff/2;
char str[100];
for (j = start_address; j <= end_address; j++) {
registers[j] = new dsPicRegister;
registers[j]->alias_mask = 0;
registers[j]->address = j;
RegisterValue rv = getWriteTT(j);
registers[j]->set_write_trace(rv);
rv = getReadTT(j);
registers[j]->set_read_trace(rv);
//The default register name is simply its address
sprintf (str, "R%03X", j);
registers[j]->new_name(str);
registers[j]->set_cpu(this);
}
RegisterValue porv(0,0);
for (j=0; j<16; j++) {
char buff[16];
snprintf(buff, 16, "W%d",j);
add_sfr_register(&W[j], j*2, buff,&porv);
}
add_sfr_register(pcl, 0x02e);
}
//------------------------------------------------------------------------
void dsPicProcessor::init_program_memory_at_index(unsigned int uIndex,
const unsigned char *bytes,
int nBytes)
{
unsigned int unBytes = nBytes;
for (unsigned int i =0; i<unBytes; i+=4)
Processor::init_program_memory_at_index(uIndex/2 + (i/4),
(((unsigned int)bytes[i+0])<<0) |
(((unsigned int)bytes[i+1])<<8) |
(((unsigned int)bytes[i+2])<<16));
}
//------------------------------------------------------------------------
void dsPicProcessor::step_one(bool refresh)
{
program_memory[pc->value]->execute();
}
void dsPicProcessor::interrupt()
{
}
unsigned int dsPicProcessor::get_config_word(unsigned int)
{
return 0xffffffff;
}
void dsPicProcessor::por()
{
}
//------------------------------------------------------------------------
// dsPIC30F6010
//------------------------------------------------------------------------
dsPic30F6010::dsPic30F6010(const char *_name, const char *desc)
{
}
Processor * dsPic30F6010::construct(const char *name)
{
dsPic30F6010 *p = new dsPic30F6010(name);
printf ("Constructing a dspic 6010\n");
get_symbol_table().add_module(p,p->name().c_str());
p->create();
return p;
}
//------------------------------------------------------------
//
void dsPic30F6010::create()
{
create_iopin_map();
dsPicProcessor::create();
}
//------------------------------------------------------------
//
void dsPic30F6010::create_iopin_map()
{
package = new Package(80);
if(!package)
return;
}
};
syntax highlighted by Code2HTML, v. 0.9.1