Skip to content
Snippets Groups Projects
c spec idea 3.83 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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.
    	IMPLEMENTED
    
    I just found out bit fields exist in C, so maybe we can use those to represent instructions (if it's more convenient). Or just pass them as a uint32_t.
    
    iftach's avatar
    iftach committed
    Remember to check memory's bounds before accessing it!
    
    
    Use uint32_t to represent data/instructions/register values
    Use int to represent booleans and 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(...)
    
    void step(struct ProcessorState *processor)
    	Decodes the next instruction and calls the appropriate method to execute it. Handles the PC's offset.
    	uses: dataProcessingInstr(...), multiplyInstr(...), dataTransferInstr(...), branchInstr(...)
    	
    void dataProcessingInstr(struct ProcessorState *processor, int address)
    
    iftach's avatar
    iftach committed
    	Executes a data processing instruction stored in (*processor).memory[address]
    
    	uses: isValidCond(...), barrelShift(...), applyOperation(...)
    int32_t applyOperation(int opcode, int32_t operand1, int32_t operand2, int *carry, int *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.
    
    
    iftach's avatar
    iftach committed
    
    void multiplyInstr(struct ProcessorState *processor, int address)
    
    iftach's avatar
    iftach committed
    	Executes a multiplication instruction stored in (*processor).memory[address]
    	uses: isValidCond(...)
    
    iftach's avatar
    iftach committed
    	
    void dataTransferInstr(struct ProcessorState *processor, int address)
    
    iftach's avatar
    iftach committed
    	Executes a single data transfer instruction stored in (*processor).memory[address]
    
    iftach's avatar
    iftach committed
    	uses: isValidCond(...), barrelShift(...)
    
    void branchInstr(stuct ProcessorState *processor, int address)
    
    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)
    
    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)
    	IMPLEMENTED
    
    
    int isSet(uint32_t source, int index)
    
    iftach's avatar
    iftach committed
    	Shorthand for getBits(source, index, index)
    	IMPLEMENTED
    
    
    int 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
    
    
    uint32_t barrelShift(int immediate, uint32_t operand, int *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.
    
    iftach's avatar
    iftach committed
    	NOTE: for some reason the I bit is used in opposite ways for data processing instructions vs for data transfer instructions. Arbitrarily, let this method
    	assume that the data processing instruction interpretation is the right one (so for data transfer instructions just call this method with NOT i).
    
    
    (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