void RST (void) { long constant; struct expr *postfixexpr; GetSym (); if ((postfixexpr = ParseNumExpr ()) != NULL) { if (postfixexpr->rangetype & NOTEVALUABLE) ReportError (CURRENTFILE->fname, CURRENTFILE->line, 2); else { constant = EvalPfixExpr (postfixexpr); if ((constant >= 0 && constant <= 56) && (constant % 8 == 0)) { if ( (cpu_type & CPU_RABBIT) && ((constant == 0) || (constant == 8) || (constant == 0x30))) { ReportError (CURRENTFILE->fname, CURRENTFILE->line, 11); } else { *codeptr++ = 199 + constant; /* RST 00H, ... 38H */ ++PC; } } else ReportError (CURRENTFILE->fname, CURRENTFILE->line, 4); } RemovePfixlist (postfixexpr); } }
void DEFS () { struct expr *postfixexpr; struct expr *constexpr; long constant,val; GetSym (); /* get numerical expression */ if ((postfixexpr = ParseNumExpr ()) != NULL) { /* expr. must not be stored in relocatable file */ if (postfixexpr->rangetype & NOTEVALUABLE) ReportError (CURRENTFILE->fname, CURRENTFILE->line, 2); else { constant = EvalPfixExpr (postfixexpr); if ( sym != comma ) { val = 0; } else { GetSym(); if ( (constexpr = ParseNumExpr ()) != NULL ) { if ( constexpr->rangetype & NOTEVALUABLE ) ReportError(CURRENTFILE->fname,CURRENTFILE->line,2); else val = EvalPfixExpr(constexpr); RemovePfixlist(constexpr); } } if (constant >= 0) { if ((PC + constant) <= MAXCODESIZE) { PC += constant; while (constant--) *codeptr++ = val; } else { ReportError (CURRENTFILE->fname, CURRENTFILE->line, 12); return; } } else { ReportError (CURRENTFILE->fname, CURRENTFILE->line, 7); return; } } RemovePfixlist (postfixexpr); /* remove linked list, expression evaluated */ }
long Parsevarsize (void) { struct expr *postfixexpr; long offset = 0, varsize, size_multiplier; if (strcmp (ident, "DS") != 0) ReportError (CURRENTFILE->fname, CURRENTFILE->line, 11); else { if ((varsize = DEFSP ()) == -1) ReportError (CURRENTFILE->fname, CURRENTFILE->line, 10); else { GetSym (); if ((postfixexpr = ParseNumExpr ()) != NULL) { if (postfixexpr->rangetype & NOTEVALUABLE) { ReportError (CURRENTFILE->fname, CURRENTFILE->line, 2); RemovePfixlist (postfixexpr); } else { size_multiplier = EvalPfixExpr (postfixexpr); RemovePfixlist (postfixexpr); if (size_multiplier > 0 && size_multiplier <= MAXCODESIZE) offset = varsize * size_multiplier; else ReportError (CURRENTFILE->fname, CURRENTFILE->line, 4); } } } } return offset; }
void IM (void) { long constant; struct expr *postfixexpr; if ( (cpu_type & CPU_RABBIT) ) { ReportError (CURRENTFILE->fname, CURRENTFILE->line, 11); return; } GetSym (); if ((postfixexpr = ParseNumExpr ()) != NULL) { if (postfixexpr->rangetype & NOTEVALUABLE) ReportError (CURRENTFILE->fname, CURRENTFILE->line, 2); else { constant = EvalPfixExpr (postfixexpr); switch (constant) { case 0: *codeptr++ = 237; *codeptr++ = 70; /* IM 0 */ break; case 1: *codeptr++ = 237; *codeptr++ = 86; /* IM 1 */ break; case 2: *codeptr++ = 237; *codeptr++ = 94; /* IM 2 */ break; } PC += 2; } RemovePfixlist (postfixexpr); /* remove linked list, because expr. was evaluated */ } }
void ReadExpr (long nextexpr, long endexpr) { char type; long lowbyte, highbyte, offsetptr; long constant, i, fptr; struct expr *postfixexpr; unsigned char *patchptr; do { type = fgetc (z80asmfile); lowbyte = fgetc (z80asmfile); highbyte = fgetc (z80asmfile); offsetptr = highbyte * 256U + lowbyte; /* assembler PC as absolute address */ PC = modulehdr->first->origin + CURRENTMODULE->startoffset + offsetptr; FindSymbol (ASSEMBLERPC, globalroot)->symvalue = PC; i = fgetc (z80asmfile); /* get length of infix expression */ fptr = ftell (z80asmfile); /* file pointer is at start of expression */ fgets (line, i + 1, z80asmfile); /* read string for error reference */ fseek (z80asmfile, fptr, SEEK_SET); /* reset file pointer to start of expression */ nextexpr += 1 + 1 + 1 + 1 + i + 1; EOL = OFF; /* reset end of line parsing flag - a line is to be parsed... */ GetSym (); if ((postfixexpr = ParseNumExpr ()) != NULL) { /* parse numerical expression */ if (postfixexpr->rangetype & NOTEVALUABLE) { ReportError (CURRENTFILE->fname, 0, 2); WriteExprMsg (); } else { constant = EvalPfixExpr (postfixexpr); patchptr = codearea + CURRENTMODULE->startoffset + offsetptr; /* absolute patch pos. * in memory buffer */ switch (type) { case 'U': *patchptr = (unsigned char) constant; break; case 'S': if ((constant >= -128) && (constant <= 255)) *patchptr = (char) constant; /* opcode is stored, now store * relative jump */ else { ReportError (CURRENTFILE->fname, 0, 7); WriteExprMsg (); } break; case 'C': if ((constant >= -32768) && (constant <= 65535)) { *patchptr++ = (unsigned short) constant % 256U; *patchptr = (unsigned short) constant / 256U; } else { ReportError (CURRENTFILE->fname, 0, 7); WriteExprMsg (); } if (autorelocate) if (postfixexpr->rangetype & SYMADDR) { /* Expression contains relocatable address */ constant = PC - curroffset; if ((constant >= 0) && (constant <= 255)) { *relocptr++ = (unsigned char) constant; sizeof_reloctable++; } else { *relocptr++ = 0; *relocptr++ = (unsigned short) (PC - curroffset) % 256U; *relocptr++ = (unsigned short) (PC - curroffset) / 256U; sizeof_reloctable += 3; } totaladdr++; curroffset = PC; } break; case 'L': if (constant >= LONG_MIN && constant <= LONG_MAX) for (i = 0; i < 4; i++) { *patchptr++ = constant & 255; constant >>= 8; } else { ReportError (CURRENTFILE->fname, 0, 7); WriteExprMsg (); } break; } } RemovePfixlist (postfixexpr); } else { WriteExprMsg (); } }
void DEFGROUP (void) { struct expr *postfixexpr; long constant, enumconst = 0; writeline = OFF; /* DEFGROUP definitions are not output'ed to listing file */ while (!feof (z80asmfile) && GetSym () != lcurly) { Skipline (z80asmfile); EOL = OFF; ++CURRENTFILE->line; } if (sym == lcurly) { while (!feof (z80asmfile) && sym != rcurly) { if (EOL == ON) { ++CURRENTFILE->line; EOL = OFF; } else { do { GetSym (); switch (sym) { case rcurly: case semicolon: case newline: break; case name: strcpy (stringconst, ident); /* remember name */ if (GetSym () == assign) { GetSym (); if ((postfixexpr = ParseNumExpr ()) != NULL) { if (postfixexpr->rangetype & NOTEVALUABLE) ReportError (CURRENTFILE->fname, CURRENTFILE->line, 2); else { constant = EvalPfixExpr (postfixexpr); enumconst = constant; DefineSymbol (stringconst, enumconst++, 0); } RemovePfixlist (postfixexpr); } GetSym (); /* prepare for next identifier */ } else DefineSymbol (stringconst, enumconst++, 0); break; default: ReportError (CURRENTFILE->fname, CURRENTFILE->line, 1); break; } } while (sym == comma); /* get enum definitions separated by comma in current line */ Skipline (z80asmfile); /* ignore rest of line */ } } } }
void DEFVARS (void) { struct expr *postfixexpr; long offset; enum flag globaldefv; writeline = OFF; /* DEFVARS definitions are not output'ed to listing file */ GetSym (); if ((postfixexpr = ParseNumExpr ()) != NULL) { /* expr. must not be stored in relocatable file */ if (postfixexpr->rangetype & NOTEVALUABLE) { ReportError (CURRENTFILE->fname, CURRENTFILE->line, 2); RemovePfixlist (postfixexpr); return; } else { offset = EvalPfixExpr (postfixexpr); /* offset expression must not contain undefined symbols */ RemovePfixlist (postfixexpr); } if ((offset != -1) && (offset != 0)) { DEFVPC = offset; globaldefv = ON; } else { if (offset == -1) { globaldefv = ON; offset = DEFVPC; } else { /* offset = 0, use temporarily without smashing DEFVPC */ globaldefv = OFF; } } } else return; /* syntax error - get next line from file... */ while (!feof (z80asmfile) && sym != lcurly) { Skipline (z80asmfile); EOL = OFF; ++CURRENTFILE->line; GetSym (); } if (sym == lcurly) { while (!feof (z80asmfile) && GetSym () != rcurly) { if (EOL == ON) { ++CURRENTFILE->line; EOL = OFF; } else offset += Parsedefvarsize (offset); } if (globaldefv == ON) { DEFVPC = offset; } } }