diff --git a/hash/ibm5170_cdrom.xml b/hash/ibm5170_cdrom.xml index 6d7885069e7..070327a4779 100644 --- a/hash/ibm5170_cdrom.xml +++ b/hash/ibm5170_cdrom.xml @@ -6509,93 +6509,29 @@ Has setup menu glitch with text [8514] - + - - - Acer CPR - 1995 - Acer America Corporation - - + + + BeOS 4.5 + 1999 + Be Inc + - - + - - - - - - - - - - - DIV Games Studio (English, v1.03b) - 1998 - Hammer Technologies - - - - - - - - - - - DIV Games Studio (French, v1.03b) - 2000 - Hammer Technologies - - - - - - - - - - Adaptec EZ-SCSI 4.01 (Rev A) - 1996 - Adaptec - - - - - - - - - - Adaptec EZ-SCSI 5.0 Deluxe Edition (Rev B) - - 1999 - Adaptec - + + - + @@ -6782,64 +6718,6 @@ EZCDLITE Contains Easy CD Creator Lite ASPI setup - - - - - Key CAD Complete Creations (v6.0) - 1996 - SoftKey - - - - - - - - - - - Lexmark Z22 / Z32 Color Jetprinter - 2000 - Lexmark - - - - - - - - - The Matrox Millennium Multimedia SuperPack (v1.60) - 1996 - Matrox - - - - - - - - - - - - Mustek Power of Scanning - 1997 - Mustek - - - - - - - - NASLite NAS Server Operating System (v1.x) 2004 @@ -6852,93 +6730,6 @@ Contains software drivers for a ScanExpress 6000SP Flatbed Scanner, SCSI i/f - - - Lotus Notes Express v3.30 for OS2, Special Promotion Copy NFR - 1995 - Lotus Development Corporation - - - - - - - - - - - Caldera OpenDOS Machine Readable Source Kit (M.R.S) 7.01 - 1997 - Caldera - - - - - - - - - - - - IBM DEMOpkg for OS2 - First Edition 99Q3 - 1999 - IBM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OS/2 Warp Special CD - november 1995 @@ -7043,24 +6834,6 @@ Contains software drivers for a ScanExpress 6000SP Flatbed Scanner, SCSI i/f - - - Paranasal Sinuses & Anterior Skull Base - 1993 - Elsevier Science B.V. - - - - - - - PC DOS 7 1995 @@ -7086,18 +6859,417 @@ Contains software drivers for a ScanExpress 6000SP Flatbed Scanner, SCSI i/f - - S3 Drivers Collection 1998 (Rev 2.1) - 1998 - S3 - + Windows 95 (en 4.00.950) + 1995 + Microsoft + + + + + + + + + + Windows 95 OSR1 (en 4.00.950.osr1) + 1996 + Microsoft + + + + + + + + + + + Windows 95 OSR2 (en 4.00.1111.osr2) + 1996 + Microsoft + + + + + + + + + + + Windows 95 OSR2.5 (en 4.03.1216.osr2.5) + 1997 + Microsoft + + + + + + + + + + Windows 98 (en 4.10.1998) (Retail Full) + 1998 + Microsoft + + + + + + + + + + Windows 98 Second Edition (en 4.10.2222) (Retail Full) + 1999 + Microsoft + + + + + + + + + + + + Windows 98 Second Edition (jp 4.10.2222) (Retail Full) + 1999 + Microsoft + + + + + + + + + + + + Windows ME (en 4.90.3000) (Retail Full) + 2000 + Microsoft + + + + + + + + + + Windows NT 3.1 Workstation (3.10.511.1) + 1993 + Microsoft + + + + + + + + + + Windows NT 3.51 Workstation (3.51.1057.1) + 1995 + Microsoft + + + + + + + + + + Windows 2000 Professional (with Service Pack 4) (en 5.00.2195.6717) + 1999 + Microsoft + + + + + + + + + + + + + + + Acer CPR + 1995 + Acer America Corporation + + + + + + + + + + + + + + + + + + + DIV Games Studio (English, v1.03b) + 1998 + Hammer Technologies + + + + + + + + + + + DIV Games Studio (French, v1.03b) + 2000 + Hammer Technologies + + + + + + + + + + Adaptec EZ-SCSI 4.01 (Rev A) + 1996 + Adaptec + + + + + + + + + + Adaptec EZ-SCSI 5.0 Deluxe Edition (Rev B) + + 1999 + Adaptec + + + + + + + + + + + + Key CAD Complete Creations (v6.0) + 1996 + SoftKey + + + + + + + + + + + Lexmark Z22 / Z32 Color Jetprinter + 2000 + Lexmark + + + + + + + + + The Matrox Millennium Multimedia SuperPack (v1.60) + 1996 + Matrox + + + + + + + + + + + + Mustek Power of Scanning + 1997 + Mustek + + + + + + + + + + + Lotus Notes Express v3.30 for OS2, Special Promotion Copy NFR + 1995 + Lotus Development Corporation + + + + + + + + + + + Caldera OpenDOS Machine Readable Source Kit (M.R.S) 7.01 + 1997 + Caldera + + + + + + + + + + + + IBM DEMOpkg for OS2 - First Edition 99Q3 + 1999 + IBM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Paranasal Sinuses & Anterior Skull Base + 1993 + Elsevier Science B.V. + + + + + + + + + S3 Drivers Collection 1998 (Rev 2.1) + 1998 + S3 + - - - - Windows 95 (en 4.00.950) - 1995 - Microsoft - - - - - - - - - - Windows 95 OSR1 (en 4.00.950.osr1) - 1996 - Microsoft - - - - - - - - - - Windows 95 OSR2 (en 4.00.1111.osr2) - 1996 - Microsoft - - - - - - - - - - Windows 95 OSR2.5 (en 4.03.1216.osr2.5) - 1997 - Microsoft - - - - - - - - - - Windows 98 (en 4.10.1998) (Retail Full) - 1998 - Microsoft - - - - - - - - - - Windows 98 Second Edition (en 4.10.2222) (Retail Full) - 1999 - Microsoft - - - - - - - - - - - - Windows 98 Second Edition (jp 4.10.2222) (Retail Full) - 1999 - Microsoft - - - - - - - - - - - - Windows ME (en 4.90.3000) (Retail Full) - 2000 - Microsoft - - - - - - - - - - Windows NT 3.1 Workstation (3.10.511.1) - 1993 - Microsoft - - - - - - - - - - Windows NT 3.51 Workstation (3.51.1057.1) - 1995 - Microsoft - - - - - - - - - - Windows 2000 Professional (with Service Pack 4) (en 5.00.2195.6717) - 1999 - Microsoft - - - - - - - - - - diff --git a/hash/msx1_flop.xml b/hash/msx1_flop.xml index 2789a6c1105..3e68fa2bdf5 100644 --- a/hash/msx1_flop.xml +++ b/hash/msx1_flop.xml @@ -44,6 +44,31 @@ The following floppies came with the machines. + + Serial Interface (Netherlands) + 1986 + Philips + Included with NMS 1210, NMS 1211, and NMS 1212 RS-232C packages. These serial interfaces are not supported. + + + + + + + + + MSX Data Communications (Netherlands) + 1987 + Philips + Included with NMS 1250 Modem package. NMS 1250 is not supported. + + + + + + + + @@ -207,6 +232,23 @@ The following floppies came with the machines. + + Aackotext II (Netherlands, v2.2) + 1985 + Aackosoft + + + + + + + + + + + + + Adonis (Japan) @@ -346,6 +388,18 @@ The following floppies came with the machines. + + Brasil Geográfico (Brazil) + 1991 + Discovery Informática + + + + + + + + Breaker Breaker (Europe) 1988 @@ -524,6 +578,18 @@ The following floppies came with the machines. + + dBASE II (Netherlands) + 1983 + C.U.C. + + + + + + + + Delta BASIC (Netherlands) 1987 @@ -1253,6 +1319,37 @@ The following floppies came with the machines. + + MS Text (Netherlands) + 1985 + Philips + + + + + + + + + + + + + + + Score Editor (Japan) + 1987 + Toshiba-EMI Ltd. + + + + + + + + + + MSX Compilation 5 (Netherlands) 1986 @@ -1303,6 +1400,17 @@ The following floppies came with the machines. + + MSX-AIDS (Japan, v1.1) + 1988 + Sansai Books + + + + + + + Music Creator (Netherlands) @@ -1366,6 +1474,28 @@ The following floppies came with the machines. + + Nihongo Waupuro Kan-juku Tomato (Japan) + 1985 + Sony + + + + + + + + + + + + + + + + + + North Sea Helicopter (Netherlands, hacked) 1987 @@ -1951,9 +2081,8 @@ The following floppies came with the machines. Methodic Solutions - - - + + @@ -2079,6 +2208,17 @@ The following floppies came with the machines. + + Zanac (Netherlands) + 1986 + Eaglesoft + + + + + + + Zen (United Kingdom) 1986 @@ -2295,6 +2435,18 @@ The following floppies came with the machines. + + JUBILEUM Diskette (Netherlands) + 1989 + Stichting C.U.C. + + + + + + + + Cyuji Games (Japan) @@ -5116,6 +5268,19 @@ The following floppies came with the machines. + + Yamaha Portatone PSR-6300 Demonstration + 19?? + Yamaha + Midi connection to PSR-6300 has not been tested. + + + + + + + + Zeta 2000 (Japan, disk conversion) 19?? @@ -5878,17 +6043,4 @@ The following floppies came with the machines. - - Zanac (Netherlands) - 1986 - Eaglesoft - - - - - - - - - diff --git a/hash/msxr_flop.xml b/hash/msxr_flop.xml index 74facbeed26..5ef38976fae 100644 --- a/hash/msxr_flop.xml +++ b/hash/msxr_flop.xml @@ -7,12 +7,13 @@ license:CC0-1.0 + - - 2021 Snooky! (Jpn) + + FS-A1GT (Japan) + 1990 + Panasonic + + + + + + + + + + + + + + + + + + + + + + FS-A1ST (Japan) + 1990 + Panasonic + + + + + + + + + + + + + + + + + + + 2021 Snooky! (Japan) 1991 Studio Hawk - @@ -45,11 +87,100 @@ Known undumped: - - Die Frage II' (Jpn) + + The Best of Hamaraja Night (Japan) + 1999 + Pastel Hope + MSX Turbo-R is not supported. + + + + + + + + + Dewoman Zenpen (Japan) + 1993 + Blue Eyes + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dewoman Chuuhen (Japan) + 1993 + Blue Eyes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Die Frage II' (Japan) 199? Studio Sequence - @@ -57,24 +188,33 @@ Known undumped: - - Die Frage II' (Jpn, Bad Dump?) + + Die Frage II' (Japan, bad dump?) 199? Studio Sequence + + + + + + + + Fantasy Attraction (Japan) + 1996 + Rem Company - + - - Fray - In Magical Adventure (Jpn) + + Fray - In Magical Adventure (Japan) 1990 Micro Cabin - - + @@ -107,12 +247,11 @@ Known undumped: - - Fray - In Magical Adventure (Jpn, Alt) + + Fray - In Magical Adventure (Japan, alt) 1990 Micro Cabin - - + @@ -145,12 +284,11 @@ Known undumped: - - Fray - In Magical Adventure (Jpn, Alt 2) + + Fray - In Magical Adventure (Japan, alt 2) 1990 Micro Cabin - - + @@ -183,12 +321,11 @@ Known undumped: - - Illusion City - Genei Toshi (Jpn) + + Illusion City - Genei Toshi (Japan) 1991 Micro Cabin - @@ -239,11 +376,85 @@ Known undumped: - - μ.Note (Jpn) + + innocent wish ~destiny2~ (Japan) + 1995 + Sign House + + + + + + + + + Mahou no Kuni no Hoippuru (Japan) + 1996 + Pastel Hope + + + + + + + + + + Mechanical Brain (Japan) + 1996 + Studio Sequence + + + + + + + + + Mejuu Sa - Medusa (Japan) + 1994 + Blue Eyes + + + + + + + + + + + + + + + + + + + + MSX ViewCALC (Japan) + 1991 + ASCII Corporation + + + + + + + + + + + + + + + + + μ.Note (Japan) 1992 Bit² - @@ -258,11 +469,10 @@ Known undumped: - - μ.Sios (Jpn) + + μ.Sios (Japan) 1991 Bit² - @@ -283,12 +493,22 @@ Known undumped: - - Ranma ½ - Hiryuu Densetsu (Jpn) + + R2 Chaser's (Japan) + 1996 + Studio Sequence + + + + + + + + + Ranma ½ - Hiryuu Densetsu (Japan) 1992 Bothtec - - + @@ -339,12 +559,11 @@ Known undumped: - - Ranma ½ - Hiryuu Densetsu (Jpn, Alt) + + Ranma ½ - Hiryuu Densetsu (Japan, alt) 1992 Bothtec - - + @@ -395,12 +614,11 @@ Known undumped: - - Ranma ½ - Hiryuu Densetsu (Jpn, Alt 2) + + Ranma ½ - Hiryuu Densetsu (Japan, alt 2) 1992 Bothtec - - + @@ -451,12 +669,11 @@ Known undumped: - - Ranma ½ - Hiryuu Densetsu (Jpn, Alt Disk 1) + + Ranma ½ - Hiryuu Densetsu (Japan, alt disk 1) 1992 Bothtec - - + @@ -507,12 +724,11 @@ Known undumped: - - Seed of Dragon (Jpn) + + Seed of Dragon (Japan) 1990 Riverhill Soft - - + @@ -533,12 +749,11 @@ Known undumped: - - Seed of Dragon (Jpn, Alt) + + Seed of Dragon (Japan, alt) 1990 Riverhill Soft - @@ -559,12 +774,11 @@ Known undumped: - - Seed of Dragon (Jpn, Alt Disk 1) + + Seed of Dragon (Japan, alt disk 1) 1990 Riverhill Soft - @@ -585,11 +799,70 @@ Known undumped: - - Turbo Booster (Jpn) + + South Town's Hero II (Japan) + 1995 + FM-Guamuom + + + + + + + + + + + + + + South Town's Hero Turbo (Japan) + 1995 + FM-Guamuom + + + + + + + + + Speedline (demo) + 2001 + Traposoft + + + + + + + + + Superiority Fighters (Japan) + 1994 + Mushroom + + + + + + + + + Turbo Blaster (Japan) + 1994 + M.O.V + + + + + + + + + Turbo Booster (Japan) 1990 Kyoto Media - @@ -597,17 +870,33 @@ Known undumped: + + Welkis the Legend (Japan) + 1996 + Uechan Dayo + + + + + + + + + + + + + + - - Dream Drops - Secret Design of the Hearts (Jpn) + + Dream Drops - Secret Design of the Hearts (Japan) 2011 - <doujin> - - + Rabbit Soft Worker's @@ -615,12 +904,10 @@ Known undumped: - - Dream Fighters (Jpn) + + Dream Fighters (Japan) 1996 - <doujin> - - + Monoki @@ -629,12 +916,10 @@ Known undumped: - - Earth Attack (Jpn) + + Earth Attack (Japan) 19?? - <doujin> - - + GW's Workshop @@ -642,12 +927,10 @@ Known undumped: - - F-Nano 2 - 3D Car Action (Jpn) + + F-Nano 2 - 3D Car Action (Japan) 1994 - <doujin> - - + XRay @@ -655,12 +938,10 @@ Known undumped: - - F-Nano 2' - 3D Car Action (Jpn) + + F-Nano 2' - 3D Car Action (Japan) 1997 - <doujin> - - + XRay @@ -668,13 +949,11 @@ Known undumped: - - Gekikara Roudousha (Jpn) + + Gekikara Roudousha (Japan) 1995 - <doujin> - - - + Delta Trial + @@ -682,12 +961,10 @@ Known undumped: - - Gun Shot vs Festa Again (Jpn) + + Gun Shot vs Festa Again (Japan) 2001 - <doujin> - - + Rabbit Soft Worker's @@ -695,12 +972,21 @@ Known undumped: - - In the 6th Sense - Product of the Hearts (Jpn) - 2007 - <doujin> - + + Hyper Role Playing Story LOSTWORD Episode 0 (Japan) + 2019 + Rabbit Soft Worker's + + + + + + + + In the 6th Sense - Product of the Hearts (Japan) + 2007 + Rabbit Soft Worker's @@ -708,12 +994,10 @@ Known undumped: - + Mistral Blue 2002 - <doujin> - - + Popcorn @@ -721,12 +1005,10 @@ Known undumped: - + Mobius Debugger 2 - Eternal Striker 1995 - <doujin> - - + Studio Sequence @@ -734,38 +1016,57 @@ Known undumped: - - Moon Light Saga (Jpn) + + Moon Light Saga - Horus no Shou (Japan) 1996 - <doujin> - - + MapleYard + + - + + + + + + + + + + + + + - - Moon Light Saga (Jpn, Bad Dump?) + + Moon Light Saga (Japan, bad dump?) 1996 - <doujin> - + MapleYard + + + + + + + + Moon Light Saga (Japan, alt) + 1996 + MapleYard - + - - Multi-Plex (Jpn) + + Multi-Plex (Japan) 1993 - <doujin> - - + MIWA @@ -773,12 +1074,10 @@ Known undumped: - - Multi-Plex (Jpn, Alt) + + Multi-Plex (Japan, alt) 1993 - <doujin> - - + MIWA @@ -787,12 +1086,10 @@ Known undumped: - - PaRaDream - Parallel Dream (Jpn) + + PaRaDream - Parallel Dream (Japan) 1992 - <doujin> - - + RAC House @@ -800,12 +1097,10 @@ Known undumped: - - PaRaDream - Parallel Dream (Jpn, Alt) + + PaRaDream - Parallel Dream (Japan, alt) 1992 - <doujin> - - + RAC House @@ -813,12 +1108,10 @@ Known undumped: - - PaRaDream - Parallel Dream (Jpn, Alt 2) + + PaRaDream - Parallel Dream (Japan, alt 2) 1992 - <doujin> - - + RAC House @@ -826,12 +1119,10 @@ Known undumped: - + Phi 2004 - <doujin> - - + Mariko-ban GCC @@ -839,25 +1130,32 @@ Known undumped: - - Space Panic! - 1998 - <doujin> - + + Qui Veut Gagner Des Millions + 2004 + Walter + + + + + + + + Quien Quiere Ser Milionario + 2009 + Walter - + - - S.T.G. (Jpn) + + S.T.G. (Japan) 1996 - <doujin> - - + Y. Tomohara @@ -865,12 +1163,10 @@ Known undumped: - - S.T.G. Special - Do Don Taku (Jpn) + + S.T.G. Special - Do Don Taku (Japan) 1998 - <doujin> - - + Y. Tomohara @@ -878,13 +1174,11 @@ Known undumped: - - Saishuu Bouei-sen - Save Your Mother Planet: The Earth (Jpn) + + Saishuu Bouei-sen - Save Your Mother Planet: The Earth (Japan) 1996 - <doujin> - - - + GW's Workshop + @@ -892,12 +1186,10 @@ Known undumped: - - Shoot That Flying Windows! (Fin) + + Shoot That Flying Windows! (Finland) 1997 - <homebrew> - - + Nyyrikki @@ -905,12 +1197,10 @@ Known undumped: - - Shoot That Flying Windows! (Fin, Alt) + + Shoot That Flying Windows! (Finland, alt) 1997 - <homebrew> - - + Nyyrikki @@ -918,27 +1208,57 @@ Known undumped: - - Shoulder Blade (Jpn, Bad Dump?) + + Shoulder Blade (Japan, bad dump?) 1997 - <doujin> - + GW's Workshop + + + + + + + + + Space Panic! (Japan) + 1998 + Mikasen + + + + + + + + Stage 11 (Japan) + 1996 + Mikasen - + + + + + + + Stage 11 Kai (Japan) + 1998 + Mikasen + + + + - - Sweet (Jpn) + + Sweet (Japan) 1994 - <doujin> - - + Kazuyuki Suzuki @@ -946,86 +1266,94 @@ Known undumped: - - Treasure of Babylon (Fra) - 2013 - <homebrew> - - + + Telebasic Edición No. 1 (Spain) + 1993 + Traposoft - + - - Zone Terra (Ned) + + Telebasic Edición No. 2 (Spain) 1994 - <homebrew> - - + Traposoft - + - - Zone Terra (Ned, Demo) - 1994 - <homebrew> - + + Telebasic Edición No. 3 (Spain) + 1995 + Traposoft + + + + + + + + Treasure of Babylon (France) + 2013 + Eric Boez - + - - Zekkou no Tsuri Biyori ya!! (Jpn) - 1996 - <doujin> - - + + Zone Terra (Netherlands) + 1994 + Quadrivium + + + + + + + + Zone Terra (Netherlands, demo) + 1994 + Quadrivium - + - - Zekkou no Tsuri Biyori ya!! (Jpn, Alt) + + Zekkou no Tsuri Biyori ya!! (Japan) 1996 - <doujin> - - - + GW's Workshop + - + - - - - MSX View (Jpn, Bad Dump?) - 19?? - <unknown> - + + Zekkou no Tsuri Biyori ya!! (Japan, alt) + 1996 + GW's Workshop + - + - diff --git a/src/devices/bus/hexbus/hexbus.h b/src/devices/bus/hexbus/hexbus.h index 1d225c55749..34bbea63193 100644 --- a/src/devices/bus/hexbus/hexbus.h +++ b/src/devices/bus/hexbus/hexbus.h @@ -161,7 +161,7 @@ class hexbus_device : public device_t, public device_single_card_slot_interface< void write(int dir, uint8_t data); protected: - void device_start() override; + virtual void device_start() override; device_hexbus_interface *m_next_dev; private: diff --git a/src/devices/bus/hexbus/hx5102.cpp b/src/devices/bus/hexbus/hx5102.cpp index 459157fc604..999df7fe520 100644 --- a/src/devices/bus/hexbus/hx5102.cpp +++ b/src/devices/bus/hexbus/hx5102.cpp @@ -86,9 +86,10 @@ #define LOG_MOTOR (1U << 9) // Motor activity #define LOG_STATUS (1U << 10) // Main status register #define LOG_FIFO (1U << 11) // Data register +#define LOG_CONFIG (1U << 12) // Configuration // Minimum log should be config and warnings -#define VERBOSE (LOG_GENERAL | LOG_WARN) +#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_CONFIG) #include "logmacro.h" @@ -104,6 +105,9 @@ #define ROM1_TAG "u25_rom" #define ROM2_TAG "u29_rom" +#define FLOP0 "d0" +#define FLOP1 "d1" + #define MOTOR_TIMER 1 #define UNDEF -1 @@ -138,6 +142,8 @@ hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, dev m_dack(false), m_dacken(false), m_wait(false), + m_flopcon0(*this, FLOP0), + m_flopcon1(*this, FLOP1), m_current_floppy(nullptr), m_floppy_select(0), m_floppy_select_last(UNDEF), @@ -581,13 +587,21 @@ void hx5102_device::update_drive_select() */ void hx5102_device::device_start() { - m_floppy[0] = m_floppy[1] = nullptr; - - if (subdevice("d0")!=nullptr) m_floppy[0] = static_cast(subdevice("d0")->subdevices().first()); - if (subdevice("d1")!=nullptr) m_floppy[1] = static_cast(subdevice("d1")->subdevices().first()); - m_rom1 = (uint8_t*)memregion(DSR_TAG)->base(); m_rom2 = (uint8_t*)memregion(DSR_TAG)->base() + 0x2000; + + m_floppy[0] = m_flopcon0->get_device(); + m_floppy[1] = m_flopcon1->get_device(); + + if (m_floppy[0] != nullptr) + LOGMASKED(LOG_CONFIG, "Internal floppy drive connected\n"); + else + LOGMASKED(LOG_WARN, "Internal floppy drive not found\n"); + + if (m_floppy[1] != nullptr) + LOGMASKED(LOG_CONFIG, "External floppy drive connected\n"); + else + LOGMASKED(LOG_CONFIG, "External floppy drive not connected\n"); } /* @@ -686,8 +700,8 @@ void hx5102_device::device_add_mconfig(machine_config& config) m_floppy_ctrl->intrq_wr_callback().set(FUNC(hx5102_device::fdc_irq_w)); m_floppy_ctrl->drq_wr_callback().set(FUNC(hx5102_device::fdc_drq_w)); - FLOPPY_CONNECTOR(config, "d0", hx5102_drive, "525dd", hx5102_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "d1", hx5102_drive, nullptr, hx5102_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_flopcon0, hx5102_drive, "525dd", hx5102_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_flopcon1, hx5102_drive, nullptr, hx5102_device::floppy_formats).enable_sound(true); // Addressable latches LS259(config, m_crulatch[0]); // U18 diff --git a/src/devices/bus/hexbus/hx5102.h b/src/devices/bus/hexbus/hx5102.h index 34c3bc6f705..b0e490237d8 100644 --- a/src/devices/bus/hexbus/hx5102.h +++ b/src/devices/bus/hexbus/hx5102.h @@ -38,7 +38,7 @@ class hx5102_device : public hexbus_chained_device protected: virtual const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; - ioport_constructor device_input_ports() const override; + virtual ioport_constructor device_input_ports() const override; void crumap(address_map &map); void memmap(address_map &map); @@ -48,8 +48,8 @@ class hx5102_device : public hexbus_chained_device void board_reset(int state); static void floppy_formats(format_registration &fr); - void device_start() override; - void device_reset() override; + virtual void device_start() override; + virtual void device_reset() override; virtual void hexbus_value_changed(uint8_t data) override; private: @@ -101,6 +101,8 @@ class hx5102_device : public hexbus_chained_device void update_readyff_input(); // Link to the attached floppy drives + required_device m_flopcon0; + required_device m_flopcon1; floppy_image_device* m_floppy[2]; floppy_image_device* m_current_floppy; int m_floppy_select, m_floppy_select_last; diff --git a/src/devices/bus/ti99/gromport/cartridges.cpp b/src/devices/bus/ti99/gromport/cartridges.cpp index f60e90d5e7e..e54f82e42ec 100644 --- a/src/devices/bus/ti99/gromport/cartridges.cpp +++ b/src/devices/bus/ti99/gromport/cartridges.cpp @@ -30,7 +30,7 @@ #define LOG_RPK (1U << 8) // RPK handler #define LOG_WARNW (1U << 9) // Warn when writing to cartridge space -#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_CONFIG) +#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_CONFIG | LOG_CHANGE) #include "logmacro.h" DEFINE_DEVICE_TYPE(TI99_CART, bus::ti99::gromport::ti99_cartridge_device, "ti99cart", "TI-99 cartridge") @@ -94,7 +94,6 @@ ti99_cartridge_device::ti99_cartridge_device(const machine_config &mconfig, cons : device_t(mconfig, TI99_CART, tag, owner, clock), device_cartrom_image_interface(mconfig, *this), m_pcbtype(0), - m_slot(0), m_pcb(nullptr), m_connector(nullptr) { @@ -274,7 +273,8 @@ int ti99_cartridge_device::get_index_from_tagname() std::pair ti99_cartridge_device::call_load() { // File name is in m_basename - LOGMASKED(LOG_CHANGE, "Loading %s in slot %s\n", basename()); + int slot = get_index_from_tagname() + 1; + LOGMASKED(LOG_CHANGE, "Loading %s in slot %d\n", basename(), slot); if (loaded_through_softlist()) { @@ -363,8 +363,7 @@ std::pair ti99_cartridge_device::call_load() prepare_cartridge(); m_pcb->set_cartridge(this); m_pcb->set_tag(tag()); - m_slot = get_index_from_tagname(); - m_connector->insert(m_slot, this); + m_connector->insert(); return std::make_pair(std::error_condition(), std::string()); } @@ -387,13 +386,21 @@ void ti99_cartridge_device::call_unload() } } - m_pcb = nullptr; - m_connector->remove(m_slot); -} + // If we don't clear this, swapping cartridges may make old contents reappear + if (memregion("grom")) + machine().memory().region_free(memregion("grom")->name()); -void ti99_cartridge_device::set_slot(int i) -{ - m_slot = i; + if (memregion("rom")) + machine().memory().region_free(memregion("rom")->name()); + + if (memregion("nvram")) + machine().memory().region_free(memregion("nvram")->name()); + + if (memregion("ram")) + machine().memory().region_free(memregion("ram")->name()); + + m_pcb = nullptr; + m_connector->remove(); } void ti99_cartridge_device::readz(offs_t offset, uint8_t *value) @@ -450,12 +457,6 @@ bool ti99_cartridge_device::is_grom_idle() return (m_pcb != nullptr)? m_pcb->is_grom_idle() : false; } -void ti99_cartridge_device::device_config_complete() -{ - m_connector = dynamic_cast(owner()); - // owner is the empty_state during -listxml, so this will be nullptr -} - /* 5 GROMs that may be contained in a cartridge */ diff --git a/src/devices/bus/ti99/gromport/cartridges.h b/src/devices/bus/ti99/gromport/cartridges.h index 952288a7d59..6402d4cf38c 100644 --- a/src/devices/bus/ti99/gromport/cartridges.h +++ b/src/devices/bus/ti99/gromport/cartridges.h @@ -27,6 +27,10 @@ class ti99_cartridge_pcb; class ti99_cartridge_device : public device_t, public device_cartrom_image_interface { + friend class ti99_single_cart_conn_device; + friend class ti99_multi_cart_conn_device; + friend class ti99_gkracker_device; + public: ti99_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -43,12 +47,10 @@ class ti99_cartridge_device : public device_t, public device_cartrom_image_inter void gclock_in(int state); bool is_available() { return m_pcb != nullptr; } - void set_slot(int i); bool is_grom_idle(); protected: virtual void device_start() override { } - virtual void device_config_complete() override; virtual void device_add_mconfig(machine_config &config) override; virtual const tiny_rom_entry* device_rom_region() const override; @@ -63,6 +65,8 @@ class ti99_cartridge_device : public device_t, public device_cartrom_image_inter const char *image_interface() const noexcept override { return "ti99_cart"; } const char *file_extensions() const noexcept override { return "rpk"; } + void set_connector(cartridge_connector_device* conn) { m_connector = conn; } + private: class ti99_rpk_socket; @@ -116,7 +120,6 @@ class ti99_cartridge_device : public device_t, public device_cartrom_image_inter bool m_readrom; int m_pcbtype; - int m_slot; int get_index_from_tagname(); std::unique_ptr m_pcb; // inbound diff --git a/src/devices/bus/ti99/gromport/gkracker.cpp b/src/devices/bus/ti99/gromport/gkracker.cpp index 0a6055bcd53..c39a3cae806 100644 --- a/src/devices/bus/ti99/gromport/gkracker.cpp +++ b/src/devices/bus/ti99/gromport/gkracker.cpp @@ -101,7 +101,7 @@ #define LOG_CHANGE (1U << 2) // Cartridge change #define LOG_GKRACKER (1U << 3) // Gram Kracker operation -#define VERBOSE (LOG_WARN) +#define VERBOSE (LOG_GENERAL | LOG_WARN) #include "logmacro.h" DEFINE_DEVICE_TYPE(TI99_GROMPORT_GK, bus::ti99::gromport::ti99_gkracker_device, "ti99_gkracker", "Miller's Graphics GRAM Kracker") @@ -141,16 +141,15 @@ ti99_gkracker_device::ti99_gkracker_device(const machine_config &mconfig, const m_ram_ptr(nullptr), m_grom_ptr(nullptr), m_waddr_LSB(false), - m_cartridge(nullptr) + m_cartridge(*this, "cartridge") { } void ti99_gkracker_device::romgq_line(int state) { m_romspace_selected = (state==ASSERT_LINE); - // Propagate to the guest - if (m_cartridge != nullptr) - m_cartridge->romgq_line(state); + // Propagate to the guest (if available) + m_cartridge->romgq_line(state); } /* @@ -159,14 +158,12 @@ void ti99_gkracker_device::romgq_line(int state) void ti99_gkracker_device::set_gromlines(line_state mline, line_state moline, line_state gsq) { m_grom_selected = (gsq==ASSERT_LINE); - if (m_cartridge != nullptr) - m_cartridge->set_gromlines(mline, moline, gsq); + m_cartridge->set_gromlines(mline, moline, gsq); } void ti99_gkracker_device::gclock_in(int state) { - if (m_cartridge != nullptr) - m_cartridge->gclock_in(state); + m_cartridge->gclock_in(state); } /* @@ -174,7 +171,7 @@ void ti99_gkracker_device::gclock_in(int state) */ bool ti99_gkracker_device::is_grom_idle() { - return (m_cartridge != nullptr) ? m_cartridge->is_grom_idle() : false; + return m_cartridge->is_grom_idle(); } void ti99_gkracker_device::readz(offs_t offset, uint8_t *value) @@ -224,25 +221,19 @@ void ti99_gkracker_device::readz(offs_t offset, uint8_t *value) } // If the guest has GROMs or ROMs they will override the GK contents - if (m_cartridge != nullptr) - { - // For debugging - uint8_t val1 = *value; + // For debugging + uint8_t val1 = *value; - // Read from the guest cartridge. - m_cartridge->readz(offset, value); - if (val1 != *value) - LOGMASKED(LOG_GKRACKER, "Read (from guest) %04x -> %02x\n", offset, *value); - } + // Read from the guest cartridge. + m_cartridge->readz(offset, value); + if (val1 != *value) + LOGMASKED(LOG_GKRACKER, "Read (from guest) %04x -> %02x\n", offset, *value); } void ti99_gkracker_device::write(offs_t offset, uint8_t data) { // write to the guest cartridge if present - if (m_cartridge != nullptr) - { - m_cartridge->write(offset, data); - } + m_cartridge->write(offset, data); if (m_grom_selected) { @@ -310,14 +301,12 @@ void ti99_gkracker_device::write(offs_t offset, uint8_t data) void ti99_gkracker_device::crureadz(offs_t offset, uint8_t *value) { - if (m_cartridge != nullptr) - m_cartridge->crureadz(offset, value); + m_cartridge->crureadz(offset, value); } void ti99_gkracker_device::cruwrite(offs_t offset, uint8_t data) { - if (m_cartridge != nullptr) - m_cartridge->cruwrite(offset, data); + m_cartridge->cruwrite(offset, data); } INPUT_CHANGED_MEMBER( ti99_gkracker_device::gk_changed ) @@ -326,21 +315,6 @@ INPUT_CHANGED_MEMBER( ti99_gkracker_device::gk_changed ) m_gk_switch[param & 0x07] = newval; } -void ti99_gkracker_device::insert(int index, ti99_cartridge_device* cart) -{ - LOGMASKED(LOG_CHANGE, "Insert cartridge\n"); - m_cartridge = cart; - // Switch 1 has a third location for resetting. We do the reset by default - // here. It can be turned off in the configuration. - m_gromport->cartridge_inserted(); -} - -void ti99_gkracker_device::remove(int index) -{ - LOGMASKED(LOG_CHANGE, "Remove cartridge\n"); - m_cartridge = nullptr; -} - void ti99_gkracker_device::gk_install_menu(const char* menutext, int len, int ptr, int next, int start) { const int base = 0x0000; @@ -406,7 +380,8 @@ void ti99_gkracker_device::device_start() { m_ram_ptr = memregion(GKRACKER_NVRAM_TAG)->base(); m_grom_ptr = memregion(GKRACKER_ROM_TAG)->base(); - m_cartridge = nullptr; + m_cartridge->set_connector(this); + for (int i=1; i < 6; i++) m_gk_switch[i] = 0; save_pointer(NAME(m_gk_switch),6); save_item(NAME(m_romspace_selected)); @@ -444,7 +419,7 @@ const tiny_rom_entry *ti99_gkracker_device::device_rom_region() const void ti99_gkracker_device::device_add_mconfig(machine_config &config) { - TI99_CART(config, "cartridge", 0); + TI99_CART(config, m_cartridge, 0); } INPUT_PORTS_START(gkracker) diff --git a/src/devices/bus/ti99/gromport/gkracker.h b/src/devices/bus/ti99/gromport/gkracker.h index a163baffd8a..79efe94544c 100644 --- a/src/devices/bus/ti99/gromport/gkracker.h +++ b/src/devices/bus/ti99/gromport/gkracker.h @@ -26,8 +26,6 @@ class ti99_gkracker_device : public cartridge_connector_device, public device_nv void set_gromlines(line_state mline, line_state moline, line_state gsq) override; void gclock_in(int state) override; - void insert(int index, ti99_cartridge_device* cart) override; - void remove(int index) override; DECLARE_INPUT_CHANGED_MEMBER( gk_changed ); // We may have a cartridge plugged into the GK @@ -57,7 +55,7 @@ class ti99_gkracker_device : public cartridge_connector_device, public device_nv bool m_waddr_LSB; - ti99_cartridge_device *m_cartridge; // guest cartridge + required_device m_cartridge; // Just for proper initialization void gk_install_menu(const char* menutext, int len, int ptr, int next, int start); diff --git a/src/devices/bus/ti99/gromport/gromport.cpp b/src/devices/bus/ti99/gromport/gromport.cpp index a317fcb998e..6204c9b5af1 100644 --- a/src/devices/bus/ti99/gromport/gromport.cpp +++ b/src/devices/bus/ti99/gromport/gromport.cpp @@ -205,8 +205,9 @@ void gromport_device::set_gromlines(line_state mline, line_state moline, line_st void gromport_device::device_start() { - save_item(NAME(m_romgq)); + if (m_connector != nullptr) + m_connector->set_port(this); } void gromport_device::device_reset() @@ -281,12 +282,6 @@ void cartridge_connector_device::ready_line(int state) m_gromport->ready_line(state); } -void cartridge_connector_device::device_config_complete() -{ - m_gromport = dynamic_cast(owner()); - // owner is the empty_state during -listxml, so this will be nullptr -} - } // end namespace bus::ti99::gromport void ti99_gromport_options(device_slot_interface &device) diff --git a/src/devices/bus/ti99/gromport/gromport.h b/src/devices/bus/ti99/gromport/gromport.h index 724885f3ec4..10c339e9128 100644 --- a/src/devices/bus/ti99/gromport/gromport.h +++ b/src/devices/bus/ti99/gromport/gromport.h @@ -59,10 +59,10 @@ class gromport_device : public device_t, public device_single_card_slot_interfac gromport_device& extend() { m_mask = 0x3fff; return *this; } protected: - void device_start() override; - void device_reset() override; - void device_config_complete() override; - ioport_constructor device_input_ports() const override; + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_config_complete() override; + virtual ioport_constructor device_input_ports() const override; private: cartridge_connector_device* m_connector; @@ -75,6 +75,8 @@ class gromport_device : public device_t, public device_single_card_slot_interfac class cartridge_connector_device : public device_t { + friend class gromport_device; + public: virtual void readz(offs_t offset, uint8_t *value) = 0; virtual void write(offs_t offset, uint8_t data) = 0; @@ -90,16 +92,17 @@ class cartridge_connector_device : public device_t void ready_line(int state); - virtual void insert(int index, bus::ti99::gromport::ti99_cartridge_device* cart) { m_gromport->cartridge_inserted(); } - virtual void remove(int index) { } + virtual void insert() { m_gromport->cartridge_inserted(); } + virtual void remove() { } virtual bool is_grom_idle() = 0; protected: cartridge_connector_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - virtual void device_config_complete() override; gromport_device* m_gromport; bool m_grom_selected; + + void set_port(gromport_device* gromport) { m_gromport = gromport; } }; } // end namespace bus::ti99::gromport diff --git a/src/devices/bus/ti99/gromport/multiconn.cpp b/src/devices/bus/ti99/gromport/multiconn.cpp index 4c6b434187b..415fc7c3873 100644 --- a/src/devices/bus/ti99/gromport/multiconn.cpp +++ b/src/devices/bus/ti99/gromport/multiconn.cpp @@ -59,7 +59,8 @@ ti99_multi_cart_conn_device::ti99_multi_cart_conn_device(const machine_config &m : cartridge_connector_device(mconfig, TI99_GROMPORT_MULTI, tag, owner, clock), m_active_slot(0), m_fixed_slot(0), - m_next_free_slot(0) + m_next_free_slot(0), + m_cart(*this, "%u", 1) { } @@ -124,31 +125,13 @@ int ti99_multi_cart_conn_device::get_active_slot(bool changebase, offs_t offset) return slot; } -void ti99_multi_cart_conn_device::insert(int index, ti99_cartridge_device* cart) -{ - LOGMASKED(LOG_CHANGE, "Insert slot %d\n", index); - m_cartridge[index] = cart; - m_gromport->cartridge_inserted(); -} - -void ti99_multi_cart_conn_device::remove(int index) -{ - LOGMASKED(LOG_CHANGE, "Remove slot %d\n", index); - m_cartridge[index] = nullptr; -} - void ti99_multi_cart_conn_device::romgq_line(int state) { m_readrom = state; // Propagate to all slots - for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) - { - if (m_cartridge[i] != nullptr) - { - m_cartridge[i]->romgq_line(state); - } - } + for (auto &cart : m_cart) + cart->romgq_line(state); } /* @@ -159,26 +142,14 @@ void ti99_multi_cart_conn_device::set_gromlines(line_state mline, line_state mol // GROM selected? m_grom_selected = (gsq == ASSERT_LINE); - // Propagate to all slots - for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) - { - if (m_cartridge[i] != nullptr) - { - m_cartridge[i]->set_gromlines(mline, moline, gsq); - } - } + for (auto &cart : m_cart) + cart->set_gromlines(mline, moline, gsq); } void ti99_multi_cart_conn_device::gclock_in(int state) { - // Propagate to all slots - for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) - { - if (m_cartridge[i] != nullptr) - { - m_cartridge[i]->gclock_in(state); - } - } + for (auto &cart : m_cart) + cart->gclock_in(state); } void ti99_multi_cart_conn_device::readz(offs_t offset, uint8_t *value) @@ -192,23 +163,16 @@ void ti99_multi_cart_conn_device::readz(offs_t offset, uint8_t *value) { for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) { - if (m_cartridge[i] != nullptr) - { - uint8_t newval = *value; - m_cartridge[i]->readz(offset, &newval); - if (i==slot) - { - *value = newval; - } - } + uint8_t newval = *value; + m_cart[i]->readz(offset, &newval); + if (i==slot) + *value = newval; } } else { - if (slot < NUMBER_OF_CARTRIDGE_SLOTS && m_cartridge[slot] != nullptr) - { - m_cartridge[slot]->readz(offset, value); - } + if (slot < NUMBER_OF_CARTRIDGE_SLOTS) + m_cart[slot]->readz(offset, value); } } @@ -218,50 +182,32 @@ void ti99_multi_cart_conn_device::write(offs_t offset, uint8_t data) // We don't have GRAM cartridges, anyway, so it's just used for setting the address. if (m_grom_selected) { - for (auto & elem : m_cartridge) - { - if (elem != nullptr) - { - elem->write(offset, data); - } - } + for (auto &cart : m_cart) + cart->write(offset, data); } else { int slot = get_active_slot(true, offset); - if (slot < NUMBER_OF_CARTRIDGE_SLOTS && m_cartridge[slot] != nullptr) - { + if (slot < NUMBER_OF_CARTRIDGE_SLOTS) // logerror("writing %04x (slot %d) <- %02x\n", offset, slot, data); - m_cartridge[slot]->write(offset, data); - } + m_cart[slot]->write(offset, data); } } void ti99_multi_cart_conn_device::crureadz(offs_t offset, uint8_t *value) { int slot = get_active_slot(false, offset); - /* Sanity check. Higher slots are always empty. */ - if (slot >= NUMBER_OF_CARTRIDGE_SLOTS) - return; - - if (m_cartridge[slot] != nullptr) - { - m_cartridge[slot]->crureadz(offset, value); - } + // Sanity check. Higher slots are always empty. + if (slot < NUMBER_OF_CARTRIDGE_SLOTS) + m_cart[slot]->crureadz(offset, value); } void ti99_multi_cart_conn_device::cruwrite(offs_t offset, uint8_t data) { int slot = get_active_slot(false, offset); - /* Sanity check. Higher slots are always empty. */ - if (slot >= NUMBER_OF_CARTRIDGE_SLOTS) - return; - - if (m_cartridge[slot] != nullptr) - { - m_cartridge[slot]->cruwrite(offset, data); - } + if (slot < NUMBER_OF_CARTRIDGE_SLOTS) + m_cart[slot]->cruwrite(offset, data); } /* @@ -270,12 +216,9 @@ void ti99_multi_cart_conn_device::cruwrite(offs_t offset, uint8_t data) */ bool ti99_multi_cart_conn_device::is_grom_idle() { - /* Sanity check. Higher slots are always empty. */ - if (m_active_slot >= NUMBER_OF_CARTRIDGE_SLOTS) - return false; - - if (m_cartridge[m_active_slot] != nullptr) - return m_cartridge[m_active_slot]->is_grom_idle(); + // Sanity check. Higher slots are always empty. + if (m_active_slot < NUMBER_OF_CARTRIDGE_SLOTS) + return m_cart[m_active_slot]->is_grom_idle(); return false; } @@ -284,14 +227,14 @@ void ti99_multi_cart_conn_device::device_start() { m_next_free_slot = 0; m_active_slot = 0; - for (auto & elem : m_cartridge) - { - elem = nullptr; - } + save_item(NAME(m_readrom)); save_item(NAME(m_active_slot)); save_item(NAME(m_fixed_slot)); save_item(NAME(m_next_free_slot)); + + for (auto &cart : m_cart) + cart->set_connector(this); } void ti99_multi_cart_conn_device::device_reset(void) @@ -303,10 +246,8 @@ void ti99_multi_cart_conn_device::device_reset(void) void ti99_multi_cart_conn_device::device_add_mconfig(machine_config &config) { - TI99_CART(config, "cartridge1", 0); - TI99_CART(config, "cartridge2", 0); - TI99_CART(config, "cartridge3", 0); - TI99_CART(config, "cartridge4", 0); + for (int i=0; i < NUMBER_OF_CARTRIDGE_SLOTS; i++) + TI99_CART(config, m_cart[i], 0); } INPUT_CHANGED_MEMBER( ti99_multi_cart_conn_device::switch_changed ) diff --git a/src/devices/bus/ti99/gromport/multiconn.h b/src/devices/bus/ti99/gromport/multiconn.h index fd4af556f8f..1767461b82f 100644 --- a/src/devices/bus/ti99/gromport/multiconn.h +++ b/src/devices/bus/ti99/gromport/multiconn.h @@ -30,26 +30,24 @@ class ti99_multi_cart_conn_device : public cartridge_connector_device void set_gromlines(line_state mline, line_state moline, line_state gsq) override; void gclock_in(int state) override; - void insert(int index, ti99_cartridge_device* cart) override; - void remove(int index) override; DECLARE_INPUT_CHANGED_MEMBER( switch_changed ); bool is_grom_idle() override; protected: - static constexpr unsigned NUMBER_OF_CARTRIDGE_SLOTS = 4; - virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; virtual ioport_constructor device_input_ports() const override; private: + static constexpr unsigned NUMBER_OF_CARTRIDGE_SLOTS = 4; bool m_readrom; int m_active_slot; int m_fixed_slot; int m_next_free_slot; - ti99_cartridge_device* m_cartridge[NUMBER_OF_CARTRIDGE_SLOTS]; + + required_device_array m_cart; void set_slot(int slotnumber); int get_active_slot(bool changebase, offs_t offset); diff --git a/src/devices/bus/ti99/gromport/singleconn.cpp b/src/devices/bus/ti99/gromport/singleconn.cpp index 35469762a65..d5b1b8a897e 100644 --- a/src/devices/bus/ti99/gromport/singleconn.cpp +++ b/src/devices/bus/ti99/gromport/singleconn.cpp @@ -15,7 +15,7 @@ namespace bus::ti99::gromport { ti99_single_cart_conn_device::ti99_single_cart_conn_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cartridge_connector_device(mconfig, TI99_GROMPORT_SINGLE, tag, owner, clock), - m_cartridge(nullptr) + m_cartridge(*this, "cartridge") { } @@ -73,19 +73,10 @@ bool ti99_single_cart_conn_device::is_grom_idle() return m_cartridge->is_grom_idle(); } -void ti99_single_cart_conn_device::device_start() -{ - m_cartridge = static_cast(subdevices().first()); -} - -void ti99_single_cart_conn_device::device_reset() -{ - m_cartridge->set_slot(0); -} - void ti99_single_cart_conn_device::device_add_mconfig(machine_config &config) { - TI99_CART(config, "cartridge", 0); + TI99_CART(config, m_cartridge, 0); + m_cartridge->set_connector(this); } } // end namespace bus::ti99::gromport diff --git a/src/devices/bus/ti99/gromport/singleconn.h b/src/devices/bus/ti99/gromport/singleconn.h index 6cf9d09240c..c368e37683c 100644 --- a/src/devices/bus/ti99/gromport/singleconn.h +++ b/src/devices/bus/ti99/gromport/singleconn.h @@ -29,12 +29,11 @@ class ti99_single_cart_conn_device : public cartridge_connector_device bool is_grom_idle() override; protected: - virtual void device_start() override; - virtual void device_reset() override; + virtual void device_start() override { }; virtual void device_add_mconfig(machine_config &config) override; private: - ti99_cartridge_device *m_cartridge; + required_device m_cartridge; }; } // end namespace bus::ti99::gromport diff --git a/src/devices/bus/ti99/internal/992board.cpp b/src/devices/bus/ti99/internal/992board.cpp index a2222b36c3a..23274d08291 100644 --- a/src/devices/bus/ti99/internal/992board.cpp +++ b/src/devices/bus/ti99/internal/992board.cpp @@ -591,7 +591,7 @@ ioport_constructor io992_device::device_input_ports() const ti992_expport_device::ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, TI992_EXPPORT, tag, owner, clock), - device_slot_interface(mconfig, *this), + device_single_card_slot_interface(mconfig, *this), m_connected(nullptr) { } @@ -610,7 +610,7 @@ void ti992_expport_device::write(offs_t offset, uint8_t data) void ti992_expport_device::device_config_complete() { - m_connected = static_cast(subdevices().first()); + m_connected = get_card_device(); } /* diff --git a/src/devices/bus/ti99/internal/992board.h b/src/devices/bus/ti99/internal/992board.h index ec345ebce0a..41c198a8e5d 100644 --- a/src/devices/bus/ti99/internal/992board.h +++ b/src/devices/bus/ti99/internal/992board.h @@ -174,10 +174,8 @@ class ti992_expport_attached_device : public device_t virtual void write(offs_t offset, uint8_t data) { } }; -class ti992_expport_device : public device_t, public device_slot_interface +class ti992_expport_device : public device_t, public device_single_card_slot_interface { - friend class expport_attached_device; - public: template ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, U &&opts, const char *dflt) diff --git a/src/devices/bus/ti99/internal/ioport.h b/src/devices/bus/ti99/internal/ioport.h index cf38f6f2540..29ac6fb7fc4 100644 --- a/src/devices/bus/ti99/internal/ioport.h +++ b/src/devices/bus/ti99/internal/ioport.h @@ -86,8 +86,8 @@ class ioport_device : public device_t, public device_single_card_slot_interface< auto ready_cb() { return m_console_ready.bind(); } protected: - void device_start() override; - void device_config_complete() override; + virtual void device_start() override; + virtual void device_config_complete() override; // Methods called back from the external device devcb_write_line m_console_extint; // EXTINT line diff --git a/src/devices/bus/ti99/joyport/joyport.h b/src/devices/bus/ti99/joyport/joyport.h index 40f7b358ac6..b377e6ce7c1 100644 --- a/src/devices/bus/ti99/joyport/joyport.h +++ b/src/devices/bus/ti99/joyport/joyport.h @@ -76,8 +76,8 @@ class joyport_device : public device_t, public device_single_card_slot_interface auto int_cb() { return m_interrupt.bind(); } protected: - void device_start() override; - void device_config_complete() override; + virtual void device_start() override; + virtual void device_config_complete() override; private: devcb_write_line m_interrupt; diff --git a/src/devices/bus/ti99/peb/bwg.cpp b/src/devices/bus/ti99/peb/bwg.cpp index 4787df88964..3f6d21a293b 100644 --- a/src/devices/bus/ti99/peb/bwg.cpp +++ b/src/devices/bus/ti99/peb/bwg.cpp @@ -60,7 +60,7 @@ #define LOG_MOTOR (1U << 8) // Show motor operations #define LOG_CONFIG (1U << 9) // Configuration -#define VERBOSE (LOG_CONFIG | LOG_WARN) +#define VERBOSE (LOG_GENERAL | LOG_CONFIG | LOG_WARN) #include "logmacro.h" DEFINE_DEVICE_TYPE(TI99_BWG, bus::ti99::peb::snug_bwg_device, "ti99_bwg", "SNUG BwG Floppy Controller") @@ -94,6 +94,7 @@ snug_bwg_device::snug_bwg_device(const machine_config &mconfig, const char *tag, m_address(0), m_dsrrom(nullptr), m_buffer_ram(*this, BUFFER), + m_floppy(*this, "%u", 0), m_sel_floppy(0), m_wd1773(*this, FDC_TAG), m_clock(*this, CLOCK_TAG), @@ -355,10 +356,10 @@ void snug_bwg_device::crureadz(offs_t offset, uint8_t *value) if ((offset & 0x00f0)==0) { // Check what drives are not connected - reply = ((m_floppy[0] != nullptr)? 0 : 0x02) // DSK1 - | ((m_floppy[1] != nullptr)? 0 : 0x04) // DSK2 - | ((m_floppy[2] != nullptr)? 0 : 0x08) // DSK3 - | ((m_floppy[3] != nullptr)? 0 : 0x01); // DSK4 + reply = ((m_floppy[0]->get_device() != nullptr)? 0 : 0x02) // DSK1 + | ((m_floppy[1]->get_device() != nullptr)? 0 : 0x04) // DSK2 + | ((m_floppy[2]->get_device() != nullptr)? 0 : 0x08) // DSK3 + | ((m_floppy[3]->get_device() != nullptr)? 0 : 0x01); // DSK4 // DIP switches for step and date/time display if (m_dip1 != 0) reply |= 0x10; @@ -463,11 +464,11 @@ void snug_bwg_device::select_drive(int n, int state) LOGMASKED(LOG_WARN, "Warning: DSK%d selected while DSK%d not yet unselected\n", n, m_sel_floppy); } - if (m_floppy[n-1] != nullptr) + if (m_floppy[n-1]->get_device() != nullptr) { m_sel_floppy = n; - m_wd1773->set_floppy(m_floppy[n-1]); - m_floppy[n-1]->ss_w(m_crulatch0_7->q7_r()); + m_wd1773->set_floppy(m_floppy[n-1]->get_device()); + m_floppy[n-1]->get_device()->ss_w(m_crulatch0_7->q7_r()); } } } @@ -478,7 +479,7 @@ void snug_bwg_device::sidsel_w(int state) if (m_sel_floppy != 0) { LOGMASKED(LOG_CRU, "Set side (bit 7) = %d on DSK%d\n", state, m_sel_floppy); - m_floppy[m_sel_floppy-1]->ss_w(m_crulatch0_7->q7_r()); + m_floppy[m_sel_floppy-1]->get_device()->ss_w(m_crulatch0_7->q7_r()); } } @@ -502,7 +503,8 @@ void snug_bwg_device::motorona_w(int state) // Set all motors for (auto & elem : m_floppy) - if (elem != nullptr) elem->mon_w((state==ASSERT_LINE)? 0 : 1); + if (elem->get_device() != nullptr) + elem->get_device()->mon_w((state==ASSERT_LINE)? 0 : 1); // The motor-on line also connects to the wait state logic operate_ready_line(); @@ -541,13 +543,13 @@ void snug_bwg_device::device_reset() m_address = 0; m_WDsel = false; m_WDsel0 = false; - - for (int i=0; i < 4; i++) + + for (auto &flop : m_floppy) { - if (m_floppy[i] != nullptr) - LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", i, m_floppy[i]->name()); + if (flop->get_device() != nullptr) + LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", flop->basetag(), flop->get_device()->name()); else - LOGMASKED(LOG_CONFIG, "Connector %d has no floppy attached\n", i); + LOGMASKED(LOG_CONFIG, "Connector %d has no floppy attached\n", flop->basetag()); } m_wd1773->set_floppy(nullptr); @@ -557,18 +559,6 @@ void snug_bwg_device::device_reset() m_dip34 = ioport("BWGDIP34")->read(); } -void snug_bwg_device::device_config_complete() -{ - for (auto & elem : m_floppy) - elem = nullptr; - - // Seems to be null when doing a "-listslots" - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); - if (subdevice("3")!=nullptr) m_floppy[3] = static_cast(subdevice("3")->subdevices().first()); -} - INPUT_PORTS_START( bwg_fdc ) PORT_START( "BWGDIP1" ) PORT_DIPNAME( 0x01, 0x00, "BwG step rate" ) @@ -615,10 +605,10 @@ void snug_bwg_device::device_add_mconfig(machine_config& config) MM58274C(config, CLOCK_TAG, 32.768_kHz_XTAL).set_mode_and_day(1, 0); // 24h, sunday - FLOPPY_CONNECTOR(config, "0", bwg_floppies, "525dd", snug_bwg_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "1", bwg_floppies, "525dd", snug_bwg_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "2", bwg_floppies, nullptr, snug_bwg_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "3", bwg_floppies, nullptr, snug_bwg_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[0], bwg_floppies, "525dd", snug_bwg_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], bwg_floppies, "525dd", snug_bwg_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[2], bwg_floppies, nullptr, snug_bwg_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[3], bwg_floppies, nullptr, snug_bwg_device::floppy_formats).enable_sound(true); RAM(config, BUFFER).set_default_size("2K").set_default_value(0); diff --git a/src/devices/bus/ti99/peb/bwg.h b/src/devices/bus/ti99/peb/bwg.h index 752eb3aff65..4739c09c175 100644 --- a/src/devices/bus/ti99/peb/bwg.h +++ b/src/devices/bus/ti99/peb/bwg.h @@ -39,13 +39,12 @@ class snug_bwg_device : public device_t, public device_ti99_peribox_card_interfa void cruwrite(offs_t offset, uint8_t data) override; protected: - void device_start() override; - void device_reset() override; - void device_config_complete() override; + virtual void device_start() override; + virtual void device_reset() override; - const tiny_rom_entry *device_rom_region() const override; + virtual const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; - ioport_constructor device_input_ports() const override; + virtual ioport_constructor device_input_ports() const override; private: static void floppy_formats(format_registration &fr); @@ -113,7 +112,7 @@ class snug_bwg_device : public device_t, public device_ti99_peribox_card_interfa required_device m_buffer_ram; // Link to the attached floppy drives - floppy_image_device* m_floppy[4]; + required_device_array m_floppy; // Currently selected floppy drive (1-4, 0=none) int m_sel_floppy; diff --git a/src/devices/bus/ti99/peb/cc_fdc.cpp b/src/devices/bus/ti99/peb/cc_fdc.cpp index 2fe2a74b3a0..88fa46d2aa3 100644 --- a/src/devices/bus/ti99/peb/cc_fdc.cpp +++ b/src/devices/bus/ti99/peb/cc_fdc.cpp @@ -72,12 +72,13 @@ namespace bus::ti99::peb { // ---------------------------------- -corcomp_fdc_device::corcomp_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock): +corcomp_fdc_device::corcomp_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const char *dpname, const char *cpname): device_t(mconfig, type, tag, owner, clock), device_ti99_peribox_card_interface(mconfig, *this), m_wdc(*this, WDC_TAG), - m_decpal(nullptr), - m_ctrlpal(nullptr), + m_decpal(*this, dpname), + m_ctrlpal(*this, cpname), + m_floppy(*this, "%u", 0), m_motormf(*this, MOTORMF_TAG), m_tms9901(*this, TMS9901_TAG), m_buffer_ram(*this, BUFFER), @@ -363,10 +364,10 @@ void corcomp_fdc_device::select_dsk(int state) } LOGMASKED(LOG_DRIVE, "Select drive DSK%d\n", m_selected_drive); - if (m_floppy[m_selected_drive-1] != nullptr) + if (m_floppy[m_selected_drive-1]->get_device() != nullptr) { - m_wdc->set_floppy(m_floppy[m_selected_drive-1]); - m_floppy[m_selected_drive-1]->ss_w(m_tms9901->read_bit(tms9901_device::INT15_P7)); + m_wdc->set_floppy(m_floppy[m_selected_drive-1]->get_device()); + m_floppy[m_selected_drive-1]->get_device()->ss_w(m_tms9901->read_bit(tms9901_device::INT15_P7)); } } } @@ -377,7 +378,7 @@ void corcomp_fdc_device::side_select(int state) if (m_selected_drive != 0) { LOGMASKED(LOG_DRIVE, "Set side (bit 7) = %d on DSK%d\n", state, m_selected_drive); - m_floppy[m_selected_drive-1]->ss_w(state); + m_floppy[m_selected_drive-1]->get_device()->ss_w(state); } } @@ -390,8 +391,10 @@ void corcomp_fdc_device::motor_w(int state) m_wdc->set_force_ready(state==ASSERT_LINE); // Set all motors - for (auto & elem : m_floppy) - if (elem != nullptr) elem->mon_w((state==ASSERT_LINE)? 0 : 1); + for (auto &elem : m_floppy) + if (elem->get_device() != nullptr) + elem->get_device()->mon_w((state==ASSERT_LINE)? 0 : 1); + operate_ready_line(); } @@ -426,24 +429,17 @@ void corcomp_fdc_device::device_start() void corcomp_fdc_device::device_reset() { - for (int i=0; i < 4; i++) + for (auto &flop : m_floppy) { - if (m_floppy[i] != nullptr) - LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", i, m_floppy[i]->name()); + if (flop->get_device() != nullptr) + LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", flop->basetag(), flop->get_device()->name()); else - LOGMASKED(LOG_CONFIG, "Connector %d has no floppy attached\n", i); + LOGMASKED(LOG_CONFIG, "Connector %d has no floppy attached\n", flop->basetag()); } -} - -void corcomp_fdc_device::connect_drives() -{ - for (auto & elem : m_floppy) - elem = nullptr; - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); - if (subdevice("3")!=nullptr) m_floppy[3] = static_cast(subdevice("3")->subdevices().first()); + m_decpal->set_board(this); + m_ctrlpal->set_board(this); + m_ctrlpal->set_decoder(m_decpal); } INPUT_PORTS_START( cc_fdc ) @@ -528,10 +524,10 @@ void corcomp_fdc_device::common_config(machine_config& config) m_motormf->set_clear_pin_value(1); m_motormf->out_cb().set(FUNC(corcomp_fdc_device::motor_w)); - FLOPPY_CONNECTOR(config, "0", ccfdc_floppies, "525dd", corcomp_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "1", ccfdc_floppies, "525dd", corcomp_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "2", ccfdc_floppies, nullptr, corcomp_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "3", ccfdc_floppies, nullptr, corcomp_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[0], ccfdc_floppies, "525dd", corcomp_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], ccfdc_floppies, "525dd", corcomp_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[2], ccfdc_floppies, nullptr, corcomp_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[3], ccfdc_floppies, nullptr, corcomp_fdc_device::floppy_formats).enable_sound(true); // SRAM 2114 1Kx4 RAM(config, BUFFER).set_default_size("1k").set_default_value(0); @@ -542,7 +538,7 @@ void corcomp_fdc_device::common_config(machine_config& config) // ============================================================================ corcomp_dcc_device::corcomp_dcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock): - corcomp_fdc_device(mconfig, TI99_CCDCC, tag, owner, clock) + corcomp_fdc_device(mconfig, TI99_CCDCC, tag, owner, clock, CCDCC_PALU2_TAG, CCDCC_PALU1_TAG) { } @@ -565,14 +561,6 @@ ROM_START( cc_dcc ) ROM_LOAD("ccdcc_v89.u4", 0x2000, 0x2000, CRC(9c4e5c08) SHA1(26f8096ae60f3839902b4e8764c5fde283ad4ba2)) /* 8K single ROM bank 2*/ ROM_END -void corcomp_dcc_device::device_config_complete() -{ - m_decpal = dynamic_cast(subdevice(CCDCC_PALU2_TAG)); - m_ctrlpal = dynamic_cast(subdevice(CCDCC_PALU1_TAG)); - if (m_decpal != nullptr) - connect_drives(); -} - ioport_constructor corcomp_fdc_device::device_input_ports() const { return INPUT_PORTS_NAME( cc_fdc ); @@ -604,12 +592,6 @@ ccfdc_sel_pal_device::ccfdc_sel_pal_device(const machine_config &mconfig, device { } -void ccfdc_dec_pal_device::device_config_complete() -{ - m_board = dynamic_cast(owner()); - // owner is the empty_state during -listxml, so this will be nullptr -} - /* Indicates 9901 addressing. */ @@ -707,19 +689,12 @@ int ccdcc_palu1_device::ready_out() return ready; } -void ccdcc_palu1_device::device_config_complete() -{ - m_board = dynamic_cast(owner()); - m_decpal = dynamic_cast(owner()->subdevice(CCDCC_PALU2_TAG)); - // owner is the empty_state during -listxml, so this will be nullptr -} - // ============================================================================ // Revised CorComp floppy disk controller card REV A // ============================================================================ corcomp_fdca_device::corcomp_fdca_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock): - corcomp_fdc_device(mconfig, TI99_CCFDC, tag, owner, clock) + corcomp_fdc_device(mconfig, TI99_CCFDC, tag, owner, clock, CCFDC_PALU12_TAG, CCFDC_PALU6_TAG) { } @@ -749,13 +724,6 @@ ROM_START( cc_fdcmg ) ROM_LOAD("ccfdc_v89mg.u2", 0x2000, 0x2000, CRC(0cad8f5b) SHA1(7744f777b51eedf614f766576bbc3f8c2c2e0042)) /* 16K single ROM */ ROM_END -void corcomp_fdca_device::device_config_complete() -{ - m_decpal = static_cast(subdevice(CCFDC_PALU12_TAG)); - m_ctrlpal = static_cast(subdevice(CCFDC_PALU6_TAG)); - connect_drives(); -} - const tiny_rom_entry *corcomp_fdca_device::device_rom_region() const { return ROM_NAME( cc_fdcmg ); @@ -816,7 +784,12 @@ int ccfdc_palu6_device::ready_out() { bool wdc = m_decpal->addresswdc(); // Addressing the WDC bool even = (m_board->get_address()&1)==0; // A15 = 0 - bool trap = static_cast(m_board)->ready_trap_active(); // READY trap active + bool trap = false; + + // The PAL u6 is only used on the Rev A board + corcomp_fdca_device* boarda = static_cast(m_board); + trap = boarda->ready_trap_active(); // READY trap active + bool waitbyte = m_wdc->drq_r()==CLEAR_LINE; // We are waiting for a byte bool noterm = m_wdc->intrq_r()==CLEAR_LINE; // There is no interrupt yet @@ -826,10 +799,4 @@ int ccfdc_palu6_device::ready_out() return ready; } -void ccfdc_palu6_device::device_config_complete() -{ - m_board = dynamic_cast(owner()); - m_decpal = dynamic_cast(owner()->subdevice(CCFDC_PALU12_TAG)); -} - } // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/peb/cc_fdc.h b/src/devices/bus/ti99/peb/cc_fdc.h index b668f2cc59d..736b8c0ae14 100644 --- a/src/devices/bus/ti99/peb/cc_fdc.h +++ b/src/devices/bus/ti99/peb/cc_fdc.h @@ -57,14 +57,13 @@ class corcomp_fdc_device : public device_t, public device_ti99_peribox_card_inte void select_bank(int state); protected: - corcomp_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + corcomp_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, const char *dpname, const char *cpname); - void device_start() override; - void device_reset() override; - void connect_drives(); + virtual void device_start() override; + virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override =0; - ioport_constructor device_input_ports() const override; + virtual ioport_constructor device_input_ports() const override; void common_config(machine_config& config); @@ -74,8 +73,8 @@ class corcomp_fdc_device : public device_t, public device_ti99_peribox_card_inte required_device m_wdc; // PALs - ccfdc_dec_pal_device* m_decpal; - ccfdc_sel_pal_device* m_ctrlpal; + required_device m_decpal; + required_device m_ctrlpal; // Lines that are polled by the PAL chips bool card_selected(); @@ -90,7 +89,7 @@ class corcomp_fdc_device : public device_t, public device_ti99_peribox_card_inte void operate_ready_line(); // Link to the attached floppy drives - floppy_image_device* m_floppy[4]; + required_device_array m_floppy; // Motor monoflop required_device m_motormf; @@ -131,15 +130,15 @@ class corcomp_dcc_device : public corcomp_fdc_device { public: corcomp_dcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); -private: - void device_add_mconfig(machine_config &config) override; - void device_config_complete() override; - const tiny_rom_entry *device_rom_region() const override; +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; }; // =========== Decoder PAL circuit ================ class ccfdc_dec_pal_device : public device_t { + friend class corcomp_fdc_device; public: int addresswdc(); int address4(); @@ -150,16 +149,18 @@ class ccfdc_dec_pal_device : public device_t ccfdc_dec_pal_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); void device_start() override { } - void device_config_complete() override; corcomp_fdc_device* m_board; required_device m_tms9901; + + void set_board(corcomp_fdc_device* board) { m_board = board; } }; // =========== Selector PAL circuit ================ class ccfdc_sel_pal_device : public device_t { + friend class corcomp_fdc_device; public: int selectram(); virtual int selectwdc(); @@ -169,14 +170,16 @@ class ccfdc_sel_pal_device : public device_t protected: ccfdc_sel_pal_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - void device_start() override { } - virtual void device_config_complete() override =0; + virtual void device_start() override { } corcomp_fdc_device* m_board; ccfdc_dec_pal_device* m_decpal; required_device m_motormf; required_device m_tms9901; required_device m_wdc; + + void set_board(corcomp_fdc_device* board) { m_board = board; } + void set_decoder(ccfdc_dec_pal_device* decpal) { m_decpal = decpal; } }; // =========== Specific decoder PAL circuit of the CCDCC ================ @@ -194,9 +197,6 @@ class ccdcc_palu1_device : public ccfdc_sel_pal_device public: ccdcc_palu1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); int ready_out() override; - -private: - void device_config_complete() override; }; // ============================================================================ @@ -209,10 +209,10 @@ class corcomp_fdca_device : public corcomp_fdc_device public: corcomp_fdca_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; private: - void device_add_mconfig(machine_config &config) override; - void device_config_complete() override; - const tiny_rom_entry *device_rom_region() const override; bool ready_trap_active(); }; @@ -235,9 +235,6 @@ class ccfdc_palu6_device : public ccfdc_sel_pal_device int selectdsr() override; int ready_out() override; - -private: - void device_config_complete() override; }; } // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/peb/hfdc.cpp b/src/devices/bus/ti99/peb/hfdc.cpp index 5f67410a299..ad116788507 100644 --- a/src/devices/bus/ti99/peb/hfdc.cpp +++ b/src/devices/bus/ti99/peb/hfdc.cpp @@ -102,6 +102,8 @@ myarc_hfdc_device::myarc_hfdc_device(const machine_config &mconfig, const char * m_motor_on_timer(nullptr), m_hdc9234(*this, FDC_TAG), m_clock(*this, CLOCK_TAG), + m_floppy(*this, "f%u", 1), + m_harddisk(*this, "h%u", 1), m_current_floppy(nullptr), m_current_harddisk(nullptr), m_current_floppy_index(NONE), @@ -727,7 +729,7 @@ void myarc_hfdc_device::connect_floppy_unit(int index) LOGMASKED(LOG_LINES, "Select floppy drive DSK%d\n", index+1); // Connect new drive - m_current_floppy = m_floppy_unit[index]; + m_current_floppy = m_floppy[index]->get_device(); m_current_floppy_index = index; // We don't use the READY line of floppy drives. @@ -757,7 +759,7 @@ void myarc_hfdc_device::connect_harddisk_unit(int index) LOGMASKED(LOG_LINES, "Select hard disk WDS%d\n", index+1); // Connect new drive - m_current_harddisk = m_harddisk_unit[index]; + m_current_harddisk = m_harddisk[index]->get_device(); m_current_hd_index = index; LOGMASKED(LOG_LINES, "Connect index callback WDS%d\n", index+1); @@ -819,8 +821,8 @@ void myarc_hfdc_device::set_floppy_motors_running(bool run) } // Set all motors - for (auto & elem : m_floppy_unit) - if (elem != nullptr) elem->mon_w((run)? 0 : 1); + for (auto & elem : m_floppy) + if (elem->get_device() != nullptr) elem->get_device()->mon_w((run)? 0 : 1); } /* @@ -943,20 +945,20 @@ void myarc_hfdc_device::device_reset() m_lastval = 0; m_readyflags = 0; - for (int i=0; i < 4; i++) + for (auto &flop : m_floppy) { - if (m_floppy_unit[i] != nullptr) - LOGMASKED(LOG_CONFIG, "FD connector %d with %s\n", i+1, m_floppy_unit[i]->name()); + if (flop->get_device() != nullptr) + LOGMASKED(LOG_CONFIG, "FD connector %d with %s\n", flop->basetag(), flop->get_device()->name()); else - LOGMASKED(LOG_CONFIG, "FD connector %d has no floppy attached\n", i+1); + LOGMASKED(LOG_CONFIG, "FD connector %d has no floppy attached\n", flop->basetag()); } - for (int i=0; i < 3; i++) + for (auto &hard : m_harddisk) { - if (m_harddisk_unit[i] != nullptr) - LOGMASKED(LOG_CONFIG, "HD connector %d with %s\n", i+1, m_harddisk_unit[i]->name()); + if (hard->get_device() != nullptr) + LOGMASKED(LOG_CONFIG, "HD connector %d with %s\n", hard->basetag(), hard->get_device()->name()); else - LOGMASKED(LOG_CONFIG, "HD connector %d has no drive attached\n", i+1); + LOGMASKED(LOG_CONFIG, "HD connector %d has no floppy attached\n", hard->basetag()); } // Disconnect all units @@ -964,29 +966,6 @@ void myarc_hfdc_device::device_reset() disconnect_hard_drives(); } -void myarc_hfdc_device::device_config_complete() -{ - for (int i=0; i < 3; i++) - { - m_floppy_unit[i] = nullptr; - m_harddisk_unit[i] = nullptr; - } - m_floppy_unit[3] = nullptr; - - // Seems to be null when doing a "-listslots" - if (subdevice("f1")!=nullptr) - { - m_floppy_unit[0] = static_cast(subdevice("f1"))->get_device(); - m_floppy_unit[1] = static_cast(subdevice("f2"))->get_device(); - m_floppy_unit[2] = static_cast(subdevice("f3"))->get_device(); - m_floppy_unit[3] = static_cast(subdevice("f4"))->get_device(); - - m_harddisk_unit[0] = static_cast(subdevice("h1"))->get_device(); - m_harddisk_unit[1] = static_cast(subdevice("h2"))->get_device(); - m_harddisk_unit[2] = static_cast(subdevice("h3"))->get_device(); - } -} - /* The HFDC controller can be configured for different CRU base addresses, but DSK1-DSK4 are only available for CRU 1100. For all other addresses, @@ -1080,15 +1059,15 @@ void myarc_hfdc_device::device_add_mconfig(machine_config& config) m_hdc9234->dmaout_cb().set(FUNC(myarc_hfdc_device::write_buffer)); // First two floppy drives shall be connected by default - FLOPPY_CONNECTOR(config, "f1", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "f2", hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "f3", hfdc_floppies, nullptr, myarc_hfdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "f4", hfdc_floppies, nullptr, myarc_hfdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[0], hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], hfdc_floppies, "525dd", myarc_hfdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[2], hfdc_floppies, nullptr, myarc_hfdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[3], hfdc_floppies, nullptr, myarc_hfdc_device::floppy_formats).enable_sound(true); // Hard disks don't go without image (other than floppy drives) - MFM_HD_CONNECTOR(config, "h1", hfdc_harddisks, nullptr, MFM_BYTE, 3000, 20, MFMHD_GEN_FORMAT); - MFM_HD_CONNECTOR(config, "h2", hfdc_harddisks, nullptr, MFM_BYTE, 3000, 20, MFMHD_GEN_FORMAT); - MFM_HD_CONNECTOR(config, "h3", hfdc_harddisks, nullptr, MFM_BYTE, 3000, 20, MFMHD_GEN_FORMAT); + MFM_HD_CONNECTOR(config, m_harddisk[0], hfdc_harddisks, nullptr, MFM_BYTE, 3000, 20, MFMHD_GEN_FORMAT); + MFM_HD_CONNECTOR(config, m_harddisk[1], hfdc_harddisks, nullptr, MFM_BYTE, 3000, 20, MFMHD_GEN_FORMAT); + MFM_HD_CONNECTOR(config, m_harddisk[2], hfdc_harddisks, nullptr, MFM_BYTE, 3000, 20, MFMHD_GEN_FORMAT); MM58274C(config, CLOCK_TAG, 0).set_mode_and_day(1, 0); // 24h, sunday diff --git a/src/devices/bus/ti99/peb/hfdc.h b/src/devices/bus/ti99/peb/hfdc.h index aeff0cca3ad..a600412849a 100644 --- a/src/devices/bus/ti99/peb/hfdc.h +++ b/src/devices/bus/ti99/peb/hfdc.h @@ -44,8 +44,6 @@ class myarc_hfdc_device : public device_t, public device_ti99_peribox_card_inter virtual void cruwrite(offs_t offset, uint8_t data) override; protected: - virtual void device_config_complete() override; - virtual void device_start() override; virtual void device_reset() override; @@ -101,10 +99,10 @@ class myarc_hfdc_device : public device_t, public device_ti99_peribox_card_inter required_device m_clock; // Link to the attached floppy drives - floppy_image_device* m_floppy_unit[4]; + required_device_array m_floppy; // Link to the attached hard disks - mfm_harddisk_device* m_harddisk_unit[3]; + required_device_array m_harddisk; // Currently selected floppy drive floppy_image_device* m_current_floppy; diff --git a/src/devices/bus/ti99/peb/myarcfdc.cpp b/src/devices/bus/ti99/peb/myarcfdc.cpp index bcaacf0222e..6d96c9587c1 100644 --- a/src/devices/bus/ti99/peb/myarcfdc.cpp +++ b/src/devices/bus/ti99/peb/myarcfdc.cpp @@ -64,6 +64,7 @@ myarc_fdc_device::myarc_fdc_device(const machine_config &mconfig, const char *ta m_buffer_ram(*this, BUFFER_TAG), m_pal(*this, PAL_TAG), m_dsrrom(nullptr), + m_floppy(*this, "%u", 0), m_banksel(false), m_cardsel(false), m_selected_drive(0), @@ -274,8 +275,8 @@ void myarc_fdc_device::fdc_mon_w(int state) // Do not start the motors when no drive is selected. However, motors // can always be stopped. if (m_selected_drive != 0 || state==1) - for (int i = 0; i < 4; i++) - if (m_floppy[i] != nullptr) m_floppy[i]->mon_w(state); + for (auto &flop : m_floppy) + if (flop->get_device() != nullptr) flop->get_device()->mon_w(state); } /* @@ -299,7 +300,7 @@ void myarc_fdc_device::sidsel_w(int state) if (m_selected_drive != 0) { LOGMASKED(LOG_DRIVE, "Set side = %d on DSK%d\n", state, m_selected_drive); - m_floppy[m_selected_drive-1]->ss_w(state); + m_floppy[m_selected_drive-1]->get_device()->ss_w(state); } } @@ -335,12 +336,12 @@ void myarc_fdc_device::drivesel_w(int state) } else { - if (m_floppy[driveno-1] != nullptr) + if (m_floppy[driveno-1]->get_device() != nullptr) { m_selected_drive = driveno; LOGMASKED(LOG_DRIVE, "Select drive DSK%d\n", driveno); - m_wdc->set_floppy(m_floppy[driveno-1]); - m_floppy[driveno-1]->ss_w(m_drivelatch->q2_r()); + m_wdc->set_floppy(m_floppy[driveno-1]->get_device()); + m_floppy[driveno-1]->get_device()->ss_w(m_drivelatch->q2_r()); } } } @@ -356,23 +357,22 @@ void myarc_fdc_device::device_start() void myarc_fdc_device::device_reset() { + for (auto &flop : m_floppy) + { + if (flop->get_device() != nullptr) + LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", flop->basetag(), flop->get_device()->name()); + else + LOGMASKED(LOG_CONFIG, "Connector %d has no floppy attached\n", flop->basetag()); + } + if (ioport("CONTROLLER")->read()==0) m_wdc = m_wd1770; else m_wdc = m_wd1772; m_dec_high = (ioport("AMADECODE")->read()!=0); -} - -void myarc_fdc_device::device_config_complete() -{ - for (auto & elem : m_floppy) - elem = nullptr; - - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); - if (subdevice("3")!=nullptr) m_floppy[3] = static_cast(subdevice("3")->subdevices().first()); + + m_pal->set_board(this); } void myarc_fdc_device::floppy_formats(format_registration &fr) @@ -459,10 +459,10 @@ void myarc_fdc_device::device_add_mconfig(machine_config& config) DDCC1_PAL(config, PAL_TAG, 0); // Floppy drives - FLOPPY_CONNECTOR(config, "0", myarc_ddcc_floppies, "525dd", myarc_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "1", myarc_ddcc_floppies, "525dd", myarc_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "2", myarc_ddcc_floppies, nullptr, myarc_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "3", myarc_ddcc_floppies, nullptr, myarc_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[0], myarc_ddcc_floppies, "525dd", myarc_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], myarc_ddcc_floppies, "525dd", myarc_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[2], myarc_ddcc_floppies, nullptr, myarc_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[3], myarc_ddcc_floppies, nullptr, myarc_fdc_device::floppy_formats).enable_sound(true); } ioport_constructor myarc_fdc_device::device_input_ports() const @@ -512,10 +512,4 @@ bool ddcc1_pal_device::cs259() return ((m_board->get_address() & 0xff00)==0x1100); } -void ddcc1_pal_device::device_config_complete() -{ - m_board = dynamic_cast(owner()); - // owner is the empty_state during -listxml, so this will be nullptr -} - } // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/peb/myarcfdc.h b/src/devices/bus/ti99/peb/myarcfdc.h index 8e64b55e483..2e3bd355576 100644 --- a/src/devices/bus/ti99/peb/myarcfdc.h +++ b/src/devices/bus/ti99/peb/myarcfdc.h @@ -38,15 +38,15 @@ class myarc_fdc_device : public device_t, public device_ti99_peribox_card_interf void crureadz(offs_t offset, uint8_t *value) override; void cruwrite(offs_t offset, uint8_t data) override; -private: - void device_start() override; - void device_reset() override; - void device_config_complete() override; +protected: + virtual void device_start() override; + virtual void device_reset() override; - const tiny_rom_entry *device_rom_region() const override; - void device_add_mconfig(machine_config &config) override; - ioport_constructor device_input_ports() const override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; +private: static void floppy_formats(format_registration &fr); // Callback methods @@ -86,7 +86,7 @@ class myarc_fdc_device : public device_t, public device_ti99_peribox_card_interf uint8_t* m_dsrrom; // Link to the attached floppy drives - floppy_image_device* m_floppy[4]; + required_device_array m_floppy; // Debugger accessors void debug_read(offs_t offset, uint8_t* value); @@ -111,6 +111,8 @@ class myarc_fdc_device : public device_t, public device_ti99_peribox_card_interf // =========== Decoder PAL circuit ================ class ddcc1_pal_device : public device_t { + friend class myarc_fdc_device; + public: ddcc1_pal_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -123,9 +125,8 @@ class ddcc1_pal_device : public device_t private: void device_start() override { } - void device_config_complete() override; - myarc_fdc_device* m_board; + void set_board(myarc_fdc_device* board) { m_board = board; } }; } // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/peb/peribox.cpp b/src/devices/bus/ti99/peb/peribox.cpp index c2d9fe68d11..4df80e153d5 100644 --- a/src/devices/bus/ti99/peb/peribox.cpp +++ b/src/devices/bus/ti99/peb/peribox.cpp @@ -683,6 +683,7 @@ peribox_slot_device::peribox_slot_device(const machine_config &mconfig, const ch device_t(mconfig, TI99_PERIBOX_SLOT, tag, owner, clock), device_single_card_slot_interface(mconfig, *this), m_card(nullptr), + m_peb(nullptr), m_slotnumber(0) { } @@ -739,9 +740,9 @@ void peribox_slot_device::device_start() void peribox_slot_device::device_config_complete() { m_card = get_card_device(); - peribox_device *peb = dynamic_cast(owner()); - if (peb) - peb->set_slot_loaded(m_slotnumber, m_card ? this : nullptr); + m_peb = dynamic_cast(owner()); + if (m_peb) + m_peb->set_slot_loaded(m_slotnumber, m_card ? this : nullptr); } /* @@ -750,26 +751,26 @@ void peribox_slot_device::device_config_complete() */ void peribox_slot_device::set_inta(int state) { - peribox_device *peb = static_cast(owner()); - peb->inta_join(m_slotnumber, state); + if (m_peb) + m_peb->inta_join(m_slotnumber, state); } void peribox_slot_device::set_intb(int state) { - peribox_device *peb = static_cast(owner()); - peb->intb_join(m_slotnumber, state); + if (m_peb) + m_peb->intb_join(m_slotnumber, state); } void peribox_slot_device::lcp_line(int state) { - peribox_device *peb = static_cast(owner()); - peb->lcp_join(m_slotnumber, state); + if (m_peb) + m_peb->lcp_join(m_slotnumber, state); } void peribox_slot_device::set_ready(int state) { - peribox_device *peb = static_cast(owner()); - peb->ready_join(m_slotnumber, state); + if (m_peb) + m_peb->ready_join(m_slotnumber, state); } /***************************************************************************/ diff --git a/src/devices/bus/ti99/peb/peribox.h b/src/devices/bus/ti99/peb/peribox.h index ca0c84f2ec3..d8e19ff0e66 100644 --- a/src/devices/bus/ti99/peb/peribox.h +++ b/src/devices/bus/ti99/peb/peribox.h @@ -125,7 +125,7 @@ class peribox_sg_device : public peribox_device peribox_sg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - void device_add_mconfig(machine_config &config) override; + virtual void device_add_mconfig(machine_config &config) override; }; /* @@ -137,7 +137,7 @@ class peribox_ev_device : public peribox_device peribox_ev_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - void device_add_mconfig(machine_config &config) override; + virtual void device_add_mconfig(machine_config &config) override; }; @@ -163,7 +163,7 @@ class peribox_genmod_device : public peribox_gen_device peribox_genmod_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - void device_add_mconfig(machine_config &config) override; + virtual void device_add_mconfig(machine_config &config) override; }; /***************************************************************************** @@ -251,12 +251,13 @@ class peribox_slot_device : public device_t, public device_single_card_slot_inte void set_number(int number) { m_slotnumber = number; } protected: - void device_start() override; - void device_config_complete() override; + virtual void device_start() override; + virtual void device_config_complete() override; private: int get_index_from_tagname(); device_ti99_peribox_card_interface *m_card; + peribox_device *m_peb; int m_slotnumber; const char* card_name() { return m_card->device().tag(); } }; diff --git a/src/devices/bus/ti99/peb/scsicard.cpp b/src/devices/bus/ti99/peb/scsicard.cpp index 1299ccc45a9..4ffe141aeb7 100644 --- a/src/devices/bus/ti99/peb/scsicard.cpp +++ b/src/devices/bus/ti99/peb/scsicard.cpp @@ -375,7 +375,8 @@ void whtech_scsi_card_device::device_add_mconfig(machine_config &config) RAM(config, BUFFER).set_default_size("32K").set_default_value(0); // PLD circuit - WHTSCSI_PLD(config, PLD_TAG, 0); + WHTSCSI_PLD(config, m_pld, 0); + m_pld->set_board(this); // SCSI bus NSCSI_BUS(config, m_scsibus); @@ -695,10 +696,4 @@ void whtscsi_pld_device::update_line_states(int address, bool drq, bool irq) m_readyout = (irq || !m_dma_lock)? true : drq; } -void whtscsi_pld_device::device_config_complete() -{ - m_board = dynamic_cast(owner()); - // owner is the empty_state during -listxml, so this will be nullptr -} - } // end namespace bus::ti99::peb diff --git a/src/devices/bus/ti99/peb/scsicard.h b/src/devices/bus/ti99/peb/scsicard.h index f442f9ffde1..e41bdcc3948 100644 --- a/src/devices/bus/ti99/peb/scsicard.h +++ b/src/devices/bus/ti99/peb/scsicard.h @@ -41,13 +41,14 @@ class whtech_scsi_card_device : public device_t, public device_ti99_peribox_card void debug_read(offs_t offset, uint8_t* value); void debug_write(offs_t offset, uint8_t data); -private: - void device_start() override; - void device_reset() override; - void device_add_mconfig(machine_config &config) override; - ioport_constructor device_input_ports() const override; - const tiny_rom_entry *device_rom_region() const override; +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + virtual const tiny_rom_entry *device_rom_region() const override; +private: // SCSI card on-board SRAM (32K) required_device m_buffer_ram; @@ -93,6 +94,8 @@ class whtech_scsi_card_device : public device_t, public device_ti99_peribox_card class whtscsi_pld_device : public device_t { + friend class whtech_scsi_card_device; + public: whtscsi_pld_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -113,13 +116,14 @@ class whtscsi_pld_device : public device_t void update_line_states(int address, bool drq, bool irq); -private: - void device_start() override; - void device_reset() override; - void device_config_complete() override; +protected: + virtual void device_start() override; + virtual void device_reset() override; +private: whtech_scsi_card_device* m_board; + void set_board(whtech_scsi_card_device* board) { m_board = board; } bool busen(); // Flags diff --git a/src/devices/bus/ti99/peb/ti_fdc.cpp b/src/devices/bus/ti99/peb/ti_fdc.cpp index bca56861607..2bb69dfbca6 100644 --- a/src/devices/bus/ti99/peb/ti_fdc.cpp +++ b/src/devices/bus/ti99/peb/ti_fdc.cpp @@ -29,7 +29,7 @@ #define LOG_MOTOR (1U << 10) #define LOG_ADDRESS (1U << 11) -#define VERBOSE (LOG_CONFIG | LOG_WARN) +#define VERBOSE (LOG_GENERAL | LOG_CONFIG | LOG_WARN) #include "logmacro.h" DEFINE_DEVICE_TYPE(TI99_FDC, bus::ti99::peb::ti_fdc_device, "ti99_fdc", "TI-99 Standard DSSD Floppy Controller") @@ -56,6 +56,7 @@ ti_fdc_device::ti_fdc_device(const machine_config &mconfig, const char *tag, dev m_crulatch(*this, "crulatch"), m_motormf(*this, "motormf"), m_dsrrom(nullptr), + m_floppy(*this, "%u", 0), m_sel_floppy(0) { } @@ -255,7 +256,8 @@ void ti_fdc_device::dvena_w(int state) // Set all motors for (auto & elem : m_floppy) - if (elem != nullptr) elem->mon_w((state==ASSERT_LINE)? 0 : 1); + if (elem->get_device() != nullptr) + elem->get_device()->mon_w((state==ASSERT_LINE)? 0 : 1); // The motor-on line also connects to the wait state logic operate_ready_line(); @@ -281,7 +283,8 @@ void ti_fdc_device::sidsel_w(int state) { // Select side of disk (bit 7) LOGMASKED(LOG_CRU, "Set side (bit 7) = %d\n", state); - if (m_sel_floppy != 0) m_floppy[m_sel_floppy-1]->ss_w(state); + if (m_sel_floppy > 0) + m_floppy[m_sel_floppy-1]->get_device()->ss_w(state); } /* @@ -323,12 +326,12 @@ void ti_fdc_device::select_drive(int n, int state) { LOGMASKED(LOG_WARN, "Warning: DSK%d selected while DSK%d not yet unselected\n", n, m_sel_floppy); } - - if (m_floppy[n-1] != nullptr) + + if (m_floppy[n-1]->get_device() != nullptr) { m_sel_floppy = n; - m_fd1771->set_floppy(m_floppy[n-1]); - m_floppy[n-1]->ss_w(m_crulatch->q7_r()); + m_fd1771->set_floppy(m_floppy[n-1]->get_device()); + m_floppy[n-1]->get_device()->ss_w(m_crulatch->q7_r()); } } } @@ -357,28 +360,18 @@ void ti_fdc_device::device_reset() m_selected = false; m_inDsrArea = false; m_WDsel = false; - - for (int i=0; i < 3; i++) + + for (auto &flop : m_floppy) { - if (m_floppy[i] != nullptr) - LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", i, m_floppy[i]->name()); + if (flop->get_device() != nullptr) + LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", flop->basetag(), flop->get_device()->name()); else - LOGMASKED(LOG_CONFIG, "No floppy attached to connector %d\n", i); + LOGMASKED(LOG_CONFIG, "Connector %d has no floppy attached\n", flop->basetag()); } - + m_sel_floppy = 0; } -void ti_fdc_device::device_config_complete() -{ - // Seems to be null when doing a "-listslots" - for (auto &elem : m_floppy) - elem = nullptr; - if (subdevice("0")!=nullptr) m_floppy[0] = static_cast(subdevice("0")->subdevices().first()); - if (subdevice("1")!=nullptr) m_floppy[1] = static_cast(subdevice("1")->subdevices().first()); - if (subdevice("2")!=nullptr) m_floppy[2] = static_cast(subdevice("2")->subdevices().first()); -} - void ti_fdc_device::floppy_formats(format_registration &fr) { fr.add_mfm_containers(); @@ -404,9 +397,9 @@ void ti_fdc_device::device_add_mconfig(machine_config& config) m_fd1771->drq_wr_callback().set(FUNC(ti_fdc_device::fdc_drq_w)); m_fd1771->hld_wr_callback().set(FUNC(ti_fdc_device::fdc_hld_w)); - FLOPPY_CONNECTOR(config, "0", tifdc_floppies, "525dd", ti_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "1", tifdc_floppies, "525dd", ti_fdc_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "2", tifdc_floppies, nullptr, ti_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[0], tifdc_floppies, "525dd", ti_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], tifdc_floppies, "525dd", ti_fdc_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[2], tifdc_floppies, nullptr, ti_fdc_device::floppy_formats).enable_sound(true); LS259(config, m_crulatch); // U23 m_crulatch->q_out_cb<0>().set(FUNC(ti_fdc_device::dskpgena_w)); diff --git a/src/devices/bus/ti99/peb/ti_fdc.h b/src/devices/bus/ti99/peb/ti_fdc.h index 0de44473001..3b67295d367 100644 --- a/src/devices/bus/ti99/peb/ti_fdc.h +++ b/src/devices/bus/ti99/peb/ti_fdc.h @@ -38,11 +38,10 @@ class ti_fdc_device : public device_t, public device_ti99_peribox_card_interface // bool dvena_r(); protected: - void device_start() override; - void device_reset() override; - void device_config_complete() override; + virtual void device_start() override; + virtual void device_reset() override; - const tiny_rom_entry *device_rom_region() const override; + virtual const tiny_rom_entry *device_rom_region() const override; virtual void device_add_mconfig(machine_config &config) override; private: @@ -105,7 +104,7 @@ class ti_fdc_device : public device_t, public device_ti99_peribox_card_interface uint8_t* m_dsrrom; // Link to the attached floppy drives - floppy_image_device* m_floppy[3]; + required_device_array m_floppy; // Currently selected floppy drive int m_sel_floppy; diff --git a/src/devices/bus/ti99/peb/ti_rs232.cpp b/src/devices/bus/ti99/peb/ti_rs232.cpp index 3fe4968630c..1005029b23c 100644 --- a/src/devices/bus/ti99/peb/ti_rs232.cpp +++ b/src/devices/bus/ti99/peb/ti_rs232.cpp @@ -206,17 +206,15 @@ void ti_rs232_attached_device::call_unload() */ std::pair ti_pio_attached_device::call_load() { - ti_rs232_pio_device* card = static_cast(owner()); - // tell whether the image is readable - card->m_pio_readable = true; + m_card->m_pio_readable = true; // tell whether the image is writable - card->m_pio_writable = !is_readonly(); + m_card->m_pio_writable = !is_readonly(); - if (card->m_pio_write && card->m_pio_writable) - card->m_pio_handshakein = false; // receiver ready + if (m_card->m_pio_write && m_card->m_pio_writable) + m_card->m_pio_handshakein = false; // receiver ready else - card->m_pio_handshakein = true; + m_card->m_pio_handshakein = true; return std::make_pair(std::error_condition(), std::string()); // OK } @@ -226,11 +224,9 @@ std::pair ti_pio_attached_device::call_load() */ void ti_pio_attached_device::call_unload() { - ti_rs232_pio_device* card = static_cast(owner()); - - card->m_pio_writable = false; - card->m_pio_handshakein = true; /* receiver not ready */ - card->m_pio_sparein = false; + m_card->m_pio_writable = false; + m_card->m_pio_handshakein = true; /* receiver not ready */ + m_card->m_pio_sparein = false; } /****************************************************************************/ @@ -1108,6 +1104,7 @@ void ti_rs232_pio_device::device_add_mconfig(machine_config &config) m_serdev1->connect(m_uart1); TI99_PIO_DEV(config, m_piodev, 0); + m_piodev->set_card(this); LS259(config, m_crulatch); // U12 m_crulatch->q_out_cb<0>().set(FUNC(ti_rs232_pio_device::selected_w)); diff --git a/src/devices/bus/ti99/peb/ti_rs232.h b/src/devices/bus/ti99/peb/ti_rs232.h index c10fd7e81a4..edd20827765 100644 --- a/src/devices/bus/ti99/peb/ti_rs232.h +++ b/src/devices/bus/ti99/peb/ti_rs232.h @@ -38,12 +38,12 @@ class ti_rs232_pio_device : public device_t, public device_ti99_peribox_card_int void cruwrite(offs_t offset, uint8_t data) override; protected: - void device_start() override; - void device_reset() override; - void device_stop() override; - const tiny_rom_entry *device_rom_region() const override; - void device_add_mconfig(machine_config &config) override; - ioport_constructor device_input_ports() const override; + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_stop() override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; private: void int0_callback(int state); @@ -159,6 +159,7 @@ class ti_rs232_attached_device : public device_t, public device_image_interface */ class ti_pio_attached_device : public device_t, public device_image_interface { + friend class ti_rs232_pio_device; public: ti_pio_attached_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -176,6 +177,10 @@ class ti_pio_attached_device : public device_t, public device_image_interface void device_start() override { } std::pair call_load() override; void call_unload() override; + +private: + ti_rs232_pio_device* m_card; + void set_card(ti_rs232_pio_device* card) { m_card = card; } }; } // end namespace bus::ti99::peb diff --git a/src/devices/cpu/palm/palm.cpp b/src/devices/cpu/palm/palm.cpp index 4e7558770d6..0febe5b3793 100644 --- a/src/devices/cpu/palm/palm.cpp +++ b/src/devices/cpu/palm/palm.cpp @@ -8,7 +8,7 @@ * - IBM 5100 Maintenance Information Manual, SY31-0405-3, Fourth Edition (October 1979), International Business Machines Corporation * * TODO: - * - machine check/interrupts + * - machine check * - instruction timing */ @@ -30,6 +30,8 @@ template constexpr T IBIT(T x, U n, V w) return BIT(x, sizeof(T) * 8 - n - w, w); } +static u8 constexpr il_priority[] = { 0, 1, 2, 2, 3, 3, 3, 3 }; + DEFINE_DEVICE_TYPE(PALM, palm_device, "palm", "IBM PALM") palm_device::palm_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) @@ -38,29 +40,41 @@ palm_device::palm_device(machine_config const &mconfig, char const *tag, device_ , m_rws_config("rws", ENDIANNESS_BIG, 16, 16) , m_ioc_config("ioc", ENDIANNESS_BIG, 8, 4) , m_iod_config("iod", ENDIANNESS_BIG, 8, 4) + , m_getb_bus(*this) + , m_select_ros(*this) , m_icount(0) , m_r{} - , m_il(0) - , m_il_pending(0) - , m_irpt_req(0) { } +enum ff_mask : u8 +{ + FF_IPL = 0x80, // initial program load + FF_MSS = 0x40, // microprogram storage switch + + FF_IE = 0x08, // interrupt enable + FF_IR3 = 0x04, // interrupt request 3 + FF_IR2 = 0x02, // interrupt request 2 + FF_IR1 = 0x01, // interrupt request 1 + + FF_IR = 0x07, // interrupt request +}; + void palm_device::device_start() { set_icountptr(m_icount); - state_add(STATE_GENPC, "GENPC", m_r[m_il][0]).mask(0xfffe).noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_r[m_il][0]).mask(0xfffe); + state_add(STATE_GENPC, "GENPC", m_pc).noshow(); + state_add(STATE_GENPCBASE, "CURPC", [this]() { return m_r[m_il][0] & 0xfffeU; }); state_add(0, "IL", m_il); for (unsigned i = 0; i < std::size(m_r[m_il]); i++) - state_add(i + 1, util::string_format("R%d", i).c_str(), m_r[m_il][i]); + state_add(i + 1, util::string_format("R%d", i).c_str(), [this, i]() { return m_r[m_il][i]; }, [this, i](u16 data) { m_r[m_il][i] = data; }); + save_item(NAME(m_pc)); save_item(NAME(m_r)); save_item(NAME(m_il)); - save_item(NAME(m_il_pending)); - save_item(NAME(m_irpt_req)); + save_item(NAME(m_ff)); space(AS_ROS).specific(m_ros); space(AS_RWS).specific(m_rws); @@ -72,10 +86,13 @@ void palm_device::device_reset() { space(AS_RWS).install_ram(0, sizeof(m_r) - 1, m_r); - m_il = 0; + // select instruction source + m_ff = FF_IPL | FF_MSS; + m_select_ros((m_ff & FF_MSS) && !(m_ff & FF_IPL)); // read initial PC from ROS - m_r[m_il][0] = m_ros.read_word(0); + m_il = 0; + m_pc = m_r[m_il][0] = m_ros.read_word(0); } #define Rx r[IBIT(op, 4, 4)] @@ -88,13 +105,14 @@ void palm_device::execute_run() { while (m_icount > 0) { - // immediately switch to highest pending interrupt level - if (m_il != m_il_pending) + // handle pending interrupts + u8 const il = il_priority[m_ff & FF_IR]; + if ((m_ff & FF_IE) && m_il != il) { - m_il = m_il_pending; + m_il = il; // notify the debugger - if (m_il && machine().debug_flags & DEBUG_FLAG_ENABLED) + if (m_il && (machine().debug_flags & DEBUG_FLAG_ENABLED)) debug()->interrupt_hook(m_il - 1, m_r[m_il][0] & ~1); } @@ -133,7 +151,13 @@ void palm_device::execute_run() case 0xf: Ry += (7 - count_leading_ones_32(u32(m_iod.read_byte(DA)) << 24)) * 2; break; // get to register and add } break; - case 0x1: m_ioc.write_byte(DA, IMM); break; // control + case 0x1: + // control + if (DA == 0) + control(IMM); + + m_ioc.write_byte(DA, IMM); + break; case 0x2: Rx = m_rws.read_word(IMM * 2); break; // load halfword direct case 0x3: m_rws.write_word(IMM * 2, Rx); break; // store halfword direct case 0x4: @@ -185,6 +209,8 @@ void palm_device::execute_run() } else { + m_getb_bus(DA, Ry); + if (MOD < 0xc) { // get byte @@ -201,13 +227,12 @@ void palm_device::execute_run() // TODO: average instruction time quoted as 1.75µs (~27 machine cycles) m_icount -= 27; + m_pc = r[0]; } } void palm_device::execute_set_input(int irqline, int state) { - u8 const il_priority[] = { 0, 1, 2, 3, 3, 3, 3, 3 }; - switch (irqline) { case INPUT_LINE_NMI: @@ -217,12 +242,9 @@ void palm_device::execute_set_input(int irqline, int state) default: // interrupt lines are active low if (!state) - m_irpt_req |= 1U << irqline; + m_ff |= 1U << irqline; else - m_irpt_req &= ~(1U << irqline); - - // update pending interrupt level - m_il_pending = il_priority[m_irpt_req & 7]; + m_ff &= ~(1U << irqline); break; } } @@ -278,3 +300,31 @@ s16 palm_device::modifier(unsigned const modifier) const else return 0; } + +void palm_device::control(u8 data) +{ + LOG("control 0x%02x (%s)\n", data, machine().describe_context()); + + // 0 reset controller errors + + // 1: 0=disable interrupts + // 2: 0=enable interrupts + if (!IBIT(data, 1)) + m_ff &= ~FF_IE; + else if (!IBIT(data, 2)) + m_ff |= FF_IE; + + // TODO: 3 not used? + // 4 not used (0:display & select frame on) + + // 5 state transition + if (!IBIT(data, 5)) + { + m_ff &= ~FF_IPL; + m_ff ^= FF_MSS; + + m_select_ros((m_ff & FF_MSS) && !(m_ff & FF_IPL)); + } + + // TODO: 6..7 not used (frame bit #1,2?) +} diff --git a/src/devices/cpu/palm/palm.h b/src/devices/cpu/palm/palm.h index ff2bc0c6d08..bd1a1c15974 100644 --- a/src/devices/cpu/palm/palm.h +++ b/src/devices/cpu/palm/palm.h @@ -20,6 +20,9 @@ class palm_device : public cpu_device static unsigned constexpr AS_IOC = AS_IO; static unsigned constexpr AS_IOD = 4; + auto getb_bus() { return m_getb_bus.bind(); } + auto select_ros() { return m_select_ros.bind(); } + palm_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); protected: @@ -43,6 +46,8 @@ class palm_device : public cpu_device bool condition(unsigned const modifier, u16 const data, u8 const mask) const; s16 modifier(unsigned const modifier) const; + void control(u8 data); + private: // address spaces address_space_config const m_ros_config; @@ -55,13 +60,16 @@ class palm_device : public cpu_device memory_access<4, 0, 0, ENDIANNESS_BIG>::specific m_ioc; memory_access<4, 0, 0, ENDIANNESS_BIG>::specific m_iod; + devcb_write8 m_getb_bus; + devcb_write_line m_select_ros; + // mame state int m_icount; + u16 m_pc; u16 m_r[4][16]; // registers u8 m_il; // interrupt level - u8 m_il_pending; // pending interrupt level - u8 m_irpt_req; // interrupt line state + u8 m_ff; // controller flip-flops }; DECLARE_DEVICE_TYPE(PALM, palm_device) diff --git a/src/devices/cpu/tms9900/tms9900.cpp b/src/devices/cpu/tms9900/tms9900.cpp index 49e60c1a28b..2f5c2d413d3 100644 --- a/src/devices/cpu/tms9900/tms9900.cpp +++ b/src/devices/cpu/tms9900/tms9900.cpp @@ -1346,6 +1346,12 @@ void tms99xx_device::service_interrupt() m_reset = false; LOG("** RESET triggered\n"); + + // RESET could occur during a data derivation sequence, so we have to + // prevent the execution loop to return into that sequence by + // clearing the return index. This fixes a bug that leads to undefined + // behaviour in that situation. + m_caller_index = NOPRG; } else { diff --git a/src/devices/cpu/upd78k/upd78k2d.cpp b/src/devices/cpu/upd78k/upd78k2d.cpp index 7fcc4bd85a2..45c7fd64342 100644 --- a/src/devices/cpu/upd78k/upd78k2d.cpp +++ b/src/devices/cpu/upd78k/upd78k2d.cpp @@ -14,7 +14,7 @@ offs_t upd78k2_disassembler::dasm_01xx(std::ostream &stream, u8 op2, offs_t pc, if (op2 == 0x05) { u8 op3 = opcodes.r8(pc + 2); - if ((op3 & 0xed) == 0x89) + if ((op3 & 0xed) == 0x8c) { util::stream_format(stream, "%-8s&[%s]", BIT(op3, 4) ? "ROL4" : "ROR4", BIT(op3, 1) ? "HL" : "DE"); return 3 | SUPPORTED; @@ -127,7 +127,7 @@ offs_t upd78k2_disassembler::dasm_05xx(std::ostream &stream, u8 op2, offs_t pc, util::stream_format(stream, "%-8s%s", BIT(op2, 4) ? "CALL" : "BR", s_rp_names[(op2 & 0x06) >> 1]); return 2 | (BIT(op2, 4) ? STEP_OVER : 0) | SUPPORTED; } - else if ((op2 & 0xed) == 0x89) + else if ((op2 & 0xed) == 0x8c) { util::stream_format(stream, "%-8s[%s]", BIT(op2, 4) ? "ROL4" : "ROR4", BIT(op2, 1) ? "HL" : "DE"); return 2 | SUPPORTED; diff --git a/src/devices/machine/icd2061a.cpp b/src/devices/machine/icd2061a.cpp index 62c90f72055..1dfe44a1e06 100644 --- a/src/devices/machine/icd2061a.cpp +++ b/src/devices/machine/icd2061a.cpp @@ -24,11 +24,15 @@ #define LOG_PINS (1 << 1) #define LOG_STATE (1 << 2) +#define LOG_TODO (1 << 3) -// #define VERBOSE (LOG_GENERAL | LOG_PINS | LOG_STATE) +// #define VERBOSE (LOG_GENERAL | LOG_PINS | LOG_STATE | LOG_TODO) +#define VERBOSE (LOG_TODO) #include "logmacro.h" +#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__) + DEFINE_DEVICE_TYPE(ICD2061A, icd2061a_device, "icd2061a", "IC Designs 2061A Dual Programmable Graphics Clock Generator") @@ -168,6 +172,8 @@ TIMER_CALLBACK_MEMBER( icd2061a_device::update_clock_callback ) const int m = BIT(m_regs[MREG], 7, 3); // post-vco divisor const int q = BIT(m_regs[MREG], 0, 7) + 2; // q counter value m_reg_clocks[MREG] = (clock() * m_prescale[a] * (p / double(q))) / (1 << m); + } else { + LOGTODO("unimplemented mclkout selected %d\n", m_mclkout_select); } if (m_reg_clocks[MREG] != m_mclkout_clock) { @@ -189,18 +195,23 @@ TIMER_CALLBACK_MEMBER( icd2061a_device::update_clock_callback ) else if (m_outdis == 1 && m_pwrdwn == 1 && m_sel1 == 1 && (m_intclk == 1 || m_sel0 == 1)) m_vclkout_select = VCLKOUT_REG2; + uint32_t vclkout_clock = m_vclkout_clock; if (m_vclkout_select == VCLKOUT_FEATCLK) { - m_reg_clocks[m_vclkout_select] = m_featclock; + vclkout_clock = m_featclock; } else if (m_vclkout_select >= VCLKOUT_REG0 && m_vclkout_select <= VCLKOUT_REG2) { const int a = BIT(m_regs[m_vclkout_select], 21, 2); // register addr const int p = BIT(m_regs[m_vclkout_select], 10, 7) + 3; // p counter value const int m = BIT(m_regs[m_vclkout_select], 7, 3); // post-vco divisor const int q = BIT(m_regs[m_vclkout_select], 0, 7) + 2; // q counter value - m_reg_clocks[m_vclkout_select] = (clock() * m_prescale[a] * (p / double(q))) / (1 << m); + vclkout_clock = m_reg_clocks[m_vclkout_select] = (clock() * m_prescale[a] * (p / double(q))) / (1 << m); + } else { + LOGTODO("unimplemented vclkout selected %d\n", m_vclkout_select); } - m_vclkout_changed_cb(m_reg_clocks[m_vclkout_select]); - m_vclkout_clock = m_reg_clocks[m_vclkout_select]; + if (vclkout_clock != m_vclkout_clock) { + m_vclkout_clock = vclkout_clock; + m_vclkout_changed_cb(vclkout_clock); + } } void icd2061a_device::update_clock() diff --git a/src/devices/machine/spi_sdcard.cpp b/src/devices/machine/spi_sdcard.cpp index 4db4fc2c8f9..23296a94b33 100644 --- a/src/devices/machine/spi_sdcard.cpp +++ b/src/devices/machine/spi_sdcard.cpp @@ -327,17 +327,18 @@ void spi_sdcard_device::do_command() case 12: // CMD12 - STOP_TRANSMISSION m_data[0] = 0; - send_data(1, m_state == SD_STATE_RCV ? SD_STATE_PRG : SD_STATE_TRAN); + send_data(1, (m_state == SD_STATE_RCV) ? SD_STATE_PRG : SD_STATE_TRAN); break; case 13: // CMD13 - SEND_STATUS m_data[0] = 0; // TODO - send_data(1, SD_STATE_STBY); + m_data[1] = 0; + send_data(2, SD_STATE_STBY); break; case 16: // CMD16 - SET_BLOCKLEN m_blksize = get_u16be(&m_cmd[3]); - if (m_image->set_block_size(m_blksize)) + if (m_image->exists() && m_image->set_block_size(m_blksize)) { m_data[0] = 0; } diff --git a/src/devices/machine/z80ctc.cpp b/src/devices/machine/z80ctc.cpp index 735ea85b8e7..7f0049b28e8 100644 --- a/src/devices/machine/z80ctc.cpp +++ b/src/devices/machine/z80ctc.cpp @@ -77,12 +77,17 @@ DEFINE_DEVICE_TYPE(Z80CTC_CHANNEL, z80ctc_channel_device, "z80ctc_channel", "Z80 //------------------------------------------------- z80ctc_device::z80ctc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, Z80CTC, tag, owner, clock) + : z80ctc_device(mconfig, Z80CTC, tag, owner, clock) +{ +} + +z80ctc_device::z80ctc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) , device_z80daisy_interface(mconfig, *this) + , m_channel(*this, "ch%u", 0U) , m_intr_cb(*this) , m_zc_cb(*this) , m_vector(0) - , m_channel(*this, "ch%u", 0U) { } diff --git a/src/devices/machine/z80ctc.h b/src/devices/machine/z80ctc.h index 9f0d5aa410f..098915aceab 100644 --- a/src/devices/machine/z80ctc.h +++ b/src/devices/machine/z80ctc.h @@ -100,6 +100,8 @@ class z80ctc_device : public device_t, u16 get_channel_constant(int ch) const { return m_channel[ch]->m_tconst; } protected: + z80ctc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + // device_t implementation virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; @@ -110,20 +112,18 @@ class z80ctc_device : public device_t, virtual int z80daisy_irq_ack() override; virtual void z80daisy_irq_reti() override; -private: // internal helpers + u8 channel_int_state(int ch) const noexcept { return m_channel[ch]->m_int_state; } void interrupt_check(); z80ctc_channel_device &channel_config(int ch) { return *m_channel[ch].lookup(); } // internal state - devcb_write_line m_intr_cb; // interrupt callback - devcb_write_line::array<4> m_zc_cb; // zero crossing/timer output callbacks - - u8 m_vector; // interrupt vector + required_device_array m_channel; // subdevice for each channel + devcb_write_line m_intr_cb; // interrupt callback + devcb_write_line::array<4> m_zc_cb; // zero crossing/timer output callbacks - // subdevice for each channel - required_device_array m_channel; + u8 m_vector; // interrupt vector }; diff --git a/src/devices/machine/z80dma.cpp b/src/devices/machine/z80dma.cpp index 34c40b6183c..2e0240af8a3 100644 --- a/src/devices/machine/z80dma.cpp +++ b/src/devices/machine/z80dma.cpp @@ -45,36 +45,13 @@ enum INT_MATCH_END_OF_BLOCK }; -constexpr int COMMAND_RESET = 0xc3; -constexpr int COMMAND_RESET_PORT_A_TIMING = 0xc7; -constexpr int COMMAND_RESET_PORT_B_TIMING = 0xcb; -constexpr int COMMAND_LOAD = 0xcf; -constexpr int COMMAND_CONTINUE = 0xd3; -constexpr int COMMAND_DISABLE_INTERRUPTS = 0xaf; -constexpr int COMMAND_ENABLE_INTERRUPTS = 0xab; -constexpr int COMMAND_RESET_AND_DISABLE_INTERRUPTS = 0xa3; -constexpr int COMMAND_ENABLE_AFTER_RETI = 0xb7; -constexpr int COMMAND_READ_STATUS_BYTE = 0xbf; -constexpr int COMMAND_REINITIALIZE_STATUS_BYTE = 0x8b; -constexpr int COMMAND_INITIATE_READ_SEQUENCE = 0xa7; -constexpr int COMMAND_FORCE_READY = 0xb3; -constexpr int COMMAND_ENABLE_DMA = 0x87; -constexpr int COMMAND_DISABLE_DMA = 0x83; -constexpr int COMMAND_READ_MASK_FOLLOWS = 0xbb; - -constexpr int TM_TRANSFER = 0x01; -constexpr int TM_SEARCH = 0x02; -constexpr int TM_SEARCH_TRANSFER = 0x03; - //************************************************************************** // MACROS //************************************************************************** -#define REGNUM(_m, _s) (((_m)<<3) + (_s)) #define GET_REGNUM(_r) (&(_r) - &(WR0)) -#define REG(_m, _s) m_regs[REGNUM(_m,_s)] #define WR0 REG(0, 0) #define WR1 REG(1, 0) #define WR2 REG(2, 0) @@ -149,7 +126,12 @@ DEFINE_DEVICE_TYPE(Z80DMA, z80dma_device, "z80dma", "Z80 DMA Controller") //------------------------------------------------- z80dma_device::z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, Z80DMA, tag, owner, clock) + : z80dma_device(mconfig, Z80DMA, tag, owner, clock) +{ +} + +z80dma_device::z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) , device_z80daisy_interface(mconfig, *this) , m_out_busreq_cb(*this) , m_out_int_cb(*this) diff --git a/src/devices/machine/z80dma.h b/src/devices/machine/z80dma.h index f327b818223..7bbb91760ac 100644 --- a/src/devices/machine/z80dma.h +++ b/src/devices/machine/z80dma.h @@ -61,32 +61,67 @@ class z80dma_device : public device_t, auto out_iorq_callback() { return m_out_iorq_cb.bind(); } uint8_t read(); - void write(uint8_t data); + virtual void write(uint8_t data); void iei_w(int state) { m_iei = state; interrupt_check(); } void rdy_w(int state); void wait_w(int state); void bai_w(int state); -private: - // device-level overrides +protected: + static inline constexpr int COMMAND_RESET = 0xc3; + static inline constexpr int COMMAND_RESET_PORT_A_TIMING = 0xc7; + static inline constexpr int COMMAND_RESET_PORT_B_TIMING = 0xcb; + static inline constexpr int COMMAND_LOAD = 0xcf; + static inline constexpr int COMMAND_CONTINUE = 0xd3; + static inline constexpr int COMMAND_DISABLE_INTERRUPTS = 0xaf; + static inline constexpr int COMMAND_ENABLE_INTERRUPTS = 0xab; + static inline constexpr int COMMAND_RESET_AND_DISABLE_INTERRUPTS = 0xa3; + static inline constexpr int COMMAND_ENABLE_AFTER_RETI = 0xb7; + static inline constexpr int COMMAND_READ_STATUS_BYTE = 0xbf; + static inline constexpr int COMMAND_REINITIALIZE_STATUS_BYTE = 0x8b; + static inline constexpr int COMMAND_INITIATE_READ_SEQUENCE = 0xa7; + static inline constexpr int COMMAND_FORCE_READY = 0xb3; + static inline constexpr int COMMAND_ENABLE_DMA = 0x87; + static inline constexpr int COMMAND_DISABLE_DMA = 0x83; + static inline constexpr int COMMAND_READ_MASK_FOLLOWS = 0xbb; + + static inline constexpr int TM_TRANSFER = 0x01; + static inline constexpr int TM_SEARCH = 0x02; + static inline constexpr int TM_SEARCH_TRANSFER = 0x03; + + z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device_t implementation virtual void device_start() override; virtual void device_reset() override; - // device_z80daisy_interface overrides - virtual int z80daisy_irq_state() override; - virtual int z80daisy_irq_ack() override; - virtual void z80daisy_irq_reti() override; - // internal helpers - int is_ready(); + bool is_dma_enabled() const noexcept { return m_dma_enabled; } + u8 num_follow() const noexcept { return m_num_follow; } + virtual int is_ready(); void interrupt_check(); void trigger_interrupt(int level); void do_read(); - void do_write(); + virtual void do_write(); void do_transfer_write(); void do_search(); + uint16_t ®(unsigned m, unsigned s) noexcept { return m_regs[REGNUM(m, s)]; } + + static constexpr unsigned REGNUM(unsigned m, unsigned s) { return (m << 3) + s; } + + uint16_t m_addressA; + uint16_t m_addressB; + uint16_t m_count; + uint16_t m_byte_counter; + +private: + // device_z80daisy_interface implementation + virtual int z80daisy_irq_state() override; + virtual int z80daisy_irq_ack() override; + virtual void z80daisy_irq_reti() override; + TIMER_CALLBACK_MEMBER(timerproc); void update_status(); @@ -105,7 +140,7 @@ class z80dma_device : public device_t, emu_timer *m_timer; - uint16_t m_regs[(6<<3)+1+1]; + uint16_t m_regs[(6 << 3) + 1 + 1]; uint8_t m_num_follow; uint8_t m_cur_follow; uint8_t m_regs_follow[5]; @@ -115,11 +150,6 @@ class z80dma_device : public device_t, uint8_t m_status; uint8_t m_dma_enabled; - uint16_t m_addressA; - uint16_t m_addressB; - uint16_t m_count; - uint16_t m_byte_counter; - int m_rdy; int m_force_ready; uint8_t m_reset_pointer; @@ -133,7 +163,7 @@ class z80dma_device : public device_t, int m_iei; // interrupt enable input int m_ip; // interrupt pending int m_ius; // interrupt under service - uint8_t m_vector; // interrupt vector + uint8_t m_vector; // interrupt vector }; diff --git a/src/devices/video/crt9007.cpp b/src/devices/video/crt9007.cpp index eac1717e41a..6bbafceebae 100644 --- a/src/devices/video/crt9007.cpp +++ b/src/devices/video/crt9007.cpp @@ -950,3 +950,13 @@ void crt9007_device::set_character_width(unsigned value) if (started()) recompute_parameters(); } + + +//------------------------------------------------- +// cursor_active - is cursor active at location +//------------------------------------------------- + +bool crt9007_device::cursor_active(unsigned x, unsigned y) +{ + return (x == HORIZONTAL_CURSOR && y == VERTICAL_CURSOR); +} diff --git a/src/devices/video/crt9007.h b/src/devices/video/crt9007.h index 9ea8b3b9a48..369cb0b9fb6 100644 --- a/src/devices/video/crt9007.h +++ b/src/devices/video/crt9007.h @@ -71,6 +71,9 @@ class crt9007_device : public device_t, void ack_w(int state); void lpstb_w(int state); + // cursor location + bool cursor_active(unsigned x, unsigned y); + protected: // device_t implementation virtual void device_start() override; diff --git a/src/devices/video/crtc_ega.cpp b/src/devices/video/crtc_ega.cpp index 15131095fd3..3b9f8ac5d20 100644 --- a/src/devices/video/crtc_ega.cpp +++ b/src/devices/video/crtc_ega.cpp @@ -105,7 +105,7 @@ void crtc_ega_device::register_w(uint8_t data) m_vert_blank_start = ((data & 0x08) << 5) | (m_vert_blank_start & 0x00ff); m_line_compare = ((data & 0x10) << 4) | (m_line_compare & 0x00ff); break; - case 0x08: m_preset_row_scan = data & 0x1f; + case 0x08: m_preset_row_latch = data & 0x1f; break; case 0x09: m_max_ras_addr = data & 0x1f; break; @@ -272,7 +272,10 @@ void crtc_ega_device::set_vblank(int state) if (!m_irq_enable) m_res_out_irq_cb(m_vblank); if (state) + { m_disp_start_addr = m_start_addr_latch; + m_preset_row_scan = m_preset_row_latch; + } } } diff --git a/src/devices/video/crtc_ega.h b/src/devices/video/crtc_ega.h index 62bcac8c5c3..6418f248ef3 100644 --- a/src/devices/video/crtc_ega.h +++ b/src/devices/video/crtc_ega.h @@ -130,6 +130,7 @@ class crtc_ega_device : public device_t, /* other internal state */ uint8_t m_register_address_latch; uint16_t m_start_addr_latch; + uint8_t m_preset_row_latch; bool m_cursor_state; /* 0 = off, 1 = on */ uint8_t m_cursor_blink_count; int m_hpixels_per_column; /* number of pixels per video memory address */ diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp index 188ed1d46d6..2569c4a617d 100644 --- a/src/emu/xtal.cpp +++ b/src/emu/xtal.cpp @@ -241,6 +241,7 @@ const double XTAL::known_xtals[] = { 14'314'000, /* 14.314_MHz_XTAL Taito TTL Board */ 14'318'181, /* 14.318181_MHz_XTAL Extremely common, used on 100's of PCBs (4x NTSC subcarrier) */ 14'349'600, /* 14.3496_MHz_XTAL Roland S-50 VDP */ + 14'469'000, /* 14.469_MHz_XTAL Esprit Systems Executive 10/102 */ 14'580'000, /* 14.58_MHz_XTAL Fortune 32:16 Video Controller */ 14'705'882, /* 14.705882_MHz_XTAL Aleck64 */ 14'728'000, /* 14.728_MHz_XTAL ADM 36 */ @@ -286,6 +287,7 @@ const double XTAL::known_xtals[] = { 16'670'000, /* 16.67_MHz_XTAL - */ 16'777'216, /* 16.777216_MHz_XTAL Nintendo Game Boy Advance */ 16'934'400, /* 16.9344_MHz_XTAL Usually used to drive 90's Yamaha OPL/FM chips (44100 * 384) */ + 16'960'000, /* 16.960_MHz_XTAL Esprit Systems Executive 10/102 */ 17'010'000, /* 17.01_MHz_XTAL Epic 14E */ 17'064'000, /* 17.064_MHz_XTAL Memorex 1377 */ 17'074'800, /* 17.0748_MHz_XTAL SWTPC 8212 */ diff --git a/src/mame/atari/harddriv.cpp b/src/mame/atari/harddriv.cpp index 45a39824363..e0b25440ad7 100644 --- a/src/mame/atari/harddriv.cpp +++ b/src/mame/atari/harddriv.cpp @@ -322,6 +322,13 @@ A046901 68010 clock input - 8.000MHz [32/4] 34010 clock input - 48.000MHz + strtdriv brake calibration doesn't work properly. You need to have + the brake fully depressed when it says to "TAKE YOUR HANDS AND FEET + OFF ALL CONTROLS" and "TAKE YOUR FOOT OFF THE BRAKE". When it says + "NOW STEP ON THE BRAKE FIRMLY AND RELEASE" you need to release the + brake and then press it again. If you abort the calibration, the + defaults will work anyway. + ****************************************************************************/ #include "emu.h" @@ -1313,7 +1320,7 @@ static INPUT_PORTS_START( strtdriv ) PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("mainpcb:8BADC.2") /* b00000 - 8 bit ADC 2 - brake */ - PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_SENSITIVITY(25) PORT_KEYDELTA(40) PORT_NAME("Brake") + PORT_BIT( 0xff, 0x20, IPT_PEDAL2 ) PORT_MINMAX(0x20, 0xf0) PORT_SENSITIVITY(25) PORT_KEYDELTA(40) PORT_NAME("Brake") PORT_START("mainpcb:8BADC.3") /* b00000 - 8 bit ADC 3 - volume */ PORT_BIT( 0xff, 0x80, IPT_UNUSED ) @@ -1331,7 +1338,7 @@ static INPUT_PORTS_START( strtdriv ) PORT_BIT( 0xff, 0x80, IPT_UNUSED ) PORT_START("mainpcb:12BADC.0") /* 400000 - steering wheel */ - PORT_BIT(0xfff, 0x800, IPT_PADDLE) PORT_MINMAX(0x010, 0xff0) PORT_SENSITIVITY(400) PORT_KEYDELTA(5) PORT_NAME("Steering Wheel") + PORT_BIT(0xfff, 0x200, IPT_PADDLE) PORT_MINMAX(0x000, 0x3ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_NAME("Steering Wheel") /* dummy ADC ports to end up with the same number as the full version */ PORT_START("mainpcb:12BADC.1") /* FAKE */ @@ -1421,7 +1428,7 @@ static INPUT_PORTS_START( hdrivair ) PORT_BIT( 0xff, 0x80, IPT_UNUSED ) PORT_START("mainpcb:12BADC.0") /* 400000 - steering wheel */ - PORT_BIT(0xfff, 0x800, IPT_PADDLE) PORT_MINMAX(0x010, 0xff0) PORT_SENSITIVITY(400) PORT_KEYDELTA(5) PORT_REVERSE PORT_NAME("Steering Wheel") + PORT_BIT(0xfff, 0x200, IPT_PADDLE) PORT_MINMAX(0x000, 0x3ff) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_REVERSE PORT_NAME("Steering Wheel") /* dummy ADC ports to end up with the same number as the full version */ PORT_START("mainpcb:12BADC.1") diff --git a/src/mame/esprit/executive10.cpp b/src/mame/esprit/executive10.cpp new file mode 100644 index 00000000000..28c25b5d4c2 --- /dev/null +++ b/src/mame/esprit/executive10.cpp @@ -0,0 +1,352 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Esprit Systems Executive 10/102 + + VT102 compatible terminal + + Hardware: + - Intel P8088 + - Intel D8284A + - Intel P8259A-8 + - 2x 2764 EPROM, 1x 2732 EPROM + - SY2128-2 (2k RAM) + - X2212D NOVRAM + - MC68B50P + - SCN2681A + - 14.469 MHz XTAL (near CPU), 3.6864 MHz XTAL (near 2681) + - CRT 9007 + - 2x CRT 9006-135 + - CRT9021A + - 2764 EPROM + - 4x SY2128-2 (8k RAM) + - 21.800 MHz XTAL (near 9007), 16.960 MHz XTAL (near 9007) + - 9 position DIP switch + + TODO: + - Improve rendering (132 columns, smooth scrolling, non-line attributes(?)) + - NOVRAM store/recall + - Printer + - DIP switch + + Notes: + - Other models in this line: 10/51 (IBM 5251), 10/78 (IBM 3278) + - To go online: Enter Set-Up, press 5 for next screen, press 4 to switch + from local to online (no feedback, would be shown on keyboard LEDs) + +***************************************************************************/ + +#include "emu.h" + +#include "executive10_102_kbd.h" + +#include "bus/rs232/rs232.h" +#include "cpu/i86/i86.h" +#include "machine/6850acia.h" +#include "machine/mc68681.h" +#include "machine/pic8259.h" +#include "machine/x2212.h" +#include "video/crt9007.h" + +#include "emupal.h" +#include "multibyte.h" +#include "screen.h" + + +namespace { + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class executive10_state : public driver_device +{ +public: + executive10_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_novram(*this, "novram"), + m_pic(*this, "pic"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_vpac(*this, "vpac"), + m_duart(*this, "duart"), + m_acia(*this, "acia"), + m_cram(*this, "cram"), + m_aram(*this, "aram"), + m_chargen(*this, "chargen") + { } + + void executive10(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + required_device m_maincpu; + required_device m_novram; + required_device m_pic; + required_device m_screen; + required_device m_palette; + required_device m_vpac; + required_device m_duart; + required_device m_acia; + required_shared_ptr m_cram; + required_shared_ptr m_aram; + required_region_ptr m_chargen; + + void mem_map(address_map &map); + void io_map(address_map &map); + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); +}; + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +void executive10_state::mem_map(address_map &map) +{ + map.global_mask(0xffff); + map(0x0000, 0x07ff).ram(); + map(0x2000, 0x2fff).ram().share("cram"); + map(0x4000, 0x4fff).ram().share("aram"); + map(0x6000, 0x60ff).rw(m_novram, FUNC(x2210_device::read), FUNC(x2210_device::write)); + map(0xb000, 0xffff).rom().region("maincpu", 0); +} + +void executive10_state::io_map(address_map &map) +{ + map(0x000, 0x03f).rw(m_vpac, FUNC(crt9007_device::read), FUNC(crt9007_device::write)); + map(0x040, 0x04f).rw(m_duart, FUNC(scn2681_device::read), FUNC(scn2681_device::write)); + map(0x080, 0x080).w(m_acia, FUNC(acia6850_device::control_w)); + map(0x081, 0x081).r(m_acia, FUNC(acia6850_device::status_r)); + map(0x082, 0x082).w(m_acia, FUNC(acia6850_device::data_w)); + map(0x083, 0x083).r(m_acia, FUNC(acia6850_device::data_r)); + map(0x0c0, 0x0c1).rw(m_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write)); + //map(0x180, 0x180).nopw(); // novram store/recall? +} + + +//************************************************************************** +// INPUT PORT DEFINITIONS +//************************************************************************** + +static INPUT_PORTS_START( executive10 ) +INPUT_PORTS_END + + +//************************************************************************** +// VIDEO EMULATION +//************************************************************************** + +uint32_t executive10_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + const pen_t *const pen = m_palette->pens(); + + for (int y = 0; y < 25; y++) + { + // f--------------- double height line + // -e-------------- double width line + // --dc------------ unknown + // ----ba9876543210 line address + + uint16_t addr = get_u16le(&m_cram[0xfcc + (y * 2)]); + bool dw = addr & 0xc000; + + uint8_t line_attr = 0x00; + + for (int x = 0; x < (dw ? 40 : 80); x++) + { + uint16_t code = m_cram[(addr & 0x0fff) + x]; + + // move bit 7 to 8 (acs characters) + code = bitswap<9>(code, 7, 8, 6, 5, 4, 3, 2, 1, 0); + + // select 80/132 column character set + code |= 0x80; // fixed 80 columns mode for now + + // 7------- active for line attributes + // -6------ unknown + // --5----- blink + // ---4---- reverse + // ----3--- 0 = blank? + // -----2-- underline + // ------1- unknown + // -------0 highlight + + uint8_t attr = m_aram[(addr & 0x0fff) + x]; + + // new line attribute? + if (BIT(attr, 7)) + line_attr = attr; + + for (int i = 0; i < 12; i++) + { + unsigned char_line = i; + + // adjust rendered line for double height mode + if (BIT(addr, 15)) + char_line = (i / 2) + (BIT(addr, 14) * (12 / 2)); + + uint16_t data = m_chargen[(code << 4) + char_line] << 1; + + // maybe? fixes line drawing characters + if (BIT(data, 8) == 1) + { + if (BIT(data, 1) == 1) + data |= 0x001; + + if (BIT(data, 7) == 0) + data &= ~0x100; + } + + // underline? + if (BIT(line_attr, 2) && i == 10) + data = 0x1ff; + + // reverse? + if (BIT(line_attr, 4)) + data = ~data; + + // blink? + if (BIT(line_attr, 5) && (m_screen->frame_number() & 0x20)) // wrong timing + data = 0x000; + + // cursor? + if (m_vpac->cursor_active(x, y)) + data = ~data; // might be solid instead + + // foreground/background colors + rgb_t fg = BIT(line_attr, 0) ? pen[2] : pen[1]; + rgb_t bg = pen[0]; + + // draw character line + if (dw) + { + for (int p = 0; p < 9; p++) + { + bitmap.pix(y * 12 + i, x * 18 + p * 2 + 0) = BIT(data, 8 - p) ? fg : bg; + bitmap.pix(y * 12 + i, x * 18 + p * 2 + 1) = BIT(data, 8 - p) ? fg : bg; + } + } + else + { + for (int p = 0; p < 9; p++) + bitmap.pix(y * 12 + i, x * 9 + p) = BIT(data, 8 - p) ? fg : bg; + } + } + } + } + + return 0; +} + +static const gfx_layout char_layout = +{ + 8, 12, + RGN_FRAC(1,1), + 1, + { 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 }, + 8 * 16 +}; + +static GFXDECODE_START( chars ) + GFXDECODE_ENTRY("chargen", 0, char_layout, 0, 1) +GFXDECODE_END + + +//************************************************************************** +// MACHINE EMULATION +//************************************************************************** + +void executive10_state::machine_start() +{ +} + +void executive10_state::machine_reset() +{ +} + + +//************************************************************************** +// MACHINE DEFINTIONS +//************************************************************************** + +void executive10_state::executive10(machine_config &config) +{ + I8088(config, m_maincpu, 14.469_MHz_XTAL / 3); + m_maincpu->set_addrmap(AS_PROGRAM, &executive10_state::mem_map); + m_maincpu->set_addrmap(AS_IO, &executive10_state::io_map); + m_maincpu->set_irq_acknowledge_callback(m_pic, FUNC(pic8259_device::inta_cb)); + + X2212(config, m_novram); + + PIC8259(config, m_pic); + m_pic->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_color(rgb_t::green()); + m_screen->set_raw(16.960_MHz_XTAL, 890, 0, 720, 320, 0, 300); // maybe + m_screen->set_screen_update(FUNC(executive10_state::screen_update)); + + PALETTE(config, m_palette, palette_device::MONOCHROME_HIGHLIGHT); + + GFXDECODE(config, "gfxdecode", m_palette, chars); + + CRT9007(config, m_vpac, 16.960_MHz_XTAL / 9); + m_vpac->set_screen("screen"); + m_vpac->set_character_width(9); + m_vpac->int_callback().set(m_pic, FUNC(pic8259_device::ir2_w)); + + SCN2681(config, m_duart, 3.6864_MHz_XTAL); + m_duart->a_tx_cb().set("serial", FUNC(rs232_port_device::write_txd)); + m_duart->outport_cb().set(m_acia, FUNC(acia6850_device::write_rxc)).bit(3); + m_duart->outport_cb().append(m_acia, FUNC(acia6850_device::write_txc)).bit(3); + m_duart->outport_cb().append(m_pic, FUNC(pic8259_device::ir0_w)).bit(4).invert(); + m_duart->outport_cb().append(m_pic, FUNC(pic8259_device::ir1_w)).bit(5).invert(); + + rs232_port_device &serial(RS232_PORT(config, "serial", default_rs232_devices, nullptr)); + serial.rxd_handler().set(m_duart, FUNC(scn2681_device::rx_a_w)); + serial.cts_handler().set(m_duart, FUNC(scn2681_device::ip0_w)); + + ACIA6850(config, m_acia); + m_acia->irq_handler().set(m_pic, FUNC(pic8259_device::ir4_w)); + m_acia->txd_handler().set("kbd", FUNC(executive10_102_kbd_device::rxd_w)); + + executive10_102_kbd_device &kbd(EXECUTIVE10_102_KBD(config, "kbd")); + kbd.txd_cb().set(m_acia, FUNC(acia6850_device::write_rxd)); + kbd.cts_cb().set(m_acia, FUNC(acia6850_device::write_cts)); +} + + +//************************************************************************** +// ROM DEFINITIONS +//************************************************************************** + +ROM_START( exe10102 ) + ROM_REGION(0x5000, "maincpu", 0) + ROM_LOAD("113-03-0.u25", 0x0000, 0x1000, CRC(bf5498d4) SHA1(46a3e832a1ba9a08c1d4938d6c94b2194ef00081)) + ROM_LOAD("113-01-0.u26", 0x1000, 0x2000, CRC(5e6babb3) SHA1(4669107e9cfaba1a697db6e832bc36c8220ee591)) + ROM_LOAD("113-02-0.u27", 0x3000, 0x2000, CRC(05bcd49b) SHA1(fbeac116ded46215644df7db1810f4f9d41e49ca)) + + ROM_REGION(0x2000, "chargen", 0) + ROM_LOAD("111-01-0.u59", 0x0000, 0x2000, CRC(4e54c69f) SHA1(92640a57863c5eab9db6d07c31deebfa3d1dafa5)) +ROM_END + + +} // anonymous namespace + + +//************************************************************************** +// SYSTEM DRIVERS +//************************************************************************** + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1983, exe10102, 0, 0, executive10, executive10, executive10_state, empty_init, "Esprit Systems", "Executive 10/102", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/esprit/executive10_102_kbd.cpp b/src/mame/esprit/executive10_102_kbd.cpp new file mode 100644 index 00000000000..04d0f7a5262 --- /dev/null +++ b/src/mame/esprit/executive10_102_kbd.cpp @@ -0,0 +1,278 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Esprit Systems Executive 10/102 Keyboard + + Hardware: + - Intel D8749 + - 6.144 MHz XTAL + - NE556 + - Buzzer + - 8 LEDs + + TODO: + - Verify Break/No Scroll key + - LEDs + + Notes: + - A/N 9102 754 2200 + - P/N 3001 900 8108 + +***************************************************************************/ + +#include "emu.h" +#include "executive10_102_kbd.h" + +#include "speaker.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(EXECUTIVE10_102_KBD, executive10_102_kbd_device, "executive10_102_kbd", "Executive 10/102 Keyboard") + +executive10_102_kbd_device::executive10_102_kbd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, EXECUTIVE10_102_KBD, tag, owner, 0U), + m_mcu(*this, "mcu"), + m_buzzer(*this, "buzzer"), + m_shift(*this, "shift"), + m_ctrl(*this, "ctrl"), + m_keys(*this, "row_%x", 0U), + m_txd_cb(*this), + m_cts_cb(*this) +{ +} + + +//************************************************************************** +// ROM DEFINITIONS +//************************************************************************** + +ROM_START( firmware ) + ROM_REGION(0x800, "mcu", 0) + ROM_LOAD("118-01-1.u1", 0x000, 0x800, CRC(311ed6a6) SHA1(2701ab4eaaf89270575ecff841f813db1907a434)) +ROM_END + +const tiny_rom_entry *executive10_102_kbd_device::device_rom_region() const +{ + return ROM_NAME( firmware ); +} + + +//************************************************************************** +// MACHINE DEFINITIONS +//************************************************************************** + +void executive10_102_kbd_device::device_add_mconfig(machine_config &config) +{ + I8749(config, m_mcu, 6.144_MHz_XTAL); + m_mcu->t0_in_cb().set(FUNC(executive10_102_kbd_device::t0_r)); + m_mcu->t1_in_cb().set(FUNC(executive10_102_kbd_device::t1_r)); + m_mcu->bus_in_cb().set(FUNC(executive10_102_kbd_device::bus_r)); + m_mcu->p1_out_cb().set(FUNC(executive10_102_kbd_device::p1_w)); + m_mcu->p2_out_cb().set(FUNC(executive10_102_kbd_device::p2_w)); + + SPEAKER(config, "mono").front_center(); + + BEEP(config, m_buzzer, 786); // unknown frequency + m_buzzer->add_route(ALL_OUTPUTS, "mono", 0.5); +} + + +//************************************************************************** +// INPUT PORT DEFINITIONS +//************************************************************************** + +static INPUT_PORTS_START( keyboard ) + PORT_START("shift") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("Shift") + + PORT_START("ctrl") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_NAME("Ctrl") + + PORT_START("row_0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_NAME("Set Up") + + PORT_START("row_1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + + PORT_START("row_2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + + PORT_START("row_3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + + PORT_START("row_4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + + PORT_START("row_5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + + PORT_START("row_6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME(u8"\u2192") // → + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME(u8"\u2190") // ← + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME(u8"\u2193") // ↓ + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME(u8"\u2191") // ↑ + + PORT_START("row_7") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(10) PORT_NAME("Line Feed") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CANCEL) PORT_CHAR(UCHAR_MAMEKEY(CANCEL)) PORT_NAME("Break") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("row_8") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad .") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("PF1") + + PORT_START("row_9") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("PF3") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("PF2") + + PORT_START("row_a") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("No Scroll") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA_PAD) PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD)) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_NAME("PF4") + + PORT_START("row_b") + PORT_BIT(0xff, 0xff, IPT_UNUSED) + + PORT_START("row_c") + PORT_BIT(0xff, 0xff, IPT_UNUSED) + + PORT_START("row_d") + PORT_BIT(0xff, 0xff, IPT_UNUSED) + + PORT_START("row_e") + PORT_BIT(0xff, 0xff, IPT_UNUSED) + + PORT_START("row_f") + PORT_BIT(0xff, 0xff, IPT_UNUSED) +INPUT_PORTS_END + +ioport_constructor executive10_102_kbd_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( keyboard ); +} + + +//************************************************************************** +// MACHINE EMULATION +//************************************************************************** + +void executive10_102_kbd_device::device_start() +{ + // register for save states + save_item(NAME(m_key_row)); +} + +void executive10_102_kbd_device::device_reset() +{ + // signal we are connected to the host + m_cts_cb(0); +} + +void executive10_102_kbd_device::rxd_w(int state) +{ + m_mcu->set_input_line(MCS48_INPUT_IRQ, state ? CLEAR_LINE : ASSERT_LINE); +} + +int executive10_102_kbd_device::t0_r() +{ + return m_shift->read(); +} + +int executive10_102_kbd_device::t1_r() +{ + return m_ctrl->read(); +} + +uint8_t executive10_102_kbd_device::bus_r() +{ + return m_keys[m_key_row]->read(); +} + +void executive10_102_kbd_device::p1_w(uint8_t data) +{ + // LEDs +} + +void executive10_102_kbd_device::p2_w(uint8_t data) +{ + // 76------ unknown + // --5----- serial data output + // ---4---- buzzer + // ----3210 key row to scan + + m_key_row = data & 0x0f; + m_buzzer->set_state(BIT(~data, 4)); + m_txd_cb(BIT(data, 5)); +} diff --git a/src/mame/esprit/executive10_102_kbd.h b/src/mame/esprit/executive10_102_kbd.h new file mode 100644 index 00000000000..9704f95e940 --- /dev/null +++ b/src/mame/esprit/executive10_102_kbd.h @@ -0,0 +1,65 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Esprit Systems Executive 10/102 Keyboard + +***************************************************************************/ + +#ifndef MAME_ESPRIT_EXECUTIVE10_102_KBD_H +#define MAME_ESPRIT_EXECUTIVE10_102_KBD_H + +#pragma once + +#include "cpu/mcs48/mcs48.h" +#include "sound/beep.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class executive10_102_kbd_device : public device_t +{ +public: + // construction/destruction + executive10_102_kbd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + // callbacks + auto txd_cb() { return m_txd_cb.bind(); } + auto cts_cb() { return m_cts_cb.bind(); } + + // from host + void rxd_w(int state); + +protected: + // device_t overrides + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + required_device m_mcu; + required_device m_buzzer; + required_ioport m_shift; + required_ioport m_ctrl; + required_ioport_array<16> m_keys; + + devcb_write_line m_txd_cb; + devcb_write_line m_cts_cb; + + uint8_t m_key_row; + + int t0_r(); + int t1_r(); + uint8_t bus_r(); + void p1_w(uint8_t data); + void p2_w(uint8_t data); +}; + +// device type declaration +DECLARE_DEVICE_TYPE(EXECUTIVE10_102_KBD, executive10_102_kbd_device) + +#endif // MAME_ESPRIT_EXECUTIVE10_102_KBD_H diff --git a/src/mame/ibm/ibm5100.cpp b/src/mame/ibm/ibm5100.cpp new file mode 100644 index 00000000000..35be65063d4 --- /dev/null +++ b/src/mame/ibm/ibm5100.cpp @@ -0,0 +1,488 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * IBM 5100. + * + * Sources: + * - IBM 5100 Maintenance Information Manual, SY31-0405-3, Fourth Edition (October 1979), International Business Machines Corporation + * + * TODO: + * - display registers + * - device address f + * - tape controller + * - printer + * - communications cards + * - expansion feature + * - later models (5110, 5120, 5130) + */ + +#include "emu.h" + +#include "ibm5100_kbd.h" + +#include "cpu/palm/palm.h" + +#include "screen.h" + +//#define VERBOSE (LOG_GENERAL) +#include "logmacro.h" + +namespace { + +class ibm5100_state : public driver_device +{ +public: + ibm5100_state(machine_config const &mconfig, device_type type, char const *tag) + : driver_device(mconfig, type, tag) + , m_cpu(*this, "cpu") + , m_screen(*this, "screen") + , m_kbd(*this, "kbd") + , m_nxr(*this, { "apl", "basic" }) + , m_j2(*this, "j2") + , m_conf(*this, "CONF") + , m_disp(*this, "DISP") + , m_lang(*this, "LANG") + , m_ros(*this, "ros") + { + } + + void ibm5100(machine_config &config); + +protected: + // driver_device implementation + virtual void machine_start() override; + virtual void machine_reset() override; + + void cpu_ros_map(address_map &map); + void cpu_rws_map(address_map &map); + void cpu_ioc_map(address_map &map); + void cpu_iod_map(address_map &map); + + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect); + + // e2 - ros control card + u8 e2_sts_r(); + void e2_ctl_w(u8 data); + u8 e2_r(); + void e2_w(u8 data); + + // f2 - base i/o card + u8 f2_kbd_sts_r(); + void f2_kbd_ctl_w(u8 data); + void da0_ctl_w(u8 data); + void daf_ctl_w(u8 data); + +private: + required_device m_cpu; + required_device m_screen; + required_device m_kbd; + + required_region_ptr_array m_nxr; + required_region_ptr m_j2; + + required_ioport m_conf; + required_ioport m_disp; + required_ioport m_lang; + + memory_view m_ros; + + u8 m_getb_bus; + + u8 m_e2_ff; // e2 card flip-flops + u8 m_f2_ff; // f2 card flip-flops + u16 m_e2_address; + + std::unique_ptr m_rws; +}; + +enum e2_ff_mask : u8 +{ + E2_RS = 0x01, // ROS select (0=APL, 1=BASIC/common) + E2_PS = 0x02, // put strobe + E2_B0 = 0x04, // data address bit 0 +}; + +enum f2_ff_mask : u8 +{ + F2_KIE = 0x01, // keyboard interrupt enable + F2_DO = 0x10, // display off +}; + +void ibm5100_state::machine_start() +{ + // for simplicity allocate maximum 64KiB + m_rws = std::make_unique(0x8000); + + save_item(NAME(m_getb_bus)); + + save_item(NAME(m_e2_ff)); + save_item(NAME(m_f2_ff)); + save_item(NAME(m_e2_address)); + + save_pointer(NAME(m_rws), 0x8000); +} + +void ibm5100_state::machine_reset() +{ + m_e2_ff = 0; + m_f2_ff = 0; + + m_e2_address = 0; + + // install configured rws + unsigned const rws_cards = (m_conf->read() & 3) + 1; + m_cpu->space(palm_device::AS_RWS).install_ram(0x80, 0x4000 * rws_cards - 1, &m_rws[0x40]); + m_ros[1].install_ram(0x80, 0x4000 * rws_cards - 1, &m_rws[0x40]); +} + +void ibm5100_state::cpu_ros_map(address_map &map) +{ + map(0x0000, 0xffff).view(m_ros); + m_ros[0](0x0000, 0xffff).rom().region("ros", 0); +} + +void ibm5100_state::cpu_rws_map(address_map &map) +{ + map.unmap_value_high(); +} + +void ibm5100_state::cpu_ioc_map(address_map &map) +{ + map(0x0, 0x0).w(FUNC(ibm5100_state::da0_ctl_w)); + map(0x1, 0x1).rw(FUNC(ibm5100_state::e2_sts_r), FUNC(ibm5100_state::e2_ctl_w)); + map(0x2, 0x3).noprw(); + map(0x4, 0x4).rw(FUNC(ibm5100_state::f2_kbd_sts_r), FUNC(ibm5100_state::f2_kbd_ctl_w)); + // 5 printer r:not used w:control + map(0x6, 0x7).noprw(); + // 8 expansion r:status w:control + map(0x9, 0xd).noprw(); + // e tape r:status w:control + map(0xf, 0xf).nopr().w(FUNC(ibm5100_state::daf_ctl_w)); +} + +void ibm5100_state::cpu_iod_map(address_map &map) +{ + map.unmap_value_high(); + + map(0x0, 0x0).noprw(); + map(0x1, 0x1).rw(FUNC(ibm5100_state::e2_r), FUNC(ibm5100_state::e2_w)); + map(0x2, 0x3).noprw(); + map(0x4, 0x4).r(m_kbd, FUNC(ibm5100_keyboard_device::read)).nopw(); + // 5 r:printer w:print data + map(0x6, 0x7).noprw(); + // 8 expansion r:not used w:data + map(0x9, 0xd).noprw(); + // e r:tape data w:tape + map(0xf, 0xf).noprw(); +} + +void ibm5100_state::ibm5100(machine_config &config) +{ + PALM(config, m_cpu, 15'091'200); + m_cpu->set_addrmap(palm_device::AS_ROS, &ibm5100_state::cpu_ros_map); + m_cpu->set_addrmap(palm_device::AS_RWS, &ibm5100_state::cpu_rws_map); + m_cpu->set_addrmap(palm_device::AS_IOC, &ibm5100_state::cpu_ioc_map); + m_cpu->set_addrmap(palm_device::AS_IOD, &ibm5100_state::cpu_iod_map); + m_cpu->getb_bus().set([this](offs_t offset, u8 data) { m_getb_bus = data; }); + m_cpu->select_ros().set([this](int state) { m_ros.select(state); }); + + /* + * Display output is 16 rows of 64 characters. Each character cell is 10x12 + * pixels with 8x12 driven from character ROS data. The last two horizontal + * pixels of each character cell line and every other scan line are blank. + */ + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(15'091'200, 64*10, 0, 64*10, 16*12*2, 0, 16*12*2); + m_screen->set_screen_update(FUNC(ibm5100_state::screen_update)); + + IBM5100_KEYBOARD(config, m_kbd); + m_kbd->strobe().set( + [this](int state) + { + if ((m_f2_ff & F2_KIE) && !state) + m_cpu->set_input_line(palm_device::IRPT_REQ3, 0); + }); +} + +u32 ibm5100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, rectangle const &cliprect) +{ + static rgb_t const c[] = { rgb_t::white(), rgb_t::black() }; + + // read display switches + u8 const disp = m_disp->read(); + + bool const reverse = BIT(disp, 0); + bool const n64 = !BIT(disp, 2); + bool const r32 = BIT(disp, 3); + + // start with a blank screen + bitmap.fill(c[reverse]); + + // then generate characters + auto const rws = util::big_endian_cast(m_rws.get()); + for (unsigned char_y = 0; char_y < 16; char_y++) + { + // every other scan line is blank + int const y = screen.visible_area().min_y + char_y * 12 * 2; + + // compute offset into rws for each row + offs_t offset = 0x200 + char_y * 64 + (r32 ? 32 : 0); + + for (unsigned char_x = 0; char_x < 64; char_x++) + { + int const x = screen.visible_area().min_x + char_x * 10; + + // read next character if display is on and normal mode or even column + u8 char_data = 0; + if (!(m_f2_ff & F2_DO) && (n64 || !(char_x & 1))) + char_data = rws[offset++]; + + // draw 8x12 character cell + for (unsigned cell_y = 0; cell_y < 12; cell_y++) + { + // index into character font data + unsigned const underline = ((cell_y > 7) && BIT(char_data, 7)) ? 4 : 0; + u8 const cell_data = m_j2[(char_data & 0x7f) * 16 + cell_y + underline]; + + bitmap.pix(y + cell_y * 2, x + 0) = c[BIT(cell_data, 7) ^ reverse]; + bitmap.pix(y + cell_y * 2, x + 1) = c[BIT(cell_data, 6) ^ reverse]; + bitmap.pix(y + cell_y * 2, x + 2) = c[BIT(cell_data, 5) ^ reverse]; + bitmap.pix(y + cell_y * 2, x + 3) = c[BIT(cell_data, 4) ^ reverse]; + bitmap.pix(y + cell_y * 2, x + 4) = c[BIT(cell_data, 3) ^ reverse]; + bitmap.pix(y + cell_y * 2, x + 5) = c[BIT(cell_data, 2) ^ reverse]; + bitmap.pix(y + cell_y * 2, x + 6) = c[BIT(cell_data, 1) ^ reverse]; + bitmap.pix(y + cell_y * 2, x + 7) = c[BIT(cell_data, 0) ^ reverse]; + } + } + } + + return 0; +} + +void ibm5100_state::da0_ctl_w(u8 data) +{ + LOG("da0_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); + + // bit 4: 0=display off + if (!BIT(data, 4)) + m_f2_ff |= F2_DO; + else + m_f2_ff &= ~F2_DO; +} + +u8 ibm5100_state::e2_sts_r() +{ + u8 data = 0xff; + + if (!machine().side_effects_disabled()) + { + data = (m_e2_ff & E2_PS) ? u8(m_e2_address) : (m_e2_address >> 8); + + m_e2_ff ^= E2_PS; + } + + return data; +} + +void ibm5100_state::e2_ctl_w(u8 data) +{ + LOG("e2_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); + + if (!BIT(data, 3)) + m_e2_ff &= ~E2_RS; + else if (!BIT(data, 2)) + m_e2_ff |= E2_RS; + + m_e2_ff &= ~(E2_B0 | E2_PS); + m_e2_address = 0; +} + +u8 ibm5100_state::e2_r() +{ + u8 data = 0xff; + + if (!machine().side_effects_disabled()) + { + bool const basic = m_e2_ff & E2_RS; + + // check model has selected ROS (all models have common) + if (BIT(m_conf->read(), 2 + basic) || (basic && m_e2_address >= 0x9000)) + { + /* + * APL non-executable ROS is addressed with an unshifted 16-bit + * address, giving a 128KiB range; BASIC uses a shifted address, + * giving 64KiB. Even and odd bytes are selected by a flip-flop + * which is toggled with each read. + */ + data = BIT(m_nxr[basic][m_e2_address >> basic], (m_e2_ff & E2_B0) ? 0 : 8, 8); + } + + // always increment address for BASIC, only on odd bytes for APL + if (basic || (m_e2_ff & E2_B0)) + m_e2_address++; + + // toggle even/odd byte flip-flop + m_e2_ff ^= E2_B0; + } + + return data; +} + +void ibm5100_state::e2_w(u8 data) +{ + m_e2_address = (m_e2_address << 8) | data; + + if (m_e2_ff & E2_PS) + { + LOG("e2_address 0x%04x (%s)\n", m_e2_address, machine().describe_context()); + + // data byte even/odd flip-flop is cleared except when BASIC is + // selected and the address is odd + if ((m_e2_ff & E2_RS) && (m_e2_address & 1)) + m_e2_ff |= E2_B0; + else + m_e2_ff &= ~E2_B0; + } + + // toggle put strobe flip-flop + m_e2_ff ^= E2_PS; +} + +u8 ibm5100_state::f2_kbd_sts_r() +{ + if (!machine().side_effects_disabled()) + { + switch (m_getb_bus) + { + case 0x40: + // keyboard data gate + return m_kbd->read(); + case 0x80: + // keyboard status gate + return m_lang->read(); + default: + LOG("f2_kbd_sts_r: unknown 0x%02x (%s)\n", m_getb_bus, machine().describe_context()); + break; + } + } + + return 0xff; +} + +void ibm5100_state::f2_kbd_ctl_w(u8 data) +{ + LOG("f2_kbd_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); + + // bit 6: 0=reset and disable keyboard interrupts + if (!BIT(data, 6)) + { + m_f2_ff &= ~F2_KIE; + + m_cpu->set_input_line(palm_device::IRPT_REQ3, 1); + } + + // bit 4: 0=lock keyboard + m_kbd->lock_w(BIT(data, 4)); + + // bit 1: 0=enable typamatic + // FIXME: inverted? + m_kbd->typamatic_w(BIT(data, 1)); + + // bit 0: 0=enable keyboard interrupt + if (!BIT(data, 0)) + m_f2_ff |= F2_KIE; + else + m_f2_ff &= ~F2_KIE; +} + +void ibm5100_state::daf_ctl_w(u8 data) +{ + LOG("daf_ctl_w 0x%02x (%s)\n", data, machine().describe_context()); + + // bit function + // 7 expansion da=8 + // 6 tape da=e + // 5 keyboard da=4 + // 4 printer da=5 + // 3 enable cycle steal + // 2 reset da=b + // 1 reset da=c + // 0 reset da=d +} + +ROM_START(ibm5100) + // Executable ROS + ROM_REGION16_BE(0x10000, "ros", 0) + ROM_LOAD("h2.ros", 0x0000, 0x8000, CRC(36d11e3d) SHA1(6be2c0728b88debcd557879c25781a9c7afc5224)) + ROM_LOAD("h4.ros", 0x8000, 0x8000, CRC(5d3eceb7) SHA1(e5412914d74e8149ea8a250a6560d1738555ec7e)) + + // BASIC + Common and Language non-executable ROS + /* + * The common ROS is physically located on the E2 card, and not on the C4 + * BASIC card, however it is selected together with the BASIC ROS and + * logically appended to the address space. + */ + ROM_REGION16_BE(0x10000, "basic", 0) + ROM_LOAD("c4.ros", 0x0000, 0x9000, CRC(b1abeb4a) SHA1(e0151fefe63c43c8912599615ddfb7c06f111c72)) + ROM_LOAD("e2.ros", 0x9000, 0x4800, CRC(be4289c3) SHA1(008ea7bb25fda94540bf5e02eff5a59bb1c86aac)) + ROM_FILL(0xd800, 0x2800, 0xff) + + // APL non-executable ROS + ROM_REGION16_BE(0x20000, "apl", 0) + ROM_LOAD("c2.ros", 0x00000, 0x8000, CRC(fba01c70) SHA1(a7dd9b60ba33021d830751df2de5513e0de452f2)) + ROM_LOAD("d2.ros", 0x08000, 0x8000, CRC(afb3ba33) SHA1(15292d1082a2d6211fbdbbb0781466506d310954)) + ROM_LOAD("d4.ros", 0x10000, 0x8000, CRC(a03570c9) SHA1(5a6e7a5b38b96c8ff47be2572272f8ed0cd31efd)) + ROM_FILL(0x18000, 0x8000, 0xff) + + // Display Adapter ROS + /* + * This data was hand-made based on the character map in the documentation. + * It was assumed that the first 8 bytes of each character store the upper + * 8x8 cell, then 2x4 byte entries contain the normal and underlined lower + * 4 rows of the total 8x12 cell respectively. + */ + ROM_REGION(0x800, "j2", 0) + ROM_LOAD("j2.ros", 0x000, 0x800, CRC(428e5b66) SHA1(9def68eed9dc2b8f08581387f8b74b49b3faf7e7) BAD_DUMP) +ROM_END + +static INPUT_PORTS_START(ibm5100) + PORT_START("CONF") + PORT_CONFNAME(0x0f, 0x0f, "Model") + PORT_CONFSETTING(0x04, "A1 - APL 16K") + PORT_CONFSETTING(0x05, "A2 - APL 32K") + PORT_CONFSETTING(0x06, "A3 - APL 48K") + PORT_CONFSETTING(0x07, "A4 - APL 64K") + + PORT_CONFSETTING(0x08, "B1 - BASIC 16K") + PORT_CONFSETTING(0x09, "B2 - BASIC 32K") + PORT_CONFSETTING(0x0a, "B3 - BASIC 48K") + PORT_CONFSETTING(0x0b, "B4 - BASIC 64K") + + PORT_CONFSETTING(0x0c, "C1 - APL/BASIC 16K") + PORT_CONFSETTING(0x0d, "C2 - APL/BASIC 32K") + PORT_CONFSETTING(0x0e, "C3 - APL/BASIC 48K") + PORT_CONFSETTING(0x0f, "C4 - APL/BASIC 64K") + + PORT_START("DISP") + PORT_CONFNAME(0x01, 0x00, "Reverse") + PORT_CONFSETTING(0x00, "Black on White") + PORT_CONFSETTING(0x01, "White on Black") + PORT_CONFNAME(0x02, 0x00, "Display") + PORT_CONFSETTING(0x00, "Normal") + PORT_CONFSETTING(0x02, "Registers") + PORT_CONFNAME(0x0c, 0x00, "Columns") + PORT_CONFSETTING(0x04, "L32") + PORT_CONFSETTING(0x00, "64") + PORT_CONFSETTING(0x0c, "R32") + + PORT_START("LANG") + PORT_CONFNAME(0x40, 0x40, "Language") + PORT_CONFSETTING(0x00, "APL") PORT_CONDITION("CONF", 0x04, EQUALS, 0x04) + PORT_CONFSETTING(0x40, "BASIC") PORT_CONDITION("CONF", 0x08, EQUALS, 0x08) +INPUT_PORTS_END + +} // anonymous namespace + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP(1975, ibm5100, 0, 0, ibm5100, ibm5100, ibm5100_state, empty_init, "International Business Machines", "IBM 5100", MACHINE_NO_SOUND_HW) diff --git a/src/mame/ibm/ibm5100_kbd.cpp b/src/mame/ibm/ibm5100_kbd.cpp new file mode 100644 index 00000000000..c20386b1495 --- /dev/null +++ b/src/mame/ibm/ibm5100_kbd.cpp @@ -0,0 +1,299 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * A high level emulation of the IBM 5100 keyboard. + * + * Sources: + * - IBM 5100 Maintenance Information Manual, SY31-0405-3, Fourth Edition (October 1979), International Business Machines Corporation + * + * TODO: + * - missing key names and chars + * + * For columns 0..15, the scan code format is SrrCcccc where: + * + * S = shift modifier (1=active) + * rr = matrix row number + * C = command modifier (1=active) + * cccc = matrix column number + * + * For columns > 15, the scan code format is 1rrccCSc where: + * + * S = shift modifier (0=active) + * rr = matrix row number + * C = command modifier (1=active) + * cc..c = matrix column number + * + * This scheme disallows modifier combinations, with shift taking priority over + * command. Bits 5 and 6 of the scan code are swapped when output. + * + * Regular alpha, numeric and keypad keys are easily mapped 1:1 with a standard + * modern keyboard. Additional keys are mapped by default as follows: + * + * 5100 Key Mapping Rationale + * -------- ------- --------- + * +/- - closest key position, matching shifted symbol + * ×/÷ = closest key position + * ←/→ ; moved to row with two non-alpha keys + * = ' moved to row with two non-alpha keys + * [/( [ moved to row with three non-alpha keys, matching unshifted symbol + * ]/) ] moved to row with three non-alpha keys, matching unshifted symbol + * #/@ \ moved to row with three non-alpha keys + * &/$ ` available standard symbol key + * + * l/r/u/d arrow keys conceptual match + * Attention Delete available non-symbol, non-modal key + * Hold Backspace available non-symbol, non-modal key + * Execute Enter conceptual match + * Command L/R Control conceptual match + */ + +#include "emu.h" +#include "ibm5100_kbd.h" + +#include "machine/keyboard.ipp" + +//#define VERBOSE (LOG_GENERAL) +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(IBM5100_KEYBOARD, ibm5100_keyboard_device, "ibm5100_keyboard", "IBM 5100 Keyboard") + +INPUT_PORTS_START(ibm5100_keyboard) + PORT_START("modifiers") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) + PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Shift") PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) + PORT_CODE(KEYCODE_RCONTROL) PORT_NAME("Command") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + + PORT_START("col.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_NAME(u8"9 \u2228") PORT_CHAR('9') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_NAME(u8"I \u2373") PORT_CHAR('I') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_NAME(u8"K '") PORT_CHAR('K') PORT_CHAR('\'') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') + + PORT_START("col.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_NAME(u8"8 \u2260") PORT_CHAR('8') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_NAME(u8"U \u2193") PORT_CHAR('U') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_NAME(u8"J \u2218") PORT_CHAR('J') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_NAME(u8"M \u2223") PORT_CHAR('M') + + PORT_START("col.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_NAME(u8"× ÷") // FIXME: PORT_CHAR? + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_NAME(u8"\u2190 \u2192") // FIXME: PORT_CHAR? + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR(')') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('\\') + + PORT_START("col.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') PORT_CHAR('-') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_NAME(u8"P \u22c6") PORT_CHAR('P') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('(') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Space") PORT_CHAR(UCHAR_MAMEKEY(SPACE)) + + PORT_START("col.4") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + + PORT_START("col.5") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + + PORT_START("col.6") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME("Keypad *") PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) + + PORT_START("col.7") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Keypad .") PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + + PORT_START("col.8") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_NAME(u8"6 \u2265") PORT_CHAR('6') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_NAME(u8"T \u223c") PORT_CHAR('T') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_NAME(u8"G \u2207") PORT_CHAR('G') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_NAME(u8"B \u22a5") PORT_CHAR('B') + + PORT_START("col.9") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_NAME(u8"7 >") PORT_CHAR('7') PORT_CHAR('>') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_NAME(u8"Y \u2191") PORT_CHAR('Y') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_NAME(u8"H \u2206") PORT_CHAR('H') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_NAME(u8"N \u22a4") PORT_CHAR('N') + + PORT_START("col.a") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_NAME(u8"4 \u2264") PORT_CHAR('4') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_NAME(u8"E \u220a") PORT_CHAR('E') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_NAME(u8"D \u230a") PORT_CHAR('D') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_NAME(u8"C \u2229") PORT_CHAR('C') + + PORT_START("col.b") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_NAME(u8"5 =") PORT_CHAR('5') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_NAME(u8"R \u2374") PORT_CHAR('R') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_NAME(u8"F _") PORT_CHAR('F') PORT_CHAR('_') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_NAME(u8"V \u222a") PORT_CHAR('V') + + PORT_START("col.c") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_NAME(u8"3 <") PORT_CHAR('3') PORT_CHAR('<') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_NAME(u8"W \u2375") PORT_CHAR('W') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_NAME(u8"S \u2308") PORT_CHAR('S') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_NAME(u8"X \u2283") PORT_CHAR('X') + + PORT_START("col.d") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_NAME(u8"1 ¨") PORT_CHAR('1') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_NAME("&") PORT_CHAR('&') PORT_CHAR('$') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("col.e") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_NAME(u8"0 \u2227") PORT_CHAR('0') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_NAME(u8"O \u25cb") PORT_CHAR('O') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_NAME(u8"L \u2395") PORT_CHAR('L') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') + + PORT_START("col.f") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_NAME(u8"2 \u203e") PORT_CHAR('2') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_NAME(u8"Q ?") PORT_CHAR('Q') PORT_CHAR('?') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_NAME(u8"A \u237a") PORT_CHAR('A') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_NAME(u8"Z \u2282") PORT_CHAR('Z') + + PORT_START("col.10") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Attention") PORT_CHAR(UCHAR_MAMEKEY(DEL)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) + PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Execute") PORT_CHAR(13) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("col.11") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Hold") PORT_CHAR(8) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_NAME("Equals") PORT_CHAR('=') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_NAME("# @") PORT_CHAR('#') PORT_CHAR('@') +INPUT_PORTS_END + +static const std::pairtypamatic_keys[] = +{ + std::make_pair( 3, 3), // space + std::make_pair( 4, 0), // cursor up + std::make_pair(13, 0), // cursor down + std::make_pair(16, 1), // cursor right + std::make_pair(17, 1), // cursor left +}; + +ibm5100_keyboard_device::ibm5100_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, IBM5100_KEYBOARD, tag, owner, clock) + , device_matrix_keyboard_interface(mconfig, *this + , "col.0", "col.1", "col.2", "col.3", "col.4", "col.5", "col.6", "col.7" + , "col.8", "col.9", "col.a", "col.b", "col.c", "col.d", "col.e", "col.f" + , "col.10", "col.11") + , m_strobe(*this) + , m_modifiers(*this, "modifiers") + , m_lock(false) +{ +} + +void ibm5100_keyboard_device::device_start() +{ + save_item(NAME(m_scan)); + save_item(NAME(m_typamatic)); + save_item(NAME(m_lock)); +} + +void ibm5100_keyboard_device::device_reset() +{ + m_scan = 0; + m_strobe(1); + m_typamatic = false; + + reset_key_state(); + start_processing(attotime::from_hz(25'000)); + typematic_stop(); +} + +void ibm5100_keyboard_device::key_make(u8 row, u8 column) +{ + if (m_lock) + return; + + m_scan = translate(row, column); + + LOG("key_make row %d column %d scan 0x%02x\n", row, column, m_scan); + + m_strobe(0); + m_strobe(1); + + // only some keys have typamatic action + if (std::find(std::begin(typamatic_keys), std::end(typamatic_keys), std::make_pair(row, column)) != std::end(typamatic_keys)) + typematic_start(row, column, attotime::from_msec(700), attotime::from_msec(100)); +} + +void ibm5100_keyboard_device::key_break(u8 row, u8 column) +{ + if (typematic_is(row, column)) + typematic_stop(); + + m_scan = 0; +} + +void ibm5100_keyboard_device::key_repeat(u8 row, u8 column) +{ + if (m_typamatic) + { + m_scan = translate(row, column); + + m_strobe(0); + m_strobe(1); + } +} + +// column and row are swapped with respect device_matrix_keyboard_interface arguments +u8 ibm5100_keyboard_device::translate(u8 column, u8 row) +{ + // compute basic scan code with bits 5 and 6 swapped + u8 data = bitswap<8>(row << 5 | column, 7, 5, 6, 4, 3, 2, 1, 0); + + u8 const modifiers = m_modifiers->read(); + + // modifiers are applied differently for columns > 15 + if (column < 16) + { + if (BIT(modifiers, 0)) + // shift + data |= 0x80; + else if (BIT(modifiers, 1)) + // command + data |= 0x10; + } + else + { + data |= 0x82; + + if (BIT(modifiers, 0)) + // shift + data &= ~0x02; + else if (BIT(modifiers, 1)) + // command + data |= 0x04; + } + + return data; +} + +void ibm5100_keyboard_device::typamatic_w(int state) +{ + m_typamatic = state; +} + +void ibm5100_keyboard_device::lock_w(int state) +{ + m_lock = !state; +} + +ioport_constructor ibm5100_keyboard_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(ibm5100_keyboard); +} diff --git a/src/mame/ibm/ibm5100_kbd.h b/src/mame/ibm/ibm5100_kbd.h new file mode 100644 index 00000000000..799bb3551ef --- /dev/null +++ b/src/mame/ibm/ibm5100_kbd.h @@ -0,0 +1,49 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_IBM_IBM5100_KBD_H +#define MAME_IBM_IBM5100_KBD_H + +#pragma once + +#include "machine/keyboard.h" + +class ibm5100_keyboard_device + : public device_t + , protected device_matrix_keyboard_interface<18U> +{ +public: + auto strobe() { return m_strobe.bind(); } + + ibm5100_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + u8 read() { return m_scan; } + void typamatic_w(int state); + void lock_w(int state); + +protected: + // device_t implementation + virtual ioport_constructor device_input_ports() const override; + virtual void device_start() override; + virtual void device_reset() override; + + // device_matrix_keyboard_interface implementation + virtual void key_make(u8 row, u8 column) override; + virtual void key_break(u8 row, u8 column) override; + virtual void key_repeat(u8 row, u8 column) override; + + u8 translate(u8 column, u8 row); + +private: + devcb_write_line m_strobe; + + required_ioport m_modifiers; + + u8 m_scan; + bool m_typamatic; + bool m_lock; +}; + +DECLARE_DEVICE_TYPE(IBM5100_KEYBOARD, ibm5100_keyboard_device) + +#endif // MAME_IBM_IBM5100_KBD_H diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 1d6df1814a2..7a9ffd21892 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -17756,6 +17756,9 @@ e9161 // @source:ericsson/eispc.cpp epc // 1984 Ericsson PC +@source:esprit/executive10.cpp +exe10102 // 1983 Esprit Systems + @source:excalibur/igor.cpp igor @@ -19798,6 +19801,9 @@ husky // DVW Husky @source:ibm/ibm3153.cpp ibm3153 // +@source:ibm/ibm5100.cpp +ibm5100 + @source:ibm/ibm5550.cpp ibm5550 // @@ -35856,6 +35862,7 @@ streetgr3 // (c) 1993 @source:pc/pcipc.cpp pciagp // pcipc // +pcipcs7 // pcipctx // @source:pc/pcipc_sis.cpp diff --git a/src/mame/namco/namcos12.cpp b/src/mame/namco/namcos12.cpp index 290ea9ce7c1..644042a503f 100644 --- a/src/mame/namco/namcos12.cpp +++ b/src/mame/namco/namcos12.cpp @@ -97,10 +97,6 @@ It was shown only at an amusement show. Possibly a prototype still exists. Possi Tekno Werk (C) Namco, 1999 Some kind of music game similar to Konami's Keyboard Mania series -Um Jammer Lammy (C) Namco, 1999 -http://www.wailee.com/sys/lpic/UM_Jammer_Lammy.jpg -https://www.youtube.com/watch?v=Jrwj4lUzKgU - The Namco System 12 system comprises 3 mandatory PCB's.... MOTHER PCB - This is the main PCB. It holds all sound circuitry, sound ROMs, program ROMs, shared RAM, bank-switching logic, controller/input logic (including sound CPU) and some video output circuitry. diff --git a/src/mame/pc/pcipc.cpp b/src/mame/pc/pcipc.cpp index bda654aafb8..65290b71e6c 100644 --- a/src/mame/pc/pcipc.cpp +++ b/src/mame/pc/pcipc.cpp @@ -40,6 +40,8 @@ #include "machine/pci-ide.h" #include "machine/w83977tf.h" +#include "softlist_dev.h" + // enable ISA verbose messaging at I/O $80 // NOTE: xubuntu 6.10 will ping the port a lot once it gets to GNOME. #define VERBOSE_ISA_DEBUG 0 @@ -59,13 +61,16 @@ class pcipc_state : public driver_device static const boot_state_info boot_state_infos_award[]; void pcipc(machine_config &config); + void pcipcs7(machine_config &config); void pcipctx(machine_config &config); void pcinv3(machine_config &config); - void pcimga(machine_config &config); void pciagp(machine_config &config); pcipc_state(const machine_config &mconfig, device_type type, const char *tag); +protected: + void x86_softlists(machine_config &config); + private: void pcipc_map(address_map &map); void pcipc_map_io(address_map &map); @@ -556,6 +561,16 @@ void pcipc_state::pcipc_map_io(address_map &map) map.unmap_value_high(); } +void pcipc_state::x86_softlists(machine_config &config) +{ + /* software lists */ + SOFTWARE_LIST(config, "pc_disk_list").set_original("ibm5150"); + SOFTWARE_LIST(config, "at_disk_list").set_original("ibm5170"); + SOFTWARE_LIST(config, "at_cdrom_list").set_original("ibm5170_cdrom"); + SOFTWARE_LIST(config, "at_hdd_list").set_original("ibm5170_hdd"); + SOFTWARE_LIST(config, "midi_disk_list").set_compatible("midi_flop"); +} + void pcipc_state::pcipc(machine_config &config) { pentium_device &maincpu(PENTIUM(config, "maincpu", 90000000)); @@ -602,6 +617,18 @@ void pcipc_state::pcipc(machine_config &config) serport1.cts_handler().set("board4:fdc37c93x", FUNC(fdc37c93x_device::ncts2_w)); // SW1000XG(config, "pci:11.0"); + + x86_softlists(config); +} + +void pcipc_state::pcipcs7(machine_config &config) +{ + pcipc_state::pcipc(config); + pentium_mmx_device &maincpu(PENTIUM_MMX(config.replace(), "maincpu", 266'000'000)); // socket 7 CPU + maincpu.set_addrmap(AS_PROGRAM, &pcipc_state::pcipc_map); + maincpu.set_addrmap(AS_IO, &pcipc_state::pcipc_map_io); + maincpu.set_irq_acknowledge_callback("pci:07.0:pic8259_master", FUNC(pic8259_device::inta_cb)); + maincpu.smiact().set("pci:00.0", FUNC(i82439hx_host_device::smi_act_w)); } void pcipc_state::pcipctx(machine_config &config) @@ -620,6 +647,8 @@ void pcipc_state::pcipctx(machine_config &config) PCI_SLOT(config, "pci:2", pci_cards, 16, 1, 2, 3, 0, nullptr); PCI_SLOT(config, "pci:3", pci_cards, 17, 2, 3, 0, 1, nullptr); PCI_SLOT(config, "pci:4", pci_cards, 18, 3, 0, 1, 2, "mga2064w"); + + x86_softlists(config); } void pcipc_state::pciagp(machine_config &config) @@ -676,6 +705,8 @@ void pcipc_state::pciagp(machine_config &config) PCI_SLOT(config, "pci:2", pci_cards, 16, 1, 2, 3, 0, nullptr); PCI_SLOT(config, "pci:3", pci_cards, 17, 2, 3, 0, 1, nullptr); PCI_SLOT(config, "pci:4", pci_cards, 18, 3, 0, 1, 2, nullptr); + + x86_softlists(config); } ROM_START(pcipc) @@ -709,6 +740,8 @@ ROM_START(pciagp) ROMX_LOAD( "p2xbl_award_451pg.bin", 0x00000, 0x040000, CRC(37d0030e) SHA1(c6773d0e02325116f95c497b9953f59a9ac81317), ROM_BIOS(0) ) ROM_END +#define rom_pcipcs7 rom_pcipc + static INPUT_PORTS_START(pcipc) INPUT_PORTS_END @@ -716,5 +749,6 @@ INPUT_PORTS_END COMP(1998, pcipc, 0, 0, pcipc, pcipc, pcipc_state, empty_init, "Hack Inc.", "Sandbox PCI PC (430HX)", MACHINE_NO_SOUND ) +COMP(1998, pcipcs7, pcipc, 0, pcipcs7, pcipc, pcipc_state, empty_init, "Hack Inc.", "Sandbox PCI PC (430HX, Socket 7 CPU)", MACHINE_NO_SOUND ) // alternative of above, for running already installed OSes at their nominal speed + fiddling with MMX COMP(1998, pcipctx, 0, 0, pcipctx, pcipc, pcipc_state, empty_init, "Hack Inc.", "Sandbox PCI PC (430TX)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) // unemulated super I/O COMP(1999, pciagp, 0, 0, pciagp, pcipc, pcipc_state, empty_init, "Hack Inc.", "Sandbox PCI/AGP PC (440BX)", MACHINE_NO_SOUND | MACHINE_NOT_WORKING) // errors out with ISA state $05 (keyboard, blame 8042kbdc.cpp) bp e140c,1,{eax&=~1;g}) does stuff if bypassed but eventually PnP breaks OS booting diff --git a/src/mame/sinclair/atm.h b/src/mame/sinclair/atm.h index 09c012e9f8b..fbdbbe20081 100644 --- a/src/mame/sinclair/atm.h +++ b/src/mame/sinclair/atm.h @@ -63,7 +63,7 @@ class atm_state : public spectrum_128_state u16 &pen_page(u8 bank) { return m_pages_map[BIT(m_port_7ffd_data, 4)][bank]; } void atm_update_memory(); virtual u8 merge_ram_with_7ffd(u8 ram_page) { return (ram_page & ~0x07) | (m_port_7ffd_data & 0x07); } - virtual bool is_port_7ffd_locked() { return BIT(m_port_7ffd_data, 5); }; + virtual bool is_port_7ffd_locked() { return BIT(m_port_7ffd_data, 5); } bool is_dos_active() { return !m_cpm_n || m_beta->is_active(); } virtual void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override; diff --git a/src/mame/sinclair/spec128.cpp b/src/mame/sinclair/spec128.cpp index a00cef71087..b89ad3a02d6 100644 --- a/src/mame/sinclair/spec128.cpp +++ b/src/mame/sinclair/spec128.cpp @@ -353,9 +353,9 @@ void spectrum_128_state::spectrum_128(machine_config &config) spectrum(config); Z80(config.replace(), m_maincpu, X1_128_SINCLAIR / 10); - m_maincpu->set_addrmap(AS_PROGRAM, &spectrum_128_state::spectrum_128_mem); - m_maincpu->set_addrmap(AS_IO, &spectrum_128_state::spectrum_128_io); - m_maincpu->set_addrmap(AS_OPCODES, &spectrum_128_state::spectrum_128_fetch); + m_maincpu->set_memory_map(&spectrum_128_state::spectrum_128_mem); + m_maincpu->set_io_map(&spectrum_128_state::spectrum_128_io); + m_maincpu->set_m1_map(&spectrum_128_state::spectrum_128_fetch); m_maincpu->set_vblank_int("screen", FUNC(spectrum_128_state::spec_interrupt)); m_maincpu->nomreq_cb().set(FUNC(spectrum_128_state::spectrum_nomreq)); diff --git a/src/mame/sinclair/spec_snqk.cpp b/src/mame/sinclair/spec_snqk.cpp index 1bd015df895..784dc7998c5 100644 --- a/src/mame/sinclair/spec_snqk.cpp +++ b/src/mame/sinclair/spec_snqk.cpp @@ -1072,7 +1072,7 @@ void spectrum_state::setup_plusd(uint8_t *snapdata, uint32_t snapsize) m_port_7ffd_data += i; update_paging(); break; - }; + } logerror("Loading bank %d from offset:%05X\n", i, PLUSD128_HDR + i*SPECTRUM_BANK); for (j = 0; j < SPECTRUM_BANK; j++) space.write_byte(j + addr, snapdata[j + PLUSD128_HDR + i*SPECTRUM_BANK]); @@ -2010,7 +2010,7 @@ void spectrum_state::setup_frz(uint8_t *snapdata, uint32_t snapsize) m_port_7ffd_data += banks[i]; update_paging(); break; - }; + } logerror("Loading bank %d from offset:%05X\n", banks[i], FRZ_HDR + i*SPECTRUM_BANK); for (j = 0; j < SPECTRUM_BANK; j++) space.write_byte(j + addr, snapdata[j + FRZ_HDR + i*SPECTRUM_BANK]); diff --git a/src/mame/sinclair/specnext_copper.cpp b/src/mame/sinclair/specnext_copper.cpp new file mode 100644 index 00000000000..acbdc0feb4d --- /dev/null +++ b/src/mame/sinclair/specnext_copper.cpp @@ -0,0 +1,142 @@ +// license:BSD-3-Clause +/********************************************************************** + Spectrum Next Copper +Refs: + https://gitlab.com/thesmog358/tbblue/-/raw/master/docs/extra-hw/copper/COPPER-v0.1c.TXT +**********************************************************************/ + +#include "emu.h" +#include "specnext_copper.h" + +#include + + +#define LOG_CTRL (1U << 1) +#define LOG_DATA (1U << 2) + +#define VERBOSE ( LOG_GENERAL /*| LOG_CTRL | LOG_DATA*/ ) +#include "logmacro.h" + +#define LOGCTRL(...) LOGMASKED(LOG_CTRL, __VA_ARGS__) +#define LOGDATA(...) LOGMASKED(LOG_DATA, __VA_ARGS__) + + +// device type definition +DEFINE_DEVICE_TYPE(SPECNEXT_COPPER, specnext_copper_device, "specnext_copper", "Spectrum Next Copper") + + +specnext_copper_device::specnext_copper_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SPECNEXT_COPPER, tag, owner, clock) + , m_timer(nullptr) + , m_frame_timer(nullptr) + , m_listram(*this, "listram", 0x400 * 2, ENDIANNESS_LITTLE) + , m_out_nextreg_cb(*this) + , m_in_until_pos_cb(*this) +{ +} + +void specnext_copper_device::copper_en_w(u8 data) +{ + if (m_copper_en != data) + { + m_copper_en = data; + if ((m_copper_en == 0b01) || (m_copper_en == 0b11)) + m_copper_list_addr = 0; + m_copper_dout = 0; + + switch(m_copper_en) + { + case 0b00: + LOGCTRL("STOP\n"); + m_timer->reset(); + m_frame_timer->reset(); + break; + case 0b01: + LOGCTRL("RESET\n"); + m_timer->adjust(m_in_until_pos_cb(0x0000)); + break; + case 0b10: + LOGCTRL("START\n"); + m_timer->adjust(attotime::zero); + break; + case 0b11: + LOGCTRL("FRAME\n"); + m_frame_timer->adjust(m_in_until_pos_cb(0x0000)); + break; + } + } +} + +void specnext_copper_device::data_w(u16 addr, u8 data) +{ + LOGDATA("data(W) %03x %02x\n", addr, data); + assert(addr < 0x800); + m_listram[addr] = data; +} + +TIMER_CALLBACK_MEMBER(specnext_copper_device::timer_callback) +{ + if (m_copper_dout == 0) + m_copper_list_data = (m_listram[m_copper_list_addr << 1] << 8) | m_listram[(m_copper_list_addr << 1) | 1]; + + if (m_copper_dout == 1) // if we are on MOVE, clear the output for the next cycle + { + m_out_nextreg_cb((m_copper_list_data >> 8) & 0x7f, m_copper_list_data & 0xff); + m_copper_dout = 0; + } + else if (BIT(m_copper_list_data, 15) == 1) // command WAIT + { + m_timer->adjust(m_in_until_pos_cb(0x8000 | m_copper_list_data)); + ++m_copper_list_addr; + m_copper_dout = 0; + return; + } + else // command MOVE + { + if (BIT(m_copper_list_data, 8, 7) != 0) // dont generate the write pulse if its a NOP (MOVE 0,0) + m_copper_dout = 1; + ++m_copper_list_addr; + }; + + m_copper_list_addr %= 0x400; + m_timer->adjust(attotime::from_hz(clock())); +} + +TIMER_CALLBACK_MEMBER(specnext_copper_device::frame_timer_callback) +{ + if (m_copper_en == 0b11) + { + m_copper_list_addr = 0; + m_copper_dout = 0; + m_frame_timer->adjust(m_in_until_pos_cb(0x0000)); + m_timer->adjust(attotime::zero); + } + else + m_frame_timer->reset(); +} + + +void specnext_copper_device::device_start() +{ + m_timer = timer_alloc(FUNC(specnext_copper_device::timer_callback), this); + m_frame_timer = timer_alloc(FUNC(specnext_copper_device::frame_timer_callback), this); + + m_in_until_pos_cb.resolve_safe(attotime::zero); + + save_item(NAME(m_copper_en)); + save_item(NAME(m_copper_list_addr)); + save_item(NAME(m_copper_list_data)); + save_item(NAME(m_copper_dout)); +} + +void specnext_copper_device::device_reset() +{ + m_timer->reset(); + m_frame_timer->reset(); + memset(m_listram, 0, sizeof(m_listram)); + + m_copper_en = 0b00; + m_copper_list_addr = 0x0000; + m_copper_list_data = 0x00; + m_copper_dout = 0; +} diff --git a/src/mame/sinclair/specnext_copper.h b/src/mame/sinclair/specnext_copper.h new file mode 100644 index 00000000000..f62ee548789 --- /dev/null +++ b/src/mame/sinclair/specnext_copper.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +#ifndef MAME_SINCLAIR_SPECNEXT_COPPER_H +#define MAME_SINCLAIR_SPECNEXT_COPPER_H + +#pragma once + +#include + + +class specnext_copper_device : public device_t +{ + +public: + specnext_copper_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + auto out_nextreg_cb() { return m_out_nextreg_cb.bind(); } + template void set_in_until_pos_cb(T &&... args) { return m_in_until_pos_cb.set(std::forward(args)...); } + + u8 data_r(u16 addr) { return m_listram[addr]; } + void data_w(u16 addr, u8 data); + + void copper_en_w(u8 data); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + TIMER_CALLBACK_MEMBER(timer_callback); + TIMER_CALLBACK_MEMBER(frame_timer_callback); + + emu_timer *m_timer; + emu_timer *m_frame_timer; + +private: + memory_share_creator m_listram; + + devcb_write8 m_out_nextreg_cb; + device_delegate m_in_until_pos_cb; + + u8 m_copper_en; // u2 + u16 m_copper_list_addr; // u10 + u16 m_copper_list_data; // u16 + bool m_copper_dout; +}; + + +DECLARE_DEVICE_TYPE(SPECNEXT_COPPER, specnext_copper_device) + +#endif // MAME_SINCLAIR_SPECNEXT_COPPER_H diff --git a/src/mame/sinclair/specnext_ctc.cpp b/src/mame/sinclair/specnext_ctc.cpp new file mode 100644 index 00000000000..07492067010 --- /dev/null +++ b/src/mame/sinclair/specnext_ctc.cpp @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/********************************************************************** + Spectrum Next CTC +**********************************************************************/ + +#include "emu.h" +#include "specnext_ctc.h" + + +// device type definition +DEFINE_DEVICE_TYPE(SPECNEXT_CTC, specnext_ctc_device, "specnext_ctc", "Spectrum Next CTC") + + +specnext_ctc_device::specnext_ctc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : z80ctc_device(mconfig, SPECNEXT_CTC, tag, owner, clock) +{ +} + +int specnext_ctc_device::z80daisy_irq_ack() +{ + int const channel = (z80ctc_device::z80daisy_irq_ack() - m_vector) / 2; + return ((channel > 0) || (channel_int_state(0) == Z80_DAISY_IEO)) + ? (m_vector + (channel + 3) * 2) + : m_vector; +} diff --git a/src/mame/sinclair/specnext_ctc.h b/src/mame/sinclair/specnext_ctc.h new file mode 100644 index 00000000000..27cdb0399ff --- /dev/null +++ b/src/mame/sinclair/specnext_ctc.h @@ -0,0 +1,23 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +#ifndef MAME_SINCLAIR_SPECNEXT_CTC_H +#define MAME_SINCLAIR_SPECNEXT_CTC_H + +#pragma once + +#include "machine/z80ctc.h" + +class specnext_ctc_device : public z80ctc_device +{ + +public: + specnext_ctc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + virtual int z80daisy_irq_ack() override; + +}; + +DECLARE_DEVICE_TYPE(SPECNEXT_CTC, specnext_ctc_device) + +#endif // MAME_SINCLAIR_SPECNEXT_CTC_H diff --git a/src/mame/sinclair/specnext_dma.cpp b/src/mame/sinclair/specnext_dma.cpp new file mode 100644 index 00000000000..863c81f8690 --- /dev/null +++ b/src/mame/sinclair/specnext_dma.cpp @@ -0,0 +1,118 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/********************************************************************** + Spectrum Next DMA + + Spectrum Next DMA operates in two mode: z80dma compatible and + N-mode with Next specific fixes. + + z80dma mode is implemented there based on intensive testing of + the device. Potentially any mismatches not related to N-mode + covered here must be moved to the z80dma parent. + +**********************************************************************/ + +#include "emu.h" +#include "specnext_dma.h" + +// device type definition +DEFINE_DEVICE_TYPE(SPECNEXT_DMA, specnext_dma_device, "specnext_dma", "Spectrum Next DMA") + + +// TODO: this stuff is copy/pasted from machine/z80dma.cpp - ideally it wouldn't need to be +#define WR0 REG(0, 0) +#define WR1 REG(1, 0) +#define WR2 REG(2, 0) + +#define PORTA_INC (WR1 & 0x10) +#define PORTB_INC (WR2 & 0x10) +#define PORTA_FIXED (((WR1 >> 4) & 0x02) == 0x02) +#define PORTB_FIXED (((WR2 >> 4) & 0x02) == 0x02) + +#define TRANSFER_MODE (WR0 & 0x03) + + +specnext_dma_device::specnext_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : z80dma_device(mconfig, SPECNEXT_DMA, tag, owner, clock) +{ +} + +int specnext_dma_device::is_ready() +{ + return is_dma_enabled() || z80dma_device::is_ready(); +} + +void specnext_dma_device::write(u8 data) +{ + z80dma_device::write(data); + + if (num_follow() == 0) + { + if ((data & 0x83) == 0x83) // WR6 + { + switch (data) + { + case COMMAND_ENABLE_DMA: + m_byte_counter = 0; + break; + default: + break; + } + } + } +} + +void specnext_dma_device::do_write() +{ + if (m_dma_mode) + { + z80dma_device::do_write(); + return; + } + // else (zxnDMA) + + if (m_byte_counter) + m_addressB += PORTB_FIXED ? 0 : PORTB_INC ? 1 : -1; + + u8 const mode = TRANSFER_MODE; + switch (mode) + { + case TM_TRANSFER: + do_transfer_write(); + break; + + case TM_SEARCH: + do_search(); + break; + + case TM_SEARCH_TRANSFER: + do_transfer_write(); + do_search(); + break; + + default: + logerror("z80dma_do_operation: invalid mode %d!\n", mode); + break; + } + + m_addressA += PORTA_FIXED ? 0 : PORTA_INC ? 1 : -1; + + m_byte_counter++; + if ((m_byte_counter + 1) == m_count) + m_byte_counter++; +} + + +void specnext_dma_device::device_start() +{ + z80dma_device::device_start(); + + save_item(NAME(m_dma_mode)); +} + +void specnext_dma_device::device_reset() +{ + z80dma_device::device_reset(); + + m_dma_mode = 0; +} diff --git a/src/mame/sinclair/specnext_dma.h b/src/mame/sinclair/specnext_dma.h new file mode 100644 index 00000000000..c1c9891e402 --- /dev/null +++ b/src/mame/sinclair/specnext_dma.h @@ -0,0 +1,32 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +#ifndef MAME_SINCLAIR_SPECNEXT_DMA_H +#define MAME_SINCLAIR_SPECNEXT_DMA_H + +#pragma once + +#include "machine/z80dma.h" + +class specnext_dma_device : public z80dma_device +{ +public: + specnext_dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + void dma_mode_w(bool dma_mode) { m_dma_mode = dma_mode; } + + virtual void write(u8 data) override; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual int is_ready() override; + virtual void do_write() override; + +private: + bool m_dma_mode; // 0 = zxn dma, 1 = z80 dma +}; + +DECLARE_DEVICE_TYPE(SPECNEXT_DMA, specnext_dma_device) + +#endif // MAME_SINCLAIR_SPECNEXT_DMA_H diff --git a/src/mame/sinclair/specnext_multiface.cpp b/src/mame/sinclair/specnext_multiface.cpp new file mode 100644 index 00000000000..75f22236037 --- /dev/null +++ b/src/mame/sinclair/specnext_multiface.cpp @@ -0,0 +1,114 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/********************************************************************** + Spectrum Next Multiface +**********************************************************************/ + +#include "emu.h" +#include "specnext_multiface.h" + + +// device type definition +DEFINE_DEVICE_TYPE(SPECNEXT_MULTIFACE, specnext_multiface_device, "specnext_multiface", "Spectrum Next Multiface") + + +specnext_multiface_device::specnext_multiface_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SPECNEXT_MULTIFACE, tag, owner, clock) +{ +} + + +bool specnext_multiface_device::mode_48() +{ + return m_mf_mode == 0b11; +} + +bool specnext_multiface_device::mode_128() +{ + return !(mode_p3() || mode_48()); +} + +bool specnext_multiface_device::mode_p3() +{ + return m_mf_mode == 0b00; +} + +bool specnext_multiface_device::button_pulse() +{ + return m_button && !m_nmi_active; +} + +bool specnext_multiface_device::invisible_eff() +{ + return m_invisible && !mode_48(); +} + +bool specnext_multiface_device::fetch_66() +{ + return m_cpu_a_0066 && !m_cpu_m1_n && m_nmi_active; +} + +bool specnext_multiface_device::mf_enable_eff() +{ + return m_mf_enable || fetch_66(); +} + +void specnext_multiface_device::clock_w() +{ + // Rising edge + bool port_io_dly = m_port_mf_enable_rd || m_port_mf_enable_wr || m_port_mf_disable_rd || m_port_mf_disable_wr; + + if (button_pulse()) + m_invisible = 0; + else if (((m_port_mf_disable_wr && !mode_p3()) || (m_port_mf_enable_wr && mode_p3())) && !port_io_dly) + m_invisible = 1; + + if (button_pulse()) + m_nmi_active = 1; + else if (m_cpu_retn_seen || ((m_port_mf_enable_wr || m_port_mf_disable_wr || (m_port_mf_disable_rd && mode_p3())) && !port_io_dly)) + m_nmi_active = 0; + + if (fetch_66() && !m_cpu_mreq_n) + m_mf_enable = 1; + else if (m_port_mf_disable_rd || m_cpu_retn_seen) + m_mf_enable = 0; + else if (m_port_mf_enable_rd) + m_mf_enable = !invisible_eff(); +} + +void specnext_multiface_device::device_start() +{ + save_item(NAME(m_cpu_a_0066)); + save_item(NAME(m_cpu_mreq_n)); + save_item(NAME(m_cpu_m1_n)); + save_item(NAME(m_cpu_retn_seen)); + save_item(NAME(m_enable)); + save_item(NAME(m_button)); + save_item(NAME(m_mf_mode)); + save_item(NAME(m_port_mf_enable_rd)); + save_item(NAME(m_port_mf_enable_wr)); + save_item(NAME(m_port_mf_disable_rd)); + save_item(NAME(m_port_mf_disable_wr)); + save_item(NAME(m_nmi_active)); + save_item(NAME(m_invisible)); + save_item(NAME(m_mf_enable)); +} + +void specnext_multiface_device::device_reset() +{ + m_cpu_a_0066 = 0; + m_cpu_mreq_n = 0;; + m_cpu_m1_n = 1; + m_cpu_retn_seen = 0; + m_enable = 1; + m_button = 0; + m_mf_mode = 0; + m_port_mf_enable_rd = 0; + m_port_mf_enable_wr = 0; + m_port_mf_disable_rd = 0; + m_port_mf_disable_wr = 0; + + m_nmi_active = 0; + m_invisible = 1; + m_mf_enable = 0; +} diff --git a/src/mame/sinclair/specnext_multiface.h b/src/mame/sinclair/specnext_multiface.h new file mode 100644 index 00000000000..f01d117b4e1 --- /dev/null +++ b/src/mame/sinclair/specnext_multiface.h @@ -0,0 +1,75 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +#ifndef MAME_SINCLAIR_SPECNEXT_MULTIFACE_H +#define MAME_SINCLAIR_SPECNEXT_MULTIFACE_H + +#pragma once + +class specnext_multiface_device : public device_t +{ +public: + specnext_multiface_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + void cpu_a_0066_w(bool data) { m_cpu_a_0066 = data; } + + void cpu_mreq_n_w(bool data) { m_cpu_mreq_n = data; } + void cpu_m1_n_w(bool data) { m_cpu_m1_n = data; } + void cpu_retn_seen_w(bool data) { m_cpu_retn_seen = data; } + + void enable_w(bool data) { m_enable = data; } + void button_w(bool data) { m_button = data; } + + void mf_mode_w(u8 data) { m_mf_mode = data; } + + void port_mf_enable_rd_w(bool data) { m_port_mf_enable_rd = data; } + void port_mf_enable_wr_w(bool data) { m_port_mf_enable_wr = data; } + void port_mf_disable_rd_w(bool data) { m_port_mf_disable_rd = data; } + void port_mf_disable_wr_w(bool data) { m_port_mf_disable_wr = data; } + + bool nmi_disable_r() { return m_enable && m_nmi_active; }; + bool mf_enabled_r() { return m_enable && mf_enable_eff(); }; + bool mf_port_en_r() { return m_enable && (m_port_mf_enable_rd && !invisible_eff() && (mode_128() || mode_p3())); }; + + void clock_w(); // called on active clock edge + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + // in + bool m_cpu_a_0066; + bool m_cpu_mreq_n; + bool m_cpu_m1_n; + bool m_cpu_retn_seen; + + bool m_enable; + bool m_button; + + u8 m_mf_mode; // u2: 00 = mf +3, 11 = mf 48, else mf 128 + + bool m_port_mf_enable_rd; + bool m_port_mf_enable_wr; + bool m_port_mf_disable_rd; + bool m_port_mf_disable_wr; + + // internal + bool m_nmi_active; + bool m_invisible; + bool m_mf_enable; + + // signal + bool mode_48(); + bool mode_128(); + bool mode_p3(); + + bool button_pulse(); + bool invisible_eff(); + bool fetch_66(); + bool mf_enable_eff(); +}; + + +DECLARE_DEVICE_TYPE(SPECNEXT_MULTIFACE, specnext_multiface_device) + +#endif // MAME_SINCLAIR_SPECNEXT_MULTIFACE_H diff --git a/src/mame/sinclair/sprinter.cpp b/src/mame/sinclair/sprinter.cpp index 3c509da368c..3fdc45ed751 100644 --- a/src/mame/sinclair/sprinter.cpp +++ b/src/mame/sinclair/sprinter.cpp @@ -122,7 +122,7 @@ class sprinter_state : public spectrum_128_state void update_memory(); void update_cpu(); - TIMER_CALLBACK_MEMBER(irq_on) override; + virtual TIMER_CALLBACK_MEMBER(irq_on) override; TIMER_CALLBACK_MEMBER(cbl_tick); u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); diff --git a/src/mame/sinclair/tsconf.h b/src/mame/sinclair/tsconf.h index 34ce5cd5df9..c247d6ce87d 100644 --- a/src/mame/sinclair/tsconf.h +++ b/src/mame/sinclair/tsconf.h @@ -51,11 +51,11 @@ class tsconf_state : public spectrum_128_state static constexpr u16 with_vblank(u16 pixclocks) { return 32 + pixclocks; } protected: - void video_start() override; - void machine_start() override; - void machine_reset() override; + virtual void video_start() override; + virtual void machine_start() override; + virtual void machine_reset() override; - TIMER_CALLBACK_MEMBER(irq_off) override; + virtual TIMER_CALLBACK_MEMBER(irq_off) override; TIMER_CALLBACK_MEMBER(irq_frame); TIMER_CALLBACK_MEMBER(irq_scanline); @@ -149,10 +149,10 @@ class tsconf_state : public spectrum_128_state template TILE_GET_INFO_MEMBER(get_tile_info_16c); - u8 get_border_color(u16 hpos = ~0, u16 vpos = ~0) override; + virtual u8 get_border_color(u16 hpos = ~0, u16 vpos = ~0) override; u32 get_vpage_offset(); - rectangle get_screen_area() override; - void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override; + virtual rectangle get_screen_area() override; + virtual void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override; void tsconf_UpdateZxScreenBitmap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void tsconf_UpdateTxtBitmap(bitmap_ind16 &bitmap, const rectangle &cliprect); void tsconf_UpdateGfxBitmap(bitmap_ind16 &bitmap, const rectangle &cliprect); diff --git a/src/mame/sinclair/tsconf_m.cpp b/src/mame/sinclair/tsconf_m.cpp index 76de0e2bd42..3c15f870f27 100644 --- a/src/mame/sinclair/tsconf_m.cpp +++ b/src/mame/sinclair/tsconf_m.cpp @@ -395,20 +395,20 @@ void tsconf_state::cram_write(u16 offset, u8 data) u8 pen = dest >> 1; rgb_t rgb = from_pwm((m_cram->read(dest | 1) << 8 | m_cram->read(dest & 0x1fe))); m_palette->set_pen_color(pen, rgb); -}; +} void tsconf_state::cram_write16(offs_t offset, u16 data) { cram_write(offset & 0x1fe, data >> 8); cram_write(offset | 1, data & 0xff); -}; +} void tsconf_state::sfile_write16(offs_t offset, u16 data) { u16 dest = offset & 0x1fe; m_sfile->write(dest, data >> 8); m_sfile->write(dest | 1, data & 0xff); -}; +} u8 tsconf_state::tsconf_port_xx1f_r(offs_t offset) { return m_beta->started() && m_beta->is_active()