summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/tms9900/tms9995.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/tms9900/tms9995.cpp')
-rw-r--r--src/devices/cpu/tms9900/tms9995.cpp89
1 files changed, 44 insertions, 45 deletions
diff --git a/src/devices/cpu/tms9900/tms9995.cpp b/src/devices/cpu/tms9900/tms9995.cpp
index 696b04fb870..905357dc597 100644
--- a/src/devices/cpu/tms9900/tms9995.cpp
+++ b/src/devices/cpu/tms9900/tms9995.cpp
@@ -124,30 +124,30 @@ enum
Add the desired LOG aspect to the VERBOSE line
******************************************************************/
-#define LOG_OP (1U<<1) // Current instruction
-#define LOG_EXEC (1U<<2) // Address of current instruction
-#define LOG_CONFIG (1U<<3) // Configuration
-#define LOG_CYCLES (1U<<4) // Cycles
-#define LOG_WARN (1U<<5) // Illegal operation or other condition
-#define LOG_MEM (1U<<6) // Memory access
-#define LOG_CONTEXT (1U<<7) // Context switch
-#define LOG_INT (1U<<8) // Interrupts
-#define LOG_READY (1U<<9) // READY line input
-#define LOG_CLOCK (1U<<10) // Clock pulses
-#define LOG_ADDRESSBUS (1U<<11) // Address bus operation
-#define LOG_STATUS (1U<<12) // Status register
-#define LOG_CRU (1U<<13) // CRU operations
-#define LOG_DEC (1U<<14) // Decrementer
-#define LOG_WAIT (1U<<15) // Wait states
-#define LOG_HOLD (1U<<16) // Hold states
-#define LOG_IDLE (1U<<17) // Idle states
-#define LOG_EMU (1U<<18) // Emulation details
-#define LOG_MICRO (1U<<19) // Microinstruction processing
-#define LOG_INTD (1U<<20) // Interrupts (detailed phases)
-#define LOG_DETAIL (1U<<31) // Increased detail
+#define LOG_OP (1U << 1) // Current instruction
+#define LOG_EXEC (1U << 2) // Address of current instruction
+#define LOG_CONFIG (1U << 3) // Configuration
+#define LOG_CYCLES (1U << 4) // Cycles
+#define LOG_WARN (1U << 5) // Illegal operation or other condition
+#define LOG_MEM (1U << 6) // Memory access
+#define LOG_CONTEXT (1U << 7) // Context switch
+#define LOG_INT (1U << 8) // Interrupts
+#define LOG_READY (1U << 9) // READY line input
+#define LOG_CLOCK (1U << 10) // Clock pulses
+#define LOG_ADDRESSBUS (1U << 11) // Address bus operation
+#define LOG_STATUS (1U << 12) // Status register
+#define LOG_CRU (1U << 13) // CRU operations
+#define LOG_DEC (1U << 14) // Decrementer
+#define LOG_WAIT (1U << 15) // Wait states
+#define LOG_HOLD (1U << 16) // Hold states
+#define LOG_IDLE (1U << 17) // Idle states
+#define LOG_EMU (1U << 18) // Emulation details
+#define LOG_MICRO (1U << 19) // Microinstruction processing
+#define LOG_INTD (1U << 20) // Interrupts (detailed phases)
+#define LOG_DETAIL (1U << 31) // Increased detail
// Minimum log should be config and warnings
-#define VERBOSE ( LOG_CONFIG | LOG_WARN )
+#define VERBOSE (LOG_CONFIG | LOG_WARN)
#include "logmacro.h"
@@ -194,17 +194,10 @@ enum
void tms9995_device::device_start()
{
- // TODO: Restore save state suport
-
m_prgspace = &space(AS_PROGRAM);
m_setaddr = has_space(AS_SETADDRESS) ? &space(AS_SETADDRESS) : nullptr;
m_cru = &space(AS_IO);
- // Resolve our external connections
- m_external_operation.resolve();
- m_clock_out_line.resolve();
- m_holda_line.resolve();
-
// set our instruction counter
set_icountptr(m_icount);
@@ -216,10 +209,14 @@ void tms9995_device::device_start()
m_nmi_active = false;
m_int_overflow = false;
+ m_reset = false;
+
m_idle_state = false;
m_source_value = 0;
+ m_index = 0;
+
// add the states for the debugger
for (int i=0; i < 20; i++)
{
@@ -227,8 +224,8 @@ void tms9995_device::device_start()
// callexport = need to use the state_export method to read the state variable
state_add(i, s_statename[i], m_state_any).callimport().callexport().formatstr("%04X");
}
- state_add(STATE_GENPC, "GENPC", PC_debug).formatstr("%4s").noshow();
- state_add(STATE_GENPCBASE, "CURPC", PC_debug).formatstr("%4s").noshow();
+ state_add(STATE_GENPC, "GENPC", PC_debug).noshow();
+ state_add(STATE_GENPCBASE, "CURPC", PC_debug).noshow();
state_add(STATE_GENFLAGS, "status", m_state_any).callimport().callexport().formatstr("%16s").noshow();
// Set up the lookup table for command decoding
@@ -242,7 +239,7 @@ void tms9995_device::device_start()
save_item(NAME(PC));
save_item(NAME(ST));
// save_item(NAME(PC_debug)); // only for debugger output
- save_pointer(NAME(m_onchip_memory),256);
+ save_item(NAME(m_onchip_memory));
save_item(NAME(m_idle_state));
save_item(NAME(m_nmi_state));
save_item(NAME(m_hold_state));
@@ -285,7 +282,7 @@ void tms9995_device::device_start()
save_item(NAME(m_cru_address));
save_item(NAME(m_cru_value));
save_item(NAME(m_cru_first_read));
- save_pointer(NAME(m_flag),16);
+ save_item(NAME(m_flag));
save_item(NAME(IR));
save_item(NAME(m_pre_IR));
save_item(NAME(m_command));
@@ -381,7 +378,7 @@ void tms9995_device::state_string_export(const device_state_entry &entry, std::s
{
static char const statestr[] = "LAECOPX-----IIII";
char flags[17];
- memset(flags, 0x00, ARRAY_LENGTH(flags));
+ std::fill(std::begin(flags), std::end(flags), 0x00);
uint16_t val = 0x8000;
if (entry.index()==STATE_GENFLAGS)
{
@@ -1341,7 +1338,7 @@ void tms9995_device::execute_set_input(int irqline, int state)
/*
Triggers a RESET.
*/
-WRITE_LINE_MEMBER( tms9995_device::reset_line )
+void tms9995_device::reset_line(int state)
{
if (state==ASSERT_LINE)
{
@@ -1360,9 +1357,9 @@ void tms9995_device::pulse_clock(int count)
{
for (int i=0; i < count; i++)
{
- if (!m_clock_out_line.isnull()) m_clock_out_line(ASSERT_LINE);
+ if (!m_clock_out_line.isunset()) m_clock_out_line(ASSERT_LINE);
m_ready = m_ready_bufd && !m_request_auto_wait_state; // get the latched READY state
- if (!m_clock_out_line.isnull()) m_clock_out_line(CLEAR_LINE);
+ if (!m_clock_out_line.isunset()) m_clock_out_line(CLEAR_LINE);
m_icount--; // This is the only location where we count down the cycles.
if (m_check_ready)
@@ -1384,13 +1381,13 @@ void tms9995_device::pulse_clock(int count)
/*
Enter the hold state.
*/
-WRITE_LINE_MEMBER( tms9995_device::hold_line )
+void tms9995_device::hold_line(int state)
{
m_hold_requested = (state==ASSERT_LINE);
LOGMASKED(LOG_HOLD, "set HOLD = %d\n", state);
if (!m_hold_requested)
{
- if (!m_holda_line.isnull()) m_holda_line(CLEAR_LINE);
+ if (!m_holda_line.isunset()) m_holda_line(CLEAR_LINE);
}
}
@@ -1398,7 +1395,7 @@ WRITE_LINE_MEMBER( tms9995_device::hold_line )
Signal READY to the CPU. When cleared, the CPU enters wait states. This
becomes effective on a clock pulse.
*/
-WRITE_LINE_MEMBER( tms9995_device::ready_line )
+void tms9995_device::ready_line(int state)
{
bool newready = (state==ASSERT_LINE);
@@ -1434,7 +1431,7 @@ void tms9995_device::abort_operation()
void tms9995_device::set_hold_state(bool state)
{
if (m_hold_state != state)
- if (!m_holda_line.isnull()) m_holda_line(state? ASSERT_LINE : CLEAR_LINE);
+ if (!m_holda_line.isunset()) m_holda_line(state? ASSERT_LINE : CLEAR_LINE);
m_hold_state = state;
}
@@ -1952,8 +1949,10 @@ void tms9995_device::mem_write()
// will result in the data byte being written into the byte specifically addressed
// and random bits being written into the other byte of the decrementer."
- // So we just don't care about the low byte.
- if (m_address == 0xfffb) m_current_value >>= 8;
+ // Tests on a real 9995 show that both bytes have the same value
+ // after a byte operation
+ u16 decbyte = m_current_value & 0xff00;
+ m_current_value = decbyte | (decbyte >> 8);
// dito: "This also loads the Decrementing Register with the same count."
m_starting_count_storage_register = m_decrementer_value = m_current_value;
@@ -2741,7 +2740,7 @@ void tms9995_device::alu_external()
LOGMASKED(LOG_OP, "RSET, new ST = %04x\n", ST);
}
- if (!m_external_operation.isnull())
+ if (!m_external_operation.isunset())
m_external_operation((IR >> 5) & 0x07, 1, 0xff);
}
@@ -3250,7 +3249,7 @@ void tms9995_device::alu_single_arithm()
set_status_bit(ST_OV, src_val == 0x8000);
break;
case SWPB:
- m_current_value = ((m_current_value << 8) | (m_current_value >> 8)) & 0xffff;
+ m_current_value = swapendian_int16(m_current_value);
// I don't know what they are doing right now, but we lose a lot of cycles
// according to the spec (which can indeed be proved on a real system)