Browse code

Add source code of the assembler compiler

Pawel Jablonski authored on 14/12/2022 19:04:16
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,208 @@
1
+/*
2
+ * Author: Pawel Jablonski
3
+ * E-mail: pj@xirx.net
4
+ * WWW: xirx.net
5
+ * GIT: git.xirx.net
6
+ *
7
+ * License: You can use this code however you like
8
+ * but leave information about the original author.
9
+ * Code is free for non-commercial and commercial use.
10
+ */
11
+
12
+#include "asm.h"
13
+
14
+//! Constructor for assembler start functions
15
+Asm::Asm()
16
+{
17
+}
18
+
19
+/**
20
+ * Compile the kernel
21
+ *
22
+ * @param inputFile Name of the input source file
23
+ * @param outputFile Name of the output binary file
24
+ * @param outputMapFile Name of the output map file
25
+ *
26
+ * @return Status of compilation
27
+ */
28
+bool Asm::compileRom(const QString &inputFile, const QString &outputFile, const QString &outputMapFile)
29
+{
30
+	return(this->compile(DataList::Mode::Rom, inputFile, outputFile, outputMapFile));
31
+}
32
+
33
+/**
34
+ * Compile the application
35
+ *
36
+ * @param inputFile Name of the input source file
37
+ * @param outputFile Name of the output binary file
38
+ *
39
+ * @return Status of compilation
40
+ */
41
+bool Asm::compileApp(const QString &inputFile, const QString &outputFile)
42
+{
43
+	return(this->compile(DataList::Mode::App, inputFile, outputFile));
44
+}
45
+
46
+/**
47
+ * Compile the source
48
+ *
49
+ * @param mode Mode of compilation
50
+ * @param inputFile Name of the input source file
51
+ * @param outputFile Name of the output binary file
52
+ * @param outputMapFile Name of the output map file
53
+ *
54
+ * @return Status of compilation
55
+ */
56
+bool Asm::compile(DataList::Mode mode, QString inputFile,  QString outputFile,  QString outputMapFile)
57
+{
58
+	QTextStream out(stdout);
59
+
60
+	DataList dataList(mode);
61
+	Parser parser(dataList);
62
+
63
+	if(!parser.parseFile(inputFile))
64
+	{
65
+		out << "ERROR: Parsing error\n\n";
66
+		return(-1);
67
+	}
68
+
69
+	Compiler compiler(dataList);
70
+	this->initInstructions(compiler);
71
+
72
+	if(!compiler.compile())
73
+	{
74
+		out << "ERROR: Compilation error\n\n";
75
+		return(-1);
76
+	}
77
+
78
+	Linker linker(dataList);
79
+
80
+	if(!linker.link())
81
+	{
82
+		out << "ERROR: Linking error\n\n";
83
+		return(-1);
84
+	}
85
+
86
+	if(!linker.saveFile(outputFile, outputMapFile))
87
+	{
88
+		out << "ERROR: Failed to save file\n\n";
89
+		return(-1);
90
+	}
91
+
92
+	out << "OK: The file was saved successfully\n\n";
93
+	return(0);
94
+}
95
+
96
+/**
97
+ * Init the instruction list for the compiler
98
+ *
99
+ * @param compiler Compiler to which the instructions will be added
100
+ */
101
+void Asm::initInstructions(Compiler &compiler)
102
+{
103
+	// LOAD_I + RPC+1
104
+	compiler.addInstruction(Instruction("nop", 0b00000000));
105
+
106
+	// LOAD_I + RPC
107
+	compiler.addInstruction(Instruction("halt", 0b11111111));
108
+
109
+	// LOAD_I + STORE + RPC+1
110
+	compiler.addInstruction(Instruction("ldf", 0b00000100, Instruction::Arg::ABXY));
111
+	compiler.addInstruction(Instruction("ldr", 0b00001000, Instruction::Arg::ABXY));
112
+	compiler.addInstruction(Instruction("str", 0b00001100, Instruction::Arg::ABXY));
113
+	compiler.addInstruction(Instruction("mov", 0b10000000, Instruction::Arg::ABXY, Instruction::Arg::ABXY));
114
+	compiler.addInstruction(Instruction("in", 0b00010000, Instruction::Arg::ABXY));
115
+	compiler.addInstruction(Instruction("out", 0b00010100, Instruction::Arg::ABXY));
116
+
117
+	// LOAD_I + ALU + RPC+1
118
+	compiler.addInstruction(Instruction("cmp", 0b11100000, Instruction::Arg::AB, Instruction::Arg::ABXY));
119
+
120
+	// LOAD_I + ALU + STORE + RPC+1
121
+	compiler.addInstruction(Instruction("inc", 0b00011000, Instruction::Arg::ABXY));
122
+	compiler.addInstruction(Instruction("incc", 0b01110000, Instruction::Arg::ABXY));
123
+	compiler.addInstruction(Instruction("dec", 0b00011100, Instruction::Arg::ABXY));
124
+	compiler.addInstruction(Instruction("decc", 0b01110100, Instruction::Arg::ABXY));
125
+	compiler.addInstruction(Instruction("not", 0b00100000, Instruction::Arg::ABXY));
126
+	compiler.addInstruction(Instruction("add", 0b10010000, Instruction::Arg::AB, Instruction::Arg::ABXY));
127
+	compiler.addInstruction(Instruction("addc", 0b10011000, Instruction::Arg::AB, Instruction::Arg::ABXY));
128
+	compiler.addInstruction(Instruction("sub", 0b10100000, Instruction::Arg::AB, Instruction::Arg::ABXY));
129
+	compiler.addInstruction(Instruction("subc", 0b10101000, Instruction::Arg::AB, Instruction::Arg::ABXY));
130
+	compiler.addInstruction(Instruction("and", 0b10110000, Instruction::Arg::AB, Instruction::Arg::ABXY));
131
+	compiler.addInstruction(Instruction("or", 0b10111000, Instruction::Arg::AB, Instruction::Arg::ABXY));
132
+	compiler.addInstruction(Instruction("xor", 0b11000000, Instruction::Arg::AB, Instruction::Arg::ABXY));
133
+	compiler.addInstruction(Instruction("shl", 0b01111000, Instruction::Arg::ABXY));
134
+	compiler.addInstruction(Instruction("clr", 0b11001000, Instruction::Arg::ABXY));
135
+
136
+	// LOAD_I + 8x ALU + STORE + RPC+1
137
+	compiler.addInstruction(Instruction("shr", 0b01111100, Instruction::Arg::ABXY));
138
+	compiler.addInstruction(Instruction("swap", 0b01101100, Instruction::Arg::ABXY));
139
+
140
+	// LOAD_I + PC+1 + STORE + RPC+1
141
+	compiler.addInstruction(Instruction("mov", 0b00100100, Instruction::Arg::Val256, Instruction::Arg::ABXY));
142
+	compiler.addInstruction(Instruction("out", 0b00000010, Instruction::Arg::Val256));
143
+
144
+	// LOAD_I + PC+1 + LOAD_D + STORE + RPC+1
145
+	compiler.addInstruction(Instruction("str", 0b00000001, Instruction::Arg::Val256));
146
+
147
+	// LOAD_I + PC+1 + LOAD_D + ALU + RPC+1
148
+	compiler.addInstruction(Instruction("cmp", 0b00101000, Instruction::Arg::Val256, Instruction::Arg::ABXY));
149
+
150
+	// LOAD_I + PC+1 + LOAD_D + ALU + STORE + RPC+1
151
+	compiler.addInstruction(Instruction("add", 0b00101100, Instruction::Arg::Val256, Instruction::Arg::ABXY));
152
+	compiler.addInstruction(Instruction("addc", 0b00110000, Instruction::Arg::Val256, Instruction::Arg::ABXY));
153
+	compiler.addInstruction(Instruction("sub", 0b00110100, Instruction::Arg::Val256, Instruction::Arg::ABXY));
154
+	compiler.addInstruction(Instruction("subc", 0b00111000, Instruction::Arg::Val256, Instruction::Arg::ABXY));
155
+	compiler.addInstruction(Instruction("and", 0b00111100, Instruction::Arg::Val256, Instruction::Arg::ABXY));
156
+	compiler.addInstruction(Instruction("or", 0b01000000, Instruction::Arg::Val256, Instruction::Arg::ABXY));
157
+	compiler.addInstruction(Instruction("xor", 0b01000100, Instruction::Arg::Val256, Instruction::Arg::ABXY));
158
+
159
+	// LOAD_I + PC+1 + LOAD_MAL + PC+1 + LOAD_MAH + STORE + RPC+1
160
+	compiler.addInstruction(Instruction("ldf", 0b01011000, Instruction::Arg::Addr, Instruction::Arg::ABXY));
161
+	compiler.addInstruction(Instruction("ldr", 0b01011100, Instruction::Arg::Addr, Instruction::Arg::ABXY));
162
+	compiler.addInstruction(Instruction("str", 0b01100000, Instruction::Arg::ABXY, Instruction::Arg::Addr));
163
+
164
+	// LOAD_I + PC+1 + LOAD_D +  PC+1 + LOAD_MAL + PC+1 + LOAD_MAH + STORE + RPC+1
165
+	compiler.addInstruction(Instruction("str", 0b00000011, Instruction::Arg::Val256, Instruction::Arg::Addr));
166
+
167
+	// LOAD_I + LOAD + LOAD + RPC+1 + LOAD_I + LOAD + RPC+1
168
+	compiler.addInstruction(Instruction("xchg", 0b11010000, Instruction::Arg::ABXY, Instruction::Arg::ABXY, Instruction::Arg::None, 0b11001100, Instruction::Arg::ABXY));
169
+
170
+	// LOAD_I + PC+1 + LOAD_MAL + PC+1 + LOAD_MAH + 3x STORE + RPC+1
171
+	compiler.addInstruction(Instruction("xchg", 0b01001000, Instruction::Arg::Addr, Instruction::Arg::ABXY));
172
+
173
+	// LOAD_I + PC+1 + LOAD_PCL + PC+1 + LOAD_PCH + STORE + RESET
174
+	compiler.addInstruction(Instruction("jmp", 0b11110000, Instruction::Arg::Addr));
175
+
176
+	// LOAD_I + PC+1 + LOAD_D + PC+1 + LOAD_PCH + STORE + RESET
177
+	//		  + PC+1 + PC+1 + RPC+1
178
+	compiler.addInstruction(Instruction("je", 0b11111000, Instruction::Arg::Addr));
179
+	compiler.addInstruction(Instruction("jne", 0b11111001, Instruction::Arg::Addr));
180
+	compiler.addInstruction(Instruction("jg", 0b11111010, Instruction::Arg::Addr));
181
+	compiler.addInstruction(Instruction("jge", 0b11111011, Instruction::Arg::Addr));
182
+	compiler.addInstruction(Instruction("jl", 0b11111100, Instruction::Arg::Addr));
183
+	compiler.addInstruction(Instruction("jle", 0b11111101, Instruction::Arg::Addr));
184
+
185
+	// LOAD_I + STORE + SP-1 + RPC+1
186
+	compiler.addInstruction(Instruction("push", 0b01100100, Instruction::Arg::ABXY));
187
+
188
+	// LOAD_I + SP+1 + STORE + RPC+1
189
+	compiler.addInstruction(Instruction("pop", 0b01101000, Instruction::Arg::ABXY));
190
+
191
+	// LOAD_I + STORE + SP-1 + STORE + SP-1 + PC+1 + LOAD_D + PC+1 + LOAD_PCH + STORE + RESET
192
+	compiler.addInstruction(Instruction("call", 0b11110001, Instruction::Arg::Addr));
193
+
194
+	// LOAD_I + SP+1 + STORE + SP+1 + STORE + RESET
195
+	compiler.addInstruction(Instruction("ret", 0b11110010));
196
+
197
+	// LOAD_I + ALU + PC+1 + PC+1 + RPC+1
198
+	//              + ALU + STORE + PC+1 + LOAD_D + PC+1 + LOAD_PCH + STORE + RESET
199
+	compiler.addInstruction(Instruction("loope", 0b11101000, Instruction::Arg::AB, Instruction::Arg::ABXY, Instruction::Arg::Addr));
200
+
201
+	// LOAD_I + ALU + STORE + PC+1 + PC+1 + PC+1 + RPC+1
202
+	//                             + ALU + STORE + PC+1 + LOAD_D + PC+1 + LOAD_PCH + STORE + RESET
203
+	compiler.addInstruction(Instruction("loope", 0b01001100, Instruction::Arg::Val256, Instruction::Arg::ABXY, Instruction::Arg::Addr));
204
+
205
+	// LOAD_I + ALU STORE + PC+1 + PC+1 + RPC+1
206
+	//                    + ALU + STORE + PC+1 + LOAD_D + PC+1 + LOAD_PCH + STORE + RESET
207
+	compiler.addInstruction(Instruction("loopz", 0b11110100, Instruction::Arg::ABXY, Instruction::Arg::Addr));
208
+}