-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.h
214 lines (182 loc) · 6.15 KB
/
main.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
#include <stdint.h>
#define PCVALUE mem[0]
#define PCTARGET mem[mem[0]]
#define PCTARGETPLUS1 mem[mem[0] +1]
#define PCTARGETPLUS2 mem[mem[0] +2]
#define PCDEREF mem[mem[mem[0]]
#define PCDEREFPLUS1 mem[mem[mem[0] +1]]
#define PCDEREFPLUS2 mem[mem[mem[0] +2]]
#define PCADDRESSDEREF mem[mem[mem[mem[0]]]]
#define PCADDRESSDEREFPLUS1 mem[mem[mem[mem[0] +1]]]
#define PCADDRESSDEREFPLUS2 mem[mem[mem[mem[0] +2]]]
#define SPVALUE mem[1]
#define BASEMEM 4096
#define MEMWORDS (BASEMEM + 16 + 2) /* Word addressed machine, "16" is to leave room for interrupt vectors on top, plus gap plus INPORTC above that! */
#define STACKTOP (BASEMEM - 1) /* Start stack at (0 based) BASEMEM-1, (ie last word in memory) */
#define STACKELEMENTS 1000 /* Maximum number of elements in stack */
#define STARTPOS 16 /* Start at memory location 16, (0 based), to avoid scribbling on registers! */
#define VECTOR_BASE 1024 /* 0 based, ie 1025th element */
#define KBDPOLL_INTERVAL 1000 /* Number of cycles between keyboard polls */
#define VECTOR_COUNT 16 /* How many interrupt vectors? */
#define INPUTBUFFER_SZ 32 /* How many characters can we store in the input buffer? */
/* R0 to R15 are first 16 words of memory, no need for pretend register addresses
* R0 is program counter.
* R1 is stack pointer.
*/
/* Hardcoded memory addresses (outside of physical memory range) */
#define OUTPORTC_LOCATION (1 << 23) + 1
#define OUTPORTI_LOCATION (1 << 23) + 2
#define INPORTC_LOCATION (MEMWORDS - 1) /* no INPORTI */
#define PCREGISTER 0
#ifdef MAIN_GLOBALS
int mem[MEMWORDS]; /* 16777216 bytes (4194304 words). ((22bit addressing) */
/* Flags aren't part of a register yet */
uint8_t eq; /* Equality flag */
uint8_t c; /* Carry flag */
int stoprun=0;
int absolute=0; /* ie don't post-fiddle with pc */
int wordcount=0; /* Assembly word count */
#else
extern int mem[MEMWORDS]; /* 16777216 bytes (4194304 words). ((22bit addressing) */
extern uint8_t eq; /* Equality flag */
extern uint8_t c; /* Carry flag */
extern int stoprun;
extern int absolute; /* ie don't post-fiddle with pc */
extern int wordcount; /* Assembly word count */
#endif
#define MAX_LINE_LEN 1024
typedef void (*Handler)(int leftaddressmode, int rightaddressmode);
typedef struct instruction {
char *name;
uint32_t opcode; /* Opcode is actually position in opcode table */
uint8_t length;
Handler handler;
} t_instruction;
/* Instruction prototypes */
void nop(int lam, int ram); /* No operation */
void hlt(int lam, int ram); /* Halt */
void inc(int lam, int ram); /* Increment */
void dec(int lam, int ram); /* Decrement */
void add(int lam, int ram); /* Add */
void sub(int lam, int ram); /* Sub */
void mul(int lam, int ram); /* Multiply */
void jmp(int lam, int ram); /* Jump */
void jeq(int lam, int ram); /* Jump if eq */
void jnq(int lam, int ram); /* Jump if not eq */
void jgt(int lam, int ram); /* Jump if carry set */
void jlt(int lam, int ram); /* Jump if carry NOT set */
void mov(int lam, int ram); /* Move */
void cmp(int lam, int ram); /* Compare, sets/clears "eq" and "c" flags */
void call(int lam, int ram); /* Function call */
void ret(int lam, int ram); /* Return from function call */
void push(int lam, int ram); /* Push to stack */
void pop(int lam, int ram); /* Pop from stack */
void pushu(int lam, int ram); /* Push user registers to stack */
void popu(int lam, int ram); /* Pop user registers from stack */
void irq(int lam, int ram); /* Interrupt call */
void mod(int lam, int ram); /* Modulo division call */
#define HLT 0 /* Halt instruction */
#define INSTRUCTION_COUNT 22
#ifdef MAIN_GLOBALS
t_instruction instructions[INSTRUCTION_COUNT] = {
{ "HLT", 0, 1, hlt },
{ "NOP", 1, 1, nop },
{ "INC", 2, 2, inc },
{ "DEC", 3, 2, dec },
{ "ADD", 4, 3, add },
{ "SUB", 5, 3, sub },
{ "MUL", 6, 3, mul },
{ "JMP", 7, 2, jmp },
{ "JEQ", 8, 2, jeq },
{ "JNQ", 9, 2, jnq },
{ "JGT", 10, 2, jgt },
{ "JLT", 11, 2, jlt },
{ "MOV", 12, 3, mov },
{ "CMP", 13, 3, cmp },
{ "PUSH", 14, 2, push },
{ "POP", 15, 2, pop },
{ "CALL", 16, 2, call },
{ "RET", 17, 1, ret },
{ "PUSHU", 18, 1, pushu },
{ "POPU", 19, 1, popu },
{ "IRQ", 20, 2, irq },
{ "MOD", 21, 3, mod }
};
int debugprint=0;
#else
extern t_instruction instructions[INSTRUCTION_COUNT];
extern int debugprint;
#endif
#define INS_IMMEDIATE 0 /* Actually "immediate" or "don't care" */
#define INS_DEREF 1 /* Dereference value */
#define INS_ADDRDEREF 2 /* Double dereference value */
#define TOKTYPE_UNKNOWN 0
#define TOKTYPE_DEREF 101
#define TOKTYPE_STRING 102
#define TOKTYPE_INTEGER 103
#define TOKTYPE_LABEL 104
#define TOKTYPE_LABEL_REF 105
#define TOKTYPE_COMMENT 106
#define TOKTYPE_INS 107
#define TOKTYPE_REGISTER 108
#define TOKTYPE_VARIABLE 109
#define TOKTYPE_VARIABLE_REF 110
#define TOKTYPE_SIZEOF_VARIABLE 111
#define TOKTYPE_CHAR 112
#define TOKTYPE_REBASE 113
typedef struct _lToken
{
int tokType;
char *tokValue;
int subTokType; /* Only single level of subtokens, so this value embedded */
} lToken;
#ifdef MAIN_GLOBALS
lToken tokenArray[1000];
int tokenpos=0;
#else
extern lToken tokenArray[1000];
extern int tokenpos;
#endif
/* LABELS (interim) */
struct namepos {
char *name;
int position;
int size; /* for variables */
};
typedef struct namepos LABEL;
typedef struct namepos VARIABLE;
/* All hardcoded at moment! */
#ifdef MAIN_GLOBALS
LABEL labels[1000];
LABEL labelreferences[1000];
int labelmax=0;
int labelrefmax=0;
VARIABLE variables[1000];
VARIABLE variablereferences[1000];
int variablemax=0;
int variablerefmax=0;
#else
extern LABEL labels[1000];
extern LABEL labelreferences[1000];
extern int labelmax;
extern int labelrefmax;
extern VARIABLE variables[1000];
extern VARIABLE variablereferences[1000];
extern int variablemax;
extern int variablerefmax;
#endif
/* Function prototypes */
uint64_t runtime(void);
void tokenize(char *fn);
void assemble(void);
void setlvrv(int lam, int ram, int opcode);
/* platform.c */
int posix_kbhit(void);
#define KEYPRESS_INTERRUPT 0 /* IRQ0 is the keypress interrupt */
#define OS_INTERRUPT 1 /* Operating system interrupt for system calls */
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif
#ifndef WIN32
#define _strdup strdup
#endif