From 17d7b519a657562d5b6806ab9e5a2f00eaecbda2 Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Fri, 20 Dec 2013 03:30:14 +0000 Subject: (MESS) Rainbow 100 updates: [Bavarese] - added DEC-190-B model - preliminary floppy (TD0 / IMG) - corrected LK201 keyboard matrix (C12, Do + cursor keys) - MHFU changes; character display speedups - nicer bezel with 'C' + 'D' drive leds --- src/emu/imagedev/flopdrv.h | 1 + src/mess/drivers/rainbow.c | 615 +++++++++++++++++++++++++++++++++---------- src/mess/layout/rainbow.lay | 141 ++++++---- src/mess/machine/dec_lk201.c | 54 ++-- src/mess/machine/dec_lk201.h | 14 + src/mess/mess.lst | 1 + src/mess/video/vtvideo.c | 97 ++++--- src/mess/video/vtvideo.h | 8 +- 8 files changed, 677 insertions(+), 254 deletions(-) (limited to 'src') diff --git a/src/emu/imagedev/flopdrv.h b/src/emu/imagedev/flopdrv.h index 0f7255922e2..c59e4d282a2 100644 --- a/src/emu/imagedev/flopdrv.h +++ b/src/emu/imagedev/flopdrv.h @@ -34,6 +34,7 @@ #define FLOPPY_STANDARD_5_25_SSSD { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_5_25_DSSD { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_SD } #define FLOPPY_STANDARD_5_25_SSDD_40 { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_DD } +#define FLOPPY_STANDARD_5_25_SSDD_80 { FLOPPY_DRIVE_5_25_INCH, 1, 83, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_DSDD_40 { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_SSDD { FLOPPY_DRIVE_5_25_INCH, 1, 83, FLOPPY_DRIVE_DD } #define FLOPPY_STANDARD_5_25_DSDD { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_DD } diff --git a/src/mess/drivers/rainbow.c b/src/mess/drivers/rainbow.c index 92d73f915f9..01dfce2c157 100644 --- a/src/mess/drivers/rainbow.c +++ b/src/mess/drivers/rainbow.c @@ -1,30 +1,36 @@ -/*************************************************************************** - +/*************************************************************************************************** DEC Rainbow 100 - Driver-in-progress by R. Belmont and Miodrag Milanovic with additions by Karl-Ludwig Deisenhofer. + Driver-in-progress by R. Belmont and Miodrag Milanovic. + Portions (2013) by Karl-Ludwig Deisenhofer (VT video, floppy, preliminary keyboard, DIP switches). - STATE AS OF NOVEMBER 2013 + STATE AS OF DECEMBER 2013 -------------------------- - - FATAL: keyboard emulation incomplete (inhibits the system from booting with ERROR 50 on cold or ERROR 13 on warm boot). - - NOT WORKING: serial (ERROR 60). + - FLOPPY TIMING: 'wd17xx_complete_command' * must * be hard wired to about 13 usecs. + Line 1063 in 'wd17xx.c' has to be changed (until legacy code here is removed): + - w->timer_cmd->adjust(attotime::from_usec(usecs)); + + w->timer_cmd->adjust(attotime::from_usec(13)); + + - WORKAROUND AVAILABLE: keyboard emulation incomplete (inhibits the system from booting with ERROR 50 on cold or ERROR 13 on warm boot). + - NOT WORKING: serial (ERROR 60). - NOT WORKING: printer interface (ERROR 40). Like error 60 not mission-critical. - - NON-CRITICAL: watchdog logic (triggered after 108 ms without interrupts) still not exactly by the book. + - NON-CRITICAL: watchdog logic (triggered after 108 ms without interrupts on original machine) still does not work as intended. Timer is reset by TWO sources: the VERT INT L from the DC012, or the MHFU ENB L from the enable flip-flop. The MHFU gets active if the 8088 has not acknowledged a video processor interrupt within approx. 108 milliseconds. BIOS assumes a power-up reset if MHFU detection is disabled - and assumes a MHFU reset if MHFU detection is ENABLED. - Therefore a 'warm boot' within MESS (F3) causes ERROR 16. + + As there is no reset switch, only a limited software reset exists on a real DEC-100 (CTRL-SETUP within SETUP). - - SHOULD BE IMPLEMENTED AS SLOT DEVICES (for now, DIP settings affect 'system_parameter_r' only and are disabled): + - TO BE IMPLEMENTED AS SLOT DEVICES (for now, DIP settings affect 'system_parameter_r' only and are disabled): * Color graphics option (uses NEC upd7220 GDC) * Extended communication option (same as BUNDLE_OPTION ?) - OTHER UPGRADES (NEC_V20 should be easy, the TURBOW is harder to come by) * Suitable Solutions TURBOW286: 12 Mhz, 68-pin, low power AMD N80L286-12 and WAYLAND/EDSUN EL286-88-10-B ( 80286 to 8088 Processor Signal Converter ) - plus DC 7174 or DT 7174 (barely readable). Add-on card, replaces main 8088 cpu (via ribbon cable). Changed BOOT ROM labeled 'TBSS1.3 - 3ED4'. + plus DC 7174 or DT 7174 (barely readable). Add-on card, replaces main 8088 cpu (via ribbon cable). Altered BOOT ROM labeled 'TBSS1.3 - 3ED4'. * NEC_V20 (requires modded BOOT ROM because of - at least 2 - hard coded timing loops): 100A: 100B/100+: 100B+ ALTERNATE RECOMMENDATION (fixes RAM size auto-detection problems when V20 is in place. @@ -154,28 +160,25 @@ W16 pulls J2 printer port pin 1 to GND when set (chassis to logical GND). W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND). ****************************************************************************/ -/* -HARD DISC SIZES AND LIMITS - HARDWARE: the Rainbow winchester controller has a built-in limit of 8 heads and 1024 cylinders (67 MB). Standard geometry is 4 surfaces. - - SOFTWARE: the original DEC boot loader (and FDISK from DOS 3.10) initially allowed a maximum hard disc size of 20 MB. - - DOS 3 has a 1024 cylinder limit (32 MB). - - the custom boot loader that comes with 'WUTIL 3.2' stretches limits to 117 MB and 8 surfaces. -*/ - +// Workarounds DO NOT APPLY to the 190-B ROM. Only enable when compiling the 'rainbow' driver - +//#define FORCE_RAINBOW_100_LOGO +#define KBD_DELAY 875 // (debounce delay). Recommended: 875. #include "emu.h" #include "cpu/i86/i86.h" #include "cpu/z80/z80.h" #include "video/vtvideo.h" + #include "machine/wd17xx.h" #include "imagedev/flopdrv.h" +#include "formats/basicdsk.h" + #include "machine/i8251.h" #include "machine/dec_lk201.h" #include "sound/beep.h" #include "machine/nvram.h" -#include "rainbow.lh" // BEZEL - LAYOUT with LEDs for diag 1-7, keyboard 8-11 and floppy 20-21 +#include "rainbow.lh" // BEZEL - LAYOUT with LEDs for diag 1-7, keyboard 8-11 and floppy 20-23 class rainbow_state : public driver_device { @@ -248,6 +251,7 @@ public: DECLARE_READ8_MEMBER(floating_bus_r); DECLARE_WRITE8_MEMBER(floating_bus_w); + DECLARE_READ8_MEMBER(hd_status_68_r); // EMULATOR TRAP TO INTERCEPT KEYBOARD cmd in AH and PARAMETER in AL (port 90 = AL / port 91 = AH) // TODO: beeper and led handling should better be handled by LK201 code. DECLARE_WRITE8_MEMBER(PORT90_W); @@ -261,7 +265,11 @@ public: DECLARE_WRITE8_MEMBER(z80_diskdiag_read_w); DECLARE_WRITE8_MEMBER(z80_diskdiag_write_w); - DECLARE_WRITE8_MEMBER(z80_diskcontrol_write_w); + DECLARE_READ8_MEMBER(z80_generalstat_r); + + DECLARE_READ8_MEMBER(z80_diskstatus_r); + DECLARE_WRITE8_MEMBER(z80_diskcontrol_w); + DECLARE_READ8_MEMBER(system_parameter_r); DECLARE_READ_LINE_MEMBER(dsr_r); @@ -273,22 +281,29 @@ public: bool m_SCREEN_BLANK; + int INT88, INTZ80; + bool m_zflip; // Z80 alternate memory map with A15 inverted bool m_z80_halted; - bool m_kbd_tx_ready, m_kbd_rx_ready; + int m_z80_diskcontrol; // retains values needed for status register + bool m_kbd_tx_ready, m_kbd_rx_ready; int m_KBD; - int m_beep_counter; - int MHFU_counter; + int m_beep_counter; + int MOTOR_DISABLE_counter; + int COLD_BOOT; private: UINT8 m_z80_private[0x800]; // Z80 private 2K UINT8 m_z80_mailbox, m_8088_mailbox; void update_kbd_irq(); virtual void machine_reset(); - void MHFU_reset(); + + int m_unit; + device_t *m_image[4]; + public: UINT32 screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(vblank_irq); @@ -296,8 +311,16 @@ public: required_device m_maincpu; }; + void rainbow_state::machine_start() { + m_image[0] = subdevice(FLOPPY_0); + m_image[1] = subdevice(FLOPPY_1); + m_image[2] = subdevice(FLOPPY_2); + m_image[3] = subdevice(FLOPPY_3); + + COLD_BOOT = 1; + m_SCREEN_BLANK = false; save_item(NAME(m_z80_private)); @@ -309,31 +332,41 @@ void rainbow_state::machine_start() UINT8 *rom = memregion("maincpu")->base(); + +#ifdef FORCE_RAINBOW_100_LOGO + rom[0xf4174]=0xeb; // jmps RAINBOW100_LOGO__loc_33D + rom[0xf4175]=0x08; + + rom[0xf4000 + 0x364a]= 0x0a; + rom[0xf4384]=0xeb; // JMPS => BOOT80 +#endif + // Enables PORT90_W + PORT91_W via BIOS call (offset +$21 in HIGH ROM) // F8 / FC ROM REGION (CHECK + PATCH) if(rom[0xfc000 + 0x0022] == 0x22 && rom[0xfc000 + 0x0023] == 0x28) { rom[0xf4303]=0x00; // Disable CRC CHECK (F0 / F4 ROM) - rom[0xfc000 + 0x0022] =0xe2; // jmp to offset $3906 - rom[0xfc000 + 0x0023] =0x38; + rom[0xfc000 + 0x0022] =0xfe; // jmp to offset $1922 + rom[0xfc000 + 0x0023] =0x18; - rom[0xfc000 + 0x3906] =0xe6; // out 90,al - rom[0xfc000 + 0x3907] =0x90; + rom[0xfc000 + 0x1922] =0xe6; // out 90,al + rom[0xfc000 + 0x1923] =0x90; - rom[0xfc000 + 0x3908] =0x86; // xchg al,ah - rom[0xfc000 + 0x3909] =0xc4; + rom[0xfc000 + 0x1924] =0x86; // xchg al,ah + rom[0xfc000 + 0x1925] =0xc4; - rom[0xfc000 + 0x390a] =0xe6; // out 91,al - rom[0xfc000 + 0x390b] =0x91; + rom[0xfc000 + 0x1926] =0xe6; // out 91,al + rom[0xfc000 + 0x1927] =0x91; - rom[0xfc000 + 0x390c] =0x86; // xchg al,ah - rom[0xfc000 + 0x390d] =0xc4; + rom[0xfc000 + 0x1928] =0x86; // xchg al,ah + rom[0xfc000 + 0x1929] =0xc4; - rom[0xfc000 + 0x390e] =0xe9; // jmp (original jump offset $2846) - rom[0xfc000 + 0x390f] =0x35; - rom[0xfc000 + 0x3910] =0xef; + rom[0xfc000 + 0x192a] =0xe9; // jmp (original jump offset $2846) e9 + 19 0f + rom[0xfc000 + 0x192b] =0x19; + rom[0xfc000 + 0x192c] =0x0f; } + } static ADDRESS_MAP_START( rainbow8088_map, AS_PROGRAM, 8, rainbow_state) @@ -374,6 +407,8 @@ static ADDRESS_MAP_START( rainbow8088_io , AS_IO, 8, rainbow_state) // 0x04 Video processor DC011 AM_RANGE (0x04, 0x04) AM_DEVWRITE("vt100_video", rainbow_video_device, dc011_w) + // TODO: unmapped [06] : Communication bit rates (see page 21 of PC 100 SPEC) + AM_RANGE (0x08, 0x08) AM_READ(system_parameter_r) AM_RANGE (0x0a, 0x0a) AM_READWRITE(diagnostic_r, diagnostic_w) @@ -381,9 +416,37 @@ static ADDRESS_MAP_START( rainbow8088_io , AS_IO, 8, rainbow_state) // 0x0C Video processor DC012 AM_RANGE (0x0c, 0x0c) AM_DEVWRITE("vt100_video", rainbow_video_device, dc012_w) + // TODO: unmapped [0e] : PRINTER BIT RATE REGISTER (WO) + AM_RANGE(0x10, 0x10) AM_DEVREADWRITE("kbdser", i8251_device, data_r, data_w) AM_RANGE(0x11, 0x11) AM_DEVREADWRITE("kbdser", i8251_device, status_r, control_w) + // UNMAPPED: + // 0x20 - 0x2f ***** EXTENDED COMM. OPTION (option select 1)- for example: + // 0x27 (RESET EXTENDED COMM OPTION) - OUT 27 @ offset 1EA7 + + // 0x40 COMMUNICATIONS DATA REGISTER (MPSC) + // 0x41 PRINTER DATA REGISTER (MPSC) + // 0x42 COMMUNICATIONS CONTROL / STATUS REGISTER (MPSC) + // 0x43 PRINTER CONTROL / STATUS REGISTER (MPSC) + + // 0x50 - 0xf ***** OPTIONAL COLOR GRAPHICS - for example: + // 0x50 (RESET_GRAPH. OPTION) - OUT 50 @ offsets F5EB5 + F5EB9 + + // =========================================================== + // TODO: hard disc emulation! + // ------ Rainbow uses 'WD 1010 AL' (Western Digital 1983) + // Register compatible to WD2010 (present in MESS) + // R/W REGISTERS 60 - 68 (?) + // =========================================================== + // HARD DISC SIZES AND LIMITS + // HARDWARE: + // Controller has a built-in limit of 8 heads / 1024 cylinders (67 MB). Standard geometry is 4 surfaces. + // SOFTWARE: the DEC boot loader (and FDISK from DOS 3.10) initially allowed a maximum hard disc size of 20 MB. + // - DOS 3 has a 1024 cylinder limit (32 MB). + // - the custom boot loader that comes with 'WUTIL 3.2' allows 117 MB and 8 surfaces. + AM_RANGE (0x68, 0x68) AM_READ(hd_status_68_r) + AM_RANGE (0x90, 0x90) AM_WRITE(PORT90_W) AM_RANGE (0x91, 0x91) AM_WRITE(PORT91_W) ADDRESS_MAP_END @@ -397,9 +460,9 @@ static ADDRESS_MAP_START( rainbowz80_io, AS_IO, 8, rainbow_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x00) AM_READWRITE(z80_latch_r, z80_latch_w) - AM_RANGE(0x20, 0x20) AM_WRITE(z80_diskdiag_read_w) - AM_RANGE(0x21, 0x21) AM_WRITE(z80_diskdiag_write_w) - AM_RANGE(0x40, 0x40) AM_WRITE(z80_diskcontrol_write_w) + AM_RANGE(0x20, 0x20) AM_READWRITE(z80_generalstat_r, z80_diskdiag_read_w) // read to port 0x20 used by MS-DOS 2.x diskette loader. + AM_RANGE(0x21, 0x21) AM_READWRITE(z80_generalstat_r, z80_diskdiag_write_w) + AM_RANGE(0x40, 0x40) AM_READWRITE(z80_diskstatus_r, z80_diskcontrol_w) AM_RANGE(0x60, 0x60) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_status_r, wd17xx_command_w) AM_RANGE(0x61, 0x61) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_track_r, wd17xx_track_w) AM_RANGE(0x62, 0x62) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_sector_r, wd17xx_sector_w) @@ -407,28 +470,16 @@ static ADDRESS_MAP_START( rainbowz80_io, AS_IO, 8, rainbow_state) ADDRESS_MAP_END /* Input ports */ -static INPUT_PORTS_START( rainbow ) + +/* KEYBOARD (preliminary - transfer to DEC_LK201.xx as soon as possible) */ +static INPUT_PORTS_START( rainbow100b_in ) +/* DIP switches */ PORT_START("MONITOR TYPE") PORT_DIPNAME( 0x03, 0x03, "MONOCHROME MONITOR") PORT_DIPSETTING( 0x01, "PAPER WHITE" ) PORT_DIPSETTING( 0x02, "GREEN" ) PORT_DIPSETTING( 0x03, "AMBER" ) - PORT_START("FLOPPY CONTROLLER") - PORT_DIPNAME( 0x02, 0x02, "FLOPPY CONTROLLER") PORT_TOGGLE - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - - PORT_START("GRAPHICS OPTION") - PORT_DIPNAME( 0x00, 0x00, "GRAPHICS OPTION") PORT_TOGGLE - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - - PORT_START("BUNDLE OPTION") - PORT_DIPNAME( 0x00, 0x00, "BUNDLE OPTION") PORT_TOGGLE - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_START("MEMORY PRESENT") PORT_DIPNAME( 0xF000, 0x2000, "MEMORY PRESENT") PORT_DIPSETTING( 0x2000, "128 K (BOARD DEFAULT)" ) // NOTE: 0x2000 hard coded in 'system_parameter_r' @@ -445,7 +496,17 @@ static INPUT_PORTS_START( rainbow ) PORT_DIPSETTING( 0xD000, "832 K (MEMORY OPTION)" ) PORT_DIPSETTING( 0xE000, "896 K (MEMORY OPTION)" ) - PORT_START("W13") + PORT_START("GRAPHICS OPTION") + PORT_DIPNAME( 0x00, 0x00, "GRAPHICS OPTION") PORT_TOGGLE + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x04, DEF_STR( On ) ) + + PORT_START("BUNDLE OPTION") + PORT_DIPNAME( 0x00, 0x00, "BUNDLE OPTION") PORT_TOGGLE + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x01, DEF_STR( On ) ) + + PORT_START("W13") // W13 - W18 affect 'system_parameter_r' PORT_DIPNAME( 0x02, 0x02, "W13 (FACTORY TEST A, LEAVE OFF)") PORT_TOGGLE PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) @@ -462,20 +523,41 @@ static INPUT_PORTS_START( rainbow ) PORT_DIPNAME( 0x01, 0x00, "W18 (FACTORY TEST D, LEAVE OFF) (8251A: DSR)") PORT_TOGGLE PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x01, DEF_STR( On ) ) -INPUT_PORTS_END + // J17 jumper on FDC controller board shifts drive select (experimental) - + PORT_START("FLOPPY CONTROLLER") + PORT_DIPNAME( 0x02, 0x00, "J17 DRIVE SELECT (A => C and B => D)") PORT_TOGGLE + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x02, DEF_STR( On ) ) +INPUT_PORTS_END -void rainbow_state::MHFU_reset() -{ - MHFU_counter = 530; // 528 = 110ms -} - +// 800K native format (80 * 10). Also reads VT-180 disks and PC-DOS 360 k disks +// ( both: 512 byte sectors, single sided, 9 sectors per track, 40 tracks ) +static LEGACY_FLOPPY_OPTIONS_START( dec100_floppy ) + LEGACY_FLOPPY_OPTION( dec100_floppy, "td0", "Teledisk floppy disk image", td0_dsk_identify, td0_dsk_construct, td0_dsk_destruct, NULL ) + LEGACY_FLOPPY_OPTION( dec100_floppy, "img", "DEC Rainbow 100", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS(40/[80]) + SECTORS(9/[10]) + SECTOR_LENGTH([512]) + INTERLEAVE([0]) + FIRST_SECTOR_ID([1]) + ) +LEGACY_FLOPPY_OPTIONS_END + void rainbow_state::machine_reset() { - MHFU_reset(); + if (COLD_BOOT == 1) + { + COLD_BOOT = 2; + m_crtc->MHFU(-100); // reset MHFU counter + } m_z80->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + INT88 = false; + INTZ80 = false; + m_zflip = true; m_z80_halted = true; m_kbd_tx_ready = m_kbd_rx_ready = false; @@ -500,12 +582,17 @@ void rainbow_state::machine_reset() output_set_value("led10", 1); output_set_value("led11", 1); - output_set_value("led20", 1); // DRIVE 0 (A) - output_set_value("led21", 1); // DRIVE 1 (B) + MOTOR_DISABLE_counter = 2; // soon resets drv.LEDs + m_unit = 0; + } UINT32 rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { + // TEST-DEBUG: no screen updates during diskette operations! + if (MOTOR_DISABLE_counter) + return 0; + m_crtc->palette_select( m_inp9->read() ); if ( m_SCREEN_BLANK ) @@ -516,31 +603,36 @@ UINT32 rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 } // It is no longer possible to key in the RAM size on the 100-B. -// The DEC-100-B boot ROM probes until a 'flaky' area is found (around F400:xxxx). +// The DEC-100-B boot ROM probes until a 'flaky' area is found (around F400:0E04). // Unexpected low RAM sizes are an indication of option RAM (at worst: 128 K on board) failure. // While motherboard errors often render the system unbootable, bad option RAM (> 128 K) -// can be narrowed down with a diagnostic disk and codes from the 'Pocket Service Guide' +// can be narrowed down with the Diagnostic Disk and codes from the 'Pocket Service Guide' // EK-PC100-PS-002 (APPENDIX B.2.2); pc100ps2.pdf - -// Simulate floating bus for initial RAM detection: +// ================================================================ +// - Simulate floating bus for initial RAM detection - +// FIXME: code valid ONLY within ROM section F4Exxx. +// +// NOTE: MS-DOS 2.x unfortunately probes RAM in a similar way. +// => SET OPTION RAM to 896 K for unknown applications (and DOS) <= +// ================================================================ READ8_MEMBER(rainbow_state::floating_bus_r) { - if ( m_maincpu->state_int(I8086_CS) != 0xF400) - return space.read_byte(offset); + int pc = space.device().safe_pc(); - if ( m_maincpu->state_int(I8086_DS) < m_inp8->read() ) - { - return space.read_byte(offset); - } else + if ( ((pc & 0xFFF00) == 0xF4E00) && + ( m_maincpu->state_int(I8086_DS) >= m_inp8->read() ) + ) { return (offset>>16) + 2; - } + } + else + return space.read_byte(offset); } WRITE8_MEMBER(rainbow_state::floating_bus_w) { - space.write_byte(offset,data); + space.write_byte(offset,data); } @@ -600,6 +692,17 @@ WRITE8_MEMBER(rainbow_state::share_z80_w) } } +// Until a full-blown hard-disc emulation evolves, deliver an error message: +READ8_MEMBER(rainbow_state::hd_status_68_r) +{ + // Top 3 bits = status / error code + // SEE -> W_INCHESTER__loc_80E + + // return 0xa0; // A0 : OK, DRIVE IS READY (!) + + return 0xe0; // => 21 DRIVE NOT READY (BIOS; when W is pressed on boot screen) +} + READ8_MEMBER(rainbow_state::system_parameter_r) { /* Info about option boards is in bits 0 - 3: @@ -610,21 +713,33 @@ READ8_MEMBER(rainbow_state::system_parameter_r) ( 1 means NOT present ) */ // Hard coded value 0x2000 - see DIP switch setup! - return 0x0f - m_inp5->read() - m_inp6->read() - m_inp7->read() - ( - (m_inp8->read() > 0x2000) ? 8 : 0 - ); + return 0x0f - m_inp5->read() + - 0 // floppy is hard coded in emulator. + - m_inp7->read() + - (m_inp8->read() > 0x2000) ? 8 : 0; } READ8_MEMBER(rainbow_state::comm_control_r) { -/* ---> What the specs says on how MHFU detection is disabled: - // 1. by first disabling interrupts with CLI - // 2. by writing 0x00 to port 0x10C (handled by 'dc012_w' in vtvideo) - // (3.) MHFU is re-enabled by writing to 0x0c (or automatically after STI - when under BIOS control ?) -*/ - return ( ( m_crtc->dc012_MHFU() << 5) // shift status of DC012 - MHFU flag to bit pos.5 - ); +/* [02] COMMUNICATIONS STATUS REGISTER - PAGE 154 (**** READ **** ) + Used to read status of SERIAL port, IRQ line of each CPU, and MHFU logic enable signal. + +// What the specs says on how MHFU detection is disabled: +// 1. by first disabling interrupts with CLI +// 2. by writing 0x00 to port 0x10C (handled by 'dc012_w' in vtvideo) +// (3.) MHFU is re-enabled by writing to 0x0c (or automatically after STI - when under BIOS control ?) +*/ + // During boot phase 2, do not consider MHFU ENABLE. Prevents ERROR 16. + int data; + if (COLD_BOOT == 2) + data = 0; + else + data = m_crtc->MHFU(1); + + return ( ( (data > 0) ? 0x00 : 0x20) |// (L): status of MHFU flag => bit pos.5 + ( (INT88) ? 0x00 : 0x40 ) | // (L) + ( (INTZ80) ? 0x00 : 0x80 ) // (L) + ); } WRITE8_MEMBER(rainbow_state::comm_control_w) @@ -651,42 +766,55 @@ WRITE8_MEMBER(rainbow_state::PORT90_W) m_KBD = 0; // reset previous command. - if (data == 0xfd) { // Powerup (beep) - m_beep->set_state(1); - m_beep_counter=600; // BELL = 125 ms + if(MOTOR_DISABLE_counter == 0) + { + + if (data == LK_CMD_POWER_UP) { // Powerup (beep) + //m_beep->set_state(1); + //m_beep_counter=600; // BELL = 125 ms } - if (data == 0xa7) { - m_beep->set_state(1); + if (data == LK_CMD_BELL) { + m_KBD = data; + m_beep->set_state(1); m_beep_counter=600; // BELL = 125 ms } - if (data == 0x9f) { // emit a keyclick (2ms) + if (data == LK_CMD_SOUND_CLK) { // emit a keyclick (2ms) + m_KBD = data; m_beep->set_state(1); m_beep_counter=25; // longer than calculated ( 9,6 ) } - if (data == 0x13) { // light LEDs - - m_KBD = 0x13; + if (data == LK_CMD_ENB_BELL) { // enable the bell - PARAMETER: VOLUME! + m_KBD = data; } - if (data == 0x11) { // switch off LEDs - - m_KBD = 0x11; + + if (data == LK_CMD_ENB_KEYCLK) { // enable the keyclick- PARAMETER: VOLUME! + m_KBD = data; + } + + if (data == LK_CMD_LEDS_ON ) { // light LEDs - + m_KBD = data; } + if (data == LK_CMD_LEDS_OFF) { // switch off LEDs - + m_KBD = data; + } + + } // prevent beeps during disk load operations } WRITE8_MEMBER(rainbow_state::PORT91_W) { - //printf("KBD PARAM %02x to AH (91) \n", data); - // 4 leds, represented in the low 4 bits of a byte - if (m_KBD == 0x13) { // light LEDs - + if (m_KBD == LK_CMD_LEDS_ON) { // light LEDs - if (data & 1) { output_set_value("led8", 0); } // KEYBOARD : "Wait" LED if (data & 2) { output_set_value("led9", 0); } // KEYBOARD : "Compose" LED if (data & 4) { output_set_value("led10", 0); } // KEYBOARD : "Lock" LED if (data & 8) { output_set_value("led11", 0); } // KEYBOARD : "Hold" LED m_KBD = 0; // reset previous command. } - if (m_KBD == 0x11) { // switch off LEDs - + if (m_KBD == LK_CMD_LEDS_OFF) { // switch off LEDs - if (data & 1) { output_set_value("led8", 1); } // KEYBOARD : "Wait" LED if (data & 2) { output_set_value("led9", 1); } // KEYBOARD : "Compose" LED if (data & 4) { output_set_value("led10", 1); } // KEYBOARD : "Lock" LED @@ -694,45 +822,113 @@ WRITE8_MEMBER(rainbow_state::PORT91_W) m_KBD = 0; // reset previous command. } - if (m_KBD == 0x1b) { /* enable the keyclick */ - /* max volume is 0, lowest is 0x7 */ + // NVRAM offet $A8 : BELL VOLUME (=> ENABLE BELL 0x23) + if ( (m_KBD == LK_CMD_BELL) || (m_KBD == LK_CMD_ENB_BELL) ) /* BOTH sound or enable bell have a parameter */ + { /* max volume is 0, lowest is 0x7 */ +// printf("\n%02x BELL CMD has bell volume = %02x\n", m_KBD, 8 - (data & 7)); + m_KBD = 0; // reset previous command. + } + + // NVRAM offet $A9 = KEYCLICK VOLUME (=> ENABLE CLK 0x1b) + // NVRAM offset $8C = KEYCLICK ENABLE / DISABLE (0/1) + if ( ( m_KBD == LK_CMD_ENB_KEYCLK ) || ( m_KBD == LK_CMD_SOUND_CLK ) ) /* BOTH keyclick cmds have a parameter */ + { // max volume is 0, lowest is 0x7 - 87 (BELL VOL:1) and 80 (BELL VOL:8) +// printf("\n%02x CLICK CMD - keyclick volume = %02x\n", m_KBD, 8 - (data & 7)); m_KBD = 0; // reset previous command. } -} +if (m_KBD > 0) + printf("UNHANDLED PARAM FOR MODE: %02x / KBD PARAM %02x to AH (91) \n", m_KBD, data); + +} +// 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); m_i8088->set_input_line(INPUT_LINE_INT0, CLEAR_LINE); + + INT88 = false; // BISLANG: INTZ80 = false; // return m_8088_mailbox; } +// 8088 writes port 0x00. See page 133 (4-34) WRITE8_MEMBER(rainbow_state::i8088_latch_w) { // printf("%02x to Z80 mailbox\n", data); m_z80->set_input_line_and_vector(0, ASSERT_LINE, 0xf7); m_z80_mailbox = data; + + INTZ80 = true; // } +// Z80 reads port 0x00 +// See page 134 (4-35) READ8_MEMBER(rainbow_state::z80_latch_r) { // printf("Read %02x from Z80 mailbox\n", m_z80_mailbox); m_z80->set_input_line(0, CLEAR_LINE); + + INTZ80 = false; // BISLANG: INT88 = false; return m_z80_mailbox; } +// Z80 writes to port 0x00 +// See page 134 (4-35) WRITE8_MEMBER(rainbow_state::z80_latch_w) { -// printf("%02x to 8088 mailbox\n", data); + // printf("%02x to 8088 mailbox\n", data); m_i8088->set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, 0x27); m_8088_mailbox = data; + + INT88 = true; } +// WRITE to 0x20 WRITE8_MEMBER(rainbow_state::z80_diskdiag_read_w) { m_zflip = true; } +// (Z80) : PORT 21H _READ_ +READ8_MEMBER(rainbow_state::z80_generalstat_r) +{ +/* +General / diag.status register Z80 / see page 157 (table 4-18). + +D7 : STEP L : reflects status of STEP signal _FROM FDC_ + (when this 2us output pulse is low, the stepper will move into DIR) +D6 : WRITE GATE L :reflects status of WRITE GATE signal _FROM FDC_ + (asserted low before data can be written on the diskette) +D5 : TR00: reflects status of TRACK 0 signal (= 1) * from the disk drive * +D4 : DIR L: reflects status of DIRECTION signal * FROM FDC * to disk + (when low, the head will step towards the center) +D3 : READY L: reflects status of READY L signal * from the disk drive * + (low active, asserts when disk is inserted and door is closed) +D2 : INT88 L: (bit reads the INT88 bit sent by Z80 to interrupt 8088) +D1 : INTZ80 L: (bit reads the INTZ80 bit sent by 8088 to interrupt Z80) +D0 : ZFLIP L: (read from the diagnostic control register of Z80A) + +NOTES: ALL LOW ACTIVE - EXCEPT TR00 +*/ + // * TRACK 00 * signal for current drive + int tk00 = ( floppy_tk00_r( m_image[m_unit] ) == CLEAR_LINE ) ? 0x20 : 0x00; + + int fdc_ready = floppy_drive_get_flag_state( m_image[m_unit] , FLOPPY_DRIVE_READY); + + int data=( 0x80 | // (STEP L) +// ( (fdc_write_gate) ) | + ( (tk00) ) | +// ( fdc_direction) | + ( (fdc_ready)? 0x00 : 0x08 ) | + ( (INT88) ? 0x00 : 0x04 ) | + ( (INTZ80) ? 0x00 : 0x02 ) | + ( (m_zflip) ? 0x00 : 0x01 ) + ); + + return data; +} + +// (Z80) : PORT 21H * WRITE * WRITE8_MEMBER(rainbow_state::z80_diskdiag_write_w) { /* Z80 LEDs: @@ -747,21 +943,109 @@ WRITE8_MEMBER(rainbow_state::z80_diskdiag_write_w) m_zflip = false; } -WRITE8_MEMBER(rainbow_state::z80_diskcontrol_write_w) +// (Z80) : PORT 40H _READ_ + +// ********************************************************************** +// POLARITY OF _DRQ_ AND _IRQ_ (depends on controller type!) +// ********************************************************************** +READ8_MEMBER(rainbow_state::z80_diskstatus_r) { - //printf("%02x to z80 DISK CONTROL (W)\n", data); +static int last_track; +int track = wd17xx_track_r(m_fdc, space, 0); - // TODO: this logic is a bit primitive. According to the spec, the RX-50 drive LED only turns on if - // (a) spindle motor runs (b) disk is in drive (c) door closed (d) drive side is selected - if ( (data & 1) && (data & 8) ) - output_set_value("led20", 0); // DISKETTE 0 SELECTED & MOTOR 0 ON => LIGHT "DRIVE A" - else - output_set_value("led20", 1); +if (track != last_track) + printf("\n%02d",track); +last_track = track; + +// 40H diskette status Register **** READ ONLY *** ( 4-60 of TM100.pdf ) + +// AND 00111011 - return what was WRITTEN to D5-D3, D1, D0 previously +// (except D7,D6,D2) +int data = m_z80_diskcontrol && 0x3b; + +// D7: DRQ: reflects status of DATA REQUEST signal from FDC. +// '1' indicates that FDC has read data OR requires new write data. +data |= wd17xx_drq_r(m_fdc) ? 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). +data |= wd17xx_intrq_r(m_fdc) ? 0x40 : 0x00; + +// D5: SIDE 0H: status of side select signal at J2 + J3 of RX50 controller. +// For 1 sided drives, this bit will always read low (0). + +// 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 " + +// D2: TG43 L : 0 = INDICATES TRACK > 43 SIGNAL FROM FDC TO DISK DRIVE. +data |= ( track > 43) ? 0x00 : 0x04; + +// D1: DS1 H: reflect status of bits 0 and 1 form disk.control reg. +// D0: DS0 H: " + return data; +} - if ( (data & 2) && (data & 8) ) - output_set_value("led21", 0); // DISKETTE 1 SELECTED & MOTOR 0 ON => LIGHT "DRIVE B" +// (Z80) : PORT 40H * WRITE * + +// RX-50 has head A and head B (1 for each of the 2 disk slots in a RX-50). + +// TODO: find out how head load and drive select really work. +WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w) +{ + // FORCE_READY = 0 : assert DRIVE READY on FDC (diagnostic override; USED BY BIOS!) + // 1 : set ready only if drive is present, disk is in the drive, + // and disk motor is on - for Amstrad, Spectrum, PCW... + int force_ready = ( (data & 4) != 0 ) ? 0 : 1; + + int drive; + if ( m_inp6->read() && ((data & 3) < 2) ) + drive = (data & 1) + 2; else - output_set_value("led21", 1); + drive = data & 3; + + int selected_drive = 255; + + if (flopimg_get_image( floppy_get_device( machine(), drive ) ) != NULL) + { selected_drive = drive; + wd17xx_set_drive(m_fdc, selected_drive); + } + + // WD emulation (wd17xx.c) will ignore 'side select' if set to WD1793. + // Is it safe to * always assume * single sided 400 K disks? + wd17xx_set_side(m_fdc, (data & 20) ? 1 : 0); + + wd17xx_dden_w(m_fdc, 0); /* SEE 'WRITE_TRACK' : 1 = SD; 0 = DD; enable double density */ + + output_set_value("driveled0", (selected_drive == 0) ? 1 : 0 ); + output_set_value("driveled1", (selected_drive == 1) ? 1 : 0 ); + + output_set_value("driveled2", (selected_drive == 2) ? 1 : 0 ); + output_set_value("driveled3", (selected_drive == 3) ? 1 : 0 ); + + if (selected_drive < 4) + { + m_unit = selected_drive; + + // MOTOR ON flags 1+2 proved to be unreliable in this context. + // So this timeout only disables LEDs. + MOTOR_DISABLE_counter = 10000; // prolonged timeout. DEFAULT: 2400 = 500 ms + + for(int f_num=0; f_num <= 3; f_num++) + { + // Although 1773 does not feature 'motor on' this statement is required: + // CLEAR_LINE = turn motor on - + floppy_mon_w(m_image[f_num], (f_num == selected_drive) ? CLEAR_LINE : ASSERT_LINE); + + // Parameters: DRIVE, STATE, FLAG + floppy_drive_set_ready_state( m_image[f_num], + (f_num == selected_drive) ? 1 : 0, + (f_num == selected_drive) ? force_ready : 0 + ); + } + } + + m_z80_diskcontrol = data; } READ8_MEMBER( rainbow_state::read_video_ram_r ) @@ -772,8 +1056,6 @@ READ8_MEMBER( rainbow_state::read_video_ram_r ) INTERRUPT_GEN_MEMBER(rainbow_state::vblank_irq) { device.execute().set_input_line_and_vector(INPUT_LINE_INT0, ASSERT_LINE, 0x20); - - MHFU_reset(); } WRITE8_MEMBER( rainbow_state::clear_video_interrupt ) @@ -797,17 +1079,13 @@ WRITE8_MEMBER( rainbow_state::diagnostic_w ) // printf("%02x to diag port (PC=%x)\n", data, space.device().safe_pc()); m_SCREEN_BLANK = (data & 2) ? false : true; - if ( !(data & 0x40) && (m_diagnostic & 0x40) ) // if set to 1 (first) and later set to 0... - { - // SAVE / PROGRAM NVM: transfer data from volatile memory to NVM + // SAVE / PROGRAM NVM: transfer data from volatile memory to NVM + if ( !(data & 0x40) && (m_diagnostic & 0x40) ) memcpy( m_p_nvram, m_p_vol_ram, 256); - } - if ( (data & 0x80) && !(m_diagnostic & 0x80) ) // if set to 0 (first) and later set to 1... - { - // READ / RECALL NVM: transfer data from NVM to volatile memory + // READ / RECALL NVM: transfer data from NVM to volatile memory + if ( (data & 0x80) && !(m_diagnostic & 0x80) ) memcpy( m_p_vol_ram, m_p_nvram, 256); - } if (!(data & 1)) { @@ -823,6 +1101,20 @@ WRITE8_MEMBER( rainbow_state::diagnostic_w ) m_z80->reset(); } + /* Page 197 or 5-13 of formatter description: + ZRESET L : this low input from the 8088 diagnostic write register + resets the formatter controller, loads 03H into the command register, + and resets the not ready (status bit 7). + + When ZRESET goes high (1), a restore command is executed regardless + of the state of the ready signal from the diskette drive and + 01H is loaded into the sector register. + */ + + // reset device when going from high to low, + // restore command when going from low to high : + wd17xx_mr_w(m_fdc, (data & 1) ? 1 : 0); + m_diagnostic = data; } @@ -876,16 +1168,24 @@ TIMER_DEVICE_CALLBACK_MEMBER(rainbow_state::keyboard_tick) m_kbd8251->transmit_clock(); m_kbd8251->receive_clock(); - if ( m_crtc->dc012_MHFU() ) // MHFU ENABLED? - { - if (MHFU_counter) - MHFU_counter--; + if (MOTOR_DISABLE_counter) + MOTOR_DISABLE_counter--; + + if (MOTOR_DISABLE_counter == 1) + { + 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) + } - if (MHFU_counter == 1) // resets ONCE. - { - printf("*** CPU RESET: MASSIVE HARDWARE FAILURE DETECTED (MHFU LOGIC ~108 ms)\n"); - m_i8088->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - } + if ( m_crtc->MHFU(1) ) // MHFU ENABLED ? + { +/* int data = m_crtc->MHFU(-1); // increment MHFU, return new value + // if (data > 480) ... + // m_crtc->MHFU(-100); + // machine().schedule_hard_reset(); // not exactly a proper watchdog reset +*/ } if (m_beep_counter > 1) @@ -928,7 +1228,7 @@ const wd17xx_interface rainbow_wd17xx_interface = DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, - {FLOPPY_0, FLOPPY_1} + {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} }; static const floppy_interface floppy_intf = @@ -938,8 +1238,8 @@ static const floppy_interface floppy_intf = DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, - FLOPPY_STANDARD_5_25_SSDD, - LEGACY_FLOPPY_OPTIONS_NAME(default), + FLOPPY_STANDARD_5_25_SSDD_80, + LEGACY_FLOPPY_OPTIONS_NAME( dec100_floppy ), "floppy_5_25", NULL }; @@ -988,7 +1288,7 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state ) MCFG_SOUND_ROUTE(ALL_OUTPUTS,"mono",0.50) MCFG_FD1793_ADD("wd1793", rainbow_wd17xx_interface ) - MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf) + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(floppy_intf) MCFG_SOFTWARE_LIST_ADD("flop_list","rainbow") MCFG_I8251_ADD("kbdser", i8251_intf) @@ -998,7 +1298,9 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state ) MCFG_NVRAM_ADD_0FILL("nvram") MACHINE_CONFIG_END -/* ROM definition */ + + +// ROM definition for 100-B ROM_START( rainbow ) ROM_REGION(0x100000,"maincpu", 0) ROM_LOAD( "23-022e5-00.bin", 0xf0000, 0x4000, CRC(9d1332b4) SHA1(736306d2a36bd44f95a39b36ebbab211cc8fea6e)) @@ -1013,7 +1315,30 @@ ROM_START( rainbow ) ROM_LOAD( "chargen.bin", 0x0000, 0x1000, CRC(1685e452) SHA1(bc299ff1cb74afcededf1a7beb9001188fdcf02f)) ROM_END +// 'Rainbow 190 B' (announced March 1985) is identical hardware with alternate ROM v5.05 +// According to an article in Wall Street Journal, it came with a 10 MB HD and 640 K RAM. + +// We have no version history. The BOOT 2.4 README reveals 'recent ROM changes for MASS 11' +// in January 1985. These were not contained in the older version 04.03.11 (for PC-100-A) +// and also not present in version 05.03 (from PC-100B / PC100B+). + +// A first glance: +// => jump tables (F4000-F40083 and FC000-FC004D) were not extended. +// => absolute addresses of some internal routines have changed. +// => programs that do not rely on specific ROM versions should be compatible. +ROM_START( rainb190 ) + ROM_REGION(0x100000,"maincpu", 0) + ROM_LOAD( "dec190rom0.bin", 0xf0000, 0x4000, CRC(FAC191D2) ) + ROM_RELOAD(0xf4000,0x4000) + ROM_LOAD( "dec190rom1.bin", 0xf8000, 0x4000, CRC(5CE59632) ) + + ROM_RELOAD(0xfc000,0x4000) + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "chargen.bin", 0x0000, 0x1000, CRC(1685e452) SHA1(bc299ff1cb74afcededf1a7beb9001188fdcf02f)) +ROM_END + /* Driver */ -/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */ -COMP( 1982, rainbow, 0, 0, rainbow, rainbow, driver_device, 0, "Digital Equipment Corporation", "Rainbow 100B", GAME_NOT_WORKING | GAME_IMPERFECT_COLORS) +/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */ +COMP( 1983, rainbow , 0 , 0, rainbow, rainbow100b_in, driver_device, 0, "Digital Equipment Corporation", "Rainbow 100-B", GAME_NOT_WORKING | GAME_IMPERFECT_COLORS) +COMP( 1985, rainb190, rainbow, 0, rainbow, rainbow100b_in, driver_device, 0, "Digital Equipment Corporation", "Rainbow 190-B", GAME_NOT_WORKING | GAME_IMPERFECT_COLORS) \ No newline at end of file diff --git a/src/mess/layout/rainbow.lay b/src/mess/layout/rainbow.lay index 641d554999a..d62437b8770 100644 --- a/src/mess/layout/rainbow.lay +++ b/src/mess/layout/rainbow.lay @@ -1,13 +1,30 @@ - - + + - + + + + + + + + + + + + + + + + + + @@ -20,42 +37,55 @@ - + + + + + + + + + + + + + - + - + - + - + - + - + - + - + + @@ -81,45 +111,51 @@ - + - + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + @@ -128,38 +164,45 @@ - - + + + + + + + + + - + - + - + - + - + - + - - + + - + - + - + diff --git a/src/mess/machine/dec_lk201.c b/src/mess/machine/dec_lk201.c index 7a6cd3e75ab..4383821fecc 100644 --- a/src/mess/machine/dec_lk201.c +++ b/src/mess/machine/dec_lk201.c @@ -5,8 +5,8 @@ This is the later "cost-reduced" 6805 version; there's also an 8048 version. */ -/* LK201-AA keyboard matrix (8048 version) - Source: VCB02 Technical Reference. +/* LK201-AA keyboard matrix (8048 version with updates) + Source: VCB02 Technical Reference. KBD controller scan matrix (PORT 1): 8 x BCD IN => 18 DECIMAL OUT @@ -20,33 +20,32 @@ ________|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 ..KBD17:|[R] |F19 |[R] |F20|PF4|N--- N,| Enter ........| | | | | | NOTE1) ........| |G22 | |G23|E23|D23|C23| A23 -........| | | | | | <- - - - - - ? ? --------|----|----|----|---|---|---|---|--- -..KBD16:|F18 |PF3 |[R] |N9 |V |N6 |N3 |N +..KBD16:|F18 |PF3 |[R] |N9 |C:D|N6 |N3 |N. ........|G21 |E22 | |D22|B17|C22|B22|A22 --------|----|----|----|---|---|---|---|--- -..KBD15:|F17 |PF2 |[R] |N8 |N5 |-> | N2|N0 +..KBD15:|F17 |PF2 |[R] |N8 |N5 |C:R| N2|N0 ........| | | | | | | |NOTE 2) ........|G20 |E21 | |D21|C21|B18|B21| --------|----|----|----|---|---|---|---|--- - KBD14:|PF1 |Next|Remove ^|N7 |N4 |N1 |N0 -........| |Scrn| | || | | | + KBD14:|PF1 |Next|Rem-|C:U|N7 |N4 |N1 |N0 +........| |Scrn|move|...| | | | ........|E20 |D18 |E18 |C17|D20|C20|B20|A20 --------|----|----|----|---|---|---|---|--- -..KBD13:|Ins.|--- |D0 Prev| { |" |[R]|[R] -........|Here|- | Scrn. [ |' | | -........|E17 |E11 |G16 |D17 D11|C11| | +..KBD13:|Ins.|--- |'Do'|Prev { |" |[R]|[R] +........|Here|- | Scrn| [ |' | | +........|E17 |E11 |G16 |D17|D11|C11| | --------|----|----|----|---|---|---|---|--- -..KBD12:|Find|+ |Help|Se-| } Re- |<- | -........| |= | |lect ] turn| | -........|E16 |E12 |G15 |D16 D12|C13| | +..KBD12:|Find|+ |Help|Se-| } |Re-|C:L| | +........| |= | |lect ] |turn...| \ +........|E16 |E12 |G15 |D16 D12|C13|B16|C12 --------|----|----|----|---|---|---|---|--- -..KBD11:Addtnl -........|Scrn|2 |....| | | | |< +..KBD_3: Hold| @ |[R] |Tab|W |S |X |> +........|Scrn| 2 |....| | | | |< ........|G99 |E02 |....|D00|D02|C02|B02|B00 --------|----|----|----|---|---|---|---|--- ..KBD_2: [R] |[R] |[R] |~ |! |Q |A |Z -........|..............| |1 +........|..............|...|1 ........|..............|E00 E01 D01 C01 B01 --------|----|----|----|---|---|---|---|--- ..KBD_1: Ctrl|Lock|Comp|[R] @@ -94,6 +93,11 @@ ________|D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 Normally only the N0 keyswitch is implemented as a double-sized key. NOTE 3) Return key occupies 2 positions that are decoded as the Return (C13) key. + + C:D - Cursor down (B17) + C:U - Cursor up (C17) + C:R - Cursor right (B18) + C:L - Cursor left (B16) */ #include "emu.h" diff --git a/src/mess/machine/dec_lk201.h b/src/mess/machine/dec_lk201.h index dad6ba15864..96f1c187cd8 100644 --- a/src/mess/machine/dec_lk201.h +++ b/src/mess/machine/dec_lk201.h @@ -11,6 +11,20 @@ #define LK201_TAG "lk201" +#define LK_CMD_LEDS_ON 0x13 /* light LEDs - 1st param: led bitmask */ +#define LK_CMD_LEDS_OFF 0x11 /* turn off LEDs */ + +#define LK_CMD_DIS_KEYCLK 0x99 /* disable the keyclick */ +#define LK_CMD_ENB_KEYCLK 0x1b /* enable the keyclick - 1st param: volume */ +//#define LK_CMD_DIS_CTLCLK 0xb9 /* disable the Ctrl keyclick */ +//#define LK_CMD_ENB_CTLCLK 0xbb /* enable the Ctrl keyclick */ +#define LK_CMD_SOUND_CLK 0x9f /* emit a keyclick - 1st param: volume */ +#define LK_CMD_DIS_BELL 0xa1 /* disable the bell */ +#define LK_CMD_ENB_BELL 0x23 /* enable the bell - 1st param: volume */ +#define LK_CMD_BELL 0xa7 /* emit a bell - 1st param: volume */ + +#define LK_CMD_POWER_UP 0xfd /* init power-up sequence */ + //************************************************************************** // INTERFACE CONFIGURATION MACROS //************************************************************************** diff --git a/src/mess/mess.lst b/src/mess/mess.lst index 932659f1c96..c64d63814e5 100644 --- a/src/mess/mess.lst +++ b/src/mess/mess.lst @@ -1433,6 +1433,7 @@ vk100 // 1980 Digital Equipment Corporation dectalk // 1982 Digital Equipment Corporation mc7105 // Elektronika MC7105 rainbow // DEC Rainbow 100B +rainb190 // DEC Rainbow 190 // Memotech mtx512 // 1983 Memotech MTX 512 diff --git a/src/mess/video/vtvideo.c b/src/mess/video/vtvideo.c index 831c3d687e4..08970cd4942 100644 --- a/src/mess/video/vtvideo.c +++ b/src/mess/video/vtvideo.c @@ -1,16 +1,16 @@ - /********************************************************************** +/********************************************************************** DEC VT Terminal video emulation [ DC012 and DC011 emulation ] 01/05/2009 Initial implementation [Miodrag Milanovic] - --/--/2013 portions by Karl-Ludwig Deisenhofer. + xx/xx/2013 portions by Karl-Ludwig Deisenhofer. DEC VIDEO : STATE AS OF NOVEMBER 2013 ------------------------------------- - - NOT WORKING : scrolling requires implementation of 'scrolling region'. Multiple regions could be present. - Split & a full screen modes exist. Scroll should be synced with beam or DMA. - See 4.7.4 and up in VT manual. + - NOT FULLY WORKING : scrolling requires implementation of 'scrolling region'. Multiple regions could be present. + Split & full screen modes exist. Scroll should be synced with beam or DMA. + See 4.7.4 and up in VT manual. - TESTS REQUIRED : do line and character attributes (plus combinations) match real hardware? @@ -103,7 +103,6 @@ void vt100_video_device::device_start() // LBA7 is scan line frequency update machine().scheduler().timer_pulse(attotime::from_nsec(31778), timer_expired_delegate(FUNC(vt100_video_device::lba7_change),this)); - save_item(NAME(m_lba7)); save_item(NAME(m_scroll_latch)); save_item(NAME(m_blink_flip_flop)); @@ -146,10 +145,11 @@ void vt100_video_device::device_reset() // 4 color (= monochrome intensities) palette, 24 and 48 line modes. void rainbow_video_device::device_reset() { - DEC_MHFU = true; // SET ON COLD BOOT + MHFU_FLAG = false; + MHFU_counter = 0; // **** MHFU: OFF ON COLD BOOT ! **** - palette_set_color_rgb(machine(), 0, 0x00, 0x00, 0x00); // black // (rest of the palette is set in the main program) + palette_set_color_rgb(machine(), 0, 0x00, 0x00, 0x00); // black m_height = 24; // <---- DEC-100 m_height_MAX = 48; @@ -201,14 +201,21 @@ READ8_MEMBER( vt100_video_device::lba7_r ) // Also used by Rainbow-100 ************ WRITE8_MEMBER( vt100_video_device::dc012_w ) { - if (data == 0) - { - if (DEC_MHFU == true) - DEC_MHFU = false; // MHFU is disabled by writing 00 to port 010C. - } else - { - if (DEC_MHFU == false) - DEC_MHFU = true; // TODO: MHFU ENABLE should also reset the MHFU timer. + // TODO: writes to 10C/0C should be treated differently (emulation disables the watchdog too often). + if (data == 0) // MHFU is disabled by writing 00 to port 010C. + { + //if (MHFU_FLAG == true) + // printf("MHFU *** DISABLED *** \n"); + MHFU_FLAG = false; + MHFU_counter = 0; + } + else + { // RESET + //if (MHFU_FLAG == false) + // printf("MHFU ___ENABLED___ \n"); + MHFU_FLAG = true; + + MHFU_counter = 0; } if (!(data & 0x08)) @@ -223,7 +230,7 @@ WRITE8_MEMBER( vt100_video_device::dc012_w ) // and unlinked down at the bottom. // Note that the scroll latch value will be used during the next frame rather than the current frame. - // All line linking/unlinking should be done during the vertical blanking interval (< 550ms). + // All line linking/unlinking is done during the vertical blanking interval (< 550ms). // More on scrolling regions: Rainbow 100 B technical documentation (QV069-GZ) April 1985 page 22 // Also see VT100 Technical Manual: 4.7.4 Address Shuffling to 4.7.9 Split Screen Smooth Scrolling. @@ -249,6 +256,7 @@ WRITE8_MEMBER( vt100_video_device::dc012_w ) case 0x09: // clear vertical frequency interrupt; m_clear_video_interrupt(0, 0); + break; case 0x0a: // set reverse field on @@ -571,7 +579,7 @@ void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, // modify line since that is how it is stored in rom if (j == 0) j = 15; else j = j - 1; - line = m_gfx[code * 16 + j]; + line = m_gfx[ (code << 4) + j]; // code * 16 // UNDERLINED CHARACTERS (CASE 5 - different in 1 line): back_intensity = back_default_intensity; // 0, 1, 2 @@ -606,13 +614,13 @@ void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, // Double, 'double_height + double_width', then normal. if (double_width) { - bitmap.pix16( y_preset, d_x_preset + b * 2 + 1) = bit; - bitmap.pix16( y_preset, d_x_preset + b * 2) = bit; + bitmap.pix16( y_preset, d_x_preset + (b << 1) + 1) = bit; + bitmap.pix16( y_preset, d_x_preset + (b << 1) ) = bit; if (double_height) { - bitmap.pix16( 1 + y_preset, d_x_preset + b * 2 + 1) = bit; - bitmap.pix16( 1 + y_preset, d_x_preset + b * 2) = bit; + bitmap.pix16( 1 + y_preset, d_x_preset + (b << 1) + 1) = bit; + bitmap.pix16( 1 + y_preset, d_x_preset + (b << 1) ) = bit; } } else @@ -683,7 +691,7 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c } // LINE ATTRIBUTE - valid for all chars on next line ** DO NOT SHUFFLE ** - attr_addr = ( 0x1000 | ((addr + xpos + 1) & 0x0fff) ); + attr_addr = 0x1000 | ( (addr + xpos + 1) & 0x0fff ); // MOVE TO NEW DATA temp = m_in_ram_func(addr + xpos + 2) * 256 + m_in_ram_func(addr + xpos + 1); @@ -747,15 +755,15 @@ void rainbow_video_device::palette_select ( int choice ) break; case 0x02: - palette_set_color_rgb(machine(), 1, 0 , 200 -50, 0); // GREEN (dim) - palette_set_color_rgb(machine(), 2, 0 , 200, 0); // GREEN (NORMAL) - palette_set_color_rgb(machine(), 3, 0, 200 +50, 0); // GREEN (brighter) + palette_set_color_rgb(machine(), 1, 0 , 205 -50, 100 - 50); // GREEN (dim) + palette_set_color_rgb(machine(), 2, 0 , 205, 100 ); // GREEN (NORMAL) + palette_set_color_rgb(machine(), 3, 0, 205 +50, 100 + 50); // GREEN (brighter) break; case 0x03: - palette_set_color_rgb(machine(), 1, 213 - 47, 146 - 47, 82 - 47); // AMBER (dim) - palette_set_color_rgb(machine(), 2, 213, 146, 82); // AMBER (normal - not exact) - palette_set_color_rgb(machine(), 3, 255, 193, 129); // AMBER (brighter) + palette_set_color_rgb(machine(), 1, 213 - 47, 146 - 47, 82 - 47); // AMBER (dim) + palette_set_color_rgb(machine(), 2, 213, 146, 82 ); // AMBER (NORMAL) + palette_set_color_rgb(machine(), 3, 255, 193, 129 ); // AMBER (brighter) break; } } @@ -764,13 +772,38 @@ void rainbow_video_device::palette_select ( int choice ) void rainbow_video_device::video_blanking(bitmap_ind16 &bitmap, const rectangle &cliprect) { // 'In reverse screen mode, termination forces the beam to the screen background intensity' - // Background intensity means 'dim' (1) according to one source. Most certainly not pitch black. + // Background intensity means 'dim' (1) according to one source. bitmap.fill( ((m_reverse_field ^ m_basic_attribute) ? 1 : 0) , cliprect); } -int rainbow_video_device::dc012_MHFU() + + +int rainbow_video_device::MHFU(int ASK) { - return DEC_MHFU; + switch (ASK) + { + case 1: // "true": RETURN BOOLEAN (MHFU disabled or enabled?) + return MHFU_FLAG; + + case -1: // -1: increment, return counter value (=> Rainbow.c) + if (MHFU_FLAG == true) + MHFU_counter++; + return MHFU_counter; + + case -100: // -100 : RESET and ENABLE MHFU counter + //printf("-100 MHFU * reset and ENABLE * \n"); + MHFU_counter = 0; + + //if (MHFU_FLAG == false) + // printf("-100 MHFU ___ENABLED___\n"); + MHFU_FLAG = true; + + return -100; + + default: + assert(1); + return -255; + } // switch } TIMER_CALLBACK_MEMBER( vt100_video_device::lba7_change ) diff --git a/src/mess/video/vtvideo.h b/src/mess/video/vtvideo.h index 953d2c23bc8..53a6e35a197 100644 --- a/src/mess/video/vtvideo.h +++ b/src/mess/video/vtvideo.h @@ -40,7 +40,6 @@ public: DECLARE_WRITE8_MEMBER(brightness_w); virtual void video_update(bitmap_ind16 &bitmap, const rectangle &cliprect); - protected: // device-level overrides virtual void device_config_complete(); @@ -58,7 +57,10 @@ protected: UINT8 *m_gfx; /* content of char rom */ int m_lba7; - bool DEC_MHFU; + + bool MHFU_FLAG; + int MHFU_counter; + // dc012 attributes UINT8 m_scroll_latch; @@ -84,7 +86,7 @@ public: virtual void video_update(bitmap_ind16 &bitmap, const rectangle &cliprect); virtual void video_blanking(bitmap_ind16 &bitmap, const rectangle &cliprect); - int dc012_MHFU(); + int MHFU(int); void palette_select(int choice); protected: virtual void display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type); -- cgit v1.2.3