all repos — mgba @ d156e48da2719e69b71a2a1a82e82d6aa6fbe18d

mGBA Game Boy Advance Emulator

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#if defined(__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