diff options
Diffstat (limited to 'apps/codecs/libgme/gb_cpu.h')
-rw-r--r-- | apps/codecs/libgme/gb_cpu.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/apps/codecs/libgme/gb_cpu.h b/apps/codecs/libgme/gb_cpu.h new file mode 100644 index 0000000000..3a3b1d6101 --- /dev/null +++ b/apps/codecs/libgme/gb_cpu.h | |||
@@ -0,0 +1,80 @@ | |||
1 | // Nintendo Game Boy CPU emulator | ||
2 | |||
3 | // Game_Music_Emu 0.6-pre | ||
4 | #ifndef GB_CPU_H | ||
5 | #define GB_CPU_H | ||
6 | |||
7 | #include "blargg_common.h" | ||
8 | #include "blargg_source.h" | ||
9 | |||
10 | typedef int addr_t; | ||
11 | |||
12 | // Emulator reads this many bytes past end of a page | ||
13 | enum { cpu_padding = 8 }; | ||
14 | enum { mem_size = 0x10000 }; | ||
15 | enum { page_bits = 13 }; | ||
16 | enum { page_size = 1 << page_bits }; | ||
17 | enum { page_count = mem_size >> page_bits }; | ||
18 | |||
19 | // Game Boy Z-80 registers. NOT kept updated during emulation. | ||
20 | struct core_regs_t { | ||
21 | uint16_t bc, de, hl, fa; | ||
22 | }; | ||
23 | |||
24 | struct registers_t { | ||
25 | int pc; // more than 16 bits to allow overflow detection | ||
26 | uint16_t sp; | ||
27 | |||
28 | struct core_regs_t rp; | ||
29 | }; | ||
30 | |||
31 | struct cpu_state_t { | ||
32 | byte* code_map [page_count + 1]; | ||
33 | int time; | ||
34 | }; | ||
35 | |||
36 | struct Gb_Cpu { | ||
37 | // Base address for RST vectors, to simplify GBS player (normally 0) | ||
38 | addr_t rst_base; | ||
39 | |||
40 | struct registers_t r; | ||
41 | struct cpu_state_t* cpu_state; // points to state_ or a local copy within run() | ||
42 | struct cpu_state_t cpu_state_; | ||
43 | }; | ||
44 | |||
45 | // Initializes Gb cpu | ||
46 | static inline void Cpu_init( struct Gb_Cpu* this ) | ||
47 | { | ||
48 | this->rst_base = 0; | ||
49 | this->cpu_state = &this->cpu_state_; | ||
50 | } | ||
51 | |||
52 | // Clears registers and map all pages to unmapped | ||
53 | void Cpu_reset( struct Gb_Cpu* this, void* unmapped ); | ||
54 | |||
55 | // Maps code memory (memory accessed via the program counter). Start and size | ||
56 | // must be multiple of page_size. | ||
57 | void Cpu_map_code( struct Gb_Cpu* this, addr_t start, int size, void* code ) ICODE_ATTR; | ||
58 | |||
59 | // Current time. | ||
60 | static inline int Cpu_time( struct Gb_Cpu* this ) { return this->cpu_state->time; } | ||
61 | |||
62 | // Changes time. Must not be called during emulation. | ||
63 | // Should be negative, because emulation stops once it becomes >= 0. | ||
64 | static inline void Cpu_set_time( struct Gb_Cpu* this, int t ) { this->cpu_state->time = t; } | ||
65 | |||
66 | #define GB_CPU_PAGE( addr ) ((unsigned) (addr) >> page_bits) | ||
67 | |||
68 | #ifdef BLARGG_NONPORTABLE | ||
69 | #define GB_CPU_OFFSET( addr ) (addr) | ||
70 | #else | ||
71 | #define GB_CPU_OFFSET( addr ) ((addr) & (page_size - 1)) | ||
72 | #endif | ||
73 | |||
74 | // Accesses emulated memory as CPU does | ||
75 | static inline uint8_t* Cpu_get_code( struct Gb_Cpu* this, addr_t addr ) | ||
76 | { | ||
77 | return this->cpu_state_.code_map [GB_CPU_PAGE( addr )] + GB_CPU_OFFSET( addr ); | ||
78 | } | ||
79 | |||
80 | #endif | ||