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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
341
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
27 // Put STOP instruction around memory to catch PC underflow/overflow.
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
28 memset( mem.padding1, 0xFF, sizeof mem.padding1 );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
102 size_t size = 0x800 * dsp.read( 0x7D );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
123 memcpy( mem.ram, new_ram, sizeof mem.ram );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
154 mem.ram [0xF0] = 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
155 mem.ram [0xF1] = 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
156 mem.ram [0xF3] = 0xFF;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
157 mem.ram [0xFA] = 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
158 mem.ram [0xFB] = 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
159 mem.ram [0xFC] = 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
160 mem.ram [0xFD] = 0xFF;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
161 mem.ram [0xFE] = 0xFF;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
257 int old = t.counter;
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents: 12
diff changeset
258 t.counter = 0;
341
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
266 if ( mem.ram [0xF2] >= Spc_Dsp::register_count )
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
267 dprintf( "DSP read from $%02X\n", (int) mem.ram [0xF2] );
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
371 mem.ram [0xF4] = 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
375 mem.ram [0xF6] = 0;
986f098da058 [svn] - merge in blargg's changes
nenolod
parents: 316
diff changeset
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 }