/************************************* * C02 Variable Management Routines * *************************************/ #include #include #include #include #include #include "common.h" #include "files.h" #include "asm.h" #include "parse.h" #include "label.h" #include "vars.h" #include "dclrtn.h" /* Lookup variable name in variable table * * Sets: varidx = index into vartbl array * * varcnt if not found * * Returns: TRUE if found, otherwise FALSE */ int fndvar(char *name) { DEBUG("vars.fndvar: Looking up variable '%s'\n", name) for (varidx=0; varidx -1) { sprintf(value, "$%hhX", membr.offset); return membr.offset; } ERROR("IndexOf operator requires a struct member\n", 0, EXIT_FAILURE); return 0; //Suppress Warning } /* Parse SizeOf Operator * * Sets: value - variable size (as string) * * Returns: variable size (as integer */ int psizof(void) { expect('@'); //Check for and Skip SizeOf Operator DEBUG("vars.psizof: Parsing SizeOf operator\n", 0); mbridx = -1; //Set Member Index to None reqvar(FALSE); //Parse Variable Name to get Size Of if (mbridx > -1) { sprintf(value, "$%hhX", membr.size); return membr.size; } if (datlen[varidx]) { sprintf(value, "$%hhX", datlen[varidx]); return datlen[varidx]; } if (strlen(varble.size) == 0) { strcpy(value,"1"); return 1; } strcpy(value, varble.size); if (strcmp(value, "*") == 0) ERROR("Unable to Determine Size of Variable %s\n", vrname, EXIT_FAILURE); return atoi(value); } /* Parse Data Array */ void prsdta(void) { DEBUG("vars.prsdta: Parsing Array Data\n", 0) int i; dtype = DTARRY; expect('{'); dlen = 0; do { skpspc(); if (match('"')) { //Parse and Add String (including terminator) getstr(); for (i=0; i<=wrdlen; i++) dattmp[dlen++] = word[i]; } else { //Parse and Add Literal prslit(); dattmp[dlen++] = litval; } } while (look(',')); expect('}'); } /* Parse Data String */ void prsdts(void) { dtype = DTSTR; getstr(); strcpy(value, word); DEBUG("vars.prsdts: Parsed Data String '%s'\n", value) } /* Store variable data * * Uses: value - Data to store * * Sets: datvar[] - Variable Data * * datlen[] - Data Length */ void setdat(void) { int i; if (dtype == DTBYTE) { DEBUG("vars.setdat: Setting variable data to '%d'\n", litval) dlen = 1; datvar[dsize++] = litval; } else if (dtype == DTINT) { DEBUG("vars.setdat: Setting variable data to '%d'\n", litval) dlen = 2; datvar[dsize++] = litval & 0xFF; datvar[dsize++] = litval >> 8; } else if (dtype == DTARRY) { DEBUG("vars.setdat: Setting variable data to array of length %d\n", dlen) for (i=0; i zpgmax) ERROR("Free Zero Page Space Exceeded\n", 0, EXIT_FAILURE) setlbl(vrname); sprintf(word, "$%hhX", zpaddr++); if (t == VTINT) zpaddr++; //int uses two bytes asmlin(EQUOP, word); } strcpy(value, "*"); //Set Variable to Non Allocated } else if (m & MTALS) { setlbl(vrname); skpspc(); expect('='); skpspc(); if (isnpre()) prsnum(0xFFFF); else { prsvar(FALSE, FALSE); if (t == VTINT && vartyp != t) ERROR("ALIAS Type Mismatch\n", 0, EXIT_FAILURE) if (t > VTINT) ERROR("Type may not be ALIASed\n", 0, EXIT_FAILURE) } asmlin(EQUOP, word); strcpy(value, "*"); //Set Variable to Non Allocated } else { if (t == VTSTRUCT) { DEBUG("vars.addvar: Setting variable size to %d\n", strct.size) sprintf(value, "%d", strct.size); } else if (t == VTINT) { DEBUG("vars.addvar: Setting variable size to %d\n", 2) sprintf(value, "%d", 2); } else if (match('[')) { t = VTARRAY; //Set Type to Array CCMNT('[') skpchr(); if (alcvar) { DEBUG("vars.addvar: Parsing array size\n", 0) prslit(); sprintf(value, "%d", litval + 1); } expect(']'); } else value[0] = 0; if (!alcvar) strcpy(value, "*"); } if (look('=')) { prsdat(m, t); //Parse Variable Data if (dtype > DTINT) t = VTARRAY; } setvar(m, t); //Add to Variable Table varcnt++; //Increment Variable Counter } /* Write Variable Definitions * * Args: m = write CONST vars flag */ void vardef(int m) { int i, j; DEBUG("Writing Variable Table\n", 0) fprintf(logfil, "\n%-8s %s %s %s %s %s\n", "Variable", "Mod", "Type", "Size", "Struct", "Data"); dlen = 0; for (i=0; i64) {asmlin(BYTEOP,value); value[0]=0;} } if (dattyp[i] == DTSTR) { if (strlen(value)) strcat(value,","); strcat(value, "$00"); } DEBUG("Allocating Data for Variable '%s'\n", varble.name) asmlin(BYTEOP, value); } else if (strlen(varble.size) > 0) { DEBUG("Allocating array '%s'\n", varble.name) asmlin(STROP, varble.size); } else { DEBUG("Allocating variable '%s'\n", varble.name) asmlin(BYTEOP, "0"); } } vrwrtn = TRUE; } /* Write Variable Table */ void wvrtbl(void) { LCMNT("Variables declared CONST") vardef(MTCONST); //Write CONST Definitions //Emit Segment Mnemonic for RAM Variables here LCMNT("Writable Variables") if (rambas) { asmlin(USEGOP,"RAMVARS"); //Create Uninitialized Segment sprintf(word, "$%X", rambas); asmlin(ORGOP, word); //Set Origin to RAM Base Address } vardef(0); //Write All Other Variables } /* Parse and Compile Struct Declaration */ void addstc(void) { if (!fndstc(word)) ERROR("Undefined Struct '%s\n", word,EXIT_FAILURE) strct = strcts[stcidx]; //Retrieve Structure do { getwrd(); //Get Variable Name addvar(MTNONE, VTSTRUCT); } while (look(',')); expect(';'); } /* Parse Struct Definition * * Uses: word - Struct Name */ void defstc(void) { DEBUG("vars.defstc: Parsing struct definition\n", 0) if (fndstc(word)) ERROR("Duplicate Declaration of Struct '%s\n", word,EXIT_FAILURE) int type; int prnidx = stcidx; strncpy(strct.name, word, STCLEN); DEBUG("vars.defstc: Set struct name to '%s'\n", word); strct.size = 0; //Initialize Struct Length while (look('/')) skpcmt(FALSE); //Skip Comments do { getwrd(); //Get Next word type = ctype(TRUE); //Check if word is a type declaration switch (type) { case TSTRUCT: vartyp = VTSTRUCT; getwrd(); //Get Structure Name if (!fndstc(word)) ERROR("Structure '%s' Not Defined\n", word, EXIT_FAILURE) mbrsiz = strcts[stcidx].size; break; case TINT: vartyp = VTINT; mbrsiz = 2; stcidx = -1; break; case TCHAR: vartyp = VTCHAR; mbrsiz = 1; stcidx = -1; break; case TENUM: ERROR("ENUM in STRUCT Not Implemented\n", 0, EXIT_FAILURE) break; default: ERROR("Invalid Type %s in Struct Definition\n", word, EXIT_FAILURE) } DEBUG("vars.defstc: Parsing members of type %s\n", word) do { getwrd(); //Get Member Name DEBUG("vars.defstc: Parsing member %s\n", word) if (fndmbr(stccnt, word)) ERROR("Duplicate Declaration of Struct Member '%s\n", word,EXIT_FAILURE) if (strlen(word) > STMLEN) ERROR("Member Name %s too long\n", word, EXIT_FAILURE) strcpy(membr.name, word); //Set Member Name membr.strcti = prnidx; //Set Parent Struct Index membr.vartyp = vartyp; //Set Member Variable Type membr.symidx = stcidx; //Set Member Symbol Index membr.offset = strct.size; //Set Offset into Struct membr.size = mbrsiz; //Set Member Size if (membr.vartyp == VTCHAR) { DEBUG("vars.defstc: Checking member for array definition\n", 0) if (match('[')) { CCMNT('['); skpchr(); membr.vartyp = VTARRAY; DEBUG("vars.defstc: Parsing member array size\n", 0) prslit(); membr.size = litval + 1; expect(']'); } } DEBUG("vars.defstc: Set member type to %d", membr.vartyp) DETAIL(" and size to %d\n", membr.size); DEBUG("vars.defstc: Adding member at index %d\n", mbrcnt); membrs[mbrcnt++] = membr; strct.size += membr.size; } while (look(',')); expect(';'); while (look('/')) skpcmt(FALSE); //Skip Comments } while (!look('}')); expect(';'); if (strct.size > 256) ERROR("Structure Size %d Exceeds Limit of 256 bytes.\n", strct.size, EXIT_FAILURE); DEBUG("vars.defstc: Adding struct with size %d", strct.size) DETAIL("at index %d\n", stccnt); strcts[stccnt++] = strct; } /* Print Struc Tables to Log File */ void logstc(void) { fprintf(logfil, "\n%-8s %5s\n", "Struct", "Size"); for (stcidx=0; stcidx