X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=token.c;h=84faa8f157bc5a9157f60e25e88dbda49e4df0f3;hp=250aa46bded07a66d02aa6cfd4705270a3d687b3;hb=b5f0b68e38eb78c9dd408dce5354584c56b8e90b;hpb=3f2bccb78ab4cd59654d521c8aedfe5512ee6608 diff --git a/token.c b/token.c index 250aa46..84faa8f 100644 --- a/token.c +++ b/token.c @@ -3,7 +3,7 @@ // TOKEN.C - Token Handling // Copyright (C) 199x Landon Dyer, 2011-2012 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 -// Source Utilised with the Kind Permission of Landon Dyer +// Source utilised with the kind permission of Landon Dyer // #include "token.h" @@ -554,6 +554,9 @@ DEBUG printf("ExM: SYMBOL=\"%s\"", d); case DOTL: d = ".l"; break; + case CR_ABSCOUNT: + d = "^^abscount"; + break; case CR_DATE: d = "^^date"; break; @@ -617,7 +620,7 @@ overflow: // char * GetNextMacroLine(void) { - unsigned source_addr; +// unsigned source_addr; IMACRO * imacro = cur_inobj->inobj.imacro; // LONG * strp = imacro->im_nextln; @@ -728,7 +731,10 @@ int fpop(void) // Pop IFENT levels until we reach the conditional assembly context we // were at when the input object was entered. while (ifent != inobj->in_ifent) - d_endif(); + { + if (d_endif() != 0) // Something bad happened during endif parsing? + return -1; // If yes, bail instead of getting stuck in a loop + } tok = inobj->in_otok; // Restore tok and otok etok = inobj->in_etok; @@ -940,8 +946,10 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); case SRC_IMACRO: if ((ln = GetNextMacroLine()) == NULL) { - ExitMacro(); // Exit macro (pop args, do fpop(), etc) - goto retry; // Try for more lines... + if (ExitMacro() == 0) // Exit macro (pop args, do fpop(), etc) + goto retry; // Try for more lines... + else + return TKEOF; // Oops, we got a non zero return code, signal EOF } lntag = '@'; @@ -1204,26 +1212,61 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); { v = 0; + // Parse the hex value while ((int)hextab[*ln] >= 0) v = (v << 4) + (int)hextab[*ln++]; + // ggn: Okay, some comments here are in order I think.... + // The original madmac sources didn't parse the size at + // this point (i.e. .b/.w/.l). It was probably done at + // another point, although it's unclear to me exactly + // where. So why change this? My understanding (at least + // from what SCPCD said on IRC) is that .w addressing + // formats produce wrong code on jaguar (or doesn't execute + // properly? something like that). So the code was changed + // to mask off the upper bits depending on length (note: I + // don't think .b is valid at all! I only know of .w/.l, so + // this should probably be wiped). Then the code that + // parses the constant and checks to see if it's between + // $ffff0000 and $8000 never got triggered, so yay job + // done! ...now say we want to assemble a st .prg. One of + // the most widely spread optimisations is move.X expr.w,Y + // (or vice versa, or both, anyway...) to access hardware + // registers (which are mapped to $fxxxxx). This botchy + // thing would create "hilarious" code while trying to + // access hardware registers. So I made a condition to see + // if st mode or jaguar is active and apply the both or + // not. One last note: this is hardcoded to get optimised + // for now on ST mode, i.e. it can't generate code like + // move.w $00001234,d0 - it'll always get optimised to + // move.w $1234.w,d0. It's probably ok, but maybe a warning + // should be emitted? Or maybe finding a way to make it not + // auto-optimise? I think it's ok for now... if (*ln == '.') { - if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B')) + if (obj_format == ALCYON) { - v &= 0x000000FF; - ln += 2; - } - - if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) - { - v &= 0x0000FFFF; - ln += 2; + if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B') || (*(ln + 1) == 'w') || (*(ln + 1) == 'W') || (*(ln + 1) == 'l') || (*(ln + 1) == 'L')) + { + ln += 2; + } } - - if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L')) + else { - ln += 2; + if ((*(ln + 1) & 0xDF) == 'B') + { + v &= 0x000000FF; + ln += 2; + } + else if ((*(ln + 1) & 0xDF) == 'W') + { + v &= 0x0000FFFF; + ln += 2; + } + else if ((*(ln + 1) & 0xDF) == 'L') + { + ln += 2; + } } } @@ -1512,7 +1555,7 @@ int d_goto(WORD unused) // Compare names (sleazo string compare) // This string compare is not right. Doesn't check for lengths. // (actually it does, but in a crappy, unclear way.) -#warning "!!! Bad string comparison !!!" +WARNING(!!!! Bad string comparison !!!) s1 = sym; // s2 = (char *)(defln + 1) + 1; s2 = defln->line; @@ -1601,6 +1644,8 @@ void DumpTokenBuffer(void) printf("[DOTI]"); else if (*t == ENDEXPR) printf("[ENDEXPR]"); + else if (*t == CR_ABSCOUNT) + printf("[CR_ABSCOUNT]"); else if (*t == CR_DEFINED) printf("[CR_DEFINED]"); else if (*t == CR_REFERENCED)