-
Notifications
You must be signed in to change notification settings - Fork 0
/
assembler.h
385 lines (326 loc) · 9.05 KB
/
assembler.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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
/*
* VICasm Assembler by h34ting4ppliance
*
* assembler.h
*
* Assembler headers.
*/
#ifndef ASSEMBLER_H
#define ASSEMBLER_H
#include <string>
#include <vector>
#include <map>
#include "parser.h"
// Unsigned char string
namespace std
{
typedef std::basic_string<uint8_t> ustring;
}
// To check if the parsed command
// matches the opcode
#define SHALT HALT, 0
#define SNOP NOP, 0
// stack
#define SPUSH_RR PUSH, 1, BIT16_REG
#define SPUSHA PUSHA, 0
#define SPOP_RR POP, 1, BIT16_REG
#define SPOPA POPA, 0
// mov
#define SMOV_RR MOV, 2, BIT8_REG, BIT8_REG
#define SMOV_PR MOV, 2, REG_POINTER, BIT8_REG
#define SMOV_RN MOV, 2, BIT8_REG, NUM_CONST
#define SMOV_RD MOV, 2, BIT8_REG, DEF_CONST
#define SMOV_PN MOV, 2, REG_POINTER, NUM_CONST
#define SMOV_PD MOV, 2, REG_POINTER, DEF_CONST
#define SMOV_RP MOV, 2, BIT8_REG, REG_POINTER
#define SMOV_SPNN MOV, 2, SP_REG, NUM_CONST
#define SMOV_SPDD MOV, 2, SP_REG, DEF_CONST
#define SMOV_SPHL MOV, 2, SP_REG, BIT16_REG
#define SMOV_HLSP MOV, 2, BIT16_REG, SP_REG
#define SMOV_ARR MOV, 2, BIT8_REG, REG_POINTER
#define SMOV_ANN MOV, 2, BIT8_REG, NUM_POINTER
#define SMOV_ADD MOV, 2, BIT8_REG, DEF_POINTER
#define SMOV_RRA MOV, 2, REG_POINTER, BIT8_REG
#define SMOV_NNA MOV, 2, NUM_POINTER, BIT8_REG
#define SMOV_DDA MOV, 2, DEF_POINTER, BIT8_REG
#define SMOV_RRNN MOV, 2, BIT16_REG, NUM_CONST
#define SMOV_RRDD MOV, 2, BIT16_REG, DEF_CONST
// add a, *
#define SADD_R ADD, 2, BIT8_REG, BIT8_REG
#define SADD_N ADD, 2, BIT8_REG, NUM_CONST
#define SADD_D ADD, 2, BIT8_REG, DEF_CONST
#define SADD_P ADD, 2, BIT8_REG, REG_POINTER
// add hl, *
#define SADD_RR ADD, 2, BIT16_REG, BIT16_REG
#define SADD_NN ADD, 2, BIT16_REG, NUM_CONST
#define SADD_DD ADD, 2, BIT16_REG, DEF_CONST
// sub
#define SSUB_R SUB, 2, BIT8_REG, BIT8_REG
#define SSUB_N SUB, 2, BIT8_REG, NUM_CONST
#define SSUB_D SUB, 2, BIT8_REG, DEF_CONST
#define SSUB_P SUB, 2, BIT8_REG, REG_POINTER
// sub hl, *
#define SSUB_RR SUB, 2, BIT16_REG, BIT16_REG
#define SSUB_NN SUB, 2, BIT16_REG, NUM_CONST
#define SSUB_DD SUB, 2, BIT16_REG, DEF_CONST
// and
#define SAND_R AND, 1, BIT8_REG
#define SAND_N AND, 1, NUM_CONST
#define SAND_D AND, 1, DEF_CONST
#define SAND_P AND, 1, REG_POINTER
// or
#define SOR_R OR, 1, BIT8_REG
#define SOR_N OR, 1, NUM_CONST
#define SOR_D OR, 1, DEF_CONST
#define SOR_P OR, 1, REG_POINTER
// xor
#define SXOR_R XOR, 1, BIT8_REG
#define SXOR_N XOR, 1, NUM_CONST
#define SXOR_D XOR, 1, DEF_CONST
#define SXOR_P XOR, 1, REG_POINTER
// inc/dec
// inc r/rr
#define SINC_R INC, 1, BIT8_REG
#define SINC_RR INC, 1, BIT16_REG
// dec r/rr
#define SDEC_R DEC, 1, BIT8_REG
#define SDEC_RR DEC, 1, BIT16_REG
// sl/sr
// sl
#define SSL_R SL, 1, BIT8_REG
// sr
#define SSR_R SR, 1, BIT8_REG
// cp
// cp r
#define SCP_R CP, 1, BIT8_REG
// cp n
#define SCP_N CP, 1, NUM_CONST
#define SCP_D CP, 1, DEF_CONST
// cp (hl)
#define SCP_P CP, 1, REG_POINTER
// jp
// jp nn
#define SJP_NN JP, 1, NUM_CONST
#define SJP_DD JP, 1, DEF_CONST
// jp HL
#define SJP_P JP, 1, BIT16_REG
// jc
// jc nn
#define SJC_NN JC, 1, NUM_CONST
#define SJC_DD JC, 1, DEF_CONST
// jc HL
#define SJC_P JC, 1, BIT16_REG
// jz
// jz nn
#define SJZ_NN JZ, 1, NUM_CONST
#define SJZ_DD JZ, 1, DEF_CONST
// jz HL
#define SJZ_P JZ, 1, BIT16_REG
// jn
// jn nn
#define SJN_NN JN, 1, NUM_CONST
#define SJN_DD JN, 1, DEF_CONST
// jn HL
#define SJN_P JN, 1, BIT16_REG
// call
// call nn
#define SCALL_NN CALL, 1, NUM_CONST
#define SCALL_DD CALL, 1, DEF_CONST
// call HL
#define SCALL_P CALL, 1, BIT16_REG
// ret
#define SRET RET, 0
// dumpr/dumpm
#define SDUMP_R DUMP_R, 0
#define SDUMP_M DUMP_M, 1, NUM_CONST
#define SDUMP_MD DUMP_M, 1, DEF_CONST
// slp
#define SSLP SLP, 0
// swap
#define SSWAP_R SWAP, 1, BIT8_REG
#define SSWAP_P SWAP, 1, REG_POINTER
#define SSWAP_RR SWAP, 1, BIT16_REG
// .define
#define SDEFINE DEFINE, 2, DEF_CONST, NUM_CONST
// .include
#define SINCLUDE INCLUDE,1, STRING
// .bin
#define SBIN BIN, 1, STRING
// .org
#define SORG ORG, 1, NUM_CONST
// Label
#define SLABEL LBL, 1, STRING
// DBG
#define SDBG DBG, 0
//////////////////////////
// Opcodes enum
typedef enum
{
// halt
IHALT,
// nop
INOP = IHALT + 1,
// push nn
IPUSH_RR = INOP + 1,
// pusha
IPUSHA = IPUSH_RR + 3,
// pop nn
IPOP_RR = IPUSHA + 1,
// popa
IPOPA = IPOP_RR + 3,
// mov
// mov r, r
IMOV_RR = IPOPA + 1,
// mov (HL), r
IMOV_PR = IMOV_RR + 49,
// mov r, n
IMOV_RN = IMOV_PR + 7,
// mov (HL), n
IMOV_PN = IMOV_RN + 7,
// mov r, (HL)
IMOV_RP = IMOV_PN + 1,
// mov SP, nn
IMOV_SPNN = IMOV_RP + 7,
// mov SP, HL
IMOV_SPHL = IMOV_SPNN + 1,
// mov HL, SP
IMOV_HLSP = IMOV_SPHL + 1,
// mov a, (BC/DE)
IMOV_ARR = IMOV_HLSP + 1,
// mov a, (nn)
IMOV_ANN = IMOV_ARR + 2,
// mov (BC/DE), a
IMOV_RRA = IMOV_ANN + 1,
// mov (nn), a
IMOV_NNA = IMOV_RRA + 2,
// mov rr, nn
IMOV_RRNN = IMOV_NNA + 1,
// ALU
// add A, r
IADD_R = IMOV_RRNN + 3,
// add A, n
IADD_N = IADD_R + 7,
// add A, (hl)
IADD_P = IADD_N + 1,
// add HL, rr
IADD_RR = IADD_P + 1,
// add HL, nn
IADD_NN = IADD_RR + 3,
// sub A, r
ISUB_R = IADD_NN + 1,
// sub A, n
ISUB_N = ISUB_R + 7,
// sub A, (hl)
ISUB_P = ISUB_N + 1,
// sub HL, rr
ISUB_RR = ISUB_P + 1,
// sub HL, nn
ISUB_NN = ISUB_RR + 3,
// and r
IAND_R = ISUB_NN + 1,
// and n
IAND_N = IAND_R + 7,
// and (hl)
IAND_P = IAND_N + 1,
// or r
IOR_R = IAND_P + 1,
// or n
IOR_N = IOR_R + 7,
// or (hl)
IOR_P = IOR_N + 1,
// xor r
IXOR_R = IOR_P + 1,
// xor n
IXOR_N = IXOR_R + 7,
// xor (hl)
IXOR_P = IXOR_N + 1,
// inc/dec
// inc r/rr
IINC_R = IXOR_P + 1,
IINC_RR = IINC_R + 7,
// dec r/rr
IDEC_R = IINC_RR + 3,
IDEC_RR = IDEC_R + 7,
// sl/sr
// sl r
ISL_R = IDEC_RR + 3,
// sr r
ISR_R = ISL_R + 7,
// cp
ICP_R = ISR_R + 7,
ICP_N = ICP_R + 7,
ICP_P = ICP_N + 1,
// Jumps
// jp nn/(hl)
IJP_NN = ICP_P + 1,
IJP_P = IJP_NN + 1,
// jc nn/(hl)
IJC_NN,
IJC_P,
// jz nn/(hl)
IJZ_NN,
IJZ_P,
// jn nn/(hl)
IJN_NN,
IJN_P,
// call nn/(hl)
ICALL_NN,
ICALL_P,
// ret
IRET,
// dumpr/dumpm
IDUMP_R,
IDUMP_M,
// slp
ISLP,
// swap A, r
ISWAP_R = ISLP + 1,
// swap (hl)
ISWAP_P = ISWAP_R + 7,
// swap HL, rr
ISWAP_RR = ISWAP_P + 1,
// dbg
IDBG = ISWAP_RR + 3
} Opcodes;
// Assembler Label/Definition class
class ASMLabel
{
public:
std::string name;
WORD value;
ASMLabel (std::string, WORD, bool);
void insert_def(std::string&, size_t);
// This value may be modified later.
bool is_word;
};
// Assembler class
class ASMAssembler
{
private:
// Actual assemble function
void assemble_one(const char*, std::ustring&);
// Append label loc
void append_label_loc(std::string, WORD, bool);
// Links labels
void label_link(std::ustring& prgm);
// Labels
std::map<std::string, WORD> labels;
// Labels location
std::vector<ASMLabel> labels_loc;
// Location pointer
WORD locpointer;
// ORG
signed int orgptr = 0;
// Main file
std::string mainfile;
// Files
std::vector<ASMFile> files;
public:
// Init function.
ASMAssembler (std::string, WORD);
// Add a file into the class.
void add_file(std::string);
// Assemble and insert the binary into an array of characters
std::ustring assemble();
};
#endif