X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=token.c;h=c78d97ac6f0054d8ca02bf68b0a3a1c0c10406e4;hp=250aa46bded07a66d02aa6cfd4705270a3d687b3;hb=134a7e3bd071d2af06ed25f9690d637cf1791cf8;hpb=3f2bccb78ab4cd59654d521c8aedfe5512ee6608 diff --git a/token.c b/token.c index 250aa46..c78d97a 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" @@ -617,7 +617,7 @@ overflow: // char * GetNextMacroLine(void) { - unsigned source_addr; +// unsigned source_addr; IMACRO * imacro = cur_inobj->inobj.imacro; // LONG * strp = imacro->im_nextln; @@ -728,7 +728,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 +943,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 +1209,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')) - { - v &= 0x000000FF; - ln += 2; - } - - if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W')) + if (obj_format == ALCYON) { - 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 +1552,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;