This commit is contained in:
David Haywood 2016-03-30 00:17:16 +01:00
commit 7ac5dcae54
5 changed files with 64 additions and 80 deletions

View File

@ -22,7 +22,7 @@
- SM511 undocumented/guessed opcodes: - SM511 undocumented/guessed opcodes:
* $01 is guessed as DIV to ACC transfer, unknown which bits * $01 is guessed as DIV to ACC transfer, unknown which bits
* $5d is certainly CEND * $5d is certainly CEND
* $65 is certainly IDIV, but not sure if it behaves same as on SM510 * $65 is certainly divider reset, but not sure if it behaves same as on SM510
*/ */
@ -144,6 +144,7 @@ void sm510_base_device::device_start()
void sm510_base_device::device_reset() void sm510_base_device::device_reset()
{ {
// ACL
m_skip = false; m_skip = false;
m_halt = false; m_halt = false;
m_op = m_prev_op = 0; m_op = m_prev_op = 0;
@ -317,7 +318,7 @@ TIMER_CALLBACK_MEMBER(sm510_base_device::div_timer_cb)
{ {
m_div = (m_div + 1) & 0x7fff; m_div = (m_div + 1) & 0x7fff;
// 1S signal on overflow(falling edge of f1) // 1S signal on overflow(falling edge of F1)
if (m_div == 0) if (m_div == 0)
m_1s = true; m_1s = true;

View File

@ -284,6 +284,7 @@ protected:
void op_skip(); void op_skip();
void op_cend(); void op_cend();
void op_idiv(); void op_idiv();
void op_dr();
void op_dta(); void op_dta();
void op_illegal(); void op_illegal();

View File

@ -450,10 +450,16 @@ void sm510_base_device::op_idiv()
m_div = 0; m_div = 0;
} }
void sm510_base_device::op_dr()
{
// DR: reset divider low 8 bits
m_div &= 0x7f;
}
void sm510_base_device::op_dta() void sm510_base_device::op_dta()
{ {
// DTA: transfer divider low bits to ACC // DTA: transfer divider low 4 bits to ACC
m_acc = BITSWAP16(m_div,0,0,0,0, 0,0,0,0, 0,0,0,0, 7,8,9,10) & 0xf; m_acc = BITSWAP16(m_div,0,0,0,0, 0,0,0,0, 0,0,0,0, 14,13,12,11) & 0xf;
} }
void sm510_base_device::op_illegal() void sm510_base_device::op_illegal()

View File

@ -127,7 +127,7 @@ void sm511_device::execute_one()
case 0x62: op_wr(); break; case 0x62: op_wr(); break;
case 0x63: op_ws(); break; case 0x63: op_ws(); break;
case 0x64: op_incb(); break; case 0x64: op_incb(); break;
case 0x65: op_idiv(); break; case 0x65: op_dr(); break; // guessed
case 0x66: op_rc(); break; case 0x66: op_rc(); break;
case 0x67: op_sc(); break; case 0x67: op_sc(); break;
case 0x6c: op_decb(); break; case 0x6c: op_decb(); break;

View File

@ -1,34 +1,35 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Aaron Giles // copyright-holders:Aaron Giles
/*************************************************************************** /**************************************************************************/
/**
attotime.h * @file attotime.h
* Support functions for working with attotime data.
Support functions for working with attotime data. * @defgroup ATTOTIME
* @{
**************************************************************************** * Support functions for working with attotime data.
*
Attotime is an attosecond-accurate timing system implemented as * @class attotime
96-bit integers. * Attotime is an attosecond-accurate timing system implemented as
* 96-bit integers.
1 second = 1e0 seconds *
1 millisecond = 1e-3 seconds * 1 second = 1e0 seconds
1 microsecond = 1e-6 seconds * 1 millisecond = 1e-3 seconds
1 nanosecond = 1e-9 seconds * 1 microsecond = 1e-6 seconds
1 picosecond = 1e-12 seconds * 1 nanosecond = 1e-9 seconds
1 femtosecond = 1e-15 seconds * 1 picosecond = 1e-12 seconds
1 attosecond = 1e-18 seconds * 1 femtosecond = 1e-15 seconds
* 1 attosecond = 1e-18 seconds
This may seem insanely accurate, but it has its uses when multiple *
clocks in the system are run by independent crystals. It is also * This may seem insanely accurate, but it has its uses when multiple
useful to compute the attotime for something small, say 1 clock tick, * clocks in the system are run by independent crystals. It is also
and still have it be accurate and useful for scaling. * useful to compute the attotime for something small, say 1 clock tick,
* and still have it be accurate and useful for scaling.
Attotime consists of a 32-bit seconds count and a 64-bit attoseconds *
count. Because the lower bits are kept as attoseconds and not as a * Attotime consists of a 32-bit seconds count and a 64-bit attoseconds
full 64-bit value, there is headroom to make some operations simpler. * count. Because the lower bits are kept as attoseconds and not as a
* full 64-bit value, there is headroom to make some operations simpler.
***************************************************************************/ */
/**************************************************************************/
#pragma once #pragma once
@ -91,6 +92,7 @@ public:
: m_seconds(0), : m_seconds(0),
m_attoseconds(0) { } m_attoseconds(0) { }
/** Constructs with @p secs seconds and @p attos attoseconds. */
attotime(seconds_t secs, attoseconds_t attos) attotime(seconds_t secs, attoseconds_t attos)
: m_seconds(secs), : m_seconds(secs),
m_attoseconds(attos) { } m_attoseconds(attos) { }
@ -109,24 +111,32 @@ public:
// queries // queries
bool is_zero() const { return (m_seconds == 0 && m_attoseconds == 0); } bool is_zero() const { return (m_seconds == 0 && m_attoseconds == 0); }
/** Test if value is above @ref ATTOTIME_MAX_SECONDS (considered an overflow) */
bool is_never() const { return (m_seconds >= ATTOTIME_MAX_SECONDS); } bool is_never() const { return (m_seconds >= ATTOTIME_MAX_SECONDS); }
// conversion to other forms // conversion to other forms
double as_double() const { return double(m_seconds) + ATTOSECONDS_TO_DOUBLE(m_attoseconds); } double as_double() const { return double(m_seconds) + ATTOSECONDS_TO_DOUBLE(m_attoseconds); }
attoseconds_t as_attoseconds() const; attoseconds_t as_attoseconds() const;
UINT64 as_ticks(UINT32 frequency) const; UINT64 as_ticks(UINT32 frequency) const;
/** Convert to string using at @p precision */
const char *as_string(int precision = 9) const; const char *as_string(int precision = 9) const;
/** @return the attoseconds portion. */
attoseconds_t attoseconds() const { return m_attoseconds; } attoseconds_t attoseconds() const { return m_attoseconds; }
/** @return the seconds portion. */
seconds_t seconds() const { return m_seconds; } seconds_t seconds() const { return m_seconds; }
// conversion from other forms
static attotime from_double(double _time); static attotime from_double(double _time);
static attotime from_ticks(UINT64 ticks, UINT32 frequency); static attotime from_ticks(UINT64 ticks, UINT32 frequency);
/** Create an attotime from a integer count of seconds @seconds */
static attotime from_seconds(INT32 seconds) { return attotime(seconds, 0); } static attotime from_seconds(INT32 seconds) { return attotime(seconds, 0); }
/** Create an attotime from a integer count of milliseconds @msec */
static attotime from_msec(INT64 msec) { return attotime(msec / 1000, (msec % 1000) * (ATTOSECONDS_PER_SECOND / 1000)); } static attotime from_msec(INT64 msec) { return attotime(msec / 1000, (msec % 1000) * (ATTOSECONDS_PER_SECOND / 1000)); }
/** Create an attotime from a integer count of microseconds @usec */
static attotime from_usec(INT64 usec) { return attotime(usec / 1000000, (usec % 1000000) * (ATTOSECONDS_PER_SECOND / 1000000)); } static attotime from_usec(INT64 usec) { return attotime(usec / 1000000, (usec % 1000000) * (ATTOSECONDS_PER_SECOND / 1000000)); }
/** Create an attotime from a integer count of nanoseconds @nsec */
static attotime from_nsec(INT64 nsec) { return attotime(nsec / 1000000000, (nsec % 1000000000) * (ATTOSECONDS_PER_SECOND / 1000000000)); } static attotime from_nsec(INT64 nsec) { return attotime(nsec / 1000000000, (nsec % 1000000000) * (ATTOSECONDS_PER_SECOND / 1000000000)); }
/** Create an attotime from at the given frequency @frequency */
static attotime from_hz(double frequency) { assert(frequency > 0); double d = 1 / frequency; return attotime(floor(d), modf(d, &d) * ATTOSECONDS_PER_SECOND); } static attotime from_hz(double frequency) { assert(frequency > 0); double d = 1 / frequency; return attotime(floor(d), modf(d, &d) * ATTOSECONDS_PER_SECOND); }
// math // math
@ -143,18 +153,14 @@ public:
static const attotime never; static const attotime never;
static const attotime zero; static const attotime zero;
}; };
/** @} */
//************************************************************************** //**************************************************************************
// INLINE FUNCTIONS // INLINE FUNCTIONS
//************************************************************************** //**************************************************************************
//------------------------------------------------- /** handle addition between two attotimes */
// operator+ - handle addition between two
// attotimes
//-------------------------------------------------
inline attotime operator+(const attotime &left, const attotime &right) inline attotime operator+(const attotime &left, const attotime &right)
{ {
attotime result; attotime result;
@ -204,11 +210,7 @@ inline attotime &attotime::operator+=(const attotime &right)
} }
//------------------------------------------------- /** handle subtraction between two attotimes */
// operator- - handle subtraction between two
// attotimes
//-------------------------------------------------
inline attotime operator-(const attotime &left, const attotime &right) inline attotime operator-(const attotime &left, const attotime &right)
{ {
attotime result; attotime result;
@ -250,12 +252,7 @@ inline attotime &attotime::operator-=(const attotime &right)
} }
//------------------------------------------------- /** handle multiplication by an integral factor; defined in terms of the assignment operators */
// operator* - handle multiplication/division by
// an integral factor; defined in terms of the
// assignment operators
//-------------------------------------------------
inline attotime operator*(const attotime &left, UINT32 factor) inline attotime operator*(const attotime &left, UINT32 factor)
{ {
attotime result = left; attotime result = left;
@ -270,6 +267,7 @@ inline attotime operator*(UINT32 factor, const attotime &right)
return result; return result;
} }
/** handle division by an integral factor; defined in terms of the assignment operators */
inline attotime operator/(const attotime &left, UINT32 factor) inline attotime operator/(const attotime &left, UINT32 factor)
{ {
attotime result = left; attotime result = left;
@ -278,11 +276,7 @@ inline attotime operator/(const attotime &left, UINT32 factor)
} }
//------------------------------------------------- /** handle comparisons between attotimes */
// operator== - handle comparisons between
// attotimes
//-------------------------------------------------
inline bool operator==(const attotime &left, const attotime &right) inline bool operator==(const attotime &left, const attotime &right)
{ {
return (left.m_seconds == right.m_seconds && left.m_attoseconds == right.m_attoseconds); return (left.m_seconds == right.m_seconds && left.m_attoseconds == right.m_attoseconds);
@ -345,12 +339,7 @@ inline attotime max(const attotime &left, const attotime &right)
return right; return right;
} }
/** Convert to an attoseconds value, clamping to +/- 1 second */
//-------------------------------------------------
// as_attoseconds - convert to an attoseconds
// value, clamping to +/- 1 second
//-------------------------------------------------
inline attoseconds_t attotime::as_attoseconds() const inline attoseconds_t attotime::as_attoseconds() const
{ {
// positive values between 0 and 1 second // positive values between 0 and 1 second
@ -371,11 +360,7 @@ inline attoseconds_t attotime::as_attoseconds() const
} }
//------------------------------------------------- /** as_ticks - convert to ticks at @p frequency */
// as_ticks - convert to ticks at the given
// frequency
//-------------------------------------------------
inline UINT64 attotime::as_ticks(UINT32 frequency) const inline UINT64 attotime::as_ticks(UINT32 frequency) const
{ {
UINT32 fracticks = (attotime(0, m_attoseconds) * frequency).m_seconds; UINT32 fracticks = (attotime(0, m_attoseconds) * frequency).m_seconds;
@ -383,11 +368,7 @@ inline UINT64 attotime::as_ticks(UINT32 frequency) const
} }
//------------------------------------------------- /** Create an attotime from a tick count @ticks at the given frequency @frequency */
// from_ticks - create an attotime from a tick
// count at the given frequency
//-------------------------------------------------
inline attotime attotime::from_ticks(UINT64 ticks, UINT32 frequency) inline attotime attotime::from_ticks(UINT64 ticks, UINT32 frequency)
{ {
attoseconds_t attos_per_tick = HZ_TO_ATTOSECONDS(frequency); attoseconds_t attos_per_tick = HZ_TO_ATTOSECONDS(frequency);
@ -400,12 +381,7 @@ inline attotime attotime::from_ticks(UINT64 ticks, UINT32 frequency)
return attotime(secs, (UINT64)remainder * attos_per_tick); return attotime(secs, (UINT64)remainder * attos_per_tick);
} }
/** Create an attotime from floating point count of seconds @p _time */
//-------------------------------------------------
// from_double - create an attotime from floating
// point count of seconds
//-------------------------------------------------
inline attotime attotime::from_double(double _time) inline attotime attotime::from_double(double _time)
{ {
seconds_t secs = floor(_time); seconds_t secs = floor(_time);