More efficient No-Slot-Clock implementation with UINT64.

Cleaned up naming and method semantics.
Made some members public for save/restore state (not yet done).
This commit is contained in:
nick_westgate 2010-08-29 10:06:36 +00:00
parent 8acfc32c91
commit 80b502dc2b
3 changed files with 54 additions and 78 deletions

View File

@ -553,8 +553,8 @@ BYTE __stdcall IORead_Cxxx(WORD programcounter, WORD address, BYTE write, BYTE v
if ((address >= 0xC300) && (address <= 0xC3FF))
{
int data;
if (g_NoSlotClock.ReadAccess(address, data))
int data = 0;
if (g_NoSlotClock.Read(address, data))
return (BYTE) data;
}
@ -587,7 +587,7 @@ BYTE __stdcall IOWrite_Cxxx(WORD programcounter, WORD address, BYTE write, BYTE
{
if ((address >= 0xC300) && (address <= 0xC3FF))
{
g_NoSlotClock.WriteAccess(address);
g_NoSlotClock.Write(address);
}
return 0;

View File

@ -21,7 +21,7 @@ along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: No Slot Clock (Dallas SmartWatch DS1216) emulation
/* Description: No Slot Clock/Phantom Clock (Dallas SmartWatch DS1216) emulation
*
* Author: Nick Westgate
*/
@ -29,12 +29,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#include "NoSlotClock.h"
static byte ClockInitSequence[] = { 0xC5, 0x3A, 0xA3, 0x5C, 0xC5, 0x3A, 0xA3, 0x5C };
CNoSlotClock::CNoSlotClock()
:
m_ClockRegister(64),
m_ComparisonRegister(ClockInitSequence, sizeof(ClockInitSequence))
m_ClockRegister(),
m_ComparisonRegister(kClockInitSequence)
{
Reset();
}
@ -47,7 +45,7 @@ void CNoSlotClock::Reset()
m_bWriteEnabled = true;
}
bool CNoSlotClock::ReadAccess(int address, int& data)
bool CNoSlotClock::Read(int address, int& data)
{
// this may read or write the clock (returns true if data is changed)
if (address & 0x04)
@ -59,7 +57,7 @@ bool CNoSlotClock::ReadAccess(int address, int& data)
}
}
void CNoSlotClock::WriteAccess(int address)
void CNoSlotClock::Write(int address)
{
// this may read or write the clock
int dummy = 0;
@ -69,7 +67,7 @@ void CNoSlotClock::WriteAccess(int address)
ClockWrite(address);
}
bool CNoSlotClock::ClockRead(int& d0)
bool CNoSlotClock::ClockRead(int& data)
{
// for a ROM, A2 high = read, and data out (if any) is on D0
if (!m_bClockRegisterEnabled)
@ -78,11 +76,13 @@ bool CNoSlotClock::ClockRead(int& d0)
m_bWriteEnabled = true;
return false;
}
else if (m_ClockRegister.ReadBit(d0))
else
{
m_bClockRegisterEnabled = false;
m_ClockRegister.ReadBit(data);
if (m_ClockRegister.NextBit())
m_bClockRegisterEnabled = false;
return true;
}
return true;
}
void CNoSlotClock::ClockWrite(int address)
@ -93,9 +93,9 @@ void CNoSlotClock::ClockWrite(int address)
if (!m_bClockRegisterEnabled)
{
if ((m_ComparisonRegister.CompareBitNoIncrement(address & 0x1)))
if ((m_ComparisonRegister.CompareBit(address & 0x1)))
{
if (m_ComparisonRegister.IncrementPointer())
if (m_ComparisonRegister.NextBit())
{
m_bClockRegisterEnabled = true;
PopulateClockRegister();
@ -107,7 +107,7 @@ void CNoSlotClock::ClockWrite(int address)
m_bWriteEnabled = false;
}
}
else if (m_ClockRegister.IncrementPointer())
else if (m_ClockRegister.NextBit())
{
// simulate writes, but our clock register is read-only
m_bClockRegisterEnabled = false;
@ -120,8 +120,6 @@ void CNoSlotClock::PopulateClockRegister()
SYSTEMTIME now;
GetLocalTime(&now);
m_ClockRegister.Reset();
int centisecond = now.wMilliseconds / 10; // 00-99
m_ClockRegister.WriteNibble(centisecond % 10);
m_ClockRegister.WriteNibble(centisecond / 10);
@ -155,76 +153,58 @@ void CNoSlotClock::PopulateClockRegister()
m_ClockRegister.WriteNibble(year / 10);
}
CNoSlotClock::RingRegister::~RingRegister()
{
delete[] m_pRegister;
}
CNoSlotClock::RingRegister::RingRegister(int bitCount)
CNoSlotClock::RingRegister64::RingRegister64()
{
Reset();
m_pRegister = new int[bitCount];
m_PointerWrap = bitCount;
m_Register = 0;
}
CNoSlotClock::RingRegister::RingRegister(byte* bytes, int byteCount)
CNoSlotClock::RingRegister64::RingRegister64(UINT64 data)
{
Reset();
m_PointerWrap = byteCount * 8;
m_pRegister = new int[m_PointerWrap];
for (int i = 0; i < byteCount; i++)
WriteByte(bytes[i]);
m_Register = data;
}
void CNoSlotClock::RingRegister::Reset()
void CNoSlotClock::RingRegister64::Reset()
{
m_Pointer = 0;
m_Mask = 1;
}
void CNoSlotClock::RingRegister::WriteByte(int data)
{
WriteBits(data, 8);
}
void CNoSlotClock::RingRegister::WriteNibble(int data)
void CNoSlotClock::RingRegister64::WriteNibble(int data)
{
WriteBits(data, 4);
}
void CNoSlotClock::RingRegister::WriteBits(int data, int count)
void CNoSlotClock::RingRegister64::WriteBits(int data, int count)
{
for (int i = 1; i <= count; i++)
{
WriteBit(data);
NextBit();
data >>= 1;
}
}
bool CNoSlotClock::RingRegister::WriteBit(int data)
void CNoSlotClock::RingRegister64::WriteBit(int data)
{
m_pRegister[m_Pointer] = data & 1;
return IncrementPointer();
m_Register = (data & 0x1) ? (m_Register | m_Mask) : (m_Register & ~m_Mask);
}
bool CNoSlotClock::RingRegister::ReadBit(int& data)
void CNoSlotClock::RingRegister64::ReadBit(int& data)
{
data = m_pRegister[m_Pointer];
return IncrementPointer();
data = (m_Register & m_Mask) ? data | 1 : data & ~1;
}
bool CNoSlotClock::RingRegister::CompareBitNoIncrement(int data)
bool CNoSlotClock::RingRegister64::CompareBit(int data)
{
return m_pRegister[m_Pointer] == data;
return ((m_Register & m_Mask) != 0) == ((data & 1) != 0);
}
bool CNoSlotClock::RingRegister::IncrementPointer()
bool CNoSlotClock::RingRegister64::NextBit()
{
if (++m_Pointer == m_PointerWrap)
if ((m_Mask <<= 1) == 0)
{
m_Pointer = 0;
m_Mask = 1;
return true; // wrap
}
return false;

View File

@ -21,7 +21,7 @@ along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: No Slot Clock (Dallas SmartWatch) emulation
/* Description: No Slot Clock/Phantom Clock (Dallas SmartWatch DS1216) emulation
*
* Author: Nick Westgate
*/
@ -30,44 +30,40 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
class CNoSlotClock
{
class RingRegister
class RingRegister64
{
public:
RingRegister(int bitCount);
RingRegister(BYTE* bytes, int byteCount);
~RingRegister();
RingRegister64();
RingRegister64(UINT64 data);
void Reset();
void WriteByte(int data);
void WriteNibble(int data);
void WriteBits(int data, int count);
bool WriteBit(int data);
bool ReadBit(int& data);
bool CompareBitNoIncrement(int data);
bool IncrementPointer();
void WriteBit(int data);
void ReadBit(int& data);
bool CompareBit(int data);
bool NextBit();
private:
RingRegister() {};
int m_Pointer;
int m_PointerWrap;
int* m_pRegister;
UINT64 m_Mask;
UINT64 m_Register;
};
public:
CNoSlotClock();
void Reset();
bool ReadAccess(int address, int& data);
void WriteAccess(int address);
bool ClockRead(int& d0);
bool Read(int address, int& data);
void Write(int address);
bool ClockRead(int& data);
void ClockWrite(int address);
bool m_bClockRegisterEnabled;
bool m_bWriteEnabled;
RingRegister64 m_ClockRegister;
RingRegister64 m_ComparisonRegister;
private:
void PopulateClockRegister();
bool m_bClockRegisterEnabled;
bool m_bWriteEnabled;
RingRegister m_ClockRegister;
RingRegister m_ComparisonRegister;
static const UINT64 kClockInitSequence = 0x5CA33AC55CA33AC5;
};