-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrnemu.h
128 lines (120 loc) · 2.97 KB
/
trnemu.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
#ifndef TRNEMU_H
#define TRNEMU_H
#include <QVector>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
class TrnEmu : public QThread
{
Q_OBJECT
public:
TrnEmu(unsigned long sleepInterval, QVector<quint32> pgm, bool logExecutionPhaseOnly, QObject* parent);
~TrnEmu();
void run();
void pause();
void resume();
inline bool getPaused() const { return _paused; }
void setInput(quint32 input);
typedef enum {
// 32 bit regs
BR,
A,
X,
IR,
// 16 bit regs
SP,
I,
PC,
AR,
// 8 bit regs
SC,
CLOCK,
F,
V,
Z,
S,
H,
REG_MAX // used for the enum->str array length
} Register;
const char* const regToString[REG_MAX] = {
"BR",
"A",
"X",
"IR",
"SP",
"I",
"PC",
"AR",
"SC",
"CLOCK",
"F",
"V",
"Z",
"S",
"H",
};
const char* const insnToString[REG_MAX] = {
"BR",
"A",
"X",
"IR",
"SP",
"I",
"PC",
"AR",
"SC",
"CLOCK",
"F",
"V",
"Z",
"S",
"H",
};
typedef enum {
Read,
Write,
InPlace, // When a register is modified in place (incremented/shifted/...)
} OperationType;
typedef enum {
INA,
INX,
INI,
DCA,
DCX,
DCI,
} InPlaceRegUpdateArg;
void setDelay(unsigned long interval);
public slots:
void step();
private:
QVector<quint32> _memory;
quint32 regBR, regA, regX, regIR, regCLOCK;
quint16 regSP, regI, regPC, regAR;
quint8 regSC, regF, regV, regZ, regS, regH;
inline void reset() { regBR = regAR = regA = regX = regIR = regSP = regI = regSC = regCLOCK = regF = regV = regZ = regS = regH = regPC = 0; }
QMutex* _isProcessing;
QMutex* _intervalMutex;
unsigned long _sleepInterval;
QWaitCondition* _cond;
QWaitCondition* _inputCond;
bool _shouldPause;
bool _paused; // This is NOT protected by a mutex. Must only be used by the parent thread. Same as getPaused
bool overflow;
bool _logAllPhases; // emu thread only
bool _printToLog; // likewise
// Private internal functions that should only be called by the emu thread
void updateFlagReg(quint8& reg, quint8 isFlag, Register regEnum);
void clock_tick();
void checkpoint();
signals:
//void dataModified(Register, OperationType);
void memoryUpdated(int addr, quint32 data, OperationType t);
void registerUpdated(Register r, OperationType t, quint8 val);
void registerUpdated(Register r, OperationType t, quint16 val);
void registerUpdated(Register r, OperationType t, quint32 val);
void executionLog(quint32 clk, QString log, QString val);
void executionError(QString err);
void outputSet(quint32 out);
void requestInput();
};
#endif // TRNEMU_H