diff options
Diffstat (limited to 'apps/codecs/libgme/nsf_cpu.c')
-rw-r--r-- | apps/codecs/libgme/nsf_cpu.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/apps/codecs/libgme/nsf_cpu.c b/apps/codecs/libgme/nsf_cpu.c new file mode 100644 index 0000000000..1f44bd3c3c --- /dev/null +++ b/apps/codecs/libgme/nsf_cpu.c | |||
@@ -0,0 +1,115 @@ | |||
1 | // Normal cpu for NSF emulator | ||
2 | |||
3 | // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ | ||
4 | |||
5 | #include "nsf_emu.h" | ||
6 | |||
7 | #include "blargg_endian.h" | ||
8 | |||
9 | #ifdef BLARGG_DEBUG_H | ||
10 | //#define CPU_LOG_START 1000000 | ||
11 | //#include "nes_cpu_log.h" | ||
12 | #undef LOG_MEM | ||
13 | #endif | ||
14 | |||
15 | /* Copyright (C) 2003-2008 Shay Green. This module is free software; you | ||
16 | can redistribute it and/or modify it under the terms of the GNU Lesser | ||
17 | General Public License as published by the Free Software Foundation; either | ||
18 | version 2.1 of the License, or (at your option) any later version. This | ||
19 | module is distributed in the hope that it will be useful, but WITHOUT ANY | ||
20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
21 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | ||
22 | details. You should have received a copy of the GNU Lesser General Public | ||
23 | License along with this module; if not, write to the Free Software Foundation, | ||
24 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ | ||
25 | |||
26 | #include "blargg_source.h" | ||
27 | |||
28 | #ifndef LOG_MEM | ||
29 | #define LOG_MEM( addr, str, data ) data | ||
30 | #endif | ||
31 | |||
32 | int read_mem( struct Nsf_Emu* this, addr_t addr ) | ||
33 | { | ||
34 | int result = this->low_ram [addr & (low_ram_size-1)]; // also handles wrap-around | ||
35 | if ( addr & 0xE000 ) | ||
36 | { | ||
37 | result = *Cpu_get_code( &this->cpu, addr ); | ||
38 | if ( addr < sram_addr ) | ||
39 | { | ||
40 | if ( addr == apu_status_addr ) | ||
41 | result = Apu_read_status( &this->apu, Cpu_time( &this->cpu ) ); | ||
42 | else | ||
43 | result = cpu_read( this, addr ); | ||
44 | } | ||
45 | } | ||
46 | return LOG_MEM( addr, ">", result ); | ||
47 | } | ||
48 | |||
49 | void write_mem( struct Nsf_Emu* this, addr_t addr, int data ) | ||
50 | { | ||
51 | (void) LOG_MEM( addr, "<", data ); | ||
52 | |||
53 | int offset = addr - sram_addr; | ||
54 | if ( (unsigned) offset < sram_size ) | ||
55 | { | ||
56 | sram( this ) [offset] = data; | ||
57 | } | ||
58 | else | ||
59 | { | ||
60 | // after sram because cpu handles most low_ram accesses internally already | ||
61 | int temp = addr & (low_ram_size-1); // also handles wrap-around | ||
62 | if ( !(addr & 0xE000) ) | ||
63 | { | ||
64 | this->low_ram [temp] = data; | ||
65 | } | ||
66 | else | ||
67 | { | ||
68 | int bank = addr - banks_addr; | ||
69 | if ( (unsigned) bank < bank_count ) | ||
70 | { | ||
71 | write_bank( this, bank, data ); | ||
72 | } | ||
73 | else if ( (unsigned) (addr - apu_io_addr) < apu_io_size ) | ||
74 | { | ||
75 | Apu_write_register( &this->apu, Cpu_time( &this->cpu ), addr, data ); | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | #ifndef NSF_EMU_APU_ONLY | ||
80 | // 0x8000-0xDFFF is writable | ||
81 | int i = addr - 0x8000; | ||
82 | if ( fds_enabled( this ) && (unsigned) i < fdsram_size ) | ||
83 | fdsram( this ) [i] = data; | ||
84 | else | ||
85 | #endif | ||
86 | cpu_write( this, addr, data ); | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | #define READ_LOW( addr ) (LOG_MEM( addr, ">", this->low_ram [addr] )) | ||
93 | #define WRITE_LOW( addr, data ) (LOG_MEM( addr, "<", this->low_ram [addr] = data )) | ||
94 | |||
95 | #define CAN_WRITE_FAST( addr ) (addr < low_ram_size) | ||
96 | #define WRITE_FAST WRITE_LOW | ||
97 | |||
98 | // addr < 0x2000 || addr >= 0x8000 | ||
99 | #define CAN_READ_FAST( addr ) ((addr ^ 0x8000) < 0xA000) | ||
100 | #define READ_FAST( addr, out ) (LOG_MEM( addr, ">", out = READ_CODE( addr ) )) | ||
101 | |||
102 | #define READ_MEM( addr ) read_mem( this, addr ) | ||
103 | #define WRITE_MEM( addr, data ) write_mem( this, addr, data ) | ||
104 | |||
105 | #define CPU_BEGIN \ | ||
106 | bool run_cpu_until( struct Nsf_Emu* this, nes_time_t end ) \ | ||
107 | { \ | ||
108 | struct Nes_Cpu* cpu = &this->cpu; \ | ||
109 | Cpu_set_end_time( cpu, end ); \ | ||
110 | if ( *Cpu_get_code( cpu, cpu->r.pc ) != halt_opcode ) \ | ||
111 | { | ||
112 | #include "nes_cpu_run.h" | ||
113 | } | ||
114 | return Cpu_time_past_end( cpu ) < 0; | ||
115 | } | ||