1 // license:GPL-2.0+
2 // copyright-holders:Kevin Thacker, Robbbert
3 /******************************************************************************
4 
5   Exidy Sorcerer machine functions
6 
7 *******************************************************************************/
8 
9 #include "emu.h"
10 #include "includes/sorcerer.h"
11 #include "machine/z80bin.h"
12 
13 // ************ TIMERS **************
14 /* timer for sorcerer serial chip transmit and receive */
15 
TIMER_CALLBACK_MEMBER(sorcerer_state::serial_tc)16 TIMER_CALLBACK_MEMBER(sorcerer_state::serial_tc)
17 {
18 	/* if rs232 is enabled, uart is connected to clock defined by bit6 of port fe.
19 	Transmit and receive clocks are connected to the same clock. */
20 
21 	/* if rs232 is disabled, receive clock is linked to cassette hardware */
22 	if (BIT(m_portfe, 7))
23 	{
24 		/* connect to rs232 */
25 		m_rs232->write_txd(m_uart->so_r());
26 		m_uart->write_si(m_rs232->rxd_r());
27 	}
28 }
29 
30 
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)31 void sorcerer_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
32 {
33 	switch (id)
34 	{
35 	case TIMER_SERIAL:
36 		serial_tc(ptr, param);
37 		break;
38 	case TIMER_CASSETTE:
39 		cassette_tc(ptr, param);
40 		break;
41 	default:
42 		throw emu_fatalerror("Unknown id in sorcerer_state::device_timer");
43 	}
44 }
45 
46 
47 /* timer to read cassette waveforms */
48 
TIMER_CALLBACK_MEMBER(sorcerer_state::cassette_tc)49 TIMER_CALLBACK_MEMBER(sorcerer_state::cassette_tc)
50 {
51 	u8 cass_ws = 0;
52 	switch (m_portfe & 0xc0)        /*/ bit 7 low indicates cassette */
53 	{
54 		case 0x00:              /* Cassette 300 baud */
55 
56 			/* loading a tape - this is basically the same as the super80.
57 			               We convert the 1200/2400 Hz signal to a 0 or 1, and send it to the uart. */
58 
59 			m_cass_data.input.length++;
60 
61 			cass_ws = ((((m_portfe & 0x20) ? m_cassette2 : m_cassette1))->input() > +0.02) ? 1 : 0;
62 
63 			if (cass_ws != m_cass_data.input.level)
64 			{
65 				m_cass_data.input.level = cass_ws;
66 				m_cass_data.input.bit = ((m_cass_data.input.length < 0x6) || (m_cass_data.input.length > 0x20)) ? 1 : 0;
67 				m_cass_data.input.length = 0;
68 				m_uart->write_si(m_cass_data.input.bit);
69 			}
70 
71 			/* saving a tape - convert the serial stream from the uart, into 1200 and 2400 Hz frequencies.
72 			               Synchronisation of the frequency pulses to the uart is extremely important. */
73 
74 			m_cass_data.output.length++;
75 			if (!(m_cass_data.output.length & 0x1f))
76 			{
77 				cass_ws = m_uart->so_r();
78 				if (cass_ws != m_cass_data.output.bit)
79 				{
80 					m_cass_data.output.bit = cass_ws;
81 					m_cass_data.output.length = 0;
82 				}
83 			}
84 
85 			if (!(m_cass_data.output.length & 3))
86 			{
87 				if (!((m_cass_data.output.bit == 0) && (m_cass_data.output.length & 4)))
88 				{
89 					m_cass_data.output.level ^= 1;          // toggle output this, except on 2nd half of low bit
90 					((m_portfe & 0x20) ? m_cassette2 : m_cassette1)->output(m_cass_data.output.level ? -1.0 : +1.0);
91 				}
92 			}
93 			return;
94 
95 		case 0x40:          /* Cassette 1200 baud */
96 			/* loading a tape */
97 			m_cass_data.input.length++;
98 
99 			cass_ws = ((((m_portfe & 0x20) ? m_cassette2 : m_cassette1))->input() > +0.02) ? 1 : 0;
100 
101 			if (cass_ws != m_cass_data.input.level || m_cass_data.input.length == 10)
102 			{
103 				m_cass_data.input.bit = ((m_cass_data.input.length < 10) || (m_cass_data.input.length > 0x20)) ? 1 : 0;
104 				if ( cass_ws != m_cass_data.input.level )
105 				{
106 					m_cass_data.input.length = 0;
107 					m_cass_data.input.level = cass_ws;
108 				}
109 				m_uart->write_si(m_cass_data.input.bit);
110 			}
111 
112 			/* saving a tape - convert the serial stream from the uart, into 600 and 1200 Hz frequencies. */
113 
114 			m_cass_data.output.length++;
115 			if (!(m_cass_data.output.length & 7))
116 			{
117 				cass_ws = m_uart->so_r();
118 				if (cass_ws != m_cass_data.output.bit)
119 				{
120 					m_cass_data.output.bit = cass_ws;
121 					m_cass_data.output.length = 0;
122 				}
123 			}
124 
125 			if (!(m_cass_data.output.length & 7))
126 			{
127 				if (!((m_cass_data.output.bit == 0) && (m_cass_data.output.length & 8)))
128 				{
129 					m_cass_data.output.level ^= 1;          // toggle output this, except on 2nd half of low bit
130 					((m_portfe & 0x20) ? m_cassette2 : m_cassette1)->output(m_cass_data.output.level ? -1.0 : +1.0);
131 				}
132 			}
133 			return;
134 	}
135 }
136 
137 
138 // ************ EXIDY VIDEO UNIT FDC **************
139 // The floppy sector has been read. Enable CPU.
intrq2_w(bool state)140 void sorcererd_state::intrq2_w(bool state)
141 {
142 	m_intrq_off = state ? false : true;
143 	if (state)
144 	{
145 		m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
146 		m_wait = false;
147 	}
148 	else
149 	if (BIT(m_port2c, 0) && m_drq_off && !m_wait)
150 	{
151 		m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE);
152 		m_wait = true;
153 	}
154 }
155 
156 // The next byte from floppy is available. Enable CPU so it can get the byte.
drq2_w(bool state)157 void sorcererd_state::drq2_w(bool state)
158 {
159 	m_drq_off = state ? false : true;
160 	if (state)
161 	{
162 		m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
163 		m_wait = false;
164 	}
165 	else
166 	if (BIT(m_port2c, 0) && m_intrq_off && !m_wait)
167 	{
168 		m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE);
169 		m_wait = true;
170 	}
171 }
172 
173 // Port 2C control signals for the video/disk unit's floppy disks
174 // Signals are unknown so guess
175 // It outputs 24 or 25 when booting, so suppose that
176 // bit 0 = enable wait generator, bit 2 = drive 0 select, bit 5 = ??
port2c_w(u8 data)177 void sorcererd_state::port2c_w(u8 data)
178 {
179 	m_port2c = data;
180 
181 	if (BIT(data, 0))
182 	{
183 		if (!m_wait && m_drq_off && m_intrq_off)
184 		{
185 			m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE);
186 			m_wait = true;
187 		}
188 	}
189 
190 	floppy_image_device *floppy = nullptr;
191 
192 	if (BIT(data, 2)) floppy = m_floppy20->get_device();
193 	if (BIT(data, 3)) floppy = m_floppy21->get_device();
194 
195 	m_fdc2->set_floppy(floppy);
196 
197 	if (floppy)
198 	{
199 		floppy->mon_w(0);
200 		floppy->ss_w(0);     // assume side 0 ? // BIT(data, 4));
201 	}
202 
203 	m_fdc2->dden_w(0);   // assume double density ? //!BIT(data, 0));
204 }
205 
206 // ************ DREAMDISK FDC **************
207 // Dreamdisk interrupts
intrq4_w(bool state)208 void sorcerer_state::intrq4_w(bool state)
209 {
210 	if (state && m_halt)
211 		m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
212 	else
213 		m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
214 }
215 
port48_r()216 u8 sorcerer_state::port48_r()
217 {
218 	return m_port48;
219 }
220 
port48_w(u8 data)221 void sorcerer_state::port48_w(u8 data)
222 {
223 	m_port48 = data;
224 	data ^= 0x1f;
225 	floppy_image_device *floppy = nullptr;
226 
227 	if (BIT(data, 0)) floppy = m_floppy40->get_device();
228 	if (BIT(data, 1)) floppy = m_floppy41->get_device();
229 	if (BIT(data, 2)) floppy = m_floppy42->get_device();
230 	if (BIT(data, 3)) floppy = m_floppy43->get_device();
231 
232 	m_fdc4->set_floppy(floppy);
233 
234 	if (floppy)
235 	{
236 		floppy->mon_w(0);
237 		floppy->ss_w(BIT(data, 4));
238 	}
239 
240 	m_fdc4->dden_w(BIT(data, 5));
241 	m_fdc4->enmf_w(BIT(data, 6));  // also connected to unsupported 5/8 pin.
242 }
243 
244 // ************ DIGITRIO FDC **************
port34_r()245 u8 sorcerer_state::port34_r()
246 {
247 	u8 data = m_port34;
248 	data |= m_fdc3->intrq_r() ? 0x80 : 0;
249 	//data |= m_floppy->twosid_r() ? 0 : 0x20; // for 20cm disks only, 0=indicates the disk has 2 sides (drive has 2 heads?)
250 	return data;
251 }
252 
port34_w(u8 data)253 void sorcerer_state::port34_w(u8 data)
254 {
255 	m_port34 = data & 0x5f;
256 	floppy_image_device *floppy = nullptr;
257 
258 	if (BIT(data, 0)) floppy = m_floppy30->get_device();
259 	if (BIT(data, 1)) floppy = m_floppy31->get_device();
260 	if (BIT(data, 2)) floppy = m_floppy32->get_device();
261 	if (BIT(data, 3)) floppy = m_floppy33->get_device();
262 
263 	m_fdc3->set_floppy(floppy);
264 
265 	if (floppy)
266 	{
267 		floppy->mon_w(0);
268 		floppy->ss_w(BIT(data, 5));
269 	}
270 
271 	m_fdc3->dden_w(BIT(data, 6));
272 	m_fdc3->set_unscaled_clock (BIT(data, 4) ? 2'000'000 : 1'000'000);
273 }
274 
275 // ************ DIGITRIO DMA **************
busreq_w(bool state)276 void sorcerer_state::busreq_w(bool state)
277 {
278 // since our Z80 has no support for BUSACK, we assume it is granted immediately
279 	m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
280 	m_maincpu->set_input_line(INPUT_LINE_HALT, state);
281 	m_dma->bai_w(state); // tell dma that bus has been granted
282 }
283 
memory_read_byte(offs_t offset)284 u8 sorcerer_state::memory_read_byte(offs_t offset)
285 {
286 	address_space& prog_space = m_maincpu->space(AS_PROGRAM);
287 	return prog_space.read_byte(offset);
288 }
289 
memory_write_byte(offs_t offset,u8 data)290 void sorcerer_state::memory_write_byte(offs_t offset, u8 data)
291 {
292 	address_space& prog_space = m_maincpu->space(AS_PROGRAM);
293 	prog_space.write_byte(offset, data);
294 }
295 
io_read_byte(offs_t offset)296 u8 sorcerer_state::io_read_byte(offs_t offset)
297 {
298 	address_space& prog_space = m_maincpu->space(AS_IO);
299 	return prog_space.read_byte(offset);
300 }
301 
io_write_byte(offs_t offset,u8 data)302 void sorcerer_state::io_write_byte(offs_t offset, u8 data)
303 {
304 	address_space& prog_space = m_maincpu->space(AS_IO);
305 	prog_space.write_byte(offset, data);
306 }
307 
308 // ************ INBUILT PORTS **************
portfd_w(u8 data)309 void sorcerer_state::portfd_w(u8 data)
310 {
311 	/* Translate data to control signals */
312 
313 	m_uart->write_cs(0);
314 	m_uart->write_nb1(BIT(data, 0));
315 	m_uart->write_nb2(BIT(data, 1));
316 	m_uart->write_tsb(BIT(data, 2));
317 	m_uart->write_eps(BIT(data, 3));
318 	m_uart->write_np(BIT(data, 4));
319 	m_uart->write_cs(1);
320 }
321 
portfe_w(u8 data)322 void sorcerer_state::portfe_w(u8 data)
323 {
324 	u8 changed_bits = (m_portfe ^ data) & 0xf0;
325 	m_portfe = data;
326 
327 	/* bits 0..3 */
328 	m_keyboard_line = data & 0x0f;
329 
330 	if (!changed_bits) return;
331 
332 	/* bits 4..5 */
333 	/* does user want to hear the sound? */
334 
335 	if (!BIT(data, 7)) // cassette operations
336 	{
337 		m_serial_timer->adjust(attotime::zero);
338 
339 		bool sound = BIT(m_iop_config->read(), 3);
340 
341 		m_cassette1->change_state(
342 			(BIT(data,4) && sound) ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER);
343 
344 		m_cassette2->change_state(
345 			(BIT(data,5) && sound) ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER);
346 
347 		/* cassette 1 motor */
348 		m_cassette1->change_state(
349 			(BIT(data,4)) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
350 
351 		/* cassette 2 motor */
352 		m_cassette2->change_state(
353 			(BIT(data,5)) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
354 
355 		if (data & 0x30)
356 			m_cassette_timer->adjust(attotime::zero, 0, attotime::from_hz(ES_UART_CLOCK*4));
357 		else
358 			m_cassette_timer->adjust(attotime::zero);
359 	}
360 	else
361 	{
362 		m_serial_timer->adjust(attotime::zero, 0, attotime::from_hz(ES_UART_CLOCK*4));
363 		m_cassette_timer->adjust(attotime::zero);
364 	}
365 
366 	// bit 6 baud rate */
367 	if (BIT(changed_bits, 6))
368 	{
369 		m_uart_clock->set_unscaled_clock(BIT(data, 6) ? ES_UART_CLOCK*4 : ES_UART_CLOCK);
370 	}
371 }
372 
portff_w(u8 data)373 void sorcerer_state::portff_w(u8 data)
374 {
375 	/// TODO: create a sorcerer parallel slot with a 7 bit and 8 bit centronics adapter as two of the options
376 	/// TODO: figure out what role FE plays http://www.trailingedge.com/exidy/exidych7.html
377 	m_centronics->write_data0(BIT(data, 0));
378 	m_centronics->write_data1(BIT(data, 1));
379 	m_centronics->write_data2(BIT(data, 2));
380 	m_centronics->write_data3(BIT(data, 3));
381 	m_centronics->write_data4(BIT(data, 4));
382 	m_centronics->write_data5(BIT(data, 5));
383 	m_centronics->write_data6(BIT(data, 6));
384 
385 	/* reading the config switch */
386 	switch (m_iop_config->read() & 0x02)
387 	{
388 	case 0: /* 7-bit port */
389 		/* bit 7 = strobe, bit 6..0 = data */
390 		m_centronics->write_data7(0);
391 		m_centronics->write_strobe(BIT(data, 7));
392 		break;
393 
394 	case 2: /* 8-bit port */
395 		/* hardware strobe driven from port select, bit 7..0 = data */
396 		m_centronics->write_data7(BIT(data, 7));
397 		m_centronics->write_strobe(0);
398 		m_centronics->write_strobe(1);
399 		break;
400 	}
401 }
402 
portfd_r()403 u8 sorcerer_state::portfd_r()
404 {
405 	/* set unused bits high */
406 	u8 data = 0xe0;
407 
408 	m_uart->write_swe(0);
409 	data |= m_uart->tbmt_r() ? 0x01 : 0;
410 	data |= m_uart->dav_r( ) ? 0x02 : 0;
411 	data |= m_uart->or_r(  ) ? 0x04 : 0;
412 	data |= m_uart->fe_r(  ) ? 0x08 : 0;
413 	data |= m_uart->pe_r(  ) ? 0x10 : 0;
414 	m_uart->write_swe(1);
415 
416 	return data;
417 }
418 
portfe_r()419 u8 sorcerer_state::portfe_r()
420 {
421 	/* bits 6..7
422 	 - hardware handshakes from user port
423 	 - not emulated
424 	 - tied high, allowing PARIN and PAROUT bios routines to run */
425 
426 	u8 data = 0xc0;
427 
428 	/* bit 5 - vsync */
429 	data |= m_iop_vs->read();
430 
431 	/* bits 4..0 - keyboard data */
432 	data |= m_iop_x[m_keyboard_line]->read();
433 
434 	return data;
435 }
436 
437 // ************ MACHINE **************
machine_start_common(offs_t endmem)438 void sorcerer_state::machine_start_common(offs_t endmem)
439 {
440 	m_cassette_timer = timer_alloc(TIMER_CASSETTE);
441 	m_serial_timer = timer_alloc(TIMER_SERIAL);
442 
443 	// register for savestates
444 	save_item(NAME(m_portfe));
445 	save_item(NAME(m_keyboard_line));
446 
447 	address_space &space = m_maincpu->space(AS_PROGRAM);
448 	/* configure RAM */
449 	switch (m_ram->size())
450 	{
451 	case 8*1024:
452 		space.unmap_readwrite(0x2000, endmem);
453 		break;
454 
455 	case 16*1024:
456 		space.unmap_readwrite(0x4000, endmem);
457 		break;
458 
459 	case 32*1024:
460 		space.unmap_readwrite(0x8000, endmem);
461 		break;
462 	}
463 
464 	if (m_cart && m_cart->exists())
465 		space.install_read_handler(0xc000, 0xdfff, read8sm_delegate(*m_cart, FUNC(generic_slot_device::read_rom)));
466 }
467 
machine_start()468 void sorcerer_state::machine_start()
469 {
470 	machine_start_common(0xbfff);
471 	save_item(NAME(m_port48));
472 	save_item(NAME(m_port34));
473 	save_item(NAME(m_halt));
474 }
475 
machine_start()476 void sorcererd_state::machine_start()
477 {
478 	machine_start_common(0xbbff);
479 	save_item(NAME(m_port2c));
480 	save_item(NAME(m_wait));
481 	save_item(NAME(m_drq_off));
482 	save_item(NAME(m_intrq_off));
483 }
484 
machine_reset_common()485 void sorcerer_state::machine_reset_common()
486 {
487 	address_space &space = m_maincpu->space(AS_PROGRAM);
488 
489 	/* Initialize cassette interface */
490 	m_cass_data.output.length = 0;
491 	m_cass_data.output.level = 1;
492 	m_cass_data.input.length = 0;
493 	m_cass_data.input.bit = 1;
494 
495 	m_portfe = 0xff;
496 	portfe_w(0);
497 
498 	space.install_rom(0x0000, 0x0fff, m_rom);   // do it here for F3
499 	m_rom_shadow_tap = space.install_read_tap(0xe000, 0xefff, "rom_shadow_r",[this](offs_t offset, u8 &data, u8 mem_mask)
500 	{
501 		if (!machine().side_effects_disabled())
502 		{
503 			// delete this tap
504 			m_rom_shadow_tap->remove();
505 
506 			// reinstall ram over the rom shadow
507 			m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x0fff, m_ram->pointer());
508 		}
509 
510 		// return the original data
511 		return data;
512 	});
513 }
514 
machine_reset()515 void sorcerer_state::machine_reset()
516 {
517 	machine_reset_common();
518 }
519 
machine_reset()520 void sorcererd_state::machine_reset()
521 {
522 	m_drq_off = true;
523 	m_intrq_off = true;
524 	m_wait = false;
525 	m_port2c = 0;
526 	machine_reset_common();
527 }
528 
529 
530 /******************************************************************************
531  Snapshot Handling
532 ******************************************************************************/
533 
SNAPSHOT_LOAD_MEMBER(sorcerer_state::snapshot_cb)534 SNAPSHOT_LOAD_MEMBER(sorcerer_state::snapshot_cb)
535 {
536 	u8 *RAM = memregion(m_maincpu->tag())->base();
537 	address_space &space = m_maincpu->space(AS_PROGRAM);
538 	u8 header[28];
539 	unsigned char s_byte;
540 
541 	/* check size */
542 	if (snapshot_size != 0x1001c)
543 	{
544 		image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Snapshot must be 65564 bytes");
545 		image.message("Snapshot must be 65564 bytes");
546 		return image_init_result::FAIL;
547 	}
548 
549 	/* get the header */
550 	image.fread( &header, sizeof(header));
551 
552 	/* write it to ram */
553 	for (int i = 0; i < 0xc000; i++)
554 	{
555 		image.fread( &s_byte, 1);
556 		space.write_byte(i, s_byte);
557 	}
558 	image.fread( RAM+0xc000, 0x4000);
559 
560 	/* patch CPU registers */
561 	m_maincpu->set_state_int(Z80_I, header[0]);
562 	m_maincpu->set_state_int(Z80_HL2, header[1] | (header[2] << 8));
563 	m_maincpu->set_state_int(Z80_DE2, header[3] | (header[4] << 8));
564 	m_maincpu->set_state_int(Z80_BC2, header[5] | (header[6] << 8));
565 	m_maincpu->set_state_int(Z80_AF2, header[7] | (header[8] << 8));
566 	m_maincpu->set_state_int(Z80_HL, header[9] | (header[10] << 8));
567 	m_maincpu->set_state_int(Z80_DE, header[11] | (header[12] << 8));
568 	m_maincpu->set_state_int(Z80_BC, header[13] | (header[14] << 8));
569 	m_maincpu->set_state_int(Z80_IY, header[15] | (header[16] << 8));
570 	m_maincpu->set_state_int(Z80_IX, header[17] | (header[18] << 8));
571 	m_maincpu->set_state_int(Z80_IFF1, header[19]&2 ? 1 : 0);
572 	m_maincpu->set_state_int(Z80_IFF2, header[19]&4 ? 1 : 0);
573 	m_maincpu->set_state_int(Z80_R, header[20]);
574 	m_maincpu->set_state_int(Z80_AF, header[21] | (header[22] << 8));
575 	m_maincpu->set_state_int(STATE_GENSP, header[23] | (header[24] << 8));
576 	m_maincpu->set_state_int(Z80_IM, header[25]);
577 	m_maincpu->set_pc(header[26] | (header[27] << 8));
578 
579 	return image_init_result::PASS;
580 }
581 
582 
583 /*-------------------------------------------------
584     QUICKLOAD_LOAD_MEMBER( sorcerer_state, sorcerer )
585 -------------------------------------------------*/
586 
QUICKLOAD_LOAD_MEMBER(sorcerer_state::quickload_cb)587 QUICKLOAD_LOAD_MEMBER(sorcerer_state::quickload_cb)
588 {
589 	uint16_t execute_address, start_address, end_address;
590 	int autorun;
591 	address_space &space = m_maincpu->space(AS_PROGRAM);
592 
593 	/* load the binary into memory */
594 	if (z80bin_load_file(&image, space, file_type, &execute_address, &start_address, &end_address) != image_init_result::PASS)
595 		return image_init_result::FAIL;
596 
597 	/* is this file executable? */
598 	if (execute_address != 0xffff)
599 	{
600 		/* check to see if autorun is on */
601 		autorun = m_iop_config->read() & 1;
602 
603 		if ((execute_address >= 0xc000) && (execute_address <= 0xdfff) && (space.read_byte(0xdffa) != 0xc3))
604 			return image_init_result::FAIL;     /* can't run a program if the cartridge isn't in */
605 
606 		/* Since Exidy Basic is by Microsoft, it needs some preprocessing before it can be run.
607 		1. A start address of 01D5 indicates a basic program which needs its pointers fixed up.
608 		2. If autorunning, jump to C689 (command processor), else jump to C3DD (READY prompt).
609 		Important addresses:
610 		    01D5 = start (load) address of a conventional basic program
611 		    C858 = an autorun basic program will have this exec address on the tape
612 		    C3DD = part of basic that displays READY and lets user enter input */
613 
614 		if (((start_address == 0x1d5) || (execute_address == 0xc858)) && (space.read_byte(0xdffa) == 0xc3))
615 		{
616 			u8 i;
617 			static const u8 data[]={
618 				0xcd, 0x26, 0xc4,   // CALL C426    ;set up other pointers
619 				0x21, 0xd4, 1,      // LD HL,01D4   ;start of program address (used by C689)
620 				0x36, 0,        // LD (HL),00   ;make sure dummy end-of-line is there
621 				0xc3, 0x89, 0xc6    // JP C689  ;run program
622 			};
623 
624 			for (i = 0; i < ARRAY_LENGTH(data); i++)
625 				space.write_byte(0xf01f + i, data[i]);
626 
627 			if (!autorun)
628 				space.write_word(0xf028,0xc3dd);
629 
630 			/* tell BASIC where program ends */
631 			space.write_byte(0x1b7, end_address & 0xff);
632 			space.write_byte(0x1b8, (end_address >> 8) & 0xff);
633 
634 			if ((execute_address != 0xc858) && autorun)
635 				space.write_word(0xf028, execute_address);
636 
637 			m_maincpu->set_pc(0xf01f);
638 		}
639 		else
640 		{
641 			if (autorun)
642 				m_maincpu->set_pc(execute_address);
643 		}
644 
645 	}
646 
647 	return image_init_result::PASS;
648 }
649