summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Michael Zapf <Michael.Zapf@mizapf.de>2019-04-05 01:04:40 +0200
committer Michael Zapf <Michael.Zapf@mizapf.de>2019-04-05 01:07:05 +0200
commitc8dee62d29d615e4a587c2864d1bea47441ed717 (patch)
treec1be1f87c902aa00293a0ba7842e5174ce7fd76b
parent7dc12c21eda416e1ff9297f82c97d0eb5cbed112 (diff)
tms9900: Modernized logging, fixed LDCR/STCR handling of reg indirect/auto-inc mode (*Rx+)
-rw-r--r--src/devices/cpu/tms9900/tms9900.cpp234
-rw-r--r--src/devices/cpu/tms9900/tms9900.h4
2 files changed, 120 insertions, 118 deletions
diff --git a/src/devices/cpu/tms9900/tms9900.cpp b/src/devices/cpu/tms9900/tms9900.cpp
index 7e831ec2395..50e7f1cc058 100644
--- a/src/devices/cpu/tms9900/tms9900.cpp
+++ b/src/devices/cpu/tms9900/tms9900.cpp
@@ -96,15 +96,6 @@
for some time set by a timer. This is done, for example, by circuits like
GROMs or speech synthesis processors (TMS52xx).
- TODO:
- - Fine-tune cycles
- - State save
- - HOLD state should be tested; I don't have test cases yet
-
-
- Previous implementation with valuable info inside:
- https://github.com/mamedev/mame/blob/677ec78eb50decdc40fad3d30daa3560feaff3cc/src/devices/cpu/tms9900/99xxcore.h
-
Michael Zapf, June 2012
*/
@@ -133,44 +124,31 @@ enum
The following defines can be set to 0 or 1 to disable or enable certain
output in the log.
*/
-// Emulation setup
-#define TRACE_SETUP 0
-
-// Emulation details
-#define TRACE_EMU 0
-
-// Location and command
-#define TRACE_EXEC 0
-
-// Memory operation
-#define TRACE_MEM 0
-
-// Address bus operation
-#define TRACE_ADDRESSBUS 0
-
-// Cycle count
-#define TRACE_CYCLES 0
-
-// Clock ticks
-#define TRACE_CLOCK 0
-
-// Wait states
-#define TRACE_WAIT 0
-
-// Interrupts
-#define TRACE_INT 0
-
-// CRU operation
-#define TRACE_CRU 0
-
-// Status register
-#define TRACE_STATUS 0
-
-// ALU details
-#define TRACE_ALU 0
-
-// Microinstruction level
-#define TRACE_MICRO 0
+#define LOG_OP (1U<<1) // Current instruction
+#define LOG_EXEC (1U<<2) // Address of current instruction
+#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_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_LOAD (1U<<21) // LOAD interrupt
+#define LOG_DETAIL (1U<<31) // Increased detail
+
+// Minimum log should be warnings
+#define VERBOSE ( LOG_GENERAL | LOG_WARN )
+
+#include "logmacro.h"
/****************************************************************************
Common constructor for TMS9900 and TMS9980A
@@ -264,6 +242,7 @@ void tms99xx_device::device_start()
save_item(NAME(m_mem_phase));
save_item(NAME(m_load_state));
save_item(NAME(m_irq_state));
+ save_item(NAME(m_log_interrupt));
save_item(NAME(m_reset));
save_item(NAME(m_irq_level));
// save_item(NAME(m_first_cycle)); // only for log output
@@ -320,12 +299,13 @@ void tms99xx_device::resolve_lines()
*/
void tms99xx_device::device_reset()
{
- if (TRACE_EMU) logerror("Device reset by emulator\n");
+ LOGMASKED(LOG_EMU, "Device reset by emulator\n");
m_reset = true;
m_check_ready = false;
m_wait_state = false;
ST = 0;
m_irq_state = false;
+ m_log_interrupt = false; // only for debugging
}
char const *const tms99xx_device::s_statename[20] =
@@ -1110,7 +1090,7 @@ void tms99xx_device::build_command_lookup_table()
{
inst = &s_command[i];
table = m_command_lookup_table.get();
- if (TRACE_SETUP) logerror("=== opcode=%04x, len=%d\n", inst->opcode, format_mask_len[inst->format]);
+ LOGMASKED(LOG_EMU, "=== opcode=%04x, len=%d\n", inst->opcode, format_mask_len[inst->format]);
bitcount = 4;
opcode = inst->opcode;
cmdindex = (opcode>>12) & 0x000f;
@@ -1120,7 +1100,7 @@ void tms99xx_device::build_command_lookup_table()
// Descend
if (table[cmdindex].next_digit == nullptr)
{
- if (TRACE_SETUP) logerror("create new table at bitcount=%d for index=%d\n", bitcount, cmdindex);
+ LOGMASKED(LOG_EMU, "create new table at bitcount=%d for index=%d\n", bitcount, cmdindex);
table[cmdindex].next_digit = std::make_unique<lookup_entry[]>(16);
for (int j=0; j < 16; j++)
{
@@ -1130,7 +1110,7 @@ void tms99xx_device::build_command_lookup_table()
}
else
{
- if (TRACE_SETUP) logerror("found a table at bitcount=%d\n", bitcount);
+ LOGMASKED(LOG_EMU, "found a table at bitcount=%d\n", bitcount);
}
table = table[cmdindex].next_digit.get();
@@ -1138,17 +1118,17 @@ void tms99xx_device::build_command_lookup_table()
bitcount = bitcount+4;
opcode <<= 4;
cmdindex = (opcode>>12) & 0x000f;
- if (TRACE_SETUP) logerror("next index=%x\n", cmdindex);
+ LOGMASKED(LOG_EMU, "next index=%x\n", cmdindex);
}
- if (TRACE_SETUP) logerror("bitcount=%d\n", bitcount);
+ LOGMASKED(LOG_EMU, "bitcount=%d\n", bitcount);
// We are at the target level
// Need to fill in the same entry for all values in the bitcount
// (if a command needs 10 bits we have to copy it four
// times for all combinations with 12 bits)
for (int j=0; j < (1<<(bitcount-format_mask_len[inst->format])); j++)
{
- if (TRACE_SETUP) logerror("opcode=%04x at position %d\n", inst->opcode, cmdindex+j);
+ LOGMASKED(LOG_EMU, "opcode=%04x at position %d\n", inst->opcode, cmdindex+j);
table[cmdindex+j].index = i;
}
i++;
@@ -1197,7 +1177,7 @@ void tms99xx_device::execute_run()
{
if (m_reset) service_interrupt();
- if (TRACE_EMU) logerror("calling execute_run for %d cycles\n", m_icount);
+ LOGMASKED(LOG_EMU, "calling execute_run for %d cycles\n", m_icount);
do
{
// Only when last instruction has completed
@@ -1205,7 +1185,6 @@ void tms99xx_device::execute_run()
{
if (m_load_state)
{
- logerror("LOAD interrupt\n");
m_irq_level = LOAD_INT;
m_irq_state = false;
service_interrupt();
@@ -1223,7 +1202,7 @@ void tms99xx_device::execute_run()
if (m_program_index == NOPRG && m_idle_state)
{
- if (TRACE_WAIT) logerror("idle state\n");
+ LOGMASKED(LOG_IDLE, "IDLE state\n");
pulse_clock(1);
if (!m_external_operation.isnull())
{
@@ -1247,7 +1226,7 @@ void tms99xx_device::execute_run()
program[MPC] != MEMORY_READ && program[MPC] != MEMORY_WRITE &&
program[MPC] != REG_READ && program[MPC] != REG_WRITE)))
{
- if (TRACE_WAIT) logerror("hold\n");
+ LOGMASKED(LOG_HOLD, "HOLD state\n");
if (!m_hold_acknowledged) acknowledge_hold();
pulse_clock(1);
}
@@ -1258,7 +1237,7 @@ void tms99xx_device::execute_run()
{
// We are in a wait state
set_wait_state(true);
- if (TRACE_WAIT) logerror("wait\n");
+ LOGMASKED(LOG_WAIT, "wait state\n");
// The clock output should be used to change the state of an outer
// device which operates the READY line
pulse_clock(1);
@@ -1270,7 +1249,7 @@ void tms99xx_device::execute_run()
// If we don't have a microprogram, acquire the next instruction
uint8_t op = (m_program_index==NOPRG)? IAQ : program[MPC];
- if (TRACE_MICRO) logerror("MPC = %d, op = %d\n", MPC, op);
+ LOGMASKED(LOG_MICRO, "MPC = %d, op = %d\n", MPC, op);
// Call the operation of the microprogram
(this->*s_microoperation[op])();
// If we have multiple passes (as in the TMS9980)
@@ -1286,7 +1265,7 @@ void tms99xx_device::execute_run()
}
}
} while (m_icount>0 && !m_reset);
- if (TRACE_EMU) logerror("cycles expired; will return soon.\n");
+ LOGMASKED(LOG_EMU, "cycles expired; will return soon.\n");
}
/**************************************************************************/
@@ -1305,7 +1284,7 @@ void tms99xx_device::execute_set_input(int irqline, int state)
if (irqline == INT_9900_LOAD)
{
m_load_state = (state==ASSERT_LINE);
- m_irq_level = -1;
+ m_irq_level = LOAD_INT;
m_reset = false;
}
else
@@ -1314,11 +1293,11 @@ void tms99xx_device::execute_set_input(int irqline, int state)
if (state==ASSERT_LINE)
{
m_irq_level = get_intlevel(state);
- if (TRACE_INT) logerror("/INT asserted, level=%d, ST=%04x\n", m_irq_level, ST);
+ LOGMASKED(LOG_INT, "/INT asserted, level=%d, ST=%04x\n", m_irq_level, ST);
}
else
{
- if (TRACE_INT) logerror("/INT cleared\n");
+ LOGMASKED(LOG_INT, "/INT cleared\n");
}
}
}
@@ -1343,13 +1322,14 @@ void tms99xx_device::service_interrupt()
m_state = 0;
- if (!m_dbin_line.isnull()) m_dbin_line(ASSERT_LINE);
-
// If reset, we just start with execution, otherwise we put the MPC
// on the first microinstruction, which also means that the main loop shall
// leave it where it is. So we pretend we have another pass to do.
m_pass = m_reset? 1 : 2;
+ // just for debugging purposes
+ if (!m_reset) m_log_interrupt = true;
+
if (m_reset)
{
m_irq_level = RESET_INT;
@@ -1365,15 +1345,14 @@ void tms99xx_device::service_interrupt()
m_mem_phase = 1;
m_reset = false;
+ LOG("** RESET triggered\n");
}
- if (TRACE_INT)
+ else
{
- switch (m_irq_level)
- {
- case RESET_INT: logerror("**** triggered a RESET interrupt\n"); break;
- case LOAD_INT: logerror("**** triggered a LOAD (NMI) interrupt\n"); break;
- default: logerror("** triggered an interrupt on level %d\n", m_irq_level); break;
- }
+ if (m_irq_level==LOAD_INT)
+ LOGMASKED(LOG_LOAD, "** LOAD interrupt triggered\n");
+ else
+ LOGMASKED(LOG_INTD, "** Interrupt on level %d\n", m_irq_level);
}
MPC = 0;
@@ -1391,11 +1370,8 @@ void tms99xx_device::pulse_clock(int count)
m_ready = m_ready_bufd; // get the latched READY state
if (!m_clock_out_line.isnull()) m_clock_out_line(CLEAR_LINE);
m_icount--; // This is the only location where we count down the cycles.
- if (TRACE_CLOCK)
- {
- if (m_check_ready) logerror("pulse_clock, READY=%d\n", m_ready? 1:0);
- else logerror("pulse_clock\n");
- }
+ if (m_check_ready) LOGMASKED(LOG_CLOCK, "pulse_clock, READY=%d\n", m_ready? 1:0);
+ else LOGMASKED(LOG_CLOCK, "pulse_clock\n");
}
}
@@ -1427,7 +1403,20 @@ inline void tms99xx_device::acknowledge_hold()
*/
void tms99xx_device::set_ready(int state)
{
- m_ready_bufd = (state==ASSERT_LINE);
+ bool newready = (state==ASSERT_LINE);
+
+ if (newready != m_ready_bufd)
+ {
+ if (m_reset)
+ {
+ LOGMASKED(LOG_WARN, "Ignoring READY=%d change due to pending RESET\n", state);
+ }
+ else
+ {
+ m_ready_bufd = newready;
+ LOGMASKED(LOG_READY, "set READY = %d\n", m_ready_bufd? 1 : 0);
+ }
+ }
}
void tms99xx_device::abort_operation()
@@ -1464,7 +1453,7 @@ void tms99xx_device::decode(uint16_t inst)
while (!complete)
{
ix = (opcode >> 12) & 0x000f;
- if (TRACE_MICRO) logerror("Check next hex digit of instruction %x\n", ix);
+ LOGMASKED(LOG_MICRO, "Check next hex digit of instruction %x\n", ix);
if (table[ix].next_digit != nullptr)
{
table = table[ix].next_digit.get();
@@ -1476,7 +1465,7 @@ void tms99xx_device::decode(uint16_t inst)
if (m_program_index == NOPRG)
{
// not found
- logerror("Address %04x: Illegal opcode %04x\n", PC, inst);
+ LOGMASKED(LOG_WARN, "** %04x: Illegal opcode %04x\n", PC, inst);
IR = 0;
// This will cause another instruction acquisition in the next machine cycle
// with an asserted IAQ line (can be used to indicate this illegal opcode detection).
@@ -1486,11 +1475,13 @@ void tms99xx_device::decode(uint16_t inst)
const tms_instruction decoded = s_command[m_program_index];
MPC = -1;
m_command = decoded.id;
- if (TRACE_MICRO) logerror("Command decoded as id %d, %s, base opcode %04x\n", m_command, opname[m_command], decoded.opcode);
+ LOGMASKED(LOG_OP, "=== %04x: Op=%04x (%s)\n", PC, IR, opname[m_command]);
+
// Byte operations are either format 1 with the byte flag set
// or format 4 (CRU multi bit operations) with 1-8 bits to transfer.
+ // Used by the data derivation sequence.
m_byteop = ((decoded.format==1 && ((IR & 0x1000)!=0))
- || (decoded.format==4 && (((IR >> 6)&0x000f) > 0) && (((IR >> 6)&0x000f) > 9)));
+ || (decoded.format==4 && (((IR >> 6)&0x000f) > 0) && (((IR >> 6)&0x000f) < 9)));
}
m_pass = 1;
}
@@ -1514,7 +1505,13 @@ void tms99xx_device::acquire_instruction()
if (m_mem_phase == 1)
{
decode(m_current_value);
- if (TRACE_EXEC) logerror("%04x: %04x (%s)\n", PC, IR, opname[m_command]);
+
+ // Mark logged address as interrupt service
+ if (m_log_interrupt)
+ LOGMASKED(LOG_EXEC, "i%04x\n", PC);
+ else
+ LOGMASKED(LOG_EXEC, "%04x\n", PC);
+
debugger_instruction_hook(PC);
PC = (PC + 2) & 0xfffe & m_prgaddr_mask;
// IAQ will be cleared in the main loop
@@ -1539,7 +1536,7 @@ void tms99xx_device::mem_read()
m_check_ready = true;
m_mem_phase = 2;
m_pass = 2;
- if (TRACE_ADDRESSBUS) logerror("set address (r) %04x\n", m_address);
+ LOGMASKED(LOG_ADDRESSBUS, "set address (r) %04x\n", m_address);
pulse_clock(1); // Concludes the first cycle
// If READY has been found to be low, the CPU will now stay in the wait state loop
@@ -1551,7 +1548,7 @@ void tms99xx_device::mem_read()
pulse_clock(1);
if (!m_dbin_line.isnull()) m_dbin_line(CLEAR_LINE);
m_mem_phase = 1; // reset to phase 1
- if (TRACE_MEM) logerror("mem r %04x -> %04x\n", m_address, m_current_value);
+ LOGMASKED(LOG_MEM, "mem r %04x -> %04x\n", m_address, m_current_value);
}
}
@@ -1561,10 +1558,10 @@ void tms99xx_device::mem_write()
{
if (!m_dbin_line.isnull()) m_dbin_line(CLEAR_LINE);
// When writing, the data bus is asserted immediately after the address bus
- if (TRACE_ADDRESSBUS) logerror("set address (w) %04x\n", m_address);
+ LOGMASKED(LOG_ADDRESSBUS, "set address (w) %04x\n", m_address);
if (m_setaddr)
m_setaddr->write_word(CLEAR_LINE, m_address & m_prgaddr_mask & 0xfffe);
- if (TRACE_MEM) logerror("mem w %04x <- %04x\n", m_address, m_current_value);
+ LOGMASKED(LOG_MEM, "mem w %04x <- %04x\n", m_address, m_current_value);
m_prgspace->write_word(m_address & m_prgaddr_mask & 0xfffe, m_current_value);
m_check_ready = true;
m_mem_phase = 2;
@@ -1660,7 +1657,7 @@ void tms99xx_device::cru_input_operation()
if (cruin)
value |= 1 << i;
- if (TRACE_CRU) logerror("CRU input operation, address %04x, value %d\n", cruaddr, cruin ? 1 : 0);
+ LOGMASKED(LOG_CRU, "CRU input operation, address %04x, value %d\n", cruaddr, cruin ? 1 : 0);
// Increment the CRU address
cruaddr = (cruaddr + 2) & m_cruaddr_mask;
@@ -1680,7 +1677,7 @@ void tms99xx_device::cru_output_operation()
// Write m_count bits from cru_address
for (int i = 0; i < m_count; i++)
{
- if (TRACE_CRU) logerror("CRU output operation, address %04x, value %d\n", cruaddr, BIT(value, 0));
+ LOGMASKED(LOG_CRU, "CRU output operation, address %04x, value %d\n", cruaddr, BIT(value, 0));
// Write one bit at a time
m_cru->write_byte(cruaddr, BIT(value, 0));
@@ -1706,13 +1703,13 @@ void tms99xx_device::return_from_subprogram()
void tms99xx_device::command_completed()
{
// Pseudo state at the end of the current instruction cycle sequence
- if (TRACE_CYCLES)
+ if (LOG_CYCLES & VERBOSE)
{
- logerror("------");
+ logerror("+++ Instruction %04x (%s) completed", IR, opname[m_command]);
int cycles = m_first_cycle - m_icount;
// Avoid nonsense values due to expired and resumed main loop
- if (cycles > 0 && cycles < 10000) logerror(" %d cycles", cycles);
- logerror("\n");
+ if (cycles > 0 && cycles < 10000) logerror(", %d cycles", cycles);
+ logerror("+++\n");
}
m_program_index = NOPRG;
}
@@ -1773,7 +1770,7 @@ inline void tms99xx_device::compare_and_set_lae(uint16_t value1, uint16_t value2
set_status_bit(ST_EQ, value1 == value2);
set_status_bit(ST_LH, value1 > value2);
set_status_bit(ST_AGT, (int16_t)value1 > (int16_t)value2);
- if (TRACE_STATUS) logerror("ST = %04x (val1=%04x, val2=%04x)\n", ST, value1, value2);
+ LOGMASKED(LOG_STATUS, "ST = %04x (val1=%04x, val2=%04x)\n", ST, value1, value2);
}
/**************************************************************************
@@ -2010,7 +2007,7 @@ void tms99xx_device::alu_f3()
compare_and_set_lae(m_current_value, 0);
}
}
- if (TRACE_STATUS) logerror("ST = %04x\n", ST);
+ LOGMASKED(LOG_STATUS, "ST = %04x\n", ST);
break;
}
@@ -2029,7 +2026,6 @@ void tms99xx_device::alu_multiply()
m_address = ((IR >> 5) & 0x001e) + WP;
break;
case 1: // After reading the register (multiplier)
- if (TRACE_ALU) logerror("Multiply %04x by %04x\n", m_current_value, m_source_value);
result = (m_source_value & 0x0000ffff) * (m_current_value & 0x0000ffff);
m_current_value = (result >> 16) & 0xffff;
m_value_copy = result & 0xffff;
@@ -2078,12 +2074,8 @@ void tms99xx_device::alu_divide()
// Create full word and perform division
uval32 = (m_value_copy << 16) | m_current_value;
- if (TRACE_ALU) logerror("Dividing %08x by %04x\n", uval32, m_source_value);
m_current_value = uval32 / m_source_value;
m_value_copy = uval32 % m_source_value;
-
- if (TRACE_ALU) logerror("Quotient %04x, remainder %04x\n", m_current_value, m_value_copy);
-
m_address = m_address_copy;
// The number of ALU cycles depends on the number of steps in
@@ -2108,7 +2100,7 @@ void tms99xx_device::alu_divide()
// Prepare to write the remainder
m_current_value = m_value_copy;
m_address = m_address + 2;
- if (TRACE_STATUS) logerror("ST = %04x (div)\n", ST);
+ LOGMASKED(LOG_STATUS, "ST = %04x (div)\n", ST);
break;
}
pulse_clock(2);
@@ -2260,13 +2252,12 @@ void tms99xx_device::alu_abs()
void tms99xx_device::alu_x()
{
- if (TRACE_ALU) logerror("Substituting current command by %04x\n", m_current_value);
decode(m_current_value);
pulse_clock(2);
}
/*
- Also used by other microprograms
+ Used by B and BL
*/
void tms99xx_device::alu_b()
{
@@ -2280,7 +2271,6 @@ void tms99xx_device::alu_b()
m_current_value = PC;
PC = m_address & m_prgaddr_mask & 0xfffe;
m_address = WP + 22;
- if (TRACE_ALU) logerror("Set new PC = %04x\n", PC);
pulse_clock(2);
}
@@ -2308,7 +2298,7 @@ void tms99xx_device::alu_blwp()
break;
case 4:
PC = m_current_value & m_prgaddr_mask & 0xfffe;
- if (TRACE_ALU) logerror("tms9900: Context switch complete; WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
+ LOGMASKED(LOG_CONTEXT, "Context switch (blwp): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
break;
}
pulse_clock(2);
@@ -2350,7 +2340,7 @@ void tms99xx_device::alu_ldcr()
}
m_cru_address = m_current_value;
m_value = value;
- if (TRACE_CRU) logerror("Load CRU address %04x (%d bits), value = %04x\n", m_cru_address, m_count, m_value);
+ LOGMASKED(LOG_CRU, "Load CRU address %04x (%d bits), value = %04x\n", m_cru_address, m_count, m_value);
}
m_state++;
pulse_clock(2);
@@ -2382,7 +2372,7 @@ void tms99xx_device::alu_stcr()
value = m_value & 0xffff;
if (m_count < 9)
{
- if (TRACE_CRU) logerror("Store CRU at %04x (%d bits) in %04x, result = %02x\n", m_cru_address, m_count, m_source_address, value);
+ LOGMASKED(LOG_CRU, "Store CRU at %04x (%d bits) in %04x, result = %02x\n", m_cru_address, m_count, m_source_address, value);
set_status_parity((uint8_t)(value & 0xff));
compare_and_set_lae(value<<8, 0);
if (m_source_even)
@@ -2394,7 +2384,7 @@ void tms99xx_device::alu_stcr()
}
else
{
- if (TRACE_CRU) logerror("Store CRU at %04x (%d bits) in %04x, result = %04x\n", m_cru_address, m_count, m_source_address, value);
+ LOGMASKED(LOG_CRU, "Store CRU at %04x (%d bits) in %04x, result = %04x\n", m_cru_address, m_count, m_source_address, value);
m_current_value = value;
compare_and_set_lae(value, 0);
pulse_clock(2*(5 + (16-m_count)));
@@ -2440,7 +2430,7 @@ void tms99xx_device::alu_tb()
break;
case 2:
set_status_bit(ST_EQ, m_value!=0);
- if (TRACE_STATUS) logerror("ST = %04x\n", ST);
+ LOGMASKED(LOG_STATUS, "ST = %04x\n", ST);
break;
}
m_state++;
@@ -2498,11 +2488,11 @@ void tms99xx_device::alu_jmp()
}
if (!cond)
{
- if (TRACE_ALU) logerror("Jump condition false\n");
+ LOGMASKED(LOG_DETAIL, "Jump condition false\n");
MPC+=1; // skip next ALU call
}
else
- if (TRACE_ALU) logerror("Jump condition true\n");
+ LOGMASKED(LOG_DETAIL, "Jump condition true\n");
}
else
{
@@ -2544,7 +2534,7 @@ void tms99xx_device::alu_shift()
}
else
{
- if (TRACE_ALU) logerror("Shift operation gets count from R0\n");
+ LOGMASKED(LOG_DETAIL, "Shift operation gets count from R0\n");
pulse_clock(2);
}
pulse_clock(2);
@@ -2594,7 +2584,7 @@ void tms99xx_device::alu_shift()
if (check_ov) set_status_bit(ST_OV, overflow); // only SLA
compare_and_set_lae(m_current_value, 0);
m_address = m_address_saved; // Register address
- if (TRACE_STATUS) logerror("ST = %04x (val=%04x)\n", ST, m_current_value);
+ LOGMASKED(LOG_STATUS, "ST = %04x (val=%04x)\n", ST, m_current_value);
break;
}
m_state++;
@@ -2645,7 +2635,7 @@ void tms99xx_device::alu_lwpi()
void tms99xx_device::alu_limi()
{
ST = (ST & 0xfff0) | (m_current_value & 0x000f);
- if (TRACE_STATUS) logerror("ST = %04x\n", ST);
+ LOGMASKED(LOG_STATUS, "ST = %04x\n", ST);
pulse_clock(2);
}
@@ -2693,6 +2683,9 @@ void tms99xx_device::alu_rtwp()
case 3:
WP = m_current_value & m_prgaddr_mask & 0xfffe;
pulse_clock(2);
+ // Just for debugging purposes
+ m_log_interrupt = false;
+ LOGMASKED(LOG_CONTEXT, "Context switch (rtwp): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
break;
}
m_state++;
@@ -2701,7 +2694,6 @@ void tms99xx_device::alu_rtwp()
void tms99xx_device::alu_int()
{
- if (TRACE_EMU) logerror("INT state %d; irq_level %d\n", m_state, m_irq_level);
switch (m_state)
{
case 0:
@@ -2715,6 +2707,7 @@ void tms99xx_device::alu_int()
if (m_irq_level == LOAD_INT) m_address = 0xfffc; // will be truncated for TMS9980
else
{
+ LOGMASKED(LOG_INTD, "interrupt service (0): Prepare to read vector\n");
m_address = (m_irq_level << 2);
}
}
@@ -2725,18 +2718,21 @@ void tms99xx_device::alu_int()
WP = m_current_value & m_prgaddr_mask & 0xfffe; // new WP
m_current_value = ST;
m_address = (WP + 30) & m_prgaddr_mask;
+ LOGMASKED(LOG_INTD, "interrupt service (1): Read new WP = %04x, save ST to %04x\n", WP, m_address);
break;
case 2:
m_current_value = PC;
m_address = (WP + 28) & m_prgaddr_mask;
+ LOGMASKED(LOG_INTD, "interrupt service (2): Save PC to %04x\n", m_address);
break;
case 3:
m_current_value = m_value_copy; // old WP
m_address = (WP + 26) & m_prgaddr_mask;
+ LOGMASKED(LOG_INTD, "interrupt service (3): Save WP to %04x\n", m_address);
break;
case 4:
m_address = (m_address_copy + 2) & 0xfffe & m_prgaddr_mask;
- if (TRACE_ALU) logerror("read from %04x\n", m_address);
+ LOGMASKED(LOG_INTD, "interrupt service (4): Read PC from %04x\n", m_address);
break;
case 5:
PC = m_current_value & m_prgaddr_mask & 0xfffe;
@@ -2744,6 +2740,10 @@ void tms99xx_device::alu_int()
{
ST = (ST & 0xfff0) | (m_irq_level - 1);
}
+ if (m_irq_level == LOAD_INT)
+ LOGMASKED(LOG_LOAD, "Context switch (LOAD): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
+ else
+ LOGMASKED(LOG_CONTEXT, "Context switch (int): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
break;
}
m_state++;
diff --git a/src/devices/cpu/tms9900/tms9900.h b/src/devices/cpu/tms9900/tms9900.h
index aabf0356e56..6de920a95c4 100644
--- a/src/devices/cpu/tms9900/tms9900.h
+++ b/src/devices/cpu/tms9900/tms9900.h
@@ -298,7 +298,6 @@ private:
void alu_abs(void);
void alu_x(void);
void alu_b(void);
- //void alu_bl(void);
void alu_blwp(void);
void alu_ldcr(void);
void alu_stcr(void);
@@ -331,6 +330,9 @@ private:
// Index of the interrupt program
int m_interrupt_mp_index;
+ // For debugging only
+ bool m_log_interrupt;
+
// State of the micro-operation. Needed for repeated ALU calls.
int m_state;