-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcz80exec.inc
124 lines (104 loc) · 2.88 KB
/
cz80exec.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/********************************************************************************/
/* */
/* CZ80 exec include source file */
/* C Z80 emulator version 0.92 */
/* Copyright 2004-2005 Stéphane Dallongeville */
/* */
/********************************************************************************/
s32 Z80_ICount;
s32 CZ80_FASTCALL Cz80_Exec(cz80_struc *cpu, s32 cycles)
{
#if CZ80_USE_JUMPTABLE
#include "cz80jmp.inc"
#endif
#if __x86__
register cz80_struc *CPU asm ("ebx");
register u8 *PC asm ("esi");
register u32 Opcode asm ("edx");
#else
cz80_struc *CPU;
u8 *PC;
u32 Opcode;
#endif
CPU = cpu;
PC = CPU->PC;
if (CPU->Status & (CZ80_RUNNING | CZ80_DISABLE | CZ80_FAULTED))
{
return (CPU->Status | 0x80000000);
}
CPU->CycleToDo = Z80_ICount = cycles;
CPU->CycleSup = 0;
CPU->Status |= CZ80_RUNNING;
Cz80_Check_Int:
// check for interrupt
if (CPU->Status & (zIFF1 | CZ80_HAS_NMI))
{
u32 newPC;
if (CPU->Status & CZ80_HAS_NMI)
{
// NMI
CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_NMI);
zIFF1 = 0;
newPC = 0x66;
}
else
{
// INT
CPU->Status &= ~(CZ80_HALTED | CZ80_HAS_INT);
zIFF= 0;
// IM = 1
if (zIM == 1) newPC = 0x38;
else
{
u32 adr;
Opcode = CPU->IntVect & 0xFF;
// IM = 0
if (zIM == 0)
goto Cz80_Exec_direct;
// IM = 2
adr = Opcode | (zI << 8);
READ_WORD(adr, newPC)
#if CZ80_IRQ_CYCLES
Z80_ICount -= 8;
#endif
}
}
// set new PC
{
u32 src = zRealPC;
PUSH_16(src)
SET_PC(newPC);
#if CZ80_IRQ_CYCLES
Z80_ICount -= 11;
#endif
}
}
// if some cycles left
if ((Z80_ICount += CPU->CycleSup) > 0)
{
CPU->CycleSup = 0;
if (!(CPU->Status & CZ80_HALTED)) goto Cz80_Exec;
// CPU halted
Z80_ICount = 0;
}
Cz80_Exec_Really_End:
// no more cycles, end execution
CPU->Status &= ~CZ80_RUNNING;
CPU->PC = PC;
// number of executed cycles
Z80_ICount = CPU->CycleToDo - Z80_ICount;
// update R register
zR = (zR + (Z80_ICount >> 2)) & 0x7F;
return Z80_ICount;
#if CZ80_SIZE_OPT
Cz80_Exec_Check:
if (Z80_ICount <= 0) goto Cz80_Check_Int;
#endif
Cz80_Exec:
{
Opcode = REAL_FETCH_BYTE;
Cz80_Exec_direct:
union16 *data = pzHL;
#include "cz80_op.inc"
}
}