1 // license:GPL-2.0+
2 // copyright-holders:Kevin Thacker, Barry Rodewald
3 /*****************************************************************************
4  *
5  * includes/amstrad.h
6  *
7  ****************************************************************************/
8 #ifndef MAME_INCLUDES_AMSTRAD_H
9 #define MAME_INCLUDES_AMSTRAD_H
10 
11 #pragma once
12 
13 #include "cpu/z80/z80.h"
14 #include "sound/ay8910.h"
15 #include "machine/upd765.h"
16 #include "video/mc6845.h"
17 #include "machine/i8255.h"
18 #include "machine/mc146818.h"
19 #include "imagedev/floppy.h"
20 #include "imagedev/snapquik.h"
21 #include "bus/cpc/cpcexp.h"
22 #include "bus/cpc/ddi1.h"
23 #include "bus/cpc/cpc_ssa1.h"
24 #include "bus/cpc/cpc_rom.h"
25 #include "bus/cpc/mface2.h"
26 #include "bus/cpc/cpc_pds.h"
27 #include "bus/cpc/cpc_rs232.h"
28 #include "bus/cpc/symbfac2.h"
29 #include "bus/cpc/amdrum.h"
30 #include "bus/cpc/playcity.h"
31 #include "bus/cpc/smartwatch.h"
32 #include "bus/cpc/brunword4.h"
33 #include "bus/cpc/hd20.h"
34 #include "bus/cpc/magicsound.h"
35 #include "bus/cpc/doubler.h"
36 #include "bus/cpc/transtape.h"
37 #include "bus/cpc/musicmachine.h"
38 #include "machine/ram.h"
39 #include "imagedev/cassette.h"
40 #include "bus/centronics/ctronics.h"
41 #include "bus/centronics/comxpl80.h"
42 #include "bus/centronics/epson_ex800.h"
43 #include "bus/centronics/epson_lx800.h"
44 #include "bus/centronics/epson_lx810l.h"
45 #include "bus/centronics/printer.h"
46 #include "bus/centronics/digiblst.h"
47 #include "bus/generic/slot.h"
48 #include "bus/generic/carts.h"
49 #include "emupal.h"
50 #include "screen.h"
51 
52 
53 /****************************
54  * Gate Array data (CPC) -
55  ****************************/
56 struct gate_array_t
57 {
58 	std::unique_ptr<bitmap_ind16>    bitmap;        /* The bitmap we work on */
59 	uint8_t   pen_selected;       /* Pen selection */
60 	uint8_t   mrer;               /* Mode and ROM Enable Register */
61 	uint8_t   upper_bank;
62 	uint8_t   romdis;  // ROMDIS signal from the expansion port
63 
64 	/* input signals from CRTC */
65 	int     vsync;
66 	int     hsync;
67 	int     de;
68 	int     ma;
69 	int     ra;
70 
71 	/* used for timing */
72 	int     hsync_after_vsync_counter;
73 	int     hsync_counter;              /* The gate array counts CRTC HSYNC pulses using an internal 6-bit counter. */
74 
75 	/* used for drawing the screen */
76 	attotime    last_draw_time;
77 	int     y;
78 	uint16_t  *draw_p;                    /* Position in the bitmap where we are currently drawing */
79 	uint16_t  colour;
80 	uint16_t  address;
81 	uint8_t   *mode_lookup;
82 	uint8_t   data;
83 	uint8_t   ticks;
84 	uint8_t   ticks_increment;
85 	uint16_t  line_ticks;
86 	uint8_t   colour_ticks;
87 	uint8_t   max_colour_ticks;
88 };
89 
90 /****************************
91  * ASIC data (CPC plus)
92  ****************************/
93 struct asic_t
94 {
95 	uint8_t   *ram;               /* pointer to RAM used for the CPC+ ASIC memory-mapped registers */
96 	uint8_t   enabled;            /* Are CPC plus features enabled/unlocked */
97 	uint8_t   pri;                /* Programmable raster interrupt */
98 	uint8_t   seqptr;             /* Current position in the ASIC unlocking sequence */
99 	uint8_t   rmr2;               /* ROM mapping register 2 */
100 	uint16_t  split_ma_base;      /* Used to handle split screen support */
101 	uint16_t  split_ma_started;   /* Used to handle split screen support */
102 	uint16_t  vpos;               /* Current logical scanline */
103 	uint16_t  h_start;            /* Position where DE became active */
104 	uint16_t  h_end;              /* Position where DE became inactive */
105 	uint8_t   addr_6845;          /* We need these to store a shadow copy of R1 of the mc6845 */
106 	uint8_t   horiz_disp;
107 	uint8_t   hscroll;
108 	uint8_t   de_start;           /* flag to check if DE is been enabled this frame yet */
109 	bool    hsync_first_tick;   /* flag to check in first CRTC tick, used for knowing when to cover left side of screen to cover horizontal softscroll mess */
110 	uint8_t   hsync_tick_count;
111 
112 	/* DMA */
113 	uint8_t   dma_status;
114 	uint8_t   dma_clear;          /* Set if DMA interrupts are to be cleared automatically */
115 	uint8_t   dma_prescaler[3];   /* DMA channel prescaler */
116 	uint16_t  dma_repeat[3];      /* Location of the DMA channel's last repeat */
117 	uint16_t  dma_addr[3];        /* DMA channel address */
118 	uint16_t  dma_loopcount[3];   /* Count loops taken on this channel */
119 	uint16_t  dma_pause[3];       /* DMA pause count */
120 };
121 
122 
123 class amstrad_state : public driver_device
124 {
125 public:
126 	enum
127 	{
128 		TIMER_PC2_LOW,
129 		TIMER_VIDEO_UPDATE,
130 		TIMER_SET_RESOLUTION
131 	};
132 
amstrad_state(const machine_config & mconfig,device_type type,const char * tag)133 	amstrad_state(const machine_config &mconfig, device_type type, const char *tag) :
134 		driver_device(mconfig, type, tag),
135 		m_maincpu(*this, "maincpu"),
136 		m_ay(*this, "ay"),
137 		m_fdc(*this, "upd765"),
138 		m_floppy(*this, "upd765:%u", 0U),
139 		m_crtc(*this, "mc6845"),
140 		m_ppi(*this, "ppi8255"),
141 		m_centronics(*this, "centronics"),
142 		m_cassette(*this, "cassette"),
143 		m_cart(*this, "cartslot"),
144 		m_ram(*this, RAM_TAG),
145 		m_exp(*this, "exp"),
146 		m_rtc(*this, "rtc"),
147 		m_region_maincpu(*this, "maincpu"),
148 		m_region_user1(*this, "user1"),
149 		m_banks(*this, "bank%u", 1U),
150 		m_io_kbrow(*this, "kbrow.%u", 0U),
151 		m_io_analog(*this, "analog.%u", 0U),
152 		m_io_mouse(*this,"mouse_input%u", 1U),
153 		m_io_solder_links(*this, "solder_links"),
154 		m_io_green_display(*this, "green_display"),
155 		m_io_ctrltype(*this,"controller_type"),
156 		m_screen(*this, "screen"),
157 		m_palette(*this, "palette")
158 	{ }
159 
160 	required_device<z80_device> m_maincpu;
161 	required_device<ay8910_device> m_ay;
162 	optional_device<upd765_family_device> m_fdc;  // not on a GX4000
163 	optional_device_array<floppy_connector, 2> m_floppy;
164 	required_device<mc6845_device> m_crtc;
165 	required_device<i8255_device> m_ppi;
166 	optional_device<centronics_device> m_centronics;  // not on a GX4000
167 	optional_device<cassette_image_device> m_cassette; // not on a GX4000, (or technically, the 6128+)
168 	optional_device<generic_slot_device> m_cart;  // only on 664+, 6128+ and GX4000
169 	required_device<ram_device> m_ram;
170 	optional_device<cpc_expansion_slot_device> m_exp; // not on a GX4000
171 	optional_device<mc146818_device> m_rtc;  // Aleste 520EX only
172 
173 	int m_system_type;
174 	uint8_t m_aleste_mode;
175 	int m_plus_irq_cause;
176 	gate_array_t m_gate_array;
177 	asic_t m_asic;
178 	int m_GateArray_RamConfiguration;
179 	unsigned char *m_AmstradCPC_RamBanks[4];
180 	unsigned char *m_Aleste_RamBanks[4];
181 	int m_aleste_active_page[4];
182 	unsigned char *m_Amstrad_ROM_Table[256];
183 	uint8_t m_ppi_port_inputs[3];
184 	uint8_t m_ppi_port_outputs[3];
185 	int m_aleste_rtc_function;
186 	int m_prev_reg;
187 	uint16_t m_GateArray_render_colours[17];
188 	uint8_t m_mode0_lookup[256];
189 	uint8_t m_mode1_lookup[256];
190 	uint8_t m_mode2_lookup[256];
191 	int m_prev_data;
192 	int m_printer_bit8_selected;
193 	unsigned char m_Psg_FunctionSelected;
194 	int m_previous_ppi_portc_w;
195 	uint8_t m_amx_mouse_data;
196 	void amstrad_plus_asic_4000_w(offs_t offset, uint8_t data);
197 	void amstrad_plus_asic_6000_w(offs_t offset, uint8_t data);
198 	uint8_t amstrad_plus_asic_4000_r(offs_t offset);
199 	uint8_t amstrad_plus_asic_6000_r(offs_t offset);
200 	void aleste_msx_mapper(offs_t offset, uint8_t data);
201 	uint8_t amstrad_cpc_io_r(offs_t offset);
202 	void amstrad_cpc_io_w(offs_t offset, uint8_t data);
203 	uint8_t amstrad_psg_porta_read();
204 	void amstrad_plus_seqcheck(int data);
205 	DECLARE_MACHINE_START(amstrad);
206 	DECLARE_MACHINE_RESET(amstrad);
207 	DECLARE_VIDEO_START(amstrad);
208 	void amstrad_cpc_palette(palette_device &palette) const;
209 	void amstrad_cpc_green_palette(palette_device &palette) const;
210 	DECLARE_MACHINE_START(plus);
211 	DECLARE_MACHINE_RESET(plus);
212 	void amstrad_plus_palette(palette_device &palette) const;
213 	DECLARE_MACHINE_START(gx4000);
214 	DECLARE_MACHINE_RESET(gx4000);
215 	DECLARE_MACHINE_START(kccomp);
216 	DECLARE_MACHINE_RESET(kccomp);
217 	void kccomp_palette(palette_device &palette) const;
218 	DECLARE_MACHINE_START(aleste);
219 	DECLARE_MACHINE_RESET(aleste);
220 	void aleste_palette(palette_device &palette) const;
221 	uint32_t screen_update_amstrad(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
222 	DECLARE_WRITE_LINE_MEMBER(screen_vblank_amstrad);
223 	DECLARE_INPUT_CHANGED_MEMBER(cpc_monitor_changed);
224 	TIMER_CALLBACK_MEMBER(amstrad_pc2_low);
225 	TIMER_CALLBACK_MEMBER(amstrad_video_update_timer);
226 	TIMER_CALLBACK_MEMBER(cb_set_resolution);
227 	DECLARE_WRITE_LINE_MEMBER(amstrad_hsync_changed);
228 	DECLARE_WRITE_LINE_MEMBER(amstrad_plus_hsync_changed);
229 	DECLARE_WRITE_LINE_MEMBER(amstrad_vsync_changed);
230 	DECLARE_WRITE_LINE_MEMBER(amstrad_plus_vsync_changed);
231 	DECLARE_WRITE_LINE_MEMBER(amstrad_de_changed);
232 	DECLARE_WRITE_LINE_MEMBER(amstrad_plus_de_changed);
233 	uint8_t amstrad_ppi_porta_r();
234 	void amstrad_ppi_porta_w(uint8_t data);
235 	uint8_t amstrad_ppi_portb_r();
236 	void amstrad_ppi_portc_w(uint8_t data);
237 
238 	DECLARE_WRITE_LINE_MEMBER( cpc_romdis );
239 	void rom_select(uint8_t data);
240 
241 	DECLARE_FLOPPY_FORMATS( aleste_floppy_formats );
242 
243 	IRQ_CALLBACK_MEMBER(amstrad_cpu_acknowledge_int);
244 
245 	DECLARE_DEVICE_IMAGE_LOAD_MEMBER( amstrad_plus_cartridge );
246 
247 	void amstrad_handle_snapshot(unsigned char *pSnapshot);
248 	void amstrad_rethinkMemory();
249 	DECLARE_SNAPSHOT_LOAD_MEMBER(snapshot_cb);
250 
251 	DECLARE_WRITE_LINE_MEMBER(write_centronics_busy);
252 
253 	void cpcplus_cartslot(machine_config &config);
254 	void amstrad_base(machine_config &config);
255 	void cpc664(machine_config &config);
256 	void cpcplus(machine_config &config);
257 	void gx4000(machine_config &config);
258 	void cpc6128(machine_config &config);
259 	void aleste(machine_config &config);
260 	void kccomp(machine_config &config);
261 	void cpc464(machine_config &config);
262 	void amstrad_io(address_map &map);
263 	void amstrad_mem(address_map &map);
264 protected:
265 	required_memory_region m_region_maincpu;
266 	optional_memory_region m_region_user1;
267 	required_memory_bank_array<16> m_banks;
268 	optional_ioport_array<11> m_io_kbrow;
269 	optional_ioport_array<4> m_io_analog;
270 	optional_ioport_array<3> m_io_mouse;
271 	required_ioport m_io_solder_links;
272 	required_ioport m_io_green_display;
273 	optional_ioport m_io_ctrltype;
274 	required_device<screen_device> m_screen;
275 	required_device<palette_device> m_palette;
276 
277 	memory_region *m_region_cart;
278 
279 	void amstrad_init_lookups();
280 	void amstrad_vh_update_mode();
281 	void amstrad_plus_dma_parse(int channel);
282 	void amstrad_plus_handle_dma();
283 	void amstrad_vh_update_colour(int PenIndex, uint16_t hw_colour_index);
284 	void aleste_vh_update_colour(int PenIndex, uint16_t hw_colour_index);
285 	void amstrad_gate_array_get_video_data();
286 	void amstrad_update_video();
287 	void amstrad_plus_gate_array_get_video_data();
288 	void amstrad_plus_update_video();
289 	void amstrad_plus_update_video_sprites();
290 	void amstrad_setLowerRom();
291 	void amstrad_setUpperRom();
292 	void AmstradCPC_GA_SetRamConfiguration();
293 	void AmstradCPC_PALWrite(int data);
294 	void amstrad_GateArray_write(uint8_t dataToGateArray);
295 	void amstrad_reset_machine();
296 	void kccomp_reset_machine();
297 	void update_psg();
298 	void amstrad_common_init();
299 	void enumerate_roms();
300 	static uint8_t kccomp_get_colour_element(int colour_value);
301 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
302 
303 	int m_centronics_busy;
304 	uint8_t m_last_write;
305 };
306 
307 
308 /*----------- defined in machine/amstrad.c -----------*/
309 
310 
311 void cpc_exp_cards(device_slot_interface &device);
312 void cpcplus_exp_cards(device_slot_interface &device);
313 
314 #endif // MAME_INCLUDES_AMSTRAD_H
315