Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/quicknes/nes_emu/Mapper_Namco106.cpp
2 views
1
2
// Namco 106 mapper
3
4
// Nes_Emu 0.7.0. http://www.slack.net/~ant/
5
6
#include "Nes_Mapper.h"
7
8
#include "Nes_Namco_Apu.h"
9
10
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
11
can redistribute it and/or modify it under the terms of the GNU Lesser
12
General Public License as published by the Free Software Foundation; either
13
version 2.1 of the License, or (at your option) any later version. This
14
module is distributed in the hope that it will be useful, but WITHOUT ANY
15
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17
more details. You should have received a copy of the GNU Lesser General
18
Public License along with this module; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
21
#include "blargg_source.h"
22
23
// to do: CHR mapping and nametable handling needs work
24
25
struct namco106_state_t
26
{
27
BOOST::uint8_t regs [16];
28
BOOST::uint16_t irq_ctr;
29
BOOST::uint8_t irq_pending;
30
BOOST::uint8_t unused1 [1];
31
};
32
BOOST_STATIC_ASSERT( sizeof (namco106_state_t) == 20 );
33
34
class Mapper_Namco106 : public Nes_Mapper, namco106_state_t {
35
Nes_Namco_Apu sound;
36
nes_time_t last_time;
37
public:
38
Mapper_Namco106()
39
{
40
namco106_state_t* state = this;
41
register_state( state, sizeof *state );
42
}
43
44
virtual int channel_count() const { return sound.osc_count; }
45
46
virtual void set_channel_buf( int i, Blip_Buffer* b ) { sound.osc_output( i, b ); }
47
48
virtual void set_treble( blip_eq_t const& eq ) { sound.treble_eq( eq ); }
49
50
void reset_state()
51
{
52
regs [12] = 0;
53
regs [13] = 1;
54
regs [14] = last_bank - 1;
55
sound.reset();
56
}
57
58
virtual void apply_mapping()
59
{
60
last_time = 0;
61
enable_sram();
62
intercept_writes( 0x4800, 1 );
63
intercept_reads ( 0x4800, 1 );
64
65
intercept_writes( 0x5000, 0x1000 );
66
intercept_reads ( 0x5000, 0x1000 );
67
68
for ( int i = 0; i < (int) sizeof regs; i++ )
69
write( 0, 0x8000 + i * 0x800, regs [i] );
70
}
71
72
virtual nes_time_t next_irq( nes_time_t time )
73
{
74
if ( irq_pending )
75
return time;
76
77
if ( !(irq_ctr & 0x8000) )
78
return no_irq;
79
80
return 0x10000 - irq_ctr + last_time;
81
}
82
83
virtual void run_until( nes_time_t end_time )
84
{
85
long count = irq_ctr + (end_time - last_time);
86
if ( irq_ctr & 0x8000 )
87
{
88
if ( count > 0xffff )
89
{
90
count = 0xffff;
91
irq_pending = true;
92
}
93
}
94
else if ( count > 0x7fff )
95
{
96
count = 0x7fff;
97
}
98
99
irq_ctr = count;
100
last_time = end_time;
101
}
102
103
virtual void end_frame( nes_time_t end_time )
104
{
105
if ( end_time > last_time )
106
run_until( end_time );
107
last_time -= end_time;
108
assert( last_time >= 0 );
109
sound.end_frame( end_time );
110
}
111
112
void write_bank( nes_addr_t, int data );
113
void write_irq( nes_time_t, nes_addr_t, int data );
114
115
virtual int read( nes_time_t time, nes_addr_t addr )
116
{
117
if ( addr == 0x4800 )
118
return sound.read_data();
119
120
if ( addr == 0x5000 )
121
{
122
irq_pending = false;
123
return irq_ctr & 0xff;
124
}
125
126
if ( addr == 0x5800 )
127
{
128
irq_pending = false;
129
return irq_ctr >> 8;
130
}
131
132
return Nes_Mapper::read( time, addr );
133
}
134
135
virtual bool write_intercepted( nes_time_t time, nes_addr_t addr, int data )
136
{
137
if ( addr == 0x4800 )
138
{
139
sound.write_data( time, data );
140
}
141
else if ( addr == 0x5000 )
142
{
143
irq_ctr = (irq_ctr & 0xff00) | data;
144
irq_pending = false;
145
irq_changed();
146
}
147
else if ( addr == 0x5800 )
148
{
149
irq_ctr = (data << 8) | (irq_ctr & 0xff);
150
irq_pending = false;
151
irq_changed();
152
}
153
else
154
{
155
return false;
156
}
157
158
return true;
159
}
160
161
virtual void write( nes_time_t, nes_addr_t addr, int data )
162
{
163
int reg = addr >> 11 & 0x0F;
164
regs [reg] = data;
165
166
int prg_bank = reg - 0x0c;
167
if ( (unsigned) prg_bank < 3 )
168
{
169
if ( prg_bank == 0 && (data & 0x40) )
170
mirror_vert();
171
set_prg_bank( 0x8000 | (prg_bank << bank_8k), bank_8k, data & 0x3F );
172
}
173
else if ( reg < 8 )
174
{
175
set_chr_bank( reg * 0x400, bank_1k, data );
176
}
177
else if ( reg < 0x0c )
178
{
179
mirror_manual( regs [8] & 1, regs [9] & 1, regs [10] & 1, regs [11] & 1 );
180
}
181
else
182
{
183
sound.write_addr( data );
184
}
185
}
186
};
187
188
void register_namco106_mapper();
189
void register_namco106_mapper()
190
{
191
register_mapper<Mapper_Namco106>( 19 );
192
}
193
194
// in the most obscure place in case crappy linker is used
195
void register_optional_mappers();
196
void register_optional_mappers()
197
{
198
extern void register_misc_mappers();
199
register_misc_mappers();
200
201
extern void register_vrc6_mapper();
202
register_vrc6_mapper();
203
204
//extern void register_mmc5_mapper();
205
//register_mmc5_mapper();
206
207
extern void register_fme7_mapper();
208
register_fme7_mapper();
209
210
extern void register_namco106_mapper();
211
register_namco106_mapper();
212
213
extern void register_mmc24();
214
register_mmc24();
215
}
216
217
218