summaryrefslogtreecommitdiffstats
path: root/src/mame/includes/turbo.h
blob: 38f4fa3613779b1ccd70810e8b29a57eb40500b4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
// license:BSD-3-Clause
// copyright-holders:Alex Pasadyn, Howie Cohen, Frank Palazzolo, Ernesto Corvi, Aaron Giles
/*************************************************************************

    Sega Z80-3D system

*************************************************************************/
#ifndef MAME_INCLUDES_TURBO_H
#define MAME_INCLUDES_TURBO_H

#pragma once

#include "cpu/z80/z80.h"
#include "machine/i8255.h"
#include "sound/discrete.h"
#include "sound/samples.h"
#include "emupal.h"
#include "screen.h"
#include "tilemap.h"

// sprites are scaled in the analog domain; to give a better rendition of this, we scale in the X direction by this factor

#define TURBO_X_SCALE       2



class turbo_base_state : public driver_device
{
public:
	turbo_base_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")
		, m_i8255(*this, "i8255%u", 0U)
		, m_spriteroms(*this, "sprites")
		, m_proms(*this, "proms")
		, m_videoram(*this, "videoram")
		, m_sprite_position(*this, "spritepos")
		, m_samples(*this, "samples")
		, m_gfxdecode(*this, "gfxdecode")
		, m_screen(*this, "screen")
		, m_digits(*this, "digit%u", 0U)
		, m_lamp(*this, "lamp")
	{ }

protected:
	virtual void machine_start() override;
	virtual void video_start() override;

	// device / memory pointers
	required_device<z80_device> m_maincpu;
	optional_device_array<i8255_device, 4> m_i8255;

	required_region_ptr<uint8_t> m_spriteroms;
	required_region_ptr<uint8_t> m_proms;

	required_shared_ptr<uint8_t> m_videoram;
	required_shared_ptr<uint8_t> m_sprite_position;

	required_device<samples_device> m_samples;

	required_device<gfxdecode_device> m_gfxdecode;
	required_device<screen_device> m_screen;
	output_finder<32> m_digits;
	output_finder<> m_lamp;

	// machine state
	uint8_t       m_i8279_scanlines = 0;

	// sound state
	uint8_t       m_sound_state[3]{};

	// video state
	tilemap_t * m_fg_tilemap = nullptr;

	struct sprite_info
	{
		uint16_t  ve = 0;                 // VE0-15 signals for this row
		uint8_t   lst = 0;                // LST0-7 signals for this row
		uint32_t  latched[8]{};         // latched pixel data
		uint8_t   plb[8]{};             // latched PLB state
		uint32_t  offset[8]{};          // current offset for this row
		uint32_t  frac[8]{};            // leftover fraction
		uint32_t  step[8]{};            // stepping value
	};

	sprite_info m_sprite_info;

	void scanlines_w(uint8_t data);
	void digit_w(uint8_t data);
	void videoram_w(offs_t offset, uint8_t data);
	TILE_GET_INFO_MEMBER(get_fg_tile_info);
	inline uint32_t sprite_xscale(uint8_t dacinput, double vr1, double vr2, double cext);
};

class buckrog_state : public turbo_base_state
{
public:
	buckrog_state(const machine_config &mconfig, device_type type, const char *tag)
		: turbo_base_state(mconfig, type, tag)
		, m_subcpu(*this, "subcpu")
		, m_decrypted_opcodes(*this, "decrypted_opcodes")
		, m_spriteram(*this, "spriteram")
		, m_bitmap_ram(*this, "bitmap_ram", 0xe000, ENDIANNESS_LITTLE)
		, m_bgcolorrom(*this, "bgcolor")
		, m_dsw(*this, "DSW%u", 1U)
	{ }

	void buckrog(machine_config &config);
	void buckroge(machine_config &config);
	void buckrogu(machine_config &config);
	void buckrog_samples(machine_config &config);

protected:
	virtual void machine_start() override;
	virtual void machine_reset() override;

private:
	required_device<z80_device> m_subcpu;
	optional_shared_ptr<uint8_t> m_decrypted_opcodes;
	required_shared_ptr<uint8_t> m_spriteram;
	memory_share_creator<uint8_t> m_bitmap_ram;
	required_region_ptr<uint8_t> m_bgcolorrom;
	required_ioport_array<2> m_dsw;

	uint8_t       m_fchg;
	uint8_t       m_mov;
	uint8_t       m_obch;
	uint8_t       m_command;
	uint8_t       m_myship;
	uint8_t       m_last_sound_a;

