-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathccore.h
205 lines (185 loc) · 4.88 KB
/
ccore.h
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "arkad.h"
#include "utils.h"
#include <vector>
#ifndef __CCOREH__
#define __CCOREH__
#ifdef _DEBUG
#define STORECALLLSTACK(a) _cstk.push_back(a);
#define LOADCALLSTACK(a) \
while (!_cstk.empty()){\
u32 b =_cstk.back();\
_cstk.pop_back();\
if(b==(a)) break;\
}
#else
#define STORECALLLSTACK(a)
#define LOADCALLSTACK(a)
#endif
#define STOREPORT(){\
u32 vx = (__cycles<<8)|(_portb);\
EnterCriticalSection(&_cr);\
_pins.push_back(vx);\
LeaveCriticalSection(&_cr);\
}
#define EXECTIMEROBJLOOP(ret,a,b)\
if(_tobj._edge && (_tobj._cyc += ret) >= _tobj._edge){\
LPCPUTIMEROBJ p=_tobj._first;\
while(p){\
LPCPUTIMEROBJ pp = p->next;\
if((p->cyc+=_tobj._cyc) >= p->elapsed){\
int i__ = p->obj->Run(b,p->cyc,p);\
p->cyc %= p->elapsed;\
if(i__> 0){a;}\
if(i__ == -1 || BVT(p->type,0))\
DelTimerObj(p->obj);\
else if(i__<0){u32 i___=i__&~0x80000000;p->elapsed=i___;if(_tobj._edge == 0 || i___ <_tobj._edge) _tobj._edge=i___;}\
}\
p=pp;\
}\
_tobj._cyc-=_tobj._edge;\
}
#define ISMEMORYBREAKPOINT(a) ((SR(a,32) & 0x8003) == 0x8003)
#define BK_VALUE(a,b,c) \
if(ISMEMORYBREAKPOINT(a)){\
b= SR(a&0xf8,3);\
if(a & 0x40000000)\
b |= SR(a&0x0fffff00,3);\
else\
b=c[b];\
}\
else{\
b = SR(a&0x7f00,8);\
if(a & 0x40000000)\
b |= SR(a&0x3fff0000,9);\
else\
b=c[rd];\
}
#define BK_CONDITION(a,b)\
if(ISMEMORYBREAKPOINT(a)) b=SR((u64)a,35)&7;\
else b=(SR(u64)a,32) & 7;\
#define ISMEMORYBREAKPOINT(a) ((SR(a,32) & 0x8003) == 0x8003)
#define ISBREAKPOINTENABLED(a) ((a & 0x8000000000000000))
#define RESETBREAKPOINTCOUNTER(a) (a & 0xFFFF8000FFFFFFFF)
#define ISBREAKPOINTCOUNTER(a) ((a&0x800000000000)==0)
#ifdef _DEBUG
#define CHECKBREAKPOINT(it)\
u32 vv=SR(v,32);\
if(vv&0x8000){\
u32 rs,rd;\
if(!(v&0x8000000000000000))\
continue;\
if((vv&7)==7)\
continue;\
rs = _regs[SR(vv,3)&0x1f];\
rd = SR(vv&0x7f00,8);\
if(vv & 0x40000000)\
rd |= SR(vv&0x3fff0000,9);\
else\
rd=_regs[rd];\
switch(vv&0x3){\
case 0:\
if(rd==rs)\
continue;\
break;\
case 1:\
if(rd!=rs)\
continue;\
break;\
}\
}\
else{\
int ret=(int)(vv&0x7fff)+1;\
v=(v&~0xFFFF00000000)|(SL((u64)(ret&0x7fff),32));\
*it=v;\
if(!(v&0x8000000000000000))\
continue;\
int i=(int)SR(vv,16) & 0x7fff;\
if(i && i != ret)\
continue;\
if(i) *it=RESETBREAKPOINTCOUNTER(v);\
}
#else
#define CHECKBREAKPOINT(it)
#endif
#define EXECCHECKBREAKPOINT(a,b)\
if(BT(a,S_DEBUG) && !BT(a,S_DEBUG_NEXT)){\
for (auto it = _bk.begin();it != _bk.end(); ++it){\
u64 v=(u64)*it;\
if(_pc < (b)v) break;\
if((b)v != _pc) continue;\
CHECKBREAKPOINT(it);\
return -2;\
}\
}
#define __S(a,...) sprintf(cc,STR(%s) STR(\x20) STR(a),## __VA_ARGS__);
#define __F(a,...) printf(STR(%08X %04X %s) STR(\x20) STR(a) STR(\n),_pc,_opcode,## __VA_ARGS__);
#define D_CYCLES(a,b,c) (c > (a) ? c-(a) : ((b)-(a))+c)
#define SPU_CYCLES(a,b,c,d) ( SR(D_CYCLES(a,b,d) * (SL(c,12)/b),12))
class CCore : public ICore{
public:
CCore(void *p=NULL);
virtual ~CCore();
virtual int Reset();
virtual int Destroy();
virtual int _exec(u32)=0;
int AddTimerObj(ICpuTimerObj *obj,u32 _elapsed=0,void* param=NULL,u32 f=0);
int DelTimerObj(ICpuTimerObj *obj);
LPCPUTIMEROBJ GetTimerObj(ICpuTimerObj *obj);
char *_getFilename(char *p=NULL){return _filename;};
virtual int Query(u32,void *);
virtual int Exec(u32);
virtual int Restart();
virtual int Stop();
virtual int _dumpMemory(char *p,u8 *mem,LPDEBUGGERDUMPINFO pdi=NULL,u32 sz=0);
virtual int _dumpRegisters(char *p);
virtual int _dumpCallstack(char *p);
I_INLINE u32 getTicks(){return _cycles;};
I_INLINE u32 getFrequency(){return _freq;};
I_INLINE u32 isStopped(){return _status & S_QUIT ? 1 : 0;};
protected:
virtual int _dump(char **,LPDEBUGGERDUMPINFO);
virtual int SaveState(IStreamer *);
virtual int LoadState(IStreamer *);
int DestroyWaitableObject();
int ResetWaitableObject();
void ResetBreakpoint();
int AddBreakpoint(u64);
virtual int Disassemble(char *dest,u32 *padr){return 0;};
struct {
u32 _cyc,_edge;
LPCPUTIMEROBJ _first;
} _tobj;
u32 _cycles,_pc,_freq,_attributes;
CRITICAL_SECTION _cr;
std::vector<u32> _cstk;
std::vector<u64> _bk;
char *_filename;
CoreMACallback *_portfnc_write,*_portfnc_read;
CoreDecode *_opcodescb;
CoreDisassebler *_disopcodecb;
u8 *_mem,*_regs,_idx;
void *_machine;
private:
u64 _status;
};
class MemoryStream : std::vector<void *>,IStreamer{
public:
MemoryStream(u32 dw=8192);
virtual ~MemoryStream();
virtual int Read(void *,u32,u32 *o=0);
virtual int Write(void *,u32,u32 *o=0);
virtual int Close();
virtual int Seek(s64,u32);
virtual int Open(char *fn=NULL,u32 a=0);
virtual int Tell(u64 *r);
protected:
struct buffer{
u8 *buf;
u32 dwSize,dwPos,dwBytesWrite;
buffer(u32 dw = 8192);
};
buffer *AddBuffer();
u32 dwPos,dwSize,dwIndex,dwBufferSize;
buffer *currentBuffer;
};
#endif