home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / emulator / unix / z80pack / z80asm / z80apfun.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-09  |  8.0 KB  |  443 lines

  1. /*
  2.  *      Z80 - Assembler
  3.  *      Copyright (C) 1987-1992 by Udo Munk
  4.  *
  5.  *    History:
  6.  *    17-SEP-1987 Development under Digital Research CP/M 2.2
  7.  *      28-JUN-1988 Switched to Unix System V.3
  8.  */
  9.  
  10. /*
  11.  *      Dieses Modul enthaelt die Funktionen zur Bearbeitung
  12.  *      aller Pseudo-Op-Codes
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <ctype.h>
  17. #include "z80a.h"
  18. #include "z80aglb.h"
  19.  
  20. /*
  21.  *      Diese Funktion behandelt den Pseudo-Op-Code ORG
  22.  */
  23. op_org()
  24. {
  25.     register int i;
  26.  
  27.     if (!gencode)
  28.         return(0);
  29.     i = eval(operand);
  30.     if (i < pc) {
  31.         asmerr(E_MEMOVR);
  32.         return(0);
  33.     }
  34.     if (pass == 1) {                /* PASS 1 */
  35.         if (!prg_flag) {
  36.             prg_adr = i;
  37.             prg_flag++;
  38.         }
  39.     } else {                        /* PASS 2 */
  40.         if (++prg_flag > 2)
  41.             obj_fill(i - pc);
  42.         sd_flag = 2;
  43.     }
  44.     pc = i;
  45.     return(0);
  46. }
  47.  
  48. /*
  49.  *      Diese Funktion behandelt den Pseudo-Op-Code EQU
  50.  */
  51. op_equ()
  52. {
  53.     struct sym *get_sym();
  54.  
  55.     if (!gencode)
  56.         return(0);
  57.     if (pass == 1) {                /* Pass 1 */
  58.         if (get_sym(label) == NULL) {
  59.             sd_val = eval(operand);
  60.             if (put_sym(label, sd_val))
  61.                 fatal(F_OUTMEM, "symbols");
  62.         } else
  63.             asmerr(E_MULSYM);
  64.     } else {                        /* Pass 2 */
  65.         sd_flag = 1;
  66.         sd_val = eval(operand);
  67.     }
  68.     return(0);
  69. }
  70.  
  71. /*
  72.  *      Diese Funktion behandelt den Pseudo-Op-Code DEFL
  73.  */
  74. op_dl()
  75. {
  76.     if (!gencode)
  77.         return(0);
  78.     sd_flag = 1;
  79.     sd_val = eval(operand);
  80.     if (put_sym(label, sd_val))
  81.         fatal(F_OUTMEM, "symbols");
  82.     return(0);
  83. }
  84.  
  85. /*
  86.  *      Diese Funktion behandelt den Pseudo-Op-Code DEFS
  87.  */
  88. op_ds()
  89. {
  90.     register int val;
  91.  
  92.     if (!gencode)
  93.         return(0);
  94.     if (pass == 1)
  95.         if (*label)
  96.             put_label();
  97.     sd_val = pc;
  98.     sd_flag = 3;
  99.     val = eval(operand);
  100.     if (pass == 2)
  101.         obj_fill(val);
  102.     pc += val;
  103.     return(0);
  104. }
  105.  
  106. /*
  107.  *      Diese Funktion behandelt den Pseudo-Op-Code DEFB
  108.  */
  109. op_db()
  110. {
  111.     register int i;
  112.     register char *p;
  113.     register char *s;
  114.  
  115.     if (!gencode)
  116.         return(0);
  117.     i = 0;
  118.     p = operand;
  119.     if (pass == 1)
  120.         if (*label)
  121.             put_label();
  122.     while (*p) {
  123.         if (*p == STRSEP) {
  124.             p++;
  125.             while (*p != STRSEP) {
  126.                 if (*p == '\n' || *p == '\0') {
  127.                     asmerr(E_MISHYP);
  128.                     goto hyp_error;
  129.                 }
  130.                 ops[i++] = *p++;
  131.                 if (i >= OPCARRAY)
  132.                     fatal(F_INTERN, "Op-Code buffer overflow");
  133.             }
  134.             p++;
  135.         } else {
  136.             s = tmp;
  137.             while (*p != ',' && *p != '\0')
  138.                 *s++ = *p++;
  139.             *s = '\0';
  140.             ops[i++] = eval(tmp);
  141.             if (i >= OPCARRAY)
  142.                 fatal(F_INTERN, "Op-Code buffer overflow");
  143.         }
  144.         if (*p == ',')
  145.             p++;
  146.     }
  147. hyp_error:
  148.     return(i);
  149. }
  150.  
  151. /*
  152.  *      Diese Funktion behandelt den Pseudo-Op-Code DEFM
  153.  */
  154. op_dm()
  155. {
  156.     register int i;
  157.     register char *p;
  158.  
  159.     if (!gencode)
  160.         return(0);
  161.     i = 0;
  162.     p = operand;
  163.     if (pass == 1)
  164.         if (*label)
  165.             put_label();
  166.     if (*p != STRSEP) {
  167.         asmerr(E_MISHYP);
  168.         return(0);
  169.     }
  170.     p++;
  171.     while (*p != STRSEP) {
  172.         if (*p == '\n' || *p == '\0') {
  173.             asmerr(E_MISHYP);
  174.             break;
  175.         }
  176.         ops[i++] = *p++;
  177.         if (i >= OPCARRAY)
  178.             fatal(F_INTERN, "Op-Code buffer overflow");
  179.     }
  180.     return(i);
  181. }
  182.  
  183. /*
  184.  *      Diese Funktion behandelt den Pseudo-Op-Code DEFW
  185.  */
  186. op_dw()
  187. {
  188.     register int i, len, temp;
  189.     register char *p;
  190.     register char *s;
  191.  
  192.     if (!gencode)
  193.         return(0);
  194.     p = operand;
  195.     i = len = 0;
  196.     if (pass == 1)
  197.         if (*label)
  198.             put_label();
  199.     while (*p) {
  200.         s = tmp;
  201.         while (*p != ',' && *p != '\0')
  202.             *s++ = *p++;
  203.         *s = '\0';
  204.         if (pass == 2) {
  205.             temp = eval(tmp);
  206.             ops[i++] = temp & 0xff;
  207.             ops[i++] = temp >> 8;
  208.             if (i >= OPCARRAY)
  209.                 fatal(F_INTERN, "Op-Code buffer overflow");
  210.         }
  211.         len += 2;
  212.         if (*p == ',')
  213.             p++;
  214.     }
  215.     return(len);
  216. }
  217.  
  218. /*
  219.  *      Diese Funktion behandelt die Pseudo-Op-Codes
  220.  *      EJECT, LIST, NOLIST, PAGE, PRINT, TITLE, INCLUDE
  221.  */
  222. op_misc(op_code, dummy)
  223. int op_code, dummy;
  224. {
  225.     register char *p, *d;
  226.     static char fn[LENFN];
  227.     static int incnest;
  228.     static struct inc incl[INCNEST];
  229.  
  230.     if (!gencode)
  231.         return(0);
  232.     sd_flag = 2;
  233.     switch(op_code) {
  234.     case 1:                         /* EJECT */
  235.         if (pass == 2)
  236.             p_line = ppl;
  237.         break;
  238.     case 2:                         /* LIST */
  239.         if (pass == 2)
  240.             list_flag = 1;
  241.         break;
  242.     case 3:                         /* NOLIST */
  243.         if (pass == 2)
  244.             list_flag = 0;
  245.         break;
  246.     case 4:                         /* PAGE */
  247.         if (pass == 2)
  248.             ppl = eval(operand);
  249.         break;
  250.     case 5:                         /* PRINT */
  251.         if (pass == 1) {
  252.             p = operand;
  253.             while (*p) {
  254.                 if (*p != STRSEP)
  255.                     putchar(*p++);
  256.                 else
  257.                     p++;
  258.             }
  259.             putchar('\n');
  260.         }
  261.         break;
  262.     case 6:                         /* INCLUDE */
  263.         if (incnest >= INCNEST) {
  264.             asmerr(E_INCNEST);
  265.             break;
  266.         }
  267.         incl[incnest].inc_line = c_line;
  268.         incl[incnest].inc_fn = srcfn;
  269.         incl[incnest].inc_fp = srcfp;
  270.         incnest++;
  271.         p = line;
  272.         d = fn;
  273.         while(isspace(*p))      /* white space bis INCLUDE ueberlesen */
  274.             p++;
  275.         while(!isspace(*p))     /* INCLUDE ueberlesen */
  276.             p++;
  277.         while(isspace(*p))      /* white space bis Filename ueberlesen */
  278.             p++;
  279.         while(!isspace(*p) && *p != COMMENT) /* Filename uebernehmen */
  280.             *d++ = *p++;
  281.         *d = '\0';
  282.         if (pass == 1) {        /* PASS 1 */
  283.             if (!ver_flag)
  284.                 printf("   Include %s\n", fn);
  285.             p1_file(fn);
  286.         } else {                /* PASS 2 */
  287.             sd_flag = 2;
  288.             lst_line(0, 0);
  289.             if (!ver_flag)
  290.                 printf("   Include %s\n", fn);
  291.             p2_file(fn);
  292.         }
  293.         incnest--;
  294.         c_line = incl[incnest].inc_line;
  295.         srcfn = incl[incnest].inc_fn;
  296.         srcfp = incl[incnest].inc_fp;
  297.         printf("   Resume  %s\n", srcfn);
  298.         if (list_flag && (pass == 2)) {
  299.             lst_header();
  300.             lst_attl();
  301.         }
  302.         sd_flag = 4;
  303.         break;
  304.     case 7:                         /* TITLE */
  305.         if (pass == 2) {
  306.             p = line;
  307.             d = title;
  308.             while (isspace(*p))     /* white space bis TITLE ueberlesen */
  309.                 p++;
  310.             while (!isspace(*p))    /* TITLE ueberlesen */
  311.                 p++;
  312.             while (isspace(*p))     /* white space bis Titel ueberlesen */
  313.                 p++;
  314.             if (*p == STRSEP)
  315.                 p++;
  316.             while (*p != '\n' && *p != STRSEP && *p != COMMENT)
  317.                 *d++ = *p++;
  318.             *d = '\0';
  319.         }
  320.         break;
  321.     default:
  322.         fatal(F_INTERN, "illegal opcode for function op_misc");
  323.         break;
  324.     }
  325.     return(0);
  326. }
  327.  
  328. /*
  329.  *      Diese Funktion behandelt die Pseudo-Op-Codes
  330.  *      IFDEF, IFNDEF, IFEQ, IFNEQ, ELSE, ENDIF
  331.  */
  332. op_cond(op_code, dummy)
  333. int op_code, dummy;
  334. {
  335.     register char *p, *p1, *p2;
  336.     static int condnest[IFNEST];
  337.     struct sym *get_sym();
  338.     char *strchr();
  339.  
  340.     switch(op_code) {
  341.     case 1:                         /* IFDEF */
  342.         if (iflevel >= IFNEST) {
  343.             asmerr(E_IFNEST);
  344.             break;
  345.         }
  346.         condnest[iflevel++] = gencode;
  347.         if (gencode)
  348.             if (get_sym(operand) == NULL)
  349.                 gencode = 0;
  350.         break;
  351.     case 2:                         /* IFNDEF */
  352.         if (iflevel >= IFNEST) {
  353.             asmerr(E_IFNEST);
  354.             break;
  355.         }
  356.         condnest[iflevel++] = gencode;
  357.         if (gencode)
  358.             if (get_sym(operand) != NULL)
  359.                 gencode = 0;
  360.         break;
  361.     case 3:                         /* IFEQ */
  362.         if (iflevel >= IFNEST) {
  363.             asmerr(E_IFNEST);
  364.             break;
  365.         }
  366.         condnest[iflevel++] = gencode;
  367.         p = operand;
  368.         if (!*p || !(p1 = strchr(operand, ','))) {
  369.             asmerr(E_MISOPE);
  370.             break;
  371.         }
  372.         if (gencode) {
  373.             p2 = tmp;
  374.             while (*p != ',')
  375.                 *p2++ = *p++;
  376.             *p2 = '\0';
  377.             if (eval(tmp) != eval(++p1))
  378.                 gencode = 0;
  379.         }
  380.         break;
  381.     case 4:                         /* IFNEQ */
  382.         if (iflevel >= IFNEST) {
  383.             asmerr(E_IFNEST);
  384.             break;
  385.         }
  386.         condnest[iflevel++] = gencode;
  387.         p = operand;
  388.         if (!*p || !(p1 = strchr(operand, ','))) {
  389.             asmerr(E_MISOPE);
  390.             break;
  391.         }
  392.         if (gencode) {
  393.             p2 = tmp;
  394.             while (*p != ',')
  395.                 *p2++ = *p++;
  396.             *p2 = '\0';
  397.             if (eval(tmp) == eval(++p1))
  398.                 gencode = 0;
  399.         }
  400.         break;
  401.     case 98:                        /* ELSE */
  402.         if (!iflevel)
  403.             asmerr(E_MISIFF);
  404.         else
  405.             if ((iflevel == 0) || (condnest[iflevel - 1] == 1))
  406.                 gencode = !gencode;
  407.         break;
  408.     case 99:                        /* ENDIF */
  409.         if (!iflevel)
  410.             asmerr(E_MISIFF);
  411.         else
  412.             gencode = condnest[--iflevel];
  413.         break;
  414.     default:
  415.         fatal(F_INTERN, "illegal opcode for function op_cond");
  416.         break;
  417.     }
  418.     sd_flag = 2;
  419.     return(0);
  420. }
  421.  
  422. /*
  423.  *      Diese Funktion behandelt die Pseudo-Op-Codes
  424.  *      EXTRN und PUBLIC
  425.  */
  426. op_glob(op_code, dummy)
  427. int op_code, dummy;
  428. {
  429.     if (!gencode)
  430.         return(0);
  431.     sd_flag = 2;
  432.     switch(op_code) {
  433.     case 1:                         /* EXTRN */
  434.         break;
  435.     case 2:                         /* PUBLIC */
  436.         break;
  437.     default:
  438.         fatal(F_INTERN, "illegal opcode for function op_glob");
  439.         break;
  440.     }
  441.     return(0);
  442. }
  443.