	uint8_t subcpu_command_r();
	uint8_t port_2_r();
	uint8_t port_3_r();
	void bitmap_w(offs_t offset, uint8_t data);
	void ppi0a_w(uint8_t data);
	void ppi0b_w(uint8_t data);
	void ppi0c_w(uint8_t data);
	void ppi1c_w(uint8_t data);
	void palette(palette_device &palette) const;
	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
	void i8255_0_w(offs_t offset, uint8_t data);
	TIMER_CALLBACK_MEMBER(delayed_i8255_w);
	void sound_a_w(uint8_t data);
	void sound_b_w(uint8_t data);
	void prepare_sprites(uint8_t y);
	uint32_t get_sprite_bits(uint8_t *plb);
	void update_samples();

	void decrypted_opcodes_map(address_map &map);
	void main_prg_map(address_map &map);
	void sub_prg_map(address_map &map);
	void sub_portmap(address_map &map);
};

class subroc3d_state : public turbo_base_state
{
public:
	subroc3d_state(const machine_config &mconfig, device_type type, const char *tag)
		: turbo_base_state(mconfig, type, tag)
		, m_spriteram(*this, "spriteram")
	{ }

	void subroc3d(machine_config &config);
	void subroc3d_samples(machine_config &config);

protected:
	virtual void machine_start() override;

private:
	required_shared_ptr<uint8_t> m_spriteram;

	uint8_t       m_col = 0;
	uint8_t       m_ply = 0;
	uint8_t       m_flip = 0;
	uint8_t       m_mdis = 0;
	uint8_t       m_mdir = 0;
	uint8_t       m_tdis = 0;
	uint8_t       m_tdir = 0;
	uint8_t       m_fdis = 0;
	uint8_t       m_fdir = 0;
	uint8_t       m_hdis = 0;
	uint8_t       m_hdir = 0;

	void ppi0a_w(uint8_t data);
	void ppi0b_w(uint8_t data);
	void ppi0c_w(uint8_t data);
	void palette(palette_device &palette) const;
	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
	void sound_a_w(uint8_t data);
	void sound_b_w(uint8_t data);
	void sound_c_w(uint8_t data);
	void prepare_sprites(uint8_t y);
	uint32_t get_sprite_bits(uint8_t *plb);
	inline void update_volume(int leftchan, uint8_t dis, uint8_t dir);

	void prg_map(address_map &map);
};

class turbo_state : public turbo_base_state
{
public:
	turbo_state(const machine_config &mconfig, device_type type, const char *tag)
		: turbo_base_state(mconfig, type, tag)
		, m_roadroms(*this, "road")
		, m_alt_spriteram(*this, "alt_spriteram", 0x80, ENDIANNESS_LITTLE)
		, m_vr(*this, "VR%u", 1U)
		, m_dsw3(*this, "DSW3")
		, m_dial(*this, "DIAL")
		, m_tachometer(*this, "tachometer")
		, m_speed(*this, "speed")
	{ }

	void turbo(machine_config &config);
	void turbo_samples(machine_config &config);

	void init_turbo_enc();

protected:
	virtual void machine_start() override;

private:
	required_region_ptr<uint8_t> m_roadroms;
	memory_share_creator<uint8_t> m_alt_spriteram;
	required_ioport_array<2> m_vr;
	required_ioport m_dsw3;
	required_ioport m_dial;
	output_finder<> m_tachometer;
	output_finder<> m_speed;

	uint8_t       m_osel;
	uint8_t       m_bsel;
	uint8_t       m_opa;
	uint8_t       m_opb;
	uint8_t       m_opc;
	uint8_t       m_ipa;
	uint8_t       m_ipb;
	uint8_t       m_ipc;
	uint8_t       m_fbpla;
	uint8_t       m_fbcol;
	uint8_t       m_collision;
	uint8_t       m_last_analog;
	uint8_t       m_accel;

	uint8_t collision_r();
	void collision_clear_w(uint8_t data);
	void analog_reset_w(uint8_t data);
	DECLARE_WRITE_LINE_MEMBER(coin_meter_1_w);
	DECLARE_WRITE_LINE_MEMBER(coin_meter_2_w);
	DECLARE_WRITE_LINE_MEMBER(start_lamp_w);
	void ppi0a_w(uint8_t data);
	void ppi0b_w(uint8_t data);
	void ppi0c_w(uint8_t data);
	void ppi1a_w(uint8_t data);
	void ppi1b_w(uint8_t data);
	void ppi1c_w(uint8_t data);
	void ppi3c_w(uint8_t data);
	uint8_t analog_r();
	uint8_t spriteram_r(offs_t offset);
	void spriteram_w(offs_t offset, uint8_t data);
	void palette(palette_device &palette) const;
	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
	void sound_a_w(uint8_t data);
	void sound_b_w(uint8_t data);
	void sound_c_w(uint8_t data);
	void prepare_sprites(uint8_t y);
	uint32_t get_sprite_bits(uint8_t road);
	void rom_decode();
	void update_samples();
	TIMER_CALLBACK_MEMBER(update_sound_a);

	void prg_map(address_map &map);
};


#endif // MAME_INCLUDES_TURBO_H