eForth1  v2.4
eforth_asm.h
Go to the documentation of this file.
1 
7 #ifndef __EFORTH_ASM_H
8 #define __EFORTH_ASM_H
9 #include "eforth_config.h"
10 
11 #define ASM_TRACE 0
12 #define CASE_SENSITIVE 0
13 #define ENABLE_SEE 1
14 #define fCMPL 0x40
23 #define fIMMD 0x80
24 #define OP(name) op##name
29 enum {
30  opNOP = 0,
32 };
33 //
34 // tracing/logging macros
35 //
36 #if ASM_TRACE
37 #define DEBUG(s,v) printf(s, v)
38 #define SHOWOP(op) printf("\n%04x: _%s\t", PC, op)
39 #else
40 #define DEBUG(s,v)
41 #define SHOWOP(op)
42 #endif // ASM_TRACE
43 #define _ARG_N( \
47  _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
48  _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
49  _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
50  _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
51  _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
52  _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
53  _61, _62, _63, N, ...) N
54 #define _NUM_N() \
55  62, 61, 60, \
56  59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
57  49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
58  39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
59  29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
60  19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
61  9, 8, 7, 6, 5, 4, 3, 2, 1, 0
62 #define _NARG0(...) _ARG_N(__VA_ARGS__)
63 #define _NARG(...) _NARG0(_, ##__VA_ARGS__, _NUM_N())
64 
68 #define _CODE(seg, ...) _code(seg, _NARG(__VA_ARGS__), __VA_ARGS__)
69 #define _PRIM(seg, x) (_CODE(seg, op##x, opEXIT), op##x)
70 #define _COLON(seg, ...) _colon(seg, _NARG(__VA_ARGS__), __VA_ARGS__)
71 #define _IMMED(seg, ...) _immed(seg, _NARG(__VA_ARGS__), __VA_ARGS__)
72 #define _LABEL(...) _label(_NARG(__VA_ARGS__), __VA_ARGS__)
73 #define _BEGIN(...) _begin(_NARG(__VA_ARGS__), __VA_ARGS__)
77 #define _AGAIN(...) _again(_NARG(__VA_ARGS__), __VA_ARGS__)
78 #define _UNTIL(...) _until(_NARG(__VA_ARGS__), __VA_ARGS__)
79 #define _WHILE(...) _while(_NARG(__VA_ARGS__), __VA_ARGS__)
80 #define _REPEAT(...) _repeat(_NARG(__VA_ARGS__), __VA_ARGS__)
81 #define _IF(...) _if(_NARG(__VA_ARGS__), __VA_ARGS__)
82 #define _ELSE(...) _else(_NARG(__VA_ARGS__), __VA_ARGS__)
83 #define _THEN(...) _then(_NARG(__VA_ARGS__), __VA_ARGS__)
84 #define _FOR(...) _for(_NARG(__VA_ARGS__), __VA_ARGS__)
85 #define _NEXT(...) _nxt(_NARG(__VA_ARGS__), __VA_ARGS__)
86 #define _AFT(...) _aft(_NARG(__VA_ARGS__), __VA_ARGS__)
87 #define _DOTQ(str) _dotq(str)
91 #define BSET(d, c) (_byte[d]=(U8)(c))
95 #define BGET(d) (_byte[d])
96 #define SET(d, v) do { U16 a=(d); U16 x=(v); BSET(a,(x)>>8); BSET((a)+1,(x)&0xff); } while (0)
97 #define GET(d) ({ U16 a=(d); ((U16)BGET(a)<<8) | BGET((a)+1); })
98 #define STORE(v) do { SET(PC,(v)); PC+=CELLSZ; } while(0)
99 #define RPUSH(a) SET(FORTH_ROM_SZ - (++R)*CELLSZ, (a))
100 #define RPOP() ((U16)GET(FORTH_ROM_SZ - (R ? R-- : R)*CELLSZ))
101 #define VL(a, i) (((U16)(a)+CELLSZ*(i))&0xff)
102 #define VH(a, i) (((U16)(a)+CELLSZ*(i))>>8)
103 #define VAL(a, i) opDOLIT,VH(a,i),VL(a,i),opEXIT
104 #define CELLCPY(n) { \
108  va_list argList; \
109  va_start(argList, n); \
110  int lit=0; \
111  for (; n; n--) { \
112  IU j = (IU)va_arg(argList, int); \
113  if (lit) { \
114  STORE(j); \
115  lit = 0; \
116  DEBUG(" %04x", j); \
117  continue; \
118  } \
119  if (j < 0x80) { \
120  lit = (j==opDOLIT); \
121  if (j != opNOP) { \
122  BSET(PC++, j); \
123  DEBUG(" %02x", j); \
124  } \
125  } \
126  else { \
127  STORE(j | fCOLON); \
128  DEBUG(" %04x", j); \
129  } \
130  } \
131  va_end(argList); \
132  _rdump(); \
133 }
134 
135 #define MEMCPY(len, seq) { \
136  memcpy(&_byte[PC], seq, len); \
137  PC += len; \
138 }
139 
140 #define OPSTR(ip, seq) { \
141  SET(PC, ip | fCOLON); \
142  PC += CELLSZ; \
143  int len = strlen(seq); \
144  BSET(PC++, len); \
145  MEMCPY(len, seq); \
146 }
147 extern IU PC;
151 extern U8 R;
152 extern IU _link;
153 extern U8 *_byte;
154 extern IU DOTQP;
155 void _dump(int b, int u) {
165  DEBUG("%s", "\n :");
166  for (int i=b; i<u; i+=sizeof(IU)) {
167  if ((i+1)<u) DEBUG(" %04x", GET(i));
168  else DEBUG(" %02x", BGET(i));
169  }
170 }
171 void _rdump()
172 {
173  DEBUG("%cR[", ' ');
174  for (int i=1; i<=R; i++) {
175  DEBUG(" %04x", GET(FORTH_ROM_SZ - i*CELLSZ));
176  }
177  DEBUG("%c]", ' ');
178 }
182 void _header(int lex, const char *seq) {
183  if (_link) {
184  if (PC >= FORTH_ROM_SZ) DEBUG("ROM %s", "max!");
185  _dump(_link - sizeof(IU), PC);
186  }
187  STORE(_link);
188  _link = PC;
189 
190  BSET(PC++, lex);
191  int len = lex & 0x1f;
192 
193  MEMCPY(len, seq);
194  DEBUG("\n%04x: ", PC);
195  DEBUG("%s", seq);
196 }
200 int _code(const char *seg, int len, ...) {
201  _header(strlen(seg), seg);
202  int addr = PC;
203  va_list argList;
204  va_start(argList, len);
205  for (; len; len--) {
206  U8 b = (U8)va_arg(argList, int);
207  BSET(PC++, b);
208  DEBUG(" %02x", b);
209  }
210  va_end(argList);
211  return addr;
212 }
216 int _colon(const char *seg, int len, ...) {
217  _header(strlen(seg), seg);
218  DEBUG(" %s", ":_COLON");
219  int addr = PC;
220  //BSET(PC++, opENTER); // no need for direct threading
221  CELLCPY(len);
222  return addr;
223 }
227 int _immed(const char *seg, int len, ...) {
228  _header(fIMMD | strlen(seg), seg);
229  SHOWOP("IMMD");
230  int addr = PC;
231  //BSET(PC++, opENTER); // no need for direct threading
232  CELLCPY(len);
233  return addr;
234 }
238 int _label(int len, ...) {
239  SHOWOP("LABEL");
240  int addr = PC;
241  // label has no opcode here
242  CELLCPY(len);
243  return addr;
244 }
248 void _begin(int len, ...) {
249  SHOWOP("BEGIN");
250  RPUSH(PC);
251  CELLCPY(len);
252 }
253 void _while(int len, ...) {
254  SHOWOP("WHILE");
255  BSET(PC++, opQBRAN);
256  STORE(0);
257  int k = RPOP();
258  RPUSH(PC - CELLSZ);
259  RPUSH(k);
260  CELLCPY(len);
261 }
262 void _repeat(int len, ...) {
263  SHOWOP("REPEAT");
264  BSET(PC++, opBRAN);
265  STORE(RPOP());
266  SET(RPOP(), PC);
267  CELLCPY(len);
268 }
269 void _until(int len, ...) {
270  SHOWOP("UNTIL");
271  BSET(PC++, opQBRAN);
272  STORE(RPOP());
273  CELLCPY(len);
274 }
275 void _again(int len, ...) {
276  SHOWOP("AGAIN");
277  BSET(PC++, opBRAN);
278  STORE(RPOP());
279  CELLCPY(len);
280 }
281 void _for(int len, ...) {
282  SHOWOP("FOR");
283  BSET(PC++, opTOR);
284  RPUSH(PC);
285  CELLCPY(len);
286 }
287 void _aft(int len, ...) {
288  SHOWOP("AFT");
289  BSET(PC++, opBRAN);
290  STORE(0);
291  RPOP();
292  RPUSH(PC);
293  RPUSH(PC - CELLSZ);
294  CELLCPY(len);
295 }
298 //
299 void _nxt(int len, ...) {
300  SHOWOP("NEXT");
301  BSET(PC++, opDONEXT);
302  STORE(RPOP());
303  CELLCPY(len);
304 }
305 void _if(int len, ...) {
306  SHOWOP("IF");
307  BSET(PC++, opQBRAN);
308  RPUSH(PC);
309  STORE(0);
310  CELLCPY(len);
311 }
312 void _else(int len, ...) {
313  SHOWOP("ELSE");
314  BSET(PC++, opBRAN);
315  STORE(0);
316  SET(RPOP(), PC);
317  RPUSH(PC - CELLSZ);
318  CELLCPY(len);
319 }
320 void _then(int len, ...) {
321  SHOWOP("THEN");
322  SET(RPOP(), PC);
323  CELLCPY(len);
324 }
328 void _dotq(const char *seq) {
329  SHOWOP("DOTQ");
330  DEBUG("%s", seq);
331  OPSTR(DOTQP, seq);
332 }
334 #endif // __EFORTH_ASM_H
RPUSH
#define RPUSH(a)
Definition: eforth_asm.h:99
DEBUG
#define DEBUG(s, v)
Definition: eforth_asm.h:40
OPCODES
@ OPCODES
Definition: eforth_asm.h:31
FORTH_ROM_SZ
#define FORTH_ROM_SZ
Definition: eforth_config.h:38
fIMMD
#define fIMMD
Definition: eforth_asm.h:23
_while
void _while(int len,...)
Definition: eforth_asm.h:253
_colon
int _colon(const char *seg, int len,...)
Definition: eforth_asm.h:216
GET
#define GET(d)
Definition: eforth_asm.h:97
_immed
int _immed(const char *seg, int len,...)
Definition: eforth_asm.h:227
BSET
#define BSET(d, c)
Definition: eforth_asm.h:94
_header
void _header(int lex, const char *seq)
Definition: eforth_asm.h:182
opNOP
@ opNOP
opcodes start at 0
Definition: eforth_asm.h:30
_label
int _label(int len,...)
Definition: eforth_asm.h:238
RPOP
#define RPOP()
Definition: eforth_asm.h:100
_for
void _for(int len,...)
Definition: eforth_asm.h:281
_again
void _again(int len,...)
Definition: eforth_asm.h:275
_link
IU _link
link to previous word
Definition: eforth_asm.c:17
eforth_config.h
eForth configurations and opcode list
_then
void _then(int len,...)
Definition: eforth_asm.h:320
_repeat
void _repeat(int len,...)
Definition: eforth_asm.h:262
SET
#define SET(d, v)
Definition: eforth_asm.h:96
OPSTR
#define OPSTR(ip, seq)
Definition: eforth_asm.h:140
_dump
void _dump(int b, int u)
Definition: eforth_asm.h:164
_else
void _else(int len,...)
Definition: eforth_asm.h:312
DOTQP
IU DOTQP
addr of output ops, used by _dotq, _strq, _abortq
Definition: eforth_asm.c:21
_until
void _until(int len,...)
Definition: eforth_asm.h:269
_begin
void _begin(int len,...)
Definition: eforth_asm.h:248
R
U8 R
assembler return stack index
Definition: eforth_asm.c:15
CELLSZ
#define CELLSZ
Definition: eforth_config.h:36
_aft
void _aft(int len,...)
Definition: eforth_asm.h:287
STORE
#define STORE(v)
Definition: eforth_asm.h:98
_rdump
void _rdump()
dump return stack
Definition: eforth_asm.h:171
_if
void _if(int len,...)
Definition: eforth_asm.h:305
IU
U16 IU
instruction/address unit (16-bit)
Definition: eforth_config.h:28
CELLCPY
#define CELLCPY(n)
Definition: eforth_asm.h:107
MEMCPY
#define MEMCPY(len, seq)
Definition: eforth_asm.h:135
BGET
#define BGET(d)
Definition: eforth_asm.h:95
_dotq
void _dotq(const char *seq)
Definition: eforth_asm.h:328
_code
int _code(const char *seg, int len,...)
Definition: eforth_asm.h:200
_nxt
void _nxt(int len,...)
Note: _next() is multi-defined in vm
Definition: eforth_asm.h:299
U8
uint8_t U8
8-bit unsigned integer
Definition: eforth_config.h:22
PC
IU PC
assembler program counter
Definition: eforth_asm.c:14
SHOWOP
#define SHOWOP(op)
Definition: eforth_asm.h:41
_byte
U8 * _byte
assembler byte array (heap)
Definition: eforth_asm.c:16