all repos — mgba @ fb267a32ff4b9ff6dc8688610b936cb8450edd8e

mGBA Game Boy Advance Emulator

include/mgba/internal/arm/arm.h (view raw)

  1/* Copyright (c) 2013-2014 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#ifndef ARM_H
  7#define ARM_H
  8
  9#include <mgba-util/common.h>
 10
 11CXX_GUARD_START
 12
 13#include <mgba/core/cpu.h>
 14
 15enum {
 16	ARM_SP = 13,
 17	ARM_LR = 14,
 18	ARM_PC = 15
 19};
 20
 21enum ExecutionMode {
 22	MODE_ARM = 0,
 23	MODE_THUMB = 1
 24};
 25
 26enum PrivilegeMode {
 27	MODE_USER = 0x10,
 28	MODE_FIQ = 0x11,
 29	MODE_IRQ = 0x12,
 30	MODE_SUPERVISOR = 0x13,
 31	MODE_ABORT = 0x17,
 32	MODE_UNDEFINED = 0x1B,
 33	MODE_SYSTEM = 0x1F
 34};
 35
 36enum WordSize {
 37	WORD_SIZE_ARM = 4,
 38	WORD_SIZE_THUMB = 2
 39};
 40
 41enum ExecutionVector {
 42	BASE_RESET = 0x00000000,
 43	BASE_UNDEF = 0x00000004,
 44	BASE_SWI = 0x00000008,
 45	BASE_PABT = 0x0000000C,
 46	BASE_DABT = 0x00000010,
 47	BASE_IRQ = 0x00000018,
 48	BASE_FIQ = 0x0000001C
 49};
 50
 51enum RegisterBank {
 52	BANK_NONE = 0,
 53	BANK_FIQ = 1,
 54	BANK_IRQ = 2,
 55	BANK_SUPERVISOR = 3,
 56	BANK_ABORT = 4,
 57	BANK_UNDEFINED = 5
 58};
 59
 60enum LSMDirection {
 61	LSM_B = 1,
 62	LSM_D = 2,
 63	LSM_IA = 0,
 64	LSM_IB = 1,
 65	LSM_DA = 2,
 66	LSM_DB = 3
 67};
 68
 69struct ARMCore;
 70
 71union PSR {
 72	struct {
 73#ifdef __BIG_ENDIAN__
 74		unsigned n : 1;
 75		unsigned z : 1;
 76		unsigned c : 1;
 77		unsigned v : 1;
 78		unsigned unused : 20;
 79		unsigned i : 1;
 80		unsigned f : 1;
 81		unsigned t : 1;
 82		unsigned priv : 5;
 83#else
 84		unsigned priv : 5;
 85		unsigned t : 1;
 86		unsigned f : 1;
 87		unsigned i : 1;
 88		unsigned unused : 20;
 89		unsigned v : 1;
 90		unsigned c : 1;
 91		unsigned z : 1;
 92		unsigned n : 1;
 93#endif
 94	};
 95
 96	struct {
 97#ifdef __BIG_ENDIAN__
 98		uint8_t flags;
 99		uint8_t status;
100		uint8_t extension;
101		uint8_t control;
102#else
103		uint8_t control;
104		uint8_t extension;
105		uint8_t status;
106		uint8_t flags;
107#endif
108	};
109
110	int32_t packed;
111};
112
113struct ARMMemory {
114	uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);
115	uint32_t (*load16)(struct ARMCore*, uint32_t address, int* cycleCounter);
116	uint32_t (*load8)(struct ARMCore*, uint32_t address, int* cycleCounter);
117
118	void (*store32)(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter);
119	void (*store16)(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter);
120	void (*store8)(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter);
121
122	uint32_t (*loadMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
123	                         int* cycleCounter);
124	uint32_t (*storeMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
125	                          int* cycleCounter);
126
127	const uint32_t* activeRegion;
128	uint32_t activeMask;
129	uint32_t activeSeqCycles32;
130	uint32_t activeSeqCycles16;
131	uint32_t activeNonseqCycles32;
132	uint32_t activeNonseqCycles16;
133	int32_t (*stall)(struct ARMCore*, int32_t wait);
134	void (*setActiveRegion)(struct ARMCore*, uint32_t address);
135};
136
137struct ARMInterruptHandler {
138	void (*reset)(struct ARMCore* cpu);
139	void (*processEvents)(struct ARMCore* cpu);
140	void (*swi16)(struct ARMCore* cpu, int immediate);
141	void (*swi32)(struct ARMCore* cpu, int immediate);
142	void (*hitIllegal)(struct ARMCore* cpu, uint32_t opcode);
143	void (*bkpt16)(struct ARMCore* cpu, int immediate);
144	void (*bkpt32)(struct ARMCore* cpu, int immediate);
145	void (*readCPSR)(struct ARMCore* cpu);
146
147	void (*hitStub)(struct ARMCore* cpu, uint32_t opcode);
148};
149
150#define ARM_REGISTER_FILE struct { \
151	int32_t gprs[16]; \
152	union PSR cpsr; \
153	union PSR spsr; \
154}
155
156struct ARMRegisterFile {
157	ARM_REGISTER_FILE;
158};
159
160struct ARMCore {
161	union {
162		struct ARMRegisterFile regs;
163		ARM_REGISTER_FILE;
164	};
165
166	int32_t cycles;
167	int32_t nextEvent;
168	int halted;
169
170	int32_t bankedRegisters[6][7];
171	int32_t bankedSPSRs[6];
172
173	int32_t shifterOperand;
174	int32_t shifterCarryOut;
175
176	uint32_t prefetch[2];
177	enum ExecutionMode executionMode;
178	enum PrivilegeMode privilegeMode;
179
180	struct ARMMemory memory;
181	struct ARMInterruptHandler irqh;
182
183	struct mCPUComponent* master;
184
185	size_t numComponents;
186	struct mCPUComponent** components;
187};
188#undef ARM_REGISTER_FILE
189
190void ARMInit(struct ARMCore* cpu);
191void ARMDeinit(struct ARMCore* cpu);
192void ARMSetComponents(struct ARMCore* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras);
193void ARMHotplugAttach(struct ARMCore* cpu, size_t slot);
194void ARMHotplugDetach(struct ARMCore* cpu, size_t slot);
195
196void ARMReset(struct ARMCore* cpu);
197void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode);
198void ARMRaiseIRQ(struct ARMCore*);
199void ARMRaiseSWI(struct ARMCore*);
200void ARMRaiseUndefined(struct ARMCore*);
201
202void ARMRun(struct ARMCore* cpu);
203void ARMRunLoop(struct ARMCore* cpu);
204void ARMRunFake(struct ARMCore* cpu, uint32_t opcode);
205
206CXX_GUARD_END
207
208#endif