include/mgba/internal/sm83/sm83.h (view raw)
1/* Copyright (c) 2013-2016 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 SM83_H
7#define SM83_H
8
9#include <mgba-util/common.h>
10
11CXX_GUARD_START
12
13#include <mgba/core/cpu.h>
14#include <mgba/internal/sm83/isa-sm83.h>
15
16struct SM83Core;
17
18#pragma pack(push, 1)
19union FlagRegister {
20 struct {
21#ifdef __BIG_ENDIAN__
22 unsigned z : 1;
23 unsigned n : 1;
24 unsigned h : 1;
25 unsigned c : 1;
26 unsigned unused : 4;
27#else
28 unsigned unused : 4;
29 unsigned c : 1;
30 unsigned h : 1;
31 unsigned n : 1;
32 unsigned z : 1;
33#endif
34 };
35
36 uint8_t packed;
37};
38#pragma pack(pop)
39
40enum SM83ExecutionState {
41 SM83_CORE_FETCH = 3,
42 SM83_CORE_IDLE_0 = 0,
43 SM83_CORE_IDLE_1 = 1,
44 SM83_CORE_EXECUTE = 2,
45
46 SM83_CORE_MEMORY_LOAD = 7,
47 SM83_CORE_MEMORY_STORE = 11,
48 SM83_CORE_READ_PC = 15,
49 SM83_CORE_STALL = 19,
50 SM83_CORE_OP2 = 23,
51 SM83_CORE_HALT_BUG = 27,
52};
53struct SM83Memory {
54 uint8_t (*cpuLoad8)(struct SM83Core*, uint16_t address);
55 uint8_t (*load8)(struct SM83Core*, uint16_t address);
56 void (*store8)(struct SM83Core*, uint16_t address, int8_t value);
57
58 int (*currentSegment)(struct SM83Core*, uint16_t address);
59
60 const uint8_t* activeRegion;
61 uint16_t activeMask;
62 uint16_t activeRegionEnd;
63 void (*setActiveRegion)(struct SM83Core*, uint16_t address);
64};
65
66struct SM83InterruptHandler {
67 void (*reset)(struct SM83Core* cpu);
68 void (*processEvents)(struct SM83Core* cpu);
69 void (*setInterrupts)(struct SM83Core* cpu, bool enable);
70 uint16_t (*irqVector)(struct SM83Core* cpu);
71 void (*halt)(struct SM83Core* cpu);
72 void (*stop)(struct SM83Core* cpu);
73
74 void (*hitIllegal)(struct SM83Core* cpu);
75};
76
77#ifdef __BIG_ENDIAN__
78#define SM83_REGISTER_PAIR(HIGH, LOW) union { \
79 struct { \
80 uint8_t HIGH; \
81 uint8_t LOW; \
82 }; \
83 uint16_t HIGH ## LOW; \
84 }
85
86#define SM83_AF_REGISTER union { \
87 struct { \
88 uint8_t a; \
89 union FlagRegister f; \
90 }; \
91 uint16_t af; \
92 }
93#else
94#define SM83_REGISTER_PAIR(HIGH, LOW) union { \
95 struct { \
96 uint8_t LOW; \
97 uint8_t HIGH; \
98 }; \
99 uint16_t HIGH ## LOW; \
100 }
101
102#define SM83_AF_REGISTER union { \
103 struct { \
104 union FlagRegister f; \
105 uint8_t a; \
106 }; \
107 uint16_t af; \
108 }
109#endif
110
111#define SM83_REGISTER_FILE struct { \
112 SM83_AF_REGISTER; \
113 SM83_REGISTER_PAIR(b, c); \
114 SM83_REGISTER_PAIR(d, e); \
115 SM83_REGISTER_PAIR(h, l); \
116 uint16_t sp; \
117 uint16_t pc; \
118}
119
120struct SM83RegisterFile {
121#pragma pack(push, 1)
122 SM83_REGISTER_FILE;
123#pragma pack(pop)
124};
125
126struct SM83Core {
127#pragma pack(push, 1)
128 union {
129 struct SM83RegisterFile regs;
130 SM83_REGISTER_FILE;
131 };
132#pragma pack(pop)
133
134 uint16_t index;
135
136 int32_t cycles;
137 int32_t nextEvent;
138 enum SM83ExecutionState executionState;
139 bool halted;
140
141 uint8_t bus;
142 bool condition;
143 SM83Instruction instruction;
144
145 bool irqPending;
146
147 struct SM83Memory memory;
148 struct SM83InterruptHandler irqh;
149
150 struct mCPUComponent* master;
151
152 size_t numComponents;
153 struct mCPUComponent** components;
154};
155#undef SM83_REGISTER_FILE
156
157void SM83Init(struct SM83Core* cpu);
158void SM83Deinit(struct SM83Core* cpu);
159void SM83SetComponents(struct SM83Core* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras);
160void SM83HotplugAttach(struct SM83Core* cpu, size_t slot);
161void SM83HotplugDetach(struct SM83Core* cpu, size_t slot);
162
163void SM83Reset(struct SM83Core* cpu);
164void SM83RaiseIRQ(struct SM83Core* cpu);
165
166void SM83Tick(struct SM83Core* cpu);
167void SM83Run(struct SM83Core* cpu);
168
169CXX_GUARD_END
170
171#endif