1 // license:GPL-2.0+
2 // copyright-holders:Kevin Thacker
3 /*****************************************************************************
4  *
5  * includes/spectrum.h
6  *
7  ****************************************************************************/
8 
9 #ifndef MAME_INCLUDES_SPECTRUM_H
10 #define MAME_INCLUDES_SPECTRUM_H
11 
12 #pragma once
13 
14 #include "machine/spec_snqk.h"
15 #include "machine/bankdev.h"
16 #include "bus/spectrum/exp.h"
17 #include "imagedev/cassette.h"
18 #include "imagedev/snapquik.h"
19 #include "machine/ram.h"
20 #include "sound/spkrdev.h"
21 #include "emupal.h"
22 #include "screen.h"
23 
24 /* Spectrum crystals */
25 
26 #define X1 XTAL(14'000'000)       // Main clock (48k Spectrum)
27 #define X1_128_AMSTRAD  35469000 // Main clock (Amstrad 128K model, +2A?)
28 #define X1_128_SINCLAIR 17734475 // Main clock (Sinclair 128K model)
29 
30 #define X2 XTAL(4'433'619) // PAL color subcarrier
31 
32 /* Spectrum screen size in pixels */
33 #define SPEC_UNSEEN_LINES  16   /* Non-visible scanlines before first border
34                                    line. Some of these may be vertical retrace. */
35 #define SPEC_TOP_BORDER    48   /* Number of border lines before actual screen */
36 #define SPEC_DISPLAY_YSIZE 192  /* Vertical screen resolution */
37 #define SPEC_BOTTOM_BORDER 56   /* Number of border lines at bottom of screen */
38 #define SPEC_SCREEN_HEIGHT (SPEC_TOP_BORDER + SPEC_DISPLAY_YSIZE + SPEC_BOTTOM_BORDER)
39 
40 #define SPEC_LEFT_BORDER   48   /* Number of left hand border pixels */
41 #define SPEC_DISPLAY_XSIZE 256  /* Horizontal screen resolution */
42 #define SPEC_RIGHT_BORDER  48   /* Number of right hand border pixels */
43 #define SPEC_SCREEN_WIDTH (SPEC_LEFT_BORDER + SPEC_DISPLAY_XSIZE + SPEC_RIGHT_BORDER)
44 
45 #define SPEC_LEFT_BORDER_CYCLES   24   /* Cycles to display left hand border */
46 #define SPEC_DISPLAY_XSIZE_CYCLES 128  /* Horizontal screen resolution */
47 #define SPEC_RIGHT_BORDER_CYCLES  24   /* Cycles to display right hand border */
48 #define SPEC_RETRACE_CYCLES       48   /* Cycles taken for horizontal retrace */
49 #define SPEC_CYCLES_PER_LINE      224  /* Number of cycles to display a single line */
50 
51 struct EVENT_LIST_ITEM
52 {
53 	/* driver defined ID for this write */
54 	int Event_ID;
55 	/* driver defined data for this write */
56 	int Event_Data;
57 	/* time at which this write occurred */
58 	int Event_Time;
59 };
60 
61 
62 
63 
64 class spectrum_state : public driver_device
65 {
66 public:
spectrum_state(const machine_config & mconfig,device_type type,const char * tag)67 	spectrum_state(const machine_config &mconfig, device_type type, const char *tag) :
68 		driver_device(mconfig, type, tag),
69 		m_video_ram(*this, "video_ram"),
70 		m_maincpu(*this, "maincpu"),
71 		m_screen(*this, "screen"),
72 		m_cassette(*this, "cassette"),
73 		m_ram(*this, RAM_TAG),
74 		m_specmem(*this, "specmem"),
75 		m_speaker(*this, "speaker"),
76 		m_exp(*this, "exp"),
77 		m_io_line0(*this, "LINE0"),
78 		m_io_line1(*this, "LINE1"),
79 		m_io_line2(*this, "LINE2"),
80 		m_io_line3(*this, "LINE3"),
81 		m_io_line4(*this, "LINE4"),
82 		m_io_line5(*this, "LINE5"),
83 		m_io_line6(*this, "LINE6"),
84 		m_io_line7(*this, "LINE7"),
85 		m_io_nmi(*this, "NMI"),
86 		m_io_config(*this, "CONFIG"),
87 		m_io_plus0(*this, "PLUS0"),
88 		m_io_plus1(*this, "PLUS1"),
89 		m_io_plus2(*this, "PLUS2"),
90 		m_io_plus3(*this, "PLUS3"),
91 		m_io_plus4(*this, "PLUS4"),
92 		m_io_joy1(*this, "JOY1"),
93 		m_io_joy2(*this, "JOY2")
94 	{ }
95 
96 	void spectrum_common(machine_config &config);
97 	void spectrum(machine_config &config);
98 	void spectrum_clone(machine_config &config);
99 	void spectrum_128(machine_config &config);
100 
101 	void init_spectrum();
102 
103 protected:
104 
105 	enum
106 	{
107 		TIMER_IRQ_ON,
108 		TIMER_IRQ_OFF,
109 		TIMER_SCANLINE
110 	};
111 
112 	int m_port_fe_data;
113 	int m_port_7ffd_data;
114 	int m_port_1ffd_data;   /* scorpion and plus3 */
115 	int m_port_ff_data; /* Display enhancement control */
116 	int m_port_f4_data; /* Horizontal Select Register */
117 
118 	/* video support */
119 	int m_frame_invert_count;
120 	int m_frame_number;    /* Used for handling FLASH 1 */
121 	int m_flash_invert;
122 	optional_shared_ptr<uint8_t> m_video_ram;
123 	uint8_t *m_screen_location;
124 
125 	int m_ROMSelection;
126 
127 	emu_timer *m_irq_off_timer;
128 
129 	// Build up the screen bitmap line-by-line as the z80 uses CPU cycles.
130 	// Elimiates sprite flicker on various games (E.g. Marauder and
131 	// Stormlord) and makes Firefly playable.
132 	emu_timer *m_scanline_timer;
133 
134 	EVENT_LIST_ITEM *m_pCurrentItem;
135 	int m_NumEvents;
136 	int m_TotalEvents;
137 	char *m_pEventListBuffer;
138 	int m_LastFrameStartTime;
139 	int m_CyclesPerLine;
140 
141 	uint8_t *m_ram_0000;
142 	uint8_t m_ram_disabled_by_beta;
143 	uint8_t pre_opcode_fetch_r(offs_t offset);
144 	void spectrum_rom_w(offs_t offset, uint8_t data);
145 	uint8_t spectrum_rom_r(offs_t offset);
146 	uint8_t spectrum_data_r(offs_t offset);
147 	void spectrum_data_w(offs_t offset, uint8_t data);
148 
149 	void spectrum_port_fe_w(offs_t offset, uint8_t data);
150 	uint8_t spectrum_port_fe_r(offs_t offset);
151 	uint8_t spectrum_port_ula_r(offs_t offset);
152 	uint8_t spectrum_clone_port_ula_r();
153 
154 	uint8_t spectrum_128_pre_opcode_fetch_r(offs_t offset);
155 	void spectrum_128_bank1_w(offs_t offset, uint8_t data);
156 	uint8_t spectrum_128_bank1_r(offs_t offset);
157 	void spectrum_128_port_7ffd_w(offs_t offset, uint8_t data);
158 	uint8_t spectrum_128_ula_r();
159 
160 	DECLARE_MACHINE_RESET(spectrum);
161 	DECLARE_VIDEO_START(spectrum);
162 	void spectrum_palette(palette_device &palette) const;
163 	DECLARE_VIDEO_START(spectrum_128);
164 	DECLARE_MACHINE_RESET(spectrum_128);
165 	uint32_t screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
166 	DECLARE_WRITE_LINE_MEMBER(screen_vblank_spectrum);
167 	INTERRUPT_GEN_MEMBER(spec_interrupt);
168 
169 	unsigned int m_previous_border_x, m_previous_border_y;
170 	bitmap_ind16 m_border_bitmap;
171 	unsigned int m_previous_screen_x, m_previous_screen_y;
172 	bitmap_ind16 m_screen_bitmap;
173 
174 	void spectrum_128_update_memory();
plus3_update_memory()175 	virtual void plus3_update_memory() { }
ts2068_update_memory()176 	virtual void ts2068_update_memory() { }
177 
178 	DECLARE_SNAPSHOT_LOAD_MEMBER(snapshot_cb);
179 	DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb);
180 
181 	required_device<cpu_device> m_maincpu;
182 	required_device<screen_device> m_screen;
183 
184 	void spectrum_128_io(address_map &map);
185 	void spectrum_128_mem(address_map &map);
186 	void spectrum_128_fetch(address_map &map);
187 	void spectrum_io(address_map &map);
188 	void spectrum_clone_io(address_map &map);
189 	void spectrum_opcodes(address_map &map);
190 	void spectrum_map(address_map &map);
191 	void spectrum_data(address_map &map);
192 
193 	required_device<cassette_image_device> m_cassette;
194 	required_device<ram_device> m_ram;
195 	optional_device<address_map_bank_device> m_specmem;
196 	required_device<speaker_sound_device> m_speaker;
197 	optional_device<spectrum_expansion_slot_device> m_exp;
198 
199 	// Regular spectrum ports; marked as optional because of other subclasses
200 	optional_ioport m_io_line0;
201 	optional_ioport m_io_line1;
202 	optional_ioport m_io_line2;
203 	optional_ioport m_io_line3;
204 	optional_ioport m_io_line4;
205 	optional_ioport m_io_line5;
206 	optional_ioport m_io_line6;
207 	optional_ioport m_io_line7;
208 	optional_ioport m_io_nmi;
209 	optional_ioport m_io_config;
210 
211 	// Plus ports
212 	optional_ioport m_io_plus0;
213 	optional_ioport m_io_plus1;
214 	optional_ioport m_io_plus2;
215 	optional_ioport m_io_plus3;
216 	optional_ioport m_io_plus4;
217 
218 	// Joystick ports
219 	optional_ioport m_io_joy1;
220 	optional_ioport m_io_joy2;
221 
222 	void spectrum_UpdateBorderBitmap();
223 	void spectrum_UpdateScreenBitmap(bool eof = false);
224 	inline unsigned char get_display_color(unsigned char color, int invert);
225 	inline void spectrum_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color);
226 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
227 
228 	// snapshot helpers
229 	void update_paging();
230 	void page_basicrom();
231 	void border_update(int data);
232 	void setup_sp(uint8_t *snapdata, uint32_t snapsize);
233 	void setup_sna(uint8_t *snapdata, uint32_t snapsize);
234 	void setup_ach(uint8_t *snapdata, uint32_t snapsize);
235 	void setup_prg(uint8_t *snapdata, uint32_t snapsize);
236 	void setup_plusd(uint8_t *snapdata, uint32_t snapsize);
237 	void setup_sem(uint8_t *snapdata, uint32_t snapsize);
238 	void setup_sit(uint8_t *snapdata, uint32_t snapsize);
239 	void setup_zx(uint8_t *snapdata, uint32_t snapsize);
240 	void setup_snp(uint8_t *snapdata, uint32_t snapsize);
241 	void snx_decompress_block(address_space &space, uint8_t *source, uint16_t dest, uint16_t size);
242 	void setup_snx(uint8_t *snapdata, uint32_t snapsize);
243 	void setup_frz(uint8_t *snapdata, uint32_t snapsize);
244 	void z80_decompress_block(address_space &space, uint8_t *source, uint16_t dest, uint16_t size);
245 	void setup_z80(uint8_t *snapdata, uint32_t snapsize);
246 
247 	// quickload helpers
248 	void log_quickload(const char *type, uint32_t start, uint32_t length, uint32_t exec, const char *exec_format);
249 	void setup_scr(uint8_t *quickdata, uint32_t quicksize);
250 	void setup_raw(uint8_t *quickdata, uint32_t quicksize);
251 
252 	uint8_t floating_bus_r();
253 };
254 
255 
256 /*----------- defined in drivers/spectrum.c -----------*/
257 
258 INPUT_PORTS_EXTERN( spectrum );
259 INPUT_PORTS_EXTERN( spec128 );
260 INPUT_PORTS_EXTERN( spec_plus );
261 
262 #endif // MAME_INCLUDES_SPECTRUM_H
263