home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 <stdio.h>
- #include <ctype.h>
- #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);
- }
- }
-