annotate src/console/Hes_Emu.cxx @ 323:230decbfe9be trunk

[svn] - what would we have ever done without Aerdan?
author nenolod
date Thu, 30 Nov 2006 23:02:05 -0800
parents fb513e10174e
children 986f098da058
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
1 // Game_Music_Emu 0.5.1. http://www.slack.net/~ant/
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
2
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
3 #include "Hes_Emu.h"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
4
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
5 #include "blargg_endian.h"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
6 #include <string.h>
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
7
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
8 /* Copyright (C) 2006 Shay Green. This module is free software; you
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
9 can redistribute it and/or modify it under the terms of the GNU Lesser
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
10 General Public License as published by the Free Software Foundation; either
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
11 version 2.1 of the License, or (at your option) any later version. This
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
12 module is distributed in the hope that it will be useful, but WITHOUT ANY
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
15 details. You should have received a copy of the GNU Lesser General Public
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
16 License along with this module; if not, write to the Free Software Foundation,
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
18
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
19 #include "blargg_source.h"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
20
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
21 int const timer_mask = 0x04;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
22 int const vdp_mask = 0x02;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
23 int const i_flag_mask = 0x04;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
24 int const unmapped = 0xFF;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
25
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
26 long const period_60hz = 262 * 455L; // scanlines * clocks per scanline
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
27
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
28 Hes_Emu::Hes_Emu()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
29 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
30 timer.raw_load = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
31 set_type( gme_hes_type );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
32
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
33 static const char* const names [Hes_Apu::osc_count] = {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
34 "Wave 1", "Wave 2", "Wave 3", "Wave 4", "Multi 1", "Multi 2"
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
35 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
36 set_voice_names( names );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
37
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
38 static int const types [Hes_Apu::osc_count] = {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
39 wave_type | 0, wave_type | 1, wave_type | 2, wave_type | 3,
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
40 mixed_type | 0, mixed_type | 1
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
41 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
42 set_voice_types( types );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
43 set_silence_lookahead( 6 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
44 set_gain( 1.11 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
45 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
46
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
47 Hes_Emu::~Hes_Emu() { }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
48
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
49 void Hes_Emu::unload()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
50 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
51 rom.clear();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
52 Music_Emu::unload();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
53 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
54
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
55 // Track info
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
56
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
57 static byte const* copy_field( byte const* in, char* out )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
58 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
59 if ( in )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
60 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
61 int len = 0x20;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
62 if ( in [0x1F] && !in [0x2F] )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
63 len = 0x30; // fields are sometimes 16 bytes longer (ugh)
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
64
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
65 // since text fields are where any data could be, detect non-text
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
66 // and fields with data after zero byte terminator
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
67
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
68 int i = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
69 for ( i = 0; i < len && in [i]; i++ )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
70 if ( ((in [i] + 1) & 0xFF) < ' ' + 1 ) // also treat 0xFF as non-text
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
71 return 0; // non-ASCII found
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
72
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
73 for ( ; i < len; i++ )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
74 if ( in [i] )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
75 return 0; // data after terminator
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
76
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
77 Gme_File::copy_field_( out, (char const*) in, len );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
78 in += len;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
79 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
80 return in;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
81 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
82
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
83 static void copy_hes_fields( byte const* in, track_info_t* out )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
84 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
85 if ( *in >= ' ' )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
86 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
87 in = copy_field( in, out->game );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
88 in = copy_field( in, out->author );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
89 in = copy_field( in, out->copyright );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
90 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
91 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
92
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
93 blargg_err_t Hes_Emu::track_info_( track_info_t* out, int ) const
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
94 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
95 copy_hes_fields( rom.begin() + 0x20, out );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
96 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
97 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
98
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
99 static blargg_err_t check_hes_header( void const* header )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
100 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
101 if ( memcmp( header, "HESM", 4 ) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
102 return gme_wrong_file_type;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
103 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
104 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
105
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
106 struct Hes_File : Gme_Info_
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
107 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
108 struct {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
109 Hes_Emu::header_t h;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
110 char unused [0x20];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
111 byte fields [0x30 * 3];
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
112 } h;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
113
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
114 Hes_File() { set_type( gme_hes_type ); }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
115
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
116 blargg_err_t load_( Data_Reader& in )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
117 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
118 blargg_err_t err = in.read( &h, sizeof h );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
119 if ( err )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
120 return (err == in.eof_error ? gme_wrong_file_type : err);
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
121 return check_hes_header( &h );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
122 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
123
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
124 blargg_err_t track_info_( track_info_t* out, int ) const
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
125 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
126 copy_hes_fields( h.fields, out );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
127 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
128 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
129 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
130
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
131 static Music_Emu* new_hes_emu () { return BLARGG_NEW Hes_Emu ; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
132 static Music_Emu* new_hes_file() { return BLARGG_NEW Hes_File; }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
133
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
134 gme_type_t_ const gme_hes_type [1] = { "PC Engine", 256, &new_hes_emu, &new_hes_file, "HES", 1 };
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
135
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
136 // Setup
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
137
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
138 blargg_err_t Hes_Emu::load_( Data_Reader& in )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
139 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
140 RETURN_ERR( rom.load( in, sizeof header_, &header_, unmapped ) );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
141
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
142 RETURN_ERR( check_hes_header( header_.tag ) );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
143
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
144 if ( header_.vers != 0 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
145 set_warning( "Unknown file version" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
146
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
147 if ( memcmp( header_.data_tag, "DATA", 4 ) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
148 set_warning( "Data header missing" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
149
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
150 if ( memcmp( header_.unused, "\0\0\0\0", 4 ) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
151 set_warning( "Unknown header data" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
152
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
153 // File spec supports multiple blocks, but I haven't found any, and
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
154 // many files have bad sizes in the only block, so it's simpler to
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
155 // just try to load the damn data as best as possible.
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
156
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
157 long addr = get_le32( header_.addr );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
158 long size = get_le32( header_.size );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
159 long const rom_max = 0x100000;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
160 if ( addr & ~(rom_max - 1) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
161 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
162 set_warning( "Invalid address" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
163 addr &= rom_max - 1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
164 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
165 if ( (unsigned long) (addr + size) > (unsigned long) rom_max )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
166 set_warning( "Invalid size" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
167
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
168 if ( size != rom.file_size() )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
169 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
170 if ( size <= rom.file_size() - 4 && !memcmp( rom.begin() + size, "DATA", 4 ) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
171 set_warning( "Multiple DATA not supported" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
172 else if ( size < rom.file_size() )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
173 set_warning( "Extra file data" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
174 else
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
175 set_warning( "Missing file data" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
176 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
177
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
178 rom.set_addr( addr );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
179
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
180 set_voice_count( apu.osc_count );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
181
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
182 apu.volume( gain() );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
183
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
184 return setup_buffer( 7159091 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
185 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
186
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
187 void Hes_Emu::update_eq( blip_eq_t const& eq )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
188 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
189 apu.treble_eq( eq );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
190 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
191
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
192 void Hes_Emu::set_voice( int i, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
193 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
194 apu.osc_output( i, center, left, right );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
195 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
196
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
197 // Emulation
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
198
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
199 void Hes_Emu::recalc_timer_load()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
200 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
201 timer.load = timer.raw_load * timer_base + 1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
202 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
203
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
204 void Hes_Emu::set_tempo_( double t )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
205 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
206 play_period = hes_time_t (period_60hz / t);
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
207 timer_base = int (1024 / t);
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
208 recalc_timer_load();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
209 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
210
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
211 blargg_err_t Hes_Emu::start_track_( int track )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
212 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
213 RETURN_ERR( Classic_Emu::start_track_( track ) );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
214
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
215 memset( ram, 0, sizeof ram ); // some HES music relies on zero fill
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
216 memset( sgx, 0, sizeof sgx );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
217
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
218 apu.reset();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
219 cpu::reset();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
220
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
221 for ( unsigned i = 0; i < sizeof header_.banks; i++ )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
222 set_mmr( i, header_.banks [i] );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
223 set_mmr( page_count, 0xFF ); // unmapped beyond end of address space
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
224
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
225 irq.disables = timer_mask | vdp_mask;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
226 irq.timer = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
227 irq.vdp = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
228
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
229 timer.enabled = false;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
230 timer.raw_load= 0x80;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
231 timer.count = timer.load;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
232 timer.fired = false;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
233 timer.last_time = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
234
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
235 vdp.latch = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
236 vdp.control = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
237 vdp.next_vbl = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
238
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
239 ram [0x1FF] = (idle_addr - 1) >> 8;
323
230decbfe9be [svn] - what would we have ever done without Aerdan?
nenolod
parents: 316
diff changeset
240 ram [0x1FE] = (idle_addr - 1) & 0xFF;
316
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
241 r.sp = 0xFD;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
242 r.pc = get_le16( header_.init_addr );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
243 r.a = track;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
244
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
245 recalc_timer_load();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
246
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
247 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
248 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
249
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
250 // Hardware
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
251
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
252 void Hes_Emu::cpu_write_vdp( int addr, int data )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
253 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
254 switch ( addr )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
255 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
256 case 0:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
257 vdp.latch = data & 0x1F;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
258 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
259
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
260 case 2:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
261 if ( vdp.latch == 5 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
262 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
263 if ( data & 0x04 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
264 set_warning( "Scanline interrupt unsupported" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
265 run_until( time() );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
266 vdp.control = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
267 irq_changed();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
268 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
269 else
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
270 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
271 dprintf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
272 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
273 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
274
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
275 case 3:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
276 dprintf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
277 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
278 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
279 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
280
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
281 void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
282 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
283 if ( unsigned (addr - apu.start_addr) <= apu.end_addr - apu.start_addr )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
284 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
285 // avoid going way past end when a long block xfer is writing to I/O space
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
286 hes_time_t t = min( time(), end_time() + 8 );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
287 apu.write_data( t, addr, data );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
288 return;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
289 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
290
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
291 hes_time_t time = this->time();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
292 switch ( addr )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
293 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
294 case 0x0000:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
295 case 0x0002:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
296 case 0x0003:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
297 cpu_write_vdp( addr, data );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
298 return;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
299
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
300 case 0x0C00: {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
301 run_until( time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
302 timer.raw_load = (data & 0x7F) + 1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
303 recalc_timer_load();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
304 timer.count = timer.load;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
305 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
306 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
307
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
308 case 0x0C01:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
309 data &= 1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
310 if ( timer.enabled == data )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
311 return;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
312 run_until( time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
313 timer.enabled = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
314 if ( data )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
315 timer.count = timer.load;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
316 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
317
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
318 case 0x1402:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
319 run_until( time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
320 irq.disables = data;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
321 if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
322 dprintf( "Int mask: $%02X\n", data );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
323 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
324
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
325 case 0x1403:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
326 run_until( time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
327 if ( timer.enabled )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
328 timer.count = timer.load;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
329 timer.fired = false;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
330 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
331
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
332 #ifndef NDEBUG
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
333 case 0x1000: // I/O port
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
334 case 0x0402: // palette
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
335 case 0x0403:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
336 case 0x0404:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
337 case 0x0405:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
338 return;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
339
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
340 default:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
341 dprintf( "unmapped write $%04X <- $%02X\n", addr, data );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
342 return;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
343 #endif
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
344 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
345
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
346 irq_changed();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
347 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
348
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
349 int Hes_Emu::cpu_read_( hes_addr_t addr )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
350 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
351 hes_time_t time = this->time();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
352 addr &= page_size - 1;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
353 switch ( addr )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
354 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
355 case 0x0000:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
356 if ( irq.vdp > time )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
357 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
358 irq.vdp = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
359 run_until( time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
360 irq_changed();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
361 return 0x20;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
362
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
363 case 0x0002:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
364 case 0x0003:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
365 dprintf( "VDP read not supported: %d\n", addr );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
366 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
367
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
368 case 0x0C01:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
369 //return timer.enabled; // TODO: remove?
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
370 case 0x0C00:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
371 run_until( time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
372 dprintf( "Timer count read\n" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
373 return (unsigned) (timer.count - 1) / timer_base;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
374
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
375 case 0x1402:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
376 return irq.disables;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
377
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
378 case 0x1403:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
379 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
380 int status = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
381 if ( irq.timer <= time ) status |= timer_mask;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
382 if ( irq.vdp <= time ) status |= vdp_mask;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
383 return status;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
384 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
385
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
386 #ifndef NDEBUG
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
387 case 0x1000: // I/O port
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
388 case 0x180C: // CD-ROM
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
389 case 0x180D:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
390 break;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
391
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
392 default:
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
393 dprintf( "unmapped read $%04X\n", addr );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
394 #endif
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
395 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
396
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
397 return unmapped;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
398 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
399
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
400 // see hes_cpu_io.h for core read/write functions
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
401
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
402 // Emulation
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
403
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
404 void Hes_Emu::run_until( hes_time_t present )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
405 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
406 while ( vdp.next_vbl < present )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
407 vdp.next_vbl += play_period;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
408
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
409 hes_time_t elapsed = present - timer.last_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
410 if ( elapsed > 0 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
411 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
412 if ( timer.enabled )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
413 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
414 timer.count -= elapsed;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
415 if ( timer.count <= 0 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
416 timer.count += timer.load;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
417 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
418 timer.last_time = present;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
419 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
420 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
421
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
422 void Hes_Emu::irq_changed()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
423 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
424 hes_time_t present = time();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
425
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
426 if ( irq.timer > present )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
427 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
428 irq.timer = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
429 if ( timer.enabled && !timer.fired )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
430 irq.timer = present + timer.count;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
431 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
432
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
433 if ( irq.vdp > present )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
434 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
435 irq.vdp = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
436 if ( vdp.control & 0x08 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
437 irq.vdp = vdp.next_vbl;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
438 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
439
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
440 hes_time_t time = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
441 if ( !(irq.disables & timer_mask) ) time = irq.timer;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
442 if ( !(irq.disables & vdp_mask) ) time = min( time, irq.vdp );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
443
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
444 set_irq_time( time );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
445 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
446
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
447 int Hes_Emu::cpu_done()
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
448 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
449 check( time() >= end_time() ||
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
450 (!(r.status & i_flag_mask) && time() >= irq_time()) );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
451
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
452 if ( !(r.status & i_flag_mask) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
453 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
454 hes_time_t present = time();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
455
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
456 if ( irq.timer <= present && !(irq.disables & timer_mask) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
457 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
458 timer.fired = true;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
459 irq.timer = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
460 irq_changed(); // overkill, but not worth writing custom code
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
461 return 0x0A;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
462 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
463
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
464 if ( irq.vdp <= present && !(irq.disables & vdp_mask) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
465 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
466 // work around for bugs with music not acknowledging VDP
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
467 //run_until( present );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
468 //irq.vdp = future_hes_time;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
469 //irq_changed();
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
470 return 0x08;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
471 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
472 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
473 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
474 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
475
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
476 static void adjust_time( blargg_long& time, hes_time_t delta )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
477 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
478 if ( time < future_hes_time )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
479 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
480 time -= delta;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
481 if ( time < 0 )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
482 time = 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
483 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
484 }
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
485
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
486 blargg_err_t Hes_Emu::run_clocks( blip_time_t& duration_, int )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
487 {
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
488 blip_time_t const duration = duration_; // cache
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
489
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
490 if ( cpu::run( duration ) )
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
491 set_warning( "Emulation error (illegal instruction)" );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
492
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
493 check( time() >= duration );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
494 //check( time() - duration < 20 ); // Txx instruction could cause going way over
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
495
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
496 run_until( duration );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
497
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
498 // end time frame
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
499 timer.last_time -= duration;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
500 vdp.next_vbl -= duration;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
501 cpu::end_frame( duration );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
502 ::adjust_time( irq.timer, duration );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
503 ::adjust_time( irq.vdp, duration );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
504 apu.end_frame( duration );
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
505
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
506 return 0;
fb513e10174e [svn] - merge libconsole-blargg into mainline libconsole:
nenolod
parents:
diff changeset
507 }