trunk/src/mess/drivers/alphatro.c
r23748 | r23749 | |
4 | 4 | |
5 | 5 | skeleton driver |
6 | 6 | |
7 | | z80 + HD46505 as a CRTC |
| 7 | z80 + HD46505SP as a CRTC |
8 | 8 | |
9 | | Has a socket for monochrome (to the standard amber monitor), |
10 | | and another for RGB. We emulate this with a configuration switch. |
| 9 | Other chips: 8251, 8257, 8259 |
| 10 | Crystals: 16MHz, 17.73447MHz |
| 11 | Floppy format: 2 sides, 40 tracks, 16 sectors, 256 bytes = 320kb. |
| 12 | FDC (unknown) is in a plug-in module. |
11 | 13 | |
12 | | The Z80 must start at E000, but unlike other designs (Super80 for |
13 | | example) which causes the ROMs to appear everywhere during boot, |
14 | | this one (it seems) holds the data bus low until E000 is reached. |
15 | | This kind of boot still needs to be emulated. |
| 14 | Has a socket for monochrome (to the standard amber monitor), |
| 15 | and another for RGB. We emulate this with a configuration switch. |
16 | 16 | |
17 | | This machine has 64k RAM, the ROMs being copied into RAM when |
18 | | needed. |
| 17 | The Z80 must start at E000, but unlike other designs (Super80 for |
| 18 | example) which cause the ROMs to appear everywhere during boot, |
| 19 | this one (it seems) holds the data bus low until E000 is reached. |
| 20 | This kind of boot still needs to be emulated. |
19 | 21 | |
| 22 | This machine has 64k RAM, the ROMs being copied into RAM when |
| 23 | needed. |
| 24 | |
20 | 25 | ***************************************************************************/ |
21 | 26 | |
22 | 27 | #include "emu.h" |
r23748 | r23749 | |
49 | 54 | m_cass(*this, "cassette"), |
50 | 55 | m_beep(*this, "beeper"), |
51 | 56 | m_p_ram(*this, "p_ram"), |
52 | | m_p_videoram(*this, "p_videoram"){ } |
| 57 | m_p_videoram(*this, "videoram"){ } |
53 | 58 | |
54 | 59 | required_device<cpu_device> m_maincpu; |
55 | 60 | required_device<mc6845_device> m_crtc; |
r23748 | r23749 | |
62 | 67 | DECLARE_INPUT_CHANGED_MEMBER(alphatro_break); |
63 | 68 | DECLARE_READ_LINE_MEMBER(rxdata_callback); |
64 | 69 | DECLARE_WRITE_LINE_MEMBER(txdata_callback); |
| 70 | TIMER_DEVICE_CALLBACK_MEMBER(alphatro_c); |
| 71 | TIMER_DEVICE_CALLBACK_MEMBER(alphatro_p); |
65 | 72 | |
66 | 73 | required_shared_ptr<UINT8> m_p_ram; |
67 | 74 | required_shared_ptr<UINT8> m_p_videoram; |
r23748 | r23749 | |
75 | 82 | |
76 | 83 | private: |
77 | 84 | UINT8 m_timer_bit; |
| 85 | UINT8 m_cass_data[4]; |
| 86 | bool m_cass_state; |
78 | 87 | virtual void palette_init(); |
79 | 88 | }; |
80 | 89 | |
r23748 | r23749 | |
105 | 114 | } |
106 | 115 | |
107 | 116 | m_cass->change_state( BIT(data, 3) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); |
| 117 | |
| 118 | if (BIT(data,2)) |
| 119 | m_cass_state = 1; |
108 | 120 | } |
109 | 121 | |
110 | 122 | void alphatro_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
r23748 | r23749 | |
128 | 140 | |
129 | 141 | READ_LINE_MEMBER( alphatro_state::rxdata_callback ) |
130 | 142 | { |
131 | | return (m_cass->input() > -0.1) ? 1 : 0; |
| 143 | return (bool)m_cass_data[2]; |
132 | 144 | } |
133 | 145 | |
134 | 146 | WRITE_LINE_MEMBER( alphatro_state::txdata_callback ) |
135 | 147 | { |
136 | | m_cass->output( (state) ? 0.8 : -0.8); |
| 148 | m_cass_state = state; |
137 | 149 | } |
138 | 150 | |
139 | 151 | void alphatro_state::video_start() |
r23748 | r23749 | |
186 | 198 | |
187 | 199 | static ADDRESS_MAP_START( alphatro_map, AS_PROGRAM, 8, alphatro_state ) |
188 | 200 | AM_RANGE(0x0000, 0xefff) AM_RAM AM_SHARE("p_ram") |
189 | | AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("p_videoram") |
| 201 | AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("videoram") |
190 | 202 | ADDRESS_MAP_END |
191 | 203 | |
192 | 204 | static ADDRESS_MAP_START( alphatro_io, AS_IO, 8, alphatro_state ) |
r23748 | r23749 | |
353 | 365 | void alphatro_state::machine_reset() |
354 | 366 | { |
355 | 367 | // do what the IPL does |
356 | | // UINT8* RAM = machine().device<ram_device>("ram")->pointer(); |
357 | 368 | UINT8* ROM = memregion("maincpu")->base(); |
358 | 369 | m_maincpu->set_pc(0xe000); |
359 | 370 | memcpy(m_p_ram, ROM, 0xf000); // copy BASIC to RAM, which the undumped IPL is supposed to do. |
360 | 371 | memcpy(m_p_videoram, ROM+0x1000, 0x1000); |
361 | | // membank("bank1")->set_base(RAM); |
362 | 372 | |
363 | 373 | // probably not correct, exact meaning of port is unknown, vblank/vsync is too slow. |
364 | 374 | m_sys_timer->adjust(attotime::from_usec(10),0,attotime::from_usec(10)); |
365 | | m_serial_timer->adjust(attotime::from_hz(500),0,attotime::from_hz(500)); // USART clock - this is a guesstimate |
| 375 | m_serial_timer->adjust(attotime::from_hz(19225),0,attotime::from_hz(19225)); // USART clock - this value loads a real tape |
366 | 376 | m_timer_bit = 0; |
| 377 | m_cass_state = 1; |
| 378 | m_cass_data[0] = 0; |
| 379 | m_cass_data[1] = 0; |
| 380 | m_cass_data[2] = 0; |
| 381 | m_cass_data[3] = 0; |
367 | 382 | m_beep->set_state(0); |
368 | 383 | m_beep->set_frequency(950); /* piezo-device needs to be measured */ |
369 | 384 | } |
r23748 | r23749 | |
412 | 427 | DEVCB_NULL |
413 | 428 | }; |
414 | 429 | |
| 430 | TIMER_DEVICE_CALLBACK_MEMBER(alphatro_state::alphatro_c) |
| 431 | { |
| 432 | m_cass_data[3]++; |
| 433 | |
| 434 | if (m_cass_state) |
| 435 | m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz |
| 436 | else |
| 437 | m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz |
| 438 | } |
| 439 | |
| 440 | TIMER_DEVICE_CALLBACK_MEMBER(alphatro_state::alphatro_p) |
| 441 | { |
| 442 | /* cassette - turn 1200/2400Hz to a bit */ |
| 443 | m_cass_data[1]++; |
| 444 | UINT8 cass_ws = (m_cass->input() > +0.03) ? 1 : 0; |
| 445 | |
| 446 | if (cass_ws != m_cass_data[0]) |
| 447 | { |
| 448 | m_cass_data[0] = cass_ws; |
| 449 | m_cass_data[2] = ((m_cass_data[1] < 12) ? 1 : 0); |
| 450 | m_cass_data[1] = 0; |
| 451 | } |
| 452 | } |
| 453 | |
415 | 454 | static const cassette_interface alphatro_cassette_interface = |
416 | 455 | { |
417 | 456 | cassette_default_formats, |
418 | 457 | NULL, |
419 | | //(cassette_state) (CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED), |
420 | 458 | (cassette_state) (CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED), |
421 | 459 | "alphatro_cass", |
422 | 460 | NULL |
r23748 | r23749 | |
446 | 484 | MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") |
447 | 485 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
448 | 486 | |
449 | | |
450 | 487 | /* Devices */ |
451 | 488 | MCFG_MC6845_ADD("crtc", MC6845, XTAL_12_288MHz / 8, alphatro_crtc6845_interface) // clk unknown |
452 | 489 | |
453 | 490 | MCFG_I8251_ADD("usart", alphatro_usart_interface) |
454 | 491 | |
455 | 492 | MCFG_CASSETTE_ADD("cassette", alphatro_cassette_interface) |
| 493 | MCFG_TIMER_DRIVER_ADD_PERIODIC("alphatro_c", alphatro_state, alphatro_c, attotime::from_hz(4800)) |
| 494 | MCFG_TIMER_DRIVER_ADD_PERIODIC("alphatro_p", alphatro_state, alphatro_p, attotime::from_hz(40000)) |
456 | 495 | |
457 | 496 | MCFG_RAM_ADD("ram") |
458 | 497 | MCFG_RAM_DEFAULT_SIZE("64K") |