uconn code6502 relocatable assembler
6502 relocatable assembler
CSE 258 · 2003 · C++ (MFC)
A systems-programming project: read 6502 assembly, work out each instruction's addressing mode and length in bytes, and print relocatable output in hex. The lengthAnalyzer class has one method per mnemonic, from ADC onward.
Line tokenizing used Richard Case's MFC CToken class (1999), which isn't shown.
Source code
2 files, 617 lines, exactly as written apart from line endings.
6502.cpp · 118 lines
//Stephen Bassoli
//CSE 258
//6502 Relocatable Assembler
#include <afx.h>
#include <fstream.h>
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include "lengthAnalyzer.h"
#include "Token.h"
//INPUTS: Integer
//OUTPUTS: Hex string
CString decToHex(int n)
{
CString hex = "0123456789ABCDEF";
CString str = "$";
for(int i = 3; i >= 0; i--)
str += hex.GetAt((n >> (i * 4)) & 0xf);
return str;
}
//INPUTS: Hex string
//OUTPUTS: Integer equivalent
int hexToDec(CString n)
{
int total = 0;
int curr;
char ch;
int power = 0;
int length = n.GetLength() - 1;
for (length; length >= 0 ; length--)
{
ch = n.GetAt(length);
if (isdigit(ch))
curr = ch - 48;
else
{
ch = toupper(ch);
curr = ch - 55;
}
total = total + curr * int(pow(16,power++));
}
return total;
}
//INPUTS: One line of 6502 code, the starting address in memory
//OUTPUTS: Adds the starting address to any memory refernces in the line of code
CString relocate(CString line, int baseAddr)
{
if (line.GetLength() < 5)
{
return line;
}
CToken tok(line);
tok.SetToken(" ");
CString hexVal;
int newAddr;
CString blank = " ";
CString command = tok.GetNextToken();
CString addr = tok.GetNextToken();
if (addr.GetLength() > 4)
{
if (isalnum(addr.GetAt(4))&&(addr.GetAt(4) != 'X')&&(addr.GetAt(4) != 'Y'))
{
hexVal.Insert(0,addr.GetAt(1));
hexVal.Insert(1,addr.GetAt(2));
hexVal.Insert(2,addr.GetAt(3));
hexVal.Insert(3,addr.GetAt(4));
newAddr = hexToDec(hexVal) + baseAddr;
hexVal = decToHex(newAddr);
addr.Delete(1,4);
addr.Insert(1,hexVal.GetAt(4));
addr.Insert(1,hexVal.GetAt(3));
addr.Insert(1,hexVal.GetAt(2));
addr.Insert(1,hexVal.GetAt(1));
}
}
return command + blank + addr;
}
int main()
{
char* filename = new char[50]; //The name of the 6502 file
int startAddress = 0; //starting memory address
int currAddress = 0; //Current memory address
char addr[20]; //Temp array for inputing the starting address
CString caddr; //CString version of starting address for function
lengthAnalyzer LA; //Length Analyzer that returns length of the instruction
char line[200]; //Temp array for inputing a line of code
CString lines[200]; //Array for all lines of 6502 code
int i = 0; //# of lines in 6502 code
cout << "Type the name of the 6502 code file: ";
cin >> filename;
cout << "What is the starting address in memory: ";
cin >> addr;
startAddress = hexToDec(addr);
currAddress = startAddress;
ifstream infile(filename);
void WriteInfile(ifstream& infile);
while (infile.getline(line,200,'\n'))
lines[i++] = line;
for (int j = 0; j < i; j++)
{
if (LA.getLength(lines[j]) == 0)
{
cerr << "SYNTAX ERROR: LINE " << j << endl;
break;
}
cout << decToHex(currAddress) << " " << relocate(lines[j],startAddress) << endl;
currAddress += LA.getLength(lines[j]);
}
return 0;
}