mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
Fixed overflow detection in INC and DEC opcodes (nw)
This commit is contained in:
parent
efe49873d4
commit
3dfb3b76ed
@ -107,14 +107,14 @@
|
||||
/* tms9900 ST register bits. */
|
||||
enum
|
||||
{
|
||||
ST_LH = 0x8000, // Logical higher (unsigned comparison)
|
||||
ST_AGT = 0x4000, // Arithmetical greater than (signed comparison)
|
||||
ST_EQ = 0x2000, // Equal
|
||||
ST_C = 0x1000, // Carry
|
||||
ST_OV = 0x0800, // Overflow (when using signed operations)
|
||||
ST_OP = 0x0400, // Odd parity (used with byte operations)
|
||||
ST_X = 0x0200, // XOP
|
||||
ST_IM = 0x000f // Interrupt mask
|
||||
ST_LH = 0x8000, // Logical higher (unsigned comparison)
|
||||
ST_AGT = 0x4000, // Arithmetical greater than (signed comparison)
|
||||
ST_EQ = 0x2000, // Equal
|
||||
ST_C = 0x1000, // Carry
|
||||
ST_OV = 0x0800, // Overflow (when using signed operations)
|
||||
ST_OP = 0x0400, // Odd parity (used with byte operations)
|
||||
ST_X = 0x0200, // XOP
|
||||
ST_IM = 0x000f // Interrupt mask
|
||||
};
|
||||
|
||||
#define LOG logerror
|
||||
@ -128,12 +128,12 @@ enum
|
||||
|
||||
tms99xx_device::tms99xx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, int databus_width, int prg_addr_bits, int cru_addr_bits, device_t *owner, UINT32 clock)
|
||||
: cpu_device(mconfig, type, name, tag, owner, clock),
|
||||
m_program_config("program", ENDIANNESS_BIG, databus_width, prg_addr_bits),
|
||||
m_io_config("cru", ENDIANNESS_BIG, 8, cru_addr_bits),
|
||||
m_prgspace(NULL),
|
||||
m_cru(NULL),
|
||||
m_prgaddr_mask((1<<prg_addr_bits)-1),
|
||||
m_cruaddr_mask((1<<cru_addr_bits)-1)
|
||||
m_program_config("program", ENDIANNESS_BIG, databus_width, prg_addr_bits),
|
||||
m_io_config("cru", ENDIANNESS_BIG, 8, cru_addr_bits),
|
||||
m_prgspace(NULL),
|
||||
m_cru(NULL),
|
||||
m_prgaddr_mask((1<<prg_addr_bits)-1),
|
||||
m_cruaddr_mask((1<<cru_addr_bits)-1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ void tms99xx_device::device_start()
|
||||
|
||||
// TODO: Restore state save feature
|
||||
|
||||
m_prgspace = &space(AS_PROGRAM); // dimemory.h
|
||||
m_prgspace = &space(AS_PROGRAM); // dimemory.h
|
||||
m_cru = &space(AS_IO);
|
||||
|
||||
// Resolve our external connections
|
||||
@ -417,21 +417,21 @@ enum
|
||||
*/
|
||||
MICROPROGRAM(data_derivation)
|
||||
{
|
||||
REG_READ, RET, 0, 0, 0, 0, 0, 0, // Rx (00)
|
||||
REG_READ, RET, 0, 0, 0, 0, 0, 0, // Rx (00)
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
REG_READ, ALU_SETADDR, MEMORY_READ, RET, 0, 0, 0, 0, // *Rx (01)
|
||||
REG_READ, ALU_SETADDR, MEMORY_READ, RET, 0, 0, 0, 0, // *Rx (01)
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
ALU_CLR, ALU_PCADDR_ADVANCE, MEMORY_READ, ALU_ADDREG, MEMORY_READ, RET, 0, 0, // @sym (10)
|
||||
REG_READ, ALU_PCADDR_ADVANCE, MEMORY_READ, ALU_ADDREG, MEMORY_READ, RET, 0, 0, // @sym(Rx) (10)
|
||||
REG_READ, ALU_SETADDR_ADDONE, ALU_ADDONE, REG_WRITE, MEMORY_READ, RET, 0, 0, // *Rx+ (word) (11)
|
||||
REG_READ, ALU_SETADDR_ADDONE, REG_WRITE, MEMORY_READ, RET, 0, 0, 0 // *Rx+ (byte) (11)
|
||||
ALU_CLR, ALU_PCADDR_ADVANCE, MEMORY_READ, ALU_ADDREG, MEMORY_READ, RET, 0, 0, // @sym (10)
|
||||
REG_READ, ALU_PCADDR_ADVANCE, MEMORY_READ, ALU_ADDREG, MEMORY_READ, RET, 0, 0, // @sym(Rx) (10)
|
||||
REG_READ, ALU_SETADDR_ADDONE, ALU_ADDONE, REG_WRITE, MEMORY_READ, RET, 0, 0, // *Rx+ (word) (11)
|
||||
REG_READ, ALU_SETADDR_ADDONE, REG_WRITE, MEMORY_READ, RET, 0, 0, 0 // *Rx+ (byte) (11)
|
||||
};
|
||||
|
||||
MICROPROGRAM(f1_mp)
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE,
|
||||
ALU_SOURCE, // Store the word
|
||||
ALU_SOURCE, // Store the word
|
||||
DATA_DERIVE,
|
||||
ALU_F1,
|
||||
MEMORY_WRITE,
|
||||
@ -445,7 +445,7 @@ MICROPROGRAM(comp_mp)
|
||||
ALU_SOURCE,
|
||||
DATA_DERIVE,
|
||||
ALU_COMP,
|
||||
ALU_NOP, // Compare operations do not write back any data
|
||||
ALU_NOP, // Compare operations do not write back any data
|
||||
END
|
||||
};
|
||||
|
||||
@ -454,9 +454,9 @@ MICROPROGRAM(f3_mp)
|
||||
ALU_NOP,
|
||||
DATA_DERIVE,
|
||||
ALU_F3,
|
||||
MEMORY_READ, // We have to distinguish this from the C/CB microprogram above
|
||||
MEMORY_READ, // We have to distinguish this from the C/CB microprogram above
|
||||
ALU_F3,
|
||||
ALU_NOP, // Compare operations do not write back any data
|
||||
ALU_NOP, // Compare operations do not write back any data
|
||||
END
|
||||
};
|
||||
|
||||
@ -467,7 +467,7 @@ MICROPROGRAM(xor_mp)
|
||||
ALU_F3,
|
||||
MEMORY_READ,
|
||||
ALU_F3,
|
||||
MEMORY_WRITE, // XOR again must write back data, cannot reuse f3_mp
|
||||
MEMORY_WRITE, // XOR again must write back data, cannot reuse f3_mp
|
||||
END
|
||||
};
|
||||
|
||||
@ -475,11 +475,11 @@ MICROPROGRAM(mult_mp)
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE,
|
||||
ALU_MPY, // Save the value; put register number in m_regnumber
|
||||
ALU_MPY, // Save the value; put register number in m_regnumber
|
||||
MEMORY_READ,
|
||||
ALU_MPY, // 18 cycles for multiplication
|
||||
MEMORY_WRITE, // Write the high word
|
||||
ALU_MPY, // Get low word, increase m_address
|
||||
ALU_MPY, // 18 cycles for multiplication
|
||||
MEMORY_WRITE, // Write the high word
|
||||
ALU_MPY, // Get low word, increase m_address
|
||||
MEMORY_WRITE,
|
||||
END
|
||||
};
|
||||
@ -487,36 +487,36 @@ MICROPROGRAM(mult_mp)
|
||||
MICROPROGRAM(div_mp)
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE, // Get divisor
|
||||
ALU_DIV, // 0 Store divisor and get register number
|
||||
MEMORY_READ, // Read register
|
||||
ALU_DIV, // 1 Check overflow, increase address (or abort here)
|
||||
DATA_DERIVE, // Get divisor
|
||||
ALU_DIV, // 0 Store divisor and get register number
|
||||
MEMORY_READ, // Read register
|
||||
ALU_DIV, // 1 Check overflow, increase address (or abort here)
|
||||
ABORT,
|
||||
MEMORY_READ, // Read subsequent word (if reg=15 this is behind the workspace)
|
||||
ALU_DIV, // 2 Calculate quotient (takes variable amount of cycles; at least 32 machine cycles), set register number
|
||||
MEMORY_WRITE, // Write quotient into register
|
||||
ALU_DIV, // 3 Get remainder
|
||||
MEMORY_WRITE, // Write remainder
|
||||
MEMORY_READ, // Read subsequent word (if reg=15 this is behind the workspace)
|
||||
ALU_DIV, // 2 Calculate quotient (takes variable amount of cycles; at least 32 machine cycles), set register number
|
||||
MEMORY_WRITE, // Write quotient into register
|
||||
ALU_DIV, // 3 Get remainder
|
||||
MEMORY_WRITE, // Write remainder
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(xop_mp)
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE, // Get argument
|
||||
ALU_XOP, // 0 Save the address of the source operand, set address = 0x0040 + xopNr*4
|
||||
MEMORY_READ, // Read the new WP
|
||||
ALU_XOP, // 1 Save old WP, set new WP, get the source operand address
|
||||
MEMORY_WRITE, // Write the address of the source operand into the new R11
|
||||
ALU_XOP, // 2
|
||||
MEMORY_WRITE, // Write the ST into the new R15
|
||||
ALU_XOP, // 3
|
||||
MEMORY_WRITE, // Write the PC into the new R14
|
||||
ALU_XOP, // 4
|
||||
MEMORY_WRITE, // Write the WP into the new R13
|
||||
ALU_XOP, // 5 Set the X bit in the ST
|
||||
MEMORY_READ, // Read the new PC
|
||||
ALU_XOP, // 6 Set the new PC
|
||||
DATA_DERIVE, // Get argument
|
||||
ALU_XOP, // 0 Save the address of the source operand, set address = 0x0040 + xopNr*4
|
||||
MEMORY_READ, // Read the new WP
|
||||
ALU_XOP, // 1 Save old WP, set new WP, get the source operand address
|
||||
MEMORY_WRITE, // Write the address of the source operand into the new R11
|
||||
ALU_XOP, // 2
|
||||
MEMORY_WRITE, // Write the ST into the new R15
|
||||
ALU_XOP, // 3
|
||||
MEMORY_WRITE, // Write the PC into the new R14
|
||||
ALU_XOP, // 4
|
||||
MEMORY_WRITE, // Write the WP into the new R13
|
||||
ALU_XOP, // 5 Set the X bit in the ST
|
||||
MEMORY_READ, // Read the new PC
|
||||
ALU_XOP, // 6 Set the new PC
|
||||
ALU_NOP,
|
||||
END
|
||||
};
|
||||
@ -534,8 +534,8 @@ MICROPROGRAM(abs_mp)
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE,
|
||||
ALU_ABS, // two cycles
|
||||
MEMORY_WRITE, // skipped when ABS is not performed
|
||||
ALU_ABS, // two cycles
|
||||
MEMORY_WRITE, // skipped when ABS is not performed
|
||||
ALU_NOP,
|
||||
END
|
||||
};
|
||||
@ -548,7 +548,7 @@ MICROPROGRAM(x_mp)
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(b_mp) // Branch
|
||||
MICROPROGRAM(b_mp) // Branch
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE,
|
||||
@ -556,7 +556,7 @@ MICROPROGRAM(b_mp) // Branch
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(bl_mp) // Branch and Link
|
||||
MICROPROGRAM(bl_mp) // Branch and Link
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE,
|
||||
@ -566,19 +566,19 @@ MICROPROGRAM(bl_mp) // Branch and Link
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(blwp_mp) // Branch and Load WP
|
||||
MICROPROGRAM(blwp_mp) // Branch and Load WP
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE, // Get argument
|
||||
ALU_BLWP, // 0 Save old WP, set new WP, save position
|
||||
MEMORY_WRITE, // write ST to R15
|
||||
ALU_BLWP, // 1
|
||||
MEMORY_WRITE, // write PC to R14
|
||||
ALU_BLWP, // 2
|
||||
MEMORY_WRITE, // write WP to R13
|
||||
ALU_BLWP, // 3 Get saved position
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_BLWP, // 4 Set new PC
|
||||
DATA_DERIVE, // Get argument
|
||||
ALU_BLWP, // 0 Save old WP, set new WP, save position
|
||||
MEMORY_WRITE, // write ST to R15
|
||||
ALU_BLWP, // 1
|
||||
MEMORY_WRITE, // write PC to R14
|
||||
ALU_BLWP, // 2
|
||||
MEMORY_WRITE, // write WP to R13
|
||||
ALU_BLWP, // 3 Get saved position
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_BLWP, // 4 Set new PC
|
||||
END
|
||||
};
|
||||
|
||||
@ -600,12 +600,12 @@ MICROPROGRAM(stcr_mp)
|
||||
{
|
||||
ALU_NOP,
|
||||
DATA_DERIVE,
|
||||
ALU_SOURCE, // Store address and value
|
||||
ALU_STCR, // 0 Set register_number = 12
|
||||
ALU_SOURCE, // Store address and value
|
||||
ALU_STCR, // 0 Set register_number = 12
|
||||
MEMORY_READ,
|
||||
ALU_STCR, // 1 Prepare CRU access
|
||||
ALU_STCR, // 1 Prepare CRU access
|
||||
CRU_INPUT,
|
||||
ALU_STCR, // 2 Create result; Cycles = 5 + (8-#C-1) or + (16-#C)
|
||||
ALU_STCR, // 2 Create result; Cycles = 5 + (8-#C-1) or + (16-#C)
|
||||
MEMORY_WRITE,
|
||||
END
|
||||
};
|
||||
@ -675,8 +675,8 @@ MICROPROGRAM(li_mp)
|
||||
{
|
||||
ALU_IMM,
|
||||
MEMORY_READ,
|
||||
ALU_LI, // sets status bits
|
||||
ALU_REG, // set register number
|
||||
ALU_LI, // sets status bits
|
||||
ALU_REG, // set register number
|
||||
MEMORY_WRITE,
|
||||
END
|
||||
};
|
||||
@ -686,7 +686,7 @@ MICROPROGRAM(lwpi_mp)
|
||||
ALU_IMM,
|
||||
MEMORY_READ,
|
||||
ALU_NOP,
|
||||
ALU_LWPI, // sets WP
|
||||
ALU_LWPI, // sets WP
|
||||
END
|
||||
};
|
||||
|
||||
@ -695,7 +695,7 @@ MICROPROGRAM(limi_mp)
|
||||
ALU_IMM,
|
||||
MEMORY_READ,
|
||||
ALU_NOP,
|
||||
ALU_LIMI, // sets interrupt mask in ST
|
||||
ALU_LIMI, // sets interrupt mask in ST
|
||||
ALU_NOP,
|
||||
ALU_NOP,
|
||||
END
|
||||
@ -715,7 +715,7 @@ MICROPROGRAM(external_mp)
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(rtwp_mp) // Problem: This makes RTWP use 8 instead of 7 machine cycles.
|
||||
MICROPROGRAM(rtwp_mp) // Problem: This makes RTWP use 8 instead of 7 machine cycles.
|
||||
{
|
||||
ALU_RTWP,
|
||||
MEMORY_READ,
|
||||
@ -730,17 +730,17 @@ MICROPROGRAM(rtwp_mp) // Problem: This makes RTWP use 8 instead of 7 machine cy
|
||||
MICROPROGRAM(int_mp)
|
||||
{
|
||||
ALU_NOP,
|
||||
ALU_INT, // 0 Set address = 0
|
||||
ALU_INT, // 0 Set address = 0
|
||||
MEMORY_READ,
|
||||
ALU_INT, // 1 Save old WP, set new WP, save position
|
||||
MEMORY_WRITE, // write ST to R15
|
||||
ALU_INT, // 2
|
||||
MEMORY_WRITE, // write PC to R14
|
||||
ALU_INT, // 3
|
||||
MEMORY_WRITE, // write WP to R13
|
||||
ALU_INT, // 4 Get saved position
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_INT, // 5 Set new PC
|
||||
ALU_INT, // 1 Save old WP, set new WP, save position
|
||||
MEMORY_WRITE, // write ST to R15
|
||||
ALU_INT, // 2
|
||||
MEMORY_WRITE, // write PC to R14
|
||||
ALU_INT, // 3
|
||||
MEMORY_WRITE, // write WP to R13
|
||||
ALU_INT, // 4 Get saved position
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_INT, // 5 Set new PC
|
||||
END
|
||||
};
|
||||
|
||||
@ -1246,7 +1246,7 @@ void tms99xx_device::pulse_clock(int count)
|
||||
{
|
||||
m_clock_out_line(ASSERT_LINE);
|
||||
m_clock_out_line(CLEAR_LINE);
|
||||
m_icount--; // This is the only location where we count down the cycles.
|
||||
m_icount--; // This is the only location where we count down the cycles.
|
||||
if (VERBOSE>7) LOG("tms99xx: pulse_clock\n");
|
||||
}
|
||||
}
|
||||
@ -1455,14 +1455,14 @@ void tms99xx_device::cru_input_operation()
|
||||
// Read 8 bits (containing the desired bits)
|
||||
value = m_cru->read_byte(location);
|
||||
|
||||
if ((offset + m_count) > 8) // spans two 8 bit cluster
|
||||
if ((offset + m_count) > 8) // spans two 8 bit cluster
|
||||
{
|
||||
// Read next 8 bits
|
||||
location = (location + 1) & (m_cruaddr_mask>>3);
|
||||
value1 = m_cru->read_byte(location);
|
||||
value |= (value1 << 8);
|
||||
|
||||
if ((offset + m_count) > 16) // spans three 8 bit cluster
|
||||
if ((offset + m_count) > 16) // spans three 8 bit cluster
|
||||
{
|
||||
// Read next 8 bits
|
||||
location = (location + 1) & (m_cruaddr_mask>>3);
|
||||
@ -1543,12 +1543,12 @@ void tms99xx_device::data_derivation_subprogram()
|
||||
m_program = (UINT8*)data_derivation;
|
||||
MPC = ircopy & 0x0030;
|
||||
|
||||
if (((MPC == 0x0020) && (m_regnumber != 0)) // indexed
|
||||
|| ((MPC == 0x0030) && m_byteop)) // byte operation
|
||||
if (((MPC == 0x0020) && (m_regnumber != 0)) // indexed
|
||||
|| ((MPC == 0x0030) && m_byteop)) // byte operation
|
||||
{
|
||||
MPC += 8; // the second option
|
||||
MPC += 8; // the second option
|
||||
}
|
||||
m_get_destination = true; // when we call this the second time before END it's the destination
|
||||
m_get_destination = true; // when we call this the second time before END it's the destination
|
||||
m_pass = 2;
|
||||
}
|
||||
|
||||
@ -1668,7 +1668,7 @@ void tms99xx_device::alu_f1()
|
||||
// Save the destination value
|
||||
UINT16 prev_dest_value = m_current_value;
|
||||
|
||||
m_destination_even = ((m_address & 1)==0); // this is the destination address; the source address has already been saved
|
||||
m_destination_even = ((m_address & 1)==0); // this is the destination address; the source address has already been saved
|
||||
bool byteop = byte_operation();
|
||||
|
||||
if (byteop)
|
||||
@ -1775,7 +1775,7 @@ void tms99xx_device::alu_f1()
|
||||
|
||||
void tms99xx_device::alu_comp()
|
||||
{
|
||||
m_destination_even = ((m_address & 1)==0); // this is the destination address; the source address has already been saved
|
||||
m_destination_even = ((m_address & 1)==0); // this is the destination address; the source address has already been saved
|
||||
if (byte_operation())
|
||||
{
|
||||
if (!m_destination_even) m_current_value <<= 8;
|
||||
@ -1840,10 +1840,10 @@ void tms99xx_device::alu_multiply()
|
||||
result = (m_source_value & 0x0000ffff) * (m_current_value & 0x0000ffff);
|
||||
m_current_value = (result >> 16) & 0xffff;
|
||||
m_value_copy = result & 0xffff;
|
||||
pulse_clock(34); // add 36 clock cycles (18 machine cycles); last one in main loop
|
||||
pulse_clock(34); // add 36 clock cycles (18 machine cycles); last one in main loop
|
||||
break;
|
||||
case 2: // After writing the high word to the destination register
|
||||
m_current_value = m_value_copy; // Prepare to save low word
|
||||
m_current_value = m_value_copy; // Prepare to save low word
|
||||
m_address = (m_address + 2) & m_prgaddr_mask;
|
||||
break;
|
||||
}
|
||||
@ -1861,7 +1861,7 @@ void tms99xx_device::alu_divide()
|
||||
switch (m_state)
|
||||
{
|
||||
case 0:
|
||||
m_source_value = m_current_value; // store divisor
|
||||
m_source_value = m_current_value; // store divisor
|
||||
// Set address of register
|
||||
m_address = WP + ((IR >> 5) & 0x001e);
|
||||
m_address_copy = m_address;
|
||||
@ -1871,14 +1871,14 @@ void tms99xx_device::alu_divide()
|
||||
// This is the case when the dividend / divisor >= 0x10000,
|
||||
// or equivalently, dividend / 0x10000 >= divisor
|
||||
|
||||
if (m_current_value < m_source_value) // also if source=0
|
||||
if (m_current_value < m_source_value) // also if source=0
|
||||
{
|
||||
MPC++; // skip the abort
|
||||
MPC++; // skip the abort
|
||||
overflow = false;
|
||||
}
|
||||
set_status_bit(ST_OV, overflow);
|
||||
m_value_copy = m_current_value; // Save the high word
|
||||
m_address = (m_address + 2) & m_prgaddr_mask; // Read next word
|
||||
m_value_copy = m_current_value; // Save the high word
|
||||
m_address = (m_address + 2) & m_prgaddr_mask; // Read next word
|
||||
break;
|
||||
case 2:
|
||||
// W2 is in m_current_value
|
||||
@ -1901,7 +1901,7 @@ void tms99xx_device::alu_divide()
|
||||
// we need as many cycles as it takes to
|
||||
// shift away the dividend. Thus, bigger dividends need more cycles.
|
||||
|
||||
pulse_clock(62); // one pulse is at the start, one at the end
|
||||
pulse_clock(62); // one pulse is at the start, one at the end
|
||||
value1 = m_value_copy & 0xffff;
|
||||
|
||||
while (value1 != 0)
|
||||
@ -1935,10 +1935,10 @@ void tms99xx_device::alu_xop()
|
||||
m_address = 0x0040 + ((IR >> 4) & 0x003c);
|
||||
break;
|
||||
case 1:
|
||||
m_value_copy = WP; // save the old WP
|
||||
WP = m_current_value & m_prgaddr_mask; // the new WP has been read in the previous microoperation
|
||||
m_current_value = m_address_saved; // we saved the address of the source operand; retrieve it
|
||||
m_address = WP + 0x0016; // Next register is R11
|
||||
m_value_copy = WP; // save the old WP
|
||||
WP = m_current_value & m_prgaddr_mask; // the new WP has been read in the previous microoperation
|
||||
m_current_value = m_address_saved; // we saved the address of the source operand; retrieve it
|
||||
m_address = WP + 0x0016; // Next register is R11
|
||||
break;
|
||||
case 2:
|
||||
m_address = WP + 0x001e;
|
||||
@ -1950,10 +1950,10 @@ void tms99xx_device::alu_xop()
|
||||
break;
|
||||
case 4:
|
||||
m_address = WP + 0x001a;
|
||||
m_current_value = m_value_copy; // old WP into new R13
|
||||
m_current_value = m_value_copy; // old WP into new R13
|
||||
break;
|
||||
case 5:
|
||||
m_address = 0x0042 + ((IR >> 4) & 0x003c); // location of new PC
|
||||
m_address = 0x0042 + ((IR >> 4) & 0x003c); // location of new PC
|
||||
set_status_bit(ST_X, true);
|
||||
break;
|
||||
case 6:
|
||||
@ -2030,7 +2030,7 @@ void tms99xx_device::alu_clr_swpb()
|
||||
|
||||
if (setstatus)
|
||||
{
|
||||
if (check_ov) set_status_bit(ST_OV, ((src_val & 0x8000)!=sign) && ((dest_new & 0x8000)==sign));
|
||||
if (check_ov) set_status_bit(ST_OV, ((src_val & 0x8000)==sign) && ((dest_new & 0x8000)!=sign));
|
||||
set_status_bit(ST_C, (dest_new & 0x10000) != 0);
|
||||
m_current_value = dest_new & 0xffff;
|
||||
compare_and_set_lae(m_current_value, 0);
|
||||
@ -2052,7 +2052,7 @@ void tms99xx_device::alu_abs()
|
||||
if ((m_current_value & 0x8000)!=0)
|
||||
{
|
||||
m_current_value = (((~m_current_value) & 0x0000ffff) + 1) & 0xffff;
|
||||
pulse_clock(2); // If ABS is performed it takes one machine cycle more
|
||||
pulse_clock(2); // If ABS is performed it takes one machine cycle more
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2093,21 +2093,21 @@ void tms99xx_device::alu_blwp()
|
||||
{
|
||||
case 0:
|
||||
m_value_copy = WP;
|
||||
WP = m_current_value & m_prgaddr_mask; // set new WP (*m_destination)
|
||||
m_address_saved = (m_address + 2) & m_prgaddr_mask; // Save the location of the WP
|
||||
WP = m_current_value & m_prgaddr_mask; // set new WP (*m_destination)
|
||||
m_address_saved = (m_address + 2) & m_prgaddr_mask; // Save the location of the WP
|
||||
m_address = WP + 30;
|
||||
m_current_value = ST; // get status register
|
||||
m_current_value = ST; // get status register
|
||||
break;
|
||||
case 1:
|
||||
m_current_value = PC; // get program counter
|
||||
m_current_value = PC; // get program counter
|
||||
m_address = m_address - 2;
|
||||
break;
|
||||
case 2:
|
||||
m_current_value = m_value_copy; // retrieve the old WP
|
||||
m_current_value = m_value_copy; // retrieve the old WP
|
||||
m_address = m_address - 2;
|
||||
break;
|
||||
case 3:
|
||||
m_address = m_address_saved; // point to PC component of branch vector
|
||||
m_address = m_address_saved; // point to PC component of branch vector
|
||||
break;
|
||||
case 4:
|
||||
PC = m_current_value & m_prgaddr_mask;
|
||||
@ -2138,7 +2138,7 @@ void tms99xx_device::alu_ldcr()
|
||||
}
|
||||
else
|
||||
{
|
||||
value = m_source_value; // copied by ALU_SOURCE
|
||||
value = m_source_value; // copied by ALU_SOURCE
|
||||
m_count = (IR >> 6) & 0x000f;
|
||||
if (m_count == 0) m_count = 16;
|
||||
if (m_count <= 8)
|
||||
@ -2264,37 +2264,37 @@ void tms99xx_device::alu_jmp()
|
||||
case JLT: // LAECOP == x00xxx
|
||||
cond = ((ST & (ST_AGT | ST_EQ))==0);
|
||||
break;
|
||||
case JLE: // LAECOP == 0xxxxx
|
||||
case JLE: // LAECOP == 0xxxxx
|
||||
cond = ((ST & ST_LH)==0);
|
||||
break;
|
||||
case JEQ: // LAECOP == xx1xxx
|
||||
case JEQ: // LAECOP == xx1xxx
|
||||
cond = ((ST & ST_EQ)!=0);
|
||||
break;
|
||||
case JHE: // LAECOP == 1x0xxx, 0x1xxx
|
||||
case JHE: // LAECOP == 1x0xxx, 0x1xxx
|
||||
cond = ((ST & (ST_LH | ST_EQ)) != 0);
|
||||
break;
|
||||
case JGT: // LAECOP == x1xxxx
|
||||
case JGT: // LAECOP == x1xxxx
|
||||
cond = ((ST & ST_AGT)!=0);
|
||||
break;
|
||||
case JNE: // LAECOP == xx0xxx
|
||||
case JNE: // LAECOP == xx0xxx
|
||||
cond = ((ST & ST_EQ)==0);
|
||||
break;
|
||||
case JNC: // LAECOP == xxx0xx
|
||||
case JNC: // LAECOP == xxx0xx
|
||||
cond = ((ST & ST_C)==0);
|
||||
break;
|
||||
case JOC: // LAECOP == xxx1xx
|
||||
case JOC: // LAECOP == xxx1xx
|
||||
cond = ((ST & ST_C)!=0);
|
||||
break;
|
||||
case JNO: // LAECOP == xxxx0x
|
||||
case JNO: // LAECOP == xxxx0x
|
||||
cond = ((ST & ST_OV)==0);
|
||||
break;
|
||||
case JL: // LAECOP == 0x0xxx
|
||||
case JL: // LAECOP == 0x0xxx
|
||||
cond = ((ST & (ST_LH | ST_EQ)) == 0);
|
||||
break;
|
||||
case JH: // LAECOP == 1xxxxx
|
||||
case JH: // LAECOP == 1xxxxx
|
||||
cond = ((ST & ST_LH)!=0);
|
||||
break;
|
||||
case JOP: // LAECOP == xxxxx1
|
||||
case JOP: // LAECOP == xxxxx1
|
||||
cond = ((ST & ST_OP)!=0);
|
||||
break;
|
||||
}
|
||||
@ -2302,7 +2302,7 @@ void tms99xx_device::alu_jmp()
|
||||
if (!cond)
|
||||
{
|
||||
if (VERBOSE>7) LOG("tms99xx: Jump condition false\n");
|
||||
MPC+=1; // skip next ALU call
|
||||
MPC+=1; // skip next ALU call
|
||||
}
|
||||
else
|
||||
if (VERBOSE>7) LOG("tms99xx: Jump condition true\n");
|
||||
@ -2385,7 +2385,7 @@ void tms99xx_device::alu_shift()
|
||||
set_status_bit(ST_C, carry);
|
||||
set_status_bit(ST_OV, overflow);
|
||||
compare_and_set_lae(m_current_value, 0);
|
||||
m_address = m_address_saved; // Register address
|
||||
m_address = m_address_saved; // Register address
|
||||
if (VERBOSE>7) LOG("tms99xx: ST = %04x (val=%04x)\n", ST, m_current_value);
|
||||
break;
|
||||
}
|
||||
@ -2473,15 +2473,15 @@ void tms99xx_device::alu_rtwp()
|
||||
switch (m_state)
|
||||
{
|
||||
case 0:
|
||||
m_address = WP + 30; // R15
|
||||
m_address = WP + 30; // R15
|
||||
break;
|
||||
case 1:
|
||||
ST = m_current_value;
|
||||
m_address -= 2; // R14
|
||||
m_address -= 2; // R14
|
||||
break;
|
||||
case 2:
|
||||
PC = m_current_value & m_prgaddr_mask;
|
||||
m_address -= 2; // R13
|
||||
m_address -= 2; // R13
|
||||
break;
|
||||
case 3:
|
||||
WP = m_current_value & m_prgaddr_mask;
|
||||
@ -2514,8 +2514,8 @@ void tms99xx_device::alu_int()
|
||||
break;
|
||||
case 1:
|
||||
m_address_copy = m_address;
|
||||
m_value_copy = WP; // old WP
|
||||
WP = m_current_value & m_prgaddr_mask; // new WP
|
||||
m_value_copy = WP; // old WP
|
||||
WP = m_current_value & m_prgaddr_mask; // new WP
|
||||
m_current_value = ST;
|
||||
m_address = (WP + 30) & m_prgaddr_mask;
|
||||
break;
|
||||
@ -2524,7 +2524,7 @@ void tms99xx_device::alu_int()
|
||||
m_address = (WP + 28) & m_prgaddr_mask;
|
||||
break;
|
||||
case 3:
|
||||
m_current_value = m_value_copy; // old WP
|
||||
m_current_value = m_value_copy; // old WP
|
||||
m_address = (WP + 26) & m_prgaddr_mask;
|
||||
break;
|
||||
case 4:
|
||||
|
@ -94,15 +94,15 @@
|
||||
/* tms9995 ST register bits. */
|
||||
enum
|
||||
{
|
||||
ST_LH = 0x8000, // Logical higher (unsigned comparison)
|
||||
ST_AGT = 0x4000, // Arithmetical greater than (signed comparison)
|
||||
ST_EQ = 0x2000, // Equal
|
||||
ST_C = 0x1000, // Carry
|
||||
ST_OV = 0x0800, // Overflow (when using signed operations)
|
||||
ST_OP = 0x0400, // Odd parity (used with byte operations)
|
||||
ST_X = 0x0200, // XOP
|
||||
ST_OE = 0x0020, // Overflow interrupt enabled
|
||||
ST_IM = 0x000f // Interrupt mask
|
||||
ST_LH = 0x8000, // Logical higher (unsigned comparison)
|
||||
ST_AGT = 0x4000, // Arithmetical greater than (signed comparison)
|
||||
ST_EQ = 0x2000, // Equal
|
||||
ST_C = 0x1000, // Carry
|
||||
ST_OV = 0x0800, // Overflow (when using signed operations)
|
||||
ST_OP = 0x0400, // Odd parity (used with byte operations)
|
||||
ST_X = 0x0200, // XOP
|
||||
ST_OE = 0x0020, // Overflow interrupt enabled
|
||||
ST_IM = 0x000f // Interrupt mask
|
||||
};
|
||||
|
||||
enum
|
||||
@ -124,10 +124,10 @@ enum
|
||||
|
||||
tms9995_device::tms9995_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: cpu_device(mconfig, TMS9995, "TMS9995", tag, owner, clock),
|
||||
m_program_config("program", ENDIANNESS_BIG, 8, 16),
|
||||
m_io_config("cru", ENDIANNESS_BIG, 8, 16),
|
||||
m_prgspace(NULL),
|
||||
m_cru(NULL)
|
||||
m_program_config("program", ENDIANNESS_BIG, 8, 16),
|
||||
m_io_config("cru", ENDIANNESS_BIG, 8, 16),
|
||||
m_prgspace(NULL),
|
||||
m_cru(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ void tms9995_device::device_start()
|
||||
|
||||
// TODO: Restore save state suport
|
||||
|
||||
m_prgspace = &space(AS_PROGRAM); // dimemory.h
|
||||
m_prgspace = &space(AS_PROGRAM); // dimemory.h
|
||||
m_cru = &space(AS_IO);
|
||||
|
||||
// Resolve our external connections
|
||||
@ -207,7 +207,7 @@ void tms9995_device::device_stop()
|
||||
*/
|
||||
void tms9995_device::device_reset()
|
||||
{
|
||||
m_reset = true; // for the main loop
|
||||
m_reset = true; // for the main loop
|
||||
}
|
||||
|
||||
const char* tms9995_device::s_statename[20] =
|
||||
@ -402,60 +402,60 @@ enum
|
||||
|
||||
MICROPROGRAM(operand_address_derivation)
|
||||
{
|
||||
RETADDR, 0, 0, 0, // Register direct 0
|
||||
WORD_READ, RETADDR, 0, 0, // Register indirect 1 (1)
|
||||
WORD_READ, RETADDR, 0, 0, // Symbolic 1 (1)
|
||||
WORD_READ, INCREG, WORD_WRITE, RETADDR1, // Reg indirect auto-increment 3 (1) (1)
|
||||
WORD_READ, INDX, WORD_READ, RETADDR // Indexed 3 (1) (1)
|
||||
RETADDR, 0, 0, 0, // Register direct 0
|
||||
WORD_READ, RETADDR, 0, 0, // Register indirect 1 (1)
|
||||
WORD_READ, RETADDR, 0, 0, // Symbolic 1 (1)
|
||||
WORD_READ, INCREG, WORD_WRITE, RETADDR1, // Reg indirect auto-increment 3 (1) (1)
|
||||
WORD_READ, INDX, WORD_READ, RETADDR // Indexed 3 (1) (1)
|
||||
};
|
||||
|
||||
MICROPROGRAM(add_s_sxc_mp)
|
||||
{
|
||||
OPERAND_ADDR, // x
|
||||
MEMORY_READ, // 1 (1)
|
||||
OPERAND_ADDR, // y
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_ADD_S_SXC, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
OPERAND_ADDR, // x
|
||||
MEMORY_READ, // 1 (1)
|
||||
OPERAND_ADDR, // y
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_ADD_S_SXC, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(b_mp)
|
||||
{
|
||||
OPERAND_ADDR,
|
||||
ALU_NOP, // Don't read, just use the address
|
||||
ALU_NOP, // Don't read, just use the address
|
||||
ALU_B,
|
||||
PREFETCH,
|
||||
ALU_NOP, // Don't save the return address
|
||||
ALU_NOP, // Don't save the return address
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(bl_mp)
|
||||
{
|
||||
OPERAND_ADDR,
|
||||
ALU_NOP, // Don't read, just use the address
|
||||
ALU_B, // Re-use the alu operation from B
|
||||
ALU_NOP, // Don't read, just use the address
|
||||
ALU_B, // Re-use the alu operation from B
|
||||
PREFETCH,
|
||||
ALU_NOP,
|
||||
MEMORY_WRITE, // Write R11
|
||||
MEMORY_WRITE, // Write R11
|
||||
ALU_NOP,
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(blwp_mp)
|
||||
{
|
||||
OPERAND_ADDR, // Determine source address
|
||||
OPERAND_ADDR, // Determine source address
|
||||
MEMORY_READ,
|
||||
ALU_BLWP, // Got new WP, save it; increase address, save
|
||||
MEMORY_WRITE, // save old ST to new R15
|
||||
ALU_BLWP, // Got new WP, save it; increase address, save
|
||||
MEMORY_WRITE, // save old ST to new R15
|
||||
ALU_BLWP,
|
||||
MEMORY_WRITE, // save old PC to new R14
|
||||
MEMORY_WRITE, // save old PC to new R14
|
||||
ALU_BLWP,
|
||||
MEMORY_WRITE, // save old WP to new R13
|
||||
ALU_BLWP, // retrieve address
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_BLWP, // Set new PC
|
||||
MEMORY_WRITE, // save old WP to new R13
|
||||
ALU_BLWP, // retrieve address
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_BLWP, // Set new PC
|
||||
PREFETCH,
|
||||
ALU_NOP,
|
||||
END
|
||||
@ -463,24 +463,24 @@ MICROPROGRAM(blwp_mp)
|
||||
|
||||
MICROPROGRAM(c_mp)
|
||||
{
|
||||
OPERAND_ADDR, // x
|
||||
MEMORY_READ, // 1 (1)
|
||||
OPERAND_ADDR, // y
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_C, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
ALU_NOP, // 1
|
||||
OPERAND_ADDR, // x
|
||||
MEMORY_READ, // 1 (1)
|
||||
OPERAND_ADDR, // y
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_C, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
ALU_NOP, // 1
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(ci_mp)
|
||||
{
|
||||
MEMORY_READ, // 1 (reg)
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (imm)
|
||||
ALU_CI, // (1) set status
|
||||
PREFETCH, // 1
|
||||
ALU_NOP, // 1
|
||||
MEMORY_READ, // 1 (reg)
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (imm)
|
||||
ALU_CI, // (1) set status
|
||||
PREFETCH, // 1
|
||||
ALU_NOP, // 1
|
||||
END
|
||||
};
|
||||
|
||||
@ -500,44 +500,44 @@ MICROPROGRAM(clr_seto_mp)
|
||||
{
|
||||
OPERAND_ADDR,
|
||||
ALU_NOP,
|
||||
ALU_CLR_SETO, // (1)
|
||||
PREFETCH, // 1
|
||||
MEMORY_WRITE, // 1
|
||||
ALU_CLR_SETO, // (1)
|
||||
PREFETCH, // 1
|
||||
MEMORY_WRITE, // 1
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(divide_mp)
|
||||
{
|
||||
OPERAND_ADDR, // Address of divisor S in Q=W1W2/S
|
||||
MEMORY_READ, // Get S
|
||||
OPERAND_ADDR, // Address of divisor S in Q=W1W2/S
|
||||
MEMORY_READ, // Get S
|
||||
ALU_DIV,
|
||||
MEMORY_READ, // Get W1
|
||||
ALU_DIV, // Check for overflow; skip next instruction if not
|
||||
MEMORY_READ, // Get W1
|
||||
ALU_DIV, // Check for overflow; skip next instruction if not
|
||||
ABORT,
|
||||
MEMORY_READ, // Get W2
|
||||
ALU_DIV, // Calculate quotient
|
||||
MEMORY_WRITE, // Write quotient to &W1
|
||||
MEMORY_READ, // Get W2
|
||||
ALU_DIV, // Calculate quotient
|
||||
MEMORY_WRITE, // Write quotient to &W1
|
||||
ALU_DIV,
|
||||
PREFETCH,
|
||||
MEMORY_WRITE, // Write remainder to &W2
|
||||
MEMORY_WRITE, // Write remainder to &W2
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(divide_signed_mp)
|
||||
{
|
||||
OPERAND_ADDR, // Address of divisor S in Q=W1W2/S
|
||||
MEMORY_READ, // Get S
|
||||
OPERAND_ADDR, // Address of divisor S in Q=W1W2/S
|
||||
MEMORY_READ, // Get S
|
||||
ALU_DIV,
|
||||
MEMORY_READ, // Get W1
|
||||
ALU_DIV, //
|
||||
MEMORY_READ, // Get W2
|
||||
ALU_DIV, // Check for overflow, skip next instruction if not
|
||||
MEMORY_READ, // Get W1
|
||||
ALU_DIV, //
|
||||
MEMORY_READ, // Get W2
|
||||
ALU_DIV, // Check for overflow, skip next instruction if not
|
||||
ABORT,
|
||||
ALU_DIV, // Calculate quotient
|
||||
MEMORY_WRITE, // Write quotient to &W1
|
||||
ALU_DIV, // Calculate quotient
|
||||
MEMORY_WRITE, // Write quotient to &W1
|
||||
ALU_DIV,
|
||||
PREFETCH,
|
||||
MEMORY_WRITE, // Write remainder to &W2
|
||||
MEMORY_WRITE, // Write remainder to &W2
|
||||
END
|
||||
};
|
||||
|
||||
@ -557,10 +557,10 @@ MICROPROGRAM(external_mp)
|
||||
MICROPROGRAM(imm_arithm_mp)
|
||||
{
|
||||
MEMORY_READ,
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_IMM_ARITHM, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_IMM_ARITHM, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
MEMORY_WRITE,
|
||||
END
|
||||
};
|
||||
@ -577,10 +577,10 @@ MICROPROGRAM(ldcr_mp)
|
||||
{
|
||||
ALU_LDCR,
|
||||
OPERAND_ADDR,
|
||||
MEMORY_READ, // Get source data
|
||||
ALU_LDCR, // Save it, point to R12
|
||||
WORD_READ, // Get R12
|
||||
ALU_LDCR, // Prepare CRU operation
|
||||
MEMORY_READ, // Get source data
|
||||
ALU_LDCR, // Save it, point to R12
|
||||
WORD_READ, // Get R12
|
||||
ALU_LDCR, // Prepare CRU operation
|
||||
CRU_OUTPUT,
|
||||
ALU_NOP,
|
||||
PREFETCH,
|
||||
@ -590,22 +590,22 @@ MICROPROGRAM(ldcr_mp)
|
||||
|
||||
MICROPROGRAM(li_mp)
|
||||
{
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_LI, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_LI, // 0
|
||||
PREFETCH, // 1 (1)
|
||||
MEMORY_WRITE,
|
||||
END
|
||||
};
|
||||
|
||||
MICROPROGRAM(limi_lwpi_mp)
|
||||
{
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_NOP, // 1
|
||||
ALU_LIMIWP, // (1)
|
||||
PREFETCH, // 1
|
||||
ALU_NOP, // 1
|
||||
SET_IMM, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_NOP, // 1
|
||||
ALU_LIMIWP, // (1)
|
||||
PREFETCH, // 1
|
||||
ALU_NOP, // 1
|
||||
END
|
||||
};
|
||||
|
||||
@ -621,12 +621,12 @@ MICROPROGRAM(lst_lwp_mp)
|
||||
|
||||
MICROPROGRAM(mov_mp)
|
||||
{
|
||||
OPERAND_ADDR, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
OPERAND_ADDR, // 0
|
||||
ALU_MOV, // 1
|
||||
OPERAND_ADDR, // 0
|
||||
MEMORY_READ, // 1 (1)
|
||||
OPERAND_ADDR, // 0
|
||||
ALU_MOV, // 1
|
||||
PREFETCH,
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
END
|
||||
};
|
||||
|
||||
@ -660,10 +660,10 @@ MICROPROGRAM(rtwp_mp)
|
||||
|
||||
MICROPROGRAM(sbo_sbz_mp)
|
||||
{
|
||||
ALU_SBO_SBZ, // Set address = &R12
|
||||
WORD_READ, // Read R12
|
||||
ALU_SBO_SBZ, // Add offset
|
||||
CRU_OUTPUT, // output via CRU
|
||||
ALU_SBO_SBZ, // Set address = &R12
|
||||
WORD_READ, // Read R12
|
||||
ALU_SBO_SBZ, // Add offset
|
||||
CRU_OUTPUT, // output via CRU
|
||||
ALU_NOP,
|
||||
PREFETCH,
|
||||
ALU_NOP,
|
||||
@ -673,9 +673,9 @@ MICROPROGRAM(sbo_sbz_mp)
|
||||
MICROPROGRAM(shift_mp)
|
||||
{
|
||||
MEMORY_READ,
|
||||
ALU_SHIFT, // skip next operation if count != 0
|
||||
MEMORY_READ, // if count=0 we must read R0
|
||||
ALU_SHIFT, // do the shift
|
||||
ALU_SHIFT, // skip next operation if count != 0
|
||||
MEMORY_READ, // if count=0 we must read R0
|
||||
ALU_SHIFT, // do the shift
|
||||
PREFETCH,
|
||||
MEMORY_WRITE,
|
||||
END
|
||||
@ -684,7 +684,7 @@ MICROPROGRAM(shift_mp)
|
||||
MICROPROGRAM(single_arithm_mp)
|
||||
{
|
||||
OPERAND_ADDR,
|
||||
MEMORY_READ, // This one is not done for CLR/SETO
|
||||
MEMORY_READ, // This one is not done for CLR/SETO
|
||||
ALU_SINGLE_ARITHM,
|
||||
PREFETCH,
|
||||
MEMORY_WRITE,
|
||||
@ -693,10 +693,10 @@ MICROPROGRAM(single_arithm_mp)
|
||||
|
||||
MICROPROGRAM(stcr_mp)
|
||||
{
|
||||
ALU_STCR, // Check for byte operation
|
||||
OPERAND_ADDR, // Source operand
|
||||
ALU_STCR, // Save, set R12
|
||||
WORD_READ, // Read R12
|
||||
ALU_STCR, // Check for byte operation
|
||||
OPERAND_ADDR, // Source operand
|
||||
ALU_STCR, // Save, set R12
|
||||
WORD_READ, // Read R12
|
||||
ALU_STCR,
|
||||
CRU_INPUT,
|
||||
ALU_STCR,
|
||||
@ -731,25 +731,25 @@ MICROPROGRAM(x_mp)
|
||||
OPERAND_ADDR,
|
||||
MEMORY_READ,
|
||||
ALU_X,
|
||||
END // should not be reached
|
||||
END // should not be reached
|
||||
};
|
||||
|
||||
MICROPROGRAM(xop_mp)
|
||||
{
|
||||
OPERAND_ADDR, // Determine source address
|
||||
ALU_XOP, // Save it; determine XOP number
|
||||
MEMORY_READ, // Read new WP
|
||||
ALU_XOP, //
|
||||
MEMORY_WRITE, // save source address to new R11
|
||||
OPERAND_ADDR, // Determine source address
|
||||
ALU_XOP, // Save it; determine XOP number
|
||||
MEMORY_READ, // Read new WP
|
||||
ALU_XOP, //
|
||||
MEMORY_WRITE, // save source address to new R11
|
||||
ALU_XOP,
|
||||
MEMORY_WRITE, // save old ST to new R15
|
||||
MEMORY_WRITE, // save old ST to new R15
|
||||
ALU_XOP,
|
||||
MEMORY_WRITE, // save old PC to new R14
|
||||
MEMORY_WRITE, // save old PC to new R14
|
||||
ALU_XOP,
|
||||
MEMORY_WRITE, // save old WP to new R13
|
||||
MEMORY_WRITE, // save old WP to new R13
|
||||
ALU_XOP,
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_XOP, // set new PC, set X flag
|
||||
MEMORY_READ, // Read new PC
|
||||
ALU_XOP, // set new PC, set X flag
|
||||
PREFETCH,
|
||||
ALU_NOP,
|
||||
END
|
||||
@ -769,20 +769,20 @@ MICROPROGRAM(xor_mp)
|
||||
|
||||
MICROPROGRAM(int_mp)
|
||||
{
|
||||
ALU_INT, // 1
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_INT, // 2
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
ALU_INT, // 1
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
ALU_INT, // 1
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
ALU_INT, // 1
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_INT, // 0
|
||||
PREFETCH_NO_INT, // 1 (1) (prefetch happens in parallel to the previous operation)
|
||||
ALU_NOP, // 1 (+decode in parallel; actually performed right after prefetch)
|
||||
ALU_NOP, // 1
|
||||
ALU_INT, // 1
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_INT, // 2
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
ALU_INT, // 1
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
ALU_INT, // 1
|
||||
MEMORY_WRITE, // 1 (1)
|
||||
ALU_INT, // 1
|
||||
MEMORY_READ, // 1 (1)
|
||||
ALU_INT, // 0
|
||||
PREFETCH_NO_INT, // 1 (1) (prefetch happens in parallel to the previous operation)
|
||||
ALU_NOP, // 1 (+decode in parallel; actually performed right after prefetch)
|
||||
ALU_NOP, // 1
|
||||
END
|
||||
};
|
||||
|
||||
@ -860,12 +860,12 @@ enum
|
||||
|
||||
static const char opname[][5] =
|
||||
{ "MID ", "A ", "AB ", "ABS ", "AI ", "ANDI", "B ", "BL ", "BLWP", "C ",
|
||||
"CB ", "CI ", "CKOF", "CKON", "CLR ", "COC ", "CZC ", "DEC ", "DECT", "DIV ",
|
||||
"CB ", "CI ", "CKOF", "CKON", "CLR ", "COC ", "CZC ", "DEC ", "DECT", "DIV ",
|
||||
"DIVS", "IDLE", "INC ", "INCT", "INV ", "JEQ ", "JGT ", "JH ", "JHE ", "JL ",
|
||||
"JLE ", "JLT ", "JMP ", "JNC ", "JNE ", "JNO ", "JOC ", "JOP ", "LDCR", "LI ",
|
||||
"LIMI", "LREX", "LST ", "LWP ", "LWPI", "MOV ", "MOVB", "MPY ", "MPYS", "NEG ",
|
||||
"ORI ", "RSET", "RTWP", "S ", "SB ", "SBO ", "SBZ ", "SETO", "SLA ", "SOC ",
|
||||
"SOCB", "SRA ", "SRC ", "SRL ", "STCR", "STST", "STWP", "SWPB", "SZC ", "SZCB",
|
||||
"ORI ", "RSET", "RTWP", "S ", "SB ", "SBO ", "SBZ ", "SETO", "SLA ", "SOC ",
|
||||
"SOCB", "SRA ", "SRC ", "SRL ", "STCR", "STST", "STWP", "SWPB", "SZC ", "SZCB",
|
||||
"TB ", "X ", "XOP ", "XOR ", "*int"
|
||||
};
|
||||
|
||||
@ -1187,7 +1187,7 @@ inline void tms9995_device::pulse_clock(int count)
|
||||
{
|
||||
m_clock_out_line(ASSERT_LINE);
|
||||
m_clock_out_line(CLEAR_LINE);
|
||||
m_icount--; // This is the only location where we count down the cycles.
|
||||
m_icount--; // This is the only location where we count down the cycles.
|
||||
if (VERBOSE>7) LOG("tms9995: pulse_clock\n");
|
||||
if (m_flag[0] == false && m_flag[1] == true) trigger_decrementer();
|
||||
}
|
||||
@ -1309,7 +1309,7 @@ void tms9995_device::int_prefetch_and_decode()
|
||||
if (VERBOSE>7) LOG("tms9995: Checking interrupts ... NMI active\n");
|
||||
m_int_pending |= PENDING_NMI;
|
||||
m_idle_state = false;
|
||||
PC = (PC + 2) & 0xfffe; // we have not prefetched the next instruction
|
||||
PC = (PC + 2) & 0xfffe; // we have not prefetched the next instruction
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1327,7 +1327,7 @@ void tms9995_device::int_prefetch_and_decode()
|
||||
m_idle_state = false;
|
||||
if (VERBOSE>7) LOG("tms9995: Interrupt occured, terminate IDLE state\n");
|
||||
}
|
||||
PC = PC + 2; // PC must be advanced (see flow chart), but no prefetch
|
||||
PC = PC + 2; // PC must be advanced (see flow chart), but no prefetch
|
||||
if (VERBOSE>7) LOG("tms9995: Interrupts pending; no prefetch; advance PC to %04x\n", PC);
|
||||
}
|
||||
else
|
||||
@ -1362,10 +1362,10 @@ void tms9995_device::prefetch_and_decode()
|
||||
// Second pass for getting the instruction
|
||||
if (VERBOSE>6) LOG("tms9995: Prefetch memory access (second pass)\n");
|
||||
word_read();
|
||||
decode(m_current_value); // This is for free; in reality it is in parallel with the next memory operation
|
||||
m_address = m_address_copy; // restore m_address
|
||||
m_current_value = m_value_copy; // restore m_current_value
|
||||
PC = (PC + 2) & 0xfffe; // advance PC
|
||||
decode(m_current_value); // This is for free; in reality it is in parallel with the next memory operation
|
||||
m_address = m_address_copy; // restore m_address
|
||||
m_current_value = m_value_copy; // restore m_current_value
|
||||
PC = (PC + 2) & 0xfffe; // advance PC
|
||||
m_iaq_line(CLEAR_LINE);
|
||||
if (VERBOSE>5) LOG("tms9995: ++++ Prefetch done ++++\n");
|
||||
m_lowbyte = false;
|
||||
@ -1383,17 +1383,17 @@ void tms9995_device::prefetch_and_decode()
|
||||
|
||||
if (VERBOSE>5) LOG("tms9995: **** Prefetching new instruction at %04x ****\n", PC);
|
||||
|
||||
m_lowbyte = false; // for mem_read
|
||||
word_read(); // this is where the clock pulses occur
|
||||
m_lowbyte = false; // for mem_read
|
||||
word_read(); // this is where the clock pulses occur
|
||||
|
||||
if (!m_lowbyte)
|
||||
{
|
||||
// Only if we got the word in one pass
|
||||
decode(m_current_value); // This is for free; in reality it is in parallel with the next memory operation
|
||||
decode(m_current_value); // This is for free; in reality it is in parallel with the next memory operation
|
||||
|
||||
m_address = m_address_copy; // restore m_address
|
||||
m_current_value = m_value_copy; // restore m_current_value
|
||||
PC = (PC + 2) & 0xfffe; // advance PC
|
||||
m_address = m_address_copy; // restore m_address
|
||||
m_current_value = m_value_copy; // restore m_current_value
|
||||
PC = (PC + 2) & 0xfffe; // advance PC
|
||||
|
||||
m_iaq_line(CLEAR_LINE);
|
||||
}
|
||||
@ -1470,7 +1470,7 @@ void tms9995_device::service_interrupt()
|
||||
if (m_reset)
|
||||
{
|
||||
vectorpos = 0;
|
||||
m_intmask = 0; // clear interrupt mask
|
||||
m_intmask = 0; // clear interrupt mask
|
||||
|
||||
m_nmi_state = false;
|
||||
m_hold_state = false;
|
||||
@ -1565,7 +1565,7 @@ void tms9995_device::service_interrupt()
|
||||
}
|
||||
MPC = 0;
|
||||
m_first_cycle = m_icount;
|
||||
m_check_ready = false; // set to default
|
||||
m_check_ready = false; // set to default
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2036,10 +2036,10 @@ void tms9995_device::operand_address_subprogram()
|
||||
m_regnumber = (ircopy & 0x000f);
|
||||
m_address = (WP + (m_regnumber<<1)) & 0xffff;
|
||||
|
||||
m_source_value = m_current_value; // will be overwritten when reading the destination
|
||||
m_current_value = m_address; // needed for first case
|
||||
m_source_value = m_current_value; // will be overwritten when reading the destination
|
||||
m_current_value = m_address; // needed for first case
|
||||
|
||||
if (MPC==8) // Symbolic
|
||||
if (MPC==8) // Symbolic
|
||||
{
|
||||
if (m_regnumber != 0)
|
||||
{
|
||||
@ -2057,7 +2057,7 @@ void tms9995_device::operand_address_subprogram()
|
||||
m_get_destination = true;
|
||||
m_lowbyte = false;
|
||||
m_address_add = 0;
|
||||
MPC--; // will be increased in the mail loop
|
||||
MPC--; // will be increased in the mail loop
|
||||
if (VERBOSE>8) LOG("tms9995: *** Operand address derivation; address=%04x; index=%d\n", m_address, MPC+1);
|
||||
}
|
||||
|
||||
@ -2067,7 +2067,7 @@ void tms9995_device::operand_address_subprogram()
|
||||
*/
|
||||
void tms9995_device::increment_register()
|
||||
{
|
||||
m_address_saved = m_current_value; // need a special return so we do not lose the value
|
||||
m_address_saved = m_current_value; // need a special return so we do not lose the value
|
||||
m_current_value += m_instruction->byteop? 1 : 2;
|
||||
m_address = (WP + (m_regnumber<<1)) & 0xffff;
|
||||
m_lowbyte = false;
|
||||
@ -2093,7 +2093,7 @@ void tms9995_device::set_immediate()
|
||||
// Need to determine the register address
|
||||
m_address_saved = WP + ((m_instruction->IR & 0x000f)<<1);
|
||||
m_address = PC;
|
||||
m_source_value = m_current_value; // needed for AI, ANDI, ORI
|
||||
m_source_value = m_current_value; // needed for AI, ANDI, ORI
|
||||
PC = (PC + 2) & 0xfffe;
|
||||
m_lowbyte = false;
|
||||
}
|
||||
@ -2238,7 +2238,7 @@ void tms9995_device::alu_blwp()
|
||||
m_address = m_address - 2;
|
||||
break;
|
||||
case 2:
|
||||
m_current_value = m_value_copy; // old WP
|
||||
m_current_value = m_value_copy; // old WP
|
||||
m_address = m_address - 2;
|
||||
break;
|
||||
case 3:
|
||||
@ -2323,13 +2323,13 @@ void tms9995_device::alu_divide()
|
||||
// or equivalently, dividend / 0x10000 >= divisor
|
||||
|
||||
// Check overflow for unsigned DIV
|
||||
if (m_current_value < m_source_value) // also if source=0
|
||||
if (m_current_value < m_source_value) // also if source=0
|
||||
{
|
||||
MPC++; // skip the abort
|
||||
MPC++; // skip the abort
|
||||
overflow = false;
|
||||
}
|
||||
set_status_bit(ST_OV, overflow);
|
||||
m_value_copy = m_current_value; // Save the high word
|
||||
m_value_copy = m_current_value; // Save the high word
|
||||
m_address = m_address + 2;
|
||||
break;
|
||||
case 2:
|
||||
@ -2412,65 +2412,65 @@ void tms9995_device::alu_divide_signed()
|
||||
// requires much less cycles when there is an overflow, so it seems as
|
||||
// if this is tested before the algorithm starts.
|
||||
|
||||
if ((w1 & 0x8000)==0) // positive dividend
|
||||
if ((w1 & 0x8000)==0) // positive dividend
|
||||
{
|
||||
if ((d & 0x8000)==0) // positive divisor
|
||||
if ((d & 0x8000)==0) // positive divisor
|
||||
{
|
||||
if ((d & 1)==0) // even divisor
|
||||
if ((d & 1)==0) // even divisor
|
||||
{
|
||||
if (w1 < d/2) overflow = false;
|
||||
}
|
||||
else // odd divisor
|
||||
else // odd divisor
|
||||
{
|
||||
if ((w1 < (d-1)/2) || (w1 == (d-1)/2 && w2 < 0x8000)) overflow = false;
|
||||
}
|
||||
}
|
||||
else // negative divisor
|
||||
else // negative divisor
|
||||
{
|
||||
d = -d;
|
||||
if ((d & 1)==0) // even divisor
|
||||
if ((d & 1)==0) // even divisor
|
||||
{
|
||||
if ((w1 < d/2) || (w1 == d/2 && w2 < d)) overflow = false;
|
||||
}
|
||||
else // odd divisor
|
||||
else // odd divisor
|
||||
{
|
||||
if ((w1 < (d+1)/2) || (w1 == (d+1)/2 && w2 < 0x8000+d)) overflow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // negative dividend
|
||||
else // negative dividend
|
||||
{
|
||||
w1 = -w1;
|
||||
if ((d & 0x8000)==0) // positive divisor
|
||||
if ((d & 0x8000)==0) // positive divisor
|
||||
{
|
||||
if ((d & 1)==0) // even divisor
|
||||
if ((d & 1)==0) // even divisor
|
||||
{
|
||||
if ((w1 < d/2+1) || (w1 == d/2+1 && w2 > (-d))) overflow = false;
|
||||
}
|
||||
else // odd divisor
|
||||
else // odd divisor
|
||||
{
|
||||
if ((w1 < (d+1)/2) || (w1 == (d+1)/2 && w2 > 0x8000-d)) overflow = false;
|
||||
}
|
||||
}
|
||||
else // negative divisor
|
||||
else // negative divisor
|
||||
{
|
||||
d = -d;
|
||||
if ((d & 1)==0) // even divisor
|
||||
if ((d & 1)==0) // even divisor
|
||||
{
|
||||
if ((w1 < d/2) || (w1 == d/2 && w2 > 0)) overflow = false;
|
||||
}
|
||||
else // odd divisor
|
||||
else // odd divisor
|
||||
{
|
||||
if ((w1 < (d+1)/2) || (w1 == (d+1)/2 && w2 > 0x8000)) overflow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
set_status_bit(ST_OV, overflow);
|
||||
if (!overflow) MPC++; // Skip the next microinstruction when there is no overflow
|
||||
if (!overflow) MPC++; // Skip the next microinstruction when there is no overflow
|
||||
break;
|
||||
case 3:
|
||||
// We are here because there was no overflow
|
||||
w = (m_value_copy << 16) | m_current_value;
|
||||
w = (m_value_copy << 16) | m_current_value;
|
||||
// Do the calculation
|
||||
m_current_value = (UINT16)(w / (INT16)m_source_value);
|
||||
m_value_copy = (UINT16)(w % (INT16)m_source_value);
|
||||
@ -2627,37 +2627,37 @@ void tms9995_device::alu_jump()
|
||||
case JLT: // LAECOP == x00xxx
|
||||
cond = ((ST & (ST_AGT | ST_EQ))==0);
|
||||
break;
|
||||
case JLE: // LAECOP == 0xxxxx
|
||||
case JLE: // LAECOP == 0xxxxx
|
||||
cond = ((ST & ST_LH)==0);
|
||||
break;
|
||||
case JEQ: // LAECOP == xx1xxx
|
||||
case JEQ: // LAECOP == xx1xxx
|
||||
cond = ((ST & ST_EQ)!=0);
|
||||
break;
|
||||
case JHE: // LAECOP == 1x0xxx, 0x1xxx
|
||||
case JHE: // LAECOP == 1x0xxx, 0x1xxx
|
||||
cond = ((ST & (ST_LH | ST_EQ)) != 0);
|
||||
break;
|
||||
case JGT: // LAECOP == x1xxxx
|
||||
case JGT: // LAECOP == x1xxxx
|
||||
cond = ((ST & ST_AGT)!=0);
|
||||
break;
|
||||
case JNE: // LAECOP == xx0xxx
|
||||
case JNE: // LAECOP == xx0xxx
|
||||
cond = ((ST & ST_EQ)==0);
|
||||
break;
|
||||
case JNC: // LAECOP == xxx0xx
|
||||
case JNC: // LAECOP == xxx0xx
|
||||
cond = ((ST & ST_C)==0);
|
||||
break;
|
||||
case JOC: // LAECOP == xxx1xx
|
||||
case JOC: // LAECOP == xxx1xx
|
||||
cond = ((ST & ST_C)!=0);
|
||||
break;
|
||||
case JNO: // LAECOP == xxxx0x
|
||||
case JNO: // LAECOP == xxxx0x
|
||||
cond = ((ST & ST_OV)==0);
|
||||
break;
|
||||
case JL: // LAECOP == 0x0xxx
|
||||
case JL: // LAECOP == 0x0xxx
|
||||
cond = ((ST & (ST_LH | ST_EQ)) == 0);
|
||||
break;
|
||||
case JH: // LAECOP == 1xxxxx
|
||||
case JH: // LAECOP == 1xxxxx
|
||||
cond = ((ST & ST_LH)!=0);
|
||||
break;
|
||||
case JOP: // LAECOP == xxxxx1
|
||||
case JOP: // LAECOP == xxxxx1
|
||||
cond = ((ST & ST_OP)!=0);
|
||||
break;
|
||||
}
|
||||
@ -2728,7 +2728,7 @@ void tms9995_device::alu_limi_lwpi()
|
||||
{
|
||||
ST = (ST & 0xfff0) | (m_current_value & 0x000f);
|
||||
if (VERBOSE>7) LOG("tms9995: ST = %04x\n", ST);
|
||||
pulse_clock(1); // needs one more than LWPI
|
||||
pulse_clock(1); // needs one more than LWPI
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2847,15 +2847,15 @@ void tms9995_device::alu_rtwp()
|
||||
switch (m_instruction->state)
|
||||
{
|
||||
case 0:
|
||||
m_address = WP + 30; // R15
|
||||
m_address = WP + 30; // R15
|
||||
break;
|
||||
case 1:
|
||||
ST = m_current_value;
|
||||
m_address -= 2; // R14
|
||||
m_address -= 2; // R14
|
||||
break;
|
||||
case 2:
|
||||
PC = m_current_value;
|
||||
m_address -= 2; // R13
|
||||
m_address -= 2; // R13
|
||||
break;
|
||||
case 3:
|
||||
WP = m_current_value;
|
||||
@ -2956,7 +2956,7 @@ void tms9995_device::alu_shift()
|
||||
set_status_bit(ST_C, carry);
|
||||
set_status_bit(ST_OV, overflow);
|
||||
compare_and_set_lae(m_current_value, 0);
|
||||
m_address = m_address_saved; // Register address
|
||||
m_address = m_address_saved; // Register address
|
||||
if (VERBOSE>7) LOG("tms9995: ST = %04x (val=%04x)\n", ST, m_current_value);
|
||||
break;
|
||||
}
|
||||
@ -3049,7 +3049,7 @@ void tms9995_device::alu_single_arithm()
|
||||
return;
|
||||
}
|
||||
|
||||
if (check_ov) set_status_bit(ST_OV, ((src_val & 0x8000)!=sign) && ((dest_new & 0x8000)==sign));
|
||||
if (check_ov) set_status_bit(ST_OV, ((src_val & 0x8000)==sign) && ((dest_new & 0x8000)!=sign));
|
||||
set_status_bit(ST_C, (dest_new & 0x10000) != 0);
|
||||
m_current_value = dest_new & 0xffff;
|
||||
compare_and_set_lae(m_current_value, 0);
|
||||
@ -3169,7 +3169,7 @@ void tms9995_device::alu_xop()
|
||||
break;
|
||||
case 1:
|
||||
// m_current_value is new WP
|
||||
m_value_copy = WP; // store this for later
|
||||
m_value_copy = WP; // store this for later
|
||||
WP = m_current_value;
|
||||
m_address = WP + 0x0016; // Address of new R11
|
||||
m_current_value = m_address_saved;
|
||||
@ -3215,9 +3215,9 @@ void tms9995_device::alu_int()
|
||||
if (VERBOSE>7) LOG("tms9995: interrupt service (0): Prepare to read vector\n");
|
||||
break;
|
||||
case 1:
|
||||
pulse = 2; // two cycles (with the one at the end)
|
||||
m_source_value = WP; // old WP
|
||||
WP = m_current_value; // new WP
|
||||
pulse = 2; // two cycles (with the one at the end)
|
||||
m_source_value = WP; // old WP
|
||||
WP = m_current_value; // new WP
|
||||
m_current_value = ST;
|
||||
m_address = (WP + 30)&0xfffe;
|
||||
if (VERBOSE>7) LOG("tms9995: interrupt service (1): Read new WP = %04x, save ST to %04x\n", WP, m_address);
|
||||
@ -3229,7 +3229,7 @@ void tms9995_device::alu_int()
|
||||
break;
|
||||
case 3:
|
||||
m_address = (WP + 26)&0xfffe;
|
||||
m_current_value = m_source_value; // old WP
|
||||
m_current_value = m_source_value; // old WP
|
||||
if (VERBOSE>7) LOG("tms9995: interrupt service (3): Save WP to %04x\n", m_address);
|
||||
break;
|
||||
case 4:
|
||||
@ -3247,7 +3247,7 @@ void tms9995_device::alu_int()
|
||||
m_int_pending &= ~PENDING_MID;
|
||||
m_address = 0xfffc;
|
||||
m_intmask = 0;
|
||||
MPC = 0; // redo the interrupt service for the NMI
|
||||
MPC = 0; // redo the interrupt service for the NMI
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user