From 955102331370c06c8f290ee5930106a4ced659ad Mon Sep 17 00:00:00 2001 From: Bavarese Date: Sun, 30 Jul 2017 20:37:49 +0200 Subject: [PATCH] Rainbow-100: use Z80SIO instead of Z80DART; make UCSD Pascal boot again (#2524) Incorporates change from Z80DART to Z80SIO proposed by Edstrom. Also make UCSD Pascal boot again. --- src/mame/drivers/rainbow.cpp | 335 ++++++++++++++++------------------- 1 file changed, 157 insertions(+), 178 deletions(-) diff --git a/src/mame/drivers/rainbow.cpp b/src/mame/drivers/rainbow.cpp index 8a25f97912a..551ca6c2e28 100644 --- a/src/mame/drivers/rainbow.cpp +++ b/src/mame/drivers/rainbow.cpp @@ -1,7 +1,3 @@ -// Define suppresses costly smooth scroll / updates when debugging: -// ENABLE BY UNCOMMENTING. ADDITIONALLY, SET SMOOTH SCROLL IN EMULATION (DISABLE BY SETTING JUMP SCROLL. To enter SETUP hit ScrollLock)- -//#define BOOST_DEBUG_PERFORMANCE - // license:GPL-2.0+ // copyright-holders:Miodrag Milanovic,Karl-Ludwig Deisenhofer /*************************************************************************************************** @@ -356,10 +352,12 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND). #include "machine/wd2010.h" #include "machine/corvushd.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "bus/rs232/rs232.h" #include "imagedev/bitbngr.h" #include "machine/com8116.h" +#include "bus/rs232/terminal.h" +#include "bus/rs232/ser_mouse.h" #include "machine/i8251.h" #include "machine/clock.h" @@ -614,7 +612,7 @@ public: IRQ_CALLBACK_MEMBER(irq_callback); DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock); - TIMER_DEVICE_CALLBACK_MEMBER(motor_tick); + TIMER_DEVICE_CALLBACK_MEMBER(hd_motor_tick); DECLARE_FLOPPY_FORMATS(floppy_formats); @@ -665,9 +663,10 @@ private: required_device m_corvus_hdc; - required_device m_mpsc; + required_device m_mpsc; required_device m_dbrg_A; required_device m_dbrg_B; + required_device m_kbd8251; required_device m_lk201; required_shared_ptr m_p_ram; @@ -720,8 +719,6 @@ private: bool m_kbd_tx_ready, m_kbd_rx_ready; int m_KBD; - int MOTOR_DISABLE_counter; - uint8_t m_diagnostic; uint8_t m_z80_private[0x800]; // Z80 private 2K @@ -730,7 +727,7 @@ private: void update_kbd_irq(); virtual void machine_reset() override; - int m_unit; + int m_present_drive; floppy_image_device *m_floppy; int m_irq_high; @@ -751,6 +748,7 @@ private: bool m_POWER_GOOD; emu_timer *cmd_timer; + emu_timer *switch_off_timer; const int vectors[9] = { 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x02 }; @@ -761,6 +759,8 @@ private: // FULL RANGE video levels for 100-B model, taken from page 46 of PDF const uint8_t video_levels[16] = { 255, 217, 201,186, 171, 156, 140, 125, 110, 97, 79, 66, 54, 31, 18, 0 }; uint8_t m_PORT50; + + const int comm_rates[16] = { 50,75,110,134,150,200,300,600,1200,1800,2000,2400,3600,4800,9600,19200 }; }; @@ -796,15 +796,6 @@ printf("\n** OPTION GRFX. RESET **\n"); UPD7220_DISPLAY_PIXELS_MEMBER( rainbow_state::hgdc_display_pixels ) { -#ifdef BOOST_DEBUG_PERFORMANCE - uint8_t *ram = memregion("maincpu")->base(); - if( !(m_p_vol_ram[0x84] == 0x00) ) - { - if( (MOTOR_DISABLE_counter) || (ram[0xEFFFE] & 16) ) // if HDD/FDD ACTIVITY -OR- SMOOTH SCROLL IN PROGRESS - return; - } -#endif - const rgb_t *paletteX = m_palette2->palette()->entry_list_raw(); int xi; @@ -864,8 +855,11 @@ FLOPPY_FORMATS_END static SLOT_INTERFACE_START(rainbow_floppies) SLOT_INTERFACE("525qd0", FLOPPY_525_QD) // QD means 80 tracks with DD data rate (single or double sided). SLOT_INTERFACE("525qd1", FLOPPY_525_QD) +//SLOT_INTERFACE("525qd2", FLOPPY_525_QD) +//SLOT_INTERFACE("525qd3", FLOPPY_525_QD) SLOT_INTERFACE("525dd", FLOPPY_525_DD) // mimic a 5.25" PC (40 track) drive. Requires IDrive5.SYS. SLOT_INTERFACE("35dd", FLOPPY_35_DD) // mimic 3.5" PC drive (720K, double density). Use Impdrv3.SYS. +SLOT_INTERFACE("525ssdd", FLOPPY_525_SSDD) // to read a single sided, (160K) PC-DOS 1 disk with MediaMaster SLOT_INTERFACE_END void rainbow_state::machine_start() @@ -874,7 +868,8 @@ void rainbow_state::machine_start() cmd_timer = timer_alloc(0); cmd_timer->adjust(attotime::from_msec(MS_TO_POWER_GOOD)); - MOTOR_DISABLE_counter = 2; // soon resets drv.LEDs + switch_off_timer = timer_alloc(1); + switch_off_timer->adjust(attotime::from_msec(10)); m_SCREEN_BLANK = false; @@ -980,7 +975,7 @@ AM_RANGE(0x56, 0x57) AM_DEVREADWRITE("upd7220", upd7220_device, read, write) // // 0x60 -> 0x6f ***** EXTENDED COMM. OPTION / Option Select 2. // =========================================================== // 0x60 -> 0x6f ***** RD51 HD. CONTROLLER / Option Select 2. -AM_RANGE(0x60, 0x67) AM_DEVREADWRITE("hdc", wd2010_device, read, write) +AM_RANGE(0x60, 0x67) AM_DEVREADWRITE("hdc", wd2010_device, read, write) AM_MIRROR(0x100) AM_RANGE(0x68, 0x68) AM_READWRITE(hd_status_68_r, hd_status_68_w) AM_RANGE(0x69, 0x69) AM_READ(hd_status_69_r) // =========================================================== @@ -1073,12 +1068,12 @@ PORT_DIPSETTING(0xE0000, "896 K (100-B MAX. MEMORY)") // EXT.COMM.card -or- RD51 HD. controller (marketed later). PORT_START("DEC HARD DISK") // BUNDLE_OPTION -PORT_DIPNAME(0x01, 0x00, "DEC HARD DISK") PORT_TOGGLE +PORT_DIPNAME(0x01, 0x00, "DEC HARD DISK (#1)") PORT_TOGGLE PORT_DIPSETTING(0x00, DEF_STR(Off)) PORT_DIPSETTING(0x01, DEF_STR(On)) PORT_START("CORVUS HARD DISKS") -PORT_DIPNAME(0x01, 0x00, "CORVUS HARD DISKS") PORT_TOGGLE +PORT_DIPNAME(0x01, 0x00, "CORVUS HARD DISKS (#2 to #5)") PORT_TOGGLE PORT_DIPSETTING(0x00, DEF_STR(Off)) PORT_DIPSETTING(0x01, DEF_STR(On)) @@ -1142,7 +1137,6 @@ void rainbow_state::machine_reset() uint32_t unmap_start = m_inp8->read(); // Verify RAM size matches hardware (DIP switches) - uint8_t *nv = memregion("maincpu")->base(); uint8_t NVRAM_LOCATION; uint32_t check; @@ -1155,7 +1149,7 @@ void rainbow_state::machine_reset() } check = (unmap_start >> 16)-1; // guess. - NVRAM_LOCATION = nv[0xed084]; // location not verified yet. DMT RAM check tests offset $84 ! + NVRAM_LOCATION = m_p_nvram[0x84]; // location not verified yet. DMT RAM check tests offset $84 ! #ifdef RTC_ENABLED // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-A' *************************************** @@ -1173,7 +1167,7 @@ void rainbow_state::machine_reset() } check = (unmap_start >> 16) - 2; - NVRAM_LOCATION = nv[0xed0db]; + NVRAM_LOCATION = m_p_nvram[0xdb]; #ifdef RTC_ENABLED // *********************************** / DS1315 'PHANTOM CLOCK' IMPLEMENTATION FOR 'DEC-100-B' *************************************** @@ -1212,6 +1206,8 @@ void rainbow_state::machine_reset() local_hard_disk = rainbow_hdc_file(0); // one hard disk for now. output().set_value("led1", 0); + switch_off_timer->adjust(attotime::from_msec(500)); + if (local_hard_disk) { hard_disk_info *info; @@ -1231,11 +1227,11 @@ void rainbow_state::machine_reset() } } - if (m_inp6->read() == 0x00) // Unmap port if Corvus not present + if (m_inp6->read() == 0x00) // Unmap port if Corvus not present io.unmap_readwrite(0x20, 0x20); // *********** FLOPPY DISK CONTROLLER [ NOT OPTIONAL ] - m_unit = INVALID_DRIVE; + m_present_drive = INVALID_DRIVE; m_fdc->reset(); m_fdc->set_floppy(nullptr); m_fdc->dden_w(0); @@ -1306,7 +1302,23 @@ void rainbow_state::device_timer(emu_timer &timer, device_timer_id tid, int para printf("\n**** WATCHDOG: CPU RESET ****\n"); m_i8088->reset(); // gives 'ERROR_16 - INTERRUPTS OFF' (indicates hardware failure or software bug). } - } // switch + break; // case 0 + + case 1: + + switch_off_timer->adjust(attotime::never); + + output().set_value("driveled0", 0); // DRIVE 0 (A) + output().set_value("driveled1", 0); // DRIVE 1 (B) + output().set_value("driveled2", 0); // DRIVE 2 (C) + output().set_value("driveled3", 0); // DRIVE 3 (D) + + output().set_value("led1", 1); // 1 = OFF (One of the CPU LEDs as drive LED for DEC hard disk) + output().set_value("led2", 1); // 1 = OFF (One of the CPU LEDs as drive LED for Corvus HD) + + break; // case 1 + + } // switch (timer ID) } uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -1332,15 +1344,6 @@ uint32_t rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind1 m_color_map_changed = true; } -#ifdef BOOST_DEBUG_PERFORMANCE - uint8_t *ram = memregion("maincpu")->base(); - if( !(m_p_vol_ram[0x84] == 0x00) ) - { - if( (MOTOR_DISABLE_counter) || (ram[0xEFFFE] & 16) ) // if HDD/FDD ACTIVITY -OR- SMOOTH SCROLL IN PROGRESS - return 0; - } -#endif - m_crtc->palette_select(palette_selected); if( m_SCREEN_BLANK || @@ -1405,10 +1408,10 @@ WRITE_LINE_MEMBER(rainbow_state::mpsc_irq) WRITE8_MEMBER(rainbow_state::comm_bitrate_w) { m_dbrg_A->str_w(data & 0x0f); // PDF is wrong, low nibble is RECEIVE clock (verified in SETUP). - printf("\nRECEIVE bitrate = %02x HEX\n",data & 0x0f); + logerror("\n(COMM.) receive bitrate = %d ($%02x)\n", comm_rates[data & 0x0f] , data & 0x0f); m_dbrg_A->stt_w( ((data & 0xf0) >> 4) ); - printf("\nTRANSMIT bitrate = %02x HEX\n",(data & 0xf0) >> 4); + logerror("(COMM.) transmit bitrate = %d ($%02x)\n", comm_rates[((data & 0xf0) >> 4)] ,(data & 0xf0) >> 4); } // PORT 0x0e : Printer bit rates @@ -1416,15 +1419,15 @@ WRITE8_MEMBER(rainbow_state::printer_bitrate_w) { m_dbrg_B->str_w(data & 7); // bits 0 - 2 m_dbrg_B->stt_w(data & 7); // TX and RX rate cannot be programmed independently. - printf("\n(PRINTER) RECEIVE / TRANSMIT bitrate = %02x HEX\n",data & 7); + logerror("\n(PRINTER) receive = transmit bitrate: %d ($%02x)", 9600 / ( 1 << (7 - (data & 7))) , data & 7); // "bit 3 controls the communications port clock (RxC,TxC). External clock when 1, internal when 0" - printf(" - CLOCK (0 = internal): %02x", data & 8); + logerror(" - CLOCK (0 = internal): %02x", data & 8); } WRITE_LINE_MEMBER(rainbow_state::com8116_a_fr_w) { - m_mpsc->rxca_w(state); + m_mpsc->rxca_w(state); } WRITE_LINE_MEMBER(rainbow_state::com8116_a_ft_w) @@ -1609,13 +1612,13 @@ READ8_MEMBER(rainbow_state::corvus_status_r) { if(m_inp6->read() == 0) // Corvus controller { - popmessage("Corvus controller invoked - but not switched on. Check DIP and perform a reset."); + popmessage("Corvus controller invoked - but switched OFF.\nCheck DIP and perform a reset.\n\nIncompatible software also triggers this warning (illegal access to port $21)"); return 0; } else { output().set_value("led2", 0); - MOTOR_DISABLE_counter = 5; + switch_off_timer->adjust(attotime::from_msec(500)); uint8_t status = m_corvus_hdc->status_r(space, 0); uint8_t data = (status & 0x80) ? 1 : 0; // 0x80 BUSY (Set = Busy, Clear = Ready) @@ -1727,6 +1730,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_read_sector) { read_status = 2; // logerror("\nTRYING TO READ"); output().set_value("led1", 0); + switch_off_timer->adjust(attotime::from_msec(500)); int hi = (m_hdc->read(generic_space(), 0x05)) & 0x07; uint16_t cylinder = (m_hdc->read(generic_space(), 0x04)) | (hi << 8); @@ -1797,7 +1801,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_write_sector) ) { output().set_value("led1", 0); // (1 = OFF ) =HARD DISK ACTIVITY = - MOTOR_DISABLE_counter = 20; + switch_off_timer->adjust(attotime::from_msec(500)); if (rainbow_hdc_file(0) != nullptr) { @@ -1834,6 +1838,7 @@ int rainbow_state::do_write_sector() { int feedback = 0; // no error output().set_value("led1", 0); // ON + switch_off_timer->adjust(attotime::from_msec(500)); hard_disk_file *local_hard_disk; local_hard_disk = rainbow_hdc_file(0); // one hard disk for now. @@ -1989,7 +1994,7 @@ WRITE8_MEMBER(rainbow_state::hd_status_68_w) if (data & 0x01) { output().set_value("led1", 0); // 1 = OFF (One of the CPU LEDs as DRIVE LED) = HARD DISK ACTIVITY = - MOTOR_DISABLE_counter = 20; + switch_off_timer->adjust(attotime::from_msec(500)); m_hdc->buffer_ready(true); } @@ -2057,7 +2062,7 @@ WRITE_LINE_MEMBER(rainbow_state::hdc_step) m_hdc_step_latch = true; output().set_value("led1", 0); // 1 = OFF (One of the CPU LEDs as DRIVE LED) = HARD DISK ACTIVITY = - MOTOR_DISABLE_counter = 20; + switch_off_timer->adjust(attotime::from_msec(500)); } WRITE_LINE_MEMBER(rainbow_state::hdc_direction) @@ -2177,11 +2182,12 @@ READ8_MEMBER(rainbow_state::comm_control_r) if (m_POWER_GOOD) is_mhfu_enabled = m_crtc->MHFU(MHFU_IS_ENABLED); - return ( + return ( (is_mhfu_enabled ? 0x00 : 0x20) | // (L) status of MHFU flag => bit pos.5 ((INT88) ? 0x00 : 0x40) | // (L) ((INTZ80) ? 0x00 : 0x80) // (L) ); + } // ******* TODO: 4 control bits * MISSING * ******************************************************** @@ -2193,7 +2199,7 @@ READ8_MEMBER(rainbow_state::comm_control_r) // 3 COMM RTS (controls request to send line of COMM) WRITE8_MEMBER(rainbow_state::comm_control_w) { - printf("%02x to COMM.CONTROL REGISTER ", data); + logerror("%02x to COMM.CONTROL REGISTER ", data); /* 8088 LEDs: 5 7 6 4 <- BIT POSITION @@ -2206,13 +2212,11 @@ WRITE8_MEMBER(rainbow_state::comm_control_w) output().set_value("led7", BIT(data, 4)); // LED "D3" } - - // 8088 writes to port 0x00 (interrupts Z80) // See page 133 (4-34) WRITE8_MEMBER(rainbow_state::i8088_latch_w) { - // printf("%02x to Z80 mailbox\n", data); + // logerror("%02x to Z80 mailbox\n", data); // The interrupt vector address(F7H) placed on the bus is hardwired into the Z80A interrupt vector encoder. // The F7H interrupt vector address causes the Z80A processor to perform an RST 30 instruction in @@ -2227,7 +2231,7 @@ WRITE8_MEMBER(rainbow_state::i8088_latch_w) // See page 134 (4-35) READ8_MEMBER(rainbow_state::z80_latch_r) { - // printf("Read %02x from Z80 mailbox\n", m_z80_mailbox); + // logerror("Read %02x from Z80 mailbox\n", m_z80_mailbox); m_z80->set_input_line(0, CLEAR_LINE); INTZ80 = false; @@ -2238,7 +2242,7 @@ READ8_MEMBER(rainbow_state::z80_latch_r) // See page 134 (4-35) WRITE8_MEMBER(rainbow_state::z80_latch_w) { - // printf("%02x to 8088 mailbox\n", data); + // logerror("%02x to 8088 mailbox\n", data); raise_8088_irq(IRQ_8088_MAILBOX); m_8088_mailbox = data; @@ -2248,7 +2252,7 @@ WRITE8_MEMBER(rainbow_state::z80_latch_w) // 8088 reads port 0x00. See page 133 (4-34) READ8_MEMBER(rainbow_state::i8088_latch_r) { - // printf("Read %02x from 8088 mailbox\n", m_8088_mailbox); + // logerror("Read %02x from 8088 mailbox\n", m_8088_mailbox); lower_8088_irq(IRQ_8088_MAILBOX); INT88 = false; @@ -2297,37 +2301,36 @@ READ8_MEMBER(rainbow_state::z80_generalstat_r) D0 : ZFLIP L: (read from the diagnostic control register of Z80A) */ static int last_track; - int track = 0; + int fdc_step = 0; int fdc_ready = 0; int tk00 = 0; int fdc_write_gate = 0; int last_dir = 0; -// printf("\nFLOPPY %02d - ", m_unit); - if (m_fdc) + uint8_t fdc_status; + + if(m_fdc) { - track = m_fdc->track_r(space, 0); - if (track != last_track) - fdc_step = 1; // calculate STEP (sic) + track = m_fdc->track_r(space, 0); + if(track == 0) + tk00 = 1; - last_dir = track > last_track ? 0 : 1; // see WD_FDC - last_track = track; - } + if (track != last_track) + fdc_step = 1; // calculate STEP (sic) - if (m_floppy) - { - if (!m_floppy->ready_r()) // weird (see wd_fdc) - fdc_ready = 1; + last_dir = track > last_track ? 0 : 1; // see WD_FDC + last_track = track; - if ((fdc_ready) && (m_floppy->wpt_r() != 1) && m_POWER_GOOD) - fdc_write_gate = 1; // * FAKE * WRITE GATE ! + fdc_status = m_fdc->status_r(); - // "valid only when drive is selected" ! - if (!m_floppy->trk00_r()) // weird (see wd_fdc) - tk00 = 1; - } + if ( (fdc_status & 0x80) == 0) // (see WD_FDC: S_WP = 0x40, S_NRDY = 0x80, S_TR00 = 0x04) + fdc_ready = 1; + + if ( fdc_ready && ((fdc_status & 0x40) == 0) && m_POWER_GOOD ) + fdc_write_gate = 1; // "valid only when drive is selected" ! + } int data = ( ((fdc_step) ? 0x00 : 0x80) | @@ -2348,41 +2351,40 @@ READ8_MEMBER(rainbow_state::z80_generalstat_r) // 40H diskette status Register **** READ ONLY *** ( 4-60 of TM100.pdf ) READ8_MEMBER(rainbow_state::z80_diskstatus_r) { - int track = 0; - int data = m_z80_diskcontrol & (255 - 0x80 - 0x40 - 0x20 - 4); + int track = 0xEE; + int data = m_z80_diskcontrol & (255 - 0x80 - 0x40 - 0x20 - 0x04); // 00011011 // D7: DRQ: reflects status of DATA REQUEST signal from FDC. // '1' indicates that FDC has read data OR requires new write data. - if (m_fdc) - data |= m_fdc->drq_r() ? 0x80 : 0x00; // D6: IRQ: indicates INTERRUPT REQUEST signal from FDC. Indicates that a // status bit has changed. Set to 1 at the completion of any // command (.. see page 207 or 5-25). if (m_fdc) + { + data |= m_fdc->drq_r() ? 0x80 : 0x00; data |= m_fdc->intrq_r() ? 0x40 : 0x00; + track = m_fdc->track_r(space, 0); + + // D2: TG43 * LOW ACTIVE * : 0 = INDICATES TRACK > 43 SIGNAL FROM FDC TO DISK DRIVE. + // (asserted when writing data to tracks 44 through 79) + data |= (track > 43) ? 0x00 : 0x04; // ! LOW ACTIVE ! + } // D5: SIDE 0 * HIGH ACTIVE *: status of side select signal at J2 + J3 of RX50 controller. // For 1 sided drives, this bit will always read low (0). - if (m_floppy) + if (m_floppy != nullptr) data |= m_floppy->ss_r() ? 0x20 : 0x00; // *LOW ACTIVE * // D4: MOTOR 1 ON L: 0 = indicates MOTOR 1 ON bit is set in drive control reg. // D3: MOTOR 0 ON L: 0 = indicates MOTOR 0 ON bit is set in drive " - if (m_fdc) - track = m_fdc->track_r(space, 0); - // Print HEX track number static uint8_t bcd2hex[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; // 0...9 ,A (0x77), b (0x7c), C (0x39) , d (0x5e), E (0x79), F (0x71) output().set_digit_value(0, bcd2hex[(track >> 4) & 0x0f]); - output().set_digit_value(1, bcd2hex[(track - ((track >> 4) << 4)) & 0x0f]); - - // D2: TG43 * LOW ACTIVE * : 0 = INDICATES TRACK > 43 SIGNAL FROM FDC TO DISK DRIVE. - // (asserted when writing data to tracks 44 through 79) - data |= (track > 43) ? 0x00 : 0x04; // ! LOW ACTIVE ! + output().set_digit_value(1, bcd2hex[ track & 0x0f]); // D1: DS1 H: reflect status of bits 0 and 1 from disk.control reg. // D0: DS0 H: " @@ -2397,6 +2399,9 @@ READ8_MEMBER(rainbow_state::z80_diskstatus_r) // BIT 5 : SIDE 0 L : For single sided drives, this bit is always set to 0 for side O. WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w) { + int enable_start; + int disable_start; // set defaults + int selected_drive = INVALID_DRIVE; static const char *names[] = { FD1793_TAG ":0", FD1793_TAG ":1", FD1793_TAG ":2", FD1793_TAG ":3" }; @@ -2415,31 +2420,14 @@ WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w) m_floppy = con->get_device(); if (m_floppy) selected_drive = drive; -// printf("%i <- SELECTED DRIVE...\n", m_unit); } if (selected_drive == INVALID_DRIVE) { - printf("(m_unit = %i) ** SELECTED DRIVE ** INVALID. (selected drive = %i)\n", m_unit, selected_drive); - m_unit = INVALID_DRIVE; - m_floppy = nullptr; - } + logerror("(m_present_drive = %i) ** SELECTED DRIVE ** INVALID. (selected drive = %i)\n", m_present_drive, selected_drive); - if (m_floppy != nullptr) - { - m_fdc->set_floppy(m_floppy); // Sets new _image device_ - m_fdc->dden_w(0); // 0 = MFM - if (!m_floppy->exists()) // invalidate selection - { - m_floppy = nullptr; - printf("(m_unit = %i) SELECTED IMAGE *** DOES NOT EXIST *** (selected drive = %i)\n", m_unit, selected_drive); - selected_drive = m_unit; - } - else - { - m_floppy->ss_w((data & 0x20) ? 1 : 0); // RX50 board in Rainbow has 'side select' - m_floppy->set_rpm(300.); - } + m_present_drive = INVALID_DRIVE; + m_floppy = nullptr; } output().set_value("driveled0", (selected_drive == 0) ? 1 : 0); @@ -2447,59 +2435,58 @@ WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w) output().set_value("driveled2", (selected_drive == 2) ? 1 : 0); output().set_value("driveled3", (selected_drive == 3) ? 1 : 0); + switch_off_timer->adjust(attotime::from_msec(500)); - if (selected_drive < 4) + if (m_floppy != nullptr) { - m_unit = selected_drive; + m_fdc->set_floppy(m_floppy); // Sets new _image device_ + m_fdc->dden_w(0); // 0 = MFM + m_floppy->ss_w((data & 0x20) ? 1 : 0); // RX50 board in Rainbow has 'side select' + m_floppy->set_rpm(300.); - if (MOTOR_DISABLE_counter == 0) // "one shot" - MOTOR_DISABLE_counter = 20; + if ( !m_floppy->exists() && (selected_drive > 1) ) + popmessage("NO IMAGE ATTACHED TO %c\n", 65 + selected_drive ); + } + + if(selected_drive < MAX_FLOPPIES) + { + m_present_drive = selected_drive; - // FORCE_READY = 1 : assert DRIVE READY on FDC (diagnostic override; USED BY BIOS!) bool force_ready = ((data & 4) == 0) ? true : false; - m_fdc->set_force_ready(force_ready); - } + m_fdc->set_force_ready(force_ready); // 1 : assert DRIVE READY on FDC (diagnostic override) - int enable_start = 0; - int disable_start = 2; // set defaults + if (selected_drive < 2) + { data |= 8; + enable_start = 0; + disable_start = 2; + } + else + { + data |= 16; - bool motor_on = false; - if (selected_drive < 2) - { - motor_on = true; - data |= 8; - } + enable_start = 2; + disable_start = 4; + } - if (selected_drive > 1) - { - motor_on = true; - data |= 16; - - enable_start = 2; - disable_start = 4; - } - - if (motor_on) - { // RX-50 has head A and head B (1 for each of the 2 disk slots in a RX-50). // Assume the other one is switched off - for (int f_num = 0; f_num < MAX_FLOPPIES; f_num++) { - floppy_connector *con = machine().device(names[f_num]); - floppy_image_device *tmp_floppy = con->get_device(); + floppy_connector *con = machine().device(names[f_num]); + floppy_image_device *tmp_floppy = con->get_device(); - tmp_floppy->mon_w(ASSERT_LINE); - if ((f_num >= enable_start) && (f_num < disable_start)) - tmp_floppy->mon_w(CLEAR_LINE); // enable + tmp_floppy->mon_w(ASSERT_LINE); + if ((f_num >= enable_start) && (f_num < disable_start)) + tmp_floppy->mon_w(CLEAR_LINE); // enable } } data = (data & (255 - 3)); // invalid drive = DRIVE 0 ?! - if (m_unit == INVALID_DRIVE) + if (m_present_drive == INVALID_DRIVE) printf("\n**** INVALID DRIVE ****"); else - data = data | m_unit; + data = data | m_present_drive; m_z80_diskcontrol = data; } @@ -2528,8 +2515,9 @@ IRQ_CALLBACK_MEMBER(rainbow_state::irq_callback) if (i == IRQ_8088_VBL) // If VBL IRQ acknowledged... m_crtc->MHFU(MHFU_RESET); // ...reset counter (also: DC012_W) - if (i == IRQ_COMM_PTR_INTR_L) - m_mpsc->m1_r(); // serial interrupt acknowledge +// Edstrom: "The call to m1_r() on line 2571 is not needed as the 7201 does not have an M1 input, instead it expects to get a software iack." +// if (i == IRQ_COMM_PTR_INTR_L) +// m_mpsc->m1_r(); // serial interrupt acknowledge intnum = vectors[i] | m_irq_high; break; @@ -2771,8 +2759,9 @@ WRITE8_MEMBER(rainbow_state::diagnostic_w) // 8088 (port 0A WRITTEN). Fig.4-28 + // Install 8088 read / write handler once loopback test is over if ( !(data & 32) && (m_diagnostic & 32) ) { - io.install_readwrite_handler(0x40, 0x43, READ8_DEVICE_DELEGATE(m_mpsc, upd7201_device,cd_ba_r), WRITE8_DEVICE_DELEGATE(m_mpsc, upd7201_device, cd_ba_w) ); + io.install_readwrite_handler(0x40, 0x43, READ8_DEVICE_DELEGATE(m_mpsc, upd7201_new_device,cd_ba_r), WRITE8_DEVICE_DELEGATE(m_mpsc, upd7201_new_device, cd_ba_w) ); printf("\n **** COMM HANDLER INSTALLED **** "); + //popmessage("Autoboot from drive %c", m_p_nvram[0xab] ? (64 + m_p_nvram[0xab]) : 0x3F ); } // BIT 6: Transfer data from volatile memory to NVM (PROGRAM: 1 => 0 BIT 6) @@ -2818,26 +2807,12 @@ WRITE_LINE_MEMBER(rainbow_state::write_keyboard_clock) m_kbd8251->write_rxc(state); } -TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::motor_tick) +TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::hd_motor_tick) { if (m_POWER_GOOD) m_crtc->MHFU(MHFU_COUNT); // // Increment IF ENABLED and POWER_GOOD, return count m_hdc_index_latch = true; // HDC drive index signal (not working ?) - - if (MOTOR_DISABLE_counter) - MOTOR_DISABLE_counter--; - - if (MOTOR_DISABLE_counter < 2) - { - output().set_value("driveled0", 0); // DRIVE 0 (A) - output().set_value("driveled1", 0); // DRIVE 1 (B) - output().set_value("driveled2", 0); // DRIVE 2 (C) - output().set_value("driveled3", 0); // DRIVE 3 (D) - - output().set_value("led1", 1); // 1 = OFF (One of the CPU LEDs as DRIVE LED) - output().set_value("led2", 1); // 1 = OFF (One of the CPU LEDs as DRIVE LED) - } } // on 100-B, DTR from the keyboard 8051 controls bit 7 of IRQ vectors @@ -3026,12 +3001,11 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w) if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_COLOR_MAP ) // 0x20 { - m_color_map_changed = true; - m_GDC_COLOR_MAP[m_GDC_color_map_index++] = ~data; // tilde data verified by DIAGNOSTIC! if(m_GDC_color_map_index == 32) { m_GDC_color_map_index = 0; // 0...31 (CPU accesses 32 bytes + m_color_map_changed = true; printf("\n * COLOR MAP FULLY LOADED *"); for(int zi =0; zi <16; zi++) @@ -3074,7 +3048,6 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w) if(m_GDC_INDIRECT_REGISTER & GDC_SELECT_PATTERN) { // NOTE : Pattern Multiplier MUST BE LOADED before (!) - OPTION_RESET_PATTERNS m_vpat = data; break; } @@ -3183,7 +3156,8 @@ WRITE8_MEMBER(rainbow_state::GDC_EXTRA_REGISTER_w) case 5: // 55h Write Mask HIGH m_GDC_WRITE_MASK = ( m_GDC_WRITE_MASK & 0xFF00 ) | BITSWAP8(data, 0, 1, 2, 3, 4, 5, 6, 7); break; - } + } // switch + } @@ -3263,6 +3237,8 @@ MCFG_SCREEN_UPDATE_DEVICE("upd7220", upd7220_device, screen_update) MCFG_FD1793_ADD(FD1793_TAG, XTAL_24_0734MHz / 24) // no separate 1 Mhz quartz MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":0", rainbow_floppies, "525qd0", rainbow_state::floppy_formats) MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":1", rainbow_floppies, "525qd1", rainbow_state::floppy_formats) +//MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":2", rainbow_floppies, "525qd2", rainbow_state::floppy_formats) +//MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":3", rainbow_floppies, "525qd3", rainbow_state::floppy_formats) MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":2", rainbow_floppies, "525dd", rainbow_state::floppy_formats) MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":3", rainbow_floppies, "35dd", rainbow_state::floppy_formats) MCFG_SOFTWARE_LIST_ADD("flop_list", "rainbow") @@ -3312,28 +3288,30 @@ MCFG_COM8116_FR_HANDLER(WRITELINE(rainbow_state, com8116_b_fr_w)) MCFG_COM8116_FT_HANDLER(WRITELINE(rainbow_state, com8116_b_ft_w)) MCFG_UPD7201_ADD("upd7201", XTAL_2_5MHz, 0, 0, 0, 0) // 2.5 Mhz from schematics -MCFG_Z80DART_OUT_INT_CB(WRITELINE(rainbow_state, mpsc_irq)) +MCFG_Z80SIO_OUT_INT_CB(WRITELINE(rainbow_state, mpsc_irq)) -MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_txd)) -MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_dtr)) -MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_rts)) +MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_txd)) +MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_dtr)) +MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE("rs232_a", rs232_port_device, write_rts)) -MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_txd)) -MCFG_Z80DART_OUT_DTRB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_dtr)) -MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_rts)) +MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_txd)) +MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_dtr)) +MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232_b", rs232_port_device, write_rts)) MCFG_RS232_PORT_ADD("rs232_a", default_rs232_devices, nullptr) -MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, rxa_w)) -MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_device, ctsa_w)) -MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, dcda_w)) +MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, rxa_w)) +MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, ctsa_w)) +MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, dcda_w)) MCFG_RS232_PORT_ADD("rs232_b", default_rs232_devices, nullptr) -MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, rxb_w)) -MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_device, ctsb_w)) -MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_device, dcdb_w)) +MCFG_RS232_RXD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, rxb_w)) +MCFG_RS232_CTS_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, ctsb_w)) +MCFG_RS232_DCD_HANDLER(DEVWRITELINE("upd7201", upd7201_new_device, dcdb_w)) MCFG_DEVICE_MODIFY("rs232_a") -MCFG_SLOT_DEFAULT_OPTION("null_modem") +MCFG_SLOT_OPTION_ADD("microsoft_mouse", MSFT_SERIAL_MOUSE) +MCFG_SLOT_OPTION_ADD("mouse_systems_mouse", MSYSTEM_SERIAL_MOUSE) +MCFG_SLOT_DEFAULT_OPTION("microsoft_mouse") MCFG_DEVICE_MODIFY("rs232_b") MCFG_SLOT_DEFAULT_OPTION("printer") @@ -3349,7 +3327,7 @@ MCFG_LK201_TX_HANDLER(DEVWRITELINE("kbdser", i8251_device, write_rxd)) MCFG_DEVICE_ADD("keyboard_clock", CLOCK, 4800 * 16) // 8251 is set to /16 on the clock input MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(rainbow_state, write_keyboard_clock)) -MCFG_TIMER_DRIVER_ADD_PERIODIC("motor", rainbow_state, motor_tick, attotime::from_hz(60)) +MCFG_TIMER_DRIVER_ADD_PERIODIC("motor", rainbow_state, hd_motor_tick, attotime::from_hz(60)) MCFG_NVRAM_ADD_0FILL("nvram") MACHINE_CONFIG_END @@ -3462,3 +3440,4 @@ ROM_END COMP(1982, rainbow100a, rainbow, 0, rainbow, rainbow100b_in, rainbow_state, 0, "Digital Equipment Corporation", "Rainbow 100-A", MACHINE_IS_SKELETON) COMP(1983, rainbow, 0, 0, rainbow, rainbow100b_in, rainbow_state, 0, "Digital Equipment Corporation", "Rainbow 100-B", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_COLORS) COMP(1985, rainbow190, rainbow, 0, rainbow, rainbow100b_in, rainbow_state, 0, "Digital Equipment Corporation", "Rainbow 190-B", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_COLORS) +