changeset 4:0990d9322fc8

Implement address-ranged labels. Breaks compatibility of label files.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 25 Feb 2015 04:15:07 +0200
parents a07eb3757bf0
children b91c47026822
files dump.c label.c main.c proto.h structures.h
diffstat 5 files changed, 85 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- 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));
         }
 
--- 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;
 }
--- 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);
--- 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 */
--- 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;