Mercurial > audlegacy-plugins
annotate src/console/Snes_Spc.cxx @ 380:1397798646fb trunk
[svn] - change use of printf to g_warning() and g_critical() where appropriate.
author | nenolod |
---|---|
date | Thu, 14 Dec 2006 18:08:50 -0800 |
parents | 986f098da058 |
children | c31e94fefd2a |
rev | line source |
---|---|
341 | 1 // Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
2 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
3 #include "Snes_Spc.h" |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
4 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
5 #include <string.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 /* Copyright (C) 2004-2006 Shay Green. This module is free software; you |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
8 can redistribute it and/or modify it under the terms of the GNU Lesser |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
9 General Public License as published by the Free Software Foundation; either |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
10 version 2.1 of the License, or (at your option) any later version. This |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
11 module is distributed in the hope that it will be useful, but WITHOUT ANY |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
13 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
14 details. You should have received a copy of the GNU Lesser General Public |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
15 License along with this module; if not, write to the Free Software Foundation, |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
17 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
18 #include "blargg_source.h" |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
19 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
20 // always in the future (CPU time can go over 0, but not by this much) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
21 int const timer_disabled_time = 127; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
22 |
341 | 23 Snes_Spc::Snes_Spc() : dsp( mem.ram ), cpu( this, mem.ram ) |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
24 { |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
25 set_tempo( 1.0 ); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
26 |
341 | 27 // Put STOP instruction around memory to catch PC underflow/overflow. |
28 memset( mem.padding1, 0xFF, sizeof mem.padding1 ); | |
29 memset( mem.padding2, 0xFF, sizeof mem.padding2 ); | |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
30 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
31 // A few tracks read from the last four bytes of IPL ROM |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
32 boot_rom [sizeof boot_rom - 2] = 0xC0; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
33 boot_rom [sizeof boot_rom - 1] = 0xFF; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
34 memset( boot_rom, 0, sizeof boot_rom - 2 ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
35 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
36 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
37 void Snes_Spc::set_tempo( double t ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
38 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
39 int unit = (int) (16.0 / t + 0.5); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
40 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
41 timer [0].divisor = unit * 8; // 8 kHz |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
42 timer [1].divisor = unit * 8; // 8 kHz |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
43 timer [2].divisor = unit; // 64 kHz |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
44 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
45 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
46 // Load |
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 void Snes_Spc::set_ipl_rom( void const* in ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
49 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
50 memcpy( boot_rom, in, sizeof boot_rom ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
51 } |
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 blargg_err_t Snes_Spc::load_spc( const void* data, long size ) |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
54 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
55 struct spc_file_t { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
56 char signature [27]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
57 char unused [10]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
58 uint8_t pc [2]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
59 uint8_t a; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
60 uint8_t x; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
61 uint8_t y; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
62 uint8_t status; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
63 uint8_t sp; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
64 char unused2 [212]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
65 uint8_t ram [0x10000]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
66 uint8_t dsp [128]; |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
67 uint8_t ipl_rom [128]; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
68 }; |
341 | 69 assert( offsetof (spc_file_t,ipl_rom) == spc_file_size ); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
70 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
71 const spc_file_t* spc = (spc_file_t const*) data; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
72 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
73 if ( size < spc_file_size ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
74 return "Not an SPC file"; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
75 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
76 if ( strncmp( spc->signature, "SNES-SPC700 Sound File Data", 27 ) != 0 ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
77 return "Not an SPC file"; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
78 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
79 registers_t regs; |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
80 regs.pc = spc->pc [1] * 0x100 + spc->pc [0]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
81 regs.a = spc->a; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
82 regs.x = spc->x; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
83 regs.y = spc->y; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
84 regs.status = spc->status; |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
85 regs.sp = spc->sp; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
86 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
87 if ( (unsigned long) size >= sizeof *spc ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
88 set_ipl_rom( spc->ipl_rom ); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
89 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
90 const char* error = load_state( regs, spc->ram, spc->dsp ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
91 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
92 echo_accessed = false; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
93 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
94 return error; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
95 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
96 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
97 void Snes_Spc::clear_echo() |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
98 { |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
99 if ( !(dsp.read( 0x6C ) & 0x20) ) |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
100 { |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
101 unsigned addr = 0x100 * dsp.read( 0x6D ); |
341 | 102 size_t size = 0x800 * dsp.read( 0x7D ); |
103 memset( mem.ram + addr, 0xFF, min( size, sizeof mem.ram - addr ) ); | |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
104 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
105 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
106 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
107 // Handle other file formats (emulator save states) in user code, not here. |
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 blargg_err_t Snes_Spc::load_state( const registers_t& cpu_state, const void* new_ram, |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
110 const void* dsp_state ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
111 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
112 // cpu |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
113 cpu.r = cpu_state; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
114 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
115 // Allow DSP to generate one sample before code starts |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
116 // (Tengai Makyo Zero, Tenjin's Table Toss first notes are lost since it |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
117 // clears KON 31 cycles from starting execution. It works on the SNES |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
118 // since the SPC player adds a few extra cycles delay after restoring |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
119 // KON from the DSP registers at the end of an SPC file). |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
120 extra_cycles = 32; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
121 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
122 // ram |
341 | 123 memcpy( mem.ram, new_ram, sizeof mem.ram ); |
124 memcpy( extra_ram, mem.ram + rom_addr, sizeof extra_ram ); | |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
125 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
126 // boot rom (have to force enable_rom() to update it) |
341 | 127 rom_enabled = !(mem.ram [0xF1] & 0x80); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
128 enable_rom( !rom_enabled ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
129 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
130 // dsp |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
131 dsp.reset(); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
132 int i; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
133 for ( i = 0; i < Spc_Dsp::register_count; i++ ) |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
134 dsp.write( i, ((uint8_t const*) dsp_state) [i] ); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
135 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
136 // timers |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
137 for ( i = 0; i < timer_count; i++ ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
138 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
139 Timer& t = timer [i]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
140 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
141 t.next_tick = 0; |
341 | 142 t.enabled = (mem.ram [0xF1] >> i) & 1; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
143 if ( !t.enabled ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
144 t.next_tick = timer_disabled_time; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
145 t.count = 0; |
341 | 146 t.counter = mem.ram [0xFD + i] & 15; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
147 |
341 | 148 int p = mem.ram [0xFA + i]; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
149 t.period = p ? p : 0x100; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
150 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
151 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
152 // Handle registers which already give 0 when read by setting RAM and not changing it. |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
153 // Put STOP instruction in registers which can be read, to catch attempted CPU execution. |
341 | 154 mem.ram [0xF0] = 0; |
155 mem.ram [0xF1] = 0; | |
156 mem.ram [0xF3] = 0xFF; | |
157 mem.ram [0xFA] = 0; | |
158 mem.ram [0xFB] = 0; | |
159 mem.ram [0xFC] = 0; | |
160 mem.ram [0xFD] = 0xFF; | |
161 mem.ram [0xFE] = 0xFF; | |
162 mem.ram [0xFF] = 0xFF; | |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
163 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
164 return 0; // success |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
165 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
166 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
167 // Hardware |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
168 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
169 // Current time starts negative and ends at 0 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
170 inline spc_time_t Snes_Spc::time() const |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
171 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
172 return -cpu.remain(); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
173 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
174 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
175 // Keep track of next time to run and avoid a function call if it hasn't been reached. |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
176 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
177 // Timers |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
178 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
179 void Snes_Spc::Timer::run_until_( spc_time_t time ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
180 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
181 if ( !enabled ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
182 dprintf( "next_tick: %ld, time: %ld", (long) next_tick, (long) time ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
183 assert( enabled ); // when disabled, next_tick should always be in the future |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
184 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
185 int elapsed = ((time - next_tick) / divisor) + 1; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
186 next_tick += elapsed * divisor; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
187 |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
188 elapsed += count; |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
189 if ( elapsed >= period ) // avoid unnecessary division |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
190 { |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
191 int n = elapsed / period; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
192 elapsed -= n * period; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
193 counter = (counter + n) & 15; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
194 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
195 count = elapsed; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
196 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
197 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
198 // DSP |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
199 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
200 const int clocks_per_sample = 32; // 1.024 MHz CPU clock / 32000 samples per second |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
201 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
202 void Snes_Spc::run_dsp_( spc_time_t time ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
203 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
204 int count = ((time - next_dsp) >> 5) + 1; // divide by clocks_per_sample |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
205 sample_t* buf = sample_buf; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
206 if ( buf ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
207 sample_buf = buf + count * 2; // stereo |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
208 assert( sample_buf <= buf_end ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
209 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
210 next_dsp += count * clocks_per_sample; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
211 dsp.run( count, buf ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
212 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
213 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
214 inline void Snes_Spc::run_dsp( spc_time_t time ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
215 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
216 if ( time >= next_dsp ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
217 run_dsp_( time ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
218 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
219 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
220 // Debug-only check for read/write within echo buffer, since this might result in |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
221 // inaccurate emulation due to the DSP not being caught up to the present. |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
222 inline void Snes_Spc::check_for_echo_access( spc_addr_t addr ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
223 { |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
224 if ( !echo_accessed && !(dsp.read( 0x6C ) & 0x20) ) |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
225 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
226 // ** If echo accesses are found that require running the DSP, cache |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
227 // the start and end address on DSP writes to speed up checking. |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
228 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
229 unsigned start = 0x100 * dsp.read( 0x6D ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
230 unsigned end = start + 0x800 * dsp.read( 0x7D ); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
231 if ( start <= addr && addr < end ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
232 echo_accessed = true; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
233 dprintf( "Read/write at $%04X within echo buffer\n", (unsigned) addr ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
234 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
235 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
236 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
237 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
238 // Read |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
239 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
240 int Snes_Spc::read( spc_addr_t addr ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
241 { |
341 | 242 int result = mem.ram [addr]; |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
243 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
244 if ( (rom_addr <= addr && addr < 0xFFFC || addr >= 0xFFFE) && rom_enabled ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
245 dprintf( "Read from ROM: %04X -> %02X\n", addr, result ); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
246 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
247 if ( unsigned (addr - 0xF0) < 0x10 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
248 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
249 assert( 0xF0 <= addr && addr <= 0xFF ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
250 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
251 // counters |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
252 int i = addr - 0xFD; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
253 if ( i >= 0 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
254 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
255 Timer& t = timer [i]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
256 t.run_until( time() ); |
341 | 257 int old = t.counter; |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
258 t.counter = 0; |
341 | 259 return old; |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
260 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
261 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
262 // dsp |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
263 if ( addr == 0xF3 ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
264 { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
265 run_dsp( time() ); |
341 | 266 if ( mem.ram [0xF2] >= Spc_Dsp::register_count ) |
267 dprintf( "DSP read from $%02X\n", (int) mem.ram [0xF2] ); | |
268 return dsp.read( mem.ram [0xF2] & 0x7F ); | |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
269 } |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
270 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
271 if ( addr == 0xF0 || addr == 0xF1 || addr == 0xF8 || |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
272 addr == 0xF9 || addr == 0xFA ) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
273 dprintf( "Read from register $%02X\n", (int) addr ); |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
274 |
341 | 275 // Registers which always read as 0 are handled by setting mem.ram [reg] to 0 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
276 // at startup then never changing that value. |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
277 |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
278 check(( check_for_echo_access( addr ), true )); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
279 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
280 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
281 return result; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
282 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
283 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
284 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
285 // Write |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
286 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
287 void Snes_Spc::enable_rom( bool enable ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
288 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
289 if ( rom_enabled != enable ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
290 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
291 rom_enabled = enable; |
341 | 292 memcpy( mem.ram + rom_addr, (enable ? boot_rom : extra_ram), rom_size ); |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
293 // TODO: ROM can still get overwritten when DSP writes to echo buffer |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
294 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
295 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
296 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
297 void Snes_Spc::write( spc_addr_t addr, int data ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
298 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
299 // first page is very common |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
300 if ( addr < 0xF0 ) { |
341 | 301 mem.ram [addr] = (uint8_t) data; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
302 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
303 else switch ( addr ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
304 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
305 // RAM |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
306 default: |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
307 check(( check_for_echo_access( addr ), true )); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
308 if ( addr < rom_addr ) { |
341 | 309 mem.ram [addr] = (uint8_t) data; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
310 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
311 else { |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
312 extra_ram [addr - rom_addr] = (uint8_t) data; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
313 if ( !rom_enabled ) |
341 | 314 mem.ram [addr] = (uint8_t) data; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
315 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
316 break; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
317 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
318 // DSP |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
319 //case 0xF2: // mapped to RAM |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
320 case 0xF3: { |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
321 run_dsp( time() ); |
341 | 322 int reg = mem.ram [0xF2]; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
323 if ( next_dsp > 0 ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
324 // skip mode |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
325 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
326 // key press |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
327 if ( reg == 0x4C ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
328 keys_pressed |= data & ~dsp.read( 0x5C ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
329 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
330 // key release |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
331 if ( reg == 0x5C ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
332 keys_released |= data; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
333 keys_pressed &= ~data; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
334 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
335 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
336 if ( reg < Spc_Dsp::register_count ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
337 dsp.write( reg, data ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
338 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
339 else { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
340 dprintf( "DSP write to $%02X\n", (int) reg ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
341 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
342 break; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
343 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
344 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
345 case 0xF0: // Test register |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
346 dprintf( "Wrote $%02X to $F0\n", (int) data ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
347 break; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
348 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
349 // Config |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
350 case 0xF1: |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
351 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
352 // timers |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
353 for ( int i = 0; i < timer_count; i++ ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
354 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
355 Timer& t = timer [i]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
356 if ( !(data & (1 << i)) ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
357 t.enabled = 0; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
358 t.next_tick = timer_disabled_time; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
359 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
360 else if ( !t.enabled ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
361 // just enabled |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
362 t.enabled = 1; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
363 t.counter = 0; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
364 t.count = 0; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
365 t.next_tick = time(); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
366 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
367 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
368 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
369 // port clears |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
370 if ( data & 0x10 ) { |
341 | 371 mem.ram [0xF4] = 0; |
372 mem.ram [0xF5] = 0; | |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
373 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
374 if ( data & 0x20 ) { |
341 | 375 mem.ram [0xF6] = 0; |
376 mem.ram [0xF7] = 0; | |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
377 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
378 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
379 enable_rom( data & 0x80 ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
380 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
381 break; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
382 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
383 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
384 // Ports |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
385 case 0xF4: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
386 case 0xF5: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
387 case 0xF6: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
388 case 0xF7: |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
389 // to do: handle output ports |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
390 break; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
391 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
392 //case 0xF8: // verified on SNES that these are read/write (RAM) |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
393 //case 0xF9: |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
394 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
395 // Timers |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
396 case 0xFA: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
397 case 0xFB: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
398 case 0xFC: { |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
399 Timer& t = timer [addr - 0xFA]; |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
400 if ( (t.period & 0xFF) != data ) { |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
401 t.run_until( time() ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
402 t.period = data ? data : 0x100; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
403 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
404 break; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
405 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
406 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
407 // Counters (cleared on write) |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
408 case 0xFD: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
409 case 0xFE: |
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
410 case 0xFF: |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
411 dprintf( "Wrote to counter $%02X\n", (int) addr ); |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
412 timer [addr - 0xFD].counter = 0; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
413 break; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
414 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
415 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
416 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
417 // Play |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
418 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
419 blargg_err_t Snes_Spc::skip( long count ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
420 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
421 if ( count > 4 * 32000L ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
422 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
423 // don't run DSP for long durations (2-3 times faster) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
424 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
425 const long sync_count = 32000L * 2; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
426 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
427 // keep track of any keys pressed/released (and not subsequently released) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
428 keys_pressed = 0; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
429 keys_released = 0; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
430 // sentinel tells play to ignore DSP |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
431 RETURN_ERR( play( count - sync_count, skip_sentinel ) ); |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
432 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
433 // press/release keys now |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
434 dsp.write( 0x5C, keys_released & ~keys_pressed ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
435 dsp.write( 0x4C, keys_pressed ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
436 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
437 clear_echo(); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
438 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
439 // play the last few seconds normally to help synchronize DSP |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
440 count = sync_count; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
441 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
442 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
443 return play( count ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
444 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
445 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
446 blargg_err_t Snes_Spc::play( long count, sample_t* out ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
447 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
448 require( count % 2 == 0 ); // output is always in pairs of samples |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
449 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
450 // CPU time() runs from -duration to 0 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
451 spc_time_t duration = (count / 2) * clocks_per_sample; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
452 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
453 // DSP output is made on-the-fly when the CPU reads/writes DSP registers |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
454 sample_buf = out; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
455 buf_end = out + (out && out != skip_sentinel ? count : 0); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
456 next_dsp = (out == skip_sentinel) ? clocks_per_sample : -duration + clocks_per_sample; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
457 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
458 // Localize timer next_tick times and run them to the present to prevent a running |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
459 // but ignored timer's next_tick from getting too far behind and overflowing. |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
460 for ( int i = 0; i < timer_count; i++ ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
461 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
462 Timer& t = timer [i]; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
463 if ( t.enabled ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
464 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
465 t.next_tick -= duration; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
466 t.run_until( -duration ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
467 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
468 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
469 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
470 // Run CPU for duration, reduced by any extra cycles from previous run |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
471 int elapsed = cpu.run( duration - extra_cycles ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
472 if ( elapsed > 0 ) |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
473 { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
474 dprintf( "Unhandled instruction $%02X, pc = $%04X\n", |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
475 (int) cpu.read( cpu.r.pc ), (unsigned) cpu.r.pc ); |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
476 return "Emulation error (illegal/unsupported instruction)"; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
477 } |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
478 extra_cycles = -elapsed; |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
479 |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
480 // Catch DSP up to present. |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
481 run_dsp( 0 ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
482 if ( out ) { |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
483 assert( next_dsp == clocks_per_sample ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
484 assert( out == skip_sentinel || sample_buf - out == count ); |
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
485 } |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
486 buf_end = 0; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
487 |
316
fb513e10174e
[svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
12
diff
changeset
|
488 return 0; |
0
13389e613d67
[svn] - initial import of audacious-plugins tree (lots to do)
nenolod
parents:
diff
changeset
|
489 } |