Skip to content

Commit 65045a3

Browse files
committed
Fixed issue with labels before BADR
1 parent 2dd7351 commit 65045a3

File tree

2 files changed

+72
-16
lines changed

2 files changed

+72
-16
lines changed

src/as4.c

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,24 @@ int main(int argc, char **argv)
162162
/* Easy one */
163163
if(!strncmp(trimed, "HLT", 4))
164164
{
165-
/* We only need to understand that it's the halt instruction, we don't care about the rest of the line. */
166-
doneline = 1;
167-
/* Add the instruction to the output buffer. */
168-
addinst(outbuf, HLT, NOADDR, &bits, &bytes);
165+
free(trimed);
166+
/* Get the next token, which is likely a label (though it could be a number) */
167+
tokens = strtok(NULL, delims);
168+
trimed = trim(tokens);
169+
/* Check firstly that there is a valid label or address after the instruction. */
170+
if(trimed == NULL || trimed[0] == '\n' || trimed[0] == '\r' || trimed[0] == '\0' || trimed[0] == ' ')
171+
{
172+
/* Address is optional - if it isn't there, just put zeros. */
173+
addinst(outbuf, HLT, NOADDR, &bits, &bytes);
174+
}
175+
/* Get the address location. */
176+
/* If it's just a number after the instruction, that will be returned with the base address added to it. */
177+
/* If it's a yet undeclared label, 65535 (UNKNOWNADDR) is returned. The instruction will be modified when the label is declared. */
178+
/* If it's an already declared label return the address relative to the base address. */
179+
address = findlabel(&unknownlabels, &labels, trimed, numlabels, &numunknownlabels, bits, INST);
180+
/* Add this to the output buffer. */
181+
addinst(outbuf, HLT, address, &bits, &bytes);
182+
169183
}
170184
/* Load instruction */
171185
else if(!strncmp(trimed, "LOD", 4))
@@ -234,10 +248,24 @@ int main(int argc, char **argv)
234248
/* No-operation instruction */
235249
else if(!strncmp(trimed, "NOP", 4))
236250
{
237-
/* We only need to understand that it's the nop instruction, we don't care about the rest of the line. */
238-
doneline = 1;
239-
/* Add the instruction to the output buffer. */
240-
addinst(outbuf, NOP, NOADDR, &bits, &bytes);
251+
free(trimed);
252+
/* Get the next token, which is likely a label (though it could be a number) */
253+
tokens = strtok(NULL, delims);
254+
trimed = trim(tokens);
255+
/* Check firstly that there is a valid label or address after the instruction. */
256+
if(trimed == NULL || trimed[0] == '\n' || trimed[0] == '\r' || trimed[0] == '\0' || trimed[0] == ' ')
257+
{
258+
/* Address is optional - if it isn't there, just put zeros. */
259+
addinst(outbuf, NOP, NOADDR, &bits, &bytes);
260+
}
261+
/* Get the address location. */
262+
/* If it's just a number after the instruction, that will be returned with the base address added to it. */
263+
/* If it's a yet undeclared label, 65535 (UNKNOWNADDR) is returned. The instruction will be modified when the label is declared. */
264+
/* If it's an already declared label return the address relative to the base address. */
265+
address = findlabel(&unknownlabels, &labels, trimed, numlabels, &numunknownlabels, bits, INST);
266+
/* Add this to the output buffer. */
267+
addinst(outbuf, NOP, address, &bits, &bytes);
268+
241269
}
242270
/* Start of the information section. Save as NOP with address 0xFFFF so the processor isn't bothered but we can tell later. */
243271
else if(!strncmp(trimed, "INF", 4))
@@ -280,11 +308,18 @@ int main(int argc, char **argv)
280308
if(baseaddr == 0)
281309
{
282310
baseaddr = findlabel(&unknownlabels, &labels, trimed, numlabels, &numunknownlabels, bits, INST);
311+
/* If the base address has changed, we should check if there are labels that have been declared before this that need adjustment. */
312+
for(i = 0; i < numlabels; i++)
313+
{
314+
label *templabels = NULL;
315+
unsigned long long templabelnum = 0;
316+
317+
addlabel(outbuf, &templabels, &unknownlabels, &templabelnum, &numunknownlabels, labels[i].str, (labels[i].addr * 4), baseaddr);
318+
labels[i].addr = templabels[0].addr;
319+
}
283320
}
284321
/* Add this to the output buffer. */
285322
addinst(outbuf, NOP, baseaddr, &bits, &bytes);
286-
287-
288323
}
289324
/* End of the program information section within the information section. Save as a NOP with address 0xFFFF so the processor isn't bothered but we can tell later. */
290325
else if(!strncmp(trimed, "EPINF", 6))
@@ -452,10 +487,23 @@ int main(int argc, char **argv)
452487
/* A very niche but important instruction. */
453488
else if(!strncmp(trimed, "CXA", 4))
454489
{
455-
/* We only need to understand that it's the carry and XOR to accumulator instruction, we don't care about the rest of the line. */
456-
doneline = 1;
457-
/* Add the instruction to the output buffer. */
458-
addinst(outbuf, CXA, NOADDR, &bits, &bytes);
490+
free(trimed);
491+
/* Get the next token, which is likely a label (though it could be a number) */
492+
tokens = strtok(NULL, delims);
493+
trimed = trim(tokens);
494+
/* Check firstly that there is a valid label or address after the instruction. */
495+
if(trimed == NULL || trimed[0] == '\n' || trimed[0] == '\r' || trimed[0] == '\0' || trimed[0] == ' ')
496+
{
497+
/* Address is optional - if it isn't there, just put zeros. */
498+
addinst(outbuf, CXA, NOADDR, &bits, &bytes);
499+
}
500+
/* Get the address location. */
501+
/* If it's just a number after the instruction, that will be returned with the base address added to it. */
502+
/* If it's a yet undeclared label, 65535 (UNKNOWNADDR) is returned. The instruction will be modified when the label is declared. */
503+
/* If it's an already declared label return the address relative to the base address. */
504+
address = findlabel(&unknownlabels, &labels, trimed, numlabels, &numunknownlabels, bits, INST);
505+
/* Add this to the output buffer. */
506+
addinst(outbuf, CXA, address, &bits, &bytes);
459507
}
460508
/* .data arbitrary data section inputs */
461509
else if(!strncmp(trimed, ".data", 6))

