all repos — mgba @ 73d32e7cc700ced48b747cbbf3c57eaefd7b4643

mGBA Game Boy Advance Emulator

src/arm/arm.h (view raw)

  1#ifndef ARM_H
  2#define ARM_H
  3
  4#include <stdint.h>
  5
  6#ifdef __POWERPC__
  7#define LOAD_32(DEST, ADDR, ARR) asm("lwbrx %0, %1, %2" : "=r"(DEST) : "r"(ADDR), "r"(ARR))
  8#define LOAD_16(DEST, ADDR, ARR) asm("lhbrx %0, %1, %2" : "=r"(DEST) : "r"(ADDR), "r"(ARR))
  9#define STORE_32(SRC, ADDR, ARR) asm("stwbrx %0, %1, %2" : : "r"(SRC), "r"(ADDR), "r"(ARR))
 10#define STORE_16(SRC, ADDR, ARR) asm("sthbrx %0, %1, %2" : : "r"(SRC), "r"(ADDR), "r"(ARR))
 11#else
 12#define LOAD_32(DEST, ADDR, ARR) DEST = ((uint32_t*) ARR)[(ADDR) >> 2]
 13#define LOAD_16(DEST, ADDR, ARR) DEST = ((uint16_t*) ARR)[(ADDR) >> 1]
 14#define STORE_32(SRC, ADDR, ARR) ((uint32_t*) ARR)[(ADDR) >> 2] = SRC
 15#define STORE_16(SRC, ADDR, ARR) ((uint16_t*) ARR)[(ADDR) >> 1] = SRC
 16#endif
 17
 18enum {
 19	ARM_SP = 13,
 20	ARM_LR = 14,
 21	ARM_PC = 15
 22};
 23
 24enum ExecutionMode {
 25	MODE_ARM = 0,
 26	MODE_THUMB = 1
 27};
 28
 29enum PrivilegeMode {
 30	MODE_USER = 0x10,
 31	MODE_FIQ = 0x11,
 32	MODE_IRQ = 0x12,
 33	MODE_SUPERVISOR = 0x13,
 34	MODE_ABORT = 0x17,
 35	MODE_UNDEFINED = 0x1B,
 36	MODE_SYSTEM = 0x1F
 37};
 38
 39enum WordSize {
 40	WORD_SIZE_ARM = 4,
 41	WORD_SIZE_THUMB = 2
 42};
 43
 44enum ExecutionVector {
 45	BASE_RESET = 0x00000000,
 46	BASE_UNDEF = 0x00000004,
 47	BASE_SWI = 0x00000008,
 48	BASE_PABT = 0x0000000C,
 49	BASE_DABT = 0x00000010,
 50	BASE_IRQ = 0x00000018,
 51	BASE_FIQ = 0x0000001C
 52};
 53
 54enum RegisterBank {
 55	BANK_NONE = 0,
 56	BANK_FIQ = 1,
 57	BANK_IRQ = 2,
 58	BANK_SUPERVISOR = 3,
 59	BANK_ABORT = 4,
 60	BANK_UNDEFINED = 5
 61};
 62
 63struct ARMCore;
 64
 65union PSR {
 66	struct {
 67#ifdef __POWERPC__
 68		unsigned n : 1;
 69		unsigned z : 1;
 70		unsigned c : 1;
 71		unsigned v : 1;
 72		unsigned : 20;
 73		unsigned i : 1;
 74		unsigned f : 1;
 75		enum ExecutionMode t : 1;
 76		enum PrivilegeMode priv : 5;
 77#else
 78		enum PrivilegeMode priv : 5;
 79		enum ExecutionMode t : 1;
 80		unsigned f : 1;
 81		unsigned i : 1;
 82		unsigned : 20;
 83		unsigned v : 1;
 84		unsigned c : 1;
 85		unsigned z : 1;
 86		unsigned n : 1;
 87#endif
 88	};
 89
 90	int32_t packed;
 91};
 92
 93struct ARMMemory {
 94	int32_t (*load32)(struct ARMMemory*, uint32_t address, int* cycleCounter);
 95	int16_t (*load16)(struct ARMMemory*, uint32_t address, int* cycleCounter);
 96	uint16_t (*loadU16)(struct ARMMemory*, uint32_t address, int* cycleCounter);
 97	int8_t (*load8)(struct ARMMemory*, uint32_t address, int* cycleCounter);
 98	uint8_t (*loadU8)(struct ARMMemory*, uint32_t address, int* cycleCounter);
 99
100	void (*store32)(struct ARMMemory*, uint32_t address, int32_t value, int* cycleCounter);
101	void (*store16)(struct ARMMemory*, uint32_t address, int16_t value, int* cycleCounter);
102	void (*store8)(struct ARMMemory*, uint32_t address, int8_t value, int* cycleCounter);
103
104	uint32_t* activeRegion;
105	uint32_t activeMask;
106	uint32_t activePrefetchCycles32;
107	uint32_t activePrefetchCycles16;
108	uint32_t activeNonseqCycles32;
109	uint32_t activeNonseqCycles16;
110	void (*setActiveRegion)(struct ARMMemory*, uint32_t address);
111	int (*waitMultiple)(struct ARMMemory*, uint32_t startAddress, int count);
112};
113
114struct ARMBoard {
115	struct ARMCore* cpu;
116	void (*reset)(struct ARMBoard* board);
117	void (*processEvents)(struct ARMBoard* board);
118	void (*swi16)(struct ARMBoard* board, int immediate);
119	void (*swi32)(struct ARMBoard* board, int immediate);
120	void (*hitIllegal)(struct ARMBoard* board, uint32_t opcode);
121	void (*readCPSR)(struct ARMBoard* board);
122
123	void (*hitStub)(struct ARMBoard* board, uint32_t opcode);
124};
125
126struct ARMCore {
127	int32_t gprs[16];
128	union PSR cpsr;
129	union PSR spsr;
130
131	int32_t cycles;
132	int32_t nextEvent;
133
134	int32_t bankedRegisters[6][7];
135	int32_t bankedSPSRs[6];
136
137	int32_t shifterOperand;
138	int32_t shifterCarryOut;
139
140	uint32_t currentPC;
141	enum ExecutionMode executionMode;
142	enum PrivilegeMode privilegeMode;
143
144	struct ARMMemory* memory;
145	struct ARMBoard* board;
146
147	int64_t absoluteCycles;
148	int32_t lastCycles;
149};
150
151void ARMInit(struct ARMCore* cpu);
152void ARMAssociateMemory(struct ARMCore* cpu, struct ARMMemory* memory);
153void ARMAssociateBoard(struct ARMCore* cpu, struct ARMBoard* board);
154
155void ARMReset(struct ARMCore* cpu);
156void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode);
157void ARMRaiseIRQ(struct ARMCore*);
158void ARMRaiseSWI(struct ARMCore*);
159
160void ARMRun(struct ARMCore* cpu);
161
162#endif