Mercurial > audlegacy-plugins
annotate src/console/Nes_Cpu.h @ 3047:4434b4c4a715
ported EsounD plugin
author | Andrew O. Shadoura <bugzilla@tut.by> |
---|---|
date | Fri, 17 Apr 2009 16:17:10 +0300 |
parents | 240bdf781ad0 |
children |
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 | 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 |