libElysianVMU 1.6.0
Full-featured, accurate, cross-platform library emulating the Dreamcast's Visual Memory Unit
Loading...
Searching...
No Matches
evmu_cpu.h
Go to the documentation of this file.
1/*! \file
2 * \brief EvmuCpu: Sanyo LC86k CPU Core
3 * \ingroup peripherals
4 *
5 * EvmuCpu models the main execution unit on the Potato.
6 * It provides an API for executing and fetching info on
7 * instructions.
8 *
9 * Additionally, virtual methods within EvmuCpu can be
10 * overridden to provide custom CPU and opcode implementations.
11 *
12 * \todo
13 * - secs per instruction in msec/nsec, not float
14 * - pull Rom/BIOS update out of CPU update path
15 * - implement/respect halted flags
16 * - ensure OV is set when divison by 0 occurs
17 *
18 * \copyright 2023 Falco Girgis
19 */
20#ifndef EVMU_CPU_H
21#define EVMU_CPU_H
22
23#include "../types/evmu_peripheral.h"
24#include "evmu_isa.h"
25
26#include <gimbal/meta/signals/gimbal_signal.h>
27
28/*! \name Type System
29 * \brief Type UUID and cast operators
30 * @{
31 */
32#define EVMU_CPU_TYPE (GBL_TYPEID(EvmuCpu)) //!< Type UUID for EvmuCpu
33#define EVMU_CPU(self) (GBL_CAST(EvmuCpu, self)) //!< Cast GblInstance to EvmuCpu
34#define EVMU_CPU_CLASS(klass) (GBL_CLASS_CAST(EvmuCpu, klass)) //!< Cast GblClass to EvmuCpuClass
35#define EVMU_CPU_GET_CLASS(self) (GBL_CLASSOF(EvmuCpu, self)) //!< Get EvmuCpuClass from GblInstance
36//! @}
37
38#define EVMU_CPU_NAME "cpu" //!< GblObject name for EvmCpu
39
40#define GBL_SELF_TYPE EvmuCpu
41
42GBL_DECLS_BEGIN
43
44GBL_FORWARD_DECLARE_STRUCT(EvmuCpu);
45
46//! Program counter for EvmuCpu instructions
47typedef uint16_t EvmuPc;
48
49/*! \struct EvmuCpuClass
50 * \extends EvmuPeripheralClass
51 * \brief Class for Sanyo LC86k CPU core
52 *
53 * This structure is responsible for providing the actual
54 * implementation of the LC86k back-end logic. It can be
55 * overridden within a subclass to customize.
56 *
57 * \sa EvmuCpu
58 */
59GBL_CLASS_DERIVE(EvmuCpu, EvmuPeripheral)
60 //! Virtual method for fetching instructions
61 EVMU_RESULT (*pFnFetch) (GBL_SELF,
62 EvmuPc pc,
63 EvmuInstruction* pEncoded);
64 //! Virtual method for decoding instructions
65 EVMU_RESULT (*pFnDecode) (GBL_SELF,
66 const EvmuInstruction* pEncoded,
67 EvmuDecodedInstruction* pDecoded);
68 //! Virtual method for executing instructions
69 EVMU_RESULT (*pFnExecute)(GBL_SELF,
70 const EvmuDecodedInstruction* pInstr);
71 //! Virtual method for top-level logic behind running a single instruction
72 EVMU_RESULT (*pFnRunNext)(GBL_SELF);
73GBL_CLASS_END
74
75/*! \struct EvmuCpu
76 * \extends EvmuPeripheral
77 * \ingroup peripherals
78 * \brief Sanyo LC86k CPU core
79 *
80 * EvmuCpu is an EvmuPeripheral which implements all of
81 * the logic behind and provides an API for the CPU core.
82 *
83 * In addition to managing normal program flow, it allows
84 * you to feed in individual instructions and then query
85 * for their decoded operands and opcode. It also provides
86 * a signal for when the PC changes, which can be used to
87 * implement breakpoints and instruction tracing.
88 *
89 * \sa EvmuCpuClass
90 */
91GBL_INSTANCE_DERIVE(EvmuCpu, EvmuPeripheral)
92 uint32_t halted : 1; //!< Halts CPU execution
93 uint32_t haltAfterNext : 1; //!< Halts the CPU execution after the next instruction
94 uint32_t pcChanged : 1; //!< User toggle (reset to false) which be set upon PC change
95GBL_INSTANCE_END
96
97//! \cond
98GBL_PROPERTIES(EvmuCpu,
99 (pc, GBL_GENERIC, (READ, WRITE, LOAD, SAVE), GBL_UINT16_TYPE),
100 (opcode, GBL_GENERIC, (READ), GBL_UINT8_TYPE),
101 (operand1, GBL_GENERIC, (READ), GBL_INT32_TYPE),
102 (operand2, GBL_GENERIC, (READ), GBL_INT32_TYPE),
103 (operand3, GBL_GENERIC, (READ), GBL_INT32_TYPE)
104)
105
106GBL_SIGNALS(EvmuCpu,
107 (pcChange, (GBL_INSTANCE_TYPE, pReceiver), (GBL_UINT16_TYPE, pc))
108)
109//! \endcond
110
111//! Returns the GblType UUID associated with EvmuCpu
112EVMU_EXPORT GblType EvmuCpu_type (void) GBL_NOEXCEPT;
113
114/*! \name Program Counter
115 * \brief Methods for reading and writing the PC
116 * \relatesalso EvmuCpu
117 * @{
118 */
119//! Returns the address for the program counter, which points to the next instruction
120EVMU_EXPORT EvmuPc EvmuCpu_pc (GBL_CSELF) GBL_NOEXCEPT;
121//! Sets the address of the program counter, so that it will be the next executed instruction
122EVMU_EXPORT void EvmuCpu_setPc (GBL_SELF, EvmuPc address) GBL_NOEXCEPT;
123//! @}
124
125/*! \name Instruction Info
126 * \brief Methods for querying current instruction info
127 * \relatesalso EvmuCpu
128 * @{
129 */
130//! Returns the number of seconds per instruction for the currently executing instruction
131EVMU_EXPORT double EvmuCpu_secs (GBL_CSELF) GBL_NOEXCEPT;
132//! Returns the number of cycles per instruction for the currently executing instruction
133EVMU_EXPORT size_t EvmuCpu_cycles (GBL_CSELF) GBL_NOEXCEPT;
134//! Returns the opcode of the currently executing instruction
135EVMU_EXPORT EvmuWord EvmuCpu_opcode (GBL_CSELF) GBL_NOEXCEPT;
136//! Returns the operand of the currently executing instruction at index \p idx
137EVMU_EXPORT int32_t EvmuCpu_operand (GBL_CSELF, size_t idx) GBL_NOEXCEPT;
138//! @}
139
140/*! \name Instruction Execution
141 * \brief Methods for executing instructions
142 * \relatesalso EvmuCpu
143 * @{
144 */
145//! Immediately executes an externally provided decoded instruction rather than fetching one from ROM or flash
146EVMU_EXPORT EVMU_RESULT EvmuCpu_execute (GBL_SELF,
147 const EvmuDecodedInstruction* pInstr) GBL_NOEXCEPT;
148//! Fetches and executes the next instruction, which is located at the address pointed to by the program counter
149EVMU_EXPORT EVMU_RESULT EvmuCpu_runNext (GBL_SELF) GBL_NOEXCEPT;
150//! @}
151
152GBL_DECLS_END
153
154#undef GBL_SELF_TYPE
155
156#endif // EVMU_CPU_H
#define EVMU_EXPORT
Define used for adding attributes to export public symbols.
Definition evmu_api.h:18
uint16_t EvmuPc
Program counter for EvmuCpu instructions.
Definition evmu_cpu.h:47
GblType EvmuCpu_type(void)
Returns the GblType UUID associated with EvmuCpu.
uint8_t EvmuWord
Represents a single 8-bit CPU word.
#define GBL_UINT16_TYPE
#define GBL_INT32_TYPE
#define GBL_UINT8_TYPE
#define GBL_PROPERTIES(object,...)
uintptr_t GblType
Sanyo LC86k CPU core.
Definition evmu_cpu.h:91
uint32_t haltAfterNext
Halts the CPU execution after the next instruction.
Definition evmu_cpu.h:93
void EvmuCpu_setPc(EvmuCpu *pSelf, EvmuPc address)
Sets the address of the program counter, so that it will be the next executed instruction.
uint32_t halted
Halts CPU execution.
Definition evmu_cpu.h:92
double EvmuCpu_secs(const EvmuCpu *pSelf)
Returns the number of seconds per instruction for the currently executing instruction.
EVMU_RESULT EvmuCpu_runNext(EvmuCpu *pSelf)
Fetches and executes the next instruction, which is located at the address pointed to by the program ...
int32_t EvmuCpu_operand(const EvmuCpu *pSelf, size_t idx)
Returns the operand of the currently executing instruction at index idx.
uint32_t pcChanged
User toggle (reset to false) which be set upon PC change.
Definition evmu_cpu.h:94
EVMU_RESULT EvmuCpu_execute(EvmuCpu *pSelf, const EvmuDecodedInstruction *pInstr)
Immediately executes an externally provided decoded instruction rather than fetching one from ROM or ...
EvmuWord EvmuCpu_opcode(const EvmuCpu *pSelf)
Returns the opcode of the currently executing instruction.
size_t EvmuCpu_cycles(const EvmuCpu *pSelf)
Returns the number of cycles per instruction for the currently executing instruction.
EvmuPc EvmuCpu_pc(const EvmuCpu *pSelf)
Returns the address for the program counter, which points to the next instruction.
#define GBL_CLASS_CAST(cType, klass)
#define GBL_CLASSOF(cType, self)
#define GBL_CAST(cType, self)