📄 i8039.c
字号:
static void mov_r1_a(void) { R1 = R.A; }
static void mov_r2_a(void) { R2 = R.A; }
static void mov_r3_a(void) { R3 = R.A; }
static void mov_r4_a(void) { R4 = R.A; }
static void mov_r5_a(void) { R5 = R.A; }
static void mov_r6_a(void) { R6 = R.A; }
static void mov_r7_a(void) { R7 = R.A; }
static void mov_psw_a(void) { R.PSW = R.A; regPTR = ((M_By) ? 24 : 0); R.SP = (R.PSW & 7) << 1; }
static void mov_r0_n(void) { R0 = M_RDMEM_OPCODE(); }
static void mov_r1_n(void) { R1 = M_RDMEM_OPCODE(); }
static void mov_r2_n(void) { R2 = M_RDMEM_OPCODE(); }
static void mov_r3_n(void) { R3 = M_RDMEM_OPCODE(); }
static void mov_r4_n(void) { R4 = M_RDMEM_OPCODE(); }
static void mov_r5_n(void) { R5 = M_RDMEM_OPCODE(); }
static void mov_r6_n(void) { R6 = M_RDMEM_OPCODE(); }
static void mov_r7_n(void) { R7 = M_RDMEM_OPCODE(); }
static void mov_a_t(void) { R.A = R.timer; }
static void mov_t_a(void) { R.timer = R.A; }
static void mov_xr0_a(void) { intRAM[R0 & 0x7f] = R.A; }
static void mov_xr1_a(void) { intRAM[R1 & 0x7f] = R.A; }
static void mov_xr0_n(void) { intRAM[R0 & 0x7f] = M_RDMEM_OPCODE(); }
static void mov_xr1_n(void) { intRAM[R1 & 0x7f] = M_RDMEM_OPCODE(); }
static void movd_a_p4(void) { R.A = port_r(4); }
static void movd_a_p5(void) { R.A = port_r(5); }
static void movd_a_p6(void) { R.A = port_r(6); }
static void movd_a_p7(void) { R.A = port_r(7); }
static void movd_p4_a(void) { port_w(4, R.A); }
static void movd_p5_a(void) { port_w(5, R.A); }
static void movd_p6_a(void) { port_w(6, R.A); }
static void movd_p7_a(void) { port_w(7, R.A); }
static void movp_a_xa(void) { R.A = M_RDMEM((R.PC.W.w1 & 0x0f00) | R.A); }
static void movp3_a_xa(void) { R.A = M_RDMEM(0x300 | R.A); }
static void movx_a_xr0(void) { R.A = M_IN(R0); }
static void movx_a_xr1(void) { R.A = M_IN(R1); }
static void movx_xr0_a(void) { M_OUT(R0, R.A); }
static void movx_xr1_a(void) { M_OUT(R1, R.A); }
static void nop(void) { }
static void orl_a_n(void) { R.A |= M_RDMEM_OPCODE(); }
static void orl_a_r0(void) { R.A |= R0; }
static void orl_a_r1(void) { R.A |= R1; }
static void orl_a_r2(void) { R.A |= R2; }
static void orl_a_r3(void) { R.A |= R3; }
static void orl_a_r4(void) { R.A |= R4; }
static void orl_a_r5(void) { R.A |= R5; }
static void orl_a_r6(void) { R.A |= R6; }
static void orl_a_r7(void) { R.A |= R7; }
static void orl_a_xr0(void) { R.A |= intRAM[R0 & 0x7f]; }
static void orl_a_xr1(void) { R.A |= intRAM[R1 & 0x7f]; }
static void orl_bus_n(void) { bus_w( bus_r() | M_RDMEM_OPCODE() ); }
static void orl_p1_n(void) { port_w(1, port_r(1) | M_RDMEM_OPCODE() ); }
static void orl_p2_n(void) { port_w(2, port_r(2) | M_RDMEM_OPCODE() ); }
static void orld_p4_a(void) { port_w(4, port_r(4) | R.A ); }
static void orld_p5_a(void) { port_w(5, port_r(5) | R.A ); }
static void orld_p6_a(void) { port_w(6, port_r(6) | R.A ); }
static void orld_p7_a(void) { port_w(7, port_r(7) | R.A ); }
static void outl_bus_a(void) { bus_w(R.A); }
static void outl_p1_a(void) { port_w(1, R.A ); }
static void outl_p2_a(void) { port_w(2, R.A ); }
static void ret(void) { R.PC.W.w1 = ((pull() & 0x0f) << 8); R.PC.W.w1 |= pull(); /*change_pc(R.PC.W.w1);*/ }
static void retr(void)
{
byte i=pull();
R.PC.W.w1 = ((i & 0x0f) << 8) | pull(); /*change_pc(R.PC.W.w1);*/
R.irq_executing = I8039_IGNORE_INT;
R.A11 = R.A11ff;
R.PSW = (R.PSW & 0x0f) | (i & 0xf0); /* Stack is already changed by pull */
regPTR = ((M_By) ? 24 : 0);
}
static void rl_a(void) { byte i=R.A & 0x80; R.A <<= 1; if (i) R.A |= 0x01; else R.A &= 0xfe; }
static void rlc_a(void) { byte i=M_Cy; if (R.A & 0x80) SET(C_FLAG); R.A <<= 1; if (i) R.A |= 0x01; else R.A &= 0xfe; }
static void rr_a(void) { byte i=R.A & 1; R.A >>= 1; if (i) R.A |= 0x80; else R.A &= 0x7f; }
static void rrc_a(void) { byte i=M_Cy; if (R.A & 1) SET(C_FLAG); R.A >>= 1; if (i) R.A |= 0x80; else R.A &= 0x7f; }
static void sel_mb0(void) { R.A11 = 0; R.A11ff = 0; }
static void sel_mb1(void) { R.A11ff = 0x800; if (R.irq_executing == I8039_IGNORE_INT) R.A11 = 0x800; }
static void sel_rb0(void) { CLR(B_FLAG); regPTR = 0; }
static void sel_rb1(void) { SET(B_FLAG); regPTR = 24; }
static void stop_tcnt(void) { R.timerON = R.countON = 0; }
static void strt_cnt(void) { R.countON = 1; }
static void strt_t(void) { R.timerON = 1; }
static void swap_a(void) { byte i=R.A >> 4; R.A <<= 4; R.A |= i; }
static void xch_a_r0(void) { byte i=R.A; R.A=R0; R0=i; }
static void xch_a_r1(void) { byte i=R.A; R.A=R1; R1=i; }
static void xch_a_r2(void) { byte i=R.A; R.A=R2; R2=i; }
static void xch_a_r3(void) { byte i=R.A; R.A=R3; R3=i; }
static void xch_a_r4(void) { byte i=R.A; R.A=R4; R4=i; }
static void xch_a_r5(void) { byte i=R.A; R.A=R5; R5=i; }
static void xch_a_r6(void) { byte i=R.A; R.A=R6; R6=i; }
static void xch_a_r7(void) { byte i=R.A; R.A=R7; R7=i; }
static void xch_a_xr0(void) { byte i=R.A; R.A=intRAM[R0 & 0x7F]; intRAM[R0 & 0x7F]=i; }
static void xch_a_xr1(void) { byte i=R.A; R.A=intRAM[R1 & 0x7F]; intRAM[R1 & 0x7F]=i; }
static void xchd_a_xr0(void) { M_XCHD(R0 & 0x7f); }
static void xchd_a_xr1(void) { M_XCHD(R1 & 0x7f); }
static void xrl_a_n(void) { R.A ^= M_RDMEM_OPCODE(); }
static void xrl_a_r0(void) { R.A ^= R0; }
static void xrl_a_r1(void) { R.A ^= R1; }
static void xrl_a_r2(void) { R.A ^= R2; }
static void xrl_a_r3(void) { R.A ^= R3; }
static void xrl_a_r4(void) { R.A ^= R4; }
static void xrl_a_r5(void) { R.A ^= R5; }
static void xrl_a_r6(void) { R.A ^= R6; }
static void xrl_a_r7(void) { R.A ^= R7; }
static void xrl_a_xr0(void) { R.A ^= intRAM[R0 & 0x7f]; }
static void xrl_a_xr1(void) { R.A ^= intRAM[R1 & 0x7f]; }
static unsigned cycles_main[256]=
{
1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2,
1, 1, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 1, 2, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2, 2,
1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 1, 0, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2,
1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
static opcode_fn opcode_main[256]=
{
nop ,illegal ,outl_bus_a ,add_a_n ,jmp ,en_i ,illegal ,dec_a ,
ins_a_bus ,in_a_p1 ,in_a_p2 ,illegal ,movd_a_p4 ,movd_a_p5 ,movd_a_p6 ,movd_a_p7,
inc_xr0 ,inc_xr1 ,jb_0 ,adc_a_n ,call ,dis_i ,jtf ,inc_a ,
inc_r0 ,inc_r1 ,inc_r2 ,inc_r3 ,inc_r4 ,inc_r5 ,inc_r6 ,inc_r7 ,
xch_a_xr0 ,xch_a_xr1 ,illegal ,mov_a_n ,jmp_1 ,en_tcnti ,jnt_0 ,clr_a ,
xch_a_r0 ,xch_a_r1 ,xch_a_r2 ,xch_a_r3 ,xch_a_r4 ,xch_a_r5 ,xch_a_r6 ,xch_a_r7 ,
xchd_a_xr0 ,xchd_a_xr1 ,jb_1 ,illegal ,call_1 ,dis_tcnti ,jt_0 ,cpl_a ,
illegal ,outl_p1_a ,outl_p2_a ,illegal ,movd_p4_a ,movd_p5_a ,movd_p6_a ,movd_p7_a,
orl_a_xr0 ,orl_a_xr1 ,mov_a_t ,orl_a_n ,jmp_2 ,strt_cnt ,jnt_1 ,swap_a ,
orl_a_r0 ,orl_a_r1 ,orl_a_r2 ,orl_a_r3 ,orl_a_r4 ,orl_a_r5 ,orl_a_r6 ,orl_a_r7 ,
anl_a_xr0 ,anl_a_xr1 ,jb_2 ,anl_a_n ,call_2 ,strt_t ,jt_1 ,daa_a ,
anl_a_r0 ,anl_a_r1 ,anl_a_r2 ,anl_a_r3 ,anl_a_r4 ,anl_a_r5 ,anl_a_r6 ,anl_a_r7 ,
add_a_xr0 ,add_a_xr1 ,mov_t_a ,illegal ,jmp_3 ,stop_tcnt ,illegal ,rrc_a ,
add_a_r0 ,add_a_r1 ,add_a_r2 ,add_a_r3 ,add_a_r4 ,add_a_r5 ,add_a_r6 ,add_a_r7 ,
adc_a_xr0 ,adc_a_xr1 ,jb_3 ,illegal ,call_3 ,ento_clk ,jf_1 ,rr_a ,
adc_a_r0 ,adc_a_r1 ,adc_a_r2 ,adc_a_r3 ,adc_a_r4 ,adc_a_r5 ,adc_a_r6 ,adc_a_r7 ,
movx_a_xr0 ,movx_a_xr1 ,illegal ,ret ,jmp_4 ,clr_f0 ,jni ,illegal ,
orl_bus_n ,orl_p1_n ,orl_p2_n ,illegal ,orld_p4_a ,orld_p5_a ,orld_p6_a ,orld_p7_a,
movx_xr0_a ,movx_xr1_a ,jb_4 ,retr ,call_4 ,cpl_f0 ,jnz ,clr_c ,
anl_bus_n ,anl_p1_n ,anl_p2_n ,illegal ,anld_p4_a ,anld_p5_a ,anld_p6_a ,anld_p7_a,
mov_xr0_a ,mov_xr1_a ,illegal ,movp_a_xa ,jmp_5 ,clr_f1 ,illegal ,cpl_c ,
mov_r0_a ,mov_r1_a ,mov_r2_a ,mov_r3_a ,mov_r4_a ,mov_r5_a ,mov_r6_a ,mov_r7_a ,
mov_xr0_n ,mov_xr1_n ,jb_5 ,jmpp_xa ,call_5 ,cpl_f1 ,jf0 ,illegal ,
mov_r0_n ,mov_r1_n ,mov_r2_n ,mov_r3_n ,mov_r4_n ,mov_r5_n ,mov_r6_n ,mov_r7_n ,
illegal ,illegal ,illegal ,illegal ,jmp_6 ,sel_rb0 ,jz ,mov_a_psw,
dec_r0 ,dec_r1 ,dec_r2 ,dec_r3 ,dec_r4 ,dec_r5 ,dec_r6 ,dec_r7 ,
xrl_a_xr0 ,xrl_a_xr1 ,jb_6 ,xrl_a_n ,call_6 ,sel_rb1 ,illegal ,mov_psw_a,
xrl_a_r0 ,xrl_a_r1 ,xrl_a_r2 ,xrl_a_r3 ,xrl_a_r4 ,xrl_a_r5 ,xrl_a_r6 ,xrl_a_r7 ,
illegal ,illegal ,illegal ,movp3_a_xa,jmp_7 ,sel_mb0 ,jnc ,rl_a ,
djnz_r0 ,djnz_r1 ,djnz_r2 ,djnz_r3 ,djnz_r4 ,djnz_r5 ,djnz_r6 ,djnz_r7 ,
mov_a_xr0 ,mov_a_xr1 ,jb_7 ,illegal ,call_7 ,sel_mb1 ,jc ,rlc_a ,
mov_a_r0 ,mov_a_r1 ,mov_a_r2 ,mov_a_r3 ,mov_a_r4 ,mov_a_r5 ,mov_a_r6 ,mov_a_r7
};
/****************************************************************************/
/* Set all registers to given values */
/****************************************************************************/
void I8039_SetRegs (I8039_Regs *Regs)
{
R=*Regs;
regPTR = ((M_By) ? 24 : 0);
R.SP = (R.PSW << 1) & 0x0f;
/*change_pc(R.PC.W.w1);*/
}
/****************************************************************************/
/* Get all registers in given buffer */
/****************************************************************************/
void I8039_GetRegs (I8039_Regs *Regs)
{
*Regs=R;
}
/****************************************************************************/
/* Reset registers to their initial values */
/****************************************************************************/
void I8039_Reset (void)
{
R.PC.W.w1 = 0;
R.SP = 0;
R.A = 0;
R.PSW = 0x08; /* Start with Carry SET, Bit 4 is always SET */
memset(R.RAM, 0x0, 128);
R.bus = 0;
R.irq_executing = I8039_IGNORE_INT;
R.pending_irq = I8039_IGNORE_INT;
R.A11ff = R.A11 = 0;
R.timerON = R.countON = 0;
R.tirq_en = R.xirq_en = 0;
R.xirq_en=1;
R.timerON = 1; /* Mario Bros. doesn't work without this */
R.masterClock = 0;
}
/****************************************************************************/
/* Return program counter */
/****************************************************************************/
unsigned I8039_GetPC (void)
{
return R.PC.W.w1;
}
/****************************************************************************/
/* Issue an interrupt if necessary */
/****************************************************************************/
static int Timer_IRQ(void)
{
if (R.tirq_en && !R.irq_executing)
{
R.irq_executing = I8039_TIMER_INT;
push(R.PC.B.l);
push((R.PC.B.h & 0x0f) | (R.PSW & 0xf0));
R.PC.W.w1 = 0x07;
/*change_pc(0x07);*/
R.A11ff = R.A11;
R.A11 = 0;
return 2; /* 2 clock cycles used */
}
return 0;
}
static int Ext_IRQ(void)
{
if (R.xirq_en)
{
R.irq_executing = I8039_EXT_INT;
push(R.PC.B.l);
push((R.PC.B.h & 0x0f) | (R.PSW & 0xf0));
R.PC.W.w1 = 0x03;
R.A11ff = R.A11;
R.A11 = 0;
return 2; /* 2 clock cycles used */
}
return 0;
}
/****************************************************************************/
/* Execute IPeriod T-States. Return 0 if emulation should be stopped */
/****************************************************************************/
int I8039_Execute(int cycles)
{
unsigned opcode, T1;
I8039_ICount=cycles;
do
{
switch (R.pending_irq)
{
case I8039_COUNT_INT:
case I8039_TIMER_INT: I8039_ICount -= Timer_IRQ();
R.t_flag = 1;
break;
case I8039_EXT_INT: I8039_ICount -= Ext_IRQ();
break;
}
R.pending_irq = I8039_IGNORE_INT;
opcode=M_RDOP(R.PC.W.w1);
{ /* NS 971024 */
extern int previouspc;
previouspc = R.PC.W.w1;
}
R.PC.W.w1++;
I8039_ICount-=cycles_main[opcode];
(*(opcode_main[opcode]))();
T1 = test_r(1);
if (R.countON && POSITIVE_EDGE_T1) /* Handle COUNTER IRQs */
{
R.timer++;
if (R.timer == 0) I8039_Cause_Interrupt(I8039_COUNT_INT);
}
if (R.timerON) /* Handle TIMER IRQs */
{
R.masterClock += cycles_main[opcode];
if (R.masterClock > 31)
{
R.masterClock -= 31;
R.timer++;
if (R.timer == 0) I8039_Cause_Interrupt(I8039_TIMER_INT);
}
}
Old_T1 = T1;
}
while (I8039_ICount>0);
return cycles - I8039_ICount;
}
void I8039_Cause_Interrupt(int type)
{
if (type != I8039_IGNORE_INT)
R.pending_irq = type;
}
void I8039_Clear_Pending_Interrupts(void)
{
R.pending_irq = I8039_IGNORE_INT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -