From c8dee62d29d615e4a587c2864d1bea47441ed717 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Fri, 5 Apr 2019 01:04:40 +0200 Subject: tms9900: Modernized logging, fixed LDCR/STCR handling of reg indirect/auto-inc mode (*Rx+) --- src/devices/cpu/tms9900/tms9900.cpp | 234 ++++++++++++++++++------------------ src/devices/cpu/tms9900/tms9900.h | 4 +- 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(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; -- cgit v1.2.3