eForth1  v2.6
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 | fCOLON16); \
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 | fCOLON16); \
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  CELLCPY(len);
221  return addr;
222 }
226 int _immed(const char *seg, int len, ...) {
227  _header(fIMMD | strlen(seg), seg);
228  SHOWOP("IMMD");
229  int addr = PC;
230  CELLCPY(len);
231  return addr;
232 }
236 int _label(int len, ...) {
237  SHOWOP("LABEL");
238  int addr = PC;
239  // label has no opcode here
240  CELLCPY(len);
241  return addr;
242 }
246 void _begin(int len, ...) {
247  SHOWOP("BEGIN");
248  RPUSH(PC);
249  CELLCPY(len);
250 }
251 void _while(int len, ...) {
252  SHOWOP("WHILE");
253  BSET(PC++, opQBRAN);
254  STORE(0);
255  int k = RPOP();
256  RPUSH(PC - CELLSZ);
257  RPUSH(k);
258  CELLCPY(len);
259 }
260 void _repeat(int len, ...) {
261  SHOWOP("REPEAT");
262  BSET(PC++, opBRAN);
263  STORE(RPOP());
264  SET(RPOP(), PC);
265  CELLCPY(len);
266 }
267 void _until(int len, ...) {
268  SHOWOP("UNTIL");
269  BSET(PC++, opQBRAN);
270  STORE(RPOP());
271  CELLCPY(len);
272 }
273 void _again(int len, ...) {
274  SHOWOP("AGAIN");
275  BSET(PC++, opBRAN);
276  STORE(RPOP());
277  CELLCPY(len);
278 }
279 void _for(int len, ...) {
280  SHOWOP("FOR");
281  BSET(PC++, opTOR);
282  RPUSH(PC);
283  CELLCPY(len);
284 }
285 void _aft(int len, ...) {
286  SHOWOP("AFT");
287  BSET(PC++, opBRAN);
288  STORE(0);
289  RPOP();
290  RPUSH(PC);
291  RPUSH(PC - CELLSZ);
292  CELLCPY(len);
293 }
296 //
297 void _nxt(int len, ...) {
298  SHOWOP("NEXT");
299  BSET(PC++, opDONEXT);
300  STORE(RPOP());
301  CELLCPY(len);
302 }
303 void _if(int len, ...) {
304  SHOWOP("IF");
305  BSET(PC++, opQBRAN);
306  RPUSH(PC);
307  STORE(0);
308  CELLCPY(len);
309 }
310 void _else(int len, ...) {
311  SHOWOP("ELSE");
312  BSET(PC++, opBRAN);
313  STORE(0);
314  SET(RPOP(), PC);
315  RPUSH(PC - CELLSZ);
316  CELLCPY(len);
317 }
318 void _then(int len, ...) {
319  SHOWOP("THEN");
320  SET(RPOP(), PC);
321  CELLCPY(len);
322 }
326 void _dotq(const char *seq) {
327  SHOWOP("DOTQ");
328  DEBUG("%s", seq);
329  OPSTR(DOTQP, seq);
330 }
332 #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:251
_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:226
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:236
RPOP
#define RPOP()
Definition: eforth_asm.h:100
_for
void _for(int len,...)
Definition: eforth_asm.h:279
_again
void _again(int len,...)
Definition: eforth_asm.h:273
_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:318
_repeat
void _repeat(int len,...)
Definition: eforth_asm.h:260
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:310
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:267
_begin
void _begin(int len,...)
Definition: eforth_asm.h:246
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:285
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:303
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:326
_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:297
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