/*
Copyright (C) 1998-2003 Scott Dattalo
2003 Mike Durian
2006 Roy Rankin
2006 David Barnett
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 <assert.h>
#include <iostream>
#include <iomanip>
using namespace std;
#include <glib.h>
#include "trace.h"
#include "pic-processor.h"
#include "pm_rd.h"
//------------------------------------------------------------------------
//
// PM-related registers
void PMCON1::put(unsigned int new_value)
{
trace.raw(write_trace.get() | value.get());
new_value &= valid_bits;
bool rd_rise = (bool)(new_value & ~value.get() & RD);
value.put((value.get() & RD) | new_value);
if (rd_rise)
pm_rd->start_read();
}
unsigned int PMCON1::get(void)
{
trace.raw(read_trace.get() | value.get());
return(value.get());
}
PMCON1::PMCON1(void)
{
new_name("pmcon1");
valid_bits = PMCON1_VALID_BITS;
}
unsigned int PMDATA::get(void)
{
trace.raw(read_trace.get() | value.get());
return(value.get());
}
void PMDATA::put(unsigned int new_value)
{
trace.raw(write_trace.get() | value.get());
value.put(new_value);
}
PMDATA::PMDATA(void) {}
unsigned int PMADR::get(void)
{
trace.raw(read_trace.get() | value.get());
return(value.get());
}
void PMADR::put(unsigned int new_value)
{
trace.raw(write_trace.get() | value.get());
value.put(new_value);
}
PMADR::PMADR(void) {}
// ----------------------------------------------------------
PM_RD::PM_RD(void)
{
cpu = NULL;
pmcon1.set_pm(this);
pmadr.new_name("pmadr");
pmadrh.new_name("pmadrh");
pmdata.new_name("pmdata");
pmdath.new_name("pmdath");
}
void PM_RD::start_read(void)
{
rd_adr = pmadr.value.get() | (pmadrh.value.get() << 8);
get_cycles().set_break(get_cycles().value + READ_CYCLES, this);
}
void PM_RD::callback(void)
{
// read program memory
if(pmcon1.value.get() & PMCON1::RD) {
int opcode = cpu->pma->get_opcode(rd_adr);
pmdata.value.put(opcode & 0xff);
pmdath.value.put((opcode>>8) & 0xff);
pmcon1.value.put(pmcon1.value.get() & (~PMCON1::RD));
}
}
syntax highlighted by Code2HTML, v. 0.9.1