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