Submit initial patch from FS#12176. Adds support for several new game music formats...
[kugel-rb.git] / apps / codecs / libgme / nsf_cpu.c
blob1f44bd3c3ceb4b28de997ea5e4f61cb5bbfd317e
1 // Normal cpu for NSF emulator
3 // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/
5 #include "nsf_emu.h"
7 #include "blargg_endian.h"
9 #ifdef BLARGG_DEBUG_H
10 //#define CPU_LOG_START 1000000
11 //#include "nes_cpu_log.h"
12 #undef LOG_MEM
13 #endif
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 */
26 #include "blargg_source.h"
28 #ifndef LOG_MEM
29 #define LOG_MEM( addr, str, data ) data
30 #endif
32 int read_mem( struct Nsf_Emu* this, addr_t addr )
34 int result = this->low_ram [addr & (low_ram_size-1)]; // also handles wrap-around
35 if ( addr & 0xE000 )
37 result = *Cpu_get_code( &this->cpu, addr );
38 if ( addr < sram_addr )
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 );
46 return LOG_MEM( addr, ">", result );
49 void write_mem( struct Nsf_Emu* this, addr_t addr, int data )
51 (void) LOG_MEM( addr, "<", data );
53 int offset = addr - sram_addr;
54 if ( (unsigned) offset < sram_size )
56 sram( this ) [offset] = data;
58 else
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) )
64 this->low_ram [temp] = data;
66 else
68 int bank = addr - banks_addr;
69 if ( (unsigned) bank < bank_count )
71 write_bank( this, bank, data );
73 else if ( (unsigned) (addr - apu_io_addr) < apu_io_size )
75 Apu_write_register( &this->apu, Cpu_time( &this->cpu ), addr, data );
77 else
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 );
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 ))
95 #define CAN_WRITE_FAST( addr ) (addr < low_ram_size)
96 #define WRITE_FAST WRITE_LOW
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 ) ))
102 #define READ_MEM( addr ) read_mem( this, addr )
103 #define WRITE_MEM( addr, data ) write_mem( this, addr, data )
105 #define CPU_BEGIN \
106 bool run_cpu_until( struct Nsf_Emu* this, nes_time_t end ) \
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 ) \
112 #include "nes_cpu_run.h"
114 return Cpu_time_past_end( cpu ) < 0;