Skip to content
Snippets Groups Projects
c spec idea 4.76 KiB
Newer Older
iftach's avatar
iftach committed
Spec idea:

DATA STUFF

iftach's avatar
iftach committed
struct ProcessorState
	Represents a processor; registers and memory.
	Let's keep the PC incremented to the actual value it's supposed to have in a real arm processor (current instruction +8).
		If the first instruction after a jump is another jump (or if the first instruction of a program is a jump) this might cause a problem (?)
		since in an actual execution the offset starts at 0 and moves to +8 after two instructions. decode() should probably account for this.
iftach's avatar
iftach committed
	struct ProcessorState
	{
  		uint32_t registers[17];
  		uint32_t memory[MEMORY_SIZE];
	};	
	
iftach's avatar
iftach committed
	IMPLEMENTED
iftach's avatar
iftach committed
	
Remember to check memory's bounds before accessing it!

Use uint32_t to represent data/instructions/register values
Use bool to represent booleans and int (if you want) to represent anything that doesn't need more than 16 bits (apparently ints can be only 16 bits on some systems)


NON-HELPER FUNCTIONS

iftach's avatar
iftach committed
main
	uses: loadBinary(...), step(...)

iftach's avatar
iftach committed
void step(struct ProcessorState *processor, bool *terminate)
iftach's avatar
iftach committed
	Decodes the next instruction and calls the appropriate method to execute it. Handles the PC's offset.
iftach's avatar
iftach committed
	Sets 'terminate' if the instruction is all 0s, and returns.
iftach's avatar
iftach committed
	uses: dataProcessingInstr(...), multiplyInstr(...), dataTransferInstr(...), branchInstr(...)
	
void dataProcessingInstr(struct ProcessorState *processor, int address)
	Executes a data processing instruction stored in processor->memory[address]
	uses: isValidCond(...), barrelShift(...), applyOperation(...)
iftach's avatar
iftach committed
int32_t applyOperation(int opcode, int32_t operand1, int32_t operand2, bool *carry, bool *store)
	Applies a binary operation (from an opcode) on two operators. Returns the result, and sets the supplied carry bit if it makes sense to do so.
	Doesn't change the carry bit when performing a logical operation.
	IMPLEMENTED, needs tests
iftach's avatar
iftach committed

iftach's avatar
iftach committed
void multiplyInstr(struct ProcessorState *processor, uint32_t instruction)
	Executes a multiplication instruction
iftach's avatar
iftach committed
	uses: isValidCond(...)
iftach's avatar
iftach committed
	
iftach's avatar
iftach committed
void dataTransferInstr(struct ProcessorState *processor, uint32_t instruction)
	Executes a single data transfer instruction
	uses: isValidCond(...), barrelShift(...) <- negate I
iftach's avatar
iftach committed

iftach's avatar
iftach committed
void branchInstr(stuct ProcessorState *processor, uint32_t instruction)
	Executes a single branch instruction
iftach's avatar
iftach committed
	uses: isValidCond(...),
iftach's avatar
iftach committed
	
struct ProcessorState *loadBinary(char* src)
iftach's avatar
iftach committed
	creates a new ProcessorState and loads its memory from a binary file.
	It's probably a good idea for this to check the edianness of the computer the emulator is running on (which is apparently possible at runtime) and flip the
	binary data accordingly when loading it, as things would get really confusing otherwise (operations like arithmetic right shifts wouldn't work properly, I think)
iftach's avatar
iftach committed


HELPER FUNCTIONS (probably used in more than one method):
iftach's avatar
iftach committed

uint32_t getBits(uint32_t source, int start, int end)
iftach's avatar
iftach committed
	Reads bits from source in the range [start, end] (inclusive). Returns a uint32_t with the result as its least significant bits.
	(e.g. getBits(8, 2, 3) == 2 because 8 == 0000'10'00)
	IMPLEMENTED, TESTED
iftach's avatar
iftach committed

iftach's avatar
iftach committed
bool isSet(uint32_t source, int index)
iftach's avatar
iftach committed
	Shorthand for getBits(source, index, index)
	IMPLEMENTED, TESTED
iftach's avatar
iftach committed

iftach's avatar
iftach committed
bool validCond(uint32_t cond, struct ProcessorState *processor)
iftach's avatar
iftach committed
	Returns 1 if the condition code 'cond' is satisfied by the processor's current state, and 0 otherwise.
	IMPLEMENTED

iftach's avatar
iftach committed
uint32_t barrelShift(bool immediate, uint32_t operand, bool *carry, struct ProcessorState *processor)
iftach's avatar
iftach committed
	Implements the functionality of the barrel shifter. The carry output is written to (*carry), just in case you need it.
	NOTE: for some reason the I bit is used in opposite ways for data processing instructions vs for data transfer instructions. Arbitrarily, this method
	uses the data processing instruction interpretation (so for data transfer instructions just call this method with !I).
	IMPLEMENTED, TESTED
iftach's avatar
iftach committed

struct ProcessorState *makeProcessor(void)
	Creates a new processor struct. Dynamically allocated, so don't forget to use free() at the end!
(optionally)
iftach's avatar
iftach committed
int32_t *accessMemory(struct ProcessorState *processor, int address)
	Gets an address from memory while ensuring it's not out of bounds
	(only if you want; you can always do bounds checking manually)
iftach's avatar
iftach committed

TESTING STUFF:
void test(bool pass, char *testname)
	prints out a formatted message stating the test name and whether it passed.
	IMPLEMENTED
uint32_t bin(char* number)
	converts a string representing a binary number (e.g. "01001") to a number. For testing purposes.
	Ignores spaces and leading zeros, so you can format it like the instructions ("0001 0 00 1 0000").
	Doesn't actually check the input at all, so only use it for testing.
	IMPLEMENTED

implemented tests:
void testBitGetters(void)
void testBarrelShifter(void)

tests still needed:
applyOperation (and maybe validCond, but it's quite a simple function so idk)



Put other stuff you've implemented here!