1
/***************************************************************************
5
Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
8
***************************************************************************/
11
#include "cpu/z80/z80.h"
12
#include "sound/msm5205.h"
13
#include "includes/stfight.h"
15
// this prototype will move to the driver
16
static WRITE8_HANDLER( stfight_bank_w );
21
Encryption PAL 16R4 on CPU board
25
ROM D1 --| |-- ROM D0 M1 = 0 M1 = 1
27
ROM D4 --| |-- D6 D6 = D1 ^^ D3 D6 = / ( D1 ^^ D0 )
28
ROM D6 --| |-- D4 D4 = / ( D6 ^^ A7 ) D4 = D3 ^^ A0
29
A0 --| |-- D3 D3 = / ( D0 ^^ A1 ) D3 = D4 ^^ A4
30
A1 --| |-- D0 D0 = D1 ^^ D4 D0 = / ( D6 ^^ A0 )
39
DRIVER_INIT( empcity )
41
stfight_state *state = machine.driver_data<stfight_state>();
42
address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);
43
UINT8 *rom = machine.region("maincpu")->base();
46
state->m_decrypt = auto_alloc_array(machine, UINT8, 0x8000);
47
space->set_decrypted_region(0x0000, 0x7fff, state->m_decrypt);
49
for (A = 0;A < 0x8000;A++)
56
( ( ( ( src << 2 ) ^ src ) << 3 ) & 0x40 ) |
57
( ~( ( src ^ ( A >> 1 ) ) >> 2 ) & 0x10 ) |
58
( ~( ( ( src << 1 ) ^ A ) << 2 ) & 0x08 ) |
59
( ( ( src ^ ( src >> 3 ) ) >> 1 ) & 0x01 );
64
( ~( ( src ^ ( src << 1 ) ) << 5 ) & 0x40 ) |
65
( ( ( src ^ ( A << 3 ) ) << 1 ) & 0x10 ) |
66
( ( ( src ^ A ) >> 1 ) & 0x08 ) |
67
( ~( ( src >> 6 ) ^ A ) & 0x01 );
71
DRIVER_INIT( stfight )
73
stfight_state *state = machine.driver_data<stfight_state>();
74
DRIVER_INIT_CALL(empcity);
76
/* patch out a tight loop during startup - is the code waiting */
77
/* for NMI to wake it up? */
78
state->m_decrypt[0xb1] = 0x00;
79
state->m_decrypt[0xb2] = 0x00;
80
state->m_decrypt[0xb3] = 0x00;
81
state->m_decrypt[0xb4] = 0x00;
82
state->m_decrypt[0xb5] = 0x00;
85
MACHINE_RESET( stfight )
87
stfight_state *state = machine.driver_data<stfight_state>();
88
address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM);
89
state->m_adpcm_data_offs = state->m_adpcm_data_end = 0;
92
state->m_coin_mech_latch[0] = 0x02;
93
state->m_coin_mech_latch[1] = 0x01;
95
state->m_coin_mech_query_active = 0;
96
state->m_coin_mech_query = 0;
98
// initialise rom bank
99
stfight_bank_w( space, 0, 0 );
102
// It's entirely possible that this bank is never switched out
103
// - in fact I don't even know how/where it's switched in!
104
static WRITE8_HANDLER( stfight_bank_w )
106
UINT8 *ROM2 = space->machine().region("maincpu")->base() + 0x10000;
108
memory_set_bankptr(space->machine(), "bank1", &ROM2[data<<14] );
112
* CPU 1 timed interrupt - 60Hz???
115
static TIMER_CALLBACK( stfight_interrupt_1 )
118
cputag_set_input_line_and_vector(machine, "maincpu", 0, HOLD_LINE, 0xcf);
121
INTERRUPT_GEN( stfight_vb_interrupt )
124
device_set_input_line_and_vector(device, 0, HOLD_LINE, 0xd7);
125
device->machine().scheduler().timer_set(attotime::from_hz(120), FUNC(stfight_interrupt_1));
132
// Perhaps define dipswitches as active low?
133
READ8_HANDLER( stfight_dsw_r )
135
return( ~input_port_read(space->machine(), offset ? "DSW1" : "DSW0") );
138
READ8_HANDLER( stfight_coin_r )
140
stfight_state *state = space->machine().driver_data<stfight_state>();
144
// Was the coin mech queried by software?
145
if( state->m_coin_mech_query_active )
147
state->m_coin_mech_query_active = 0;
148
return( (~state->m_coin_mech_query) & 0x03 );
152
* Is this really necessary?
153
* - we can control impulse length so that the port is
154
* never strobed twice within the impulse period
155
* since it's read by the 30Hz interrupt ISR
158
coin_mech_data = input_port_read(space->machine(), "COIN");
162
/* Only valid on signal edge */
163
if( ( coin_mech_data & (1<<i) ) != state->m_coin_mech_latch[i] )
164
state->m_coin_mech_latch[i] = coin_mech_data & (1<<i);
166
coin_mech_data |= coin_mech_data & (1<<i);
169
return( coin_mech_data );
172
WRITE8_HANDLER( stfight_coin_w )
174
stfight_state *state = space->machine().driver_data<stfight_state>();
175
// interrogate coin mech
176
state->m_coin_mech_query_active = 1;
177
state->m_coin_mech_query = data;
181
* Machine hardware for MSM5205 ADPCM sound control
184
static const int sampleLimits[] =
186
0x0000, // machine gun fire?
187
0x1000, // player getting shot
188
0x2C00, // player shooting
189
0x3C00, // girl screaming
190
0x5400, // girl getting shot
191
0x7200 // (end of samples)
194
void stfight_adpcm_int(device_t *device)
196
stfight_state *state = device->machine().driver_data<stfight_state>();
197
UINT8 *SAMPLES = device->machine().region("adpcm")->base();
198
int adpcm_data = SAMPLES[state->m_adpcm_data_offs & 0x7fff];
200
// finished playing sample?
201
if( state->m_adpcm_data_offs == state->m_adpcm_data_end )
203
msm5205_reset_w( device, 1 );
207
if( state->m_toggle == 0 )
208
msm5205_data_w( device, ( adpcm_data >> 4 ) & 0x0f );
211
msm5205_data_w( device, adpcm_data & 0x0f );
212
state->m_adpcm_data_offs++;
215
state->m_toggle ^= 1;
218
WRITE8_DEVICE_HANDLER( stfight_adpcm_control_w )
220
stfight_state *state = device->machine().driver_data<stfight_state>();
223
state->m_adpcm_data_offs = sampleLimits[data];
224
state->m_adpcm_data_end = sampleLimits[data+1];
227
msm5205_reset_w( device, data & 0x08 ? 1 : 0 );
230
WRITE8_HANDLER( stfight_e800_w )
235
* Machine hardware for YM2303 fm sound control
238
WRITE8_HANDLER( stfight_fm_w )
240
stfight_state *state = space->machine().driver_data<stfight_state>();
241
// the sound cpu ignores any fm data without bit 7 set
242
state->m_fm_data = 0x80 | data;
245
READ8_HANDLER( stfight_fm_r )
247
stfight_state *state = space->machine().driver_data<stfight_state>();
248
int data = state->m_fm_data;
250
// clear the latch?!?
251
state->m_fm_data &= 0x7f;