annotate Plugins/Input/console/Gbs_Emu.cpp @ 98:e42694a28331 trunk

[svn] More progress -- now loads as an audacious module. :)
author nenolod
date Tue, 01 Nov 2005 21:34:11 -0800
parents 252843aac42f
children 84aabc053b6e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
90
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
1
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
2 // Game_Music_Emu 0.2.4. http://www.slack.net/~ant/libs/
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
3
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
4 #include "Gbs_Emu.h"
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
5
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
6 #include <string.h>
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
7
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
8 #include "blargg_endian.h"
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
9
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
10 /* Copyright (C) 2003-2005 Shay Green. This module is free software; you
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
11 can redistribute it and/or modify it under the terms of the GNU Lesser
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
12 General Public License as published by the Free Software Foundation; either
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
13 version 2.1 of the License, or (at your option) any later version. This
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
14 module is distributed in the hope that it will be useful, but WITHOUT ANY
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
17 more details. You should have received a copy of the GNU Lesser General
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
18 Public License along with this module; if not, write to the Free Software
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
20
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
21 #include BLARGG_SOURCE_BEGIN
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
22
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
23 const long clock_rate = 4194304;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
24 const long bank_size = 0x4000;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
25 const gb_addr_t ram_addr = 0xa000;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
26 const gb_addr_t halt_addr = 0x9eff;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
27 static BOOST::uint8_t unmapped_code [Gb_Cpu::page_size];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
28
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
29 // RAM
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
30
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
31 int Gbs_Emu::read_ram( Gbs_Emu* emu, gb_addr_t addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
32 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
33 return emu->ram [addr - ram_addr];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
34 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
35
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
36 void Gbs_Emu::write_ram( Gbs_Emu* emu, gb_addr_t addr, int data )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
37 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
38 emu->ram [addr - ram_addr] = data;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
39 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
40
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
41 // Unmapped
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
42
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
43 int Gbs_Emu::read_unmapped( Gbs_Emu*, gb_addr_t addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
44 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
45 dprintf( "Read from unmapped memory $%.4x\n", (unsigned) addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
46 return 0xff; // open bus value (probably due to pull-up resistors)
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
47 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
48
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
49 void Gbs_Emu::write_unmapped( Gbs_Emu*, gb_addr_t addr, int )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
50 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
51 dprintf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
52 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
53
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
54 // ROM
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
55
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
56 int Gbs_Emu::read_rom( Gbs_Emu* emu, gb_addr_t addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
57 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
58 return emu->rom [addr];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
59 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
60
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
61 int Gbs_Emu::read_bank( Gbs_Emu* emu, gb_addr_t addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
62 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
63 return emu->rom_bank [addr & (bank_size - 1)];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
64 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
65
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
66 void Gbs_Emu::set_bank( int n )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
67 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
68 if ( n >= bank_count ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
69 n = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
70 dprintf( "Set to non-existent bank %d\n", (int) n );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
71 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
72 if ( n == 0 && bank_count > 1 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
73 dprintf( "Selected ROM bank 0\n" );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
74 rom_bank = &rom [n * bank_size];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
75 cpu.map_code( bank_size, bank_size, rom_bank );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
76 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
77
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
78 void Gbs_Emu::write_rom( Gbs_Emu* emu, gb_addr_t addr, int data )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
79 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
80 if ( unsigned (addr - 0x2000) < 0x2000 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
81 emu->set_bank( data & 0x1f );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
82 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
83
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
84 // I/O: Timer, APU
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
85
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
86 void Gbs_Emu::set_timer( int modulo, int rate )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
87 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
88 if ( timer_mode )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
89 play_period = gb_time_t (256 - modulo) << (((rate - 1) & 3) * 2 + 4 - double_speed);
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
90 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
91
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
92 inline gb_time_t Gbs_Emu::clock() const
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
93 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
94 return cpu_time - cpu.remain();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
95 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
96
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
97 int Gbs_Emu::read_io( Gbs_Emu* emu, gb_addr_t addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
98 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
99 // hi_page is accessed most
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
100 if ( addr >= 0xff80 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
101 return emu->hi_page [addr & 0xff];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
102
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
103 if ( unsigned (addr - Gb_Apu::start_addr) <= Gb_Apu::register_count )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
104 return emu->apu.read_register( emu->clock(), addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
105
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
106 if ( addr == 0xff00 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
107 return 0; // joypad
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
108
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
109 dprintf( "Unhandled I/O read 0x%4x\n", (unsigned) addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
110
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
111 return 0xff;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
112 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
113
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
114 void Gbs_Emu::write_io( Gbs_Emu* emu, gb_addr_t addr, int data )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
115 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
116 // apu is accessed most
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
117 if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
118 emu->apu.write_register( emu->clock(), addr, data );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
119 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
120 else {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
121 emu->hi_page [addr & 0xff] = data;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
122
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
123 if ( addr == 0xff06 || addr == 0xff07 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
124 emu->set_timer( emu->hi_page [6], emu->hi_page [7] );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
125
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
126 if ( addr == 0xffff )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
127 dprintf( "Wrote interrupt mask\n" );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
128 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
129 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
130
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
131 Gbs_Emu::Gbs_Emu( double gain )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
132 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
133 rom = NULL;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
134
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
135 apu.volume( gain );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
136
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
137 // to do: decide on equalization parameters
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
138 set_equalizer( equalizer_t( -32, 8000, 90 ) );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
139
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
140 // unmapped code is all HALT instructions
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
141 memset( unmapped_code, 0x76, sizeof unmapped_code );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
142
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
143 // cpu
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
144 cpu.callback_data = this;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
145 cpu.reset( unmapped_code );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
146 cpu.map_memory( 0x0000, 0x4000, read_rom, write_rom );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
147 cpu.map_memory( 0x4000, 0x4000, read_bank, write_rom );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
148 cpu.map_memory( 0x8000, 0x8000, read_unmapped, write_unmapped );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
149 cpu.map_memory( ram_addr, 0x4000, read_ram, write_ram );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
150 cpu.map_code( ram_addr, 0x4000, ram );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
151 cpu.map_code( 0xff00, 0x0100, hi_page );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
152 cpu.map_memory( 0xff00, 0x0100, read_io, write_io );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
153 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
154
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
155 Gbs_Emu::~Gbs_Emu()
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
156 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
157 unload();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
158 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
159
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
160 void Gbs_Emu::unload()
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
161 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
162 delete [] rom;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
163 rom = NULL;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
164 cpu.r.pc = halt_addr;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
165 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
166
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
167 void Gbs_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
168 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
169 apu.osc_output( i, c, l, r );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
170 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
171
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
172 void Gbs_Emu::update_eq( blip_eq_t const& eq )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
173 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
174 apu.treble_eq( eq );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
175 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
176
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
177 blargg_err_t Gbs_Emu::load( const header_t& h, Emu_Reader& in )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
178 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
179 unload();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
180
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
181 // check compatibility
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
182 if ( 0 != memcmp( h.tag, "GBS", 3 ) )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
183 return "Not a GBS file";
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
184 if ( h.vers != 1 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
185 return "Unsupported GBS format";
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
186
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
187 // gather relevant fields
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
188 load_addr = get_le16( h.load_addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
189 init_addr = get_le16( h.init_addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
190 play_addr = get_le16( h.play_addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
191 stack_ptr = get_le16( h.stack_ptr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
192 double_speed = (h.timer_mode & 0x80) != 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
193 timer_modulo_init = h.timer_modulo;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
194 timer_mode = h.timer_mode;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
195 if ( !(timer_mode & 0x04) )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
196 timer_mode = 0; // using vbl
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
197
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
198 #ifndef NDEBUG
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
199 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
200 if ( h.timer_mode & 0x78 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
201 dprintf( "TAC field has extra bits set: 0x%02x\n", (unsigned) h.timer_mode );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
202
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
203 if ( load_addr < 0x400 || load_addr >= 0x8000 ||
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
204 init_addr < 0x400 || init_addr >= 0x8000 ||
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
205 play_addr < 0x400 || play_addr >= 0x8000 )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
206 dprintf( "Load/init/play address violates GBS spec.\n" );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
207 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
208 #endif
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
209
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
210 // rom
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
211 bank_count = (load_addr + in.remain() + bank_size - 1) / bank_size;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
212 long rom_size = bank_count * bank_size;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
213 rom = new BOOST::uint8_t [rom_size];
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
214 if ( !rom )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
215 return "Out of memory";
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
216 memset( rom, 0, rom_size );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
217 blargg_err_t err = in.read( &rom [load_addr], in.remain() );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
218 if ( err ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
219 unload();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
220 return err;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
221 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
222
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
223 // cpu
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
224 cpu.rst_base = load_addr;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
225 cpu.map_code( 0x0000, 0x4000, rom );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
226
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
227 voice_count_ = Gb_Apu::osc_count;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
228 track_count_ = h.track_count;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
229
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
230 return setup_buffer( clock_rate );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
231 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
232
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
233 const char** Gbs_Emu::voice_names() const
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
234 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
235 static const char* names [] = { "Square 1", "Square 2", "Wave", "Noise" };
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
236 return names;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
237 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
238
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
239 // Emulation
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
240
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
241 static const BOOST::uint8_t sound_data [Gb_Apu::register_count] = {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
242 0x80, 0xbf, 0x00, 0x00, 0xbf, // square 1
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
243 0x00, 0x3f, 0x00, 0x00, 0xbf, // square 2
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
244 0x7f, 0xff, 0x9f, 0x00, 0xbf, // wave
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
245 0x00, 0xff, 0x00, 0x00, 0xbf, // noise
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
246
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
247 0x77, 0xf3, 0xf1, // vin/volume, status, power mode
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
248
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
249 0, 0, 0, 0, 0, 0, 0, 0, 0, // unused
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
250
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
251 0xac, 0xdd, 0xda, 0x48, 0x36, 0x02, 0xcf, 0x16, // waveform data
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
252 0x2c, 0x04, 0xe5, 0x2c, 0xac, 0xdd, 0xda, 0x48
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
253 };
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
254
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
255 void Gbs_Emu::cpu_jsr( gb_addr_t addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
256 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
257 cpu.write( --cpu.r.sp, cpu.r.pc >> 8 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
258 cpu.write( --cpu.r.sp, cpu.r.pc&0xff );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
259 cpu.r.pc = addr;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
260 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
261
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
262 blargg_err_t Gbs_Emu::start_track( int track_index )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
263 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
264 require( rom ); // file must be loaded
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
265 require( (unsigned) track_index < track_count() );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
266
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
267 starting_track();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
268
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
269 apu.reset();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
270
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
271 memset( ram, 0, sizeof ram );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
272 memset( hi_page, 0, sizeof hi_page );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
273
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
274 // configure hardware
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
275 set_bank( bank_count > 1 );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
276 for ( int i = 0; i < sizeof sound_data; i++ )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
277 apu.write_register( 0, i + apu.start_addr, sound_data [i] );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
278 play_period = 70224; // 59.73 Hz
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
279 set_timer( timer_modulo_init, timer_mode ); // ignored if using vbl
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
280 next_play = play_period;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
281
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
282 // set up init call
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
283 cpu.r.a = track_index;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
284 cpu.r.b = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
285 cpu.r.c = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
286 cpu.r.d = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
287 cpu.r.e = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
288 cpu.r.h = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
289 cpu.r.l = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
290 cpu.r.flags = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
291 cpu.r.pc = halt_addr;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
292 cpu.r.sp = stack_ptr;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
293 cpu_jsr( init_addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
294
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
295 return blargg_success;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
296 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
297
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
298 blip_time_t Gbs_Emu::run( int msec, bool* added_stereo )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
299 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
300 require( rom ); // file must be loaded
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
301
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
302 gb_time_t duration = clock_rate * (1.0 / 1000.0) * msec;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
303 cpu_time = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
304 while ( cpu_time < duration )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
305 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
306 // check for idle cpu
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
307 if ( cpu.r.pc == halt_addr )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
308 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
309 if ( next_play > duration ) {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
310 cpu_time = duration;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
311 break;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
312 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
313
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
314 if ( cpu_time < next_play )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
315 cpu_time = next_play;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
316 next_play += play_period;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
317 cpu_jsr( play_addr );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
318 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
319
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
320 long count = duration - cpu_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
321 cpu_time = duration;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
322 Gb_Cpu::result_t result = cpu.run( count );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
323 cpu_time -= cpu.remain();
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
324
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
325 if ( (result == Gb_Cpu::result_halt && cpu.r.pc != halt_addr) ||
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
326 result == Gb_Cpu::result_badop )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
327 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
328 if ( result == Gb_Cpu::result_halt && cpu.r.pc < cpu.page_size )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
329 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
330 dprintf( "PC wrapped around\n" );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
331 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
332 else
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
333 {
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
334 dprintf( "Bad opcode $%.2x at $%.4x\n",
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
335 (int) cpu.read( cpu.r.pc ), (int) cpu.r.pc );
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
336 return 0; // error
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
337 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
338 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
339 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
340
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
341 // end time frame
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
342
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
343 next_play -= cpu_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
344 if ( next_play < 0 ) // could go negative if routine is taking too long to return
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
345 next_play = 0;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
346
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
347 if ( apu.end_frame( cpu_time ) && added_stereo )
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
348 *added_stereo = true;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
349
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
350 return cpu_time;
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
351 }
252843aac42f [svn] Import the initial sources for console music support.
nenolod
parents:
diff changeset
352