Mercurial > hg > forks > dxa
annotate label.c @ 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 | ec2f8f6f1dc9 |
children | 122134900c0e |
rev | line source |
---|---|
0 | 1 /*\ |
2 * dxa v0.1.1 -- symbolic 65xx disassembler | |
3 * | |
4 * Copyright (C) 1993, 1994 Marko M\"akel\"a | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 * | |
20 * Contacting the author: | |
21 * | |
22 * Via Internet E-mail: | |
23 * <Marko.Makela@FTP.FUNET.FI> | |
24 * | |
25 * Via Snail Mail: | |
26 * Marko M\"akel\"a | |
27 * Sillitie 10 A | |
28 * FIN-01480 VANTAA | |
29 * Finland | |
30 \*/ | |
31 | |
32 #define _LABEL_C_ | |
33 | |
34 #include <stdlib.h> | |
35 #include <stdio.h> | |
36 #include <string.h> | |
37 | |
38 #include "proto.h" | |
39 #include "options.h" | |
40 #include "opcodes.h" | |
41 | |
42 label *labeltable; | |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
43 char defaultlabel[512]; |
0 | 44 unsigned numLabels = 0; |
45 | |
2
ec2f8f6f1dc9
Cleanup pass #1: Get rid of some ancient K&R-isms.
Matti Hamalainen <ccr@tnsp.org>
parents:
1
diff
changeset
|
46 |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
47 void AddLabel(ADDR_T address, char *name, int is_range, ADDR_T len) |
0 | 48 { |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
49 label * entry = numLabels ? |
0 | 50 realloc (labeltable, (numLabels + 1) * sizeof *entry) : |
51 malloc (sizeof *entry); | |
52 | |
53 if (!entry) return; | |
54 | |
55 labeltable = entry; | |
56 entry = &labeltable[numLabels++]; | |
57 | |
58 entry->address = address; | |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
59 entry->name = strdup(name); |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
60 entry->is_range = is_range; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
61 entry->len = len; |
0 | 62 } |
63 | |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
64 int IsInsideRegion(ADDR_T address) |
0 | 65 { |
66 label *entry; | |
67 | |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
68 for (entry = &labeltable[numLabels]; entry-- > labeltable;) |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
69 { |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
70 int offs = address - entry->address; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
71 if (entry->is_range && offs > 0 && offs < entry->len) |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
72 return TRUE; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
73 } |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
74 return FALSE; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
75 } |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
76 |
0 | 77 |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
78 char *Label(ADDR_T address, int admode, int allow_range) |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
79 { |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
80 label *entry; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
81 int match = 0; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
82 |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
83 if (!IsLabeled (address)) { |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
84 // dirty kludge to allow zero page stuff to still work. this sometimes |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
85 // guesses wrong |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
86 if (admode == zp) |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
87 snprintf(defaultlabel, sizeof(defaultlabel), "$%02x", address); |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
88 else |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
89 snprintf(defaultlabel, sizeof(defaultlabel), "$%04x", address); |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
90 |
0 | 91 return defaultlabel; |
92 } | |
93 | |
94 for (entry = &labeltable[numLabels]; entry-- > labeltable;) | |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
95 { |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
96 int offs = address - entry->address; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
97 |
0 | 98 if (entry->address == address) |
99 return entry->name; | |
100 | |
4
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
101 if (entry->is_range && offs >= 0 && offs < entry->len) |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
102 { |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
103 match = 1; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
104 if (allow_range) |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
105 { |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
106 snprintf(defaultlabel, sizeof(defaultlabel), |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
107 (offs < 16) ? "%s + %d" : "%s + $%x", |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
108 entry->name, offs); |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
109 return defaultlabel; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
110 } |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
111 else |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
112 break; |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
113 } |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
114 } |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
115 |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
116 if (match) |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
117 snprintf(defaultlabel, sizeof(defaultlabel), "XXX_%x", address); |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
118 else |
0990d9322fc8
Implement address-ranged labels. Breaks compatibility of label files.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
119 snprintf(defaultlabel, sizeof(defaultlabel), "l_%x", address); |
0 | 120 |
121 return defaultlabel; | |
122 } | |
123 | |
2
ec2f8f6f1dc9
Cleanup pass #1: Get rid of some ancient K&R-isms.
Matti Hamalainen <ccr@tnsp.org>
parents:
1
diff
changeset
|
124 |
0 | 125 void Collect (void) |
126 { | |
127 unsigned counter = 0; | |
128 table *entry = NULL, *entry2; | |
129 label *labels; | |
130 | |
131 if (fVerbose) | |
132 fprintf (stderr, "%s: collecting garbage.\n", prog); | |
133 | |
134 while ((entry = entry2 = FindNextEntryType (entry, 0, 0))) { | |
135 counter++; | |
136 | |
137 PutLabel (entry->address); | |
138 PutLowByte (entry->address); | |
139 PutHighByte (entry->address); | |
140 | |
141 while ((entry2 = FindNextEntry (entry2, entry->address, | |
142 ~0, entry->type))) | |
143 DeleteEntry (entry2); /* remove duplicate warnings */ | |
144 } | |
145 | |
146 if ((entry = malloc (counter * sizeof *entry))) { /* compact the table */ | |
147 entrycount = counter; | |
148 | |
149 for (entry2 = scantable; counter; entry2++) { | |
150 if (!entry2->type) continue; | |
151 | |
152 memcpy (&entry[--counter], entry2, sizeof *entry); | |
153 } | |
154 | |
155 free (scantable); | |
156 scantable = entry; | |
157 } | |
158 | |
159 for (labels = &labeltable[numLabels]; labels-- > labeltable;) | |
160 if ((ADDR_T)(labels->address - StartAddress) < | |
161 (ADDR_T)(EndAddress - StartAddress)) { | |
162 PutLabel (labels->address); | |
163 PutLowByte (labels->address); | |
164 PutHighByte (labels->address); | |
165 } | |
166 } |