summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/hes_cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libgme/hes_cpu.h')
-rw-r--r--apps/codecs/libgme/hes_cpu.h95
1 files changed, 95 insertions, 0 deletions
diff --git a/apps/codecs/libgme/hes_cpu.h b/apps/codecs/libgme/hes_cpu.h
new file mode 100644
index 0000000000..f3bcf7d4cf
--- /dev/null
+++ b/apps/codecs/libgme/hes_cpu.h
@@ -0,0 +1,95 @@
1// PC Engine CPU emulator for use with HES music files
2
3// Game_Music_Emu 0.5.2
4#ifndef HES_CPU_H
5#define HES_CPU_H
6
7#include "blargg_common.h"
8
9typedef blargg_long hes_time_t; // clock cycle count
10typedef unsigned hes_addr_t; // 16-bit address
11
12struct Hes_Emu;
13
14enum { future_hes_time = LONG_MAX / 2 + 1 };
15enum { page_size = 0x2000 };
16enum { page_shift = 13 };
17enum { page_count = 8 };
18
19// Attempt to execute instruction here results in CPU advancing time to
20// lesser of irq_time() and end_time() (or end_time() if IRQs are
21// disabled)
22enum { idle_addr = 0x1FFF };
23
24// Can read this many bytes past end of a page
25enum { cpu_padding = 8 };
26enum { irq_inhibit = 0x04 };
27
28
29// Cpu state
30struct state_t {
31 uint8_t const* code_map [page_count + 1];
32 hes_time_t base;
33 blargg_long time;
34};
35
36// Cpu registers
37struct registers_t {
38 uint16_t pc;
39 uint8_t a;
40 uint8_t x;
41 uint8_t y;
42 uint8_t status;
43 uint8_t sp;
44};
45
46struct Hes_Cpu {
47 struct registers_t r;
48
49 hes_time_t irq_time;
50 hes_time_t end_time;
51
52 struct state_t* state; // points to state_ or a local copy within run()
53 struct state_t state_;
54
55 // page mapping registers
56 uint8_t mmr [page_count + 1];
57 uint8_t ram [page_size];
58};
59
60// Init cpu state
61void Cpu_init( struct Hes_Cpu* this );
62
63// Reset hes cpu
64void Cpu_reset( struct Hes_Cpu* this );
65
66// Set end_time and run CPU from current time. Returns true if any illegal
67// instructions were encountered.
68bool Cpu_run( struct Hes_Emu* this, hes_time_t end_time ) ICODE_ATTR;
69
70void Cpu_set_mmr( struct Hes_Emu* this, int reg, int bank ) ICODE_ATTR;
71
72// Time of ning of next instruction to be executed
73static inline hes_time_t Cpu_time( struct Hes_Cpu* this )
74{
75 return this->state->time + this->state->base;
76}
77
78static inline uint8_t const* Cpu_get_code( struct Hes_Cpu* this, hes_addr_t addr )
79{
80 return this->state->code_map [addr >> page_shift] + addr
81 #if !defined (BLARGG_NONPORTABLE)
82 % (unsigned) page_size
83 #endif
84 ;
85}
86
87static inline int Cpu_update_end_time( struct Hes_Cpu* this, uint8_t reg_status, hes_time_t t, hes_time_t irq )
88{
89 if ( irq < t && !(reg_status & irq_inhibit) ) t = irq;
90 int delta = this->state->base - t;
91 this->state->base = t;
92 return delta;
93}
94
95#endif