1 /* 2012 - pancake@nopcode.org - radare2 integration */
2 /* Z80 assembler by shevek
3 
4    Copyright (C) 2002-2009 Bas Wijnen <wijnen@debian.org>
5    Copyright (C) 2005 Jan Wilmans <jw@dds.nl>
6 
7    This file is part of z80asm.
8 
9    Z80asm is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    Z80asm is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef R_API_I
24 #define R_API_I
25 #endif
26 #include "z80asm.h"
27 #include <r_util.h>
28 
29 /* hack */
30 // must remove: equ, include, incbin, macro
31 // static void wrt_ref (int val, int type, int count);
32 static unsigned char *obuf;
33 static int obuflen = 0;
34 #define write_one_byte(x, y) obuf[obuflen++] = x
35 #define wrtb(x) obuf[obuflen++] = x
36 
37 /* global variables */
38 /* mnemonics, used as argument to indx() in assemble */
39 static const char *mnemonics[] = {
40 	"call", "cpdr", "cpir", "djnz", "halt", "indr", "inir", "lddr", "ldir",
41 	"otdr", "otir", "outd", "outi", "push", "reti", "retn", "rlca", "rrca",
42 	"defb", "defw", "defs", "defm",
43 	"adc", "add", "and", "bit", "ccf", "cpd", "cpi", "cpl", "daa", "dec", "equ",
44 	"exx", "inc", "ind", "ini", "ldd", "ldi", "neg", "nop", "out", "pop",
45 	"res", "ret", "rla", "rlc", "rld", "rra", "rrc", "rrd", "rst", "sbc",
46 	"scf", "set", "sla", "sll", "sli", "sra", "srl", "sub", "xor", "org",
47 	"cp", "di", "ei", "ex", "im", "in", "jp", "jr", "ld", "or", "rl", "rr",
48 	"db", "dw", "ds", "dm",
49 	"include", "incbin", "if", "else", "endif", "end", "macro", "endm",
50 	"seek", NULL
51 };
52 
53 /* current line, address and file */
54 static int addr = 0, file;
55 /* current number of characters in list file, for indentation */
56 // static int listdepth;
57 
58 /* use readbyte instead of (hl) if writebyte is true */
59 static int writebyte;
60 static const char *readbyte;
61 /* variables which are filled by rd_* functions and used later,
62  * like readbyte */
63 static const char *readword, *indexjmp, *bitsetres;
64 
65 /* 0, 0xdd or 0xfd depening on which index prefix should be given */
66 static int indexed;
67 
68 /* increased for every -v option on the command line */
69 static int verbose = 0;
70 
71 /* read commas after indx() if comma > 1. increase for every call */
72 static int comma;
73 
74 /* address at start of line (for references) */
75 static int baseaddr;
76 
77 /* set by readword and readbyte, used for new_reference */
78 static char mem_delimiter;
79 
80 /* line currently being parsed */
81 static char *z80buffer = NULL;
82 
83 /* if a macro is currently being defined */
84 static int define_macro = 0;
85 
86 /* file (and macro) stack */
87 static int sp;
88 static struct stack stack[MAX_INCLUDE];	/* maximum level of includes */
89 
90 /* hack */
91 #include "expressions.c"
92 
93 /* print an error message, including current line and file */
printerr(int error,const char * fmt,...)94 static void printerr(int error, const char *fmt, ...) {
95 #if 0
96 	va_list l;
97 	va_start (l, fmt);
98 	if ((sp < 0) || (stack[sp].name == 0)) {
99 		fprintf (stderr, "internal assembler error, sp == %i\n", sp);
100 		vfprintf (stderr, fmt, l);
101 	}
102 	fprintf (stderr, "%s%s:%d: %s: ", stack[sp].dir? stack[sp].dir->name: "",
103 		stack[sp].name, stack[sp].line, error? "error": "warning");
104 	vfprintf (stderr, fmt, l);
105 	va_end (l);
106 	if (error) {
107 		errors++;
108 	}
109 #endif
110 }
111 
112 /* skip over spaces in string */
delspc(const char * ptr)113 static const char *delspc(const char *ptr) {
114 	while (*ptr && isspace ((const unsigned char) *ptr))
115 		ptr++;
116 	if (*ptr == ';') {
117 		ptr = "";
118 	}
119 	return ptr;
120 }
121 
122 /* read away a comma, error if there is none */
rd_comma(const char ** p)123 static void rd_comma(const char **p) {
124 	*p = delspc (*p);
125 	if (**p != ',') {
126 		eprintf ("`,' expected. Remainder of line: %s\n", *p);
127 		return;
128 	}
129 	*p = delspc ((*p) + 1);
130 }
131 
132 /* look ahead for a comma, no error if not found */
has_argument(const char ** p)133 static int has_argument(const char **p) {
134 	const char *q = delspc (*p);
135 	return *q == ',';
136 }
137 
138 /* During assembly, many literals are not parsed.  Instead, they are saved
139  * until all labels are read.  After that, they are parsed.  This function
140  * is used during assembly, to find the place where the command continues. */
skipword(const char ** pos,char delimiter)141 static void skipword(const char **pos, char delimiter) {
142 	/* rd_expr will happily read the expression, and possibly return
143 	 * an invalid result.  It will update pos, which is what we need.  */
144 	/* Pass valid to allow using undefined labels without errors.  */
145 	int valid;
146 	rd_expr (pos, delimiter, &valid, sp, 0);
147 }
148 
149 /* find any of the list[] entries as the start of ptr and return index */
indx(const char ** ptr,const char ** list,int error,const char ** expr)150 static int indx(const char **ptr, const char **list, int error, const char **expr) {
151 	int i;
152 	*ptr = delspc (*ptr);
153 	if (!**ptr) {
154 		if (error) {
155 			eprintf ("unexpected end of line\n");
156 			return 0;
157 		} else {
158 			return 0;
159 		}
160 	}
161 	if (comma > 1) {
162 		rd_comma (ptr);
163 	}
164 	for (i = 0; list[i]; i++) {
165 		const char *input = *ptr;
166 		const char *check = list[i];
167 		int had_expr = 0;
168 		if (!list[i][0]) {
169 			continue;
170 		}
171 		while (*check) {
172 			if (*check == ' ') {
173 				input = delspc (input);
174 			} else if (*check == '*') {
175 				*expr = input;
176 				mem_delimiter = check[1];
177 				rd_expr (&input, mem_delimiter, NULL, sp, 0);
178 				had_expr = 1;
179 			} else if (*check == '+') {
180 				if (*input == '+' || *input == '-') {
181 					*expr = input;
182 					mem_delimiter = check[1];
183 					rd_expr (&input, mem_delimiter, NULL, sp, 0);
184 				}
185 			} else if (*check == *input || (*check >= 'a' && *check <= 'z'
186 							&& *check - 'a' + 'A' == *input)) {
187 				++input;
188 			} else {
189 				break;
190 			}
191 
192 			++check;
193 		}
194 		if (*check || (isalnum ((const unsigned char) check[-1]) && isalnum ((const unsigned char) input[0]))) {
195 			continue;
196 		}
197 		if (had_expr) {
198 			input = delspc (input);
199 			if (*input && *input != ',') {
200 				continue;
201 			}
202 		}
203 		*ptr = input;
204 		comma++;
205 		return i + 1;
206 	}
207 	// if (error) eprintf ("parse error. Remainder of line=%s\n", *ptr);
208 	return 0;
209 }
210 
211 /* read a mnemonic */
readcommand(const char ** p)212 static int readcommand(const char **p) {
213 	return indx (p, mnemonics, 0, NULL);
214 }
215 
216 /* try to read a label and optionally store it in the list */
readlabel(const char ** p,int store)217 static void readlabel(const char **p, int store) {
218 	const char *c, *d, *pos, *dummy;
219 	int i, j;
220 	struct label *previous;
221 	for (d = *p; *d && *d != ';'; d++) {
222 		;
223 	}
224 	for (c = *p; !strchr (" \r\n\t", *c) && c < d; c++) {
225 		;
226 	}
227 	pos = strchr (*p, ':');
228 	if (!pos || pos >= c) {
229 		return;
230 	}
231 	if (pos == *p) {
232 		eprintf ("`:' found without a label");
233 		return;
234 	}
235 	if (!store) {
236 		*p = pos + 1;
237 		return;
238 	}
239 	c = pos + 1;
240 	dummy = *p;
241 	j = rd_label (&dummy, &i, &previous, sp, 0);
242 	if (i || j) {
243 		eprintf ("duplicate definition of label %s\n", *p);
244 		*p = c;
245 		return;
246 	}
247 
248 	*p = c;
249 }
250 
compute_ref(struct reference * ref,int allow_invalid)251 static int compute_ref(struct reference *ref, int allow_invalid) {
252 	const char *ptr;
253 	int valid = 0;
254 	int backup_addr = addr;
255 	int backup_baseaddr = baseaddr;
256 	int backup_comma = comma;
257 	int backup_file = file;
258 	int backup_sp = sp;
259 	sp = ref->level;
260 	addr = ref->addr;
261 	baseaddr = ref->baseaddr;
262 	comma = ref->comma;
263 	file = ref->infile;
264 	ptr = ref->input;
265 	if (!ref->done) {
266 		ref->computed_value = rd_expr (&ptr, ref->delimiter,
267 			allow_invalid? &valid: NULL,
268 			ref->level, 1);
269 		if (valid) {
270 			ref->done = 1;
271 		}
272 	}
273 	sp = backup_sp;
274 	addr = backup_addr;
275 	baseaddr = backup_baseaddr;
276 	comma = backup_comma;
277 	file = backup_file;
278 	return ref->computed_value;
279 }
280 
281 /* read a word from input and store it in readword. return 1 on success */
rd_word(const char ** p,char delimiter)282 static int rd_word(const char **p, char delimiter) {
283 	*p = delspc (*p);
284 	if (**p == 0) {
285 		return 0;
286 	}
287 	readword = *p;
288 	mem_delimiter = delimiter;
289 	skipword (p, delimiter);
290 	return 1;
291 }
292 
293 /* read a byte from input and store it in readbyte. return 1 on success */
rd_byte(const char ** p,char delimiter)294 static int rd_byte(const char **p, char delimiter) {
295 	*p = delspc (*p);
296 	if (**p == 0) {
297 		return 0;
298 	}
299 	readbyte = *p;
300 	writebyte = 1;
301 	mem_delimiter = delimiter;
302 	skipword (p, delimiter);
303 	return 1;
304 }
305 
306 /* read (SP), DE, or AF */
rd_ex1(const char ** p)307 static int rd_ex1(const char **p) {
308 #define DE 2
309 #define AF 3
310 	const char *list[] = {
311 		"( sp )", "de", "af", NULL
312 	};
313 	return indx (p, list, 1, NULL);
314 }
315 
316 /* read first argument of IN */
rd_in(const char ** p)317 static int rd_in(const char **p) {
318 #define A 8
319 	const char *list[] = {
320 		"b", "c", "d", "e", "h", "l", "f", "a", NULL
321 	};
322 	return indx (p, list, 1, NULL);
323 }
324 
325 /* read second argument of out (c),x */
rd_out(const char ** p)326 static int rd_out(const char **p) {
327 	const char *list[] = {
328 		"b", "c", "d", "e", "h", "l", "0", "a", NULL
329 	};
330 	return indx (p, list, 1, NULL);
331 }
332 
333 /* read (c) or (nn) */
rd_nnc(const char ** p)334 static int rd_nnc(const char **p) {
335 #define C 1
336 	int i;
337 	const char *list[] = {
338 		"( c )", "(*)", "a , (*)", NULL
339 	};
340 	i = indx (p, list, 1, &readbyte);
341 	if (i < 2) {
342 		return i;
343 	}
344 	return 2;
345 }
346 
347 /* read (C) */
rd_c(const char ** p)348 static int rd_c(const char **p) {
349 	const char *list[] = {
350 		"( c )", "( bc )", NULL
351 	};
352 	return indx (p, list, 1, NULL);
353 }
354 
355 /* read a or hl */
rd_a_hl(const char ** p)356 static int rd_a_hl(const char **p) {
357 #define HL 2
358 	const char *list[] = {
359 		"a", "hl", NULL
360 	};
361 	return indx (p, list, 1, NULL);
362 }
363 
364 /* read first argument of ld */
rd_ld(const char ** p)365 static int rd_ld(const char **p) {
366 #define ldBC    1
367 #define ldDE    2
368 #define ldHL    3
369 #define ldSP    4
370 #define ldIX    5
371 #define ldIY    6
372 #define ldB     7
373 #define ldC     8
374 #define ldD     9
375 #define ldE     10
376 #define ldH     11
377 #define ldL     12
378 #define ld_HL   13
379 #define ldA     14
380 #define ldI     15
381 #define ldR     16
382 #define ld_BC   17
383 #define ld_DE   18
384 #define ld_IX   19
385 #define ld_IY   20
386 #define ld_NN   21
387 	int i;
388 	const char *list[] = {
389 		"ixh", "ixl", "iyh", "iyl", "bc", "de", "hl", "sp", "ix",
390 		"iy", "b", "c", "d", "e", "h", "l", "( hl )", "a", "i",
391 		"r", "( bc )", "( de )", "( ix +)", "(iy +)", "(*)", NULL
392 	};
393 	const char *nn;
394 	i = indx (p, list, 1, &nn);
395 	if (!i) {
396 		return 0;
397 	}
398 	if (i <= 2) {
399 		indexed = 0xdd;
400 		return ldH + (i == 2);
401 	}
402 	if (i <= 4) {
403 		indexed = 0xfd;
404 		return ldH + (i == 4);
405 	}
406 	i -= 4;
407 	if (i == ldIX || i == ldIY) {
408 		indexed = i == ldIX? 0xDD: 0xFD;
409 		return ldHL;
410 	}
411 	if (i == ld_IX || i == ld_IY) {
412 		indexjmp = nn;
413 		indexed = i == ld_IX? 0xDD: 0xFD;
414 		return ld_HL;
415 	}
416 	if (i == ld_NN) {
417 		readword = nn;
418 	}
419 	return i;
420 }
421 
422 /* read first argument of JP */
rd_jp(const char ** p)423 static int rd_jp(const char **p) {
424 	int i;
425 	const char *list[] = {
426 		"nz", "z", "nc", "c", "po", "pe", "p", "m", "( ix )", "( iy )",
427 		"(hl)", NULL
428 	};
429 	i = indx (p, list, 0, NULL);
430 	if (i < 9) {
431 		return i;
432 	}
433 	if (i == 11) {
434 		return -1;
435 	}
436 	indexed = 0xDD + 0x20 * (i - 9);
437 	return -1;
438 }
439 
440 /* read first argument of JR */
rd_jr(const char ** p)441 static int rd_jr(const char **p) {
442 	const char *list[] = {
443 		"nz", "z", "nc", "c", NULL
444 	};
445 	return indx (p, list, 0, NULL);
446 }
447 
448 /* read A */
rd_a(const char ** p)449 static int rd_a(const char **p) {
450 	const char *list[] = {
451 		"a", NULL
452 	};
453 	return indx (p, list, 1, NULL);
454 }
455 
456 /* read bc,de,hl,af */
rd_stack(const char ** p)457 static int rd_stack(const char **p) {
458 	int i;
459 	const char *list[] = {
460 		"bc", "de", "hl", "af", "ix", "iy", NULL
461 	};
462 	i = indx (p, list, 1, NULL);
463 	if (i < 5) {
464 		return i;
465 	}
466 	indexed = 0xDD + 0x20 * (i - 5);
467 	return 3;
468 }
469 
470 /* read b,c,d,e,h,l,(hl),a,(ix+nn),(iy+nn),nn
471  * but now with extra hl or i[xy](15) for add-instruction
472  * and set variables accordingly */
rd_r_add(const char ** p)473 static int rd_r_add(const char **p) {
474 #define addHL   15
475 	int i;
476 	const char *list[] = {
477 		"ixl", "ixh", "iyl", "iyh", "b", "c", "d", "e", "h", "l",
478 		"( hl )", "a", "( ix +)", "( iy +)", "hl", "ix", "iy", "*", NULL
479 	};
480 	const char *nn;
481 	i = indx (p, list, 0, &nn);
482 	if (i == 18) {	/* expression */
483 		readbyte = nn;
484 		writebyte = 1;
485 		return 7;
486 	}
487 	if (i > 14) {	/* hl, ix, iy */
488 		if (i > 15) {
489 			indexed = 0xDD + 0x20 * (i - 16);
490 		}
491 		return addHL;
492 	}
493 	if (i <= 4) {	/* i[xy][hl]  */
494 		indexed = 0xdd + 0x20 * (i > 2);
495 		return 6 - (i & 1);
496 	}
497 	i -= 4;
498 	if (i < 9) {
499 		return i;
500 	}
501 	indexed = 0xDD + 0x20 * (i - 9);	/* (i[xy] +) */
502 	indexjmp = nn;
503 	return 7;
504 }
505 
506 /* read bc,de,hl, or sp */
rd_rr_(const char ** p)507 static int rd_rr_(const char **p) {
508 	const char *list[] = {
509 		"bc", "de", "hl", "sp", NULL
510 	};
511 	return indx (p, list, 1, NULL);
512 }
513 
514 /* read bc,de,hl|ix|iy,sp. hl|ix|iy only if it is already indexed the same. */
rd_rrxx(const char ** p)515 static int rd_rrxx(const char **p) {
516 	const char *listx[] = {
517 		"bc", "de", "ix", "sp", NULL
518 	};
519 	const char *listy[] = {
520 		"bc", "de", "iy", "sp", NULL
521 	};
522 	const char *list[] = {
523 		"bc", "de", "hl", "sp", NULL
524 	};
525 	if (indexed == 0xdd) {
526 		return indx (p, listx, 1, NULL);
527 	}
528 	if (indexed == 0xfd) {
529 		return indx (p, listy, 1, NULL);
530 	}
531 	return indx (p, list, 1, NULL);
532 }
533 
534 /* read b,c,d,e,h,l,(hl),a,(ix+nn),(iy+nn),nn
535  * and set variables accordingly */
rd_r(const char ** p)536 static int rd_r(const char **p) {
537 	int i;
538 	const char *nn;
539 	const char *list[] = {
540 		"ixl", "ixh", "iyl", "iyh", "b", "c", "d", "e", "h", "l", "( hl )",
541 		"a", "( ix +)", "( iy +)", "*", NULL
542 	};
543 	i = indx (p, list, 0, &nn);
544 	if (i == 15) {	/* expression */
545 		readbyte = nn;
546 		writebyte = 1;
547 		return 7;
548 	}
549 	if (i <= 4) {
550 		indexed = 0xdd + 0x20 * (i > 2);
551 		return 6 - (i & 1);
552 	}
553 	i -= 4;
554 	if (i < 9) {
555 		return i;
556 	}
557 	indexed = 0xDD + 0x20 * (i - 9);
558 	indexjmp = nn;
559 	return 7;
560 }
561 
562 /* like rd_r(), but without nn */
rd_r_(const char ** p)563 static int rd_r_(const char **p) {
564 	int i;
565 	const char *list[] = {
566 		"b", "c", "d", "e", "h", "l", "( hl )", "a", "( ix +)", "( iy +)", NULL
567 	};
568 	i = indx (p, list, 1, &indexjmp);
569 	if (i < 9) {
570 		return i;
571 	}
572 	indexed = 0xDD + 0x20 * (i - 9);
573 	return 7;
574 }
575 
576 /* read a number from 0 to 7, for bit, set or res */
rd_0_7(const char ** p)577 static int rd_0_7(const char **p) {
578 	*p = delspc (*p);
579 	if (**p == 0) {
580 		return 0;
581 	}
582 	bitsetres = *p;
583 	skipword (p, ',');
584 	return 1;
585 }
586 
587 /* read long condition. do not error if not found. */
rd_cc(const char ** p)588 static int rd_cc(const char **p) {
589 	const char *list[] = {
590 		"nz", "z", "nc", "c", "po", "pe", "p", "m", NULL
591 	};
592 	return indx (p, list, 0, NULL);
593 }
594 
595 /* read long or short register,  */
rd_r_rr(const char ** p)596 static int rd_r_rr(const char **p) {
597 	int i;
598 	const char *list[] = {
599 		"iy", "ix", "sp", "hl", "de", "bc", "", "b", "c", "d", "e", "h",
600 		"l", "( hl )", "a", "( ix +)", "( iy +)", NULL
601 	};
602 	i = indx (p, list, 1, &indexjmp);
603 	if (!i) {
604 		return 0;
605 	}
606 	if (i < 16 && i > 2) {
607 		return 7 - i;
608 	}
609 	if (i > 15) {
610 		indexed = 0xDD + (i - 16) * 0x20;
611 		return -7;
612 	}
613 	indexed = 0xDD + (2 - i) * 0x20;
614 	return 3;
615 }
616 
617 /* read hl */
rd_hl(const char ** p)618 static int rd_hl(const char **p) {
619 	const char *list[] = {
620 		"hl", NULL
621 	};
622 	return indx (p, list, 1, NULL);
623 }
624 
625 /* read hl, ix, or iy */
rd_hlx(const char ** p)626 static int rd_hlx(const char **p) {
627 	int i;
628 	const char *list[] = {
629 		"hl", "ix", "iy", NULL
630 	};
631 	i = indx (p, list, 1, NULL);
632 	if (i < 2) {
633 		return i;
634 	}
635 	indexed = 0xDD + 0x20 * (i - 2);
636 	return 1;
637 }
638 
639 /* read af' */
rd_af_(const char ** p)640 static int rd_af_(const char **p) {
641 	const char *list[] = {
642 		"af'", NULL
643 	};
644 	return indx (p, list, 1, NULL);
645 }
646 
647 /* read 0(1), 1(3), or 2(4) */
rd_0_2(const char ** p)648 static int rd_0_2(const char **p) {
649 	const char *list[] = {
650 		"0", "", "1", "2", NULL
651 	};
652 	return indx (p, list, 1, NULL);
653 }
654 
655 /* read argument of ld (hl), */
rd_ld_hl(const char ** p)656 static int rd_ld_hl(const char **p) {
657 	int i;
658 	const char *list[] = {
659 		"b", "c", "d", "e", "h", "l", "", "a", "*", NULL
660 	};
661 	i = indx (p, list, 0, &readbyte);
662 	if (i < 9) {
663 		return i;
664 	}
665 	writebyte = 1;
666 	return 7;
667 }
668 
669 /* read argument of ld (nnnn), */
rd_ld_nn(const char ** p)670 static int rd_ld_nn(const char **p) {
671 #define ld_nnHL 5
672 #define ld_nnA 6
673 	int i;
674 	const char *list[] = {
675 		"bc", "de", "", "sp", "hl", "a", "ix", "iy", NULL
676 	};
677 	i = indx (p, list, 1, NULL);
678 	if (i < 7) {
679 		return i;
680 	}
681 	indexed = 0xdd + 0x20 * (i == 8);
682 	return ld_nnHL;
683 }
684 
685 /* read argument of ld a, */
rd_lda(const char ** p)686 static int rd_lda(const char **p) {
687 #define A_N 7
688 #define A_I 9
689 #define A_R 10
690 #define A_NN 11
691 	int i;
692 	const char *list[] = {
693 		"( sp )", "( iy +)", "( de )", "( bc )", "( ix +)", "b", "c", "d", "e", "h",
694 		"l", "( hl )", "a", "i", "r", "(*)", "*", NULL
695 	};
696 	const char *nn;
697 	i = indx (p, list, 0, &nn);
698 	if (i == 2 || i == 5) {
699 		indexed = (i == 2)? 0xFD: 0xDD;
700 		indexjmp = nn;
701 		return 7;
702 	}
703 	if (i == 17) {
704 		readbyte = nn;
705 		writebyte = 1;
706 		return 7;
707 	}
708 	if (i == 16) {
709 		readword = nn;
710 	}
711 	return i - 5;
712 }
713 
714 /* read argument of ld b|c|d|e|h|l */
rd_ldbcdehla(const char ** p)715 static int rd_ldbcdehla(const char **p) {
716 	int i;
717 	const char *list[] = {
718 		"b", "c", "d", "e", "h", "l", "( hl )", "a", "( ix +)", "( iy +)", "ixh",
719 		"ixl", "iyh", "iyl", "*", NULL
720 	};
721 	const char *nn;
722 	i = indx (p, list, 0, &nn);
723 	if (i == 15) {
724 		readbyte = nn;
725 		writebyte = 1;
726 		return 7;
727 	}
728 	if (i > 10) {
729 		int x;
730 		x = 0xdd + 0x20 * (i > 12);
731 		if (indexed && indexed != x) {
732 			eprintf ("illegal use of index registers\n");
733 			return 0;
734 		}
735 		indexed = x;
736 		return 6 - (i & 1);
737 	}
738 	if (i > 8) {
739 		if (indexed) {
740 			eprintf ("illegal use of index registers\n");
741 			return 0;
742 		}
743 		indexed = 0xDD + 0x20 * (i == 10);
744 		indexjmp = nn;
745 		return 7;
746 	}
747 	return i;
748 }
749 
750 /* read nnnn, or (nnnn) */
rd_nn_nn(const char ** p)751 static int rd_nn_nn(const char **p) {
752 #define _NN 1
753 	const char *list[] = {
754 		"(*)", "*", NULL
755 	};
756 	return 2 - indx (p, list, 0, &readword);
757 }
758 
759 /* read {HL|IX|IY},nnnn, or (nnnn) */
rd_sp(const char ** p)760 static int rd_sp(const char **p) {
761 #define SPNN 0
762 #define SPHL 1
763 	int i;
764 	const char *list[] = {
765 		"hl", "ix", "iy", "(*)", "*", NULL
766 	};
767 	const char *nn;
768 	i = indx (p, list, 0, &nn);
769 	if (i > 3) {
770 		readword = nn;
771 		return i == 4? 2: 0;
772 	}
773 	if (i != 1) {
774 		indexed = 0xDD + 0x20 * (i - 2);
775 	}
776 	return 1;
777 }
778 
779 /* do the actual work */
assemble(const char * str,unsigned char * _obuf)780 static int assemble(const char *str, unsigned char *_obuf) {
781 	const char *ptr;
782 	char *bufptr;
783 	int r, s;			/* registers */
784 
785 	obuflen = 0;
786 	obuf = _obuf;
787 	int cmd, cont = 1;
788 	// XXX: must free
789 	z80buffer = strdup (str);
790 	if (!cont) {
791 		return obuflen;
792 	}
793 	// if (havelist)
794 	// fprintf (listfile, "%04x", addr);
795 	for (bufptr = z80buffer; (bufptr = strchr (bufptr, '\n'));) {
796 		*bufptr = ' ';
797 	}
798 	for (bufptr = z80buffer; (bufptr = strchr (bufptr, '\r'));) {
799 		*bufptr = ' ';
800 	}
801 	ptr = z80buffer;
802 	// lastlabel = NULL;
803 	baseaddr = addr;
804 	++stack[sp].line;
805 	ptr = delspc (ptr);
806 	if (!*ptr) {
807 		return obuflen;
808 	}
809 	if (!define_macro) {
810 		readlabel (&ptr, 1);
811 	} else {
812 		readlabel (&ptr, 0);
813 	}
814 	ptr = delspc (ptr);
815 	if (!*ptr) {
816 		return obuflen;
817 	}
818 	comma = 0;
819 	indexed = 0;
820 	indexjmp = 0;
821 	writebyte = 0;
822 	readbyte = 0;
823 	readword = 0;
824 	cmd = readcommand (&ptr) - 1;
825 	int i, have_quote;
826 	switch (cmd) {
827 		case Z80_ADC:
828 			if (!(r = rd_a_hl (&ptr))) {
829 				break;
830 			}
831 			if (r == HL) {
832 				if (!(r = rd_rr_(&ptr))) {
833 					break;
834 				}
835 				wrtb (0xED);
836 				r--;
837 				wrtb (0x4A + 0x10 * r);
838 				break;
839 			}
840 			if (!(r = rd_r (&ptr))) {
841 				break;
842 			}
843 			r--;
844 			wrtb (0x88 + r);
845 			break;
846 		case Z80_ADD:
847 			if (!(r = rd_r_add (&ptr))) {
848 				break;
849 			}
850 			if (r == addHL) {
851 				if (!(r = rd_rrxx (&ptr))) {
852 					break;
853 				}
854 				r--;
855 				wrtb (0x09 + 0x10 * r);		/* ADD HL/IX/IY, qq  */
856 				break;
857 			}
858 			if (has_argument (&ptr)) {
859 				if (r != A) {
860 					eprintf ("parse error before: %s\n", ptr);
861 					break;
862 				}
863 				if (!(r = rd_r (&ptr))) {
864 					break;
865 				}
866 				r--;
867 				wrtb (0x80 + r);		/* ADD A,r  */
868 				break;
869 			}
870 			r--;
871 			wrtb (0x80 + r);		/* ADD r  */
872 			break;
873 		case Z80_AND:
874 			if (!(r = rd_r (&ptr))) {
875 				break;
876 			}
877 			r--;
878 			wrtb (0xA0 + r);
879 			break;
880 		case Z80_BIT:
881 			if (!rd_0_7 (&ptr)) {
882 				break;
883 			}
884 			rd_comma (&ptr);
885 			if (!(r = rd_r_(&ptr))) {
886 				break;
887 			}
888 			wrtb (0xCB);
889 			wrtb (0x40 + (r - 1));
890 			break;
891 		case Z80_CALL:
892 			if ((r = rd_cc (&ptr))) {
893 				r--;
894 				wrtb (0xC4 + 8 * r);
895 				rd_comma (&ptr);
896 			} else {
897 				wrtb (0xCD);
898 			}
899 			break;
900 		case Z80_CCF:
901 			wrtb (0x3F);
902 			break;
903 		case Z80_CP:
904 			if (!(r = rd_r (&ptr))) {
905 				break;
906 			}
907 			r--;
908 			wrtb (0xB8 + r);
909 			break;
910 		case Z80_CPD:
911 			wrtb (0xED);
912 			wrtb (0xA9);
913 			break;
914 		case Z80_CPDR:
915 			wrtb (0xED);
916 			wrtb (0xB9);
917 			break;
918 		case Z80_CPI:
919 			wrtb (0xED);
920 			wrtb (0xA1);
921 			break;
922 		case Z80_CPIR:
923 			wrtb (0xED);
924 			wrtb (0xB1);
925 			break;
926 		case Z80_CPL:
927 			wrtb (0x2F);
928 			break;
929 		case Z80_DAA:
930 			wrtb (0x27);
931 			break;
932 		case Z80_DEC:
933 			if (!(r = rd_r_rr (&ptr))) {
934 				break;
935 			}
936 			if (r < 0) {
937 				r--;
938 				wrtb (0x05 - 8 * r);
939 				break;
940 			}
941 			r--;
942 			wrtb (0x0B + 0x10 * r);
943 			break;
944 		case Z80_DI:
945 			wrtb (0xF3);
946 			break;
947 		case Z80_DJNZ:
948 			wrtb (0x10);
949 			// rd_wrt_jr (&ptr, '\0');
950 			break;
951 		case Z80_EI:
952 			wrtb (0xFB);
953 			break;
954 		case Z80_EX:
955 			if (!(r = rd_ex1 (&ptr))) {
956 				break;
957 			}
958 			switch (r) {
959 				case DE:
960 					if (!rd_hl (&ptr)) {
961 						break;
962 					}
963 					wrtb (0xEB);
964 					break;
965 				case AF:
966 					if (!rd_af_(&ptr)) {
967 						break;
968 					}
969 					wrtb (0x08);
970 					break;
971 				default:
972 					if (!rd_hlx (&ptr)) {
973 						break;
974 					}
975 					wrtb (0xE3);
976 			}
977 			break;
978 		case Z80_EXX:
979 			wrtb (0xD9);
980 			break;
981 		case Z80_HALT:
982 			wrtb (0x76);
983 			break;
984 		case Z80_IM:
985 			if (!(r = rd_0_2 (&ptr))) {
986 				break;
987 			}
988 			wrtb (0xED);
989 			r--;
990 			wrtb (0x46 + 8 * r);
991 			break;
992 		case Z80_IN:
993 			if (!(r = rd_in (&ptr))) {
994 				break;
995 			}
996 			if (r == A) {
997 				if (!(r = rd_nnc (&ptr))) {
998 					break;
999 				}
1000 				if (r == C) {
1001 					wrtb (0xED);
1002 					wrtb (0x40 + 8 * (A - 1));
1003 					break;
1004 				}
1005 				wrtb (0xDB);
1006 				break;
1007 			}
1008 			if (!rd_c (&ptr)) {
1009 				break;
1010 			}
1011 			wrtb (0xED);
1012 			r--;
1013 			wrtb (0x40 + 8 * r);
1014 			break;
1015 		case Z80_INC:
1016 			if (!(r = rd_r_rr (&ptr))) {
1017 				break;
1018 			}
1019 			if (r < 0) {
1020 				r++;
1021 				wrtb (0x04 - 8 * r);
1022 				break;
1023 			}
1024 			r--;
1025 			wrtb (0x03 + 0x10 * r);
1026 			break;
1027 		case Z80_IND:
1028 			wrtb (0xED);
1029 			wrtb (0xAA);
1030 			break;
1031 		case Z80_INDR:
1032 			wrtb (0xED);
1033 			wrtb (0xBA);
1034 			break;
1035 		case Z80_INI:
1036 			wrtb (0xED);
1037 			wrtb (0xA2);
1038 			break;
1039 		case Z80_INIR:
1040 			wrtb (0xED);
1041 			wrtb (0xB2);
1042 			break;
1043 		case Z80_JP:
1044 			r = rd_jp (&ptr);
1045 			if (r < 0) {
1046 				wrtb (0xE9);
1047 				break;
1048 			}
1049 			if (r) {
1050 				r--;
1051 				wrtb (0xC2 + 8 * r);
1052 				rd_comma (&ptr);
1053 			} else {
1054 				wrtb (0xC3);
1055 			}
1056 			break;
1057 		case Z80_JR:
1058 			r = rd_jr (&ptr);
1059 			if (r) {
1060 				rd_comma (&ptr);
1061 			}
1062 			wrtb (0x18 + 8 * r);
1063 			break;
1064 		case Z80_LD:
1065 			if (!(r = rd_ld (&ptr))) {
1066 				break;
1067 			}
1068 			switch (r) {
1069 				case ld_BC:
1070 				case ld_DE:
1071 					if (!rd_a (&ptr)) {
1072 						break;
1073 					}
1074 					wrtb (0x02 + 0x10 * (r == ld_DE ? 1 : 0));
1075 					break;
1076 				case ld_HL:
1077 					r = rd_ld_hl (&ptr) - 1;
1078 					wrtb (0x70 + r);
1079 					break;
1080 				case ld_NN:
1081 					if (!(r = rd_ld_nn (&ptr))) {
1082 						break;
1083 					}
1084 					if (r == ld_nnA || r == ld_nnHL) {
1085 						wrtb (0x22 + 0x10 * (r == ld_nnA ? 1 : 0));
1086 						break;
1087 					}
1088 					wrtb (0xED);
1089 					wrtb (0x43 + 0x10 * --r);
1090 					break;
1091 				case ldA:
1092 					if (!(r = rd_lda (&ptr))) {
1093 						break;
1094 					}
1095 					if (r == A_NN) {
1096 						wrtb (0x3A);
1097 						break;
1098 					}
1099 					if (r == A_I || r == A_R) {
1100 						wrtb (0xED);
1101 						wrtb (0x57 + 8 * (r == A_R ? 1 : 0));
1102 						break;
1103 					}
1104 					if (r == A_N) {
1105 						char n = r_num_math (NULL, readbyte);
1106 						wrtb (0x3E);
1107 						wrtb (n);
1108 						break;
1109 					}
1110 					if (r < 0) {
1111 						r++;
1112 						wrtb (0x0A - 0x10 * r);
1113 						break;
1114 					}
1115 					wrtb (0x78 + --r);
1116 					break;
1117 				case ldB:
1118 				case ldC:
1119 				case ldD:
1120 				case ldE:
1121 				case ldH:
1122 				case ldL:
1123 					if (!(s = rd_ldbcdehla (&ptr))) {
1124 						break;
1125 					}
1126 					if (s == 7) {
1127 						char n = r_num_math (NULL, readbyte);
1128 						wrtb (0x08 * (r - 7) + 0x6);
1129 						wrtb (n);
1130 					} else {
1131 						wrtb (0x40 + 0x08 * (r -7) + (s - 1));
1132 					}
1133 					break;
1134 				case ldBC:
1135 				case ldDE:
1136 					s = rd_nn_nn (&ptr);
1137 					if (s == _NN) {
1138 						wrtb (0xED);
1139 						wrtb (0x4B + 0x10 * (r == ldDE ? 1 : 0));
1140 						break;
1141 					}
1142 					wrtb (0x01 + (r == ldDE ? 1 : 0) * 0x10);
1143 					break;
1144 				case ldHL:
1145 					r = rd_nn_nn (&ptr);
1146 					wrtb (0x21 + (r == _NN ? 1 : 0) * 9);
1147 					break;
1148 				case ldI:
1149 				case ldR:
1150 					if (!rd_a (&ptr)) {
1151 						break;
1152 					}
1153 					wrtb (0xED);
1154 					wrtb (0x47 + 0x08 * (r == ldR ? 1 : 0));
1155 					break;
1156 				case ldSP:
1157 					r = rd_sp (&ptr);
1158 					if (r == SPHL) {
1159 						wrtb (0xF9);
1160 						break;
1161 					}
1162 					if (r == SPNN) {
1163 						wrtb (0x31);
1164 						break;
1165 					}
1166 					wrtb (0xED);
1167 					wrtb (0x7B);
1168 					break;
1169 			}
1170 			break;
1171 		case Z80_LDD:
1172 			wrtb (0xED);
1173 			wrtb (0xA8);
1174 			break;
1175 		case Z80_LDDR:
1176 			wrtb (0xED);
1177 			wrtb (0xB8);
1178 			break;
1179 		case Z80_LDI:
1180 			wrtb (0xED);
1181 			wrtb (0xA0);
1182 			break;
1183 		case Z80_LDIR:
1184 			wrtb (0xED);
1185 			wrtb (0xB0);
1186 			break;
1187 		case Z80_NEG:
1188 			wrtb (0xED);
1189 			wrtb (0x44);
1190 			break;
1191 		case Z80_NOP:
1192 			wrtb (0x00);
1193 			break;
1194 		case Z80_OR:
1195 			if (!(r = rd_r (&ptr))) {
1196 				break;
1197 			}
1198 			r--;
1199 			wrtb (0xB0 + r);
1200 			break;
1201 		case Z80_OTDR:
1202 			wrtb (0xED);
1203 			wrtb (0xBB);
1204 			break;
1205 		case Z80_OTIR:
1206 			wrtb (0xED);
1207 			wrtb (0xB3);
1208 			break;
1209 		case Z80_OUT:
1210 			if (!(r = rd_nnc (&ptr))) {
1211 				break;
1212 			}
1213 			if (r == C) {
1214 				if (!(r = rd_out (&ptr))) {
1215 					break;
1216 				}
1217 				wrtb (0xED);
1218 				r--;
1219 				wrtb (0x41 + 8 * r);
1220 				break;
1221 			}
1222 			if (!rd_a (&ptr)) {
1223 				break;
1224 			}
1225 			wrtb (0xD3);
1226 			break;
1227 		case Z80_OUTD:
1228 			wrtb (0xED);
1229 			wrtb (0xAB);
1230 			break;
1231 		case Z80_OUTI:
1232 			wrtb (0xED);
1233 			wrtb (0xA3);
1234 			break;
1235 		case Z80_POP:
1236 			if (!(r = rd_stack (&ptr))) {
1237 				break;
1238 			}
1239 			r--;
1240 			wrtb (0xC1 + 0x10 * r);
1241 			break;
1242 		case Z80_PUSH:
1243 			if (!(r = rd_stack (&ptr))) {
1244 				break;
1245 			}
1246 			r--;
1247 			wrtb (0xC5 + 0x10 * r);
1248 			break;
1249 		case Z80_RES:
1250 			if (!rd_0_7 (&ptr)) {
1251 				break;
1252 			}
1253 			rd_comma (&ptr);
1254 			if (!(r = rd_r_(&ptr))) {
1255 				break;
1256 			}
1257 			wrtb (0xCB);
1258 			r--;
1259 			wrtb (0x80 + r);
1260 			break;
1261 		case Z80_RET:
1262 			if (!(r = rd_cc (&ptr))) {
1263 				wrtb (0xC9);
1264 				break;
1265 			}
1266 			r--;
1267 			wrtb (0xC0 + 8 * r);
1268 			break;
1269 		case Z80_RETI:
1270 			wrtb (0xED);
1271 			wrtb (0x4D);
1272 			break;
1273 		case Z80_RETN:
1274 			wrtb (0xED);
1275 			wrtb (0x45);
1276 			break;
1277 		case Z80_RL:
1278 			if (!(r = rd_r_(&ptr))) {
1279 				break;
1280 			}
1281 			wrtb (0xCB);
1282 			r--;
1283 			wrtb (0x10 + r);
1284 			break;
1285 		case Z80_RLA:
1286 			wrtb (0x17);
1287 			break;
1288 		case Z80_RLC:
1289 			if (!(r = rd_r_(&ptr))) {
1290 				break;
1291 			}
1292 			wrtb (0xCB);
1293 			r--;
1294 			wrtb (0x00 + r);
1295 			break;
1296 		case Z80_RLCA:
1297 			wrtb (0x07);
1298 			break;
1299 		case Z80_RLD:
1300 			wrtb (0xED);
1301 			wrtb (0x6F);
1302 			break;
1303 		case Z80_RR:
1304 			if (!(r = rd_r_(&ptr))) {
1305 				break;
1306 			}
1307 			wrtb (0xCB);
1308 			r--;
1309 			wrtb (0x18 + r);
1310 			break;
1311 		case Z80_RRA:
1312 			wrtb (0x1F);
1313 			break;
1314 		case Z80_RRC:
1315 			if (!(r = rd_r_(&ptr))) {
1316 				break;
1317 			}
1318 			wrtb (0xCB);
1319 			r--;
1320 			wrtb (0x08 + r);
1321 			break;
1322 		case Z80_RRCA:
1323 			wrtb (0x0F);
1324 			break;
1325 		case Z80_RRD:
1326 			wrtb (0xED);
1327 			wrtb (0x67);
1328 			break;
1329 		case Z80_RST:
1330 			ptr = "";
1331 			break;
1332 		case Z80_SBC:
1333 			if (!(r = rd_a_hl (&ptr))) {
1334 				break;
1335 			}
1336 			if (r == HL) {
1337 				if (!(r = rd_rr_(&ptr))) {
1338 					break;
1339 				}
1340 				wrtb (0xED);
1341 				r--;
1342 				wrtb (0x42 + 0x10 * r);
1343 				break;
1344 			}
1345 			if (!(r = rd_r (&ptr))) {
1346 				break;
1347 			}
1348 			r--;
1349 			wrtb (0x98 + r);
1350 			break;
1351 		case Z80_SCF:
1352 			wrtb (0x37);
1353 			break;
1354 		case Z80_SET:
1355 			if (!rd_0_7 (&ptr)) {
1356 				break;
1357 			}
1358 			rd_comma (&ptr);
1359 			if (!(r = rd_r_(&ptr))) {
1360 				break;
1361 			}
1362 			wrtb (0xCB);
1363 			r--;
1364 			wrtb (0xC0 + r);
1365 			break;
1366 		case Z80_SLA:
1367 			if (!(r = rd_r_(&ptr))) {
1368 				break;
1369 			}
1370 			wrtb (0xCB);
1371 			r--;
1372 			wrtb (0x20 + r);
1373 			break;
1374 		case Z80_SLI:
1375 			if (!(r = rd_r_(&ptr))) {
1376 				break;
1377 			}
1378 			wrtb (0xCB);
1379 			r--;
1380 			wrtb (0x30 + r);
1381 			break;
1382 		case Z80_SRA:
1383 			if (!(r = rd_r_(&ptr))) {
1384 				break;
1385 			}
1386 			wrtb (0xCB);
1387 			r--;
1388 			wrtb (0x28 + r);
1389 			break;
1390 		case Z80_SRL:
1391 			if (!(r = rd_r_(&ptr))) {
1392 				break;
1393 			}
1394 			wrtb (0xCB);
1395 			r--;
1396 			wrtb (0x38 + r);
1397 			break;
1398 		case Z80_SUB:
1399 			if (!(r = rd_r (&ptr))) {
1400 				break;
1401 			}
1402 			if (has_argument (&ptr)) {		/* SUB A,r ?  */
1403 				if (r != A) {
1404 					eprintf ("parse error before: %s\n", ptr);
1405 					break;
1406 				}
1407 				if (!(r = rd_r (&ptr))) {
1408 					break;
1409 				}
1410 			}
1411 			r--;
1412 			wrtb (0x90 + r);
1413 			break;
1414 		case Z80_XOR:
1415 			if (!(r = rd_r (&ptr))) {
1416 				break;
1417 			}
1418 			r--;
1419 			wrtb (0xA8 + r);
1420 			break;
1421 		case Z80_DEFB:
1422 		case Z80_DB:
1423 		case Z80_DEFM:
1424 		case Z80_DM:
1425 			ptr = delspc (ptr);
1426 			while (1) {
1427 				have_quote = (*ptr == '"' || *ptr == '\'');
1428 				if (have_quote) {
1429 					/* Read string.  */
1430 					int quote = *ptr;
1431 					++ptr;
1432 					while (*ptr != quote) {
1433 						write_one_byte (rd_character (&ptr, NULL, 1), 0);
1434 						if (*ptr == 0) {
1435 							eprintf ("end of line in quoted string\n");
1436 							break;
1437 						}
1438 					}
1439 					++ptr;
1440 				} else {
1441 					/* Read expression.  */
1442 					skipword (&ptr, ',');
1443 				}
1444 				ptr = delspc (ptr);
1445 				if (*ptr == ',') {
1446 					++ptr;
1447 					continue;
1448 				}
1449 				if (*ptr != 0) {
1450 					eprintf ("junk in byte definition: %s\n", ptr);
1451 				}
1452 				break;
1453 			}
1454 			break;
1455 		case Z80_DEFW:
1456 		case Z80_DW:
1457 			if (!rd_word (&ptr, ',')) {
1458 				eprintf ("No data for word definition\n");
1459 				break;
1460 			}
1461 			while (1) {
1462 				ptr = delspc (ptr);
1463 				if (*ptr != ',') {
1464 					break;
1465 				}
1466 				++ptr;
1467 				if (!rd_word (&ptr, ',')) {
1468 					eprintf ("Missing expression in defw\n");
1469 				}
1470 			}
1471 			break;
1472 		case Z80_DEFS:
1473 		case Z80_DS:
1474 			r = rd_expr (&ptr, ',', NULL, sp, 1);
1475 			if (r < 0) {
1476 				eprintf ("ds should have its first argument >=0"
1477 						" (not -0x%x)\n", -r);
1478 				break;
1479 			}
1480 			ptr = delspc (ptr);
1481 			if (*ptr) {
1482 				rd_comma (&ptr);
1483 				readbyte = 0;
1484 				rd_byte (&ptr, '\0');
1485 				writebyte = 0;
1486 				break;
1487 			}
1488 			for (i = 0; i < r; i++) {
1489 				write_one_byte (0, 0);
1490 			}
1491 			break;
1492 		case Z80_END:
1493 			break;
1494 		case Z80_ORG:
1495 			addr = rd_expr (&ptr, '\0', NULL, sp, 1) & 0xffff;
1496 			break;
1497 		case Z80_IF:
1498 			break;
1499 		case Z80_ELSE:
1500 			eprintf ("else without if\n");
1501 			break;
1502 		case Z80_ENDIF:
1503 			eprintf ("endif without if\n");
1504 			break;
1505 		case Z80_ENDM:
1506 			if (stack[sp].file) {
1507 				eprintf ("endm outside macro definition\n");
1508 			}
1509 			break;
1510 		case Z80_SEEK:
1511 			eprintf ("seek error\n");
1512 			break;
1513 		default:
1514 			// eprintf ("command or comment expected (was %s)\n", ptr);
1515 			return 0;
1516 	}
1517 
1518 	return obuflen;
1519 }
1520 
1521 // XXX
z80asm(unsigned char * outbuf,const char * s)1522 R_API_I int z80asm(unsigned char *outbuf, const char *s) {
1523 	return assemble (s, outbuf);
1524 }
1525 
1526 #ifdef MAIN_ASM
main(int argc,char ** argv)1527 int main(int argc, char **argv) {
1528 	int len;
1529 	unsigned char buf[4];
1530 
1531 	buf[0] = buf[1] = buf[2] = 0;
1532 	len = z80asm (buf, "nop");
1533 	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
1534 
1535 	len = z80asm (buf, "cp b");
1536 	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
1537 
1538 	len = z80asm (buf, "call 0x123");
1539 	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
1540 
1541 	len = z80asm (buf, "call bla");
1542 	printf ("%d   %02x%02x%02x\n", len, buf[0], buf[1], buf[2]);
1543 
1544 	return 0;
1545 }
1546 #endif
1547