diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libgme/nes_cpu.h | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libgme/nes_cpu.h')
-rw-r--r-- | lib/rbcodec/codecs/libgme/nes_cpu.h | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/nes_cpu.h b/lib/rbcodec/codecs/libgme/nes_cpu.h new file mode 100644 index 0000000000..e4538cd00c --- /dev/null +++ b/lib/rbcodec/codecs/libgme/nes_cpu.h | |||
@@ -0,0 +1,109 @@ | |||
1 | // NES cpu emulator | ||
2 | |||
3 | // Game_Music_Emu 0.6-pre | ||
4 | #ifndef NES_CPU_H | ||
5 | #define NES_CPU_H | ||
6 | |||
7 | #include "blargg_common.h" | ||
8 | #include "blargg_source.h" | ||
9 | |||
10 | typedef int nes_time_t; | ||
11 | typedef int addr_t; | ||
12 | |||
13 | enum { page_bits = 11 }; | ||
14 | enum { page_size = 1 << page_bits }; | ||
15 | enum { page_count = 0x10000 >> page_bits }; | ||
16 | |||
17 | // Unmapped page should be filled with this | ||
18 | enum { halt_opcode = 0x22 }; | ||
19 | |||
20 | enum { future_time = INT_MAX/2 + 1 }; | ||
21 | enum { irq_inhibit_mask = 0x04 }; | ||
22 | |||
23 | // Can read this many bytes past end of a page | ||
24 | enum { cpu_padding = 8 }; | ||
25 | |||
26 | struct registers_t { | ||
27 | uint16_t pc; | ||
28 | uint8_t a; | ||
29 | uint8_t x; | ||
30 | uint8_t y; | ||
31 | uint8_t flags; | ||
32 | uint8_t sp; | ||
33 | }; | ||
34 | |||
35 | struct cpu_state_t { | ||
36 | uint8_t const* code_map [page_count + 1]; | ||
37 | nes_time_t base; | ||
38 | int time; | ||
39 | }; | ||
40 | |||
41 | struct Nes_Cpu { | ||
42 | // NES 6502 registers. NOT kept updated during emulation. | ||
43 | struct registers_t r; | ||
44 | nes_time_t irq_time; | ||
45 | nes_time_t end_time; | ||
46 | |||
47 | struct cpu_state_t* cpu_state; // points to cpu_state_ or a local copy | ||
48 | struct cpu_state_t cpu_state_; | ||
49 | }; | ||
50 | |||
51 | static inline void Cpu_init( struct Nes_Cpu* this ) | ||
52 | { | ||
53 | this->cpu_state = &this->cpu_state_; | ||
54 | } | ||
55 | |||
56 | // Clears registers and maps all pages to unmapped_page | ||
57 | void Cpu_reset( struct Nes_Cpu* this, void const* unmapped_page ); | ||
58 | |||
59 | // Maps code memory (memory accessed via the program counter). Start and size | ||
60 | // must be multiple of page_size. If mirror_size is non-zero, the first | ||
61 | // mirror_size bytes are repeated over the range. mirror_size must be a | ||
62 | // multiple of page_size. | ||
63 | void Cpu_map_code( struct Nes_Cpu* this, addr_t start, int size, void const* code, int mirror_size ); | ||
64 | |||
65 | // Time of beginning of next instruction to be executed | ||
66 | static inline nes_time_t Cpu_time( struct Nes_Cpu* this ) { return this->cpu_state->time + this->cpu_state->base; } | ||
67 | static inline void Cpu_set_time( struct Nes_Cpu* this, nes_time_t t ) { this->cpu_state->time = t - this->cpu_state->base; } | ||
68 | static inline void Cpu_adjust_time( struct Nes_Cpu* this, int delta ) { this->cpu_state->time += delta; } | ||
69 | |||
70 | // Clocks past end (negative if before) | ||
71 | static inline int Cpu_time_past_end( struct Nes_Cpu* this ) { return this->cpu_state->time; } | ||
72 | |||
73 | #define NES_CPU_PAGE( addr ) ((unsigned) (addr) >> page_bits) | ||
74 | |||
75 | #ifdef BLARGG_NONPORTABLE | ||
76 | #define NES_CPU_OFFSET( addr ) (addr) | ||
77 | #else | ||
78 | #define NES_CPU_OFFSET( addr ) ((addr) & (page_size - 1)) | ||
79 | #endif | ||
80 | |||
81 | // Accesses emulated memory as cpu does | ||
82 | static inline uint8_t const* Cpu_get_code( struct Nes_Cpu* this, addr_t addr ) | ||
83 | { | ||
84 | return this->cpu_state_.code_map [NES_CPU_PAGE( addr )] + NES_CPU_OFFSET( addr ); | ||
85 | } | ||
86 | |||
87 | static inline void Cpu_update_end_time( struct Nes_Cpu* this, nes_time_t end, nes_time_t irq ) | ||
88 | { | ||
89 | if ( end > irq && !(this->r.flags & irq_inhibit_mask) ) | ||
90 | end = irq; | ||
91 | |||
92 | this->cpu_state->time += this->cpu_state->base - end; | ||
93 | this->cpu_state->base = end; | ||
94 | } | ||
95 | |||
96 | // Time of next IRQ | ||
97 | static inline void Cpu_set_irq_time( struct Nes_Cpu* this, nes_time_t t ) | ||
98 | { | ||
99 | this->irq_time = t; | ||
100 | Cpu_update_end_time( this, this->end_time, t ); | ||
101 | } | ||
102 | |||
103 | static inline void Cpu_set_end_time( struct Nes_Cpu* this, nes_time_t t ) | ||
104 | { | ||
105 | this->end_time = t; | ||
106 | Cpu_update_end_time( this, t, this->irq_time ); | ||
107 | } | ||
108 | |||
109 | #endif | ||