📄 i8085.c
字号:
I.IM &= ~IM_IEN; /* remove general interrupt enable bit */
switch (I.IRQ1 & 0xff0000)
{
case 0xcd0000: /* CALL nnnn */
I8085_ICount -= 7;
M_PUSH(PC);
case 0xc30000: /* JMP nnnn */
I8085_ICount -= 10;
I.PC.D = I.IRQ1 & 0xffff;
change_pc16(I.PC.D);
break;
default:
switch (I.IRQ1)
{
case I8085_TRAP:
case I8085_RST75:
case I8085_RST65:
case I8085_RST55:
M_PUSH(PC);
I.PC.D = I.IRQ1;
change_pc16(I.PC.D);
break;
default:
ExecOne(I.IRQ1 & 0xff);
}
}
}
int I8085_Execute(int cycles)
{
I8085_ICount = cycles;
do
{
/* interrupts enabled or TRAP pending ? */
if ( (I.IM & IM_IEN) || (I.IREQ & IM_TRAP) )
{
/* copy scheduled to executed interrupt request */
I.IRQ1 = I.IRQ2;
/* reset scheduled interrupt request */
I.IRQ2 = 0;
/* interrupt now ? */
if (I.IRQ1) Interrupt();
}
/* here we go... */
ExecOne(RDOP());
} while (I8085_ICount > 0);
return cycles - I8085_ICount;
}
/****************************************************************************/
/* Initialise the various lookup tables used by the emulation code */
/****************************************************************************/
static void InitTables (void)
{
byte zs;
int i, p;
for (i = 0; i < 256; i++)
{
zs = 0;
if (i==0) zs |= ZF;
if (i&128) zs |= SF;
p = 0;
if (i&1) ++p;
if (i&2) ++p;
if (i&4) ++p;
if (i&8) ++p;
if (i&16) ++p;
if (i&32) ++p;
if (i&64) ++p;
if (i&128) ++p;
ZS[i] = zs;
ZSP[i] = zs | ((p&1) ? 0 : VF);
}
}
/****************************************************************************/
/* Reset the 8085 emulation */
/****************************************************************************/
void I8085_Reset(void)
{
InitTables();
memset(&I, 0, sizeof(I8085_Regs));
change_pc16(I.PC.D);
}
/****************************************************************************/
/* Get the current 8085 context */
/****************************************************************************/
void I8085_GetRegs(I8085_Regs * regs)
{
*regs = I;
}
/****************************************************************************/
/* Set the current 8085 context */
/****************************************************************************/
void I8085_SetRegs(I8085_Regs * regs)
{
I = *regs;
}
/****************************************************************************/
/* Get the current 8085 PC */
/****************************************************************************/
int I8085_GetPC(void)
{
return I.PC.D;
}
/****************************************************************************/
/* Set the 8085 SID input signal state */
/****************************************************************************/
void I8085_SetSID(int state)
{
if (state)
I.IM |= IM_SID;
else
I.IM &= ~IM_SID;
}
/****************************************************************************/
/* Set a callback to be called at SOD output change */
/****************************************************************************/
void I8085_Set_SOD_callback(void (*callback)(int state))
{
I.SOD_callback = callback;
}
/****************************************************************************/
/* Set TRAP signal state */
/****************************************************************************/
void I8085_SetTRAP(int state)
{
if (state)
{
I.IREQ |= IM_TRAP;
/* already servicing TRAP ? */
if (I.ISRV & IM_TRAP)
return;
/* schedule TRAP */
I.ISRV = IM_TRAP;
I.IRQ2 = ADDR_TRAP;
}
else
{
/* remove request for TRAP */
I.IREQ &= ~IM_TRAP;
}
}
/****************************************************************************/
/* Set RST7.5 signal state */
/****************************************************************************/
void I8085_SetRST75(int state)
{
if (state)
{
/* request RST7.5 */
I.IREQ |= IM_RST75;
/* if masked, ignore it for now */
if (I.IM & IM_RST75)
return;
/* if no higher priority IREQ is serviced */
if (!I.ISRV)
{
/* schedule RST7.5 */
I.ISRV = IM_RST75;
I.IRQ2 = ADDR_RST75;
}
}
/* RST7.5 is reset only by SIM or end of service routine ! */
}
/****************************************************************************/
/* Set RST6.5 signal state */
/****************************************************************************/
void I8085_SetRST65(int state)
{
if (state)
{
/* request RST6.5 */
I.IREQ |= IM_RST65;
/* if masked, ignore it for now */
if (I.IM & IM_RST65)
return;
/* if no higher priority IREQ is serviced */
if (!I.ISRV)
{
/* schedule RST6.5 */
I.ISRV = IM_RST65;
I.IRQ2 = ADDR_RST65;
}
}
else
{
/* remove request for RST6.5 */
I.IREQ &= ~IM_RST65;
}
}
/****************************************************************************/
/* Set RST5.5 signal state */
/****************************************************************************/
void I8085_SetRST55(int state)
{
if (state)
{
/* request RST5.5 */
I.IREQ |= IM_RST55;
/* if masked, ignore it for now */
if (I.IM & IM_RST55)
return;
/* if no higher priority IREQ is serviced */
if (!I.ISRV)
{
/* schedule RST5.5 */
I.ISRV = IM_RST55;
I.IRQ2 = ADDR_RST55;
}
}
else
{
/* remove request for RST5.5 */
I.IREQ &= ~IM_RST55;
}
}
/****************************************************************************/
/* Set INTR signal */
/****************************************************************************/
void I8085_SetINTR(int type)
{
if (type)
{
/* request INTR */
I.IREQ |= IM_INTR;
I.INTR = type;
/* if masked, ignore it for now */
if (I.IM & IM_INTR)
return;
/* if no higher priority IREQ is serviced */
if (!I.ISRV)
{
/* schedule INTR */
I.ISRV = IM_INTR;
I.IRQ2 = I.INTR;
}
}
else
{
/* remove request for INTR */
I.IREQ &= ~IM_INTR;
}
}
/****************************************************************************/
/* Cause an interrupt */
/****************************************************************************/
void I8085_Cause_Interrupt(int type)
{
switch (type)
{
case I8085_SID:
I8085_SetSID(1);
break;
case I8085_TRAP:
I8085_SetTRAP(1);
break;
case I8085_RST75:
I8085_SetRST75(1);
break;
case I8085_RST65:
I8085_SetRST65(1);
break;
case I8085_RST55:
I8085_SetRST55(1);
break;
default:
I8085_SetINTR(type);
break;
}
}
void I8085_Clear_Pending_Interrupts(void)
{
if (I.IREQ & IM_TRAP)
I8085_SetTRAP(I8085_NONE);
if (I.IREQ & IM_RST75)
I8085_SetRST75(I8085_NONE);
if (I.IREQ & IM_RST65)
I8085_SetRST65(I8085_NONE);
if (I.IREQ & IM_RST55)
I8085_SetRST55(I8085_NONE);
if (I.IREQ & IM_INTR)
I8085_SetINTR(I8085_NONE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -