1 // license:BSD-3-Clause
2 // copyright-holders:Robbbert
3 //**************************************************************************************************************************
4
5 #include "emu.h"
6 #include "includes/trs80m3.h"
7
8
9 #define IRQ_M4_RTC 0x04 /* RTC on Model 4 */
10 #define CASS_RISE 0x01 /* high speed cass on Model III/4) */
11 #define CASS_FALL 0x02 /* high speed cass on Model III/4) */
12 #define MODEL4_MASTER_CLOCK 20275200
13
14
TIMER_CALLBACK_MEMBER(trs80m3_state::cassette_data_callback)15 TIMER_CALLBACK_MEMBER(trs80m3_state::cassette_data_callback)
16 {
17 /* This does all baud rates. 250 baud (trs80), and 500 baud (all others) set bit 7 of "cassette_data".
18 1500 baud (trs80m3, trs80m4) is interrupt-driven and uses bit 0 of "cassette_data" */
19
20 double new_val = (m_cassette->input());
21
22 /* Check for HI-LO transition */
23 if ( m_old_cassette_val > -0.2 && new_val < -0.2 )
24 {
25 m_cassette_data |= 0x80; /* 500 baud */
26 if (m_mask & CASS_FALL) /* see if 1500 baud */
27 {
28 m_cassette_data = 0;
29 m_irq |= CASS_FALL;
30 m_maincpu->set_input_line(0, HOLD_LINE);
31 }
32 }
33 else
34 if ( m_old_cassette_val < -0.2 && new_val > -0.2 )
35 {
36 if (m_mask & CASS_RISE) /* 1500 baud */
37 {
38 m_cassette_data = 1;
39 m_irq |= CASS_RISE;
40 m_maincpu->set_input_line(0, HOLD_LINE);
41 }
42 }
43
44 m_old_cassette_val = new_val;
45 }
46
47
48 /*************************************
49 *
50 * Port handlers.
51 *
52 *************************************/
53
54
port_e0_r()55 uint8_t trs80m3_state::port_e0_r()
56 {
57 /* Indicates which devices are interrupting - d6..d3 not emulated.
58 Whenever an interrupt occurs, this port is immediately read
59 to find out which device requires service. Lowest-numbered
60 bit takes precedence. We take this opportunity to clear the
61 cpu INT line.
62
63 d6 RS232 Error (Any of {FE, PE, OR} errors has occurred)
64 d5 RS232 Rcv (DAV indicates a char ready to be picked up from uart)
65 d4 RS232 Xmit (TBMT indicates ready to accept another char from cpu)
66 d3 I/O Bus
67 d2 RTC
68 d1 Cass 1500 baud Falling
69 d0 Cass 1500 baud Rising */
70
71 m_maincpu->set_input_line(0, CLEAR_LINE);
72 return ~(m_mask & m_irq);
73 }
74
port_e4_r()75 uint8_t trs80m3_state::port_e4_r()
76 {
77 /* Indicates which devices are interrupting - d6..d5 not emulated.
78 Whenever an NMI occurs, this port is immediately read
79 to find out which device requires service. Lowest-numbered
80 bit takes precedence. We take this opportunity to clear the
81 cpu NMI line.
82
83 d7 status of FDC INTREQ (0=true)
84 d6 status of Motor Timeout (0=true)
85 d5 status of Reset signal (0=true - this will reboot the computer) */
86
87 m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
88
89 u8 data = m_nmi_data;
90 m_nmi_data = 0;
91 return ~(m_nmi_mask & data);
92 }
93
port_e8_r()94 uint8_t trs80m3_state::port_e8_r()
95 {
96 /* not emulated
97 d7 Clear-to-Send (CTS), Pin 5
98 d6 Data-Set-Ready (DSR), pin 6
99 d5 Carrier Detect (CD), pin 8
100 d4 Ring Indicator (RI), pin 22
101 d3,d2,d0 Not used
102 d1 UART Receiver Input, pin 20 (pin 20 is also DTR) */
103
104 return 0;
105 }
106
port_ea_r()107 uint8_t trs80m3_state::port_ea_r()
108 {
109 /* UART Status Register
110 d7 Data Received ('1'=condition true)
111 d6 Transmitter Holding Register empty ('1'=condition true)
112 d5 Overrun Error ('1'=condition true)
113 d4 Framing Error ('1'=condition true)
114 d3 Parity Error ('1'=condition true)
115 d2..d0 Not used */
116
117 uint8_t data=7;
118 m_uart->write_swe(0);
119 data |= m_uart->tbmt_r() ? 0x40 : 0;
120 data |= m_uart->dav_r( ) ? 0x80 : 0;
121 data |= m_uart->or_r( ) ? 0x20 : 0;
122 data |= m_uart->fe_r( ) ? 0x10 : 0;
123 data |= m_uart->pe_r( ) ? 0x08 : 0;
124 m_uart->write_swe(1);
125
126 return data;
127 }
128
port_ec_r()129 uint8_t trs80m3_state::port_ec_r()
130 {
131 /* Reset the RTC interrupt */
132 m_irq &= ~IRQ_M4_RTC;
133 return 0;
134 }
135
port_ff_r()136 uint8_t trs80m3_state::port_ff_r()
137 {
138 /* Return of cassette data stream from tape
139 d7 Low-speed data
140 d6..d1 info from write of port EC
141 d0 High-speed data */
142
143 m_irq &= 0xfc; /* clear cassette interrupts */
144
145 return m_port_ec | m_cassette_data;
146 }
147
cp500_port_f4_r()148 uint8_t trs80m3_state::cp500_port_f4_r()
149 {
150 /* The A11 flipflop is used for enabling access to
151 the system monitor code at the EPROM address range 3800-3fff */
152 uint8_t *rom = memregion("maincpu")->base();
153 uint8_t *bootrom = memregion("bootrom")->base();
154
155 m_a11_flipflop ^= 1; //toggle the flip-flop at every read at io addresses 0xf4-f7
156
157 for (u8 block=0; block<8; block++)
158 memcpy(&rom[block * 0x800], &bootrom[(block | m_a11_flipflop) * 0x800], 0x800);
159
160 return 0x00; //really?!
161 }
162
163
port_84_w(uint8_t data)164 void trs80m3_state::port_84_w(uint8_t data) // Model 4 & 4P only
165 {
166 /* Memory banking control, video mode control
167 d7 Video Page Control
168 d6 Despage (see p129 of service manual)
169 d5 Enable page mapping (1=enabled)
170 d4 Srcpage (see p129 of service manual)
171 d3 Invert Video
172 d2 80/64 width
173 d1 Select bit 1
174 d0 Select bit 0 */
175
176 if (!(m_model4 & 6)) // Model 3 leave now
177 return;
178
179 m_mode = (m_mode & 0x73) | (data & 0x8c);
180
181 m_model4 &= 0xce;
182 m_model4 |= (data & 3) << 4;
183
184 if (BIT(m_model4, 1)) // Model 4
185 {
186 if (m_mainram->size() >= (64 * 1024))
187 {
188 m_m4_bank->set_bank(data & 0x03);
189 m_32kbanks[0]->set_entry((data >> 4) & 0x07);
190 m_32kbanks[1]->set_entry((data >> 4) & 0x07);
191 m_16kbank->set_entry((data >> 4) & 0x07);
192 }
193 m_vidbank->set_entry(BIT(data, 7));
194 return;
195 }
196
197 if (BIT(m_model4, 2)) // Model 4P
198 {
199 m_32kbanks[0]->set_entry((data >> 4) & 0x07);
200 m_32kbanks[1]->set_entry((data >> 4) & 0x07);
201 m_16kbank->set_entry((data >> 4) & 0x07);
202 m_vidbank->set_entry(BIT(data, 7));
203
204 switch (data & 3)
205 {
206 case 0: /* normal operation */
207 if (BIT(m_model4, 3))
208 m_m4p_bank->set_bank(0);
209 else
210 m_m4p_bank->set_bank(4);
211 break;
212
213 case 1: /* write-only ram backs up the rom */
214 if (BIT(m_model4, 3))
215 m_m4p_bank->set_bank(1);
216 else
217 m_m4p_bank->set_bank(5);
218 break;
219
220 case 2: /* keyboard and video are moved to high memory, and the rest is ram */
221 m_m4p_bank->set_bank(2);
222 m_model4 |= 1;
223 break;
224
225 case 3: /* 64k of ram */
226 m_m4p_bank->set_bank(3);
227 break;
228 }
229 }
230 }
231
port_90_w(uint8_t data)232 void trs80m3_state::port_90_w(uint8_t data)
233 {
234 m_speaker->level_w(!(BIT(data, 0)));
235 }
236
port_9c_w(uint8_t data)237 void trs80m3_state::port_9c_w(uint8_t data) /* model 4P only - swaps the ROM with read-only RAM */
238 {
239 /* Meaning of model4 variable:
240 d5..d4 memory mode (as described in section above)
241 d3 rom switch (1=enabled) only effective in mode0 and 1
242 d2 this is a Model 4P
243 d1 this is a Model 4
244 d0 Video banking exists yes/no (1=not banked) */
245
246 if (!(BIT(m_model4, 2))) // If not Model 4P, leave now
247 return;
248
249 m_model4 &= 0xf7;
250 m_model4 |= (data << 3);
251
252 switch (m_model4 & 0x38)
253 {
254 case 0x00:
255 m_m4p_bank->set_bank(4);
256 break;
257
258 case 0x08:
259 m_m4p_bank->set_bank(0);
260 break;
261
262 case 0x10:
263 m_m4p_bank->set_bank(5);
264 break;
265
266 case 0x18:
267 m_m4p_bank->set_bank(1);
268 break;
269
270 default:
271 break;
272 }
273 }
274
port_e0_w(uint8_t data)275 void trs80m3_state::port_e0_w(uint8_t data)
276 {
277 /* Interrupt settings - which devices are allowed to interrupt - bits align with read of E0
278 d6 Enable Rec Err
279 d5 Enable Rec Data
280 d4 Enable Xmit Emp
281 d3 Enable I/O int
282 d2 Enable RT int
283 d1 C fall Int
284 d0 C Rise Int */
285
286 m_mask = data;
287 }
288
port_e4_w(uint8_t data)289 void trs80m3_state::port_e4_w(uint8_t data)
290 {
291 /* Disk to NMI interface
292 d7 1=enable disk INTRQ to generate NMI
293 d6 1=enable disk Motor Timeout to generate NMI */
294
295 m_nmi_mask = data;
296 }
297
port_e8_w(uint8_t data)298 void trs80m3_state::port_e8_w(uint8_t data)
299 {
300 /* d1 when '1' enables control register load (see below) */
301
302 m_reg_load = BIT(data, 1);
303 }
304
port_ea_w(uint8_t data)305 void trs80m3_state::port_ea_w(uint8_t data)
306 {
307 if (m_reg_load)
308
309 /* d2..d0 not emulated
310 d7 Even Parity Enable ('1'=even, '0'=odd)
311 d6='1',d5='1' for 8 bits
312 d6='0',d5='1' for 7 bits
313 d6='1',d5='0' for 6 bits
314 d6='0',d5='0' for 5 bits
315 d4 Stop Bit Select ('1'=two stop bits, '0'=one stop bit)
316 d3 Parity Inhibit ('1'=disable; No parity, '0'=parity enabled)
317 d2 Break ('0'=disable transmit data; continuous RS232 'SPACE' condition)
318 d1 Request-to-Send (RTS), pin 4
319 d0 Data-Terminal-Ready (DTR), pin 20 */
320
321 {
322 m_uart->write_cs(0);
323 m_uart->write_nb1(BIT(data, 6));
324 m_uart->write_nb2(BIT(data, 5));
325 m_uart->write_tsb(BIT(data, 4));
326 m_uart->write_eps(BIT(data, 7));
327 m_uart->write_np(BIT(data, 3));
328 m_uart->write_cs(1);
329 }
330 else
331 {
332 /* not emulated
333 d7,d6 Not used
334 d5 Secondary Unassigned, pin 18
335 d4 Secondary Transmit Data, pin 14
336 d3 Secondary Request-to-Send, pin 19
337 d2 Break ('0'=disable transmit data; continuous RS232 'SPACE' condition)
338 d1 Data-Terminal-Ready (DTR), pin 20
339 d0 Request-to-Send (RTS), pin 4 */
340
341 }
342 }
343
port_ec_w(uint8_t data)344 void trs80m3_state::port_ec_w(uint8_t data)
345 {
346 /* Hardware settings - d5..d4 not emulated
347 d6 CPU fast (1=4MHz, 0=2MHz)
348 d5 1=Enable Video Wait
349 d4 1=Enable External I/O bus
350 d3 1=Enable Alternate Character Set
351 d2 Mode Select (0=64 chars, 1=32chars)
352 d1 Cassette Motor (1=On) */
353
354 m_maincpu->set_unscaled_clock(data & 0x40 ? MODEL4_MASTER_CLOCK/5 : MODEL4_MASTER_CLOCK/10);
355
356 m_mode = (m_mode & 0xde) | (BIT(data, 2) ? 1 : 0) | (BIT(data, 3) ? 0x20 : 0);
357
358 m_cassette->change_state(( data & 2 ) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR );
359
360 m_port_ec = data & 0x7e;
361 }
362
363 /* Selection of drive and parameters - d6..d5 not emulated.
364 A write also causes the selected drive motor to turn on for about 3 seconds.
365 When the motor turns off, the drive is deselected.
366 d7 1=MFM, 0=FM
367 d6 1=Wait
368 d5 1=Write Precompensation enabled
369 d4 0=Side 0, 1=Side 1
370 d3 1=select drive 3
371 d2 1=select drive 2
372 d1 1=select drive 1
373 d0 1=select drive 0 */
port_f4_w(uint8_t data)374 void trs80m3_state::port_f4_w(uint8_t data)
375 {
376 if (BIT(data, 6))
377 {
378 if (m_drq_off && m_intrq_off)
379 {
380 m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE);
381 m_wait = true;
382 }
383 }
384 else
385 {
386 m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
387 m_wait = false;
388 }
389
390 m_floppy = nullptr;
391
392 if (BIT(data, 0)) m_floppy = m_floppy0->get_device();
393 if (BIT(data, 1)) m_floppy = m_floppy1->get_device();
394
395 m_fdc->set_floppy(m_floppy);
396
397 if (m_floppy)
398 {
399 m_floppy->mon_w(0);
400 m_floppy->ss_w(BIT(data, 4));
401 m_timeout = 1600;
402 }
403
404 m_fdc->dden_w(!BIT(data, 7));
405 }
406
port_ff_w(uint8_t data)407 void trs80m3_state::port_ff_w(uint8_t data)
408 {
409 /* Cassette port
410 d1, d0 Cassette output */
411
412 static const double levels[4] = { 0.0, 1.0, -1.0, 0.0 };
413 m_cassette->output(levels[data & 3]);
414 m_cassette_data &= ~0x80;
415 }
416
417
418 /*************************************
419 *
420 * Interrupt handlers.
421 *
422 *************************************/
423
INTERRUPT_GEN_MEMBER(trs80m3_state::rtc_interrupt)424 INTERRUPT_GEN_MEMBER(trs80m3_state::rtc_interrupt)
425 {
426 /* This enables the processing of interrupts for the clock and the flashing cursor.
427 The OS counts one tick for each interrupt. It is called 30 times per second. */
428
429 if (m_mask & IRQ_M4_RTC)
430 {
431 m_irq |= IRQ_M4_RTC;
432 m_maincpu->set_input_line(0, HOLD_LINE);
433 }
434
435 // While we're here, let's countdown the motor timeout too.
436 if (m_timeout)
437 {
438 m_timeout--;
439 if (m_timeout == 0)
440 if (m_floppy)
441 m_floppy->mon_w(1); // motor off
442 }
443 // Also, if cpu is in wait, unlock it and trigger NMI
444 // Don't, it breaks disk loading
445 // if (m_wait)
446 // {
447 // m_wait = false;
448 // m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
449 // if (BIT(m_nmi_mask, 6))
450 // {
451 // m_nmi_data |= 0x40;
452 // m_maincpu->set_input_line(INPUT_LINE_NMI, HOLD_LINE);
453 // }
454 // }
455 }
456
457 // The floppy sector has been read. Enable CPU and NMI.
WRITE_LINE_MEMBER(trs80m3_state::intrq_w)458 WRITE_LINE_MEMBER(trs80m3_state::intrq_w)
459 {
460 m_intrq_off = state ? false : true;
461 if (state)
462 {
463 m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
464 m_wait = false;
465 if (BIT(m_nmi_mask, 7))
466 {
467 m_nmi_data |= 0x80;
468 //m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
469 m_maincpu->set_input_line(INPUT_LINE_NMI, HOLD_LINE);
470 }
471 }
472 }
473
474 // The next byte from floppy is available. Enable CPU so it can get the byte.
WRITE_LINE_MEMBER(trs80m3_state::drq_w)475 WRITE_LINE_MEMBER(trs80m3_state::drq_w)
476 {
477 m_drq_off = state ? false : true;
478 if (state)
479 {
480 m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE);
481 m_wait = false;
482 }
483 }
484
485
486 /*************************************
487 * *
488 * Memory handlers *
489 * *
490 *************************************/
491
wd179x_r()492 uint8_t trs80m3_state::wd179x_r()
493 {
494 uint8_t data = 0xff;
495 if (BIT(m_io_config->read(), 7))
496 data = m_fdc->status_r();
497
498 return data;
499 }
500
printer_r()501 uint8_t trs80m3_state::printer_r()
502 {
503 return m_cent_status_in->read();
504 }
505
printer_w(uint8_t data)506 void trs80m3_state::printer_w(uint8_t data)
507 {
508 m_cent_data_out->write(data);
509 m_centronics->write_strobe(0);
510 m_centronics->write_strobe(1);
511 }
512
513 /*************************************
514 * Keyboard *
515 *************************************/
keyboard_r(offs_t offset)516 uint8_t trs80m3_state::keyboard_r(offs_t offset)
517 {
518 u8 i, result = 0;
519
520 for (i = 0; i < 8; i++)
521 if (BIT(offset, i))
522 result |= m_io_keyboard[i]->read();
523
524 return result;
525 }
526
527
528 /*************************************
529 * Machine *
530 *************************************/
531
machine_start()532 void trs80m3_state::machine_start()
533 {
534 save_item(NAME(m_model4));
535 save_item(NAME(m_mode));
536 save_item(NAME(m_irq));
537 save_item(NAME(m_mask));
538 save_item(NAME(m_nmi_mask));
539 save_item(NAME(m_port_ec));
540 save_item(NAME(m_reg_load));
541 save_item(NAME(m_nmi_data));
542 save_item(NAME(m_cassette_data));
543 save_item(NAME(m_old_cassette_val));
544 save_item(NAME(m_start_address));
545 save_item(NAME(m_crtc_reg));
546 save_item(NAME(m_size_store));
547 save_item(NAME(m_a11_flipflop));
548 save_item(NAME(m_timeout));
549 save_item(NAME(m_wait));
550 save_item(NAME(m_drq_off));
551 save_item(NAME(m_intrq_off));
552
553 m_mode = 0;
554 m_reg_load = 1;
555 m_nmi_data = 0;
556 m_timeout = 1;
557 m_wait = 0;
558
559 m_cassette_data_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(trs80m3_state::cassette_data_callback),this));
560 m_cassette_data_timer->adjust( attotime::zero, 0, attotime::from_hz(11025) );
561 if (!(m_model4 & 6)) // Model 3 leave now
562 return;
563
564 if (m_mainram->size() < (64 * 1024))
565 {
566 if (BIT(m_model4, 1)) // Model 4
567 {
568 m_m4_bank->set_stride(0x00000);
569 m_m4_bank->space(0).unmap_readwrite(0x08000, 0x0ffff);
570 }
571 else
572 if (BIT(m_model4, 2)) // Model 4P
573 {
574 m_m4p_bank->set_stride(0x00000);
575 m_m4p_bank->space(0).unmap_readwrite(0x08000, 0x0ffff);
576 }
577 m_16kbank->configure_entries(0, 8, m_mainram->pointer() + 0x00000, 0x00000);
578 }
579 else
580 if (m_mainram->size() < (128 * 1024))
581 {
582 m_32kbanks[0]->configure_entries(0, 8, m_mainram->pointer() + 0x00000, 0x00000);
583 m_32kbanks[1]->configure_entries(0, 8, m_mainram->pointer() + 0x08000, 0x00000);
584 m_16kbank->configure_entries(0, 8, m_mainram->pointer() + 0x04000, 0x00000);
585 }
586 else
587 {
588 m_32kbanks[0]->configure_entries(0, 4, m_mainram->pointer() + 0x00000, 0x00000);
589 m_32kbanks[0]->configure_entries(4, 2, m_mainram->pointer() + 0x00000, 0x00000);
590 m_32kbanks[0]->configure_entries(6, 2, m_mainram->pointer() + 0x10000, 0x08000);
591
592 m_32kbanks[1]->configure_entries(0, 2, m_mainram->pointer() + 0x08000, 0x00000);
593 m_32kbanks[1]->configure_entries(2, 2, m_mainram->pointer() + 0x10000, 0x08000);
594 m_32kbanks[1]->configure_entries(4, 4, m_mainram->pointer() + 0x08000, 0x00000);
595
596 m_16kbank->configure_entries(0, 4, m_mainram->pointer() + 0x04000, 0x00000);
597 m_16kbank->configure_entries(4, 2, m_mainram->pointer() + 0x04000, 0x00000);
598 m_16kbank->configure_entries(6, 2, m_mainram->pointer() + 0x14000, 0x08000);
599 }
600 m_vidbank->configure_entries(0, 2, &m_p_videoram[0], 0x0400);
601 }
602
machine_reset()603 void trs80m3_state::machine_reset()
604 {
605 m_a11_flipflop = 0; // for cp500
606 m_cassette_data = 0;
607 m_size_store = 0xff;
608 m_drq_off = true;
609 m_intrq_off = true;
610
611 if (m_model4 & 4)
612 port_9c_w(1); // 4P - enable rom
613 if (m_model4 & 6)
614 port_84_w(0); // 4 & 4P - switch in devices
615 }
616
617
618 /***************************************************************************
619 PARAMETERS
620 ***************************************************************************/
621
622 #define LOG 1
623
624 #define CMD_TYPE_OBJECT_CODE 0x01
625 #define CMD_TYPE_TRANSFER_ADDRESS 0x02
626 #define CMD_TYPE_END_OF_PARTITIONED_DATA_SET_MEMBER 0x04
627 #define CMD_TYPE_LOAD_MODULE_HEADER 0x05
628 #define CMD_TYPE_PARTITIONED_DATA_SET_HEADER 0x06
629 #define CMD_TYPE_PATCH_NAME_HEADER 0x07
630 #define CMD_TYPE_ISAM_DIRECTORY_ENTRY 0x08
631 #define CMD_TYPE_END_OF_ISAM_DIRECTORY_ENTRY 0x0a
632 #define CMD_TYPE_PDS_DIRECTORY_ENTRY 0x0c
633 #define CMD_TYPE_END_OF_PDS_DIRECTORY_ENTRY 0x0e
634 #define CMD_TYPE_YANKED_LOAD_BLOCK 0x10
635 #define CMD_TYPE_COPYRIGHT_BLOCK 0x1f
636
637 /***************************************************************************
638 IMPLEMENTATION
639 ***************************************************************************/
640
QUICKLOAD_LOAD_MEMBER(trs80m3_state::quickload_cb)641 QUICKLOAD_LOAD_MEMBER(trs80m3_state::quickload_cb)
642 {
643 address_space &program = m_maincpu->space(AS_PROGRAM);
644
645 uint8_t type, length;
646 uint8_t data[0x100];
647 uint8_t addr[2];
648 void *ptr;
649
650 while (!image.image_feof())
651 {
652 image.fread( &type, 1);
653 image.fread( &length, 1);
654
655 length -= 2;
656 int block_length = length ? length : 256;
657
658 switch (type)
659 {
660 case CMD_TYPE_OBJECT_CODE:
661 {
662 image.fread( &addr, 2);
663 uint16_t address = (addr[1] << 8) | addr[0];
664 if (LOG) logerror("/CMD object code block: address %04x length %u\n", address, block_length);
665 ptr = program.get_write_ptr(address);
666 image.fread( ptr, block_length);
667 }
668 break;
669
670 case CMD_TYPE_TRANSFER_ADDRESS:
671 {
672 image.fread( &addr, 2);
673 uint16_t address = (addr[1] << 8) | addr[0];
674 if (LOG) logerror("/CMD transfer address %04x\n", address);
675 m_maincpu->set_state_int(Z80_PC, address);
676 }
677 break;
678
679 case CMD_TYPE_LOAD_MODULE_HEADER:
680 image.fread( &data, block_length);
681 if (LOG) logerror("/CMD load module header '%s'\n", data);
682 break;
683
684 case CMD_TYPE_COPYRIGHT_BLOCK:
685 image.fread( &data, block_length);
686 if (LOG) logerror("/CMD copyright block '%s'\n", data);
687 break;
688
689 default:
690 image.fread( &data, block_length);
691 logerror("/CMD unsupported block type %u!\n", type);
692 }
693 }
694
695 return image_init_result::PASS;
696 }
697