trunk/src/mess/machine/bbc.c
r22551 | r22552 | |
564 | 564 | if ((myo>=0x00) && (myo<=0x07)) return bbc_6845_r(space, myo-0x00); /* Video Controller */ |
565 | 565 | if ((myo>=0x08) && (myo<=0x0f)) |
566 | 566 | { |
567 | | acia6850_device *acia = machine().device<acia6850_device>("acia6850"); |
568 | | |
569 | 567 | if ((myo - 0x08) & 1) |
570 | | return acia->status_read(space,0); |
| 568 | return m_acia->status_read(space,0); |
571 | 569 | else |
572 | | return acia->data_read(space,0); |
| 570 | return m_acia->data_read(space,0); |
573 | 571 | } |
574 | 572 | if ((myo>=0x10) && (myo<=0x17)) return 0xfe; /* Serial System Chip */ |
575 | 573 | if ((myo>=0x18) && (myo<=0x1f)) return uPD7002_r(machine().device("upd7002"), space, myo-0x18); /* A to D converter */ |
r22551 | r22552 | |
604 | 602 | if ((myo>=0x00) && (myo<=0x07)) bbc_6845_w(space, myo-0x00,data); /* Video Controller */ |
605 | 603 | if ((myo>=0x08) && (myo<=0x0f)) |
606 | 604 | { |
607 | | acia6850_device *acia = machine().device<acia6850_device>("acia6850"); |
608 | | |
609 | 605 | if ((myo - 0x08) & 1) |
610 | | acia->control_write(space, 0, data); |
| 606 | m_acia->control_write(space, 0, data); |
611 | 607 | else |
612 | | acia->data_write(space, 0, data); |
| 608 | m_acia->data_write(space, 0, data); |
613 | 609 | } |
614 | 610 | if ((myo>=0x10) && (myo<=0x17)) bbc_SerialULA_w(space, myo-0x10,data); /* Serial System Chip */ |
615 | 611 | if ((myo>=0x18) && (myo<=0x1f)) uPD7002_w(machine().device("upd7002"),space,myo-0x18,data); /* A to D converter */ |
r22551 | r22552 | |
1296 | 1292 | |
1297 | 1293 | void bbc_state::MC6850_Receive_Clock(int new_clock) |
1298 | 1294 | { |
1299 | | if (!m_mc6850_clock && new_clock) |
| 1295 | m_rxd = new_clock; |
| 1296 | |
| 1297 | // |
| 1298 | // Somehow the "serial processor" generates 16 clock signals towards |
| 1299 | // the 6850. Exact details are unknown, faking it with the following |
| 1300 | // loop. |
| 1301 | // |
| 1302 | for (int i = 0; i < 16; i++ ) |
1300 | 1303 | { |
1301 | | acia6850_device *acia = machine().device<acia6850_device>("acia6850"); |
1302 | | acia->tx_clock_in(); |
| 1304 | m_acia->rx_clock_in(); |
1303 | 1305 | } |
1304 | | m_mc6850_clock = new_clock; |
1305 | 1306 | } |
1306 | 1307 | |
1307 | 1308 | TIMER_CALLBACK_MEMBER(bbc_state::bbc_tape_timer_cb) |
1308 | 1309 | { |
1309 | 1310 | double dev_val = m_cassette->input(); |
1310 | 1311 | |
1311 | | // look for rising edges on the cassette wave |
| 1312 | // look for edges on the cassette wave |
1312 | 1313 | if (((dev_val>=0.0) && (m_last_dev_val<0.0)) || ((dev_val<0.0) && (m_last_dev_val>=0.0))) |
1313 | 1314 | { |
1314 | 1315 | if (m_wav_len>(9*3)) |
1315 | 1316 | { |
1316 | 1317 | //this is to long to recive anything so reset the serial IC. This is a hack, this should be done as a timer in the MC6850 code. |
1317 | 1318 | logerror ("Cassette length %d\n",m_wav_len); |
| 1319 | m_nr_high_tones = 0; |
| 1320 | m_dcd = 0; |
1318 | 1321 | m_len0=0; |
1319 | 1322 | m_len1=0; |
1320 | 1323 | m_len2=0; |
r22551 | r22552 | |
1335 | 1338 | { |
1336 | 1339 | /* Clock a 0 onto the serial line */ |
1337 | 1340 | logerror("Serial value 0\n"); |
| 1341 | m_nr_high_tones = 0; |
| 1342 | m_dcd = 0; |
1338 | 1343 | MC6850_Receive_Clock(0); |
1339 | 1344 | m_len0=0; |
1340 | 1345 | m_len1=0; |
r22551 | r22552 | |
1346 | 1351 | { |
1347 | 1352 | /* Clock a 1 onto the serial line */ |
1348 | 1353 | logerror("Serial value 1\n"); |
| 1354 | m_nr_high_tones++; |
| 1355 | if ( m_nr_high_tones > 100 ) |
| 1356 | { |
| 1357 | m_dcd = 1; |
| 1358 | } |
1349 | 1359 | MC6850_Receive_Clock(1); |
1350 | 1360 | m_len0=0; |
1351 | 1361 | m_len1=0; |
r22551 | r22552 | |
1384 | 1394 | |
1385 | 1395 | WRITE8_MEMBER(bbc_state::bbc_SerialULA_w) |
1386 | 1396 | { |
1387 | | BBC_Cassette_motor((data & 0x80) >> 7); |
| 1397 | m_serproc_data = data; |
| 1398 | BBC_Cassette_motor(m_serproc_data & 0x80); |
1388 | 1399 | } |
1389 | 1400 | |
1390 | 1401 | /************************************** |
r22551 | r22552 | |
1970 | 1981 | DRIVER_INIT_MEMBER(bbc_state,bbc) |
1971 | 1982 | { |
1972 | 1983 | m_Master=0; |
| 1984 | m_rxd = 0; |
| 1985 | m_dcd = 0; |
| 1986 | m_txd = 0; |
| 1987 | m_cts = 1; |
| 1988 | m_nr_high_tones = 0; |
| 1989 | m_serproc_data = 0; |
1973 | 1990 | m_tape_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bbc_state::bbc_tape_timer_cb),this)); |
1974 | 1991 | } |
| 1992 | |
1975 | 1993 | DRIVER_INIT_MEMBER(bbc_state,bbcm) |
1976 | 1994 | { |
1977 | 1995 | m_Master=1; |
| 1996 | m_rxd = 0; |
| 1997 | m_dcd = 0; |
| 1998 | m_txd = 0; |
| 1999 | m_cts = 1; |
| 2000 | m_nr_high_tones = 0; |
| 2001 | m_serproc_data = 0; |
1978 | 2002 | m_tape_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bbc_state::bbc_tape_timer_cb),this)); |
1979 | 2003 | } |
1980 | 2004 | |
trunk/src/mess/includes/bbc.h
r22551 | r22552 | |
31 | 31 | m_sn(*this, "sn76489"), |
32 | 32 | m_trom(*this, "saa505x"), |
33 | 33 | m_cassette(*this, "cassette"), |
| 34 | m_acia(*this, "acia6850"), |
34 | 35 | m_ACCCON_IRR(CLEAR_LINE), |
35 | 36 | m_via_system_irq(CLEAR_LINE), |
36 | 37 | m_via_user_irq(CLEAR_LINE), |
r22551 | r22552 | |
52 | 53 | optional_device<sn76489_device> m_sn; |
53 | 54 | required_device<saa5050_device> m_trom; |
54 | 55 | required_device<cassette_image_device> m_cassette; |
| 56 | required_device<acia6850_device> m_acia; |
55 | 57 | |
56 | 58 | void check_interrupts(); |
57 | 59 | |
r22551 | r22552 | |
158 | 160 | int m_len2; |
159 | 161 | int m_len3; |
160 | 162 | int m_mc6850_clock; |
| 163 | UINT8 m_serproc_data; |
| 164 | int m_dcd; |
| 165 | int m_rxd; |
| 166 | int m_txd; |
| 167 | int m_cts; |
| 168 | UINT32 m_nr_high_tones; |
161 | 169 | emu_timer *m_tape_timer; |
162 | 170 | |
163 | 171 | |
r22551 | r22552 | |
319 | 327 | DECLARE_WRITE_LINE_MEMBER(bbc_wd177x_intrq_w); |
320 | 328 | DECLARE_WRITE_LINE_MEMBER(bbc_wd177x_drq_w); |
321 | 329 | DECLARE_WRITE_LINE_MEMBER(bbc_vsync); |
| 330 | DECLARE_READ_LINE_MEMBER(bbc_rxd_r) { return m_rxd; } |
| 331 | DECLARE_READ_LINE_MEMBER(bbc_dcd_r) { return m_dcd; } |
| 332 | DECLARE_READ_LINE_MEMBER(bbc_cts_r) { return m_cts; } |
322 | 333 | |
323 | 334 | DECLARE_DEVICE_IMAGE_LOAD_MEMBER( bbcb_cart ); |
324 | 335 | |