1 // Normal cpu for NSF emulator
3 // Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/
7 #include "blargg_endian.h"
10 //#define CPU_LOG_START 1000000
11 //#include "nes_cpu_log.h"
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"
29 #define LOG_MEM( addr, str, data ) data
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
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
) );
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
;
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
;
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
);
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
;
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 )
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;