annotate src/console/Nes_Cpu.h @ 3183:19e3ec80dac9

alsa-ng: Another arithmetic overflow (hopefully the last one).
author John Lindgren <john.lindgren@tds.net>
date Fri, 12 Jun 2009 17:15:10 -0400
parents 240bdf781ad0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
1 // NES 6502 CPU emulator
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
2
341
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
3 // Game_Music_Emu 0.5.2
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
4 #ifndef NES_CPU_H
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
5 #define NES_CPU_H
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
6
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
7 #include "blargg_common.h"
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
8
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
9 typedef blargg_long nes_time_t; // clock cycle count
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
10 typedef unsigned nes_addr_t; // 16-bit address
2238
240bdf781ad0 eliminate warnings on x86_64.
Yoshiki Yazawa <yaz@cc.rim.or.jp>
parents: 341
diff changeset
11 enum { future_nes_time = INT_MAX / 2 + 1 };
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
12
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
13 class Nes_Cpu {
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
14 public:
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
15 typedef BOOST::uint8_t uint8_t;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
16
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
17 // Clear registers, map low memory and its three mirrors to address 0,
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
18 // and mirror unmapped_page in remaining memory
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
19 void reset( void const* unmapped_page = 0 );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
20
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
21 // Map code memory (memory accessed via the program counter). Start and size
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
22 // must be multiple of page_size. If mirror is true, repeats code page
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
23 // throughout address range.
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
24 enum { page_size = 0x800 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
25 void map_code( nes_addr_t start, unsigned size, void const* code, bool mirror = false );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
26
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
27 // Access emulated memory as CPU does
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
28 uint8_t const* get_code( nes_addr_t );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
29
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
30 // 2KB of RAM at address 0
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
31 uint8_t low_mem [0x800];
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
32
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
33 // NES 6502 registers. Not kept updated during a call to run().
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
34 struct registers_t {
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
35 BOOST::uint16_t pc;
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
36 BOOST::uint8_t a;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
37 BOOST::uint8_t x;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
38 BOOST::uint8_t y;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
39 BOOST::uint8_t status;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
40 BOOST::uint8_t sp;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
41 };
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
42 registers_t r;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
43
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
44 // Set end_time and run CPU from current time. Returns true if execution
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
45 // stopped due to encountering bad_opcode.
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
46 bool run( nes_time_t end_time );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
47
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
48 // Time of beginning of next instruction to be executed
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
49 nes_time_t time() const { return state->time + state->base; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
50 void set_time( nes_time_t t ) { state->time = t - state->base; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
51 void adjust_time( int delta ) { state->time += delta; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
52
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
53 nes_time_t irq_time() const { return irq_time_; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
54 void set_irq_time( nes_time_t );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
55
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
56 nes_time_t end_time() const { return end_time_; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
57 void set_end_time( nes_time_t );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
58
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
59 // Number of undefined instructions encountered and skipped
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
60 void clear_error_count() { error_count_ = 0; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
61 unsigned long error_count() const { return error_count_; }
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
62
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
63 // CPU invokes bad opcode handler if it encounters this
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
64 enum { bad_opcode = 0xF2 };
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
65
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
66 public:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
67 Nes_Cpu() { state = &state_; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
68 enum { page_bits = 11 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
69 enum { page_count = 0x10000 >> page_bits };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
70 enum { irq_inhibit = 0x04 };
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
71 private:
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
72 struct state_t {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
73 uint8_t const* code_map [page_count + 1];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
74 nes_time_t base;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
75 int time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
76 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
77 state_t* state; // points to state_ or a local copy within run()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
78 state_t state_;
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
79 nes_time_t irq_time_;
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
80 nes_time_t end_time_;
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
81 unsigned long error_count_;
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
82
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
83 void set_code_page( int, void const* );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
84 inline int update_end_time( nes_time_t end, nes_time_t irq );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
85 };
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
86
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
87 inline BOOST::uint8_t const* Nes_Cpu::get_code( nes_addr_t addr )
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
88 {
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
89 return state->code_map [addr >> page_bits] + addr
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
90 #if !BLARGG_NONPORTABLE
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
91 % (unsigned) page_size
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
92 #endif
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
93 ;
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
94 }
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
95
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
96 inline int Nes_Cpu::update_end_time( nes_time_t t, nes_time_t irq )
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
97 {
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
98 if ( irq < t && !(r.status & irq_inhibit) ) t = irq;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
99 int delta = state->base - t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
100 state->base = t;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
101 return delta;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
102 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
103
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
104 inline void Nes_Cpu::set_irq_time( nes_time_t t )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
105 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
106 state->time += update_end_time( end_time_, (irq_time_ = t) );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
107 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
108
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
109 inline void Nes_Cpu::set_end_time( nes_time_t t )
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
110 {
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
111 state->time += update_end_time( (end_time_ = t), irq_time_ );
0
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
112 }
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
113
13389e613d67 [svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff changeset
114 #endif