1 // license:BSD-3-Clause
2 // copyright-holders:Wilbert Pol, Charles MacDonald,Mathis Rosenhauer,Brad Oliver,Michael Luong,Fabio Priuli,Enik Land
3 /*****************************************************************************
4  *
5  * includes/sms.h
6  *
7  ****************************************************************************/
8 
9 #ifndef MAME_INCLUDES_SMS_H
10 #define MAME_INCLUDES_SMS_H
11 
12 #define LOG_REG
13 #define LOG_PAGING
14 #define LOG_COLOR
15 
16 #define NVRAM_SIZE             (0x08000)
17 #define CPU_ADDRESSABLE_SIZE   (0x10000)
18 
19 #define MAX_CARTRIDGES        16
20 
21 #define CONTROL1_TAG   "ctrl1"
22 #define CONTROL2_TAG   "ctrl2"
23 
24 #include "bus/gamegear/ggext.h"
25 #include "bus/sega8/sega8_slot.h"
26 #include "bus/sg1000_exp/sg1000exp.h"
27 #include "bus/sms_ctrl/smsctrl.h"
28 #include "bus/sms_exp/smsexp.h"
29 #include "sound/ym2413.h"
30 #include "video/315_5124.h"
31 
32 #include "screen.h"
33 #include "machine/timer.h"
34 
35 
36 class sms_state : public driver_device
37 {
38 public:
sms_state(const machine_config & mconfig,device_type type,const char * tag)39 	sms_state(const machine_config &mconfig, device_type type, const char *tag) :
40 		driver_device(mconfig, type, tag),
41 		m_maincpu(*this, "maincpu"),
42 		m_vdp(*this, "sms_vdp"),
43 		m_main_scr(*this, "screen"),
44 		m_ym(*this, "ym2413"),
45 		m_port_ctrl1(*this, CONTROL1_TAG),
46 		m_port_ctrl2(*this, CONTROL2_TAG),
47 		m_port_gg_ext(*this, "ext"),
48 		m_port_gg_dc(*this, "GG_PORT_DC"),
49 		m_port_pause(*this, "PAUSE"),
50 		m_port_reset(*this, "RESET"),
51 		m_port_rapid(*this, "RAPID"),
52 		m_port_start(*this, "START"),
53 		m_port_persist(*this, "PERSISTENCE"),
54 		m_led_pwr(*this, "led_pwr"),
55 		m_region_maincpu(*this, "maincpu"),
56 		m_mainram(nullptr),
57 		m_is_gamegear(false),
58 		m_is_smsj(false),
59 		m_is_mark_iii(false),
60 		m_ioctrl_region_is_japan(false),
61 		m_has_bios_0400(false),
62 		m_has_bios_2000(false),
63 		m_has_bios_full(false),
64 		m_has_jpn_sms_cart_slot(false),
65 		m_has_pwr_led(false),
66 		m_slot(*this, "slot"),
67 		m_cardslot(*this, "mycard"),
68 		m_smsexpslot(*this, "smsexp"),
69 		m_sgexpslot(*this, "sgexp")
70 	{ }
71 
72 	void sms_base(machine_config &config);
73 	void sms_ntsc_base(machine_config &config);
74 	void sms_pal_base(machine_config &config);
75 	void sms_paln_base(machine_config &config);
76 	void sms_br_base(machine_config &config);
77 	void sms3_br(machine_config &config);
78 	void sms3_paln(machine_config &config);
79 	void sms2_pal(machine_config &config);
80 	void sms2_kr(machine_config &config);
81 	void sms2_ntsc(machine_config &config);
82 
83 	uint32_t screen_update_sms(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
84 
85 protected:
86 	template <typename X> static void screen_sms_pal_raw_params(screen_device &screen, X &&pixelclock);
87 	template <typename X> static void screen_sms_ntsc_raw_params(screen_device &screen, X &&pixelclock);
88 
89 	uint8_t read_0000(offs_t offset);
90 	uint8_t read_4000(offs_t offset);
91 	uint8_t read_8000(offs_t offset);
92 	uint8_t read_ram(offs_t offset);
93 	void write_ram(offs_t offset, uint8_t data);
94 	void write_cart(offs_t offset, uint8_t data);
95 
96 	uint8_t sms_mapper_r(offs_t offset);
97 	void sms_mapper_w(offs_t offset, uint8_t data);
98 	void sms_mem_control_w(uint8_t data);
99 	void sms_io_control_w(uint8_t data);
100 	uint8_t sms_count_r(offs_t offset);
101 	uint8_t sms_input_port_dc_r();
102 	uint8_t sms_input_port_dd_r();
103 	uint8_t sg1000m3_peripheral_r(offs_t offset);
104 	void sg1000m3_peripheral_w(offs_t offset, uint8_t data);
105 	uint8_t smsj_audio_control_r();
106 	void smsj_audio_control_w(uint8_t data);
107 	void smsj_ym2413_register_port_w(uint8_t data);
108 	void smsj_ym2413_data_port_w(uint8_t data);
109 
110 	DECLARE_WRITE_LINE_MEMBER(rapid_n_csync_callback);
111 	DECLARE_WRITE_LINE_MEMBER(sms_ctrl1_th_input);
112 	DECLARE_WRITE_LINE_MEMBER(sms_ctrl2_th_input);
113 
114 	void sg1000m3_io(address_map &map);
115 	void sms_io(address_map &map);
116 	void sms_mem(address_map &map);
117 	void smsj_io(address_map &map);
118 	void smskr_io(address_map &map);
119 
120 	virtual void machine_start() override;
121 	virtual void machine_reset() override;
122 	uint8_t read_bus(unsigned int bank, uint16_t base_addr, uint16_t offset);
123 	void setup_bios();
124 	void setup_media_slots();
125 	void setup_enabled_slots();
126 	void lphaser_hcount_latch();
127 	void sms_get_inputs();
128 	void smsj_set_audio_control(uint8_t data);
129 
130 	// devices
131 	required_device<cpu_device> m_maincpu;
132 	required_device<sega315_5124_device> m_vdp;
133 	required_device<screen_device> m_main_scr;
134 	optional_device<ym2413_device> m_ym;
135 	optional_device<sms_control_port_device> m_port_ctrl1;
136 	optional_device<sms_control_port_device> m_port_ctrl2;
137 	optional_device<gg_ext_port_device> m_port_gg_ext;
138 
139 	optional_ioport m_port_gg_dc;
140 	optional_ioport m_port_pause;
141 	optional_ioport m_port_reset;
142 	optional_ioport m_port_rapid;
143 	optional_ioport m_port_start;
144 	optional_ioport m_port_persist;
145 
146 	output_finder<> m_led_pwr;
147 
148 	required_memory_region m_region_maincpu;
149 	std::unique_ptr<uint8_t[]> m_mainram;
150 	uint8_t *m_BIOS;
151 
152 	// for gamegear LCD persistence hack
153 	bitmap_rgb32 m_prev_bitmap;
154 	bool m_prev_bitmap_copied;
155 
156 	// model identifiers
157 	bool m_is_gamegear;
158 	bool m_is_smsj;
159 	bool m_is_mark_iii;
160 	bool m_ioctrl_region_is_japan;
161 	bool m_has_bios_0400;
162 	bool m_has_bios_2000;
163 	bool m_has_bios_full;
164 	bool m_has_jpn_sms_cart_slot;
165 	bool m_has_pwr_led;
166 
167 	// [0] for 0x400-0x3fff, [1] for 0x4000-0x7fff, [2] for 0x8000-0xffff, [3] for 0x0000-0x0400
168 	uint8_t m_bios_page[4];
169 
170 	uint8_t m_bios_page_count;
171 	uint8_t m_mapper[4];
172 	uint8_t m_io_ctrl_reg;
173 	uint8_t m_mem_ctrl_reg;
174 	uint8_t m_mem_device_enabled;
175 	uint8_t m_smsj_audio_control;
176 	uint8_t m_port_dc_reg;
177 	uint8_t m_port_dd_reg;
178 
179 	uint8_t m_ctrl1_th_state;
180 	uint8_t m_ctrl2_th_state;
181 	uint8_t m_ctrl1_th_latch;
182 	uint8_t m_ctrl2_th_latch;
183 
184 	// Data needed for Light Phaser
185 	int m_lphaser_x_offs;   /* Needed to 'calibrate' lphaser; set at cart loading */
186 	emu_timer *m_lphaser_th_timer;
187 	TIMER_CALLBACK_MEMBER(lphaser_th_generate);
188 
189 	// Data needed for Rapid button (smsj, sms1kr, sms1krfm)
190 	uint16_t m_csync_counter;
191 	uint8_t m_rapid_mode;
192 	uint8_t m_rapid_read_state;
193 	uint8_t m_rapid_last_dc;
194 	uint8_t m_rapid_last_dd;
195 
196 	// slot devices
197 	sega8_cart_slot_device *m_cartslot;
198 	optional_device<sega8_cart_slot_device> m_slot;
199 	optional_device<sega8_card_slot_device> m_cardslot;
200 	optional_device<sms_expansion_slot_device> m_smsexpslot;
201 	optional_device<sg1000_expansion_slot_device> m_sgexpslot;
202 };
203 
204 class sms1_state : public sms_state
205 {
206 public:
sms1_state(const machine_config & mconfig,device_type type,const char * tag)207 	sms1_state(const machine_config &mconfig, device_type type, const char *tag) :
208 		sms_state(mconfig, type, tag),
209 		m_left_lcd(*this, "left_lcd"),
210 		m_right_lcd(*this, "right_lcd"),
211 		m_port_scope(*this, "SEGASCOPE"),
212 		m_port_scope_binocular(*this, "SSCOPE_BINOCULAR")
213 	{ }
214 
215 	void sms1_paln(machine_config &config);
216 	void sms1_ntsc(machine_config &config);
217 	void sms1_pal(machine_config &config);
218 	void sms1_br(machine_config &config);
219 	void sms1_kr(machine_config &config);
220 	void smsj(machine_config &config);
221 	void sg1000m3(machine_config &config);
222 
223 protected:
224 	virtual void video_start() override;
225 	virtual void video_reset() override;
226 
227 private:
228 	uint8_t sscope_r(offs_t offset);
229 	void sscope_w(offs_t offset, uint8_t data);
230 
231 	DECLARE_WRITE_LINE_MEMBER(sscope_vblank);
232 	uint32_t screen_update_left(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
233 	uint32_t screen_update_right(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
234 
235 	void sms1_mem(address_map &map);
236 
237 	// for 3D glass binocular hack
238 	required_device<screen_device> m_left_lcd;
239 	required_device<screen_device> m_right_lcd;
240 	required_ioport m_port_scope;
241 	required_ioport m_port_scope_binocular;
242 	bitmap_rgb32 m_prevleft_bitmap;
243 	bitmap_rgb32 m_prevright_bitmap;
244 
245 	// Data needed for SegaScope (3D glasses)
246 	uint8_t m_sscope_state;
247 	uint8_t m_frame_sscope_state;
248 };
249 
250 class smssdisp_state : public sms1_state
251 {
252 public:
smssdisp_state(const machine_config & mconfig,device_type type,const char * tag)253 	smssdisp_state(const machine_config &mconfig, device_type type, const char *tag) :
254 		sms1_state(mconfig, type, tag),
255 		m_control_cpu(*this, "control"),
256 		m_slots(*this, {"slot", "slot2", "slot3", "slot4", "slot5", "slot6", "slot7", "slot8", "slot9", "slot10", "slot11", "slot12", "slot13", "slot14", "slot15", "slot16"}),
257 		m_cards(*this, "slot%u", 17U),
258 		m_store_cart_selection_data(0)
259 	{ }
260 
261 	void sms_sdisp(machine_config &config);
262 
263 protected:
264 	virtual void machine_start() override;
265 	virtual void machine_reset() override;
266 	virtual void device_post_load() override;
267 
268 private:
269 	uint8_t sms_store_cart_select_r();
270 	void sms_store_cart_select_w(uint8_t data);
271 	void store_select_cart(uint8_t data);
272 	void sms_store_control_w(uint8_t data);
273 
274 	uint8_t store_cart_peek(offs_t offset);
275 
276 	DECLARE_WRITE_LINE_MEMBER(sms_store_int_callback);
277 	void sms_store_mem(address_map &map);
278 
279 	required_device<cpu_device> m_control_cpu;
280 	required_device_array<sega8_cart_slot_device, 16> m_slots;
281 	required_device_array<sega8_card_slot_device, 16> m_cards;
282 
283 	uint8_t m_store_control;
284 	uint8_t m_store_cart_selection_data;
285 };
286 
287 class gamegear_state : public sms_state
288 {
289 public:
gamegear_state(const machine_config & mconfig,device_type type,const char * tag)290 	gamegear_state(const machine_config &mconfig, device_type type, const char *tag) :
291 		sms_state(mconfig, type, tag)
292 	{ }
293 
294 	void gamegear(machine_config &config);
295 	void gamegeaj(machine_config &config);
296 
297 protected:
298 	virtual void machine_start() override;
299 	virtual void machine_reset() override;
300 	virtual void video_start() override;
301 	virtual void video_reset() override;
302 
303 private:
304 	template <typename X> static void screen_gg_raw_params(screen_device &screen, X &&pixelclock);
305 
306 	uint8_t gg_input_port_00_r();
307 	uint8_t gg_sio_r(offs_t offset);
308 	void gg_sio_w(offs_t offset, uint8_t data);
309 	void gg_psg_stereo_w(uint8_t data);
310 
311 	DECLARE_WRITE_LINE_MEMBER(gg_pause_callback);
312 	DECLARE_WRITE_LINE_MEMBER(gg_ext_th_input);
313 
314 	uint32_t screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
315 	void screen_gg_sms_mode_scaling(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
316 
317 	void gg_io(address_map &map);
318 
319 	// for gamegear SMS mode scaling
320 	bitmap_rgb32 m_gg_sms_mode_bitmap;
321 	// line_buffer will be used to hold 4 lines of line data as a kind of cache for
322 	// vertical scaling in the gamegear sms compatibility mode.
323 	std::unique_ptr<int[]> m_line_buffer;
324 
325 	uint8_t m_gg_sio[5];
326 	int m_gg_paused;
327 };
328 
329 
330 /*----------- defined in machine/sms.c -----------*/
331 
332 #define IO_EXPANSION    (0x80)  /* Expansion slot enable (1= disabled, 0= enabled) */
333 #define IO_CARTRIDGE    (0x40)  /* Cartridge slot enable (1= disabled, 0= enabled) */
334 #define IO_CARD         (0x20)  /* Card slot disabled (1= disabled, 0= enabled) */
335 #define IO_WORK_RAM     (0x10)  /* Work RAM disabled (1= disabled, 0= enabled) */
336 #define IO_BIOS_ROM     (0x08)  /* BIOS ROM disabled (1= disabled, 0= enabled) */
337 #define IO_CHIP         (0x04)  /* I/O chip disabled (1= disabled, 0= enabled) */
338 
339 #endif // MAME_INCLUDES_SMS_H
340