i8085: small cleanup

This commit is contained in:
hap 2025-04-07 12:18:39 +02:00
parent 8f2cde3399
commit 35b49fd3f2

View File

@ -108,7 +108,7 @@
* April 2025, Roberto Fresca
* - Reworked the DSUB (Double Substraction) undocumented instruction.
* - Reworked the RDEL (Rotate D and E Left with Carry) undocumented instruction.
* (ref: https://robertofresca.com/files/New_8085_instruction.pdf)
* (ref: https://robertofresca.com/files/New_8085_instruction.pdf)
*
*****************************************************************************/
@ -274,10 +274,10 @@ void i8085a_cpu_device::init_tables()
{
for (int i = 0; i < 256; i++)
{
/* cycles */
// cycles
lut_cycles[i] = is_8085() ? lut_cycles_8085[i] : lut_cycles_8080[i];
/* flags */
// flags
u8 zs = 0;
if (i == 0) zs |= ZF;
if (i & 0x80) zs |= SF;
@ -312,7 +312,7 @@ void i8085a_cpu_device::device_start()
init_tables();
/* set up the state table */
// set up the state table
state_add(I8085_PC, "PC", m_PC.w.l);
state_add(STATE_GENPC, "GENPC", m_PC.w.l).noshow();
state_add(STATE_GENPCBASE, "CURPC", m_PC.w.l).noshow();
@ -347,7 +347,7 @@ void i8085a_cpu_device::device_start()
space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).cache(m_copcodes);
space(AS_IO).specific(m_io);
/* register for state saving */
// register for state saving
save_item(NAME(m_PC.w.l));
save_item(NAME(m_SP.w.l));
save_item(NAME(m_AF.w.l));
@ -485,7 +485,7 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state)
{
int newstate = (state != CLEAR_LINE);
/* TRAP is level and edge-triggered NMI */
// TRAP is level and edge-triggered NMI
if (irqline == I8085_TRAP_LINE)
{
if (!m_nmi_state && newstate)
@ -495,7 +495,7 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state)
m_nmi_state = newstate;
}
/* RST7.5 is edge-triggered */
// RST7.5 is edge-triggered
else if (irqline == I8085_RST75_LINE)
{
if (!m_irq_state[I8085_RST75_LINE] && newstate)
@ -503,105 +503,105 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state)
m_irq_state[I8085_RST75_LINE] = newstate;
}
/* remaining sources are level triggered */
// remaining sources are level triggered
else if (irqline < std::size(m_irq_state))
m_irq_state[irqline] = state;
}
void i8085a_cpu_device::break_halt_for_interrupt()
{
/* de-halt if necessary */
// de-halt if necessary
if (m_halt)
{
m_PC.w.l++;
m_halt = 0;
set_status(0x26); /* int ack while halt */
set_status(0x26); // int ack while halt
}
else
set_status(0x23); /* int ack */
set_status(0x23); // int ack
m_in_acknowledge = true;
}
void i8085a_cpu_device::check_for_interrupts()
{
/* TRAP is the highest priority */
// TRAP is the highest priority
if (m_trap_pending)
{
/* the first RIM after a TRAP reflects the original IE state; remember it here,
setting the high bit to indicate it is valid */
// the first RIM after a TRAP reflects the original IE state; remember it here,
// setting the high bit to indicate it is valid
m_trap_im_copy = m_im | 0x80;
/* reset the pending state */
// reset the pending state
m_trap_pending = false;
/* break out of HALT state and call the IRQ ack callback */
// break out of HALT state and call the IRQ ack callback
break_halt_for_interrupt();
standard_irq_callback(I8085_TRAP_LINE, m_PC.w.l);
/* push the PC and jump to $0024 */
// push the PC and jump to $0024
op_push(m_PC);
set_inte(0);
m_PC.w.l = ADDR_TRAP;
m_icount -= 11;
}
/* followed by RST7.5 */
// followed by RST7.5
else if ((m_im & IM_I75) && !(m_im & IM_M75) && (m_im & IM_IE))
{
/* reset the pending state (which is CPU-visible via the RIM instruction) */
// reset the pending state (which is CPU-visible via the RIM instruction)
m_im &= ~IM_I75;
/* break out of HALT state and call the IRQ ack callback */
// break out of HALT state and call the IRQ ack callback
break_halt_for_interrupt();
standard_irq_callback(I8085_RST75_LINE, m_PC.w.l);
/* push the PC and jump to $003C */
// push the PC and jump to $003C
op_push(m_PC);
set_inte(0);
m_PC.w.l = ADDR_RST75;
m_icount -= 11;
}
/* followed by RST6.5 */
// followed by RST6.5
else if (m_irq_state[I8085_RST65_LINE] && !(m_im & IM_M65) && (m_im & IM_IE))
{
/* break out of HALT state and call the IRQ ack callback */
// break out of HALT state and call the IRQ ack callback
break_halt_for_interrupt();
standard_irq_callback(I8085_RST65_LINE, m_PC.w.l);
/* push the PC and jump to $0034 */
// push the PC and jump to $0034
op_push(m_PC);
set_inte(0);
m_PC.w.l = ADDR_RST65;
m_icount -= 11;
}
/* followed by RST5.5 */
// followed by RST5.5
else if (m_irq_state[I8085_RST55_LINE] && !(m_im & IM_M55) && (m_im & IM_IE))
{
/* break out of HALT state and call the IRQ ack callback */
// break out of HALT state and call the IRQ ack callback
break_halt_for_interrupt();
standard_irq_callback(I8085_RST55_LINE, m_PC.w.l);
/* push the PC and jump to $002C */
// push the PC and jump to $002C
op_push(m_PC);
set_inte(0);
m_PC.w.l = ADDR_RST55;
m_icount -= 11;
}
/* followed by classic INTR */
// followed by classic INTR
else if (m_irq_state[I8085_INTR_LINE] && (m_im & IM_IE))
{
/* break out of HALT state and call the IRQ ack callback */
// break out of HALT state and call the IRQ ack callback
if (!m_in_inta_func.isunset())
standard_irq_callback(I8085_INTR_LINE, m_PC.w.l);
break_halt_for_interrupt();
u8 vector = read_inta();
/* use the resulting vector as an opcode to execute */
// use the resulting vector as an opcode to execute
set_inte(0);
LOG("i8085 take int $%02x\n", vector);
execute_one(vector);
@ -654,12 +654,12 @@ u8 i8085a_cpu_device::get_rim_value()
u8 result = m_im;
int sid = m_in_sid_func();
/* copy live RST5.5 and RST6.5 states */
// copy live RST5.5 and RST6.5 states
result &= ~(IM_I65 | IM_I55);
if (m_irq_state[I8085_RST65_LINE]) result |= IM_I65;
if (m_irq_state[I8085_RST55_LINE]) result |= IM_I55;
/* fetch the SID bit if we have a callback */
// fetch the SID bit if we have a callback
result = (result & ~IM_SID) | (sid ? IM_SID : 0);
return result;
@ -867,21 +867,21 @@ void i8085a_cpu_device::op_rst(u8 v)
void i8085a_cpu_device::execute_run()
{
/* check for TRAPs before diving in (can't do others because of after_ei) */
// check for TRAPs before diving in (can't do others because of after_ei)
if (m_trap_pending || m_after_ei == 0)
check_for_interrupts();
do
{
/* the instruction after an EI does not take an interrupt, so
we cannot check immediately; handle post-EI behavior here */
// the instruction after an EI does not take an interrupt, so
// we cannot check immediately; handle post-EI behavior here
if (m_after_ei != 0 && --m_after_ei == 0)
check_for_interrupts();
m_in_acknowledge = false;
debugger_instruction_hook(m_PC.d);
/* here we go... */
// here we go...
execute_one(read_op());
} while (m_icount > 0);
@ -926,32 +926,32 @@ void i8085a_cpu_device::execute_one(int opcode)
break;
case 0x08: // 8085: undocumented DSUB (Double Subtraction, HL - BC)
if (is_8085())
{
// Low byte subtraction: L = L - C
int q_low = m_HL.b.l - m_BC.b.l;
u8 res_low = q_low & 0xff;
// Calculate flags for low byte
m_AF.b.l = lut_zs[res_low]
| ((q_low >> 8) & CF) // Carry
| ((m_HL.b.l ^ res_low ^ m_BC.b.l) & HF) // Half Carry
| (((m_BC.b.l ^ m_HL.b.l) & (m_HL.b.l ^ res_low) & SF)) >> 5; // Overflow
m_HL.b.l = res_low;
if (is_8085())
{
// Low byte subtraction: L = L - C
int q_low = m_HL.b.l - m_BC.b.l;
u8 res_low = q_low & 0xff;
// Calculate flags for low byte
m_AF.b.l = lut_zs[res_low]
| ((q_low >> 8) & CF) // Carry
| ((m_HL.b.l ^ res_low ^ m_BC.b.l) & HF) // Half Carry
| (((m_BC.b.l ^ m_HL.b.l) & (m_HL.b.l ^ res_low) & SF)) >> 5; // Overflow
m_HL.b.l = res_low;
// High byte subtraction: H = H - B - carry_from_low
int q_high = m_HL.b.h - m_BC.b.h - (m_AF.b.l & CF);
u8 res_high = q_high & 0xff;
// Calculate flags for high byte
m_AF.b.l = lut_zs[res_high]
| ((q_high >> 8) & CF) // Carry
| ((m_HL.b.h ^ res_high ^ m_BC.b.h) & HF) // Half Carry
| (((m_BC.b.h ^ m_HL.b.h) & (m_HL.b.h ^ res_high) & SF)) >> 5; // Overflow
m_HL.b.h = res_high;
// High byte subtraction: H = H - B - carry_from_low
int q_high = m_HL.b.h - m_BC.b.h - (m_AF.b.l & CF);
u8 res_high = q_high & 0xff;
// Calculate flags for high byte
m_AF.b.l = lut_zs[res_high]
| ((q_high >> 8) & CF) // Carry
| ((m_HL.b.h ^ res_high ^ m_BC.b.h) & HF) // Half Carry
| (((m_BC.b.h ^ m_HL.b.h) & (m_HL.b.h ^ res_high) & SF)) >> 5; // Overflow
m_HL.b.h = res_high;
// Set Zero flag based on 16-bit result
m_AF.b.l = (m_AF.b.l & ~ZF) | (((m_HL.b.l | m_HL.b.h) == 0) ? ZF : 0);
}
break;
// Set Zero flag based on 16-bit result
m_AF.b.l = (m_AF.b.l & ~ZF) | (((m_HL.b.l | m_HL.b.h) == 0) ? ZF : 0);
}
break;
case 0x09: // DAD B
op_dad(m_BC.w.l);
break;