libElysianVMU 1.6.0
Full-featured, accurate, cross-platform library emulating the Dreamcast's Visual Memory Unit
Loading...
Searching...
No Matches
evmu_isa.h
Go to the documentation of this file.
1/*! \file
2 * \brief Instruction set, opcode, and operand info
3 *
4 * This file provides the API for everything relating to the
5 * instruction set architecture of the Sanyo LC86K:
6 * * Opcodes
7 * * Operand Info
8 * * Encoded Instructions
9 * * Decoded Instructions
10 *
11 * \author 2023 Falco Girgis
12 * \copyright MIT License
13*/
14
15#ifndef EVMU_ISA_H
16#define EVMU_ISA_H
17
18#include <stdint.h>
19#include <string.h>
20#include <gimbal/strings/gimbal_string_buffer.h>
21#include "../types/evmu_typedefs.h"
22#include "../evmu_api.h"
23
24/*! \defgroup opcodes Instruction Opcodes
25 * \brief First byte of all opcodes
26 *
27 * Collection of defines used to identify the opcode of
28 * a particular instruction by its first byte.
29 *
30 * \warning
31 * Some opcodes span a range of values and are not just
32 * a single byte value. Only use these values when
33 * encoding an instruction or when looking at a decoded
34 * instruction.
35 *
36 * \subpage instruction_ref
37 *
38 * @{
39 */
40#define EVMU_OPCODE_NOP 0x00 //!< No operation
41#define EVMU_OPCODE_BR 0x01 //!< Branch near relative address
42#define EVMU_OPCODE_LD 0x02 //!< Load direct byte to accumulator
43#define EVMU_OPCODE_LD_IND 0x04 //!< Load indirect byte to accumulator
44#define EVMU_OPCODE_CALL 0x08 //!< Near absolute subroutine call
45#define EVMU_OPCODE_CALLR 0x10 //!< Far relative subroutine call
46#define EVMU_OPCODE_BRF 0x11 //!< Branch far relative address
47#define EVMU_OPCODE_ST 0x12 //!< Store direct byte from accumulator
48#define EVMU_OPCODE_ST_IND 0x14 //!< Store indirect byte from accumulator
49#define EVMU_OPCODE_CALLF 0x20 //!< Far absolute subroutine call
50#define EVMU_OPCODE_JMPF 0x21 //!< Jump far absolute address
51#define EVMU_OPCODE_MOV 0x22 //!< Move direct data to indirect byte
52#define EVMU_OPCODE_MOV_IND 0x24 //!< Move immediate data to indirect byte
53#define EVMU_OPCODE_JMP 0x28 //!< Jump near absolute address
54#define EVMU_OPCODE_MUL 0x30 //!< Multiply accumulator and C register by B register
55#define EVMU_OPCODE_BEI 0x31 //!< Compare immediate byte to accumulator and branch near relative address if equal
56#define EVMU_OPCODE_BE 0x32 //!< Compare direct byte to accumulator and branch near relativa address if equal
57#define EVMU_OPCODE_BE_IND 0x34 //!< Compare indirect byte to accumulator and branch near relative address if equal
58#define EVMU_OPCODE_DIV 0x40 //!< Divide accumulator and C register by B register
59#define EVMU_OPCODE_BNEI 0x41 //!< Compare immediate byte to accumulator and branch near relative address if not zero
60#define EVMU_OPCODE_BNE 0x42 //!< Compare direct byte to accumulator and branch near relative address if not zero
61#define EVMU_OPCODE_BNE_IND 0x44 //!< Compare indirect byte to accumulator and branch near relative address if not zero
62#define EVMU_OPCODE_BPC 0x48 //!< Branch near relative address if direct bit is one ("positive") and clear
63#define EVMU_OPCODE_LDF 0x50 //!< Load from Flash
64#define EVMU_OPCODE_STF 0x51 //!< Store to Flash
65#define EVMU_OPCODE_DBNZ 0x52 //!< Decrement direct byte and branch near relative address if indirect byte is not zero
66#define EVMU_OPCODE_DBNZ_IND 0x54 //!< Decrement indirect byte and branch near relative address if indirect byte is not zero
67#define EVMU_OPCODE_PUSH 0x60 //!< Push direct byte to stack
68#define EVMU_OPCODE_INC 0x62 //!< Increment direct byte
69#define EVMU_OPCODE_INC_IND 0x64 //!< Increment indirect byte
70#define EVMU_OPCODE_BP 0x68 //!< Branch near relative address if direct bit is one ("positive")
71#define EVMU_OPCODE_POP 0x70 //!< Pop direct byte from stack
72#define EVMU_OPCODE_DEC 0x72 //!< Decrement direct byte
73#define EVMU_OPCODE_DEC_IND 0x74 //!< Decrement indirect byte
74#define EVMU_OPCODE_BZ 0x80 //!< Branch near relative address if accumulator is zero
75#define EVMU_OPCODE_ADDI 0x81 //!< Add immediate byte to accumulator
76#define EVMU_OPCODE_ADD 0x82 //!< Add direct byte to accumulator
77#define EVMU_OPCODE_ADD_IND 0x84 //!< Add indirect byte to accumulator
78#define EVMU_OPCODE_BN 0x88 //!< Branch near relative address if direct bit is zero ("negative")
79#define EVMU_OPCODE_BNZ 0x90 //!< Branch near relative address if accumulator is not zero
80#define EVMU_OPCODE_ADDCI 0x91 //!< Add imediate byte and carry flag to accumulator
81#define EVMU_OPCODE_ADDC 0x92 //!< Add direct byte and carry flag to accumulator
82#define EVMU_OPCODE_ADDC_IND 0x94 //!< Add indirect byte and carry flag to accumualtor
83#define EVMU_OPCODE_RET 0xa0 //!< Return from subroutine
84#define EVMU_OPCODE_SUBI 0xa1 //!< Subtract immediate byte from accumulator
85#define EVMU_OPCODE_SUB 0xa2 //!< Subtract direct byte from accumulator
86#define EVMU_OPCODE_SUB_IND 0xa4 //!< Subtract indirect byte from accumulator
87#define EVMU_OPCODE_NOT1 0xa8 //!< Not direct bit
88#define EVMU_OPCODE_RETI 0xb0 //!< Return from interrupt
89#define EVMU_OPCODE_SUBCI 0xb1 //!< Subtract immediate byte and carry flag from accumulator
90#define EVMU_OPCODE_SUBC 0xb2 //!< Subtract direct byte and carry flag from accumulator
91#define EVMU_OPCODE_SUBC_IND 0xb4 //!< Subtract indirect byte and carry flag from accumulator
92#define EVMU_OPCODE_ROR 0xc0 //!< Rotate accumulator right
93#define EVMU_OPCODE_LDC 0xc1 //!< Load code byte relative to TRR to accumulator
94#define EVMU_OPCODE_XCH 0xc2 //!< Exchange direct byte with accumulator
95#define EVMU_OPCODE_XCH_IND 0xc4 //!< Exchange indirect byte with accumulator
96#define EVMU_OPCODE_CLR1 0xc8 //!< Clear direct bit
97#define EVMU_OPCODE_RORC 0xd0 //!< Rotate accumulator right through the carry flag
98#define EVMU_OPCODE_ORI 0xd1 //!< OR immediate byte to accumulator
99#define EVMU_OPCODE_OR 0xd2 //!< OR direct byte to accumulator
100#define EVMU_OPCODE_OR_IND 0xd4 //!< OR indirect byte to accumulator
101#define EVMU_OPCODE_ROL 0xe0 //!< Rotate accumulator left
102#define EVMU_OPCODE_ANDI 0xe1 //!< AND immediate byte to accumulator
103#define EVMU_OPCODE_AND 0xe2 //!< AND direct byte to accumulator
104#define EVMU_OPCODE_AND_IND 0xe4 //!< AND indirect byte to accumulator
105#define EVMU_OPCODE_SET1 0xe8 //!< Set direct bit
106#define EVMU_OPCODE_ROLC 0xf0 //!< Rotate accumulator left through carry flag
107#define EVMU_OPCODE_XORI 0xf1 //!< XOR immediate byte to accumulator
108#define EVMU_OPCODE_XOR 0xf2 //!< XOR direct byte to accumulator
109#define EVMU_OPCODE_XOR_IND 0xf4 //!< XOR indirect byte to accumulator
110//! @}
111
112/*! \name Program Status Word Flags
113 * \brief Flags which may be modified by a particular instruction
114 * @{
115 */
116#define EVMU_ISA_PSW_SYSTEM_POS 3 //!< System bit
117#define EVMU_ISA_PSW_SYSTEM_MASK 0x8 //!< System mask
118#define EVMU_ISA_PSW_CY_POS 2 //!< Carry bit
119#define EVMU_ISA_PSW_CY_MASK 0x4 //!< Carry mask
120#define EVMU_ISA_PSW_AC_POS 1 //!< Auxiliary carry bit
121#define EVMU_ISA_PSW_AC_MASK 0x2 //!< Auxiliary carry mask
122#define EVMU_ISA_PSW_OV_POS 0 //!< Overflow bit
123#define EVMU_ISA_PSW_OV_MASK 0x1 //!< Overflow mask
124#define EVMU_ISA_PSW_NONE 0x0 //!< No PSW flags effected
125// @}
126
127/*! \name Argument Packs
128 * \brief Macros for handling packed argument types
129 * @{
130 */
131//! Packs the given argument types into an EvmuIsaArgFormat
132#define EVMU_ISA_ARG_FORMAT_PACK(...)
133 GBL_VA_OVERLOAD_CALL(EVMU_ISA_ARG_FORMAT_PACK, GBL_VA_OVERLOAD_SUFFIXER_ARGC, __VA_ARGS__)
134
135//! Unpacks the given field from the EvmuIsaArgFormat provided as argFormat
136#define EVMU_ISA_ARG_FORMAT_UNPACK(argFormat, field)
137 ((argFormat >> (field * 8u)) & 0xff)
138
139//! Returns the number of arguments encoded within an EvmuIsaArgFormat
140#define EVMU_ISA_ARGC(argFmt)
141 ((uint8_t)(EVMU_ISA_ARG_FORMAT_UNPACK(argFmt, EVMU_ISA_ARG1) != EVMU_ISA_ARG_TYPE_NONE) +
142 (uint8_t)(EVMU_ISA_ARG_FORMAT_UNPACK(argFmt, EVMU_ISA_ARG2) != EVMU_ISA_ARG_TYPE_NONE) +
143 (uint8_t)(EVMU_ISA_ARG_FORMAT_UNPACK(argFmt, EVMU_ISA_ARG3) != EVMU_ISA_ARG_TYPE_NONE))
144//! @}
145
146GBL_DECLS_BEGIN
147
148//! Flags type for EvmuInstructionFormat::flags
149typedef uint32_t EvmuIsaFlags;
150
151//! Type for holding encoded instruction argument types in EvmuInstructionFormat::args
152typedef uint32_t EvmuIsaArgFormat;
153
154// ==== ARGS =======
155
156//! Enumeration with every type of instruction argument
157typedef enum EVMU_ISA_ARG_TYPE {
158 EVMU_ISA_ARG_TYPE_NONE, //!< No Argument
159 EVMU_ISA_ARG_TYPE_RELATIVE_8, //!< 8-bit relative address
160 EVMU_ISA_ARG_TYPE_RELATIVE_16, //!< 16-bit relative address
161 EVMU_ISA_ARG_TYPE_IMMEDIATE_8, //!< 8-bit immediate value
162 EVMU_ISA_ARG_TYPE_DIRECT_9, //!< 9-bit direct address
163 EVMU_ISA_ARG_TYPE_INDIRECT_2, //!< 2-bit indirection mode
164 EVMU_ISA_ARG_TYPE_ABSOLUTE_12, //!< 12-bit absolute address
165 EVMU_ISA_ARG_TYPE_ABSOLUTE_16, //!< 16-bit absolute address
166 EVMU_ISA_ARG_TYPE_BIT_3, //!< 3-bit bit position
167 EVMU_ISA_ARG_TYPE_COUNT //!< Number of different types
168} EVMU_ISA_ARG_TYPE;
169
170//! Enumeration for each argument position in an EvmuIaArgFormat
171typedef enum EVMU_ISA_ARG {
172 EVMU_ISA_ARG1, //!< First argument
173 EVMU_ISA_ARG2, //!< Second argument
174 EVMU_ISA_ARG3, //!< Third argument
175 EVMU_ISA_ARG_COUNT //!< Size of argument pack
176} EVMU_ISA_ARG;
177
178/*! Structrure describing the format of each type of instruction
179 *
180 * EvmuInstructionFormat describes for the EvmuCpu core what the
181 * layout of each type of instruction is. It also contains
182 * useful metadata for other tools.
183 *
184 * \sa EvmuIsa_format()
185 */
186typedef struct EvmuInstructionFormat {
187 const char* pMnemonic; //!< ASM instruction
188 const char* pDesc; //!< Instruction description
189 uint8_t opcode; //!< Opcode
190 uint8_t opBits; //!< Bits for opcode (8 max)
191 EvmuIsaArgFormat args; //!< Operand arguments
192 uint8_t bytes; //!< Bytes per instruction (1-3)
193 uint8_t cc; //!< Clock cycles (1-7)
194 EvmuIsaFlags flags; //!< Program status word modifiers (CY, AC, DV)
195} EvmuInstructionFormat;
196
197//! Enumeration containing each byte within an encoded EvmuInstruction
199 EVMU_INSTRUCTION_BYTE_OPCODE, //!< First byte of an encoded instruction (opcode)
200 EVMU_INSTRUCTION_BYTE_2, //!< Second byte of an encoded instruction (if present)
201 EVMU_INSTRUCTION_BYTE_3, //!< Third byte of an encoded instruction (if present)
202 EVMU_INSTRUCTION_BYTE_MAX = 0x4 //!< Maximum number of bytes in an encoded instruction (1 for padding)
203} EVMU_INSTRUCTION_BYTE;
204
205//! Contains a collection of bytes, representing an encoded instruction
206typedef struct EvmuInstruction {
207 uint8_t bytes[EVMU_INSTRUCTION_BYTE_MAX]; //!< Raw instruction byte data
208 uint8_t byteCount; //!< Byte size of instruciton data
209} EvmuInstruction;
210
211//! Contains the decoded operands of an instruction
212typedef struct EvmuOperands {
213 union {
214 uint16_t absolute; //!< 12 or 16-bit absolute address
215 uint16_t relative16; //!< 16-bit relative address
216 uint16_t direct; //!< 9-bit direct address
217 };
218 uint8_t bit; //!< 3-bit bit offset
219 uint8_t indirect; //!< 2-bit indirection mode
220 int8_t relative8; //!< 8-bit relative address
221 uint8_t immediate; //!< 8-bit immediate data
222} EvmuOperands;
223
224//! Represents an instruction which has been decoded
226 EvmuOperands operands; //!< Decoded operands
227 EvmuWord opcode; //!< Opcode byte (see \ref opcodes)
228} EvmuDecodedInstruction;
229
230//! Fetches information on an instruction from the internal database
231EVMU_EXPORT const EvmuInstructionFormat*
232 EvmuIsa_format (EvmuWord firstByte) GBL_NOEXCEPT;
233
234//! Fetches an encoded instruction from a buffer
235EVMU_EXPORT EVMU_RESULT EvmuIsa_fetch (EvmuInstruction* pEncoded,
236 const void* pBuffer,
237 size_t* pBytes) GBL_NOEXCEPT;
238
239//! Decodes an instruction into an EvmuDecodedInstruction
240EVMU_EXPORT EVMU_RESULT EvmuIsa_decode (const EvmuInstruction* pEncoded,
241 EvmuDecodedInstruction* pDecoded) GBL_NOEXCEPT;
242
243GBL_DECLS_END
244
245//! \cond
246#define EVMU_ISA_ARG_FORMAT_PACK_3(arg1, arg2, arg3)
247 ((EvmuIsaArgFormat)
248 (((EvmuIsaArgFormat)arg1 & 0xffu) << ((EvmuIsaArgFormat)EVMU_ISA_ARG1 * 8)) |
249 (((EvmuIsaArgFormat)arg2 & 0xffu) << ((EvmuIsaArgFormat)EVMU_ISA_ARG2 * 8)) |
250 (((EvmuIsaArgFormat)arg3 & 0xffu) << ((EvmuIsaArgFormat)EVMU_ISA_ARG3 * 8)))
251
252#define EVMU_ISA_ARG_FORMAT_PACK_2(a, b) (EVMU_ISA_ARG_FORMAT_PACK_3(a, b, EVMU_ISA_ARG_TYPE_NONE))
253
254#define EVMU_ISA_ARG_FORMAT_PACK_1(a) (EVMU_ISA_ARG_FORMAT_PACK_2(a, EVMU_ISA_ARG_TYPE_NONE))
255//! \endcond
256
257#endif // EVMU_ISA_H
#define EVMU_EXPORT
Define used for adding attributes to export public symbols.
Definition evmu_api.h:18
#define EVMU_ISA_ARG_FORMAT_UNPACK(argFormat, field)
Unpacks the given field from the EvmuIsaArgFormat provided as argFormat.
Definition evmu_isa.h:136
EVMU_ISA_ARG
Enumeration for each argument position in an EvmuIaArgFormat.
Definition evmu_isa.h:171
@ EVMU_ISA_ARG2
Second argument.
Definition evmu_isa.h:173
@ EVMU_ISA_ARG3
Third argument.
Definition evmu_isa.h:174
@ EVMU_ISA_ARG1
First argument.
Definition evmu_isa.h:172
@ EVMU_ISA_ARG_COUNT
Size of argument pack.
Definition evmu_isa.h:175
EVMU_ISA_ARG_TYPE
Enumeration with every type of instruction argument.
Definition evmu_isa.h:157
@ EVMU_ISA_ARG_TYPE_INDIRECT_2
2-bit indirection mode
Definition evmu_isa.h:163
@ EVMU_ISA_ARG_TYPE_BIT_3
3-bit bit position
Definition evmu_isa.h:166
@ EVMU_ISA_ARG_TYPE_COUNT
Number of different types.
Definition evmu_isa.h:167
@ EVMU_ISA_ARG_TYPE_ABSOLUTE_12
12-bit absolute address
Definition evmu_isa.h:164
@ EVMU_ISA_ARG_TYPE_DIRECT_9
9-bit direct address
Definition evmu_isa.h:162
@ EVMU_ISA_ARG_TYPE_ABSOLUTE_16
16-bit absolute address
Definition evmu_isa.h:165
@ EVMU_ISA_ARG_TYPE_RELATIVE_16
16-bit relative address
Definition evmu_isa.h:160
@ EVMU_ISA_ARG_TYPE_RELATIVE_8
8-bit relative address
Definition evmu_isa.h:159
@ EVMU_ISA_ARG_TYPE_NONE
No Argument.
Definition evmu_isa.h:158
@ EVMU_ISA_ARG_TYPE_IMMEDIATE_8
8-bit immediate value
Definition evmu_isa.h:161
uint32_t EvmuIsaFlags
Flags type for EvmuInstructionFormat::flags.
Definition evmu_isa.h:149
const EvmuInstructionFormat * EvmuIsa_format(EvmuWord firstByte)
Fetches information on an instruction from the internal database.
EVMU_RESULT EvmuIsa_fetch(EvmuInstruction *pEncoded, const void *pBuffer, size_t *pBytes)
Fetches an encoded instruction from a buffer.
EVMU_RESULT EvmuIsa_decode(const EvmuInstruction *pEncoded, EvmuDecodedInstruction *pDecoded)
Decodes an instruction into an EvmuDecodedInstruction.
#define EVMU_ISA_ARG_FORMAT_PACK(...)
Packs the given argument types into an EvmuIsaArgFormat.
Definition evmu_isa.h:132
EVMU_INSTRUCTION_BYTE
Enumeration containing each byte within an encoded EvmuInstruction.
Definition evmu_isa.h:198
@ EVMU_INSTRUCTION_BYTE_OPCODE
First byte of an encoded instruction (opcode)
Definition evmu_isa.h:199
@ EVMU_INSTRUCTION_BYTE_2
Second byte of an encoded instruction (if present)
Definition evmu_isa.h:200
@ EVMU_INSTRUCTION_BYTE_MAX
Maximum number of bytes in an encoded instruction (1 for padding)
Definition evmu_isa.h:202
@ EVMU_INSTRUCTION_BYTE_3
Third byte of an encoded instruction (if present)
Definition evmu_isa.h:201
uint32_t EvmuIsaArgFormat
Type for holding encoded instruction argument types in EvmuInstructionFormat::args.
Definition evmu_isa.h:152
uint8_t EvmuWord
Represents a single 8-bit CPU word.
Represents an instruction which has been decoded.
Definition evmu_isa.h:225
EvmuWord opcode
Opcode byte (see Instruction Opcodes)
Definition evmu_isa.h:227
EvmuOperands operands
Decoded operands.
Definition evmu_isa.h:226
Structrure describing the format of each type of instruction.
Definition evmu_isa.h:186
uint8_t opBits
Bits for opcode (8 max)
Definition evmu_isa.h:190
uint8_t opcode
Opcode.
Definition evmu_isa.h:189
const char * pDesc
Instruction description.
Definition evmu_isa.h:188
EvmuIsaFlags flags
Program status word modifiers (CY, AC, DV)
Definition evmu_isa.h:194
uint8_t bytes
Bytes per instruction (1-3)
Definition evmu_isa.h:192
EvmuIsaArgFormat args
Operand arguments.
Definition evmu_isa.h:191
const char * pMnemonic
ASM instruction.
Definition evmu_isa.h:187
uint8_t cc
Clock cycles (1-7)
Definition evmu_isa.h:193
Contains a collection of bytes, representing an encoded instruction.
Definition evmu_isa.h:206
uint8_t byteCount
Byte size of instruciton data.
Definition evmu_isa.h:208
uint8_t bytes[EVMU_INSTRUCTION_BYTE_MAX]
Raw instruction byte data.
Definition evmu_isa.h:207
Contains the decoded operands of an instruction.
Definition evmu_isa.h:212
uint16_t direct
9-bit direct address
Definition evmu_isa.h:216
uint8_t immediate
8-bit immediate data
Definition evmu_isa.h:221
uint16_t absolute
12 or 16-bit absolute address
Definition evmu_isa.h:214
uint8_t bit
3-bit bit offset
Definition evmu_isa.h:218
uint16_t relative16
16-bit relative address
Definition evmu_isa.h:215
int8_t relative8
8-bit relative address
Definition evmu_isa.h:220
uint8_t indirect
2-bit indirection mode
Definition evmu_isa.h:219