/* * Z80 - Assembler * Copyright (C) 1987-1992 by Udo Munk * * History: * 17-SEP-1987 Development under Digital Research CP/M 2.2 * 28-JUN-1988 Switched to Unix System V.3 */ /* * Dieses Modul enthaelt die numerischen * Rechen- und Umwandlungsfunktionen. */ #include #include #include "z80a.h" #include "z80aglb.h" #ifndef isxdigit #define isxdigit(c) (isdigit(c) || (c>='a' && c<='f') || (c>='A' && c<='F')) #endif /* * Definition Operatoren-Symbole fuer den Expression-Parser */ #define OPEDEC 1 /* Dezimalzahl */ #define OPEHEX 2 /* Hexzahl */ #define OPEOCT 3 /* Octalzahl */ #define OPEBIN 4 /* Binaerzahl */ #define OPESUB 5 /* arithmetisches - */ #define OPEADD 6 /* arithmetisches + */ #define OPEMUL 7 /* arithmetisches * */ #define OPEDIV 8 /* arithmetisches / */ #define OPEMOD 9 /* arithmetisches Modulo */ #define OPESHL 10 /* logisches shift left */ #define OPESHR 11 /* logisches shift right */ #define OPELOR 12 /* logisches OR */ #define OPELAN 13 /* logisches AND */ #define OPEXOR 14 /* logisches XOR */ #define OPECOM 15 /* logisches Komplement */ #define OPESYM 99 /* Symbol */ /* * Rekursiver Expression-Parser * * Input: Pointer auf den restlichen Argument-String * * Output: berechneter Wert */ eval(s) register char *s; { register char *p; register int val; char word[MAXLINE]; struct sym *sp, *get_sym(); val = 0; while (*s) { p = word; if (*s == '(') { s++; while (*s != ')') { if (*s == '\0') { asmerr(E_MISPAR); goto eval_break; } *p++ = *s++; } *p = '\0'; s++; val = eval(word); continue; } if (*s == STRSEP) { s++; while (*s != STRSEP) { if (*s == '\n' || *s == '\0') { asmerr(E_MISHYP); goto hyp_error; } *p++ = *s++; } s++; hyp_error: *p = '\0'; val = strval(word); continue; } if (isari(*s)) *p++ = *s++; else while (!isspace(*s) && !isari(*s) && (*s != '\0')) *p++ = *s++; *p = '\0'; switch (get_type(word)) { case OPESYM: /* Symbol */ if (strcmp(word, "$") == 0) { val = pc; break; } if (strlen(word) > SYMSIZE) word[SYMSIZE] = '\0'; if ((sp = get_sym(word)) != NULL) val = sp->sym_wert; else asmerr(E_UNDSYM); break; case OPEDEC: /* Dezimalzahl */ val = atoi(word); break; case OPEHEX: /* Hexzahl */ val = axtoi(word); break; case OPEBIN: /* Binaerzahl */ val = abtoi(word); break; case OPEOCT: /* Oktalzahl */ val = aotoi(word); break; case OPESUB: /* arithmetisches - */ val -= eval(s); goto eval_break; case OPEADD: /* arithmetisches + */ val += eval(s); goto eval_break; case OPEMUL: /* arithmetisches * */ val *= eval(s); goto eval_break; case OPEDIV: /* arithmetisches / */ val /= eval(s); goto eval_break; case OPEMOD: /* arithmetisches Modulo */ val %= eval(s); goto eval_break; case OPESHL: /* logisches shift left */ val <<= eval(s); goto eval_break; case OPESHR: /* logisches shift right */ val >>= eval(s); goto eval_break; case OPELOR: /* logisches OR */ val |= eval(s); goto eval_break; case OPELAN: /* logisches AND */ val &= eval(s); goto eval_break; case OPEXOR: /* logisches XOR */ val ^= eval(s); goto eval_break; case OPECOM: /* logisches Komplement */ val = ~(eval(s)); goto eval_break; } } eval_break: return(val); } /* * Operanden Typ-Bestimmung * * Input: Pointer auf zu bestimmenden String * * Output: Operanden Typ */ get_type(s) char *s; { if (isdigit(*s)) { /* numerischer Operand */ if (isdigit(*(s + strlen(s) - 1))) /* Dezimalzahl */ return(OPEDEC); else if (*(s + strlen(s) - 1) == 'H') /* Hexzahl */ return(OPEHEX); else if (*(s + strlen(s) - 1) == 'B') /* Binaerzahl */ return(OPEBIN); else if (*(s + strlen(s) - 1) == 'O') /* Oktalzahl */ return(OPEOCT); } else if (*s == '-') /* arithmetischer Operand - */ return(OPESUB); else if (*s == '+') /* arithmetischer Operand + */ return(OPEADD); else if (*s == '*') /* arithmetischer Operand * */ return(OPEMUL); else if (*s == '/') /* arithmetischer Operand / */ return(OPEDIV); else if (*s == '%') /* arithmetisches Modulo */ return(OPEMOD); else if (*s == '<') /* logisches shift left */ return(OPESHL); else if (*s == '>') /* logisches shift rigth */ return(OPESHR); else if (*s == '|') /* logisches OR */ return(OPELOR); else if (*s == '&') /* logisches AND */ return(OPELAN); else if (*s == '^') /* logisches XOR */ return(OPEXOR); else if (*s == '~') /* logisches Komplement */ return(OPECOM); return(OPESYM); /* Operand ist ein Symbol */ } /* * Die Funktion prueft einen Character auf die arithmetischen * Operatoren +, -, *, /, %, <, >, |, &, ~ und ^. */ isari(c) register int c; { return((c) == '+' || (c) == '-' || (c) == '*' || (c) == '/' || (c) == '%' || (c) == '<' || (c) == '>' || (c) == '|' || (c) == '&' || (c) == '~' || (c) == '^'); } /* * Umwandlung eines ASCII-Strings mit einer Hexzahl in * einen Integer. * Format: nnnnH oder 0nnnnH wenn 1.Ziffer > 9 */ axtoi(str) register char *str; { register int num; num = 0; while (isxdigit(*str)) { num *= 16; num += *str - ((*str <= '9') ? '0' : '7'); str++; } return(num); } /* * Umwandlung eines ASCII-Strings mit einer Oktalzahl in * einen Integer. * Format: nnnnO */ aotoi(str) register char *str; { register int num; num = 0; while ('0' <= *str && *str <= '7') { num *= 8; num += (*str++) - '0'; } return(num); } /* * Umwandlung eines ASCII-Strings mit einer Binaerzahl in * einen Integer. * Format: nnnnnnnnnnnnnnnnB */ abtoi(str) register char *str; { register int num; num = 0; while ('0' <= *str && *str <= '1') { num *= 2; num += (*str++) - '0'; } return(num); } /* * Umwandlung eines ASCII-Strings in einen Integer. */ strval(str) register char *str; { register int num; num = 0; while (*str) { num <<= 8; num += (int) *str++; } return(num); } /* * Die Funktion prueft einen Wert auf -256 < Wert < 256 * Output: Wert wenn im Bereich, sonst 0 und Fehlermeldung */ chk_v1(i) register int i; { if (i >= -255 && i <= 255) return(i); else { asmerr(E_VALOUT); return(0); } } /* * Die Funktion prueft einen Wert auf -128 < Wert < 128 * Output: Wert wenn im Bereich, sonst 0 und Fehlermeldung */ chk_v2(i) register int i; { if (i >= -127 && i <= 127) return(i); else { asmerr(E_VALOUT); return(0); } }