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