Document all emulate files
This commit is contained in:
parent
9f31c6306b
commit
98196c4578
@ -1,3 +1,11 @@
|
||||
/** @file emulate.c
|
||||
* @brief The main file for the ARMv8 emulator. Reads a binary file and outputs
|
||||
* the state of the machine after executing the instructions in the file.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "a64instruction/a64instruction.h"
|
||||
@ -20,6 +28,7 @@ int main(int argc, char **argv) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// If a second argument is provided, use it as output file instead of stdout.
|
||||
FILE *out = stdout;
|
||||
if (argc > 2) {
|
||||
out = fopen(argv[2], "w");
|
||||
|
||||
@ -17,6 +17,102 @@
|
||||
// FIELDNAME_LSB and FIELDNAME_MSB, storing the result in the variable wrd
|
||||
#define getField(fieldname) getBits(wrd, fieldname##_LSB, fieldname##_MSB)
|
||||
|
||||
/************************************
|
||||
* CONSTANTS
|
||||
************************************/
|
||||
|
||||
#define HALT_WORD 0x8a000000
|
||||
|
||||
#define TYPE_ID_LSB 26
|
||||
#define TYPE_ID_MSB 29
|
||||
#define DP_IMM_ID 4
|
||||
#define BRANCH_ID 5
|
||||
|
||||
#define DP_REG_FLAG_LSB 25
|
||||
#define DP_REG_FLAG_MSB 26
|
||||
|
||||
#define DP_WIDTH_LSB 31
|
||||
#define DP_WIDTH_MSB 32
|
||||
#define DP_OP_LSB 29
|
||||
#define DP_OP_MSB 31
|
||||
#define DP_DEST_LSB 0
|
||||
#define DP_DEST_MSB 5
|
||||
|
||||
#define DP_IMM_OPTYPE_LSB 23
|
||||
#define DP_IMM_OPTYPE_MSB 26
|
||||
#define DP_IMM_OPTYPE_ARITHM 2
|
||||
#define DP_IMM_OPTYPE_WIDEMOV 5
|
||||
#define DP_IMM_ARITHM_SHIFTFLAG_LSB 22
|
||||
#define DP_IMM_ARITHM_SHIFTFLAG_MSB 23
|
||||
#define DP_IMM_ARITHM_IMMVAL_LSB 10
|
||||
#define DP_IMM_ARITHM_IMMVAL_MSB 22
|
||||
#define DP_IMM_ARITHM_DEST_LSB 5
|
||||
#define DP_IMM_ARITHM_DEST_MSB 10
|
||||
#define DP_IMM_WIDEMOV_SHIFTSCALAR_LSB 21
|
||||
#define DP_IMM_WIDEMOV_SHIFTSCALAR_MSB 23
|
||||
#define DP_IMM_WIDEMOV_IMMVAL_LSB 5
|
||||
#define DP_IMM_WIDEMOV_IMMVAL_MSB 21
|
||||
|
||||
#define DP_REG_SRC1_LSB 5
|
||||
#define DP_REG_SRC1_MSB 10
|
||||
#define DP_REG_SRC2_LSB 16
|
||||
#define DP_REG_SRC2_MSB 21
|
||||
#define DP_REG_OPTYPE_LSB 28
|
||||
#define DP_REG_OPTYPE_MSB 29
|
||||
#define DP_REG_ARITHMLOGIC_ARITHMFLAG_LSB 24
|
||||
#define DP_REG_ARITHMLOGIC_ARITHMFLAG_MSB 25
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTTYPE_LSB 22
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTTYPE_MSB 24
|
||||
#define DP_REG_ARITHMLOGIC_NEGSRC2FLAG_LSB 21
|
||||
#define DP_REG_ARITHMLOGIC_NEGSRC2FLAG_MSB 22
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTAMOUNT_LSB 10
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTAMOUNT_MSB 16
|
||||
#define DP_REG_MULTIPLY_SUMMAND_LSB 10
|
||||
#define DP_REG_MULTIPLY_SUMMAND_MSB 15
|
||||
#define DP_REG_MULTIPLY_NEGPROD_LSB 15
|
||||
#define DP_REG_MULTIPLY_NEGPROD_MSB 16
|
||||
#define DP_REG_MULTIPLY_PROCESSOP 0
|
||||
#define DP_REG_MULTIPLY_ARITHMFLAG 1
|
||||
#define DP_REG_MULTIPLY_SHIFTTYPE 0
|
||||
#define DP_REG_MULTIPLY_NEGSRC2FLAG 0
|
||||
|
||||
#define SDT_OPTYPE_FLAG_LSB 31
|
||||
#define SDT_OPTYPE_FLAG_MSB 32
|
||||
#define SDT_REGTYPE_FLAG_LSB 30
|
||||
#define SDT_REGTYPE_FLAG_MSB 31
|
||||
#define SDT_TARGET_REG_LSB 0
|
||||
#define SDT_TARGET_REG_MSB 5
|
||||
|
||||
#define SDT_BASE_REG_LSB 5
|
||||
#define SDT_BASE_REG_MSB 10
|
||||
#define SDT_OFFSET_LSB 10
|
||||
#define SDT_OFFSET_MSB 22
|
||||
#define SDT_TRANSFER_TYPE_LSB 22
|
||||
#define SDT_TRANSFER_TYPE_MSB 23
|
||||
#define SDT_UNSIGNED_FLAG_LSB 24
|
||||
#define SDT_UNSIGNED_FLAG_MSB 25
|
||||
#define SDT_REGISTER_FLAG_LSB 21
|
||||
#define SDT_REGISTER_FLAG_MSB 22
|
||||
#define SDT_REGISTER_REG_LSB 16
|
||||
#define SDT_REGISTER_REG_MSB 21
|
||||
#define SDT_INDEXED_ADDRMODE_LSB 11
|
||||
#define SDT_INDEXED_ADDRMODE_MSB 12
|
||||
#define SDT_INDEXED_OFFSET_LSB 12
|
||||
#define SDT_INDEXED_OFFSET_MSB 21
|
||||
#define SDT_LOAD_LITERAL_OFFSET_LSB 5
|
||||
#define SDT_LOAD_LITERAL_OFFSET_MSB 24
|
||||
|
||||
#define BRANCH_TYPE_LSB 30
|
||||
#define BRANCH_TYPE_MSB 32
|
||||
#define BRANCH_UNCONDITIONAL_OFFSET_LSB 0
|
||||
#define BRANCH_UNCONDITIONAL_OFFSET_MSB 26
|
||||
#define BRANCH_REGISTER_SRC_LSB 5
|
||||
#define BRANCH_REGISTER_SRC_MSB 10
|
||||
#define BRANCH_CONDITIONAL_COND_LSB 0
|
||||
#define BRANCH_CONDITIONAL_COND_MSB 4
|
||||
#define BRANCH_CONDITIONAL_OFFSET_LSB 5
|
||||
#define BRANCH_CONDITIONAL_OFFSET_MSB 24
|
||||
|
||||
/************************************
|
||||
* PROTOTYPES
|
||||
************************************/
|
||||
@ -26,12 +122,10 @@ static void decodeBranch(word wrd, a64inst_instruction *inst);
|
||||
static void decodeDPRegister(word wrd, a64inst_instruction *inst);
|
||||
static void decodeSingleTransfer(word wrd, a64inst_instruction *inst);
|
||||
|
||||
/** @brief The main decode function. Takes a word (uint32_t) representing the
|
||||
* instruction and decodes it into an a64inst_instruction struct.
|
||||
* @param wrd The word (uint32_t) to be decoded in binary.
|
||||
* @return a pointer to the heap-allocated a64inst_instruction struct
|
||||
* representing the decoded instruction if successful.
|
||||
*/
|
||||
/************************************
|
||||
* FUNCTIONS
|
||||
************************************/
|
||||
|
||||
a64inst_instruction *decode(word wrd) {
|
||||
|
||||
a64inst_instruction *inst = malloc(sizeof(a64inst_instruction));
|
||||
|
||||
@ -1,96 +1,21 @@
|
||||
/** @file decode.h
|
||||
* @brief Decode Function from binary words to a special internal
|
||||
* representation of instructions, a64inst_instruction.
|
||||
*
|
||||
* This defines the decode function which takes a binary word (uint32_t) and
|
||||
* decodes it into an a64inst_instruction conveying the same information.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#include "../global.h"
|
||||
#include "../a64instruction/a64instruction.h"
|
||||
|
||||
#define HALT_WORD 0x8a000000
|
||||
|
||||
#define TYPE_ID_LSB 26
|
||||
#define TYPE_ID_MSB 29
|
||||
#define DP_IMM_ID 4
|
||||
#define BRANCH_ID 5
|
||||
|
||||
#define DP_REG_FLAG_LSB 25
|
||||
#define DP_REG_FLAG_MSB 26
|
||||
|
||||
#define DP_WIDTH_LSB 31
|
||||
#define DP_WIDTH_MSB 32
|
||||
#define DP_OP_LSB 29
|
||||
#define DP_OP_MSB 31
|
||||
#define DP_DEST_LSB 0
|
||||
#define DP_DEST_MSB 5
|
||||
|
||||
#define DP_IMM_OPTYPE_LSB 23
|
||||
#define DP_IMM_OPTYPE_MSB 26
|
||||
#define DP_IMM_OPTYPE_ARITHM 2
|
||||
#define DP_IMM_OPTYPE_WIDEMOV 5
|
||||
#define DP_IMM_ARITHM_SHIFTFLAG_LSB 22
|
||||
#define DP_IMM_ARITHM_SHIFTFLAG_MSB 23
|
||||
#define DP_IMM_ARITHM_IMMVAL_LSB 10
|
||||
#define DP_IMM_ARITHM_IMMVAL_MSB 22
|
||||
#define DP_IMM_ARITHM_DEST_LSB 5
|
||||
#define DP_IMM_ARITHM_DEST_MSB 10
|
||||
#define DP_IMM_WIDEMOV_SHIFTSCALAR_LSB 21
|
||||
#define DP_IMM_WIDEMOV_SHIFTSCALAR_MSB 23
|
||||
#define DP_IMM_WIDEMOV_IMMVAL_LSB 5
|
||||
#define DP_IMM_WIDEMOV_IMMVAL_MSB 21
|
||||
|
||||
#define DP_REG_SRC1_LSB 5
|
||||
#define DP_REG_SRC1_MSB 10
|
||||
#define DP_REG_SRC2_LSB 16
|
||||
#define DP_REG_SRC2_MSB 21
|
||||
#define DP_REG_OPTYPE_LSB 28
|
||||
#define DP_REG_OPTYPE_MSB 29
|
||||
#define DP_REG_ARITHMLOGIC_ARITHMFLAG_LSB 24
|
||||
#define DP_REG_ARITHMLOGIC_ARITHMFLAG_MSB 25
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTTYPE_LSB 22
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTTYPE_MSB 24
|
||||
#define DP_REG_ARITHMLOGIC_NEGSRC2FLAG_LSB 21
|
||||
#define DP_REG_ARITHMLOGIC_NEGSRC2FLAG_MSB 22
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTAMOUNT_LSB 10
|
||||
#define DP_REG_ARITHMLOGIC_SHIFTAMOUNT_MSB 16
|
||||
#define DP_REG_MULTIPLY_SUMMAND_LSB 10
|
||||
#define DP_REG_MULTIPLY_SUMMAND_MSB 15
|
||||
#define DP_REG_MULTIPLY_NEGPROD_LSB 15
|
||||
#define DP_REG_MULTIPLY_NEGPROD_MSB 16
|
||||
// Defines the values for fields used for arithmetic/logic DPR instructions
|
||||
// that are necessary to indicate a multiplication instruction
|
||||
#define DP_REG_MULTIPLY_PROCESSOP 0
|
||||
#define DP_REG_MULTIPLY_ARITHMFLAG 1
|
||||
#define DP_REG_MULTIPLY_SHIFTTYPE 0
|
||||
#define DP_REG_MULTIPLY_NEGSRC2FLAG 0
|
||||
|
||||
#define SDT_OPTYPE_FLAG_LSB 31
|
||||
#define SDT_OPTYPE_FLAG_MSB 32
|
||||
#define SDT_REGTYPE_FLAG_LSB 30
|
||||
#define SDT_REGTYPE_FLAG_MSB 31
|
||||
#define SDT_TARGET_REG_LSB 0
|
||||
#define SDT_TARGET_REG_MSB 5
|
||||
|
||||
#define SDT_BASE_REG_LSB 5
|
||||
#define SDT_BASE_REG_MSB 10
|
||||
#define SDT_OFFSET_LSB 10
|
||||
#define SDT_OFFSET_MSB 22
|
||||
#define SDT_TRANSFER_TYPE_LSB 22
|
||||
#define SDT_TRANSFER_TYPE_MSB 23
|
||||
#define SDT_UNSIGNED_FLAG_LSB 24
|
||||
#define SDT_UNSIGNED_FLAG_MSB 25
|
||||
#define SDT_REGISTER_FLAG_LSB 21
|
||||
#define SDT_REGISTER_FLAG_MSB 22
|
||||
#define SDT_REGISTER_REG_LSB 16
|
||||
#define SDT_REGISTER_REG_MSB 21
|
||||
#define SDT_INDEXED_ADDRMODE_LSB 11
|
||||
#define SDT_INDEXED_ADDRMODE_MSB 12
|
||||
#define SDT_INDEXED_OFFSET_LSB 12
|
||||
#define SDT_INDEXED_OFFSET_MSB 21
|
||||
#define SDT_LOAD_LITERAL_OFFSET_LSB 5
|
||||
#define SDT_LOAD_LITERAL_OFFSET_MSB 24
|
||||
|
||||
#define BRANCH_TYPE_LSB 30
|
||||
#define BRANCH_TYPE_MSB 32
|
||||
#define BRANCH_UNCONDITIONAL_OFFSET_LSB 0
|
||||
#define BRANCH_UNCONDITIONAL_OFFSET_MSB 26
|
||||
#define BRANCH_REGISTER_SRC_LSB 5
|
||||
#define BRANCH_REGISTER_SRC_MSB 10
|
||||
#define BRANCH_CONDITIONAL_COND_LSB 0
|
||||
#define BRANCH_CONDITIONAL_COND_MSB 4
|
||||
#define BRANCH_CONDITIONAL_OFFSET_LSB 5
|
||||
#define BRANCH_CONDITIONAL_OFFSET_MSB 24
|
||||
/** @brief The main decode function. Takes a word (uint32_t) representing the
|
||||
* instruction and decodes it into an a64inst_instruction struct.
|
||||
* @param wrd The word (uint32_t) to be decoded in binary.
|
||||
* @return a pointer to the heap-allocated a64inst_instruction struct
|
||||
* representing the decoded instruction if successful.
|
||||
*/
|
||||
a64inst_instruction *decode(word wrd);
|
||||
|
||||
@ -1,3 +1,11 @@
|
||||
/** @file emulator.h
|
||||
* @brief Structures to represent the state of the ARMv8 machine to be used
|
||||
* in the emulator.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#ifndef __EMULATOR__
|
||||
#define __EMULATOR__
|
||||
#include "../global.h"
|
||||
|
||||
@ -1,3 +1,14 @@
|
||||
/** @file execute.c
|
||||
* @brief Implementation of the execute function for the ARMv8 emulator.
|
||||
*
|
||||
* This defines the execute function which takes a pointer to the machine state
|
||||
* and a pointer to an a64inst_instruction struct and executes the instruction
|
||||
* updating the machine state accordingly.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "execute.h"
|
||||
@ -40,7 +51,7 @@ const executeFunction EXECUTE_FUNCTIONS[] =
|
||||
&executeBranch,
|
||||
&executeHalt};
|
||||
|
||||
// Main execute function
|
||||
|
||||
void execute(Machine *state, a64inst_instruction *inst) {
|
||||
EXECUTE_FUNCTIONS[inst->type](state, inst);
|
||||
}
|
||||
|
||||
@ -3,5 +3,11 @@
|
||||
#include "../a64instruction/a64instruction.h"
|
||||
#include "emulator.h"
|
||||
|
||||
/** @brief Executes the given instruction on the given machine state.
|
||||
* Updates the machine state to reflect the execution of the instruction.
|
||||
*
|
||||
* @param state The machine state to execute the instruction on.
|
||||
* @param inst The instruction to execute.
|
||||
*/
|
||||
void execute(Machine *state, a64inst_instruction *inst);
|
||||
#endif
|
||||
|
||||
@ -1,4 +1,13 @@
|
||||
/** Machine Util */
|
||||
/** @file machine_util.c
|
||||
* @brief Implementation of utility functions for manipulating the machine state.
|
||||
*
|
||||
* This defines utility functions for reading and writing memory and registers,
|
||||
* which are used by the emulator to execute instructions.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#include "assert.h"
|
||||
#include "machine_util.h"
|
||||
#include "../a64instruction/a64instruction_global.h"
|
||||
@ -6,7 +15,6 @@
|
||||
#include "emulator.h"
|
||||
#include "../util/binary_util.h"
|
||||
|
||||
// Returns the dword starting at address. The value is truncated if regType is a 64-bit register.
|
||||
dword readMemory(byte *memory, uint32_t address, a64inst_regType regType) {
|
||||
dword result = 0;
|
||||
int bytesPerWord = (regType == a64inst_W ? WORD_BITS : DWORD_BITS) / BYTE_BITS - 1;
|
||||
@ -20,7 +28,6 @@ dword readMemory(byte *memory, uint32_t address, a64inst_regType regType) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Store into memory starting at address the given dword.
|
||||
void storeMemory(byte *memory, uint32_t address, dword data) {
|
||||
int bytesPerDword = DWORD_BITS / BYTE_BITS - 1;
|
||||
for (int i = 0; i <= bytesPerDword; i++) {
|
||||
@ -28,9 +35,6 @@ void storeMemory(byte *memory, uint32_t address, dword data) {
|
||||
}
|
||||
}
|
||||
|
||||
// Read from processor register, ensuring that a valid register specifier is given
|
||||
// and accounting for the case where the zero register is accessed. Truncate
|
||||
// the 32 most significant bits stored in the R register when reading W register.
|
||||
dword readRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType) {
|
||||
assert(reg <= REGISTER_COUNT);
|
||||
if (reg == ZERO_REGISTER) {
|
||||
@ -40,8 +44,6 @@ dword readRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType reg
|
||||
}
|
||||
}
|
||||
|
||||
// Write to a processor register, ensuring that a valid register specifier is given
|
||||
// and truncating the value being written when it can't fit in the specified register
|
||||
void writeRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType, dword value) {
|
||||
assert(reg <= REGISTER_COUNT);
|
||||
if (reg != ZERO_REGISTER) {
|
||||
|
||||
@ -1,16 +1,55 @@
|
||||
/** @file machine_util.h
|
||||
* @brief Utility functions for manipulating the machine state.
|
||||
*
|
||||
* This defines utility functions for reading and writing memory and registers,
|
||||
* which are used by the emulator to execute instructions.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#ifndef __MACHINE_UTIL__
|
||||
#define __MACHINE_UTIL__
|
||||
#include "../global.h"
|
||||
#include "../a64instruction/a64instruction_global.h"
|
||||
#include "emulator.h"
|
||||
|
||||
|
||||
/** @brief Reads a (double) word from memory starting at the given address.
|
||||
* If regType is a64inst_W, the value is truncated to 32 bits.
|
||||
*
|
||||
* @param memory The starting address byte-addressable memory block.
|
||||
* @param address The address to read from.
|
||||
* @param regType The register type to truncate the value to if necessary.
|
||||
* @return The (double) word read from memory.
|
||||
*/
|
||||
dword readMemory(byte *memory, uint32_t address, a64inst_regType regType);
|
||||
|
||||
/** @brief Stores a double word into memory starting at the given address.
|
||||
*
|
||||
* @param memory The starting address byte-addressable memory block.
|
||||
* @param address The address to store the data at.
|
||||
* @param data The double word to store.
|
||||
*/
|
||||
void storeMemory(byte *memory, uint32_t address, dword data);
|
||||
|
||||
/** @brief Reads a register from the machine state.
|
||||
* If regType is a64inst_W, the value is truncated to 32 bits.
|
||||
*
|
||||
* @param state The machine state to read the register from.
|
||||
* @param reg The register specifier to read.
|
||||
* @param regType The register type to truncate the value to if necessary.
|
||||
* @return The value stored in the register, truncated if necessary.
|
||||
*/
|
||||
dword readRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType);
|
||||
|
||||
/** @brief Writes a value to a register in the machine state.
|
||||
* If regType is a64inst_W, the value is truncated to 32 bits.
|
||||
*
|
||||
* @param state The machine state to write the register to.
|
||||
* @param reg The register specifier to write to.
|
||||
* @param regType The register type to truncate the value to if necessary.
|
||||
* @param value The value to write to the register.
|
||||
*/
|
||||
void writeRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType, dword value);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,3 +1,14 @@
|
||||
/** @file print.c
|
||||
* @brief Implementation of functions to print the machine state.
|
||||
*
|
||||
* The function prints the current machine state, including the registers,
|
||||
* memory and condition codes. This is used to print the final state machine
|
||||
* in the emulator after all instructions have been executed.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
@ -8,13 +19,11 @@
|
||||
|
||||
#define UNSET_CONDITION_CODE_CHAR '-'
|
||||
|
||||
// Prints the current machine state into the provided stream
|
||||
void printState(Machine *state, FILE *stream) {
|
||||
printRegisters(state, stream);
|
||||
printMemory(state, stream);
|
||||
}
|
||||
|
||||
// Prints the current machine registers into the provided stream
|
||||
void printRegisters(Machine *state, FILE *stream) {
|
||||
fprintf(stream, "Registers:\n");
|
||||
for (int i = 0; i < REGISTER_COUNT; i++) {
|
||||
@ -27,7 +36,6 @@ void printRegisters(Machine *state, FILE *stream) {
|
||||
state->conditionCodes.Overflow ? 'V' : UNSET_CONDITION_CODE_CHAR);
|
||||
}
|
||||
|
||||
// Prints all non-zero memory locations into the provided stream
|
||||
void printMemory(Machine *state, FILE *stream) {
|
||||
fprintf(stream, "\nNon-zero memory:\n");
|
||||
|
||||
|
||||
@ -1,10 +1,48 @@
|
||||
/** @file print.h
|
||||
* @brief Functions to print the machine state, inc registers and memory.
|
||||
*
|
||||
* The function prints the current machine state, including the registers,
|
||||
* memory and condition codes. This is used to print the final state machine
|
||||
* in the emulator after all instructions have been executed.
|
||||
*
|
||||
* @author Saleh Bubshait
|
||||
* @author Themis Demetriades
|
||||
*/
|
||||
|
||||
#ifndef __PRINT__
|
||||
#define __PRINT__
|
||||
#include <stdio.h>
|
||||
#include "emulator.h"
|
||||
|
||||
/** @brief Prints the current machine state into the provided stream.
|
||||
*
|
||||
* @param state The machine state to print.
|
||||
* @param stream The stream to print the state to.
|
||||
*
|
||||
* @see printRegisters
|
||||
* @see printMemory
|
||||
*/
|
||||
void printState(Machine *state, FILE *stream);
|
||||
|
||||
/** @brief Prints the current machine registers into the provided stream.
|
||||
* The registers are printed in the format "Xn = value" where n is the register
|
||||
* number and value is the value stored in the register, in hexadecimal. The
|
||||
* program counter (PC) and condition codes are also printed. SP is ignored.
|
||||
*
|
||||
* @param state The machine state to print the registers of.
|
||||
* @param stream The stream to print the registers to.
|
||||
*/
|
||||
void printRegisters(Machine *state, FILE *stream);
|
||||
|
||||
/** @brief Prints all non-zero memory locations into the provided stream.
|
||||
* The memory is printed in the format "0xaddress: data" where address is the
|
||||
* memory address and data is the data stored at that address, in hexadecimal.
|
||||
* Memory locations are printed 4 bytes at a time.
|
||||
* Note. Only non-zero memory locations are printed!
|
||||
*
|
||||
* @param state The machine state to print the memory of.
|
||||
* @param stream The stream to print the memory to.
|
||||
*/
|
||||
void printMemory(Machine *state, FILE *stream);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user