# HG changeset patch # User Matti Hamalainen # Date 1424830507 -7200 # Node ID 0990d9322fc813459ce2d42383f33bf28512dd6d # Parent a07eb3757bf0ccbbff70178175136d2166b2a0ae Implement address-ranged labels. Breaks compatibility of label files. diff -r a07eb3757bf0 -r 0990d9322fc8 dump.c --- a/dump.c Wed Feb 25 04:13:08 2015 +0200 +++ b/dump.c Wed Feb 25 04:15:07 2015 +0200 @@ -90,14 +90,14 @@ for (address = EndAddress < StartAddress ? EndAddress : 0; address != StartAddress; address++) - if (IsLabeled (address)) - fprintf (stdout, "%s%s = $%x\n", lineprefix, Label (address, abso), + if (IsLabeled (address) && !IsInsideRegion(address)) + fprintf (stdout, "%s%s = $%x\n", lineprefix, Label (address, abso, 0), address); if (EndAddress >= StartAddress) for (address = EndAddress; address; address++) - if (IsLabeled (address)) - fprintf (stdout, "%s%s = $%x\n", lineprefix, Label (address, abso), + if (IsLabeled (address) && !IsInsideRegion(address)) + fprintf (stdout, "%s%s = $%x\n", lineprefix, Label (address, abso, 0), address); /* dump the program */ @@ -112,9 +112,9 @@ if (IsLabeled (address)) { if (Options & M_ADDRESSES) fprintf (stdout, "%04x %s%s:\n", address, - lineinfix, Label (address, abso)); + lineinfix, Label (address, abso, 0)); else { - fprintf (stdout, "%s", Label (address, abso)); + fprintf (stdout, "%s", Label (address, abso, 0)); if (Options & B_LABCOL) fprintf(stdout, ":\n"); } @@ -128,10 +128,10 @@ if (Options & M_ADDRESSES) fprintf (stdout, "\t%04x %s%s = * + %u\n", (ADDR_T)(address + counter), - lineinfix, Label (address + counter, abso), counter); + lineinfix, Label (address + counter, abso, 0), counter); else fprintf (stdout, "\t%s = * + %u\n", - Label (address + counter, abso), counter); + Label (address + counter, abso, 0), counter); } if (FindNextEntry (NULL, address, ~0, WRN_INSTR_WRITTEN_TO)) @@ -191,7 +191,7 @@ prefix[instr->admode], ((addr < 256 && instr->mnemonic != S_JMP && instr->mnemonic != S_JSR) ? "!" : ""), - Label (addr, abso),postfix[instr->admode]); + Label (addr, abso, 1), postfix[instr->admode]); break; case zp: case zpx: @@ -201,7 +201,7 @@ case indy: addr = Memory[(ADDR_T)(address + 1)]; fprintf (stdout, "%s %s%s%s\n", mne[instr->mnemonic], - prefix[instr->admode], Label (addr, zp), + prefix[instr->admode], Label (addr, zp, 1), postfix[instr->admode]); break; case rel: @@ -210,7 +210,7 @@ /*fprintf(stderr, "%d %d %d\n", address, size, addr);*/ addr += address + size; fprintf (stdout, "%s %s%s%s\n", mne[instr->mnemonic], - prefix[instr->admode], Label (addr, abso), + prefix[instr->admode], Label (addr, abso, 1), postfix[instr->admode]); break; case zrel: /* BBR0, etc. 65C02 instructions */ @@ -218,8 +218,8 @@ /* addr -= (addr > 127) ? 256 : 0; BUGFIX: sign extend already done */ addr += address + size; fprintf (stdout, "%s %s, %s\n", mne[instr->mnemonic], - Label (Memory[(ADDR_T)(address + 1)], abso), - Label (addr, abso)); + Label (Memory[(ADDR_T)(address + 1)], abso, 1), + Label (addr, abso, 1)); break; } } @@ -230,18 +230,18 @@ if (IsLabeled (address)) { if (Options & M_ADDRESSES) fprintf (stdout, "%04x %s%s:\n", address, lineinfix, - Label (address, abso)); + Label (address, abso, 0)); else - fprintf (stdout, "%s ", Label (address, abso)); + fprintf (stdout, "%s ", Label (address, abso, 0)); } for (counter = size > (maxwidth & ~1) ? (maxwidth & ~1) : size, addr = address + 1; --counter; addr++) if (IsLabeled (addr)) { if (Options & M_ADDRESSES) fprintf (stdout, "%04x %s%s = * + %u\n", addr, lineinfix, - Label (addr, abso), (ADDR_T)(addr - address)); + Label (addr, abso, 0), (ADDR_T)(addr - address)); else - fprintf (stdout, "\t%s = * + %u\n", Label (addr, abso), + fprintf (stdout, "\t%s = * + %u\n", Label (addr, abso, 0), (ADDR_T)(addr - address)); } @@ -259,13 +259,13 @@ fprintf (stdout, " .word %s", Label (Memory[address] | - (Memory[(ADDR_T)(address + 1)] << 8), abso)); + (Memory[(ADDR_T)(address + 1)] << 8), abso, 0)); for (counter = size > (maxwidth & ~1) ? (maxwidth & ~1) : size, addr = address + 2; counter -= 2; addr += 2) fprintf (stdout, ",%s", Label (Memory[addr] | (Memory[(ADDR_T)(addr + 1)] << 8), - abso)); + abso, 0)); fputc ('\n', stdout); @@ -283,18 +283,18 @@ if (IsLabeled (address)) { if (Options & M_ADDRESSES) fprintf (stdout, "%04x %s%s:\n", address, lineinfix, - Label (address, abso)); + Label (address, abso, 0)); else - fprintf (stdout, "%s ", Label (address, abso)); + fprintf (stdout, "%s ", Label (address, abso, 0)); } for (counter = size, addr = address + 1; --counter; addr++) if (IsLabeled (addr)) { if (Options & M_ADDRESSES) fprintf (stdout, "%04x %s%s = * + %u\n", addr, lineinfix, - Label (addr, abso), (ADDR_T)(addr - address)); + Label (addr, abso, 0), (ADDR_T)(addr - address)); else - fprintf (stdout, "\t%s = * + %u\n", Label (addr, abso), + fprintf (stdout, "\t%s = * + %u\n", Label (addr, abso, 0), (ADDR_T)(addr - address)); } diff -r a07eb3757bf0 -r 0990d9322fc8 label.c --- a/label.c Wed Feb 25 04:13:08 2015 +0200 +++ b/label.c Wed Feb 25 04:15:07 2015 +0200 @@ -40,19 +40,13 @@ #include "opcodes.h" label *labeltable; -char defaultlabel[6]; +char defaultlabel[512]; unsigned numLabels = 0; -void AddLabel (ADDR_T address, char *name) +void AddLabel(ADDR_T address, char *name, int is_range, ADDR_T len) { - label *entry; - char *buffer; - - if (!((buffer = malloc (strlen (name) + 1)))) - return; - - entry = numLabels ? + label * entry = numLabels ? realloc (labeltable, (numLabels + 1) * sizeof *entry) : malloc (sizeof *entry); @@ -62,31 +56,67 @@ entry = &labeltable[numLabels++]; entry->address = address; - entry->name = buffer; - while ((*buffer++ = *name++)); + entry->name = strdup(name); + entry->is_range = is_range; + entry->len = len; } - -char *Label (ADDR_T address, int admode) +int IsInsideRegion(ADDR_T address) { label *entry; - if (!IsLabeled (address)) { + for (entry = &labeltable[numLabels]; entry-- > labeltable;) + { + int offs = address - entry->address; + if (entry->is_range && offs > 0 && offs < entry->len) + return TRUE; + } + return FALSE; +} + - /* dirty kludge to allow zero page stuff to still work. this sometimes - guesses wrong */ - if (admode == zp) - sprintf (defaultlabel, "$%02x", address); - else - sprintf (defaultlabel, "$%04x", address); +char *Label(ADDR_T address, int admode, int allow_range) +{ + label *entry; + int match = 0; + + if (!IsLabeled (address)) { + // dirty kludge to allow zero page stuff to still work. this sometimes + // guesses wrong + if (admode == zp) + snprintf(defaultlabel, sizeof(defaultlabel), "$%02x", address); + else + snprintf(defaultlabel, sizeof(defaultlabel), "$%04x", address); + return defaultlabel; } for (entry = &labeltable[numLabels]; entry-- > labeltable;) + { + int offs = address - entry->address; + if (entry->address == address) return entry->name; - sprintf (defaultlabel, "l%x", address); + if (entry->is_range && offs >= 0 && offs < entry->len) + { + match = 1; + if (allow_range) + { + snprintf(defaultlabel, sizeof(defaultlabel), + (offs < 16) ? "%s + %d" : "%s + $%x", + entry->name, offs); + return defaultlabel; + } + else + break; + } + } + + if (match) + snprintf(defaultlabel, sizeof(defaultlabel), "XXX_%x", address); + else + snprintf(defaultlabel, sizeof(defaultlabel), "l_%x", address); return defaultlabel; } diff -r a07eb3757bf0 -r 0990d9322fc8 main.c --- a/main.c Wed Feb 25 04:13:08 2015 +0200 +++ b/main.c Wed Feb 25 04:15:07 2015 +0200 @@ -422,6 +422,7 @@ } while (!feof (file)) { + int tmp; fType = fgetc (file); if (feof (file)) @@ -429,16 +430,11 @@ ungetc (fType, file); -#if(0) - /* This is the old behaviour. -- Cameron */ - if (!fscanf (file, "%X:", &address1) || address1 > 65535 || - !fgets (labelname, sizeof labelname, file)) { -#else /* This is the xa-compatible label scanner. */ - if (!fscanf(file, "%s%i", labelname, &address1) || - address1 > 65535 || - !fgets(strig, sizeof strig, file)) { -#endif + if (!fscanf(file, "%s%i,%i,%i", labelname, &address1, &tmp, &address2) || + address1 > 65535 || + !fgets(strig, sizeof strig, file)) { + LabelError: fprintf (stderr, "%s: Error in label file %s.\n", prog, optarg); fprintf (stderr, "Address(?): 0x%x ... Label(?): \"%s\"\n\n", @@ -461,7 +457,7 @@ for (scanner = labelname; *(unsigned char *)scanner < 32; scanner++) if (!*scanner) goto LabelError; /* label name missing */ - AddLabel (address1, scanner); + AddLabel (address1, scanner, address2 != 0, address2); } fclose (file); diff -r a07eb3757bf0 -r 0990d9322fc8 proto.h --- a/proto.h Wed Feb 25 04:13:08 2015 +0200 +++ b/proto.h Wed Feb 25 04:15:07 2015 +0200 @@ -52,8 +52,9 @@ /* label.c */ -void AddLabel(ADDR_T address, char *name); -char *Label(ADDR_T address, int admode); +int IsInsideRegion(ADDR_T address); +void AddLabel(ADDR_T address, char *name, int is_range, ADDR_T len); +char *Label(ADDR_T address, int admode, int allow_range); void Collect(void); /* garbage collection */ /* vector.c */ diff -r a07eb3757bf0 -r 0990d9322fc8 structures.h --- a/structures.h Wed Feb 25 04:13:08 2015 +0200 +++ b/structures.h Wed Feb 25 04:15:07 2015 +0200 @@ -205,7 +205,8 @@ typedef struct label { - ADDR_T address; + int is_range; + ADDR_T address, len; char *name; } label;