1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett
3 /*************************************************************************
4 
5     TX-1/Buggy Boy hardware
6 
7 *************************************************************************/
8 #ifndef MAME_INCLUDES_TX1_H
9 #define MAME_INCLUDES_TX1_H
10 
11 #pragma once
12 
13 #include "emupal.h"
14 #include "screen.h"
15 #include "audio/tx1.h"
16 
17 #define TX1_PIXEL_CLOCK     (XTAL(18'000'000) / 3)
18 #define TX1_HBSTART         256
19 #define TX1_HBEND           0
20 #define TX1_HTOTAL          384
21 #define TX1_VBSTART         240
22 #define TX1_VBEND           0
23 #define TX1_VTOTAL          264
24 
25 /*
26  * HACK! Increased VTOTAL to 'fix' a timing issue
27  * that prevents one of the start countdown tones
28  * from playing.
29  */
30 #define BB_PIXEL_CLOCK      (XTAL(18'000'000) / 3)
31 #define BB_HBSTART          256
32 #define BB_HBEND            0
33 #define BB_HTOTAL           384
34 #define BB_VBSTART          240
35 #define BB_VBEND            0
36 #define BB_VTOTAL           288 + 1
37 
38 #define CPU_MASTER_CLOCK    (XTAL(15'000'000))
39 #define BUGGYBOY_ZCLK       (CPU_MASTER_CLOCK / 2)
40 
41 
42 class tx1_state : public driver_device
43 {
44 public:
tx1_state(const machine_config & mconfig,device_type type,const char * tag)45 	tx1_state(const machine_config &mconfig, device_type type, const char *tag) :
46 		driver_device(mconfig, type, tag),
47 		m_mathcpu(*this, "math_cpu"),
48 		m_maincpu(*this, "main_cpu"),
49 		m_math_ram(*this, "math_ram"),
50 		m_vram(*this, "vram"),
51 		m_objram(*this, "objram"),
52 		m_rcram(*this, "rcram"),
53 		m_char_tiles(*this, "char_tiles"),
54 		m_obj_tiles(*this, "obj_tiles"),
55 		m_road_rom(*this, "road"),
56 		m_obj_map(*this, "obj_map"),
57 		m_obj_luts(*this, "obj_luts"),
58 		m_proms(*this, "proms"),
59 		m_screen(*this, "screen"),
60 		m_sound(*this, "soundbrd")
61 	{ }
62 
63 	void tx1(machine_config &config);
64 	void tx1j(machine_config &config);
65 	void buggyboy(machine_config &config);
66 	void buggybjr(machine_config &config);
67 
68 private:
69 	struct math_t
70 	{
71 		uint16_t  cpulatch;
72 		uint16_t  promaddr;
73 		uint16_t  inslatch;
74 		uint32_t  mux;
75 		uint16_t  ppshift;
76 		uint32_t  i0ff;
77 		uint16_t  retval;
78 		uint16_t  muxlatch;   // TX-1
79 		int     dbgaddr;
80 		int     dbgpc;
81 
82 		uint16_t get_datarom_addr() const;
83 		uint16_t get_bb_datarom_addr() const;
84 	};
85 
86 	// SN74S516 16x16 Multiplier/Divider
87 	class sn74s516_t
88 	{
89 	public:
90 		int16_t   X;
91 		int16_t   Y;
92 
93 		union
94 		{
95 #ifdef LSB_FIRST
96 			struct { uint16_t W; int16_t Z; } as16bit;
97 #else
98 			struct { int16_t Z; uint16_t W; } as16bit;
99 #endif
100 			int32_t ZW32;
101 		} ZW;
102 
103 		int     code;
104 		int     state;
105 		int     ZWfl;
106 
107 		void kick(running_machine &machine, math_t &math, uint16_t *data, int ins);
108 
109 	private:
110 		void multiply(running_machine &machine);
111 		void divide(running_machine &machine);
112 		void update(running_machine &machine, int ins);
113 	};
114 
115 	struct vregs_t
116 	{
117 		uint16_t  scol;       /* Road colours */
118 		uint32_t  slock;      /* Scroll lock */
119 		uint8_t   flags;      /* Road flags */
120 
121 		uint32_t  ba_val;     /* Accumulator */
122 		uint32_t  ba_inc;
123 		uint32_t  bank_mode;
124 
125 		uint16_t  h_val;      /* Accumulator */
126 		uint16_t  h_inc;
127 		uint16_t  h_init;
128 
129 		uint8_t   slin_val;   /* Accumulator */
130 		uint8_t   slin_inc;
131 
132 		/* Buggyboy only */
133 		uint8_t   wa8;
134 		uint8_t   wa4;
135 
136 		uint16_t  wave_lfsr;
137 		uint8_t   sky;
138 		uint16_t  gas;
139 		uint8_t   shift;
140 	};
141 
142 	math_t m_math;
143 	sn74s516_t m_sn74s516;
144 
145 	required_device<cpu_device> m_mathcpu;
146 
147 	required_device<cpu_device> m_maincpu;
148 	required_shared_ptr<uint16_t> m_math_ram;
149 	required_shared_ptr<uint16_t> m_vram;
150 	required_shared_ptr<uint16_t> m_objram;
151 	required_shared_ptr<uint16_t> m_rcram;
152 
153 	required_region_ptr<uint8_t> m_char_tiles;
154 	required_region_ptr<uint8_t> m_obj_tiles;
155 	required_region_ptr<uint8_t> m_road_rom;
156 	required_region_ptr<uint8_t> m_obj_map;
157 	required_region_ptr<uint8_t> m_obj_luts;
158 	required_region_ptr<uint8_t> m_proms;
159 
160 	required_device<screen_device> m_screen;
161 	required_device<tx1_sound_device> m_sound;
162 
163 	emu_timer *m_interrupt_timer;
164 
165 	vregs_t m_vregs;
166 	std::unique_ptr<uint8_t[]> m_chr_bmp;
167 	std::unique_ptr<uint8_t[]> m_obj_bmp;
168 	std::unique_ptr<uint8_t[]> m_rod_bmp;
169 	std::unique_ptr<bitmap_ind16> m_bitmap;
170 
171 	bool m_needs_update;
172 
173 	void kick_sn74s516(uint16_t *data, int ins);
174 	void tx1_update_state();
175 	void buggyboy_update_state();
176 
177 	uint16_t tx1_math_r(offs_t offset);
178 	void tx1_math_w(offs_t offset, uint16_t data);
179 	uint16_t tx1_spcs_rom_r(offs_t offset);
180 	uint16_t tx1_spcs_ram_r(offs_t offset);
181 	void tx1_spcs_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
182 	uint16_t buggyboy_math_r(offs_t offset);
183 	void buggyboy_math_w(offs_t offset, uint16_t data);
184 	uint16_t buggyboy_spcs_rom_r(offs_t offset);
185 	void buggyboy_spcs_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
186 	uint16_t buggyboy_spcs_ram_r(offs_t offset);
187 	uint16_t tx1_crtc_r();
188 	void tx1_crtc_w(offs_t offset, uint16_t data);
189 	void tx1_bankcs_w(offs_t offset, uint16_t data);
190 	void tx1_slincs_w(offs_t offset, uint16_t data);
191 	void tx1_slock_w(uint16_t data);
192 	void tx1_scolst_w(uint16_t data);
193 	void tx1_flgcs_w(uint16_t data);
194 	void buggyboy_gas_w(offs_t offset, uint16_t data);
195 	void buggyboy_sky_w(uint16_t data);
196 	void buggyboy_scolst_w(uint16_t data);
197 	void resume_math_w(uint16_t data);
198 	void halt_math_w(uint16_t data);
199 	u16 dipswitches_r();
200 	DECLARE_MACHINE_RESET(tx1);
201 	DECLARE_VIDEO_START(tx1);
202 	void tx1_palette(palette_device &palette) const;
203 	DECLARE_MACHINE_RESET(buggyboy);
204 	DECLARE_VIDEO_START(buggyboy);
205 	void buggyboy_palette(palette_device &palette) const;
206 	DECLARE_VIDEO_START(buggybjr);
207 
208 	void tx1_draw_char(uint8_t *bitmap);
209 	void tx1_draw_road_pixel(int screen, uint8_t *bmpaddr,
210 								uint8_t apix[3], uint8_t bpix[3], uint32_t pixnuma, uint32_t pixnumb,
211 								uint8_t stl, uint8_t sld, uint8_t selb,
212 								uint8_t bnk, uint8_t rorev, uint8_t eb, uint8_t r, uint8_t delr);
213 	void tx1_draw_road(uint8_t *bitmap);
214 	void tx1_draw_objects(uint8_t *bitmap);
215 	void tx1_update_layers();
216 	void tx1_combine_layers(bitmap_ind16 &bitmap, int screen);
217 
218 	void buggyboy_draw_char(uint8_t *bitmap, bool wide);
219 	void buggyboy_get_roadpix(int screen, int ls161, uint8_t rva0_6, uint8_t sld, uint32_t *_rorev,
220 								uint8_t *rc0, uint8_t *rc1, uint8_t *rc2, uint8_t *rc3);
221 	void buggyboy_draw_road(uint8_t *bitmap);
222 	void buggybjr_draw_road(uint8_t *bitmap);
223 	void buggyboy_draw_objs(uint8_t *bitmap, bool wide);
224 	void bb_combine_layers(bitmap_ind16 &bitmap, int screen);
225 	void bb_update_layers();
226 
227 	uint32_t screen_update_tx1_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
228 	uint32_t screen_update_tx1_middle(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
229 	uint32_t screen_update_tx1_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
230 	uint32_t screen_update_buggyboy_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
231 	uint32_t screen_update_buggyboy_middle(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
232 	uint32_t screen_update_buggyboy_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
233 	uint32_t screen_update_buggybjr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
234 	DECLARE_WRITE_LINE_MEMBER(screen_vblank_tx1);
235 	DECLARE_WRITE_LINE_MEMBER(screen_vblank_buggyboy);
236 	TIMER_CALLBACK_MEMBER(interrupt_callback);
237 
238 	void buggybjr_main(address_map &map);
239 	void buggyboy_main(address_map &map);
240 	void buggyboy_math(address_map &map);
241 	void tx1_main(address_map &map);
242 	void tx1_math(address_map &map);
243 };
244 
245 #endif // MAME_INCLUDES_TX1_H
246