#pragma once #define VCPU_FREQ 600 #define DTST_FREQ 60 #define SCREEN_FREQ 60 #define REG_FLAG 0xF /** * @brief Store the entire VCPU state * */ typedef struct VCPU_State { /// @brief Program Counter (16 bits but only 12 bits used (4096 memory addresses)) unsigned short PC; /// @brief Index register (16 bits but only 12 bits used (4096 memory addresses)) unsigned short I; /// @brief Stack register (16 bits) unsigned short S; unsigned short stack[100]; // Emulated stack /// @brief General purpose registers (8 bits each) unsigned char V[16]; // Note last one often used as a flag register /// @brief Delay timer (8 bits) unsigned char DT; /// @brief Sound timer (8 bits) unsigned char ST; /// @brief Intruction (opcode + decoded fields) unsigned short opcode; unsigned char X; unsigned char Y; unsigned char N; unsigned char NN; unsigned short NNN; /// @brief Keypressed int keypressed; // Not 0 if a key was pressed unsigned char key; /// @brief Count VCPU ticks int dt_ticks; int st_ticks; int screen_ticks; } VCPU_State; /** * @brief Must be called first! * */ void VCPUInit(); /** * @brief Fetch instruction from memory * */ void VCPUFetch(); /** * @brief Decode instruction from the last fetch * */ void VCPUDecode(); /** * @brief Execute decode instruction * */ void VCPUExecute(); /** * @brief Fetch, decode and execute an instruction * */ void VCPUTick(); /** * @brief Simple (a bit) binary to BCD convertion * * @param x * @param u * @param t * @param h */ void VCPUDoubleDabble(unsigned char x, unsigned char *u, unsigned char *t, unsigned char *h); /** * @brief Dump VCPU state * */ void VCPUDump();