src/label.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,16 @@ void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long
5959
exit(5);
6060
}
6161
/* Copy the contains of the label's name, up until the zero terminator (our calloc gave us an all zero string array, so any data copied in is automatically zero terminated). */
62-
memcpy(tempstr, labelstr, (strlen(labelstr) - 1));
62+
strcpy(tempstr, labelstr);
63+
/* Strip the trailing ":" */
64+
for(i = 0; i < strlen(tempstr); i++)
65+
{
66+
if(tempstr[i] == ':')
67+
{
68+
tempstr[i] = '\0';
69+
break;
70+
}
71+
}
6372
/* Before we commit to keeping this label, check if we've used the name already. */
6473
/* Because using the same label for two different locations makes no sense. */
6574
for(i = 0; i < ((*numlabels) - 1); i++)
@@ -110,7 +119,6 @@ void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long
110119
/* Check if the name of the unknown label is the same as the label that we just had declared. */
111120
if(!strcmp((*unknownlabels)[i].str, tempstr))
112121
{
113-
114122
/* If it is, then take stock of both the address it was referenced. If a label is referencing a label, we need to move 1 nibble back (as there is no instruction, just 4 nibbles). Cheaper than doing an if below. */
115123
unsigned short int instaddress = (*unknownlabels)[i].addr - ((*unknownlabels)[i].type & 1);
116124
/* And the address the label points to plus the requested offset. We need to add one nibble if it is an instruction referencing a nibble as we moved one back above. */

0 commit comments

Comments
 (0)