/*
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. */
#include <stdio.h>
#include <iostream>
#include <iomanip>
#include "../config.h"
//#include "14bit-registers.h"
//#include "14bit-instructions.h"
#include "14bit-processors.h"
#include "pic-ioports.h"
#include <string>
#include "stimuli.h"
//========================================================================
// Generic Configuration word for the midrange family.
class Generic14bitConfigWord : public ConfigMemory
{
public:
Generic14bitConfigWord(_14bit_processor *pCpu)
: ConfigMemory("CONFIG", 0x3fff, "Configuration Word", pCpu, 0x2007)
{
}
enum {
FOSC0 = 1<<0,
FOSC1 = 1<<1,
WDTEN = 1<<2,
PWRTEN = 1<<3
};
virtual void set(gint64 v)
{
gint64 oldV = getVal();
Integer::set(v);
if (m_pCpu) {
gint64 diff = oldV ^ v;
if (diff & WDTEN)
m_pCpu->wdt.initialize((v & WDTEN) == WDTEN);
}
}
};
//-------------------------------------------------------------------
_14bit_processor::_14bit_processor(const char *_name, const char *_desc)
: pic_processor(_name,_desc), intcon(0)
{
pc = new Program_Counter();
pc->set_trace_command(trace.allocateTraceType(new PCTraceType(this,1)));
}
_14bit_processor::~_14bit_processor()
{
// delete pc;
}
//-------------------------------------------------------------------
//
//
// create
//
// The purpose of this member function is to 'create' those things
// that are unique to the 14-bit core processors.
void _14bit_processor :: create (void)
{
if(verbose)
cout << "_14bit_processor create, type = " << isa() << '\n';
pic_processor::create();
fsr = new FSR;
fsr->new_name("fsr");
}
//-------------------------------------------------------------------
void _14bit_processor::interrupt (void)
{
bp.clear_interrupt();
stack->push(pc->value);
intcon->clear_gie();
pc->interrupt(INTERRUPT_VECTOR);
}
//-------------------------------------------------------------------
void _14bit_processor::por(void)
{
pic_processor::por();
}
//-------------------------------------------------------------------
void _14bit_processor::option_new_bits_6_7(unsigned int bits)
{
cout << "14bit, option bits 6 and/or 7 changed\n";
}
//------------------------------------------------------------------
// Fetch the rom contents at a particular address.
unsigned int _14bit_processor::get_program_memory_at_address(unsigned int address)
{
unsigned int uIndex = map_pm_address2index(address);
if (uIndex < program_memory_size())
return program_memory[uIndex] ? program_memory[uIndex]->get_opcode() : 0xffffffff;
return get_config_word(address);
}
//-------------------------------------------------------------------
void _14bit_processor::create_config_memory()
{
m_configMemory = new ConfigMemory *[1];
*m_configMemory = new Generic14bitConfigWord(this);
}
#if 0
//-------------------------------------------------------------------
class PortBSink;
class PortBIntEdgeSink :: public SignalSink
{
public:
PortBIntEdgeSink(PortBSink *, unsigned int iobit);
virtual void setSinkState(bool);
private:
PortBSink *m_PortBSink;
unsigned int m_bitMask;
};
class PortBSink
{
public:
PortBSink(PortRegister *portReg);
void setSink(unsigned int, bool);
void setPullups(bool);
private:
PortRegister *m_port;
bool m_bPullupState;
};
//------------------------------------------------------------------------
PortBIntEdgeSink::PortBIntEdgeSink(PortBSink *_PortBSink, unsigned int iobit)
: m_PortBSink(_PortBSink), m_bitMask(1<<iobit)
{
}
void PortBIntEdgeSink::setSinkState(bool bMewState)
{
m_PortBSink->setSink(m_bitBask, bNewState);
}
//------------------------------------------------------------------------
PortBSink::PortBSink(PicPortRegister *portReg)
: m_port(portReg),
m_bPullupState(false)
{
assert (portReg);
portReg->addSink(new PortBIntEdgeSink(this, 0), 0);
unsigned int mask = portReg->getEnableMask();
for (unsigned int i=0, m=1; mask; i++, m<<= 1)
if (mask & m) {
mask ^= m;
portReg->addSink(new PortBPinSink(this, i), i);
}
}
void PortBSink::setPullups(bool new_pullupState)
{
unsigned int mask = portReg->getEnableMask();
for (unsigned int i=0, m=1; mask; i++, m<<= 1)
if (mask & m) {
mask ^= m;
(*portReg)[i].update_pullup(new_pullupState);
}
}
#endif
//-------------------------------------------------------------------
Pic14Bit::Pic14Bit(const char *_name, const char *_desc)
: _14bit_processor(_name,_desc)
{
m_porta = new PicPortRegister("porta",8,0x1f);
m_trisa = new PicTrisRegister("trisa",m_porta);
tmr0.set_cpu(this, m_porta, 4);
tmr0.start(0);
m_portb = new PicPortBRegister("portb",8,0xff);
m_trisb = new PicTrisRegister("trisb",m_portb);
}
//-------------------------------------------------------------------
Pic14Bit::~Pic14Bit()
{
}
//-------------------------------------------------------------------
void Pic14Bit::create_symbols(void)
{
pic_processor::create_symbols();
// add a special symbol for W
symbol_table.add_w(W);
}
//-------------------------------------------------------------------
void Pic14Bit::create_sfr_map(void)
{
add_sfr_register(indf, 0x80);
add_sfr_register(indf, 0x00);
add_sfr_register(&tmr0, 0x01);
add_sfr_register(&option_reg, 0x81, RegisterValue(0xff,0));
add_sfr_register(pcl, 0x02, RegisterValue(0,0));
add_sfr_register(status, 0x03, RegisterValue(0x18,0));
add_sfr_register(fsr, 0x04);
alias_file_registers(0x02,0x04,0x80);
add_sfr_register(m_porta, 0x05);
add_sfr_register(m_trisa, 0x85, RegisterValue(0x3f,0));
add_sfr_register(m_portb, 0x06);
add_sfr_register(m_trisb, 0x86, RegisterValue(0xff,0));
add_sfr_register(pclath, 0x8a, RegisterValue(0,0));
add_sfr_register(pclath, 0x0a, RegisterValue(0,0));
add_sfr_register(&intcon_reg, 0x8b, RegisterValue(0,0));
add_sfr_register(&intcon_reg, 0x0b, RegisterValue(0,0));
intcon = &intcon_reg;
}
//-------------------------------------------------------------------
void Pic14Bit::option_new_bits_6_7(unsigned int bits)
{
//1 ((PORTB *)portb)->rbpu_intedg_update(bits);
m_portb->setRBPU( (bits & (1<<7)) == (1<<7));
m_portb->setIntEdge((bits & (1<<6)) == (1<<6));
}
syntax highlighted by Code2HTML, v. 0.9.1