//
// srecord - manipulate eprom load files
// Copyright (C) 1998, 1999, 2001-2003, 2006, 2007 Peter Miller
//
// This program 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 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see
// .
//
#include
#include
#include
srec_memory_chunk::srec_memory_chunk(unsigned long arg) :
address(arg)
{
memset(data, 0, sizeof(data));
memset(mask, 0, sizeof(mask));
}
srec_memory_chunk::srec_memory_chunk(const srec_memory_chunk &arg) :
address(arg.address)
{
memcpy(data, arg.data, sizeof(data));
memcpy(mask, arg.mask, sizeof(mask));
}
srec_memory_chunk &
srec_memory_chunk::operator=(const srec_memory_chunk &arg)
{
if (this != &arg)
{
address = arg.address;
memcpy(data, arg.data, sizeof(data));
memcpy(mask, arg.mask, sizeof(mask));
}
return *this;
}
srec_memory_chunk::~srec_memory_chunk()
{
}
void
srec_memory_chunk::set(unsigned long offset, int datum)
{
data[offset] = datum;
mask[offset >> 3] |= (1 << (offset & 7));
}
void
srec_memory_chunk::walk(srec_memory_walker *w)
const
{
for (int j = 0; j < size; ++j)
{
if (!set_p(j))
continue;
int k;
for (k = j + 1; k < size && set_p(k); ++k)
;
w->observe(address * size + j, data + j, k - j);
j = k;
}
}
bool
srec_memory_chunk::find_next_data(unsigned long &ret_addr, void *ret_data,
size_t &nbytes)
const
{
for (unsigned j = ret_addr % size; j < size; ++j)
{
if (!set_p(j))
continue;
size_t max = j + nbytes;
if (max > size)
max = size;
unsigned k;
for (k = j + 1; k < max && set_p(k); ++k)
;
nbytes = k - j;
memcpy(ret_data, data + j, nbytes);
ret_addr = address * size + j;
return true;
}
return false;
}
int
srec_memory_chunk::get(unsigned long offset)
{
return data[offset];
}
bool
srec_memory_chunk::set_p(unsigned long offset)
const
{
return (0 != (mask[offset >> 3] & (1 << (offset & 7))));
}
bool
srec_memory_chunk::equal(const srec_memory_chunk &lhs,
const srec_memory_chunk &rhs)
{
return
(
lhs.address == rhs.address
&&
0 == memcmp(lhs.data, rhs.data, sizeof(lhs.data))
&&
0 == memcmp(lhs.mask, rhs.mask, sizeof(lhs.mask))
);
}
unsigned long
srec_memory_chunk::get_upper_bound()
const
{
for (size_t j = size; j > 0; --j)
{
if (set_p(j - 1))
return (address * size + j);
}
// can't happen?
return (address * size);
}
bool
operator == (const srec_memory_chunk &lhs, const srec_memory_chunk &rhs)
{
return srec_memory_chunk::equal(lhs, rhs);
}
bool
operator != (const srec_memory_chunk &lhs, const srec_memory_chunk &rhs)
{
return !srec_memory_chunk::equal(lhs, rhs);
}