Skip to content
uconn code

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;
}

6502.cpp as plain text

lengthanalyzer.h · 499 lines

lengthanalyzer.h as plain text