diff --git a/COPYING b/COPYING
index 76c46d4ed180e..dcc0fd2f41f4b 100644
--- a/COPYING
+++ b/COPYING
@@ -11,7 +11,7 @@ distributions.
MAME
-Copyright (c) 1997-2023 MAMEdev and contributors
+Copyright (c) 1997-2024 MAMEdev and contributors
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2, as provided
diff --git a/README.md b/README.md
index 11e1a799e2ade..c8d61bbe84daa 100644
--- a/README.md
+++ b/README.md
@@ -102,7 +102,7 @@ is required to use the "MAME" name, logo, or wordmark.
- Copyright (C) 1997-2021 MAMEDev and contributors
+ Copyright (c) 1997-2024 MAMEdev and contributors
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2, as provided in
diff --git a/android-project/LICENSE b/android-project/LICENSE
index e5929c3bc95ad..1c4f0fe4393c4 100644
--- a/android-project/LICENSE
+++ b/android-project/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 1997-2023, MAMEdev and contributors
+Copyright (c) 1997-2024, MAMEdev and contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml
index 395d388956360..ab0dbdce70ed3 100644
--- a/android-project/app/src/main/AndroidManifest.xml
+++ b/android-project/app/src/main/AndroidManifest.xml
@@ -4,8 +4,8 @@
-->
diff --git a/docs/source/conf.py b/docs/source/conf.py
index e7f52cf5e9eba..e932d633316ce 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -56,16 +56,16 @@
# General information about the project.
project = u'MAME Documentation'
-copyright = u'1997-2023, MAMEdev and contributors'
+copyright = u'1997-2024, MAMEdev and contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = '0.262'
+version = '0.263'
# The full version, including alpha/beta/rc tags.
-release = '0.262'
+release = '0.263'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/docs/source/initialsetup/compilingmame.rst b/docs/source/initialsetup/compilingmame.rst
index 51c8d408fd844..f458f34af0860 100644
--- a/docs/source/initialsetup/compilingmame.rst
+++ b/docs/source/initialsetup/compilingmame.rst
@@ -559,6 +559,9 @@ Optional features
TOOLS
Set to **1** to build additional tools along with the emulator, including
**unidasm**, **chdman**, **romcmp**, and **srcclean**.
+EMULATOR
+ Set to **0** along with **TOOLS=1** to build *only* the tools and not the
+ main MAME emulator itself.
NO_OPENGL
Set to **1** to disable building the OpenGL video output module.
NO_USE_PORTAUDIO
diff --git a/docs/source/license.rst b/docs/source/license.rst
index e58d21b6dea23..aaffd97a1694d 100644
--- a/docs/source/license.rst
+++ b/docs/source/license.rst
@@ -12,7 +12,7 @@ would encourage new contributors to distribute files under this license.
Please note that MAME is a registered trademark of Gregory Ember, and permission
is required to use the “MAME” name, logo, or wordmark.
- Copyright (C) 1997-2023 MAMEDev and contributors
+ Copyright (c) 1997-2024 MAMEDev and contributors
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/docs/source/whatis.rst b/docs/source/whatis.rst
index b7b9e11c4a942..e6e93382ea300 100644
--- a/docs/source/whatis.rst
+++ b/docs/source/whatis.rst
@@ -19,7 +19,7 @@ that were its initial focus.
|
| **MAME®**
-| **Copyright © 1997-2023 MAMEdev and contributors**
+| **Copyright © 1997-2024 MAMEdev and contributors**
| **MAME is a registered trademark of Gregory Ember**
|
diff --git a/hash/apple2_flop_misc.xml b/hash/apple2_flop_misc.xml
index 6346a20753157..00dc839179b49 100644
--- a/hash/apple2_flop_misc.xml
+++ b/hash/apple2_flop_misc.xml
@@ -789,7 +789,8 @@ Generated by SLIST 0.2.1
2019
4AM
-
+
+
@@ -938,7 +944,8 @@ Generated by SLIST 0.2.1
Anti-M (version 1.6)
2019
4AM
-
+
+
@@ -967,11 +975,12 @@ Generated by SLIST 0.2.1
-
+
Anti-M (version 1.8)
2020
4AM
-
+
+
+
+
+
+
+
+
+
+
+
+ Anti-M (version 2.0)
+ 2023
+ 4AM
+
+
+
+
+
+
+
+
+
+
+
+
+ Anti-M (version 2.1)
+ 2024
+ 4AM
+
+
+
+
+
+
+
+
+
+
+
+
+ Anti-M (version 2.2)
+ 2024
+ 4AM
+
+
+
+
+
+
+
+
+
+
Ankh
diff --git a/hash/bbc_rom.xml b/hash/bbc_rom.xml
index 03b315f9566dd..3f8af86232d8b 100644
--- a/hash/bbc_rom.xml
+++ b/hash/bbc_rom.xml
@@ -497,7 +497,7 @@ license:CC0-1.0
- Advanced Disc Toolkit 1.77 [cracked]
+ Advanced Disc Toolkit 1.77 (cracked)
1986
Advanced Computer Products
@@ -2057,7 +2057,7 @@ license:CC0-1.0
- BeebFont [alt]
+ BeebFont (alt)
1984
Watford Electronics
@@ -3903,7 +3903,7 @@ license:CC0-1.0
- Digitiser 1.00 [alt]
+ Digitiser 1.00 (alt)
1985
Watford Electronics
@@ -6169,7 +6169,7 @@ license:CC0-1.0
- Inter-Word 1.02 [hack]
+ Inter-Word 1.02 (hack)
1986
Computer Concepts
@@ -6185,7 +6185,7 @@ license:CC0-1.0
- Inter-Word 1.O2 [alt1]
+ Inter-Word 1.O2 (alt 1)
1986
Computer Concepts
@@ -6197,7 +6197,7 @@ license:CC0-1.0
- Inter-Word 1.O2 [alt2]
+ Inter-Word 1.O2 (alt 2)
1986
Computer Concepts
@@ -7057,7 +7057,7 @@ license:CC0-1.0
- Meta Assembler 2.13R [alt]
+ Meta Assembler 2.13R (alt)
1985
Crash Barrier
@@ -7681,7 +7681,7 @@ license:CC0-1.0
- Multi-FORTH 83 [alt]
+ Multi-FORTH 83 (alt)
1984
Skywave
@@ -8967,7 +8967,7 @@ license:CC0-1.0
- Ramrod MS4.00c [alt]
+ Ramrod MS4.00c (alt)
1987
Clares
@@ -10561,7 +10561,7 @@ license:CC0-1.0
- Solidisk DFS 2.2k Issue 2 [hack]
+ Solidisk DFS 2.2k Issue 2 (hack)
1986
Solidisk
diff --git a/hash/coco_cart.xml b/hash/coco_cart.xml
index ae5bbeb075653..230c0e818dc84 100644
--- a/hash/coco_cart.xml
+++ b/hash/coco_cart.xml
@@ -1119,7 +1119,7 @@ Laggy keyboard presses (verify)
-
+
diff --git a/hash/fmtowns_cd.xml b/hash/fmtowns_cd.xml
index b91ff7dfc18a6..e7d7dea93dada 100644
--- a/hash/fmtowns_cd.xml
+++ b/hash/fmtowns_cd.xml
@@ -1479,7 +1479,7 @@ User/save disks that can be created from the game itself are not included.
-
+
- The 4th Unit 5 - D-Again (Demo)
+ The 4th Unit 5 - D-Again (demo)
1990
データウエスト (Data West)
@@ -1566,7 +1566,7 @@ User/save disks that can be created from the game itself are not included.
-
+
-
+
- Taito Chase H.Q. (Demo)
+ Taito Chase H.Q. (demo)
1991
ビング (Ving)
@@ -7448,7 +7448,7 @@ User/save disks that can be created from the game itself are not included.
-->
- Emit Vol. 1 - Toki no Maigo (Demo)
+ Emit Vol. 1 - Toki no Maigo (demo)
1994
光栄 (Koei)
@@ -13244,7 +13244,7 @@ User/save disks that can be created from the game itself are not included.
-
+
- Indiana Jones and the Last Crusade (Pre-Release Version)
+ Indiana Jones and the Last Crusade (pre-release version)
1990
富士通 (Fujitsu)
@@ -17409,7 +17409,7 @@ User/save disks that can be created from the game itself are not included.
-
+
- Megamorph (Demo)
+ Megamorph (demo)
1994
富士通 (Fujitsu)
@@ -22807,7 +22807,7 @@ User/save disks that can be created from the game itself are not included.
-
+
- Psychic Detective Series Vol. 2 - Memories (Demo)
+ Psychic Detective Series Vol. 2 - Memories (demo)
1989
データウエスト (Data West)
@@ -22909,7 +22909,7 @@ User/save disks that can be created from the game itself are not included.
-
+
-
+
- Psychic Detective Series Vol. 4 - Orgel (Demo)
+ Psychic Detective Series Vol. 4 - Orgel (demo)
1991
データウエスト (Data West)
@@ -23055,7 +23055,7 @@ User/save disks that can be created from the game itself are not included.
-
+
-
+
- Psychic Detective Series Final - Solitude Gekan (Demo)
+ Psychic Detective Series Final - Solitude Gekan (demo)
1993
データウエスト (Data West)
@@ -25035,13 +25035,13 @@ User/save disks that can be created from the game itself are not included.
-
+
- Sherlock Holmes - Consulting Detective (Demo)
+ Sherlock Holmes - Consulting Detective (demo)
1990
富士通 (Fujitsu)
@@ -25506,7 +25506,7 @@ User/save disks that can be created from the game itself are not included.
-
+
- Super Street Fighter II - The New Challengers (Sample Disc)
+ Super Street Fighter II - The New Challengers (sample disc)
1994
カプコン (Capcom)
diff --git a/hash/gcslottv.xml b/hash/gcslottv.xml
index ef028f02552ef..1576f94bd102e 100644
--- a/hash/gcslottv.xml
+++ b/hash/gcslottv.xml
@@ -21,7 +21,7 @@ license:CC0-1.0
-
+
Ginginmaru TV
2002
Sammy
@@ -45,6 +45,19 @@ license:CC0-1.0
+
+
+ Jū-ō Junior
+ 2002
+ Sammy
+
+
+
+
+
+
+
+
Mōjū-ō TV
2002
diff --git a/hash/ibm5170_cdrom.xml b/hash/ibm5170_cdrom.xml
index efb9dd624b4c1..6d7885069e760 100644
--- a/hash/ibm5170_cdrom.xml
+++ b/hash/ibm5170_cdrom.xml
@@ -7092,7 +7092,7 @@ Contains software drivers for a ScanExpress 6000SP Flatbed Scanner, SCSI i/f
S3
Apple Legacy Recovery
1998
Apple
-
-
+
+
@@ -87,8 +88,8 @@ PPC750 - PowerPC 750 (G3) CPU
Mac OS 7.6 (US English)
1997
Apple
-
-
+
+
@@ -99,8 +100,8 @@ PPC750 - PowerPC 750 (G3) CPU
Mac OS 7.6 (German)
1997
Apple
-
-
+
+
@@ -111,8 +112,8 @@ PPC750 - PowerPC 750 (G3) CPU
Mac OS 7.6.1 (US English)
1997
Apple
-
-
+
+
diff --git a/hash/pc1512_hdd.xml b/hash/pc1512_hdd.xml
index f23c5ac154bbb..176666301966c 100644
--- a/hash/pc1512_hdd.xml
+++ b/hash/pc1512_hdd.xml
@@ -10,7 +10,7 @@ license:CC0-1.0
1986
Amstrad
-
+
diff --git a/hash/scv.xml b/hash/scv.xml
index 7011d9ecca27f..c69cbfe68e829 100644
--- a/hash/scv.xml
+++ b/hash/scv.xml
@@ -89,10 +89,12 @@ Information found at http://www.rhod.fr/yeno_epoch.html
1985
Epoch
-
+
+
+
diff --git a/language/Afrikaans/strings.po b/language/Afrikaans/strings.po
index 672f42b653413..a0e9f66b27196 100644
--- a/language/Afrikaans/strings.po
+++ b/language/Afrikaans/strings.po
@@ -1,5 +1,5 @@
# Afrikaans translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Albanian/strings.po b/language/Albanian/strings.po
index 5e0cf2e87cef1..7835e571533da 100644
--- a/language/Albanian/strings.po
+++ b/language/Albanian/strings.po
@@ -1,5 +1,5 @@
# Albanian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Arabic/strings.po b/language/Arabic/strings.po
index 007cf18aeb32e..e457ebcd3801e 100644
--- a/language/Arabic/strings.po
+++ b/language/Arabic/strings.po
@@ -1,5 +1,5 @@
# Arabic translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Basque/strings.po b/language/Basque/strings.po
index e9a3cb374d67c..44750cd65ff34 100644
--- a/language/Basque/strings.po
+++ b/language/Basque/strings.po
@@ -1,6 +1,6 @@
# Basque translations for MAME package
# MAME paketearen Ingelesezko itzulpena.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Belarusian/strings.po b/language/Belarusian/strings.po
index 8dc4504d9e7ce..152229ad9cb43 100644
--- a/language/Belarusian/strings.po
+++ b/language/Belarusian/strings.po
@@ -1,6 +1,6 @@
# Belarusian translations for MAME package
# Беларускі пераклад для MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Bosnian/strings.po b/language/Bosnian/strings.po
index 0201a3c9bb58c..f185ef3d29cf8 100644
--- a/language/Bosnian/strings.po
+++ b/language/Bosnian/strings.po
@@ -1,5 +1,5 @@
# Bosnian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Bulgarian/strings.po b/language/Bulgarian/strings.po
index 94c1824fbe501..ace6d27006b0a 100644
--- a/language/Bulgarian/strings.po
+++ b/language/Bulgarian/strings.po
@@ -1,6 +1,6 @@
# Bulgarian translations for MAME package
# Български превод за пакет MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Burmese/strings.po b/language/Burmese/strings.po
index d4568f94f6882..822ef9dbec242 100644
--- a/language/Burmese/strings.po
+++ b/language/Burmese/strings.po
@@ -1,5 +1,5 @@
# Burmese translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Catalan/strings.po b/language/Catalan/strings.po
index 998bd9edb186f..6b461187c209a 100644
--- a/language/Catalan/strings.po
+++ b/language/Catalan/strings.po
@@ -1,5 +1,5 @@
# Catalan translations for MAME package
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Jordi Mallach , 2016
#
diff --git a/language/Chinese_Simplified/strings.po b/language/Chinese_Simplified/strings.po
index 26b427761a62e..df088f0eb093f 100644
--- a/language/Chinese_Simplified/strings.po
+++ b/language/Chinese_Simplified/strings.po
@@ -1,6 +1,6 @@
# Chinese Simplified translations for MAME package
# MAME 套件的简体中文翻译
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Chinese_Traditional/strings.po b/language/Chinese_Traditional/strings.po
index 97cc17cde13eb..fd00555eb84a4 100644
--- a/language/Chinese_Traditional/strings.po
+++ b/language/Chinese_Traditional/strings.po
@@ -1,6 +1,6 @@
# Chinese Traditional translations for MAME package
# MAME 套件的正體中文翻譯
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Croatian/strings.po b/language/Croatian/strings.po
index 99652d822e205..beb5ca6a4686e 100644
--- a/language/Croatian/strings.po
+++ b/language/Croatian/strings.po
@@ -1,5 +1,5 @@
# Croatian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Czech/strings.po b/language/Czech/strings.po
index 0013bf53046ef..4712d4d2dd1f8 100644
--- a/language/Czech/strings.po
+++ b/language/Czech/strings.po
@@ -1,6 +1,6 @@
# Czech translations for MAME package.
# České preklady pre balík MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Danish/strings.po b/language/Danish/strings.po
index bb2e2399c2c82..0e2687a59d83b 100644
--- a/language/Danish/strings.po
+++ b/language/Danish/strings.po
@@ -1,6 +1,6 @@
# Danish translations for MAME package
# Danske oversættelser for pakke MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Dutch/strings.po b/language/Dutch/strings.po
index a35a1a1e680ad..37cdb5af17370 100644
--- a/language/Dutch/strings.po
+++ b/language/Dutch/strings.po
@@ -1,6 +1,6 @@
# Dutch translations for MAME package
# Nederlandse vertalingen voor het pakket MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/English/strings.po b/language/English/strings.po
index bd9382398c15d..397e5caa9e997 100644
--- a/language/English/strings.po
+++ b/language/English/strings.po
@@ -1,5 +1,5 @@
# English translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Estonian/strings.po b/language/Estonian/strings.po
index 9367c5f08b93a..aa72d7caa4a3d 100644
--- a/language/Estonian/strings.po
+++ b/language/Estonian/strings.po
@@ -1,5 +1,5 @@
# Estonian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Finnish/strings.po b/language/Finnish/strings.po
index 2c5023df25a40..945ff6c0f7110 100644
--- a/language/Finnish/strings.po
+++ b/language/Finnish/strings.po
@@ -1,6 +1,6 @@
# Finnish translations for MAME package
# Suomenkielinen käännös MAME-paketille.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/French/strings.po b/language/French/strings.po
index 5bf9cb542f51d..09bf6802364bd 100644
--- a/language/French/strings.po
+++ b/language/French/strings.po
@@ -1,5 +1,5 @@
# Traductions françaises du paquet MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/French_Belgium/strings.po b/language/French_Belgium/strings.po
index b518608f2180e..0370553390c82 100644
--- a/language/French_Belgium/strings.po
+++ b/language/French_Belgium/strings.po
@@ -1,5 +1,5 @@
# Traductions françaises du paquet MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/French_Canada/strings.po b/language/French_Canada/strings.po
index 7e2a725e8446c..d7628254e4bb9 100644
--- a/language/French_Canada/strings.po
+++ b/language/French_Canada/strings.po
@@ -1,6 +1,6 @@
# French translations for MAME package
# Traductions françaises du paquet MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Georgian/strings.po b/language/Georgian/strings.po
index a000af04f3949..d15a66f7c17a9 100644
--- a/language/Georgian/strings.po
+++ b/language/Georgian/strings.po
@@ -1,5 +1,5 @@
# Georgian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/German/strings.po b/language/German/strings.po
index 3d45321b11806..5acd563396371 100644
--- a/language/German/strings.po
+++ b/language/German/strings.po
@@ -1,6 +1,6 @@
# German translations for MAME package
# German translation for MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Greek/strings.po b/language/Greek/strings.po
index 8c7a70a640ef8..824367ff84b1a 100644
--- a/language/Greek/strings.po
+++ b/language/Greek/strings.po
@@ -1,5 +1,5 @@
# Greek translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
msgid ""
diff --git a/language/Hebrew/strings.po b/language/Hebrew/strings.po
index 5e84de0633e2e..83afca11730cf 100644
--- a/language/Hebrew/strings.po
+++ b/language/Hebrew/strings.po
@@ -1,5 +1,5 @@
# Hebrew translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Hindi/strings.po b/language/Hindi/strings.po
index 89a9f0d78d8a0..1a82de729e0f5 100644
--- a/language/Hindi/strings.po
+++ b/language/Hindi/strings.po
@@ -1,5 +1,5 @@
# Hindi translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Indonesian/strings.po b/language/Indonesian/strings.po
index c408b0fb3b176..e741d430fb5ca 100644
--- a/language/Indonesian/strings.po
+++ b/language/Indonesian/strings.po
@@ -1,6 +1,6 @@
# Indonesian translations for MAME package
# Terjemahan bahasa inggris untuk paket MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Italian/strings.po b/language/Italian/strings.po
index 3a17975c6b92e..80366bce03d74 100644
--- a/language/Italian/strings.po
+++ b/language/Italian/strings.po
@@ -1,4 +1,4 @@
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Japanese/strings.po b/language/Japanese/strings.po
index a349f286f8e26..14352192da25f 100644
--- a/language/Japanese/strings.po
+++ b/language/Japanese/strings.po
@@ -1,5 +1,5 @@
# MAME パッケージに対する英訳.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Korean/strings.po b/language/Korean/strings.po
index f7bc6b3f7a4b7..93490f003f7a8 100644
--- a/language/Korean/strings.po
+++ b/language/Korean/strings.po
@@ -1,6 +1,6 @@
# Korean translations for MAME package
# MAME 패키지에 대한 한국어 번역문.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Latvian/strings.po b/language/Latvian/strings.po
index 4fc7d0521b0b6..f473faa0c6602 100644
--- a/language/Latvian/strings.po
+++ b/language/Latvian/strings.po
@@ -1,5 +1,5 @@
# Latvian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Lithuanian/strings.po b/language/Lithuanian/strings.po
index 506f2dd8119d6..621da97bf3fd1 100644
--- a/language/Lithuanian/strings.po
+++ b/language/Lithuanian/strings.po
@@ -1,5 +1,5 @@
# Lithuanian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Macedonian/strings.po b/language/Macedonian/strings.po
index 0668e7ac2fa35..e81bf6808cbc6 100644
--- a/language/Macedonian/strings.po
+++ b/language/Macedonian/strings.po
@@ -1,5 +1,5 @@
# Macedonian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Norwegian/strings.po b/language/Norwegian/strings.po
index 705d48be15f1b..a819f123e8320 100644
--- a/language/Norwegian/strings.po
+++ b/language/Norwegian/strings.po
@@ -1,5 +1,5 @@
# Norwegian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Persian/strings.po b/language/Persian/strings.po
index f55be5cabbccb..0e072148f741d 100644
--- a/language/Persian/strings.po
+++ b/language/Persian/strings.po
@@ -1,5 +1,5 @@
# Persian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Polish/strings.po b/language/Polish/strings.po
index 77187dc88c362..e7fba3a22beec 100644
--- a/language/Polish/strings.po
+++ b/language/Polish/strings.po
@@ -1,6 +1,6 @@
# Polish translations for MAME package
# Polskie tłumaczenia dla pakietu MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Portuguese/strings.po b/language/Portuguese/strings.po
index c64b6d6d46de3..8f03f3261b5a2 100644
--- a/language/Portuguese/strings.po
+++ b/language/Portuguese/strings.po
@@ -1,5 +1,5 @@
# Portuguese translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Portuguese_Brazil/strings.po b/language/Portuguese_Brazil/strings.po
index 9efe627c42a40..1cb4054fcff03 100644
--- a/language/Portuguese_Brazil/strings.po
+++ b/language/Portuguese_Brazil/strings.po
@@ -1,6 +1,6 @@
# Brazilian Portuguese translation for the MAME Project.
# Tradução pro Português Brasileiro para o Projeto MAME.
-# Copyright (C) 1997-2023 MAMEDev and contributors
+# Copyright (C) 1997-2024 MAMEDev and contributors
# This file is distributed under the same license as the MAME Project.
# Automatically generated, 2023.
#
diff --git a/language/Romanian/strings.po b/language/Romanian/strings.po
index f068f5a6065af..ced43f14cc4b0 100644
--- a/language/Romanian/strings.po
+++ b/language/Romanian/strings.po
@@ -1,6 +1,6 @@
# Romanian translations for MAME package
# Traducerea în limba românã pentru pachetul MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Russian/strings.po b/language/Russian/strings.po
index 1fa66968aa5f5..c2c20236de864 100644
--- a/language/Russian/strings.po
+++ b/language/Russian/strings.po
@@ -1,6 +1,6 @@
# Russian translations for MAME package
# Русский перевод для пакета MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Serbian/strings.po b/language/Serbian/strings.po
index 55e09de93773b..f8b5c7fb8cda8 100644
--- a/language/Serbian/strings.po
+++ b/language/Serbian/strings.po
@@ -1,5 +1,5 @@
# Serbian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Serbian_Cyrillic/strings.po b/language/Serbian_Cyrillic/strings.po
index 4608059945d07..a531adeaafaa0 100644
--- a/language/Serbian_Cyrillic/strings.po
+++ b/language/Serbian_Cyrillic/strings.po
@@ -1,5 +1,5 @@
# Serbian translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Slovak/strings.po b/language/Slovak/strings.po
index f65cac147632c..9e4b07e6ad04f 100644
--- a/language/Slovak/strings.po
+++ b/language/Slovak/strings.po
@@ -1,6 +1,6 @@
# Slovak translations for MAME package
# Slovenské preklady pre balík MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Slovenian/strings.po b/language/Slovenian/strings.po
index cffda959f21c2..939fc6d92fb34 100644
--- a/language/Slovenian/strings.po
+++ b/language/Slovenian/strings.po
@@ -1,6 +1,6 @@
# Slovenian translations for MAME package
# Slovenski prevodi paketa MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Spanish/strings.po b/language/Spanish/strings.po
index f6da1167e97b9..a291692f571c2 100644
--- a/language/Spanish/strings.po
+++ b/language/Spanish/strings.po
@@ -1,6 +1,6 @@
# Spanish translations for MAME package
# Traducciones al español para el paquete MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
# A. Viloria, 2016-2018.
diff --git a/language/Spanish_Mexico/strings.po b/language/Spanish_Mexico/strings.po
index eb49aab269c44..6d4594b2c5450 100644
--- a/language/Spanish_Mexico/strings.po
+++ b/language/Spanish_Mexico/strings.po
@@ -1,6 +1,6 @@
# Spanish translations for MAME package
# Traducciones al español para el paquete MAME.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Swedish/strings.po b/language/Swedish/strings.po
index 71a42eec0cfaa..09763a226216a 100644
--- a/language/Swedish/strings.po
+++ b/language/Swedish/strings.po
@@ -1,5 +1,5 @@
# Swedish translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Thai/strings.po b/language/Thai/strings.po
index 8539846206df6..ad309fe38cb4e 100644
--- a/language/Thai/strings.po
+++ b/language/Thai/strings.po
@@ -1,5 +1,5 @@
# Thai translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Turkish/strings.po b/language/Turkish/strings.po
index 61c40d44d2c72..f16450a33d324 100644
--- a/language/Turkish/strings.po
+++ b/language/Turkish/strings.po
@@ -1,6 +1,6 @@
# Turkish translations for MAME package
# MAME paketi için Türkçe çeviriler.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Ukrainian/strings.po b/language/Ukrainian/strings.po
index 96a30ebc2ca74..d41319d812b0d 100644
--- a/language/Ukrainian/strings.po
+++ b/language/Ukrainian/strings.po
@@ -1,6 +1,6 @@
# Ukrainian translations for MAME package.
# Український переклад MAME-пакета
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/language/Vietnamese/strings.po b/language/Vietnamese/strings.po
index 2ba9ed917e9db..ae82551a21cf4 100644
--- a/language/Vietnamese/strings.po
+++ b/language/Vietnamese/strings.po
@@ -1,5 +1,5 @@
# Vietnamese translations for MAME package.
-# Copyright (C) 1997-2023 MAMEdev and contributors
+# Copyright (C) 1997-2024 MAMEdev and contributors
# This file is distributed under the same license as the MAME package.
# Automatically generated, 2023.
#
diff --git a/makefile b/makefile
index 00d27444465f9..3567ccd3f7d23 100644
--- a/makefile
+++ b/makefile
@@ -1578,7 +1578,7 @@ endif
ifeq (posix,$(SHELLTYPE))
$(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS)
- @echo '#define BARE_BUILD_VERSION "0.262"' > $@
+ @echo '#define BARE_BUILD_VERSION "0.263"' > $@
@echo '#define BARE_VCS_REVISION "$(NEW_GIT_VERSION)"' >> $@
@echo 'extern const char bare_build_version[];' >> $@
@echo 'extern const char bare_vcs_revision[];' >> $@
@@ -1588,7 +1588,7 @@ $(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS)
@echo 'const char build_version[] = BARE_BUILD_VERSION " (" BARE_VCS_REVISION ")";' >> $@
else
$(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS)
- @echo #define BARE_BUILD_VERSION "0.262" > $@
+ @echo #define BARE_BUILD_VERSION "0.263" > $@
@echo #define BARE_VCS_REVISION "$(NEW_GIT_VERSION)" >> $@
@echo extern const char bare_build_version[]; >> $@
@echo extern const char bare_vcs_revision[]; >> $@
diff --git a/scripts/build/verinfo.py b/scripts/build/verinfo.py
index 4b05d86040643..6cbc66813eaac 100644
--- a/scripts/build/verinfo.py
+++ b/scripts/build/verinfo.py
@@ -23,7 +23,7 @@ def parse_args():
def extract_version(verinfo):
- pattern = re.compile('\s+BARE_BUILD_VERSION\s+"(([^."]+)\.([^."]+))"')
+ pattern = re.compile(r'\s+BARE_BUILD_VERSION\s+"(([^."]+)\.([^."]+))"')
for line in verinfo:
match = pattern.search(line)
if match:
@@ -122,7 +122,7 @@ def extract_version(verinfo):
original=options.executable,
product=('MAME' if options.target == 'mame' else options.target),
rdns=('org.mamedev.' + internal),
- copyright='\u00a9 1997-2023 MAMEdev and contributors',
+ copyright='\u00a9 1997-2024 MAMEdev and contributors',
winfileflags=('0x0L' if verbuild == '0' else 'VS_FF_PRERELEASE'),
resources=(options.resources or 'mame.rc'))
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index 23aed10441e4a..e7b5a6150ea07 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2075,6 +2075,8 @@ if (BUSES["MC10"]~=null) then
MAME_DIR .. "src/devices/bus/mc10/mc10_cart.h",
MAME_DIR .. "src/devices/bus/mc10/mcx128.cpp",
MAME_DIR .. "src/devices/bus/mc10/mcx128.h",
+ MAME_DIR .. "src/devices/bus/mc10/multiports_ext.cpp",
+ MAME_DIR .. "src/devices/bus/mc10/multiports_ext.h",
MAME_DIR .. "src/devices/bus/mc10/pak.cpp",
MAME_DIR .. "src/devices/bus/mc10/pak.h",
MAME_DIR .. "src/devices/bus/mc10/ram.cpp",
@@ -2572,6 +2574,8 @@ if (BUSES["VCS_CTRL"]~=null) then
files {
MAME_DIR .. "src/devices/bus/vcs_ctrl/ctrl.cpp",
MAME_DIR .. "src/devices/bus/vcs_ctrl/ctrl.h",
+ MAME_DIR .. "src/devices/bus/vcs_ctrl/cx85.cpp",
+ MAME_DIR .. "src/devices/bus/vcs_ctrl/cx85.h",
MAME_DIR .. "src/devices/bus/vcs_ctrl/joystick.cpp",
MAME_DIR .. "src/devices/bus/vcs_ctrl/joystick.h",
MAME_DIR .. "src/devices/bus/vcs_ctrl/joybooster.cpp",
@@ -5490,6 +5494,8 @@ if (BUSES["PCI"]~=null) then
MAME_DIR .. "src/devices/bus/pci/aha2940au.h",
MAME_DIR .. "src/devices/bus/pci/audiowerk2.cpp",
MAME_DIR .. "src/devices/bus/pci/audiowerk2.h",
+ MAME_DIR .. "src/devices/bus/pci/clgd546x_laguna.cpp",
+ MAME_DIR .. "src/devices/bus/pci/clgd546x_laguna.h",
MAME_DIR .. "src/devices/bus/pci/ds2416.cpp",
MAME_DIR .. "src/devices/bus/pci/ds2416.h",
MAME_DIR .. "src/devices/bus/pci/ess_maestro.cpp",
@@ -5502,6 +5508,8 @@ if (BUSES["PCI"]~=null) then
MAME_DIR .. "src/devices/bus/pci/oti_spitfire.h",
MAME_DIR .. "src/devices/bus/pci/opti82c861.cpp",
MAME_DIR .. "src/devices/bus/pci/opti82c861.h",
+ MAME_DIR .. "src/devices/bus/pci/pdc20262.cpp",
+ MAME_DIR .. "src/devices/bus/pci/pdc20262.h",
MAME_DIR .. "src/devices/bus/pci/promotion.cpp",
MAME_DIR .. "src/devices/bus/pci/promotion.h",
MAME_DIR .. "src/devices/bus/pci/riva128.cpp",
@@ -5518,6 +5526,8 @@ if (BUSES["PCI"]~=null) then
MAME_DIR .. "src/devices/bus/pci/sw1000xg.h",
MAME_DIR .. "src/devices/bus/pci/virge_pci.cpp",
MAME_DIR .. "src/devices/bus/pci/virge_pci.h",
+ MAME_DIR .. "src/devices/bus/pci/vision.cpp",
+ MAME_DIR .. "src/devices/bus/pci/vision.h",
MAME_DIR .. "src/devices/bus/pci/vt6306.cpp",
MAME_DIR .. "src/devices/bus/pci/vt6306.h",
MAME_DIR .. "src/devices/bus/pci/wd9710_pci.cpp",
@@ -5532,14 +5542,16 @@ end
---------------------------------------------------
--
---@src/devices/bus/plg100/plg100.h,BUSES["PLG100"] = true
+--@src/devices/bus/plg1x0/plg1x0.h,BUSES["PLG1X0"] = true
---------------------------------------------------
-if (BUSES["PLG100"]~=null) then
+if (BUSES["PLG1X0"]~=null) then
files {
- MAME_DIR .. "src/devices/bus/plg100/plg100.cpp",
- MAME_DIR .. "src/devices/bus/plg100/plg100.h",
- MAME_DIR .. "src/devices/bus/plg100/vl.cpp",
- MAME_DIR .. "src/devices/bus/plg100/vl.h",
+ MAME_DIR .. "src/devices/bus/plg1x0/plg1x0.cpp",
+ MAME_DIR .. "src/devices/bus/plg1x0/plg1x0.h",
+ MAME_DIR .. "src/devices/bus/plg1x0/plg100-vl.cpp",
+ MAME_DIR .. "src/devices/bus/plg1x0/plg100-vl.h",
+ MAME_DIR .. "src/devices/bus/plg1x0/plg150-ap.cpp",
+ MAME_DIR .. "src/devices/bus/plg1x0/plg150-ap.h",
}
end
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index 881e4ca7338c9..c621575295433 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -701,8 +701,6 @@ if CPUS["H8"] then
MAME_DIR .. "src/devices/cpu/h8/h8s2600.h",
MAME_DIR .. "src/devices/cpu/h8/h8325.cpp",
MAME_DIR .. "src/devices/cpu/h8/h8325.h",
- MAME_DIR .. "src/devices/cpu/h8/h83337.cpp",
- MAME_DIR .. "src/devices/cpu/h8/h83337.h",
MAME_DIR .. "src/devices/cpu/h8/h83002.cpp",
MAME_DIR .. "src/devices/cpu/h8/h83002.h",
MAME_DIR .. "src/devices/cpu/h8/h83003.cpp",
@@ -717,10 +715,16 @@ if CPUS["H8"] then
MAME_DIR .. "src/devices/cpu/h8/h83042.h",
MAME_DIR .. "src/devices/cpu/h8/h83048.cpp",
MAME_DIR .. "src/devices/cpu/h8/h83048.h",
+ MAME_DIR .. "src/devices/cpu/h8/h83217.cpp",
+ MAME_DIR .. "src/devices/cpu/h8/h83217.h",
+ MAME_DIR .. "src/devices/cpu/h8/h83337.cpp",
+ MAME_DIR .. "src/devices/cpu/h8/h83337.h",
MAME_DIR .. "src/devices/cpu/h8/h8s2245.cpp",
MAME_DIR .. "src/devices/cpu/h8/h8s2245.h",
- MAME_DIR .. "src/devices/cpu/h8/h8s2320.cpp",
- MAME_DIR .. "src/devices/cpu/h8/h8s2320.h",
+ MAME_DIR .. "src/devices/cpu/h8/h8s2319.cpp",
+ MAME_DIR .. "src/devices/cpu/h8/h8s2319.h",
+ MAME_DIR .. "src/devices/cpu/h8/h8s2329.cpp",
+ MAME_DIR .. "src/devices/cpu/h8/h8s2329.h",
MAME_DIR .. "src/devices/cpu/h8/h8s2357.cpp",
MAME_DIR .. "src/devices/cpu/h8/h8s2357.h",
MAME_DIR .. "src/devices/cpu/h8/h8s2655.cpp",
@@ -897,6 +901,14 @@ if CPUS["SH"] then
MAME_DIR .. "src/devices/cpu/sh/sh7032.h",
MAME_DIR .. "src/devices/cpu/sh/sh7042.cpp",
MAME_DIR .. "src/devices/cpu/sh/sh7042.h",
+ MAME_DIR .. "src/devices/cpu/sh/sh_adc.cpp",
+ MAME_DIR .. "src/devices/cpu/sh/sh_adc.h",
+ MAME_DIR .. "src/devices/cpu/sh/sh_cmt.cpp",
+ MAME_DIR .. "src/devices/cpu/sh/sh_cmt.h",
+ MAME_DIR .. "src/devices/cpu/sh/sh_intc.cpp",
+ MAME_DIR .. "src/devices/cpu/sh/sh_intc.h",
+ MAME_DIR .. "src/devices/cpu/sh/sh_port.cpp",
+ MAME_DIR .. "src/devices/cpu/sh/sh_port.h",
MAME_DIR .. "src/devices/cpu/sh/sh7604_bus.cpp",
MAME_DIR .. "src/devices/cpu/sh/sh7604_bus.h",
MAME_DIR .. "src/devices/cpu/sh/sh7604_sci.cpp",
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index f1869389ae268..30425b67a80bb 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -1938,6 +1938,18 @@ if (MACHINES["K056230"]~=null) then
}
end
+---------------------------------------------------
+--
+--@src/devices/machine/1801vp128.h,MACHINES["K1801VP128"] = true
+---------------------------------------------------
+
+if (MACHINES["K1801VP128"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/1801vp128.cpp",
+ MAME_DIR .. "src/devices/machine/1801vp128.h",
+ }
+end
+
---------------------------------------------------
--
--@src/devices/machine/kb3600.h,MACHINES["KB3600"] = true
@@ -4475,6 +4487,18 @@ if (MACHINES["PC87306"]~=null) then
}
end
+---------------------------------------------------
+--
+--@src/devices/machine/w83787f.h,MACHINES["W83787F"] = true
+---------------------------------------------------
+
+if (MACHINES["W83787F"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/w83787f.cpp",
+ MAME_DIR .. "src/devices/machine/w83787f.h",
+ }
+end
+
---------------------------------------------------
--
--@src/devices/machine/w83977tf.h,MACHINES["W83977TF"] = true
diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua
index a92578153aad2..43cb768704d5a 100644
--- a/scripts/src/osd/modules.lua
+++ b/scripts/src/osd/modules.lua
@@ -60,6 +60,7 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/interface/inputman.h",
MAME_DIR .. "src/osd/interface/inputseq.cpp",
MAME_DIR .. "src/osd/interface/inputseq.h",
+ MAME_DIR .. "src/osd/interface/midiport.h",
MAME_DIR .. "src/osd/interface/nethandler.cpp",
MAME_DIR .. "src/osd/interface/nethandler.h",
MAME_DIR .. "src/osd/modules/debugger/debug_module.h",
diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua
index fe1b86137cdff..522aff460425e 100644
--- a/scripts/src/sound.lua
+++ b/scripts/src/sound.lua
@@ -692,11 +692,12 @@ end
--@src/devices/sound/msm5232.h,SOUNDS["MSM5232"] = true
--@src/devices/sound/okim6376.h,SOUNDS["OKIM6376"] = true
--@src/devices/sound/okim6295.h,SOUNDS["OKIM6295"] = true
+--@src/devices/sound/okim6588.h,SOUNDS["OKIM6588"] = true
--@src/devices/sound/okim9810.h,SOUNDS["OKIM9810"] = true
--@src/devices/sound/okiadpcm.h,SOUNDS["OKIADPCM"] = true
---------------------------------------------------
-if (SOUNDS["OKIM6258"]~=null or SOUNDS["OKIM6295"]~=null or SOUNDS["OKIM9810"]~=null or SOUNDS["I5000_SND"]~=null or SOUNDS["OKIADPCM"]~=null) then
+if (SOUNDS["OKIM6258"]~=null or SOUNDS["OKIM6295"]~=null or SOUNDS["OKIM6588"]~=null or SOUNDS["OKIM9810"]~=null or SOUNDS["I5000_SND"]~=null or SOUNDS["OKIADPCM"]~=null) then
files {
MAME_DIR .. "src/devices/sound/okiadpcm.cpp",
MAME_DIR .. "src/devices/sound/okiadpcm.h",
@@ -738,6 +739,13 @@ if (SOUNDS["OKIM6258"]~=null) then
}
end
+if (SOUNDS["OKIM6588"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/sound/okim6588.cpp",
+ MAME_DIR .. "src/devices/sound/okim6588.h",
+ }
+end
+
if (SOUNDS["OKIM9810"]~=null) then
files {
MAME_DIR .. "src/devices/sound/okim9810.cpp",
diff --git a/scripts/src/tools.lua b/scripts/src/tools.lua
index 3914a8f4191eb..e2340724e0c4e 100644
--- a/scripts/src/tools.lua
+++ b/scripts/src/tools.lua
@@ -469,7 +469,7 @@ includedirs {
}
defines {
- "NL_DISABLE_DYNAMIC_LOAD=1",
+ "NL_DISABLE_DYNAMIC_LOAD=1",
}
files {
@@ -747,7 +747,7 @@ if _OPTIONS["targetos"] == "macosx" then
}
dependency {
- { "aueffectutil", MAME_DIR .. "src/tools/aueffectutil-Info.plist", true },
+ { "aueffectutil", MAME_DIR .. "src/tools/aueffectutil-Info.plist", true },
}
links {
diff --git a/scripts/src/video.lua b/scripts/src/video.lua
index 33b5c11066229..2b95f647fc659 100644
--- a/scripts/src/video.lua
+++ b/scripts/src/video.lua
@@ -247,28 +247,6 @@ if (VIDEOS["EF9365"]~=null) then
}
end
---------------------------------------------------
---@src/devices/video/epic12.h,VIDEOS["EPIC12"] = true
---------------------------------------------------
-
-if (VIDEOS["EPIC12"]~=null) then
- files {
- MAME_DIR .. "src/devices/video/epic12.cpp",
- MAME_DIR .. "src/devices/video/epic12.h",
- MAME_DIR .. "src/devices/video/epic12_blit0.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit1.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit2.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit3.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit4.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit5.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit6.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit7.cpp",
- MAME_DIR .. "src/devices/video/epic12_blit8.cpp",
- MAME_DIR .. "src/devices/video/epic12in.hxx",
- MAME_DIR .. "src/devices/video/epic12pixel.hxx",
- }
-end
-
--------------------------------------------------
--
--@src/devices/video/fixfreq.h,VIDEOS["FIXFREQ"] = true
@@ -1038,19 +1016,6 @@ if (VIDEOS["PC_XGA"]~=null) then
end
---------------------------------------------------
---
---@src/devices/video/clgd546x_laguna.h,VIDEOS["CLGD546X_LAGUNA"] = true
---------------------------------------------------
-
-if (VIDEOS["CLGD546X_LAGUNA"]~=null) then
- files {
- MAME_DIR .. "src/devices/video/clgd546x_laguna.cpp",
- MAME_DIR .. "src/devices/video/clgd546x_laguna.h",
- }
-end
-
-
--------------------------------------------------
--
--@src/devices/video/pcd8544.h,VIDEOS["PCD8544"] = true
diff --git a/src/devices/bus/ata/xm3301.cpp b/src/devices/bus/ata/xm3301.cpp
index fad92778dfd08..a03579a6407b0 100644
--- a/src/devices/bus/ata/xm3301.cpp
+++ b/src/devices/bus/ata/xm3301.cpp
@@ -1,8 +1,8 @@
// license:BSD-3-Clause
-// copyright-holders: Angelo Salese
+// copyright-holders: Angelo Salese, Grull Osgo
/**************************************************************************************************
-Toshiba TAISATAP.SYS support
+Toshiba TAISATAP.SYS support / CD_BALLY.SYS (gammagic)
TODO:
- XM-3301 on its own is a SCSI-2 drive, the ATAPI variants must be higher number(s)?
@@ -25,9 +25,17 @@ void toshiba_xm3301_device::device_start()
memset(m_identify_buffer, 0, sizeof(m_identify_buffer));
- // "E:XM" and "1.0" is where Master Model and Revision are printed
- t10mmc::set_model("TOSHIBA CD-ROM DRVE:XM 1.0");
-
+ // From a XM-5401 SCSI dump string $7f08
+ // [5401] will be printed as Master Model
+ // [3605] as Rev number
+ // Both TAISATAP.SYS and CD_BALLY.SYS tests against one of these strings:
+ // "TOSHIBA CD-ROM"
+ // "TOSHIBA CD-ROM XM-3301"
+ // "TOSHIBA CD-ROM DRIVE:XM"
+ // "TOSHIBA DVD" (CD_BALLY.SYS only)
+ t10mmc::set_model("TOSHIBA CD-ROM XM-5401TA3605");
+
+ // xx20 is the only confirmed part (wants IRQ for command $a0)
m_identify_buffer[0] = 0x8520;
// TODO: everything below here is unconfirmed
diff --git a/src/devices/bus/ata/xm3301.h b/src/devices/bus/ata/xm3301.h
index 2c497e6586055..b730502b24161 100644
--- a/src/devices/bus/ata/xm3301.h
+++ b/src/devices/bus/ata/xm3301.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Angelo Salese
+// copyright-holders:Angelo Salese, Grull Osgo
#ifndef MAME_BUS_ATA_XM3301_H
#define MAME_BUS_ATA_XM3301_H
diff --git a/src/devices/bus/isa/sblaster.cpp b/src/devices/bus/isa/sblaster.cpp
index a8f06fab8091c..c073dd6fe07a6 100644
--- a/src/devices/bus/isa/sblaster.cpp
+++ b/src/devices/bus/isa/sblaster.cpp
@@ -1821,3 +1821,21 @@ void sb_device::xmit_char(uint8_t data)
m_tx_waiting++;
}
}
+
+void isa16_sblaster16_device::remap(int space_id, offs_t start, offs_t end)
+{
+ if (space_id == AS_IO)
+ {
+ ymf262_device &ymf262 = *subdevice("ymf262");
+ m_isa->install_device(0x0200, 0x0207, read8smo_delegate(*subdevice("pc_joy"), FUNC(pc_joy_device::joy_port_r)), write8smo_delegate(*subdevice("pc_joy"), FUNC(pc_joy_device::joy_port_w)));
+ m_isa->install_device(0x0226, 0x0227, read8sm_delegate(*this, FUNC(sb_device::dsp_reset_r)), write8sm_delegate(*this, FUNC(sb_device::dsp_reset_w)));
+ m_isa->install_device(0x022a, 0x022b, read8sm_delegate(*this, FUNC(sb_device::dsp_data_r)), write8sm_delegate(*this, FUNC(sb_device::dsp_data_w)));
+ m_isa->install_device(0x022c, 0x022d, read8sm_delegate(*this, FUNC(sb_device::dsp_wbuf_status_r)), write8sm_delegate(*this, FUNC(sb_device::dsp_cmd_w)));
+ m_isa->install_device(0x022e, 0x022f, read8sm_delegate(*this, FUNC(sb_device::dsp_rbuf_status_r)), write8sm_delegate(*this, FUNC(sb_device::dsp_rbuf_status_w)));
+ m_isa->install_device(0x0224, 0x0225, read8sm_delegate(*this, FUNC(sb16_device::mixer_r)), write8sm_delegate(*this, FUNC(sb16_device::mixer_w)));
+ m_isa->install_device(0x0330, 0x0331, read8sm_delegate(*this, FUNC(sb16_device::mpu401_r)), write8sm_delegate(*this, FUNC(sb16_device::mpu401_w)));
+ m_isa->install_device(0x0388, 0x038b, read8sm_delegate(ymf262, FUNC(ymf262_device::read)), write8sm_delegate(ymf262, FUNC(ymf262_device::write)));
+ m_isa->install_device(0x0220, 0x0223, read8sm_delegate(ymf262, FUNC(ymf262_device::read)), write8sm_delegate(ymf262, FUNC(ymf262_device::write)));
+ m_isa->install_device(0x0228, 0x0229, read8sm_delegate(ymf262, FUNC(ymf262_device::read)), write8sm_delegate(ymf262, FUNC(ymf262_device::write)));
+ }
+}
diff --git a/src/devices/bus/isa/sblaster.h b/src/devices/bus/isa/sblaster.h
index 723998f919648..1443f2fa09c35 100644
--- a/src/devices/bus/isa/sblaster.h
+++ b/src/devices/bus/isa/sblaster.h
@@ -244,6 +244,7 @@ class isa16_sblaster16_device : public sb16_device
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
+ virtual void remap(int space_id, offs_t start, offs_t end) override;
};
// device type definition
diff --git a/src/devices/bus/isa/svga_cirrus.cpp b/src/devices/bus/isa/svga_cirrus.cpp
index 42b5f37eb3d04..2111b8c6e6bc7 100644
--- a/src/devices/bus/isa/svga_cirrus.cpp
+++ b/src/devices/bus/isa/svga_cirrus.cpp
@@ -353,7 +353,17 @@ void isa16_svga_cirrus_gd542x_device::device_start()
m_isa->install_memory(0xa0000, 0xbffff, read8sm_delegate(*m_vga, FUNC(cirrus_gd5428_device::mem_r)), write8sm_delegate(*m_vga, FUNC(cirrus_gd5428_device::mem_w)));
m_isa->install_device(0x03b0, 0x03df, *this, &isa16_svga_cirrus_gd542x_device::io_isa_map);
+}
+void isa16_svga_cirrus_gd542x_device::remap(int space_id, offs_t start, offs_t end)
+{
+ if (space_id == AS_PROGRAM)
+ {
+ m_isa->install_memory(0xa0000, 0xbffff, read8sm_delegate(*m_vga, FUNC(cirrus_gd5428_device::mem_r)), write8sm_delegate(*m_vga, FUNC(cirrus_gd5428_device::mem_w)));
+ m_isa->install_rom(this, 0xc0000, 0xc7fff, "clgd542x");
+ }
+ else if (space_id == AS_IO)
+ m_isa->install_device(0x03b0, 0x03df, *this, &isa16_svga_cirrus_gd542x_device::io_isa_map);
}
//-------------------------------------------------
diff --git a/src/devices/bus/isa/svga_cirrus.h b/src/devices/bus/isa/svga_cirrus.h
index 0286d3d8510aa..dafb11c84d575 100644
--- a/src/devices/bus/isa/svga_cirrus.h
+++ b/src/devices/bus/isa/svga_cirrus.h
@@ -47,6 +47,7 @@ class isa16_svga_cirrus_gd542x_device :
uint8_t input_port_0_r();
+ virtual void remap(int space_id, offs_t start, offs_t end) override;
protected:
// device-level overrides
virtual void device_start() override;
diff --git a/src/devices/bus/isa/svga_paradise.cpp b/src/devices/bus/isa/svga_paradise.cpp
index 7a318ca124af2..955096ea3aa5c 100644
--- a/src/devices/bus/isa/svga_paradise.cpp
+++ b/src/devices/bus/isa/svga_paradise.cpp
@@ -106,6 +106,17 @@ void isa16_pvga1a_device::device_start()
m_isa->install_device(0x03b0, 0x03df, *this, &isa16_pvga1a_device::io_isa_map);
}
+void isa16_pvga1a_device::remap(int space_id, offs_t start, offs_t end)
+{
+ if (space_id == AS_PROGRAM)
+ {
+ m_isa->install_memory(0xa0000, 0xbffff, read8sm_delegate(*m_vga, FUNC(pvga1a_vga_device::mem_r)), write8sm_delegate(*m_vga, FUNC(pvga1a_vga_device::mem_w)));
+ m_isa->install_rom(this, 0xc0000, 0xc7fff, "vga_rom");
+ }
+ else if (space_id == AS_IO)
+ m_isa->install_device(0x03b0, 0x03df, *this, &isa16_pvga1a_device::io_isa_map);
+}
+
/******************
*
* PVGA1A-JK
@@ -460,6 +471,20 @@ void isa16_wd90c31_lr_device::device_start()
m_isa->install_device(0x23c0, 0x23c7, *m_vga, &wd90c31_vga_device::ext_io_map);
}
+void isa16_wd90c31_lr_device::remap(int space_id, offs_t start, offs_t end)
+{
+ if (space_id == AS_PROGRAM)
+ {
+ m_isa->install_rom(this, 0xc0000, 0xc7fff, "vga_rom");
+
+ m_isa->install_memory(0xa0000, 0xbffff, read8sm_delegate(*m_vga, FUNC(wd90c31_vga_device::mem_r)), write8sm_delegate(*m_vga, FUNC(wd90c31_vga_device::mem_w)));
+ }
+ else if (space_id == AS_IO)
+ {
+ m_isa->install_device(0x03b0, 0x03df, *this, &isa16_wd90c31_lr_device::io_isa_map);
+ m_isa->install_device(0x23c0, 0x23c7, *m_vga, &wd90c31_vga_device::ext_io_map);
+ }
+}
/******************
*
diff --git a/src/devices/bus/isa/svga_paradise.h b/src/devices/bus/isa/svga_paradise.h
index 35ab345b5d9f8..8b9eeea63679e 100644
--- a/src/devices/bus/isa/svga_paradise.h
+++ b/src/devices/bus/isa/svga_paradise.h
@@ -21,6 +21,8 @@ class isa16_pvga1a_device :
// construction/destruction
isa16_pvga1a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual void remap(int space_id, offs_t start, offs_t end) override;
+
protected:
// device-level overrides
virtual void device_start() override;
@@ -153,6 +155,8 @@ class isa16_wd90c31_lr_device :
// construction/destruction
isa16_wd90c31_lr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual void remap(int space_id, offs_t start, offs_t end) override;
+
protected:
// device-level overrides
virtual void device_start() override;
diff --git a/src/devices/bus/isa/svga_s3.cpp b/src/devices/bus/isa/svga_s3.cpp
index 527fa762ad769..c935e3e0152a1 100644
--- a/src/devices/bus/isa/svga_s3.cpp
+++ b/src/devices/bus/isa/svga_s3.cpp
@@ -75,9 +75,9 @@ void isa16_svga_s3_device::device_add_mconfig(machine_config &config)
{
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(25.175_MHz_XTAL, 800, 0, 640, 524, 0, 480);
- screen.set_screen_update(m_vga, FUNC(s3_vga_device::screen_update));
+ screen.set_screen_update(m_vga, FUNC(s3trio64_vga_device::screen_update));
- S3_VGA(config, m_vga, 0);
+ S3_TRIO64_VGA(config, m_vga, 0);
m_vga->set_screen("screen");
m_vga->set_vram_size(0x100000);
}
@@ -108,7 +108,7 @@ isa16_svga_s3_device::isa16_svga_s3_device(const machine_config &mconfig, const
void isa16_svga_s3_device::io_isa_map(address_map &map)
{
- map(0x00, 0x2f).m(m_vga, FUNC(s3_vga_device::io_map));
+ map(0x00, 0x2f).m(m_vga, FUNC(s3trio64_vga_device::io_map));
}
//-------------------------------------------------
@@ -141,7 +141,7 @@ void isa16_svga_s3_device::device_start()
m_isa->install16_device(0xbee8, 0xbeeb, read16smo_delegate(*m_8514, FUNC(ibm8514a_device::ibm8514_multifunc_r)), write16smo_delegate(*m_8514, FUNC(ibm8514a_device::ibm8514_multifunc_w)));
m_isa->install16_device(0xe2e8, 0xe2eb, read16sm_delegate(*m_8514, FUNC(ibm8514a_device::ibm8514_pixel_xfer_r)), write16sm_delegate(*m_8514, FUNC(ibm8514a_device::ibm8514_pixel_xfer_w)));
- m_isa->install_memory(0xa0000, 0xbffff, read8sm_delegate(*m_vga, FUNC(s3_vga_device::mem_r)), write8sm_delegate(*m_vga, FUNC(s3_vga_device::mem_w)));
+ m_isa->install_memory(0xa0000, 0xbffff, read8sm_delegate(*m_vga, FUNC(s3trio64_vga_device::mem_r)), write8sm_delegate(*m_vga, FUNC(s3trio64_vga_device::mem_w)));
}
//-------------------------------------------------
diff --git a/src/devices/bus/isa/svga_s3.h b/src/devices/bus/isa/svga_s3.h
index c391443abe071..921eff6f440fd 100644
--- a/src/devices/bus/isa/svga_s3.h
+++ b/src/devices/bus/isa/svga_s3.h
@@ -37,7 +37,7 @@ class isa16_svga_s3_device :
void io_isa_map(address_map &map);
private:
- required_device m_vga;
+ required_device m_vga;
required_device m_8514;
};
diff --git a/src/devices/bus/mc10/mc10_cart.cpp b/src/devices/bus/mc10/mc10_cart.cpp
index 77d2ae58332b3..0100a8ae5ba61 100644
--- a/src/devices/bus/mc10/mc10_cart.cpp
+++ b/src/devices/bus/mc10/mc10_cart.cpp
@@ -27,6 +27,10 @@
16 A3 33 GND
17 A5 34 GND
+ Alice 32 and Alice 90 have 2 more pins:
+ 35 IRQ (optional)
+ 36 SOUND
+
SEL is an input to the MC-10 that allows the cartridge to remove
the internal chips from the bus.
@@ -36,6 +40,7 @@
#include "mc10_cart.h"
#include "mcx128.h"
+#include "multiports_ext.h"
#include "pak.h"
#include "ram.h"
@@ -198,6 +203,7 @@ void mc10_cart_add_basic_devices(device_slot_interface &device)
device.option_add("mcx128", MC10_PAK_MCX128);
device.option_add("pak", MC10_PAK);
device.option_add("ram", MC10_PAK_RAM);
+ device.option_add("multi", ALICE_MULTIPORTS_EXT);
}
//-------------------------------------------------
@@ -210,6 +216,7 @@ void alice_cart_add_basic_devices(device_slot_interface &device)
device.option_add("alice128", ALICE_PAK_MCX128);
device.option_add("pak", MC10_PAK);
device.option_add("ram", MC10_PAK_RAM);
+ device.option_add("multi", ALICE_MULTIPORTS_EXT);
}
//-------------------------------------------------
@@ -221,4 +228,5 @@ void alice32_cart_add_basic_devices(device_slot_interface &device)
// basic devices
device.option_add("pak", MC10_PAK);
device.option_add("ram", MC10_PAK_RAM);
+ device.option_add("multi", ALICE_MULTIPORTS_EXT);
}
diff --git a/src/devices/bus/mc10/multiports_ext.cpp b/src/devices/bus/mc10/multiports_ext.cpp
new file mode 100644
index 0000000000000..90f3716ccee03
--- /dev/null
+++ b/src/devices/bus/mc10/multiports_ext.cpp
@@ -0,0 +1,122 @@
+/***************************************************************************
+
+ multiports_ext.cpp
+
+ Emulation of the Alice Multiports Extension
+
+ Features:
+ The extension provides an extension doubler and two joystick ports.
+
+ The extension also provides (for the whole Alice family and MC-10):
+ - 16K of RAM expansion ($5000-$8FFF)
+ - 64K of ROM expansion in two possible configurations:
+ - 8K of ROM between $1000 and $2FFF, as 8 banks (Cartridge mode).
+ - 16K of ROM between $C000 and $FFFF, as 4 banks (ROM mode).
+
+ Only the RAM/ROM expansion is emulated here.
+
+ Banks are selected by writing to:
+ - $1000 to $1FFF in Cartridge mode (number of bank between 0 and 7)
+ - $C000 to $CFFF in ROM mode (number of bank between 0 and 3)
+
+***************************************************************************/
+
+#include "emu.h"
+#include "multiports_ext.h"
+
+
+namespace {
+
+//**************************************************************************
+// TYPE DECLARATIONS
+//**************************************************************************
+
+class mc10_multiports_ext_device : public device_t, public device_mc10cart_interface
+{
+public:
+ mc10_multiports_ext_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ virtual int max_rom_length() const override;
+ virtual std::pair load() override;
+
+protected:
+ mc10_multiports_ext_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ // device_t implementation
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ void control_register_write(offs_t offset, u8 data);
+
+ void multiports_mem(address_map &map);
+ void update_bank();
+
+private:
+ memory_bank_creator m_bank;
+ uint8_t rom_bank_index;
+ memory_share_creator m_extention_ram;
+};
+
+//-------------------------------------------------
+// IMPLEMENTATION
+//-------------------------------------------------
+
+mc10_multiports_ext_device::mc10_multiports_ext_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : mc10_multiports_ext_device(mconfig, ALICE_MULTIPORTS_EXT, tag, owner, clock)
+{
+}
+
+mc10_multiports_ext_device::mc10_multiports_ext_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_mc10cart_interface(mconfig, *this)
+ , m_bank(*this, "cart_bank")
+ , rom_bank_index(0)
+ , m_extention_ram(*this, "ext_ram", 1024 * 16, ENDIANNESS_BIG)
+{
+}
+
+int mc10_multiports_ext_device::max_rom_length() const
+{
+ return 1024 * 64;
+}
+
+void mc10_multiports_ext_device::multiports_mem(address_map &map)
+{
+ map(0x0000, 0x1fff).bankr("cart_bank").w(FUNC(mc10_multiports_ext_device::control_register_write));
+}
+
+//-------------------------------------------------
+
+void mc10_multiports_ext_device::device_start()
+{
+ owning_slot().memspace().install_device(0x1000, 0x2fff, *this, &mc10_multiports_ext_device::multiports_mem);
+ owning_slot().memspace().install_ram(0x5000, 0x8fff, &m_extention_ram[0]);
+}
+
+//-------------------------------------------------
+
+void mc10_multiports_ext_device::device_reset()
+{
+ m_bank->set_entry(0);
+}
+
+void mc10_multiports_ext_device::control_register_write(offs_t offset, u8 data)
+{
+ if (offset < 0x1000)
+ m_bank->set_entry(data & 0x07);
+}
+
+std::pair mc10_multiports_ext_device::load()
+{
+ memory_region *const romregion(memregion("^rom"));
+ if (romregion->bytes() < (0x2000 * 8))
+ return std::make_pair(image_error::INVALIDLENGTH, "Cartridge ROM must be at least 64KB");
+
+ m_bank->configure_entries(0, 8, romregion->base(), 0x2000);
+
+ return std::make_pair(std::error_condition(), std::string());
+}
+
+} // anonymous namespace
+
+DEFINE_DEVICE_TYPE_PRIVATE(ALICE_MULTIPORTS_EXT, device_mc10cart_interface, mc10_multiports_ext_device, "mc10_multiports_ext", "Fred_72 and 6502man's Multiports Extension")
diff --git a/src/devices/bus/mc10/multiports_ext.h b/src/devices/bus/mc10/multiports_ext.h
new file mode 100644
index 0000000000000..2c31b9020a401
--- /dev/null
+++ b/src/devices/bus/mc10/multiports_ext.h
@@ -0,0 +1,12 @@
+#ifndef MAME_BUS_MC10_MULTIPORTS_EXT_H
+#define MAME_BUS_MC10_MULTIPORTS_EXT_H
+
+#pragma once
+
+#include "mc10_cart.h"
+
+// device type definition
+DECLARE_DEVICE_TYPE(ALICE_MULTIPORTS_EXT, device_mc10cart_interface)
+
+#endif // MAME_BUS_MC10_MC10_MULTIPORTS_EXT_H
+
diff --git a/src/devices/video/clgd546x_laguna.cpp b/src/devices/bus/pci/clgd546x_laguna.cpp
similarity index 100%
rename from src/devices/video/clgd546x_laguna.cpp
rename to src/devices/bus/pci/clgd546x_laguna.cpp
diff --git a/src/devices/video/clgd546x_laguna.h b/src/devices/bus/pci/clgd546x_laguna.h
similarity index 92%
rename from src/devices/video/clgd546x_laguna.h
rename to src/devices/bus/pci/clgd546x_laguna.h
index 67b8af14c2031..3eea0fcba27f8 100644
--- a/src/devices/video/clgd546x_laguna.h
+++ b/src/devices/bus/pci/clgd546x_laguna.h
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
-#ifndef MAME_VIDEO_CLGD546X_LAGUNA_H
-#define MAME_VIDEO_CLGD546X_LAGUNA_H
+#ifndef MAME_BUS_PCI_CLGD546X_LAGUNA_H
+#define MAME_BUS_PCI_CLGD546X_LAGUNA_H
#pragma once
@@ -45,4 +45,4 @@ class cirrus_gd5465_laguna3d_device : public pci_device
DECLARE_DEVICE_TYPE(CIRRUS_GD5465_LAGUNA3D, cirrus_gd5465_laguna3d_device)
-#endif // MAME_VIDEO_CLGD546X_LAGUNA_H
+#endif // MAME_BUS_PCI_CLGD546X_LAGUNA_H
diff --git a/src/devices/bus/pci/pci_slot.cpp b/src/devices/bus/pci/pci_slot.cpp
index 43b84f5540582..c03140091fd93 100644
--- a/src/devices/bus/pci/pci_slot.cpp
+++ b/src/devices/bus/pci/pci_slot.cpp
@@ -8,12 +8,14 @@
#include "aha2940au.h"
#include "audiowerk2.h"
+#include "clgd546x_laguna.h"
#include "ds2416.h"
#include "ess_maestro.h"
#include "geforce.h"
#include "mga2064w.h"
#include "opti82c861.h"
#include "oti_spitfire.h"
+#include "pdc20262.h"
#include "promotion.h"
#include "riva128.h"
#include "rivatnt.h"
@@ -22,6 +24,7 @@
#include "sonicvibes.h"
#include "sw1000xg.h"
#include "virge_pci.h"
+#include "vision.h"
#include "vt6306.h"
#include "wd9710_pci.h"
#include "zr36057.h"
@@ -103,26 +106,23 @@ void pci_card_device::irq_pin_w(offs_t line, int state)
void pci_cards(device_slot_interface &device)
{
+ // 0x00 - backward compatible pre-class code
+// device.option_add("voodoo1", VOODOO_1_PCI);
+ device.option_add("vision864", VISION864_PCI);
+ device.option_add("vision964", VISION964_PCI);
+
// 0x01 - mass storage controllers
device.option_add("aha2940au", AHA2940AU);
+ device.option_add("pdc20262", PDC20262);
// 0x02 - network controllers
device.option_add("rtl8029as", RTL8029AS_PCI);
device.option_add("rtl8139", RTL8139_PCI);
// 0x03 - display controllers
+ device.option_add("vision968", VISION968_PCI);
device.option_add("virge", VIRGE_PCI);
device.option_add("virgedx", VIRGEDX_PCI);
- device.option_add("riva128", RIVA128);
- device.option_add("riva128zx", RIVA128ZX);
- device.option_add("rivatnt", RIVATNT);
- device.option_add("rivatnt2", RIVATNT2);
- device.option_add("rivatnt2_ultra", RIVATNT2_ULTRA);
- device.option_add("vanta", VANTA);
- device.option_add("rivatnt2_m64", RIVATNT2_M64);
- device.option_add("geforce256", GEFORCE256);
- device.option_add("geforce256_ddr", GEFORCE256_DDR);
- device.option_add("quadro", QUADRO);
device.option_add("mga2064w", MGA2064W);
device.option_add("promotion3210", PROMOTION3210);
device.option_add("oti64111", OTI64111_PCI);
@@ -155,3 +155,19 @@ void pci_cards(device_slot_interface &device)
// 0x12 - Processing accelerators
// 0x13 - Debug
}
+
+// assume all natively with class code 03
+void agp_cards(device_slot_interface &device)
+{
+ device.option_add("riva128", RIVA128);
+ device.option_add("riva128zx", RIVA128ZX);
+ device.option_add("rivatnt", RIVATNT);
+ device.option_add("rivatnt2", RIVATNT2);
+ device.option_add("rivatnt2_ultra", RIVATNT2_ULTRA);
+ device.option_add("vanta", VANTA);
+ device.option_add("rivatnt2_m64", RIVATNT2_M64);
+ device.option_add("geforce256", GEFORCE256);
+ device.option_add("geforce256_ddr", GEFORCE256_DDR);
+ device.option_add("quadro", QUADRO);
+ device.option_add("laguna3d", CIRRUS_GD5465_LAGUNA3D);
+}
diff --git a/src/devices/bus/pci/pci_slot.h b/src/devices/bus/pci/pci_slot.h
index e37cea79bd88a..7c8c17ff32087 100644
--- a/src/devices/bus/pci/pci_slot.h
+++ b/src/devices/bus/pci/pci_slot.h
@@ -87,5 +87,6 @@ class pci_card_device : public pci_device, public pci_card_interface
DECLARE_DEVICE_TYPE(PCI_SLOT, pci_slot_device)
void pci_cards(device_slot_interface &device);
+void agp_cards(device_slot_interface &device);
#endif
diff --git a/src/devices/bus/pci/pdc20262.cpp b/src/devices/bus/pci/pdc20262.cpp
new file mode 100644
index 0000000000000..022f1f2fc9c8f
--- /dev/null
+++ b/src/devices/bus/pci/pdc20262.cpp
@@ -0,0 +1,263 @@
+// license:BSD-3-Clause
+// copyright-holders: Angelo Salese
+/**************************************************************************************************
+
+Promise PDC20262 FastTrak66/UDMA66 IDE controller
+
+No documentation, ATA4 complaint
+
+TODO:
+- how it sets compatible/native modes? Subvendor ID list suggests it can switch at will;
+- Install win9x driver causes huge loading hiccups, eventually freezes by accessing drive with
+ explorer.exe (enable UDMA?). For common use is **suggested** to not install them.
+- Reportedly has issues with very big HDDs, pinpoint limit and assuming there isn't an issue here.
+\- Tested with Seagate Barracuda ST380021A -chs=158816,16,63 (expected: 80GB, actual: 13655MB)
+- Marketed as RAID card, verify;
+\- Gets classified as SCSI controller in win9x device manager;
+- ID and hookup Flash ROM type;
+- PME 1.0 support (no low power states D1/D2, no PME#)
+
+**************************************************************************************************/
+
+#include "emu.h"
+#include "pdc20262.h"
+
+#define LOG_WARN (1U << 1)
+
+#define VERBOSE (LOG_GENERAL | LOG_WARN)
+//#define LOG_OUTPUT_FUNC osd_printf_info
+#include "logmacro.h"
+
+#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
+
+
+DEFINE_DEVICE_TYPE(PDC20262, pdc20262_device, "pdc20262", "Promise PDC20262 FastTrak66 EIDE controller")
+
+
+
+pdc20262_device::pdc20262_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : pci_card_device(mconfig, type, tag, owner, clock)
+ , m_ide1(*this, "ide1")
+ , m_ide2(*this, "ide2")
+ , m_irqs(*this, "irqs")
+ // HACK: how to get to get_pci_busmaster_space()?
+ , m_bus_master_space(*this, ":maincpu", 0)
+ , m_bios_rom(*this, "bios_rom")
+{
+ // Subsystems:
+ // 105a 4d30 Ultra Device on SuperTrak
+ // 105a 4d33 Ultra66
+ // 105a 4d39 FastTrak66
+ // class code is trusted, bp 0xca09c
+ // assume revision depending on BIOS
+ set_ids(0x105a4d38, 0x02, 0x018000, 0x105a4d33);
+}
+
+pdc20262_device::pdc20262_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : pdc20262_device(mconfig, PDC20262, tag, owner, clock)
+{
+}
+
+ROM_START( pdc20262 )
+ ROM_REGION32_LE( 0x8000, "bios_rom", ROMREGION_ERASEFF )
+ ROM_DEFAULT_BIOS("v200")
+
+ ROM_SYSTEM_BIOS( 0, "v200", "Promise Ultra66 BIOS v2.00 (Build 18)" )
+ ROMX_LOAD( "ul200b18.bin", 0x0000, 0x4000, CRC(71e48d73) SHA1(84d8c72118a3e26181573412e2cbb859691672de), ROM_BIOS(0) )
+ ROM_SYSTEM_BIOS( 1, "v114", "Promise Ultra66 BIOS v1.14 (Build 0728)" )
+ ROMX_LOAD( "ul114b0728.bin", 0x0000, 0x4000, CRC(a71f0c3d) SHA1(ace4872c6060e9dd8458540c0f3193d1a9b4321a), ROM_BIOS(1) )
+
+ // v1.12 known to exist
+ROM_END
+
+const tiny_rom_entry *pdc20262_device::device_rom_region() const
+{
+ return ROM_NAME(pdc20262);
+}
+
+
+void pdc20262_device::device_add_mconfig(machine_config &config)
+{
+ INPUT_MERGER_ANY_HIGH(config, m_irqs).output_handler().set([this] (int state) {
+ irq_pin_w(0, state);
+ });
+
+ BUS_MASTER_IDE_CONTROLLER(config, m_ide1).options(ata_devices, "hdd", nullptr, false);
+ m_ide1->irq_handler().set([this] (int state) {
+ m_irq_state &= ~0x4;
+ m_irq_state |= (state << 2);
+ m_irqs->in_w<0>(state);
+ });
+ m_ide1->set_bus_master_space(m_bus_master_space);
+
+ BUS_MASTER_IDE_CONTROLLER(config, m_ide2).options(ata_devices, nullptr, nullptr, false);
+ m_ide2->irq_handler().set([this] (int state) {
+ m_irq_state &= ~0x40;
+ m_irq_state |= (state << 6);
+ m_irqs->in_w<1>(state);
+ });
+ m_ide2->set_bus_master_space(m_bus_master_space);
+}
+
+// $1f0
+void pdc20262_device::ide1_command_map(address_map &map)
+{
+ map(0, 7).rw(FUNC(pdc20262_device::ide1_read32_cs0_r), FUNC(pdc20262_device::ide1_write32_cs0_w));
+}
+
+// $3f4
+void pdc20262_device::ide1_control_map(address_map &map)
+{
+ map(2, 2).rw(FUNC(pdc20262_device::ide1_read_cs1_r), FUNC(pdc20262_device::ide1_write_cs1_w));
+}
+
+// $170
+void pdc20262_device::ide2_command_map(address_map &map)
+{
+ map(0, 7).rw(FUNC(pdc20262_device::ide2_read32_cs0_r), FUNC(pdc20262_device::ide2_write32_cs0_w));
+}
+
+// $374
+void pdc20262_device::ide2_control_map(address_map &map)
+{
+ map(2, 2).rw(FUNC(pdc20262_device::ide2_read_cs1_r), FUNC(pdc20262_device::ide2_write_cs1_w));
+}
+
+void pdc20262_device::bus_master_ide_control_map(address_map &map)
+{
+ map(0x00, 0x07).rw(m_ide1, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w));
+ map(0x08, 0x0f).rw(m_ide2, FUNC(bus_master_ide_controller_device::bmdma_r), FUNC(bus_master_ide_controller_device::bmdma_w));
+
+ map(0x11, 0x11).lrw8(
+ NAME([this] () {
+ return m_clock;
+ }),
+ NAME([this] (u8 data) {
+ LOG("extra $11: Clock set %02x\n", data);
+ m_clock = data;
+ })
+ );
+
+// map(0x1a, 0x1a) Primary Mode
+// map(0x1b, 0x1b) Secondary Mode
+/*
+ * upper nibble secondary, lower primary
+ *
+ * x--- error
+ * -x-- irq
+ * --x- FIFO full
+ * ---x FIFO empty
+ */
+ map(0x1d, 0x1d).lr8(
+ NAME([this] () {
+ // FIXME: definitely requires a FIFO i/f
+ return m_irq_state | 1;
+ })
+ );
+// map(0x1f, 0x1f) Ultra DMA speed flag
+}
+
+void pdc20262_device::extra_map(address_map &map)
+{
+ // TODO: should be memory mapped versions of above, *nix driver seems to use this
+// map(0x00, 0x07).m(*this, FUNC(pdc20262_device::ide1_command_map)));
+// ...
+}
+
+void pdc20262_device::device_start()
+{
+ pci_card_device::device_start();
+
+ add_map(8, M_IO, FUNC(pdc20262_device::ide1_command_map));
+ add_map(4, M_IO, FUNC(pdc20262_device::ide1_control_map));
+ add_map(8, M_IO, FUNC(pdc20262_device::ide2_command_map));
+ add_map(4, M_IO, FUNC(pdc20262_device::ide2_control_map));
+ add_map(32, M_IO, FUNC(pdc20262_device::bus_master_ide_control_map));
+ // TODO: unknown size (a lot larger?), to be verified later thru PnP
+ add_map(64, M_MEM, FUNC(pdc20262_device::extra_map));
+
+ add_rom((u8 *)m_bios_rom->base(), 0x4000);
+ expansion_rom_base = 0xc8000;
+
+ // INTA#
+ intr_pin = 1;
+}
+
+void pdc20262_device::device_reset()
+{
+ pci_card_device::device_reset();
+
+ command = 0x0000;
+ command_mask = 7;
+ status = 0x0210;
+
+ remap_cb();
+}
+
+void pdc20262_device::config_map(address_map &map)
+{
+ pci_card_device::config_map(map);
+ // latency timer
+ map(0x0d, 0x0d).lr8(NAME([] () { return 0x01; }));
+ // TODO: everything, starting from capptr_r override
+}
+
+/*
+ * Start of legacy handling, to be moved out
+ */
+
+uint32_t pdc20262_device::ide1_read32_cs0_r(offs_t offset, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return 0xffffffff;
+ return m_ide1->read_cs0(offset, mem_mask);
+}
+
+void pdc20262_device::ide1_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return;
+ m_ide1->write_cs0(offset, data, mem_mask);
+}
+
+uint32_t pdc20262_device::ide2_read32_cs0_r(offs_t offset, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return 0xffffffff;
+ return m_ide2->read_cs0(offset, mem_mask);
+}
+
+void pdc20262_device::ide2_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (!(command & 1))
+ return;
+ m_ide2->write_cs0(offset, data, mem_mask);
+}
+
+uint8_t pdc20262_device::ide1_read_cs1_r()
+{
+ if (!(command & 1))
+ return 0xff;
+ return m_ide1->read_cs1(1, 0xff0000) >> 16;
+}
+
+void pdc20262_device::ide1_write_cs1_w(uint8_t data)
+{
+ if (!(command & 1))
+ return;
+ m_ide1->write_cs1(1, data << 16, 0xff0000);
+}
+
+uint8_t pdc20262_device::ide2_read_cs1_r()
+{
+ if (!(command & 1))
+ return 0xff;
+ return m_ide2->read_cs1(1, 0xff0000) >> 16;
+}
+
+void pdc20262_device::ide2_write_cs1_w(uint8_t data)
+{
+ if (!(command & 1))
+ return;
+ m_ide2->write_cs1(1, data << 16, 0xff0000);
+}
diff --git a/src/devices/bus/pci/pdc20262.h b/src/devices/bus/pci/pdc20262.h
new file mode 100644
index 0000000000000..f448894eb033f
--- /dev/null
+++ b/src/devices/bus/pci/pdc20262.h
@@ -0,0 +1,65 @@
+// license:BSD-3-Clause
+// copyright-holders: Angelo Salese
+
+#ifndef MAME_BUS_PCI_PDC20262_H
+#define MAME_BUS_PCI_PDC20262_H
+
+#pragma once
+
+#include "pci_slot.h"
+#include "machine/idectrl.h"
+#include "machine/input_merger.h"
+
+class pdc20262_device : public pci_card_device
+{
+public:
+ pdc20262_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ static constexpr feature_type imperfect_features() { return feature::DISK; }
+
+protected:
+ pdc20262_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+// virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
+// uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
+
+ virtual void config_map(address_map &map) override;
+
+private:
+ void ide1_command_map(address_map &map);
+ void ide1_control_map(address_map &map);
+ void ide2_command_map(address_map &map);
+ void ide2_control_map(address_map &map);
+ void bus_master_ide_control_map(address_map &map);
+ void extra_map(address_map &map);
+
+// virtual void device_config_complete() override;
+
+ required_device m_ide1;
+ required_device m_ide2;
+ required_device m_irqs;
+ required_address_space m_bus_master_space;
+ required_memory_region m_bios_rom;
+
+ u8 m_clock = 0;
+ u8 m_irq_state = 0;
+
+ uint32_t ide1_read32_cs0_r(offs_t offset, uint32_t mem_mask = ~0);
+ void ide1_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+ uint32_t ide2_read32_cs0_r(offs_t offset, uint32_t mem_mask = ~0);
+ void ide2_write32_cs0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+ uint8_t ide1_read_cs1_r();
+ void ide1_write_cs1_w(uint8_t data);
+ uint8_t ide2_read_cs1_r();
+ void ide2_write_cs1_w(uint8_t data);
+};
+
+DECLARE_DEVICE_TYPE(PDC20262, pdc20262_device)
+
+#endif // MAME_BUS_PCI_PDC20262_H
diff --git a/src/devices/bus/pci/virge_pci.cpp b/src/devices/bus/pci/virge_pci.cpp
index 847796bba12ad..9ff07e24b5177 100644
--- a/src/devices/bus/pci/virge_pci.cpp
+++ b/src/devices/bus/pci/virge_pci.cpp
@@ -138,12 +138,12 @@ void virge_pci_device::linear_config_changed_w(int state)
uint8_t virge_pci_device::vram_r(offs_t offset)
{
- return downcast(m_vga.target())->mem_r(offset);
+ return downcast(m_vga.target())->mem_r(offset);
}
void virge_pci_device::vram_w(offs_t offset, uint8_t data)
{
- downcast(m_vga.target())->mem_w(offset, data);
+ downcast(m_vga.target())->mem_w(offset, data);
}
void virge_pci_device::postload()
diff --git a/src/devices/bus/pci/vision.cpp b/src/devices/bus/pci/vision.cpp
new file mode 100644
index 0000000000000..ed6ab003613e9
--- /dev/null
+++ b/src/devices/bus/pci/vision.cpp
@@ -0,0 +1,286 @@
+// license:BSD-3-Clause
+// copyright-holders: Angelo Salese
+/**************************************************************************************************
+
+S3 Vision 864 / 868 / 964 / 968
+
+TODO:
+- Add Vision868
+- Add Trio32/Trio64, pillage roms from isa/svga_s3
+- Make ViRGE to derive from here rather than reinventing the wheel
+
+Notes:
+- Some of these BIOSes are buggy in SDD VBETEST.EXE, doesn't return any video mode,
+ Reportedly mirocrys (vision964) and no9fx771 (vision968) has this inconvenient.
+
+**************************************************************************************************/
+
+#include "emu.h"
+#include "vision.h"
+
+#define LOG_WARN (1U << 1)
+
+#define VERBOSE (LOG_GENERAL | LOG_WARN)
+//#define LOG_OUTPUT_FUNC osd_printf_info
+#include "logmacro.h"
+
+#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
+
+
+DEFINE_DEVICE_TYPE(VISION864_PCI, vision864_pci_device, "vision864", "S3 86C864 Vision864")
+// Vision868
+DEFINE_DEVICE_TYPE(VISION964_PCI, vision964_pci_device, "vision964", "S3 86C964 Vision964")
+DEFINE_DEVICE_TYPE(VISION968_PCI, vision968_pci_device, "vision968", "S3 86C968 Vision968")
+
+
+
+vision864_pci_device::vision864_pci_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : pci_card_device(mconfig, type, tag, owner, clock)
+ , m_vga(*this, "vga")
+ , m_bios(*this, "bios")
+{
+}
+
+vision864_pci_device::vision864_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : vision864_pci_device(mconfig, VISION864_PCI, tag, owner, clock)
+{
+ // device IDs:
+ // 88c0 = 86c864 DRAM v0
+ // 88c1 = 86c864 DRAM v1
+ // 88c2 = 86c864-P DRAM v2
+ // 88c3 = 86c864-P DRAM v3
+ // NOTE: class code = 0 (backward compatible VGA device)
+ set_ids(0x533388c1, 0x00, 0x000100, 0x00000000);
+}
+
+ROM_START( vision864 )
+ ROM_REGION32_LE( 0x8000, "bios", ROMREGION_ERASEFF )
+ ROM_SYSTEM_BIOS( 0, "vision864", "Phoenix S3 Vision864 1.04-01" )
+ ROMX_LOAD( "bios.bin", 0x0000, 0x8000, CRC(791c9e0d) SHA1(340a64402958d2ee734d929dfce147d9afcf23f4), ROM_BIOS(0) )
+ ROM_IGNORE( 0x8000 )
+ROM_END
+
+const tiny_rom_entry *vision864_pci_device::device_rom_region() const
+{
+ return ROM_NAME(vision864);
+}
+
+void vision864_pci_device::device_add_mconfig(machine_config &config)
+{
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
+ screen.set_raw(XTAL(25'174'800), 900, 0, 640, 526, 0, 480);
+ screen.set_screen_update("vga", FUNC(s3vision864_vga_device::screen_update));
+
+ S3_VISION864_VGA(config, m_vga, 0);
+ m_vga->set_screen("screen");
+ // 1MB, option for 2MB
+ m_vga->set_vram_size(2*1024*1024);
+}
+
+void vision864_pci_device::device_start()
+{
+ pci_card_device::device_start();
+
+// add_map(64 * 1024 * 1024, M_MEM | M_DISABLED, FUNC(vision864_pci_device::lfb_map));
+// set_map_address(0, 0x70000000);
+
+ add_rom((u8 *)m_bios->base(), 0x8000);
+ expansion_rom_base = 0xc0000;
+
+ // TODO: can't read the intr pin reg but still has an INTA#
+}
+
+void vision864_pci_device::device_reset()
+{
+ pci_card_device::device_reset();
+
+ command = 0x0020;
+ command_mask = 0x23;
+ // Medium DEVSEL
+ status = 0x0200;
+
+ remap_cb();
+}
+
+void vision864_pci_device::legacy_io_map(address_map &map)
+{
+ map(0, 0x02f).m(m_vga, FUNC(s3vision864_vga_device::io_map));
+}
+
+uint8_t vision864_pci_device::vram_r(offs_t offset)
+{
+ return downcast(m_vga.target())->mem_r(offset);
+}
+
+void vision864_pci_device::vram_w(offs_t offset, uint8_t data)
+{
+ downcast(m_vga.target())->mem_w(offset, data);
+}
+
+void vision864_pci_device::map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
+ uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space)
+{
+ if (BIT(command, 1))
+ {
+ memory_space->install_readwrite_handler(0xa0000, 0xbffff, read8sm_delegate(*this, FUNC(vision864_pci_device::vram_r)), write8sm_delegate(*this, FUNC(vision864_pci_device::vram_w)));
+ }
+
+ if (BIT(command, 0))
+ {
+ io_space->install_device(0x03b0, 0x03df, *this, &vision864_pci_device::legacy_io_map);
+ }
+}
+
+/******************
+ *
+ * Vision964
+ *
+ *****************/
+
+vision964_pci_device::vision964_pci_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : vision864_pci_device(mconfig, type, tag, owner, clock)
+{
+}
+
+vision964_pci_device::vision964_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : vision964_pci_device(mconfig, VISION964_PCI, tag, owner, clock)
+{
+ // device IDs:
+ // 88d0-88d1 = 86c964 VRAM v0-1
+ // 88d2-88d3 = 86c964-P VRAM v2-3
+ // NOTE: class code = 0 (backward compatible VGA device)
+ set_ids(0x533388d0, 0x00, 0x000100, 0x00000000);
+}
+
+ROM_START( vision964 )
+ ROM_REGION32_LE( 0x8000, "bios", ROMREGION_ERASEFF )
+ ROM_DEFAULT_BIOS("mirocrys")
+
+ ROM_SYSTEM_BIOS( 0, "mirocrys", "miroCRYSTAL Rev.2.13" )
+ ROMX_LOAD( "mirocrystal.vbi", 0x0000, 0x8000, CRC(d0b0aa1c) SHA1(004e2432c4783f1539a7989e7d9ee422df09e695), ROM_BIOS(0) )
+ROM_END
+
+const tiny_rom_entry *vision964_pci_device::device_rom_region() const
+{
+ return ROM_NAME(vision964);
+}
+
+void vision964_pci_device::device_add_mconfig(machine_config &config)
+{
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
+ screen.set_raw(XTAL(25'174'800), 900, 0, 640, 526, 0, 480);
+ screen.set_screen_update("vga", FUNC(s3vision964_vga_device::screen_update));
+
+ S3_VISION964_VGA(config, m_vga, 0);
+ m_vga->set_screen("screen");
+ // 2MB/4MB/8MB
+ m_vga->set_vram_size(4*1024*1024);
+}
+
+
+/******************
+ *
+ * Vision968
+ *
+ *****************/
+
+vision968_pci_device::vision968_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : vision964_pci_device(mconfig, VISION968_PCI, tag, owner, clock)
+{
+ // device IDs:
+ // 88f0-88f3 = 86c968 RAM v0-3
+ // first device to actually have a real class code
+ set_ids(0x533388f0, 0x00, 0x030000, 0x00000000);
+}
+
+ROM_START( vision968 )
+ ROM_REGION32_LE( 0x8000, "bios", ROMREGION_ERASEFF )
+ ROM_DEFAULT_BIOS("elsaw2k")
+
+ ROM_SYSTEM_BIOS( 0, "no9fx771", "Number Nine 9FX MotionFX 771 v2.45.11" )
+ ROMX_LOAD( "no9motionfx771.bin", 0x0000, 0x8000, CRC(7732e382) SHA1(9ec2fe056712cef39bd8380d406be3c874ea5ec9), ROM_BIOS(0) )
+ ROM_IGNORE( 0x8000 )
+
+ ROM_SYSTEM_BIOS( 1, "elsaw2k", "Elsa Winner 2000Pro/X-8 v1.21.01-B" )
+ ROMX_LOAD( "elsaw20008m.bin", 0x0000, 0x8000, CRC(47563211) SHA1(f51a40956c3e6e7c86851d81f81ba5f77509d361), ROM_BIOS(1) )
+ ROM_IGNORE( 0x8000 )
+
+ ROM_SYSTEM_BIOS( 2, "speamp64", "SPEA/Videoseven V7-Mercury P-64 v1.01-08" )
+ ROMX_LOAD( "spea.bin", 0x0000, 0x8000, CRC(2caeadaf) SHA1(236829f1e6065a2f0ebee91f71891d8402f0ab5a), ROM_BIOS(2) )
+ ROM_IGNORE( 0x8000 )
+ROM_END
+
+const tiny_rom_entry *vision968_pci_device::device_rom_region() const
+{
+ return ROM_NAME(vision968);
+}
+
+void vision968_pci_device::device_add_mconfig(machine_config &config)
+{
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
+ screen.set_raw(XTAL(25'174'800), 900, 0, 640, 526, 0, 480);
+ screen.set_screen_update("vga", FUNC(s3vision968_vga_device::screen_update));
+
+ S3_VISION968_VGA(config, m_vga, 0);
+ m_vga->set_screen("screen");
+ // 2MB/4MB/8MB
+ m_vga->set_vram_size(4*1024*1024);
+// m_vga->linear_config_changed().set(FUNC(s3vision864_vga_device::linear_config_changed_w));
+}
+
+void vision968_pci_device::device_start()
+{
+ pci_card_device::device_start();
+
+// add_map(64 * 1024 * 1024, M_MEM | M_DISABLED, FUNC(vision968_pci_device::lfb_map));
+ add_map(64 * 1024 * 1024, M_MEM, FUNC(vision968_pci_device::lfb_map));
+ set_map_address(0, 0x70000000);
+
+ add_rom((u8 *)m_bios->base(), 0x8000);
+ expansion_rom_base = 0xc0000;
+
+ // INTA#
+ intr_pin = 1;
+}
+
+void vision968_pci_device::device_reset()
+{
+ pci_card_device::device_reset();
+
+ command = 0x0020;
+ command_mask = 0x23;
+ // Adds fast back-to-back
+ status = 0x0280;
+
+ remap_cb();
+}
+
+// TODO: 0x0200'0000 "mirror" (really an endian relocation?)
+void vision968_pci_device::lfb_map(address_map &map)
+{
+ map(0x0000'0000, 0x00ff'ffff).rw(m_vga, FUNC(s3vision864_vga_device::mem_linear_r), FUNC(s3vision864_vga_device::mem_linear_w));
+// map(0x0100'0000, 0x0100'7fff) image transfer data
+ map(0x0100'8000, 0x0100'803f).m(FUNC(vision968_pci_device::config_map));
+// map(0x0100'8100, 0x0100'816f) packed copro regs
+// map(0x0100'82e8, 0x0100'82e8) current ypos
+// map(0x0100'82ea, 0x0100'82ea) current ypos-2
+ map(0x0100'83b0, 0x0100'83df).m(m_vga, FUNC(s3vision968_vga_device::io_map));
+// map(0x0100'8502, 0x0100'8502) (VGA $0102 alias)
+// map(0x0100'8504, 0x0100'8504) (VGA $42e8 alias)
+// map(0x0100'8508, 0x0100'8508) (VGA $46e8 alias)
+// map(0x0100'850c, 0x0100'850c) (VGA $4ae8 alias)
+// map(0x0100'86e8, 0x0100'8eea) PnP copro region
+// map(0x0101'0000, 0x0101'3fff) Pixel formatter data transfer
+// map(0x0101'4000, 0x0101'7fff) Pixel formatter Mask data
+// map(0x0101'8080, 0x0101'809f) Pixel formatter regs
+}
+
+void vision968_pci_device::map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
+ uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space)
+{
+ vision964_pci_device::map_extra(
+ memory_window_start, memory_window_end, memory_offset, memory_space,
+ io_window_start, io_window_end, io_offset, io_space
+ );
+ // TODO: new MMIO goes here
+}
diff --git a/src/devices/bus/pci/vision.h b/src/devices/bus/pci/vision.h
new file mode 100644
index 0000000000000..f1e9439ddb6f9
--- /dev/null
+++ b/src/devices/bus/pci/vision.h
@@ -0,0 +1,76 @@
+// license:BSD-3-Clause
+// copyright-holders: Angelo Salese
+
+#ifndef MAME_BUS_PCI_S3VISION_PCI_H
+#define MAME_BUS_PCI_S3VISION_PCI_H
+
+#pragma once
+
+#include "pci_slot.h"
+
+#include "video/pc_vga_s3.h"
+
+class vision864_pci_device : public pci_card_device
+{
+public:
+ vision864_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ static constexpr feature_type imperfect_features() { return feature::GRAPHICS; }
+
+ void legacy_io_map(address_map &map);
+
+protected:
+ vision864_pci_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
+ uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
+
+ required_device m_vga;
+ required_memory_region m_bios;
+private:
+ u8 vram_r(offs_t offset);
+ void vram_w(offs_t offset, uint8_t data);
+};
+
+class vision964_pci_device : public vision864_pci_device
+{
+public:
+ vision964_pci_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ vision964_pci_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual const tiny_rom_entry *device_rom_region() const override;
+};
+
+class vision968_pci_device : public vision964_pci_device
+{
+public:
+ vision968_pci_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;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
+ uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
+
+ void lfb_map(address_map &map);
+};
+
+DECLARE_DEVICE_TYPE(VISION864_PCI, vision864_pci_device)
+DECLARE_DEVICE_TYPE(VISION964_PCI, vision964_pci_device)
+DECLARE_DEVICE_TYPE(VISION968_PCI, vision968_pci_device)
+
+#endif // MAME_BUS_PCI_S3VISION_PCI_H
diff --git a/src/devices/bus/plg100/plg100.cpp b/src/devices/bus/plg100/plg100.cpp
deleted file mode 100644
index 80da3152c7cbd..0000000000000
--- a/src/devices/bus/plg100/plg100.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert
-
-#include "emu.h"
-#include "plg100.h"
-
-#include "vl.h"
-
-DEFINE_DEVICE_TYPE(PLG100_CONNECTOR, plg100_connector, "plg100_connector", "PLG100 extension connector")
-
-plg100_connector::plg100_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, PLG100_CONNECTOR, tag, owner, clock),
- device_single_card_slot_interface(mconfig, *this),
- device_mixer_interface(mconfig, *this, 2),
- m_midi_tx(*this)
-{
-}
-
-void plg100_connector::device_start()
-{
- save_item(NAME(m_state_system_is_annoying));
-}
-
-void plg100_connector::midi_rx(int state)
-{
- auto card = get_card_device();
- if(card)
- card->midi_rx(state);
-}
-
-void plg100_intf(device_slot_interface &device)
-{
- device.option_add("vl", PLG100_VL);
-}
-
-device_plg100_interface::device_plg100_interface(const machine_config &mconfig, device_t &device) :
- device_interface(device, "plg100"),
- m_connector(nullptr)
-{
-}
-
-device_plg100_interface::~device_plg100_interface()
-{
-}
-
-void device_plg100_interface::interface_pre_start()
-{
- m_connector = downcast(device().owner());
-}
diff --git a/src/devices/bus/plg100/vl.h b/src/devices/bus/plg100/vl.h
deleted file mode 100644
index 57e1b520a3803..0000000000000
--- a/src/devices/bus/plg100/vl.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert
-
-#ifndef MAME_BUS_PLG100_VL_H
-#define MAME_BUS_PLG100_VL_H
-
-// Yamaha PLG100-VL
-
-#pragma once
-
-#include "plg100.h"
-
-DECLARE_DEVICE_TYPE(PLG100_VL, device_plg100_interface)
-
-#endif // MAME_BUS_PLG100_VL_H
diff --git a/src/devices/bus/plg100/vl.cpp b/src/devices/bus/plg1x0/plg100-vl.cpp
similarity index 91%
rename from src/devices/bus/plg100/vl.cpp
rename to src/devices/bus/plg1x0/plg100-vl.cpp
index ec89fbeab0abc..177813052df6f 100644
--- a/src/devices/bus/plg100/vl.cpp
+++ b/src/devices/bus/plg1x0/plg100-vl.cpp
@@ -8,14 +8,14 @@
// Build around a h8 for the control and a dsp-v for the synthesis
#include "emu.h"
-#include "vl.h"
+#include "plg100-vl.h"
#include "cpu/h8/h83002.h"
#include "sound/dspv.h"
namespace {
-class plg100_vl_device : public device_t, public device_plg100_interface
+class plg100_vl_device : public device_t, public device_plg1x0_interface
{
public:
plg100_vl_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
@@ -38,7 +38,7 @@ class plg100_vl_device : public device_t, public device_plg100_interface
plg100_vl_device::plg100_vl_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, PLG100_VL, tag, owner, clock),
- device_plg100_interface(mconfig, *this),
+ device_plg1x0_interface(mconfig, *this),
m_cpu(*this, "cpu"),
m_dspv(*this, "dspv")
{
@@ -50,7 +50,7 @@ plg100_vl_device::~plg100_vl_device()
void plg100_vl_device::midi_rx(int state)
{
- m_cpu->sci_rx_w<0>(state);
+ m_cpu->sci_rx_w<1>(state);
}
void plg100_vl_device::map(address_map &map)
@@ -93,4 +93,4 @@ const tiny_rom_entry *plg100_vl_device::device_rom_region() const
} // anonymous namespace
-DEFINE_DEVICE_TYPE_PRIVATE(PLG100_VL, device_plg100_interface, plg100_vl_device, "plg100_vl", "Yamaha PLG100-VL")
+DEFINE_DEVICE_TYPE_PRIVATE(PLG100_VL, device_plg1x0_interface, plg100_vl_device, "plg100_vl", "Yamaha PLG100-VL")
diff --git a/src/devices/bus/plg1x0/plg100-vl.h b/src/devices/bus/plg1x0/plg100-vl.h
new file mode 100644
index 0000000000000..6ff3cd48a8f93
--- /dev/null
+++ b/src/devices/bus/plg1x0/plg100-vl.h
@@ -0,0 +1,15 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+#ifndef MAME_BUS_PLG1X0_PLG100VL_H
+#define MAME_BUS_PLG1X0_PLG100VL_H
+
+// Yamaha PLG100-VL
+
+#pragma once
+
+#include "plg1x0.h"
+
+DECLARE_DEVICE_TYPE(PLG100_VL, device_plg1x0_interface)
+
+#endif // MAME_BUS_PLG1X0_PLG100_VL_H
diff --git a/src/devices/bus/plg1x0/plg150-ap.cpp b/src/devices/bus/plg1x0/plg150-ap.cpp
new file mode 100644
index 0000000000000..103e7a2c8c7a6
--- /dev/null
+++ b/src/devices/bus/plg1x0/plg150-ap.cpp
@@ -0,0 +1,89 @@
+// license:BSD-3-Clause
+// copyright-holders: Olivier Galibert
+
+// Yamaha PLG150-AP
+
+// Acoustic Piano, a plugin dedicated to a high-quality piano sound
+
+// Dual SWX00
+
+#include "emu.h"
+#include "plg150-ap.h"
+
+#include "cpu/h8/swx00.h"
+
+namespace {
+
+class plg150_ap_device : public device_t, public device_plg1x0_interface
+{
+public:
+ plg150_ap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ virtual ~plg150_ap_device();
+
+ virtual void midi_rx(int state) override;
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ required_device m_cpu;
+
+ void map(address_map &map);
+};
+
+plg150_ap_device::plg150_ap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, PLG150_AP, tag, owner, clock),
+ device_plg1x0_interface(mconfig, *this),
+ m_cpu(*this, "cpu")
+{
+}
+
+plg150_ap_device::~plg150_ap_device()
+{
+}
+
+void plg150_ap_device::midi_rx(int state)
+{
+ m_cpu->sci_rx_w<1>(state);
+}
+
+void plg150_ap_device::map(address_map &map)
+{
+ map(0x000000, 0x07ffff).rom().region("cpu", 0);
+}
+
+void plg150_ap_device::device_add_mconfig(machine_config &config)
+{
+ SWX00(config, m_cpu, 8.4672_MHz_XTAL, 1);
+ m_cpu->set_addrmap(AS_PROGRAM, &plg150_ap_device::map);
+ m_cpu->write_sci_tx<1>().set([this] (int state) { m_connector->do_midi_tx(state); });
+}
+
+ROM_START( plg150_ap )
+ ROM_REGION( 0x80000, "cpu", 0 )
+ ROM_LOAD16_WORD_SWAP( "x5757b0.ic03", 0x00000, 0x80000, CRC(5383b363) SHA1(b8e8e0673439c80dc9aecd6638f1c20454c82080) )
+
+ ROM_REGION( 0x1000000, "swx00", 0 )
+ ROM_LOAD( "x575810.ic09", 0x000000, 0x800000, CRC(273b4574) SHA1(b33d67f7fe3a020c19133cc52bd6a228227941c5) )
+ ROM_LOAD( "x575910.ic11", 0x800000, 0x800000, CRC(32a37ef3) SHA1(c0b5dfb1fbb5a3ddd33e6303039fbc197478abd2) )
+ROM_END
+
+void plg150_ap_device::device_start()
+{
+}
+
+void plg150_ap_device::device_reset()
+{
+}
+
+const tiny_rom_entry *plg150_ap_device::device_rom_region() const
+{
+ return ROM_NAME(plg150_ap);
+}
+
+} // anonymous namespace
+
+DEFINE_DEVICE_TYPE_PRIVATE(PLG150_AP, device_plg1x0_interface, plg150_ap_device, "plg150_ap", "Yamaha PLG150-AP")
diff --git a/src/devices/bus/plg1x0/plg150-ap.h b/src/devices/bus/plg1x0/plg150-ap.h
new file mode 100644
index 0000000000000..8e56ed6061c87
--- /dev/null
+++ b/src/devices/bus/plg1x0/plg150-ap.h
@@ -0,0 +1,15 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+#ifndef MAME_BUS_PLG1X0_PLG150AP_H
+#define MAME_BUS_PLG1X0_PLG150AP_H
+
+// Yamaha PLG150-AP
+
+#pragma once
+
+#include "plg1x0.h"
+
+DECLARE_DEVICE_TYPE(PLG150_AP, device_plg1x0_interface)
+
+#endif // MAME_BUS_PLG1X0_PLG150_AP_H
diff --git a/src/devices/bus/plg1x0/plg1x0.cpp b/src/devices/bus/plg1x0/plg1x0.cpp
new file mode 100644
index 0000000000000..6abd510020985
--- /dev/null
+++ b/src/devices/bus/plg1x0/plg1x0.cpp
@@ -0,0 +1,51 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+#include "emu.h"
+#include "plg1x0.h"
+
+#include "plg100-vl.h"
+#include "plg150-ap.h"
+
+DEFINE_DEVICE_TYPE(PLG1X0_CONNECTOR, plg1x0_connector, "plg1x0_connector", "PLG1x0 extension connector")
+
+plg1x0_connector::plg1x0_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, PLG1X0_CONNECTOR, tag, owner, clock),
+ device_single_card_slot_interface(mconfig, *this),
+ device_mixer_interface(mconfig, *this, 2),
+ m_midi_tx(*this)
+{
+}
+
+void plg1x0_connector::device_start()
+{
+ save_item(NAME(m_state_system_is_annoying));
+}
+
+void plg1x0_connector::midi_rx(int state)
+{
+ auto card = get_card_device();
+ if(card)
+ card->midi_rx(state);
+}
+
+void plg1x0_intf(device_slot_interface &device)
+{
+ device.option_add("plg100vl", PLG100_VL);
+ device.option_add("plg150ap", PLG150_AP);
+}
+
+device_plg1x0_interface::device_plg1x0_interface(const machine_config &mconfig, device_t &device) :
+ device_interface(device, "plg1x0"),
+ m_connector(nullptr)
+{
+}
+
+device_plg1x0_interface::~device_plg1x0_interface()
+{
+}
+
+void device_plg1x0_interface::interface_pre_start()
+{
+ m_connector = downcast(device().owner());
+}
diff --git a/src/devices/bus/plg100/plg100.h b/src/devices/bus/plg1x0/plg1x0.h
similarity index 53%
rename from src/devices/bus/plg100/plg100.h
rename to src/devices/bus/plg1x0/plg1x0.h
index 18864f7e2dff9..8c049c215d58c 100644
--- a/src/devices/bus/plg100/plg100.h
+++ b/src/devices/bus/plg1x0/plg1x0.h
@@ -5,6 +5,9 @@
// MU series of expanders. It mostly provides two midi-rate (and midi
// protocol) serial lines (in and out) and two stereo serial sample
// streams (in and out too).
+//
+// The PLG150 series, the successor, seems essentially compatible.
+// The main difference is (in some cases) nvram to save settings.
// Known existing cards:
// PLG100-DX: DX7 as a plugin
@@ -12,20 +15,29 @@
// PLG100-VH: Voice Harmonizer, harmony effects on the A/D inputs
// PLG100-VL: Virtual Acoustic Synthesis, physical-modelling synthesis, a VL70-m on a plugin card
// PLG100-XG: MU50 as a plugin
+//
+// PLG150-AN: Analog Physical Modeling
+// PLG150-AP: Acoustic Piano
+// PLG150-DR: Drums
+// PLG150-DX: DX7 as a plugin
+// PLG150-PC: Latin drums
+// PLG150-PF: Piano
+// PLG150-VL: Virtual Acoustic Synthesis
-#ifndef MAME_BUS_PLG100_PLG100_H
-#define MAME_BUS_PLG100_PLG100_H
+
+#ifndef MAME_BUS_PLG1X0_PLG1X0_H
+#define MAME_BUS_PLG1X0_PLG1X0_H
#pragma once
-class device_plg100_interface;
+class device_plg1x0_interface;
-class plg100_connector: public device_t, public device_single_card_slot_interface, public device_mixer_interface
+class plg1x0_connector: public device_t, public device_single_card_slot_interface, public device_mixer_interface
{
public:
template
- plg100_connector(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt)
- : plg100_connector(mconfig, tag, owner, (uint32_t)0)
+ plg1x0_connector(const machine_config &mconfig, const char *tag, device_t *owner, T &&opts, const char *dflt)
+ : plg1x0_connector(mconfig, tag, owner, (uint32_t)0)
{
option_reset();
opts(*this);
@@ -33,7 +45,7 @@ class plg100_connector: public device_t, public device_single_card_slot_interfac
set_fixed(false);
}
- plg100_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ plg1x0_connector(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
void midi_rx(int state);
auto midi_tx() { return m_midi_tx.bind(); }
@@ -47,24 +59,24 @@ class plg100_connector: public device_t, public device_single_card_slot_interfac
virtual void device_start() override;
};
-class device_plg100_interface: public device_interface
+class device_plg1x0_interface: public device_interface
{
public:
- virtual ~device_plg100_interface();
+ virtual ~device_plg1x0_interface();
virtual void midi_rx(int state) = 0;
protected:
- plg100_connector *m_connector;
+ plg1x0_connector *m_connector;
- device_plg100_interface(const machine_config &mconfig, device_t &device);
+ device_plg1x0_interface(const machine_config &mconfig, device_t &device);
virtual void interface_pre_start() override;
};
-DECLARE_DEVICE_TYPE(PLG100_CONNECTOR, plg100_connector)
+DECLARE_DEVICE_TYPE(PLG1X0_CONNECTOR, plg1x0_connector)
-void plg100_intf(device_slot_interface &device);
+void plg1x0_intf(device_slot_interface &device);
-#endif // MAME_BUS_PLG100_PLG100_H
+#endif // MAME_BUS_PLG1X0_PLG1X0_H
diff --git a/src/devices/bus/vcs_ctrl/ctrl.cpp b/src/devices/bus/vcs_ctrl/ctrl.cpp
index 2ff11e88040c4..0ddccd7f2ed58 100644
--- a/src/devices/bus/vcs_ctrl/ctrl.cpp
+++ b/src/devices/bus/vcs_ctrl/ctrl.cpp
@@ -65,6 +65,7 @@ void vcs_control_port_device::device_start()
// SLOT_INTERFACE( vcs_control_port_devices )
//-------------------------------------------------
+#include "cx85.h"
#include "joybooster.h"
#include "joystick.h"
#include "keypad.h"
@@ -88,4 +89,6 @@ void a800_control_port_devices(device_slot_interface &device)
{
vcs_control_port_devices(device);
device.set_option_machine_config("pad", &vcs_paddles_device::reverse_players);
+
+ device.option_add("cx85", ATARI_CX85);
}
diff --git a/src/devices/bus/vcs_ctrl/cx85.cpp b/src/devices/bus/vcs_ctrl/cx85.cpp
new file mode 100644
index 0000000000000..6f987a99250b0
--- /dev/null
+++ b/src/devices/bus/vcs_ctrl/cx85.cpp
@@ -0,0 +1,123 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/**********************************************************************
+
+ Atari CX85 Numeric Keypad
+
+**********************************************************************/
+
+#include "emu.h"
+#include "cx85.h"
+
+#include "machine/rescap.h"
+
+
+//**************************************************************************
+// DEVICE TYPE DEFINITION
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(ATARI_CX85, atari_cx85_device, "atari_cx85", "Atari CX85 Numeric Keypad")
+
+
+//**************************************************************************
+// INPUT PORTS
+//**************************************************************************
+
+static INPUT_PORTS_START(atari_cx85)
+ PORT_START("X1")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_PLUS_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("X2")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad + Enter") PORT_CODE(KEYCODE_ENTER_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("X3")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("X4")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F4 (Yes)") PORT_CODE(KEYCODE_MINUS_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F2 (No)") PORT_CODE(KEYCODE_SLASH_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F3 (Delete)") PORT_CODE(KEYCODE_ASTERISK)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F1 (Escape)") PORT_CODE(KEYCODE_NUMLOCK)
+INPUT_PORTS_END
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// atari_cx85_device - constructor
+//-------------------------------------------------
+
+atari_cx85_device::atari_cx85_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, ATARI_CX85, tag, owner, clock)
+ , device_vcs_control_port_interface(mconfig, *this)
+ , m_encoder(*this, "encoder")
+{
+}
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void atari_cx85_device::device_add_mconfig(machine_config &config)
+{
+ MM74C923(config, m_encoder, 0); // MCM74C923N
+ m_encoder->set_cap_osc(CAP_U(.1));
+ m_encoder->set_cap_debounce(CAP_U(.47));
+ m_encoder->data_tri_callback().set_constant(0);
+ m_encoder->x1_rd_callback().set_ioport("X1");
+ m_encoder->x2_rd_callback().set_ioport("X2");
+ m_encoder->x3_rd_callback().set_ioport("X3");
+ m_encoder->x4_rd_callback().set_ioport("X4");
+ m_encoder->da_wr_callback().set(FUNC(atari_cx85_device::trigger_w)).invert();
+}
+
+//-------------------------------------------------
+// device_input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor atari_cx85_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(atari_cx85);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void atari_cx85_device::device_start()
+{
+}
+
+//-------------------------------------------------
+// vcs_joy_r - read digital inputs
+//-------------------------------------------------
+
+u8 atari_cx85_device::vcs_joy_r()
+{
+ // 74C923 outputs are buffered through 4049B
+ return (~m_encoder->read() & 0x0f) | (m_encoder->da_r() ? 0 : 0x20);
+}
+
+//-------------------------------------------------
+// vcs_pot_x_r - sample B pot
+//-------------------------------------------------
+
+u8 atari_cx85_device::vcs_pot_x_r()
+{
+ return BIT(m_encoder->read(), 4) ? 0 : 0xff;
+}
diff --git a/src/devices/bus/vcs_ctrl/cx85.h b/src/devices/bus/vcs_ctrl/cx85.h
new file mode 100644
index 0000000000000..32fca503a9f27
--- /dev/null
+++ b/src/devices/bus/vcs_ctrl/cx85.h
@@ -0,0 +1,54 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/**********************************************************************
+
+ Atari CX85 Numeric Keypad
+
+**********************************************************************/
+
+#ifndef MAME_BUS_VCS_CTRL_CX85_H
+#define MAME_BUS_VCS_CTRL_CX85_H
+
+#pragma once
+
+#include "ctrl.h"
+#include "machine/mm74c922.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> atari_cx85_device
+
+class atari_cx85_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ atari_cx85_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override;
+
+ // device_vcs_control_port_interface overrides
+ virtual u8 vcs_joy_r() override;
+ virtual u8 vcs_pot_x_r() override;
+
+ virtual bool has_pot_x() override { return true; }
+ virtual bool has_pot_y() override { return false; } // pin 9 not used
+
+private:
+ required_device m_encoder;
+};
+
+
+// device type declaration
+DECLARE_DEVICE_TYPE(ATARI_CX85, atari_cx85_device)
+
+#endif // MAME_BUS_VCS_CTRL_CX85_H
diff --git a/src/devices/cpu/g65816/g65816.cpp b/src/devices/cpu/g65816/g65816.cpp
index b44c99c561e82..b3c195f295e2a 100644
--- a/src/devices/cpu/g65816/g65816.cpp
+++ b/src/devices/cpu/g65816/g65816.cpp
@@ -258,10 +258,10 @@ unsigned g65816_device::g65816i_read_8_opcode(unsigned address)
unsigned g65816_device::g65816i_read_8_direct(unsigned address)
{
- if (FLAG_E)
+ if (FLAG_E && !MAKE_UINT_8(REGISTER_D))
{
/* force address into zero page */
- address = REGISTER_D + MAKE_UINT_8(address - REGISTER_D);
+ address = REGISTER_D | MAKE_UINT_8(address);
CLOCKS -= (bus_5A22_cycle_burst(address));
}
else
@@ -290,10 +290,10 @@ void g65816_device::g65816i_write_8_normal(unsigned address, unsigned value)
void g65816_device::g65816i_write_8_direct(unsigned address, unsigned value)
{
- if (FLAG_E)
+ if (FLAG_E && !MAKE_UINT_8(REGISTER_D))
{
/* force address into zero page */
- address = REGISTER_D + MAKE_UINT_8(address - REGISTER_D);
+ address = REGISTER_D | MAKE_UINT_8(address);
CLOCKS -= (bus_5A22_cycle_burst(address));
}
else
@@ -322,6 +322,23 @@ unsigned g65816_device::g65816i_read_16_direct(unsigned address)
(g65816i_read_8_direct(address+1)<<8);
}
+unsigned g65816_device::g65816i_read_16_direct_x(unsigned address)
+{
+ if (FLAG_E && MAKE_UINT_8(REGISTER_D))
+ {
+ // The (direct,X) addressing mode has a bug in which the high byte is
+ // wrapped within the page if E = 1 and D&0xFF != 0.
+ uint8_t lo = g65816i_read_8_direct(address);
+ uint8_t hi = g65816i_read_8_direct((address & 0xFFFF00) |
+ MAKE_UINT_8(address+1));
+ return lo | (hi<<8);
+ }
+ else
+ {
+ return g65816i_read_16_direct(address);
+ }
+}
+
unsigned g65816_device::g65816i_read_16_vector(unsigned address)
{
return g65816i_read_8_vector(address) |
@@ -354,13 +371,6 @@ unsigned g65816_device::g65816i_read_24_immediate(unsigned address)
(g65816i_read_8_immediate(address+2)<<16);
}
-unsigned g65816_device::g65816i_read_24_direct(unsigned address)
-{
- return g65816i_read_8_direct(address) |
- (g65816i_read_8_direct(address+1)<<8) |
- (g65816i_read_8_direct(address+2)<<16);
-}
-
/* ======================================================================== */
/* ================================= STACK ================================ */
@@ -418,6 +428,51 @@ unsigned g65816_device::g65816i_pull_24()
return ((res + 1) & 0xffff) | (g65816i_pull_8() << 16);
}
+void g65816_device::g65816i_push_8_native(unsigned value)
+{
+ g65816i_write_8_normal(REGISTER_S, value);
+ REGISTER_S = MAKE_UINT_16(REGISTER_S-1);
+}
+
+unsigned g65816_device::g65816i_pull_8_native()
+{
+ REGISTER_S = MAKE_UINT_16(REGISTER_S+1);
+ return g65816i_read_8_normal(REGISTER_S);
+}
+
+void g65816_device::g65816i_push_16_native(unsigned value)
+{
+ g65816i_push_8_native(value>>8);
+ g65816i_push_8_native(value&0xff);
+}
+
+unsigned g65816_device::g65816i_pull_16_native()
+{
+ unsigned res = g65816i_pull_8_native();
+ return res | (g65816i_pull_8_native() << 8);
+}
+
+void g65816_device::g65816i_push_24_native(unsigned value)
+{
+ g65816i_push_8_native(value>>16);
+ g65816i_push_8_native((value>>8)&0xff);
+ g65816i_push_8_native(value&0xff);
+}
+
+unsigned g65816_device::g65816i_pull_24_native()
+{
+ unsigned res = g65816i_pull_8_native();
+ res |= g65816i_pull_8_native() << 8;
+ return ((res + 1) & 0xffff) | (g65816i_pull_8_native() << 16);
+}
+
+void g65816_device::g65816i_update_reg_s()
+{
+ if (FLAG_E)
+ {
+ REGISTER_S = MAKE_UINT_8(REGISTER_S) | 0x100;
+ }
+}
/* ======================================================================== */
/* ============================ PROGRAM COUNTER =========================== */
@@ -686,15 +741,15 @@ unsigned g65816_device::EA_AX() {unsigned tmp = EA_A(); if((tmp^(tmp+REGISTER
unsigned g65816_device::EA_ALX() {return EA_AL() + REGISTER_X;}
unsigned g65816_device::EA_AY() {unsigned tmp = EA_A(); if((tmp^(tmp+REGISTER_Y))&0xff00) CLK(1); return tmp + REGISTER_Y;}
unsigned g65816_device::EA_DI() {return REGISTER_DB | g65816i_read_16_direct(EA_D());}
-unsigned g65816_device::EA_DLI() {return g65816i_read_24_direct(EA_D());}
+unsigned g65816_device::EA_DLI() {return g65816i_read_24_normal(EA_D());}
unsigned g65816_device::EA_AI() {return g65816i_read_16_normal(g65816i_read_16_immediate(EA_IMM16()));}
unsigned g65816_device::EA_ALI() {return g65816i_read_24_normal(EA_A());}
-unsigned g65816_device::EA_DXI() {return REGISTER_DB | g65816i_read_16_direct(EA_DX());}
+unsigned g65816_device::EA_DXI() {return REGISTER_DB | g65816i_read_16_direct_x(EA_DX());}
unsigned g65816_device::EA_DIY() {unsigned tmp = REGISTER_DB | g65816i_read_16_direct(EA_D()); if((tmp^(tmp+REGISTER_Y))&0xff00) CLK(1); return tmp + REGISTER_Y;}
-unsigned g65816_device::EA_DLIY() {return g65816i_read_24_direct(EA_D()) + REGISTER_Y;}
+unsigned g65816_device::EA_DLIY() {return g65816i_read_24_normal(EA_D()) + REGISTER_Y;}
unsigned g65816_device::EA_AXI() {return g65816i_read_16_normal(MAKE_UINT_16(g65816i_read_16_immediate(EA_IMM16()) + REGISTER_X));}
unsigned g65816_device::EA_S() {return MAKE_UINT_16(REGISTER_S + g65816i_read_8_immediate(EA_IMM8()));}
-unsigned g65816_device::EA_SIY() {return MAKE_UINT_16(g65816i_read_16_normal(REGISTER_S + g65816i_read_8_immediate(EA_IMM8())) + REGISTER_Y) | REGISTER_DB;}
+unsigned g65816_device::EA_SIY() {return (g65816i_read_16_normal(REGISTER_S + g65816i_read_8_immediate(EA_IMM8())) | REGISTER_DB) + REGISTER_Y;}
diff --git a/src/devices/cpu/g65816/g65816.h b/src/devices/cpu/g65816/g65816.h
index d918eba4f2922..59794cc66a09f 100644
--- a/src/devices/cpu/g65816/g65816.h
+++ b/src/devices/cpu/g65816/g65816.h
@@ -157,18 +157,25 @@ class g65816_device : public cpu_device, public g65816_disassembler::config
unsigned g65816i_read_16_normal(unsigned address);
unsigned g65816i_read_16_immediate(unsigned address);
unsigned g65816i_read_16_direct(unsigned address);
+ unsigned g65816i_read_16_direct_x(unsigned address);
unsigned g65816i_read_16_vector(unsigned address);
void g65816i_write_16_normal(unsigned address, unsigned value);
void g65816i_write_16_direct(unsigned address, unsigned value);
unsigned g65816i_read_24_normal(unsigned address);
unsigned g65816i_read_24_immediate(unsigned address);
- unsigned g65816i_read_24_direct(unsigned address);
void g65816i_push_8(unsigned value);
unsigned g65816i_pull_8();
void g65816i_push_16(unsigned value);
unsigned g65816i_pull_16();
void g65816i_push_24(unsigned value);
unsigned g65816i_pull_24();
+ void g65816i_push_8_native(unsigned value);
+ unsigned g65816i_pull_8_native();
+ void g65816i_push_16_native(unsigned value);
+ unsigned g65816i_pull_16_native();
+ void g65816i_push_24_native(unsigned value);
+ unsigned g65816i_pull_24_native();
+ void g65816i_update_reg_s();
void g65816i_jump_16(unsigned address);
void g65816i_jump_24(unsigned address);
void g65816i_branch_8(unsigned offset);
diff --git a/src/devices/cpu/g65816/g65816op.h b/src/devices/cpu/g65816/g65816op.h
index 79de3ae49502a..663781b5e1446 100644
--- a/src/devices/cpu/g65816/g65816op.h
+++ b/src/devices/cpu/g65816/g65816op.h
@@ -101,11 +101,11 @@
#define read_24_NORM(A) g65816i_read_24_normal(A)
#define read_24_IMM(A) g65816i_read_24_immediate(A)
-#define read_24_D(A) g65816i_read_24_direct(A)
+#define read_24_D(A) g65816i_read_24_normal(A)
#define read_24_A(A) g65816i_read_24_normal(A)
#define read_24_AL(A) g65816i_read_24_normal(A)
-#define read_24_DX(A) g65816i_read_24_direct(A)
-#define read_24_DY(A) g65816i_read_24_direct(A)
+#define read_24_DX(A) g65816i_read_24_normal(A)
+#define read_24_DY(A) g65816i_read_24_normal(A)
#define read_24_AX(A) g65816i_read_24_normal(A)
#define read_24_ALX(A) g65816i_read_24_normal(A)
#define read_24_AY(A) g65816i_read_24_normal(A)
@@ -588,8 +588,9 @@
#define OP_JSL(MODE) \
CLK(CLK_OP + CLK_W24 + CLK_##MODE + 1); \
DST = EA_##MODE(); \
- g65816i_push_8(REGISTER_PB>>16); \
- g65816i_push_16(REGISTER_PC-1); \
+ g65816i_push_8_native(REGISTER_PB>>16); \
+ g65816i_push_16_native(REGISTER_PC-1); \
+ g65816i_update_reg_s(); \
g65816i_jump_24(DST)
/* M6502 Jump to Subroutine */
@@ -601,13 +602,14 @@
g65816i_push_16(REGISTER_PC-1); \
g65816i_jump_16(DST)
-/* M6502 Jump to Subroutine */
+/* G65816 Jump to Subroutine */
/* Unusual behavior: stacks PC-1 */
#undef OP_JSRAXI
#define OP_JSRAXI() \
CLK(8); \
DST = read_16_AXI(REGISTER_PB | (MAKE_UINT_16(OPER_16_IMM() + REGISTER_X))); \
- g65816i_push_16(REGISTER_PC-1); \
+ g65816i_push_16_native(REGISTER_PC-1); \
+ g65816i_update_reg_s(); \
g65816i_jump_16(DST)
/* M6502 Load accumulator with operand */
@@ -868,20 +870,23 @@
#undef OP_PEA
#define OP_PEA() \
CLK(CLK_OP + CLK_R16 + CLK_W16); \
- g65816i_push_16(OPER_16_IMM())
+ g65816i_push_16_native(OPER_16_IMM()); \
+ g65816i_update_reg_s()
/* G65816 Push Effective Indirect Address */
#undef OP_PEI
#define OP_PEI() \
CLK(CLK_OP + CLK_R16 + CLK_W16 + CLK_D); \
- g65816i_push_16(EA_DI())
+ g65816i_push_16_native(REGISTER_DB | g65816i_read_16_normal(EA_D())); \
+ g65816i_update_reg_s()
/* G65816 Push Effective PC-Relative Address */
#undef OP_PER
#define OP_PER() \
CLK(CLK_OP + CLK_R16 + CLK_W16 + 1); \
SRC = OPER_16_IMM(); \
- g65816i_push_16(REGISTER_PC + SRC)
+ g65816i_push_16_native(REGISTER_PC + SRC); \
+ g65816i_update_reg_s()
/* M6502 Push accumulator to the stack */
#undef OP_PHA
@@ -917,7 +922,8 @@
#undef OP_PHD
#define OP_PHD() \
CLK(CLK_OP + CLK_W16 + 1); \
- g65816i_push_16(REGISTER_D)
+ g65816i_push_16_native(REGISTER_D); \
+ g65816i_update_reg_s()
/* G65816 Push program bank register */
#undef OP_PHK
@@ -961,14 +967,16 @@
#undef OP_PLB
#define OP_PLB() \
CLK(CLK_OP + CLK_R8 + 2); \
- FLAG_N = FLAG_Z = g65816i_pull_8(); \
+ FLAG_N = FLAG_Z = g65816i_pull_8_native(); \
+ g65816i_update_reg_s(); \
REGISTER_DB = FLAG_Z << 16
/* G65816 Pull direct register */
#undef OP_PLD
#define OP_PLD() \
CLK(CLK_OP + CLK_R16 + 2); \
- FLAG_Z = REGISTER_D = g65816i_pull_16(); \
+ FLAG_Z = REGISTER_D = g65816i_pull_16_native(); \
+ g65816i_update_reg_s(); \
FLAG_N = NFLAG_16(FLAG_Z)
/* M6502 Pull the Processor Status Register from the stack */
@@ -1077,7 +1085,8 @@
#undef OP_RTL
#define OP_RTL() \
CLK(6); \
- g65816i_jump_24(g65816i_pull_24())
+ g65816i_jump_24(g65816i_pull_24_native()); \
+ g65816i_update_reg_s()
/* M6502 Return from Subroutine */
/* Unusual behavior: Gets PC and increments */
diff --git a/src/devices/cpu/h8/gt913.cpp b/src/devices/cpu/h8/gt913.cpp
index 8b2de950f5eb8..e32ad3f679ef5 100644
--- a/src/devices/cpu/h8/gt913.cpp
+++ b/src/devices/cpu/h8/gt913.cpp
@@ -253,6 +253,12 @@ void gt913_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void gt913_device::notify_standby(int state)
+{
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+}
+
void gt913_device::execute_set_input(int inputnum, int state)
{
m_intc->set_input(inputnum, state);
diff --git a/src/devices/cpu/h8/gt913.h b/src/devices/cpu/h8/gt913.h
index 5686915bafc90..878dbc48ebe40 100644
--- a/src/devices/cpu/h8/gt913.h
+++ b/src/devices/cpu/h8/gt913.h
@@ -56,6 +56,7 @@ class gt913_device : public h8_device, public device_mixer_interface {
virtual void update_irq_filter() override;
virtual void interrupt_taken() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void irq_setup() override;
virtual void execute_set_input(int inputnum, int state) override;
diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp
index 131f9aabf4c0a..2816dd25e2ddb 100644
--- a/src/devices/cpu/h8/h8.cpp
+++ b/src/devices/cpu/h8/h8.cpp
@@ -39,7 +39,7 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char
m_PPC(0), m_NPC(0), m_PC(0), m_PIR(0), m_EXR(0), m_CCR(0), m_MAC(0), m_MACF(0),
m_TMP1(0), m_TMP2(0), m_TMPR(0), m_inst_state(0), m_inst_substate(0), m_icount(0), m_bcount(0),
m_irq_vector(0), m_taken_irq_vector(0), m_irq_level(0), m_taken_irq_level(0), m_irq_required(false), m_irq_nmi(false),
- m_standby_pending(false), m_nvram_defval(0), m_nvram_battery(true)
+ m_standby_pending(false), m_standby_time(0), m_nvram_defval(0), m_nvram_battery(true)
{
m_supports_advanced = false;
m_mode_advanced = false;
@@ -145,6 +145,7 @@ void h8_device::device_start()
state_add(H8_R7, "ER7", m_TMPR).callimport().callexport().formatstr("%9s");
}
+ save_item(NAME(m_cycles_base));
save_item(NAME(m_PPC));
save_item(NAME(m_NPC));
save_item(NAME(m_PC));
@@ -164,6 +165,7 @@ void h8_device::device_start()
save_item(NAME(m_irq_nmi));
save_item(NAME(m_current_dma));
save_item(NAME(m_standby_pending));
+ save_item(NAME(m_standby_time));
save_item(NAME(m_nvram_battery));
set_icountptr(m_icount);
@@ -189,6 +191,7 @@ void h8_device::device_start()
void h8_device::device_reset()
{
+ m_cycles_base = machine().time().as_ticks(clock());
m_inst_state = STATE_RESET;
m_inst_substate = 0;
m_count_before_instruction_step = 0;
@@ -577,6 +580,7 @@ void h8_device::set_irq(int irq_vector, int irq_level, bool irq_nmi)
// wake up from software standby with an external interrupt
if(standby() && m_irq_vector) {
+ notify_standby(0);
resume(SUSPEND_REASON_CLOCK);
m_standby_cb(0);
take_interrupt();
@@ -610,13 +614,14 @@ int h8_device::trapa_setup()
u8 h8_device::do_addx8(u8 v1, u8 v2)
{
- u16 res = v1 + v2 + (m_CCR & F_C ? 1 : 0);
+ u8 c = m_CCR & F_C ? 1 : 0;
+ u16 res = v1 + v2 + c;
m_CCR &= ~(F_N|F_V|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
- if(((v1 & 0xf) + (v2 & 0xf) + (m_CCR & F_C ? 1 : 0)) & 0x10)
+ if(m_has_hc) {
+ if(((v1 & 0xf) + (v2 & 0xf) + c) & 0x10)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(u8(res))
m_CCR &= ~F_Z;
@@ -631,13 +636,14 @@ u8 h8_device::do_addx8(u8 v1, u8 v2)
u8 h8_device::do_subx8(u8 v1, u8 v2)
{
- u16 res = v1 - v2 - (m_CCR & F_C ? 1 : 0);
+ u8 c = m_CCR & F_C ? 1 : 0;
+ u16 res = v1 - v2 - c;
m_CCR &= ~(F_N|F_V|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
- if(((v1 & 0xf) - (v2 & 0xf) - (m_CCR & F_C ? 1 : 0)) & 0x10)
+ if(m_has_hc) {
+ if(((v1 & 0xf) - (v2 & 0xf) - c) & 0x10)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(u8(res))
m_CCR &= ~F_Z;
@@ -693,11 +699,11 @@ u8 h8_device::do_add8(u8 v1, u8 v2)
{
u16 res = v1 + v2;
m_CCR &= ~(F_N|F_V|F_Z|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
+ if(m_has_hc) {
if(((v1 & 0xf) + (v2 & 0xf)) & 0x10)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(!u8(res))
m_CCR |= F_Z;
@@ -714,11 +720,11 @@ u16 h8_device::do_add16(u16 v1, u16 v2)
{
u32 res = v1 + v2;
m_CCR &= ~(F_N|F_V|F_Z|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
+ if(m_has_hc) {
if(((v1 & 0xfff) + (v2 & 0xfff)) & 0x1000)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(!u16(res))
m_CCR |= F_Z;
@@ -735,11 +741,11 @@ u32 h8_device::do_add32(u32 v1, u32 v2)
{
u64 res = u64(v1) + u64(v2);
m_CCR &= ~(F_N|F_V|F_Z|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
+ if(m_has_hc) {
if(((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(!u32(res))
m_CCR |= F_Z;
@@ -795,11 +801,11 @@ u8 h8_device::do_sub8(u8 v1, u8 v2)
{
u16 res = v1 - v2;
m_CCR &= ~(F_N|F_V|F_Z|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
+ if(m_has_hc) {
if(((v1 & 0xf) - (v2 & 0xf)) & 0x10)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(!u8(res))
m_CCR |= F_Z;
@@ -816,11 +822,11 @@ u16 h8_device::do_sub16(u16 v1, u16 v2)
{
u32 res = v1 - v2;
m_CCR &= ~(F_N|F_V|F_Z|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
+ if(m_has_hc) {
if(((v1 & 0xfff) - (v2 & 0xfff)) & 0x1000)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(!u16(res))
m_CCR |= F_Z;
@@ -837,11 +843,11 @@ u32 h8_device::do_sub32(u32 v1, u32 v2)
{
u64 res = u64(v1) - u64(v2);
m_CCR &= ~(F_N|F_V|F_Z|F_C);
- if(m_has_hc)
- {
- m_CCR &= ~F_H;
+ if(m_has_hc) {
if(((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000)
m_CCR |= F_H;
+ else
+ m_CCR &= ~F_H;
}
if(!u32(res))
m_CCR |= F_Z;
diff --git a/src/devices/cpu/h8/h8.h b/src/devices/cpu/h8/h8.h
index 9cce7631d9dc6..bf6b9540b7345 100644
--- a/src/devices/cpu/h8/h8.h
+++ b/src/devices/cpu/h8/h8.h
@@ -49,6 +49,7 @@ class h8_device : public cpu_device, public device_nvram_interface {
void nvram_set_default_value(u16 val) { m_nvram_defval = val; } // default is 0
auto standby_cb() { return m_standby_cb.bind(); } // notifier (not an output pin)
int standby() { return suspended(SUSPEND_REASON_CLOCK) ? 1 : 0; }
+ u64 standby_time() { return m_standby_time; }
void internal_update();
void set_irq(int irq_vector, int irq_level, bool irq_nmi);
@@ -65,6 +66,8 @@ class h8_device : public cpu_device, public device_nvram_interface {
void do_sci_tx(int sci, int state) { m_sci_tx[sci](state); }
void do_sci_clk(int sci, int state) { m_sci_clk[sci](state); }
+ u64 now_as_cycles() const { return machine().time().as_ticks(clock()) - m_cycles_base; }
+
protected:
enum {
// digital I/O ports
@@ -153,19 +156,20 @@ class h8_device : public cpu_device, public device_nvram_interface {
h8_dma_state *m_dma_channel[8];
int m_current_dma;
h8_dtc_state *m_current_dtc;
-
- u32 m_PPC; // previous program counter
- u32 m_NPC; // next start-of-instruction program counter
- u32 m_PC; // program counter
- u16 m_PIR; // Prefetched word
- u16 m_IR[5]; // Fetched instruction
- u16 m_R[16]; // Rn (0-7), En (8-15, h8-300h+)
- u8 m_EXR; // Interrupt/trace register (h8s/2000+)
- u8 m_CCR; // Condition-code register
- s64 m_MAC; // Multiply accumulator (h8s/2600+)
- u8 m_MACF; // MAC flags (h8s/2600+)
- u32 m_TMP1, m_TMP2;
- u32 m_TMPR; // For debugger ER register import
+ u64 m_cycles_base;
+
+ u32 m_PPC; // previous program counter
+ u32 m_NPC; // next start-of-instruction program counter
+ u32 m_PC; // program counter
+ u16 m_PIR; // Prefetched word
+ u16 m_IR[5]; // Fetched instruction
+ u16 m_R[16]; // Rn (0-7), En (8-15, h8-300h+)
+ u8 m_EXR; // Interrupt/trace register (h8s/2000+)
+ u8 m_CCR; // Condition-code register
+ s64 m_MAC; // Multiply accumulator (h8s/2600+)
+ u8 m_MACF; // MAC flags (h8s/2600+)
+ u32 m_TMP1, m_TMP2;
+ u32 m_TMPR; // For debugger ER register import
bool m_has_exr, m_has_mac, m_has_trace, m_supports_advanced, m_mode_advanced, m_mode_a20, m_mac_saturating;
bool m_has_hc; // GT913's CCR bit 5 is I, not H
@@ -176,6 +180,7 @@ class h8_device : public cpu_device, public device_nvram_interface {
int m_irq_level, m_taken_irq_level;
bool m_irq_required, m_irq_nmi;
bool m_standby_pending;
+ u64 m_standby_time;
u16 m_nvram_defval;
bool m_nvram_battery;
@@ -186,6 +191,7 @@ class h8_device : public cpu_device, public device_nvram_interface {
virtual void update_irq_filter() = 0;
virtual void interrupt_taken() = 0;
virtual void internal_update(u64 current_time) = 0;
+ virtual void notify_standby(int state) = 0;
void recompute_bcount(u64 event_time);
virtual int trace_setup();
virtual int trapa_setup();
diff --git a/src/devices/cpu/h8/h8.lst b/src/devices/cpu/h8/h8.lst
index 92a9e03cacab4..d1ddf51cdf8ac 100644
--- a/src/devices/cpu/h8/h8.lst
+++ b/src/devices/cpu/h8/h8.lst
@@ -742,6 +742,8 @@ macro jsr32 %opc %spreg
0180 ffff 0 sleep - -
prefetch_start
if(m_standby_pending) {
+ m_standby_time = total_cycles();
+ notify_standby(1);
suspend(SUSPEND_REASON_CLOCK, true);
m_standby_cb(1);
} else {
@@ -2874,7 +2876,7 @@ macro jsr32 %opc %spreg
m_TMP2 = 0xffffff00 | m_IR[0];
m_TMP1 = read8(m_TMP2);
prefetch_start
- bst m_IR[0] >> 4
+ bst m_IR[1] >> 4
write8(m_TMP2, m_TMP1);
prefetch_done();
@@ -2882,7 +2884,7 @@ macro jsr32 %opc %spreg
m_TMP2 = 0xffffff00 | m_IR[0];
m_TMP1 = read8(m_TMP2);
prefetch_start
- bist m_IR[0] >> 4
+ bist m_IR[1] >> 4
write8(m_TMP2, m_TMP1);
prefetch_done();
diff --git a/src/devices/cpu/h8/h83002.cpp b/src/devices/cpu/h8/h83002.cpp
index d29b7e8ef5a40..f6215e62e40a5 100644
--- a/src/devices/cpu/h8/h83002.cpp
+++ b/src/devices/cpu/h8/h83002.cpp
@@ -233,6 +233,19 @@ void h83002_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83002_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83002_device::device_start()
{
h8h_device::device_start();
diff --git a/src/devices/cpu/h8/h83002.h b/src/devices/cpu/h8/h83002.h
index c45fad837113a..19bbbc12bc0b8 100644
--- a/src/devices/cpu/h8/h83002.h
+++ b/src/devices/cpu/h8/h83002.h
@@ -86,6 +86,7 @@ class h83002_device : public h8h_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83003.cpp b/src/devices/cpu/h8/h83003.cpp
index ba9c8aabafa5d..505d9887d2952 100644
--- a/src/devices/cpu/h8/h83003.cpp
+++ b/src/devices/cpu/h8/h83003.cpp
@@ -260,6 +260,19 @@ void h83003_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83003_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83003_device::device_start()
{
h8h_device::device_start();
diff --git a/src/devices/cpu/h8/h83003.h b/src/devices/cpu/h8/h83003.h
index a10ec7e824132..34597c07048f1 100644
--- a/src/devices/cpu/h8/h83003.h
+++ b/src/devices/cpu/h8/h83003.h
@@ -96,6 +96,7 @@ class h83003_device : public h8h_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83006.cpp b/src/devices/cpu/h8/h83006.cpp
index 586b9d1f72055..9da44a6a85e18 100644
--- a/src/devices/cpu/h8/h83006.cpp
+++ b/src/devices/cpu/h8/h83006.cpp
@@ -227,6 +227,22 @@ void h83006_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83006_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_sci[2]->notify_standby(state);
+ m_timer8_0->notify_standby(state);
+ m_timer8_1->notify_standby(state);
+ m_timer8_2->notify_standby(state);
+ m_timer8_3->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83006_device::device_start()
{
h8h_device::device_start();
diff --git a/src/devices/cpu/h8/h83006.h b/src/devices/cpu/h8/h83006.h
index 5271d3574465c..883452ce23c2a 100644
--- a/src/devices/cpu/h8/h83006.h
+++ b/src/devices/cpu/h8/h83006.h
@@ -79,6 +79,7 @@ class h83006_device : public h8h_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83008.cpp b/src/devices/cpu/h8/h83008.cpp
index 96aa5b9546e29..a1a6ee12ebed1 100644
--- a/src/devices/cpu/h8/h83008.cpp
+++ b/src/devices/cpu/h8/h83008.cpp
@@ -204,6 +204,21 @@ void h83008_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83008_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer8_0->notify_standby(state);
+ m_timer8_1->notify_standby(state);
+ m_timer8_2->notify_standby(state);
+ m_timer8_3->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83008_device::device_start()
{
h8h_device::device_start();
diff --git a/src/devices/cpu/h8/h83008.h b/src/devices/cpu/h8/h83008.h
index bd23cca64b91a..30f62b539d05e 100644
--- a/src/devices/cpu/h8/h83008.h
+++ b/src/devices/cpu/h8/h83008.h
@@ -76,6 +76,7 @@ class h83008_device : public h8h_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83032.cpp b/src/devices/cpu/h8/h83032.cpp
index 269158d4f87e1..d47f7958dacad 100644
--- a/src/devices/cpu/h8/h83032.cpp
+++ b/src/devices/cpu/h8/h83032.cpp
@@ -228,6 +228,18 @@ void h83032_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83032_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83032_device::device_start()
{
h8h_device::device_start();
diff --git a/src/devices/cpu/h8/h83032.h b/src/devices/cpu/h8/h83032.h
index fcd03d027287a..0075625b3252a 100644
--- a/src/devices/cpu/h8/h83032.h
+++ b/src/devices/cpu/h8/h83032.h
@@ -86,6 +86,7 @@ class h83032_device : public h8h_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83042.cpp b/src/devices/cpu/h8/h83042.cpp
index f0f35a0ea7765..70f74bc94799f 100644
--- a/src/devices/cpu/h8/h83042.cpp
+++ b/src/devices/cpu/h8/h83042.cpp
@@ -263,6 +263,19 @@ void h83042_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83042_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83042_device::device_start()
{
h8h_device::device_start();
diff --git a/src/devices/cpu/h8/h83042.h b/src/devices/cpu/h8/h83042.h
index 7bec2bceccf52..c14bb217232d7 100644
--- a/src/devices/cpu/h8/h83042.h
+++ b/src/devices/cpu/h8/h83042.h
@@ -94,6 +94,7 @@ class h83042_device : public h8h_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83048.cpp b/src/devices/cpu/h8/h83048.cpp
index be0fdc0936cb5..2443b7a58cd65 100644
--- a/src/devices/cpu/h8/h83048.cpp
+++ b/src/devices/cpu/h8/h83048.cpp
@@ -268,6 +268,19 @@ void h83048_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83048_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83048_device::device_start()
{
h8h_device::device_start();
diff --git a/src/devices/cpu/h8/h83048.h b/src/devices/cpu/h8/h83048.h
index bb14b78e10859..668e7996446e6 100644
--- a/src/devices/cpu/h8/h83048.h
+++ b/src/devices/cpu/h8/h83048.h
@@ -98,6 +98,7 @@ class h83048_device : public h8h_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83217.cpp b/src/devices/cpu/h8/h83217.cpp
new file mode 100644
index 0000000000000..f82a77f8fec84
--- /dev/null
+++ b/src/devices/cpu/h8/h83217.cpp
@@ -0,0 +1,276 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, hap
+/***************************************************************************
+
+ h83217.cpp
+
+ H8/3217 family emulation
+
+ TODO:
+ - H8/3212 and H8/3202 have less internal modules
+ - PWM timer module
+ - Host Interface module
+ - optional I2C bus module
+ - keyboard matrix interrupt
+ - TCONR @ 0xff9f (timer connection)
+ - SEDGR @ 0xffa8 (edge sense)
+ - WSCR @ 0xffc2 (waitstate control)
+ - finish STCR emulation
+ - finish SYSCR emulation
+
+***************************************************************************/
+
+#include "emu.h"
+#include "h83217.h"
+
+DEFINE_DEVICE_TYPE(H83217, h83217_device, "h83217", "Hitachi H8/3217")
+DEFINE_DEVICE_TYPE(H83216, h83216_device, "h83216", "Hitachi H8/3216")
+DEFINE_DEVICE_TYPE(H83214, h83214_device, "h83214", "Hitachi H8/3214")
+DEFINE_DEVICE_TYPE(H83212, h83212_device, "h83212", "Hitachi H8/3212")
+DEFINE_DEVICE_TYPE(H83202, h83202_device, "h83202", "Hitachi H8/3202")
+
+
+h83217_device::h83217_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start) :
+ h8_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h83217_device::map), this)),
+ m_intc(*this, "intc"),
+ m_port(*this, "port%u", 1),
+ m_timer8(*this, "timer8_%u", 0),
+ m_timer16(*this, "timer16"),
+ m_timer16_0(*this, "timer16:0"),
+ m_watchdog(*this, "watchdog"),
+ m_ram_view(*this, "ram_view"),
+ m_ram_start(start),
+ m_md(3)
+{
+}
+
+h83217_device::h83217_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h83217_device(mconfig, H83217, tag, owner, clock, 0xf780)
+{
+}
+
+h83216_device::h83216_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h83217_device(mconfig, H83216, tag, owner, clock, 0xf780)
+{
+}
+
+h83214_device::h83214_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h83217_device(mconfig, H83214, tag, owner, clock, 0xfb80)
+{
+}
+
+h83212_device::h83212_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h83217_device(mconfig, H83212, tag, owner, clock, 0xfd80)
+{
+}
+
+h83202_device::h83202_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h83217_device(mconfig, H83202, tag, owner, clock, 0xfd80)
+{
+}
+
+void h83217_device::map(address_map &map)
+{
+ map(m_ram_start, 0xff7f).view(m_ram_view);
+ m_ram_view[0](m_ram_start, 0xff7f).ram().share(m_internal_ram);
+
+ map(0xff90, 0xff90).rw(m_timer16_0, FUNC(h8325_timer16_channel_device::tcr_r), FUNC(h8325_timer16_channel_device::tcr_w));
+ map(0xff91, 0xff91).rw(m_timer16_0, FUNC(h8325_timer16_channel_device::tsr_r), FUNC(h8325_timer16_channel_device::tsr_w));
+ map(0xff92, 0xff93).rw(m_timer16_0, FUNC(h8325_timer16_channel_device::tcnt_r), FUNC(h8325_timer16_channel_device::tcnt_w));
+ map(0xff94, 0xff95).rw(m_timer16_0, FUNC(h8325_timer16_channel_device::ocra_r), FUNC(h8325_timer16_channel_device::ocra_w));
+ map(0xff96, 0xff97).rw(m_timer16_0, FUNC(h8325_timer16_channel_device::ocrb_r), FUNC(h8325_timer16_channel_device::ocrb_w));
+ map(0xff98, 0xff99).r(m_timer16_0, FUNC(h8325_timer16_channel_device::icr_r));
+
+ map(0xff9a, 0xff9a).rw(m_timer8[2], FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
+ map(0xff9b, 0xff9b).rw(m_timer8[2], FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
+ map(0xff9c, 0xff9d).rw(m_timer8[2], FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w));
+ map(0xff9e, 0xff9e).rw(m_timer8[2], FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
+
+ map(0xffaa, 0xffab).rw(m_watchdog, FUNC(h8_watchdog_device::wd_r), FUNC(h8_watchdog_device::wd_w));
+
+ map(0xffac, 0xffac).rw(m_port[0], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffad, 0xffad).rw(m_port[1], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffae, 0xffae).rw(m_port[2], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffb0, 0xffb0).w(m_port[0], FUNC(h8_port_device::ddr_w));
+ map(0xffb1, 0xffb1).w(m_port[1], FUNC(h8_port_device::ddr_w));
+ map(0xffb2, 0xffb2).rw(m_port[0], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
+ map(0xffb3, 0xffb3).rw(m_port[1], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
+ map(0xffb4, 0xffb4).w(m_port[2], FUNC(h8_port_device::ddr_w));
+ map(0xffb5, 0xffb5).w(m_port[3], FUNC(h8_port_device::ddr_w));
+ map(0xffb6, 0xffb6).rw(m_port[2], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
+ map(0xffb7, 0xffb7).rw(m_port[3], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
+ map(0xffb8, 0xffb8).w(m_port[4], FUNC(h8_port_device::ddr_w));
+ map(0xffb9, 0xffb9).w(m_port[5], FUNC(h8_port_device::ddr_w));
+ map(0xffba, 0xffba).rw(m_port[4], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
+ map(0xffbb, 0xffbb).rw(m_port[5], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
+ map(0xffbc, 0xffbc).w(m_port[6], FUNC(h8_port_device::ddr_w));
+ map(0xffbe, 0xffbe).rw(m_port[6], FUNC(h8_port_device::port_r), FUNC(h8_port_device::dr_w));
+
+ map(0xffc3, 0xffc3).rw(FUNC(h83217_device::stcr_r), FUNC(h83217_device::stcr_w));
+ map(0xffc4, 0xffc4).rw(FUNC(h83217_device::syscr_r), FUNC(h83217_device::syscr_w));
+ map(0xffc5, 0xffc5).r(FUNC(h83217_device::mdcr_r));
+ map(0xffc6, 0xffc6).lr8(NAME([this]() { return m_intc->iscr_r() | ~0x47; }));
+ map(0xffc6, 0xffc6).lw8(NAME([this](u8 data) { m_intc->iscr_w(data & 0x47); }));
+ map(0xffc7, 0xffc7).lr8(NAME([this]() { return m_intc->ier_r() | ~0x47; }));
+ map(0xffc7, 0xffc7).lw8(NAME([this](u8 data) { m_intc->ier_w(data & 0x47); }));
+
+ map(0xffc8, 0xffc8).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
+ map(0xffc9, 0xffc9).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
+ map(0xffca, 0xffcb).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w));
+ map(0xffcc, 0xffcc).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
+ map(0xffd0, 0xffd0).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
+ map(0xffd1, 0xffd1).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
+ map(0xffd2, 0xffd3).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w));
+ map(0xffd4, 0xffd4).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
+
+ map(0xffd8, 0xffd8).rw(m_sci[0], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
+ map(0xffd9, 0xffd9).rw(m_sci[0], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
+ map(0xffda, 0xffda).rw(m_sci[0], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
+ map(0xffdb, 0xffdb).rw(m_sci[0], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
+ map(0xffdc, 0xffdc).rw(m_sci[0], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
+ map(0xffdd, 0xffdd).r(m_sci[0], FUNC(h8_sci_device::rdr_r));
+ map(0xffe0, 0xffe0).rw(m_sci[1], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
+ map(0xffe1, 0xffe1).rw(m_sci[1], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
+ map(0xffe2, 0xffe2).rw(m_sci[1], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
+ map(0xffe3, 0xffe3).rw(m_sci[1], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
+ map(0xffe4, 0xffe4).rw(m_sci[1], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
+ map(0xffe5, 0xffe5).r(m_sci[1], FUNC(h8_sci_device::rdr_r));
+}
+
+void h83217_device::device_add_mconfig(machine_config &config)
+{
+ H8_INTC(config, m_intc, *this);
+ H8_PORT(config, m_port[0], *this, h8_device::PORT_1, 0x00, 0x00);
+ H8_PORT(config, m_port[1], *this, h8_device::PORT_2, 0x00, 0x00);
+ H8_PORT(config, m_port[2], *this, h8_device::PORT_3, 0x00, 0x00);
+ H8_PORT(config, m_port[3], *this, h8_device::PORT_4, 0x00, 0x00);
+ H8_PORT(config, m_port[4], *this, h8_device::PORT_5, 0x00, 0xc0);
+ H8_PORT(config, m_port[5], *this, h8_device::PORT_6, 0x00, 0x80);
+ H8_PORT(config, m_port[6], *this, h8_device::PORT_7, 0x00, 0x00);
+ H8_TIMER8_CHANNEL(config, m_timer8[0], *this, m_intc, 23, 24, 25, 8, 2, 64, 32, 1024, 256);
+ H8_TIMER8_CHANNEL(config, m_timer8[1], *this, m_intc, 26, 27, 28, 8, 2, 64, 128, 1024, 2048);
+ H8_TIMER8_CHANNEL(config, m_timer8[2], *this, m_intc, 47, 48, 49, 1, 1, 2, 2, 512, 512);
+ H8_TIMER16(config, m_timer16, *this, 1, 0xff);
+ H8325_TIMER16_CHANNEL(config, m_timer16_0, *this, m_intc, 19);
+ H8_SCI(config, m_sci[0], 0, *this, m_intc, 29, 30, 31, 32);
+ H8_SCI(config, m_sci[1], 1, *this, m_intc, 33, 34, 35, 36);
+ H8_WATCHDOG(config, m_watchdog, *this, m_intc, 44, h8_watchdog_device::B);
+}
+
+void h83217_device::execute_set_input(int inputnum, int state)
+{
+ m_intc->set_input(inputnum, state);
+}
+
+void h83217_device::irq_setup()
+{
+ m_CCR |= F_I;
+}
+
+void h83217_device::update_irq_filter()
+{
+ if(m_CCR & F_I)
+ m_intc->set_filter(2, -1);
+ else
+ m_intc->set_filter(0, -1);
+}
+
+void h83217_device::interrupt_taken()
+{
+ standard_irq_callback(m_intc->interrupt_taken(m_taken_irq_vector), m_NPC);
+}
+
+void h83217_device::internal_update(u64 current_time)
+{
+ u64 event_time = 0;
+
+ add_event(event_time, m_sci[0]->internal_update(current_time));
+ add_event(event_time, m_sci[1]->internal_update(current_time));
+ add_event(event_time, m_timer8[0]->internal_update(current_time));
+ add_event(event_time, m_timer8[1]->internal_update(current_time));
+ add_event(event_time, m_timer8[2]->internal_update(current_time));
+ add_event(event_time, m_timer16_0->internal_update(current_time));
+ add_event(event_time, m_watchdog->internal_update(current_time));
+
+ recompute_bcount(event_time);
+}
+
+void h83217_device::notify_standby(int state)
+{
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+
+ for (auto & timer8 : m_timer8)
+ timer8->notify_standby(state);
+
+ m_timer16_0->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
+void h83217_device::device_start()
+{
+ h8_device::device_start();
+
+ m_stcr = 0;
+ m_syscr = 0;
+
+ save_item(NAME(m_md));
+ save_item(NAME(m_stcr));
+ save_item(NAME(m_syscr));
+}
+
+void h83217_device::device_reset()
+{
+ h8_device::device_reset();
+
+ m_stcr = 0x00;
+ m_syscr = 0x09;
+ m_ram_view.select(0);
+}
+
+u8 h83217_device::stcr_r()
+{
+ return m_stcr;
+}
+
+void h83217_device::stcr_w(u8 data)
+{
+ logerror("stcr = %02x\n", data);
+
+ // ICKS0/1
+ m_timer8[0]->set_extra_clock_bit(BIT(data, 0));
+ m_timer8[1]->set_extra_clock_bit(BIT(data, 1));
+
+ m_stcr = data;
+}
+
+u8 h83217_device::syscr_r()
+{
+ return m_syscr;
+}
+
+void h83217_device::syscr_w(u8 data)
+{
+ logerror("syscr = %02x\n", data);
+
+ // RAME
+ if (data & 1)
+ m_ram_view.select(0);
+ else
+ m_ram_view.disable();
+
+ // NMIEG
+ m_intc->set_nmi_edge(BIT(data, 2));
+
+ // SSBY
+ m_standby_pending = bool(data & 0x80);
+
+ m_syscr = (m_syscr & 0x08) | (data & 0xf7);
+}
+
+u8 h83217_device::mdcr_r()
+{
+ if(!machine().side_effects_disabled())
+ logerror("mdcr_r\n");
+ return (m_md & 0x03) | 0xe4;
+}
diff --git a/src/devices/cpu/h8/h83217.h b/src/devices/cpu/h8/h83217.h
new file mode 100644
index 0000000000000..a0274b0e9bdde
--- /dev/null
+++ b/src/devices/cpu/h8/h83217.h
@@ -0,0 +1,119 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, hap
+/***************************************************************************
+
+ h83217.h
+
+ H8/3217 family emulation
+
+ H8-300-based mcus.
+
+ Variant ROM RAM
+ H8/3217 60K 2K
+ H8/3216 48K 2K
+ H8/3214 32K 1K
+ H8/3212 16K 512B
+ H8/3202 16K 512B
+
+***************************************************************************/
+
+#ifndef MAME_CPU_H8_H83217_H
+#define MAME_CPU_H8_H83217_H
+
+#pragma once
+
+#include "h8.h"
+
+#include "h8_intc.h"
+#include "h8_port.h"
+#include "h8_timer8.h"
+#include "h8_timer16.h"
+#include "h8_sci.h"
+#include "h8_watchdog.h"
+
+class h83217_device : public h8_device {
+public:
+ h83217_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // I/O ports
+ auto read_port1() { return m_read_port [PORT_1].bind(); }
+ auto write_port1() { return m_write_port[PORT_1].bind(); }
+ auto read_port2() { return m_read_port [PORT_2].bind(); }
+ auto write_port2() { return m_write_port[PORT_2].bind(); }
+ auto read_port3() { return m_read_port [PORT_3].bind(); }
+ auto write_port3() { return m_write_port[PORT_3].bind(); }
+ auto read_port4() { return m_read_port [PORT_4].bind(); }
+ auto write_port4() { return m_write_port[PORT_4].bind(); }
+ auto read_port5() { return m_read_port [PORT_5].bind(); }
+ auto write_port5() { return m_write_port[PORT_5].bind(); }
+ auto read_port6() { return m_read_port [PORT_6].bind(); }
+ auto write_port6() { return m_write_port[PORT_6].bind(); }
+ auto read_port7() { return m_read_port [PORT_7].bind(); }
+ auto write_port7() { return m_write_port[PORT_7].bind(); }
+
+ // MD pins, default mode 3 (single chip)
+ void set_mode(u8 mode) { m_md = mode & 3; }
+
+ u8 stcr_r();
+ void stcr_w(u8 data);
+ u8 syscr_r();
+ void syscr_w(u8 data);
+ u8 mdcr_r();
+
+protected:
+ h83217_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start);
+
+ required_device m_intc;
+ required_device_array m_port;
+ required_device_array m_timer8;
+ required_device m_timer16;
+ required_device m_timer16_0;
+ required_device m_watchdog;
+
+ memory_view m_ram_view;
+
+ u32 m_ram_start;
+ u8 m_md;
+ u8 m_stcr;
+ u8 m_syscr;
+
+ virtual void update_irq_filter() override;
+ virtual void interrupt_taken() override;
+ virtual void irq_setup() override;
+ virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ void map(address_map &map);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void execute_set_input(int inputnum, int state) override;
+};
+
+class h83216_device : public h83217_device {
+public:
+ h83216_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h83214_device : public h83217_device {
+public:
+ h83214_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h83212_device : public h83217_device {
+public:
+ h83212_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h83202_device : public h83217_device {
+public:
+ h83202_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+DECLARE_DEVICE_TYPE(H83217, h83217_device)
+DECLARE_DEVICE_TYPE(H83216, h83216_device)
+DECLARE_DEVICE_TYPE(H83214, h83214_device)
+DECLARE_DEVICE_TYPE(H83212, h83212_device)
+DECLARE_DEVICE_TYPE(H83202, h83202_device)
+
+#endif // MAME_CPU_H8_H83217_H
diff --git a/src/devices/cpu/h8/h8325.cpp b/src/devices/cpu/h8/h8325.cpp
index 194f9557a9ab0..40cc6b53d84f7 100644
--- a/src/devices/cpu/h8/h8325.cpp
+++ b/src/devices/cpu/h8/h8325.cpp
@@ -9,8 +9,8 @@
TODO:
- serial controllers are slightly different, has 3 interrupt sources
instead of 4
- - HCSR register @ 0xfffe (port 3 handshake)
- - FNCR register @ 0xffff (16-bit timer noise canceler)
+ - HCSR @ 0xfffe (port 3 handshake)
+ - FNCR @ 0xffff (16-bit timer noise canceler)
***************************************************************************/
@@ -97,8 +97,10 @@ void h8325_device::map(address_map &map)
map(0xffc4, 0xffc4).rw(FUNC(h8325_device::syscr_r), FUNC(h8325_device::syscr_w));
map(0xffc5, 0xffc5).r(FUNC(h8325_device::mdcr_r));
- map(0xffc6, 0xffc6).rw(m_intc, FUNC(h8325_intc_device::iscr_r), FUNC(h8325_intc_device::iscr_w));
- map(0xffc7, 0xffc7).rw(m_intc, FUNC(h8325_intc_device::ier_r), FUNC(h8325_intc_device::ier_w));
+ map(0xffc6, 0xffc6).lr8(NAME([this]() { return m_intc->iscr_r() | ~0x77; }));
+ map(0xffc6, 0xffc6).lw8(NAME([this](u8 data) { m_intc->iscr_w(data & 0x77); }));
+ map(0xffc7, 0xffc7).lr8(NAME([this]() { return m_intc->ier_r() | ~0x07; }));
+ map(0xffc7, 0xffc7).lw8(NAME([this](u8 data) { m_intc->ier_w(data & 0x07); }));
map(0xffc8, 0xffc8).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
map(0xffc9, 0xffc9).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
@@ -177,6 +179,15 @@ void h8325_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h8325_device::notify_standby(int state)
+{
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer8[0]->notify_standby(state);
+ m_timer8[1]->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+}
+
void h8325_device::device_start()
{
h8_device::device_start();
@@ -197,7 +208,7 @@ void h8325_device::device_reset()
m_ram_view.select(0);
// MD pins are latched at reset
- m_mds = m_md & 3;
+ m_mds = m_md;
}
u8 h8325_device::syscr_r()
@@ -228,5 +239,5 @@ u8 h8325_device::mdcr_r()
{
if(!machine().side_effects_disabled())
logerror("mdcr_r\n");
- return m_mds | 0xe4;
+ return (m_mds & 0x03) | 0xe4;
}
diff --git a/src/devices/cpu/h8/h8325.h b/src/devices/cpu/h8/h8325.h
index c6ba5b2672b31..8f4ca3356a603 100644
--- a/src/devices/cpu/h8/h8325.h
+++ b/src/devices/cpu/h8/h8325.h
@@ -8,7 +8,7 @@
H8-300-based mcus.
- Variant ROM RAM
+ Variant ROM RAM
H8/3257 60K 2K
H8/3256 48K 2K
H8/325 32K 1K
@@ -24,6 +24,7 @@
#pragma once
#include "h8.h"
+
#include "h8_intc.h"
#include "h8_port.h"
#include "h8_timer8.h"
@@ -51,7 +52,7 @@ class h8325_device : public h8_device {
auto write_port7() { return m_write_port[PORT_7].bind(); }
// MD pins, default mode 3 (single chip)
- void set_mode(u8 mode) { m_md = mode; }
+ void set_mode(u8 mode) { m_md = mode & 3; }
u8 syscr_r();
void syscr_w(u8 data);
@@ -80,6 +81,7 @@ class h8325_device : public h8_device {
virtual void interrupt_taken() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h83337.cpp b/src/devices/cpu/h8/h83337.cpp
index 5fd3101dd1350..09a9482f4af82 100644
--- a/src/devices/cpu/h8/h83337.cpp
+++ b/src/devices/cpu/h8/h83337.cpp
@@ -7,7 +7,12 @@
H8-3337 family emulation
TODO:
- - 16-bit timer module is different
+ - 16-bit timer module is different from how it's implemented in h8_timer16.cpp
+ - PWM timer module
+ - Host Interface module
+ - finish WSCR emulation, CKDBL flag would need support in peripherals
+ - finish STCR emulation
+ - finish SYSCR emulation
***************************************************************************/
@@ -37,7 +42,6 @@ h83337_device::h83337_device(const machine_config &mconfig, device_type type, co
m_timer16(*this, "timer16"),
m_timer16_0(*this, "timer16:0"),
m_watchdog(*this, "watchdog"),
- m_syscr(0),
m_ram_start(start)
{
}
@@ -189,15 +193,36 @@ void h83337_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h83337_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer8_0->notify_standby(state);
+ m_timer8_1->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h83337_device::device_start()
{
h8_device::device_start();
+
+ m_wscr = 0;
+ m_stcr = 0;
+ m_syscr = 0;
+
+ save_item(NAME(m_wscr));
+ save_item(NAME(m_stcr));
save_item(NAME(m_syscr));
}
void h83337_device::device_reset()
{
h8_device::device_reset();
+
+ m_wscr = 0x08;
+ m_stcr = 0x00;
m_syscr = 0x09;
}
@@ -208,30 +233,35 @@ u8 h83337_device::syscr_r()
void h83337_device::syscr_w(u8 data)
{
- m_syscr = data;
logerror("syscr = %02x\n", data);
+ m_syscr = (m_syscr & 0x08) | (data & 0xf7);
}
u8 h83337_device::wscr_r()
{
- return 0x00;
+ return m_wscr;
}
void h83337_device::wscr_w(u8 data)
{
logerror("wscr = %02x\n", data);
+ m_wscr = data;
}
u8 h83337_device::stcr_r()
{
- return 0x00;
+ return m_stcr;
}
void h83337_device::stcr_w(u8 data)
{
logerror("stcr = %02x\n", data);
- m_timer8_0->set_extra_clock_bit(data & 0x01);
- m_timer8_1->set_extra_clock_bit(data & 0x02);
+
+ // ICKS0/1
+ m_timer8_0->set_extra_clock_bit(BIT(data, 0));
+ m_timer8_1->set_extra_clock_bit(BIT(data, 1));
+
+ m_stcr = data;
}
u8 h83337_device::mdcr_r()
diff --git a/src/devices/cpu/h8/h83337.h b/src/devices/cpu/h8/h83337.h
index ee4b349ae7b51..0a732b2e11af1 100644
--- a/src/devices/cpu/h8/h83337.h
+++ b/src/devices/cpu/h8/h83337.h
@@ -23,6 +23,7 @@
#pragma once
#include "h8.h"
+
#include "h8_intc.h"
#include "h8_adc.h"
#include "h8_port.h"
@@ -82,13 +83,16 @@ class h83337_device : public h8_device {
required_device m_timer16_0;
required_device m_watchdog;
- u8 m_syscr;
u32 m_ram_start;
+ u8 m_wscr;
+ u8 m_stcr;
+ u8 m_syscr;
virtual void update_irq_filter() override;
virtual void interrupt_taken() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h8_adc.cpp b/src/devices/cpu/h8/h8_adc.cpp
index bab8bc6aa37ff..c1ad3f4b04816 100644
--- a/src/devices/cpu/h8/h8_adc.cpp
+++ b/src/devices/cpu/h8/h8_adc.cpp
@@ -11,7 +11,7 @@ static constexpr int V = 0;
DEFINE_DEVICE_TYPE(H8_ADC_3337, h8_adc_3337_device, "h8_adc_3337", "H8/3337 ADC")
DEFINE_DEVICE_TYPE(H8_ADC_3006, h8_adc_3006_device, "h8_adc_3006", "H8/3006 ADC")
DEFINE_DEVICE_TYPE(H8_ADC_2245, h8_adc_2245_device, "h8_adc_2245", "H8/2245 ADC")
-DEFINE_DEVICE_TYPE(H8_ADC_2320, h8_adc_2320_device, "h8_adc_2320", "H8/2320 ADC")
+DEFINE_DEVICE_TYPE(H8_ADC_2319, h8_adc_2319_device, "h8_adc_2319", "H8/2319 ADC")
DEFINE_DEVICE_TYPE(H8_ADC_2357, h8_adc_2357_device, "h8_adc_2357", "H8/2357 ADC")
DEFINE_DEVICE_TYPE(H8_ADC_2655, h8_adc_2655_device, "h8_adc_2655", "H8/2655 ADC")
@@ -149,6 +149,12 @@ u64 h8_adc_device::internal_update(u64 current_time)
return m_next_event;
}
+void h8_adc_device::notify_standby(int state)
+{
+ if(!state && m_next_event)
+ m_next_event += m_cpu->total_cycles() - m_cpu->standby_time();
+}
+
void h8_adc_device::conversion_wait(bool first, bool poweron, u64 current_time)
{
if(current_time)
@@ -358,29 +364,29 @@ void h8_adc_2245_device::mode_update()
}
-h8_adc_2320_device::h8_adc_2320_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8_adc_device(mconfig, H8_ADC_2320, tag, owner, clock)
+h8_adc_2319_device::h8_adc_2319_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8_adc_device(mconfig, H8_ADC_2319, tag, owner, clock)
{
m_register_mask = 3;
}
-int h8_adc_2320_device::conversion_time(bool first, bool poweron)
+int h8_adc_2319_device::conversion_time(bool first, bool poweron)
{
int tm;
if(first)
- if(m_adcr & 0x04)
+ if(m_adcr & 0x08)
tm = m_adcsr & 0x08 ? 134 : 266;
else
- tm = m_adcsr & 0x08 ? 68 : 580;
+ tm = m_adcsr & 0x08 ? 68 : 530;
else
- if(m_adcr & 0x04)
+ if(m_adcr & 0x08)
tm = m_adcsr & 0x08 ? 128 : 256;
else
tm = m_adcsr & 0x08 ? 64 : 512;
return tm;
}
-void h8_adc_2320_device::mode_update()
+void h8_adc_2319_device::mode_update()
{
m_trigger = 1 << ((m_adcr >> 6) & 3);
diff --git a/src/devices/cpu/h8/h8_adc.h b/src/devices/cpu/h8/h8_adc.h
index bb180703c64e9..2ea510e6c4a15 100644
--- a/src/devices/cpu/h8/h8_adc.h
+++ b/src/devices/cpu/h8/h8_adc.h
@@ -19,7 +19,11 @@
class h8_adc_device : public device_t {
public:
- template void set_info(T &&cpu, U &&intc, int vect) { m_cpu.set_tag(std::forward(cpu)), m_intc.set_tag(std::forward(intc)); m_intc_vector = vect; }
+ template void set_info(T &&cpu, U &&intc, int vect) {
+ m_cpu.set_tag(std::forward(cpu));
+ m_intc.set_tag(std::forward(intc));
+ m_intc_vector = vect;
+ }
u8 addr8_r(offs_t offset);
u16 addr16_r(offs_t offset);
@@ -31,6 +35,7 @@ class h8_adc_device : public device_t {
void set_suspend(bool suspend);
u64 internal_update(u64 current_time);
+ void notify_standby(int state);
protected:
h8_adc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
@@ -131,11 +136,11 @@ class h8_adc_2245_device : public h8_adc_device {
virtual void mode_update() override;
};
-class h8_adc_2320_device : public h8_adc_device {
+class h8_adc_2319_device : public h8_adc_device {
public:
- h8_adc_2320_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- template h8_adc_2320_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu, U &&intc, int vect)
- : h8_adc_2320_device(mconfig, tag, owner, 0)
+ h8_adc_2319_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ template h8_adc_2319_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu, U &&intc, int vect)
+ : h8_adc_2319_device(mconfig, tag, owner, 0)
{
set_info(cpu, intc, vect);
}
@@ -178,7 +183,7 @@ class h8_adc_2655_device : public h8_adc_device {
DECLARE_DEVICE_TYPE(H8_ADC_3337, h8_adc_3337_device)
DECLARE_DEVICE_TYPE(H8_ADC_3006, h8_adc_3006_device)
DECLARE_DEVICE_TYPE(H8_ADC_2245, h8_adc_2245_device)
-DECLARE_DEVICE_TYPE(H8_ADC_2320, h8_adc_2320_device)
+DECLARE_DEVICE_TYPE(H8_ADC_2319, h8_adc_2319_device)
DECLARE_DEVICE_TYPE(H8_ADC_2357, h8_adc_2357_device)
DECLARE_DEVICE_TYPE(H8_ADC_2655, h8_adc_2655_device)
diff --git a/src/devices/cpu/h8/h8_intc.cpp b/src/devices/cpu/h8/h8_intc.cpp
index 8a85f5802ecd1..f599f5e93dba5 100644
--- a/src/devices/cpu/h8/h8_intc.cpp
+++ b/src/devices/cpu/h8/h8_intc.cpp
@@ -98,7 +98,7 @@ void h8_intc_device::set_input(int inputnum, int state)
default: assert(0); break;
}
m_nmi_input = state == ASSERT_LINE;
- if(set) {
+ if(machine().time() > attotime::zero && set) {
m_pending_irqs[0] |= 1 << m_irq_vector_nmi;
update_irq_state();
}
@@ -148,7 +148,7 @@ void h8_intc_device::ier_w(u8 data)
void h8_intc_device::check_level_irqs(bool update)
{
bool set = false;
- for(int i=0; i> i) & 1) {
case 0:
m_irq_type[i] = LEVEL_LOW;
@@ -189,7 +189,7 @@ void h8_intc_device::update_irq_types()
void h8_intc_device::update_irq_state()
{
if(m_irq_vector_count > 0) {
- const unsigned mask = (1 << m_irq_vector_count) - 1;
+ const u32 mask = (1 << m_irq_vector_count) - 1;
m_pending_irqs[0] &= ~(mask << m_irq_vector_base);
m_pending_irqs[0] |= (m_isr & m_ier & mask) << m_irq_vector_base;
@@ -198,10 +198,10 @@ void h8_intc_device::update_irq_state()
int cur_vector = 0;
int cur_level = -1;
- for(int i=0; i(m_iscr >> i,0,4)) {
case 0: case 1:
m_irq_type[i] = LEVEL_LOW;
@@ -305,16 +305,6 @@ void h8h_intc_device::icr_w(offs_t offset, u8 data)
logerror("icr %d = %02x\n", offset, data);
}
-u8 h8h_intc_device::icrc_r()
-{
- return icr_r(2);
-}
-
-void h8h_intc_device::icrc_w(u8 data)
-{
- icr_w(2, data);
-}
-
const int h8h_intc_device::vector_to_slot[64] = {
-1, -1, -1, -1, -1, -1, -1, -1, // NMI at 7
-1, -1, -1, -1, 0, 1, 2, 2, // IRQ 0-3
@@ -371,16 +361,6 @@ void h8s_intc_device::ipr_w(offs_t offset, u8 data)
logerror("ipr %d = %02x\n", offset, data);
}
-u8 h8s_intc_device::iprk_r()
-{
- return ipr_r(10);
-}
-
-void h8s_intc_device::iprk_w(u8 data)
-{
- ipr_w(10, data);
-}
-
u8 h8s_intc_device::iscrh_r()
{
return m_iscr >> 8;
@@ -407,7 +387,7 @@ void h8s_intc_device::iscrl_w(u8 data)
void h8s_intc_device::update_irq_types()
{
- for(int i=0; i> (2*i)) & 3) {
case 0:
m_irq_type[i] = LEVEL_LOW;
diff --git a/src/devices/cpu/h8/h8_intc.h b/src/devices/cpu/h8/h8_intc.h
index 424137d761489..15fe2952f5f94 100644
--- a/src/devices/cpu/h8/h8_intc.h
+++ b/src/devices/cpu/h8/h8_intc.h
@@ -98,8 +98,6 @@ class h8h_intc_device : public h8_intc_device {
void isr_w(u8 data);
u8 icr_r(offs_t offset);
void icr_w(offs_t offset, u8 data);
- u8 icrc_r();
- void icrc_w(u8 data);
protected:
static const int vector_to_slot[];
@@ -125,8 +123,6 @@ class h8s_intc_device : public h8h_intc_device {
u8 ipr_r(offs_t offset);
void ipr_w(offs_t offset, u8 data);
- u8 iprk_r();
- void iprk_w(u8 data);
u8 iscrh_r();
void iscrh_w(u8 data);
u8 iscrl_r();
diff --git a/src/devices/cpu/h8/h8_port.cpp b/src/devices/cpu/h8/h8_port.cpp
index 3ba9c56a494fb..521cc29dedd62 100644
--- a/src/devices/cpu/h8/h8_port.cpp
+++ b/src/devices/cpu/h8/h8_port.cpp
@@ -26,7 +26,7 @@ h8_port_device::h8_port_device(const machine_config &mconfig, const char *tag, d
void h8_port_device::ddr_w(u8 data)
{
- // logerror("ddr_w %02x\n", data);
+ //logerror("ddr_w %02x\n", data);
m_ddr = data;
update_output();
}
@@ -38,14 +38,14 @@ u8 h8_port_device::ddr_r()
void h8_port_device::dr_w(u8 data)
{
- // logerror("dr_w %02x\n", data);
+ //logerror("dr_w %02x\n", data);
m_dr = data;
update_output();
}
u8 h8_port_device::dr_r()
{
- // logerror("dr_r %02x\n", (dr | mask) & 0xff);
+ //logerror("dr_r %02x\n", (dr | mask) & 0xff);
return m_dr | m_mask;
}
@@ -55,7 +55,7 @@ u8 h8_port_device::port_r()
if((m_ddr & ~m_mask) != u8(~m_mask))
res |= m_cpu->do_read_port(m_address) & ~m_ddr;
- // logerror("port_r %02x (%02x %02x)\n", res, ddr & ~mask, u8(~mask));
+ //logerror("port_r %02x (%02x %02x)\n", res, ddr & ~mask, u8(~mask));
return res;
}
diff --git a/src/devices/cpu/h8/h8_sci.cpp b/src/devices/cpu/h8/h8_sci.cpp
index e5af601bae124..f11e8239805d4 100644
--- a/src/devices/cpu/h8/h8_sci.cpp
+++ b/src/devices/cpu/h8/h8_sci.cpp
@@ -7,16 +7,60 @@
#include "h8.h"
#include "h8_intc.h"
-// Verbosity level
-// 0 = no messages
-// 1 = transmitted/received bytes, reception errors and clock setup
-// 2 = everything but status register reads
-// 3 = everything
-static constexpr int V = 0;
+#define LOG_REGS (1 << 1U) // Register writes
+#define LOG_RREGS (1 << 2U) // Register reads
+#define LOG_RATE (1 << 3U) // Bitrate setting, beware that gk2000 changes it all the time ending up in a massive slowdown, don't leave it active
+#define LOG_DATA (1 << 4U) // Bytes transmitted
+#define LOG_CLOCK (1 << 5U) // Clock and transmission start/stop
+#define LOG_STATE (1 << 6U) // State machine states
+#define LOG_TICK (1 << 7U) // Clock ticks
+#define VERBOSE (LOG_DATA)
+
+#include "logmacro.h"
DEFINE_DEVICE_TYPE(H8_SCI, h8_sci_device, "h8_sci", "H8 Serial Communications Interface")
+
+// Clocking:
+// Async mode:
+// The circuit wants 16 events per bit.
+// * Internal clocking: the cpu clock is divided by one of (1, 4, 16, 64) from the cks field of smr
+// then by (brr+1) then by 2.
+// * External clocking: the external clock is supposed to be 16*bitrate.
+// Sync mode:
+// The circuit wants 2 events per bit, a positive and a negative edge.
+// * Internal clocking: the cpu clock is divided by one of (1, 4, 16, 64) from the cks field of smr
+// then by (brr+1) then by 2. Events are then interpreted has been alternatively positive and
+// negative (e.g. another divide-by-two, sync-wise).
+// * External clocking: the external clock is supposed to be at bitrate, both edges are used.
+//
+// Synchronization:
+// Async mode:
+// Both modes use a 4-bits counter incremented on every event (16/bit).
+//
+// * Transmit sets the counter to 0 at transmit start. Output data line changes value
+// on counter == 0. If the clock output is required, clk=1 outside of transmit,
+// clk=0 on counter==0, clk=1 on counter==8.
+//
+// * Receive sets the counter to 0 when the data line initially goes down (start bit)
+// Output line is read on counter==8. It is unknown whether the counter is reset
+// on every data line level change.
+//
+// Sync mode:
+// * Transmit changes the data line on negative edges, the clock line, following positive and
+// negative edge definition, is output as long as transmit is active and is otherwise 1.
+//
+// * Receive reads the data line on positive edges.
+//
+// Framing:
+// Async mode: 1 bit of start at 0, 7 or 8 bits of data, nothing or 1 bit of parity or 1 bit of multiprocessing, 1 or 2 bits of stop at 1.
+// Sync mode: 8 bits of data.
+//
+// Multiprocessing bit is an extra bit which value can be set on transmit in bit zero of ssr.
+// On receive when zero the byte is dropped.
+
+
const char *const h8_sci_device::state_names[] = { "idle", "start", "bit", "parity", "stop", "last-tick" };
h8_sci_device::h8_sci_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
@@ -24,8 +68,9 @@ h8_sci_device::h8_sci_device(const machine_config &mconfig, const char *tag, dev
m_cpu(*this, finder_base::DUMMY_TAG),
m_intc(*this, finder_base::DUMMY_TAG),
m_external_to_internal_ratio(0), m_internal_to_external_ratio(0), m_sync_timer(nullptr), m_id(0), m_eri_int(0), m_rxi_int(0), m_txi_int(0), m_tei_int(0),
- m_tx_state(0), m_rx_state(0), m_tx_bit(0), m_rx_bit(0), m_clock_state(0), m_tx_parity(0), m_rx_parity(0), m_tx_ext_clock_counter(0), m_rx_ext_clock_counter(0), m_clock_mode(clock_mode_t::INTERNAL_ASYNC), m_tx_clock_value(false), m_rx_clock_value(false), m_ext_clock_value(false), m_rx_value(false),
- m_rdr(0), m_tdr(0), m_smr(0), m_scr(0), m_ssr(0), m_brr(0), m_rsr(0), m_tsr(0), m_tx_clock_base(0), m_rx_clock_base(0), m_divider(0)
+ m_tx_state(0), m_rx_state(0), m_tx_bit(0), m_rx_bit(0), m_clock_state(0), m_tx_parity(0), m_rx_parity(0), m_tx_clock_counter(0), m_rx_clock_counter(0),
+ m_clock_mode(INTERNAL_ASYNC), m_ext_clock_value(false), m_rx_value(true),
+ m_rdr(0), m_tdr(0), m_smr(0), m_scr(0), m_ssr(0), m_brr(0), m_rsr(0), m_tsr(0), m_clock_event(0), m_divider(0)
{
m_external_clock_period = attotime::never;
}
@@ -38,33 +83,35 @@ void h8_sci_device::do_set_external_clock_period(const attotime &period)
void h8_sci_device::smr_w(u8 data)
{
m_smr = data;
- if(V>=2) logerror("smr_w %02x %s %c%c%c%s /%d (%06x)\n", data,
- data & SMR_CA ? "sync" : "async",
- data & SMR_CHR ? '7' : '8',
- data & SMR_PE ? data & SMR_OE ? 'o' : 'e' : 'n',
- data & SMR_STOP ? '2' : '1',
- data & SMR_MP ? " mp" : "",
- 1 << 2*(data & SMR_CKS),
- m_cpu->pc());
+
+ LOGMASKED(LOG_REGS, "smr_w %02x %s %c%c%c%s /%d (%06x)\n", data,
+ data & SMR_CA ? "sync" : "async",
+ data & SMR_CHR ? '7' : '8',
+ data & SMR_PE ? data & SMR_OE ? 'o' : 'e' : 'n',
+ data & SMR_STOP ? '2' : '1',
+ data & SMR_MP ? " mp" : "",
+ 1 << 2*(data & SMR_CKS),
+ m_cpu->pc());
+
clock_update();
}
u8 h8_sci_device::smr_r()
{
- if(V>=2) logerror("smr_r %02x (%06x)\n", m_smr, m_cpu->pc());
+ LOGMASKED(LOG_RREGS, "smr_r %02x (%06x)\n", m_smr, m_cpu->pc());
return m_smr;
}
void h8_sci_device::brr_w(u8 data)
{
m_brr = data;
- if(V>=2) logerror("brr_w %02x (%06x)\n", data, m_cpu->pc());
+ LOGMASKED(LOG_REGS, "brr_w %02x (%06x)\n", m_brr, m_cpu->pc());
clock_update();
}
u8 h8_sci_device::brr_r()
{
- if(V>=2) logerror("brr_r %02x (%06x)\n", m_brr, m_cpu->pc());
+ LOGMASKED(LOG_RREGS, "brr_r %02x (%06x)\n", m_brr, m_cpu->pc());
return m_brr;
}
@@ -80,15 +127,15 @@ bool h8_sci_device::has_recv_error() const
void h8_sci_device::scr_w(u8 data)
{
- if(V>=2) logerror("scr_w %02x%s%s%s%s%s%s clk=%d (%06x)\n", data,
- data & SCR_TIE ? " txi" : "",
- data & SCR_RIE ? " rxi" : "",
- data & SCR_TE ? " tx" : "",
- data & SCR_RE ? " rx" : "",
- data & SCR_MPIE ? " mpi" : "",
- data & SCR_TEIE ? " tei" : "",
- data & SCR_CKE,
- m_cpu->pc());
+ LOGMASKED(LOG_REGS, "scr_w %02x%s%s%s%s%s%s clk=%d (%06x)\n", data,
+ data & SCR_TIE ? " txi" : "",
+ data & SCR_RIE ? " rxi" : "",
+ data & SCR_TE ? " tx" : "",
+ data & SCR_RE ? " rx" : "",
+ data & SCR_MPIE ? " mpi" : "",
+ data & SCR_TEIE ? " tei" : "",
+ data & SCR_CKE,
+ m_cpu->pc());
u8 delta = m_scr ^ data;
m_scr = data;
@@ -113,13 +160,13 @@ void h8_sci_device::scr_w(u8 data)
u8 h8_sci_device::scr_r()
{
- if(V>=2) logerror("scr_r %02x (%06x)\n", m_scr, m_cpu->pc());
+ LOGMASKED(LOG_RREGS, "scr_r %02x (%06x)\n", m_scr, m_cpu->pc());
return m_scr;
}
void h8_sci_device::tdr_w(u8 data)
{
- if(V>=2) logerror("tdr_w %02x (%06x)\n", data, m_cpu->pc());
+ LOGMASKED(LOG_REGS, "tdr_w %02x (%06x)\n", data, m_cpu->pc());
m_tdr = data;
if(m_cpu->access_is_dma()) {
m_ssr &= ~SSR_TDRE;
@@ -130,7 +177,7 @@ void h8_sci_device::tdr_w(u8 data)
u8 h8_sci_device::tdr_r()
{
- if(V>=2) logerror("tdr_r %02x (%06x)\n", m_tdr, m_cpu->pc());
+ LOGMASKED(LOG_RREGS, "tdr_r %02x (%06x)\n", m_tdr, m_cpu->pc());
return m_tdr;
}
@@ -143,7 +190,7 @@ void h8_sci_device::ssr_w(u8 data)
if((m_ssr & SSR_TDRE) && !(data & SSR_TDRE))
m_ssr &= ~SSR_TEND;
m_ssr = ((m_ssr & ~SSR_MPBT) | (data & SSR_MPBT)) & (data | (SSR_TEND|SSR_MPB|SSR_MPBT));
- if(V>=2) logerror("ssr_w %02x -> %02x (%06x)\n", data, m_ssr, m_cpu->pc());
+ LOGMASKED(LOG_REGS, "ssr_w %02x -> %02x (%06x)\n", data, m_ssr, m_cpu->pc());
if(m_tx_state == ST_IDLE && !(m_ssr & SSR_TDRE))
tx_start();
@@ -154,83 +201,81 @@ void h8_sci_device::ssr_w(u8 data)
u8 h8_sci_device::ssr_r()
{
- if(V>=3) logerror("ssr_r %02x (%06x)\n", m_ssr, m_cpu->pc());
+ LOGMASKED(LOG_RREGS, "ssr_r %02x (%06x)\n", m_ssr, m_cpu->pc());
return m_ssr;
}
u8 h8_sci_device::rdr_r()
{
- if(V>=2) logerror("rdr_r %02x (%06x)\n", m_rdr, m_cpu->pc());
- if(m_cpu->access_is_dma())
+ LOGMASKED(LOG_RREGS, "rdr_r %02x (%06x)\n", m_rdr, m_cpu->pc());
+
+ if(!machine().side_effects_disabled() && m_cpu->access_is_dma())
m_ssr &= ~SSR_RDRF;
return m_rdr;
}
void h8_sci_device::scmr_w(u8 data)
{
- if(V>=2) logerror("scmr_w %02x (%06x)\n", data, m_cpu->pc());
+ LOGMASKED(LOG_REGS, "scmr_w %02x (%06x)\n", data, m_cpu->pc());
}
u8 h8_sci_device::scmr_r()
{
- if(V>=2) logerror("scmr_r (%06x)\n", m_cpu->pc());
+ LOGMASKED(LOG_RREGS, "scmr_r (%06x)\n", m_cpu->pc());
return 0x00;
}
void h8_sci_device::clock_update()
{
- // Sync: Divider must be the time of a half-period (both edges are used, datarate*2)
- // Async: Divider must be the time of one period (only rising edge used, datarate*16)
-
m_divider = 2 << (2*(m_smr & SMR_CKS));
m_divider *= m_brr+1;
if(m_smr & SMR_CA) {
if(m_scr & SCR_CKE1)
- m_clock_mode = clock_mode_t::EXTERNAL_SYNC;
+ m_clock_mode = EXTERNAL_SYNC;
else
- m_clock_mode = clock_mode_t::INTERNAL_SYNC_OUT;
+ m_clock_mode = INTERNAL_SYNC_OUT;
} else {
if(m_scr & SCR_CKE1)
- m_clock_mode = clock_mode_t::EXTERNAL_ASYNC;
+ m_clock_mode = EXTERNAL_ASYNC;
else if(m_scr & SCR_CKE0)
- m_clock_mode = clock_mode_t::INTERNAL_ASYNC_OUT;
+ m_clock_mode = INTERNAL_ASYNC_OUT;
else
- m_clock_mode = clock_mode_t::INTERNAL_ASYNC;
+ m_clock_mode = INTERNAL_ASYNC;
}
- if(m_clock_mode == clock_mode_t::EXTERNAL_ASYNC && !m_external_clock_period.is_never())
- m_clock_mode = clock_mode_t::EXTERNAL_RATE_ASYNC;
- if(m_clock_mode == clock_mode_t::EXTERNAL_SYNC && !m_external_clock_period.is_never())
- m_clock_mode = clock_mode_t::EXTERNAL_RATE_SYNC;
+ if(m_clock_mode == EXTERNAL_ASYNC && !m_external_clock_period.is_never())
+ m_clock_mode = EXTERNAL_RATE_ASYNC;
+ if(m_clock_mode == EXTERNAL_SYNC && !m_external_clock_period.is_never())
+ m_clock_mode = EXTERNAL_RATE_SYNC;
- if(V>=1) {
+ if(VERBOSE & LOG_RATE) {
std::string new_message;
switch(m_clock_mode) {
- case clock_mode_t::INTERNAL_ASYNC:
+ case INTERNAL_ASYNC:
new_message = util::string_format("clock internal at %d Hz, async, bitrate %d bps\n", int(m_cpu->clock() / m_divider), int(m_cpu->clock() / (m_divider*16)));
break;
- case clock_mode_t::INTERNAL_ASYNC_OUT:
+ case INTERNAL_ASYNC_OUT:
new_message = util::string_format("clock internal at %d Hz, async, bitrate %d bps, output\n", int(m_cpu->clock() / m_divider), int(m_cpu->clock() / (m_divider*16)));
break;
- case clock_mode_t::EXTERNAL_ASYNC:
+ case EXTERNAL_ASYNC:
new_message = "clock external, async\n";
break;
- case clock_mode_t::EXTERNAL_RATE_ASYNC:
+ case EXTERNAL_RATE_ASYNC:
new_message = util::string_format("clock external at %d Hz, async, bitrate %d bps\n", int(m_cpu->clock()*m_internal_to_external_ratio), int(m_cpu->clock()*m_internal_to_external_ratio/16));
break;
- case clock_mode_t::INTERNAL_SYNC_OUT:
+ case INTERNAL_SYNC_OUT:
new_message = util::string_format("clock internal at %d Hz, sync, output\n", int(m_cpu->clock() / (m_divider*2)));
break;
- case clock_mode_t::EXTERNAL_SYNC:
+ case EXTERNAL_SYNC:
new_message = "clock external, sync\n";
break;
- case clock_mode_t::EXTERNAL_RATE_SYNC:
+ case EXTERNAL_RATE_SYNC:
new_message = util::string_format("clock external at %d Hz, sync\n", int(m_cpu->clock()*m_internal_to_external_ratio));
break;
}
if(new_message != m_last_clock_message) {
- logerror(new_message);
+ (LOG_OUTPUT_FUNC)(new_message);
m_last_clock_message = std::move(new_message);
}
}
@@ -248,7 +293,6 @@ void h8_sci_device::device_start()
m_internal_to_external_ratio = 1/m_external_to_internal_ratio;
}
-
save_item(NAME(m_rdr));
save_item(NAME(m_tdr));
save_item(NAME(m_smr));
@@ -262,16 +306,15 @@ void h8_sci_device::device_start()
save_item(NAME(m_rx_state));
save_item(NAME(m_tx_state));
save_item(NAME(m_tx_parity));
+ save_item(NAME(m_clock_mode));
save_item(NAME(m_clock_state));
- save_item(NAME(m_tx_clock_value));
- save_item(NAME(m_rx_clock_value));
- save_item(NAME(m_tx_clock_base));
- save_item(NAME(m_rx_clock_base));
+ save_item(NAME(m_clock_event));
+ save_item(NAME(m_clock_step));
save_item(NAME(m_divider));
+ save_item(NAME(m_rx_value));
save_item(NAME(m_ext_clock_value));
- save_item(NAME(m_tx_ext_clock_counter));
- save_item(NAME(m_rx_ext_clock_counter));
- save_item(NAME(m_cur_sync_time));
+ save_item(NAME(m_tx_clock_counter));
+ save_item(NAME(m_rx_clock_counter));
}
void h8_sci_device::device_reset()
@@ -289,25 +332,14 @@ void h8_sci_device::device_reset()
m_tx_state = ST_IDLE;
m_rx_state = ST_IDLE;
m_clock_state = 0;
- m_clock_mode = clock_mode_t::INTERNAL_ASYNC;
- m_tx_clock_base = 0;
- m_rx_clock_base = 0;
+ m_clock_mode = INTERNAL_ASYNC;
+ m_clock_event = 0;
clock_update();
- m_tx_clock_value = true;
- m_rx_clock_value = true;
m_ext_clock_value = true;
- m_tx_ext_clock_counter = 0;
- m_rx_ext_clock_counter = 0;
- m_rx_value = true;
- m_cpu->do_sci_clk(m_id, m_tx_clock_value);
+ m_tx_clock_counter = 0;
+ m_rx_clock_counter = 0;
+ m_cpu->do_sci_clk(m_id, 1);
m_cpu->do_sci_tx(m_id, 1);
- m_cur_sync_time = attotime::never;
-}
-
-void h8_sci_device::device_post_load()
-{
- // Set clock_mode correctly as it's not saved
- clock_update();
}
TIMER_CALLBACK_MEMBER(h8_sci_device::sync_tick)
@@ -317,239 +349,85 @@ TIMER_CALLBACK_MEMBER(h8_sci_device::sync_tick)
void h8_sci_device::do_rx_w(int state)
{
+ if(m_cpu->standby()) {
+ m_rx_value = state;
+ return;
+ }
+
+ if(state != m_rx_value && (m_clock_state & CLK_RX))
+ if(m_rx_clock_counter == 1 || m_rx_clock_counter == 15)
+ m_rx_clock_counter = 0;
+
m_rx_value = state;
- if(V>=2) logerror("rx=%d\n", state);
- if(!m_rx_value && !(m_clock_state & CLK_RX) && m_rx_state != ST_IDLE && !m_cpu->standby())
+ if(!m_rx_value && !(m_clock_state & CLK_RX) && m_rx_state != ST_IDLE)
clock_start(CLK_RX);
}
void h8_sci_device::do_clk_w(int state)
{
- if(m_ext_clock_value != state) {
- m_ext_clock_value = state;
- if(m_clock_state && !m_cpu->standby()) {
- switch(m_clock_mode) {
- case clock_mode_t::EXTERNAL_ASYNC:
- if(m_ext_clock_value) {
- m_tx_ext_clock_counter = (m_tx_ext_clock_counter+1) & 15;
- m_rx_ext_clock_counter = (m_rx_ext_clock_counter+1) & 15;
-
- if((m_clock_state & CLK_TX) && m_tx_ext_clock_counter == 0)
- tx_dropped_edge();
- if((m_clock_state & CLK_RX) && m_rx_ext_clock_counter == 8)
- rx_raised_edge();
- }
- break;
-
- case clock_mode_t::EXTERNAL_SYNC:
- if((!m_ext_clock_value) && (m_clock_state & CLK_TX))
- tx_dropped_edge();
-
- else if(m_ext_clock_value && (m_clock_state & CLK_RX))
- rx_raised_edge();
- break;
- default:
- // Do nothing
- break;
- }
- }
+ if(m_ext_clock_value == state)
+ return;
+
+ m_ext_clock_value = state;
+ if(!m_clock_state || m_cpu->standby())
+ return;
+
+ if(m_clock_mode == EXTERNAL_ASYNC) {
+ if(m_clock_state & CLK_TX)
+ tx_async_tick();
+ if(m_clock_state & CLK_RX)
+ rx_async_tick();
+ } else if(m_clock_mode == EXTERNAL_SYNC) {
+ if(m_clock_state & CLK_TX)
+ tx_sync_tick();
+ if(m_clock_state & CLK_RX)
+ rx_sync_tick();
}
}
u64 h8_sci_device::internal_update(u64 current_time)
{
- u64 tx_event = 0, rx_event = 0;
- switch(m_clock_mode) {
- case clock_mode_t::INTERNAL_SYNC_OUT:
- if(m_clock_state & CLK_TX) {
- u64 fp = m_divider*2;
- if(current_time >= m_tx_clock_base) {
- u64 delta = current_time - m_tx_clock_base;
- if(delta >= fp) {
- delta -= fp;
- m_tx_clock_base += fp;
- }
- assert(delta < fp);
-
- bool new_clock = delta >= m_divider;
- if(new_clock != m_tx_clock_value) {
- machine().scheduler().synchronize();
- if(!new_clock)
- tx_dropped_edge();
-
- m_tx_clock_value = new_clock;
- if(m_clock_state || m_tx_clock_value)
- m_cpu->do_sci_clk(m_id, m_tx_clock_value);
- }
- }
- tx_event = m_tx_clock_base + (m_tx_clock_value ? fp : m_divider);
- }
- if(m_clock_state & CLK_RX) {
- u64 fp = m_divider*2;
- if(current_time >= m_rx_clock_base) {
- u64 delta = current_time - m_rx_clock_base;
- if(delta >= fp) {
- delta -= fp;
- m_rx_clock_base += fp;
- }
- assert(delta < fp);
-
- bool new_clock = delta >= m_divider;
- if(new_clock != m_rx_clock_value) {
- machine().scheduler().synchronize();
- if(new_clock)
- rx_raised_edge();
-
- m_rx_clock_value = new_clock;
- }
- }
- rx_event = m_rx_clock_base + (m_rx_clock_value ? fp : m_divider);
- }
- break;
-
- case clock_mode_t::INTERNAL_ASYNC:
- case clock_mode_t::INTERNAL_ASYNC_OUT:
- if(m_clock_state & CLK_TX) {
- u64 fp = m_divider*16;
- if(current_time >= m_tx_clock_base) {
- u64 delta = current_time - m_tx_clock_base;
- if(delta >= fp) {
- delta -= fp;
- m_tx_clock_base += fp;
- }
- assert(delta < fp);
- bool new_clock = delta >= m_divider*8;
- if(new_clock != m_tx_clock_value) {
- machine().scheduler().synchronize();
- if(!new_clock)
- tx_dropped_edge();
-
- m_tx_clock_value = new_clock;
- if(m_clock_mode == clock_mode_t::INTERNAL_ASYNC_OUT && (m_clock_state || !m_tx_clock_value))
- m_cpu->do_sci_clk(m_id, m_tx_clock_value);
- }
- }
- tx_event = m_tx_clock_base + (m_tx_clock_value ? fp : m_divider*8);
- }
-
- if(m_clock_state & CLK_RX) {
- u64 fp = m_divider*16;
- if(current_time >= m_rx_clock_base) {
- u64 delta = current_time - m_rx_clock_base;
- if(delta >= fp) {
- delta -= fp;
- m_rx_clock_base += fp;
- }
- assert(delta < fp);
- bool new_clock = delta >= m_divider*8;
- if(new_clock != m_rx_clock_value) {
- machine().scheduler().synchronize();
- if(new_clock)
- rx_raised_edge();
-
- m_rx_clock_value = new_clock;
- if(m_clock_mode == clock_mode_t::INTERNAL_ASYNC_OUT && (m_clock_state || !m_rx_clock_value))
- m_cpu->do_sci_clk(m_id, m_rx_clock_value);
- }
- }
- rx_event = m_rx_clock_base + (m_rx_clock_value ? fp : m_divider*8);
- }
- break;
-
- case clock_mode_t::EXTERNAL_RATE_SYNC:
- if(m_clock_state & CLK_TX) {
- u64 ctime = u64(current_time*m_internal_to_external_ratio*2);
- if(ctime >= m_tx_clock_base) {
- u64 delta = ctime - m_tx_clock_base;
- m_tx_clock_base += delta & ~1;
- delta &= 1;
- bool new_clock = delta >= 1;
- if(new_clock != m_tx_clock_value) {
- machine().scheduler().synchronize();
- if(!new_clock)
- tx_dropped_edge();
-
- m_tx_clock_value = new_clock;
- }
- }
-
- tx_event = u64((m_tx_clock_base + (m_tx_clock_value ? 2 : 1))*m_external_to_internal_ratio)+1;
- }
+ if(!m_clock_event || current_time < m_clock_event)
+ return m_clock_event;
+
+ if(m_clock_mode == INTERNAL_ASYNC || m_clock_mode == INTERNAL_ASYNC_OUT || m_clock_mode == EXTERNAL_RATE_ASYNC) {
+ if(m_clock_state & CLK_TX)
+ tx_async_tick();
+ if(m_clock_state & CLK_RX)
+ rx_async_tick();
+ } else if(m_clock_mode == INTERNAL_SYNC_OUT || m_clock_mode == EXTERNAL_RATE_SYNC) {
+ if(m_clock_state & CLK_TX)
+ tx_sync_tick();
+ if(m_clock_state & CLK_RX)
+ rx_sync_tick();
+ }
- if(m_clock_state & CLK_RX) {
- u64 ctime = u64(current_time*m_internal_to_external_ratio*2);
- if(ctime >= m_rx_clock_base) {
- u64 delta = ctime - m_rx_clock_base;
- m_rx_clock_base += delta & ~1;
- delta &= 1;
- bool new_clock = delta >= 1;
- if(new_clock != m_rx_clock_value) {
- machine().scheduler().synchronize();
- if(new_clock)
- rx_raised_edge();
-
- m_rx_clock_value = new_clock;
- }
- }
+ if(m_clock_state) {
+ if(m_clock_step)
+ m_clock_event += m_clock_step;
+ else if(m_clock_mode == EXTERNAL_RATE_ASYNC || m_clock_mode == EXTERNAL_RATE_SYNC)
+ m_clock_event = u64(u64(m_clock_event * m_internal_to_external_ratio + 1) * m_external_to_internal_ratio + 1);
+ else
+ m_clock_event = 0;
- rx_event = u64((m_rx_clock_base + (m_rx_clock_value ? 2 : 1))*m_external_to_internal_ratio)+1;
+ if(m_clock_event) {
+ m_sync_timer->adjust(attotime::from_ticks(m_clock_event - m_cpu->now_as_cycles(), m_cpu->clock()));
+ m_cpu->internal_update();
}
- break;
- case clock_mode_t::EXTERNAL_RATE_ASYNC:
- if(m_clock_state & CLK_TX) {
- u64 ctime = u64(current_time*m_internal_to_external_ratio);
- if(ctime >= m_tx_clock_base) {
- u64 delta = ctime - m_tx_clock_base;
- m_tx_clock_base += delta & ~15;
- delta &= 15;
- bool new_clock = delta >= 8;
- if(new_clock != m_tx_clock_value) {
- machine().scheduler().synchronize();
- if(!new_clock)
- tx_dropped_edge();
- m_tx_clock_value = new_clock;
- }
- }
-
- tx_event = u64((m_tx_clock_base + (m_tx_clock_value ? 16 : 8))*m_external_to_internal_ratio)+1;
- }
- if(m_clock_state & CLK_RX) {
- u64 ctime = u64(current_time*m_internal_to_external_ratio);
- if(ctime >= m_rx_clock_base) {
- u64 delta = ctime - m_rx_clock_base;
- m_rx_clock_base += delta & ~15;
- delta &= 15;
- bool new_clock = delta >= 8;
- if(new_clock != m_rx_clock_value) {
- machine().scheduler().synchronize();
- if(new_clock)
- rx_raised_edge();
-
- m_rx_clock_value = new_clock;
- }
- }
+ } else if(!m_clock_state) {
+ m_clock_event = 0;
+ if(m_clock_mode == INTERNAL_ASYNC_OUT || m_clock_mode == INTERNAL_SYNC_OUT)
+ m_cpu->do_sci_clk(m_id, 1);
+ }
- rx_event = u64((m_rx_clock_base + (m_rx_clock_value ? 16 : 8))*m_external_to_internal_ratio)+1;
- }
- break;
+ return m_clock_event;
+}
- case clock_mode_t::EXTERNAL_ASYNC:
- case clock_mode_t::EXTERNAL_SYNC:
- break;
- }
- u64 event = rx_event;
- if(!event || (tx_event && tx_event < event))
- event = tx_event;
- if(event) {
- attotime ctime = machine().time();
- attotime sync_time = attotime::from_ticks(event-10, m_cpu->clock());
- if(m_cur_sync_time != sync_time && sync_time > ctime) {
- m_sync_timer->adjust(sync_time - ctime);
- m_cur_sync_time = sync_time;
- }
- }
- return event;
+void h8_sci_device::notify_standby(int state)
+{
+ if(!state && m_clock_event)
+ m_clock_event += m_cpu->total_cycles() - m_cpu->standby_time();
}
void h8_sci_device::clock_start(int mode)
@@ -558,48 +436,43 @@ void h8_sci_device::clock_start(int mode)
if(m_clock_state & mode)
return;
- machine().scheduler().synchronize();
+ if(mode == CLK_TX)
+ m_tx_clock_counter = 15;
+ else
+ m_rx_clock_counter = 15;
+
m_clock_state |= mode;
- switch(m_clock_mode) {
- case clock_mode_t::INTERNAL_ASYNC:
- case clock_mode_t::INTERNAL_ASYNC_OUT:
- case clock_mode_t::INTERNAL_SYNC_OUT:
- if(V>=1) logerror("Starting internal clock\n");
- if(mode == CLK_TX)
- m_tx_clock_base = machine().time().as_ticks(m_cpu->clock());
- else
- m_rx_clock_base = machine().time().as_ticks(m_cpu->clock());
- m_cpu->internal_update();
- break;
+ if(m_clock_state != mode)
+ return;
- case clock_mode_t::EXTERNAL_RATE_ASYNC:
- if(V>=1) logerror("Simulating external clock async\n");
- if(mode == CLK_TX)
- m_tx_clock_base = u64(m_cpu->total_cycles()*m_internal_to_external_ratio);
- else
- m_rx_clock_base = u64(m_cpu->total_cycles()*m_internal_to_external_ratio);
- m_cpu->internal_update();
- break;
+ m_clock_step = 0;
- case clock_mode_t::EXTERNAL_RATE_SYNC:
- if(V>=1) logerror("Simulating external clock sync\n");
- if(mode == CLK_TX)
- m_tx_clock_base = u64(m_cpu->total_cycles()*2*m_internal_to_external_ratio);
- else
- m_rx_clock_base = u64(m_cpu->total_cycles()*2*m_internal_to_external_ratio);
+ switch(m_clock_mode) {
+ case INTERNAL_ASYNC:
+ case INTERNAL_ASYNC_OUT:
+ case INTERNAL_SYNC_OUT: {
+ LOGMASKED(LOG_CLOCK, "Starting internal clock\n");
+ m_clock_step = m_divider;
+ u64 now = mode == CLK_TX ? m_cpu->total_cycles() : m_cpu->now_as_cycles();
+ m_clock_event = (now / m_clock_step + 1) * m_clock_step;
+ m_sync_timer->adjust(attotime::from_ticks(m_clock_event - now, m_cpu->clock()));
m_cpu->internal_update();
break;
+ }
- case clock_mode_t::EXTERNAL_ASYNC:
- if(V>=1) logerror("Waiting for external clock async\n");
- if(mode == CLK_TX)
- m_tx_ext_clock_counter = 15;
- else
- m_rx_ext_clock_counter = 15;
+ case EXTERNAL_RATE_ASYNC:
+ case EXTERNAL_RATE_SYNC: {
+ LOGMASKED(LOG_CLOCK, "Simulating external clock\n", m_clock_mode == EXTERNAL_RATE_ASYNC ? "async" : "sync");
+ u64 now = mode == CLK_TX ? m_cpu->total_cycles() : m_cpu->now_as_cycles();
+ m_clock_event = u64(u64(now * m_internal_to_external_ratio + 1) * m_external_to_internal_ratio + 1);
+ m_sync_timer->adjust(attotime::from_ticks(m_clock_event - now, m_cpu->clock()));
+ m_cpu->internal_update();
break;
+ }
- case clock_mode_t::EXTERNAL_SYNC:
- if(V>=1) logerror("Waiting for external clock sync\n");
+ case EXTERNAL_ASYNC:
+ case EXTERNAL_SYNC:
+ LOGMASKED(LOG_CLOCK, "Waiting for external clock\n");
break;
}
}
@@ -607,6 +480,11 @@ void h8_sci_device::clock_start(int mode)
void h8_sci_device::clock_stop(int mode)
{
m_clock_state &= ~mode;
+ if(!m_clock_state) {
+ m_clock_event = 0;
+ m_clock_step = 0;
+ LOGMASKED(LOG_CLOCK, "Stopping clocks\n");
+ }
m_cpu->internal_update();
}
@@ -615,7 +493,7 @@ void h8_sci_device::tx_start()
m_ssr |= SSR_TDRE;
m_tsr = m_tdr;
m_tx_parity = m_smr & SMR_OE ? 0 : 1;
- if(V>=1) logerror("start transmit %02x '%c'\n", m_tsr, m_tsr >= 32 && m_tsr < 127 ? m_tsr : '.');
+ LOGMASKED(LOG_DATA, "start transmit %02x '%c'\n", m_tsr, m_tsr >= 32 && m_tsr < 127 ? m_tsr : '.');
if(m_scr & SCR_TIE)
m_intc->internal_interrupt(m_txi_int);
if(m_smr & SMR_CA) {
@@ -630,9 +508,23 @@ void h8_sci_device::tx_start()
rx_start();
}
-void h8_sci_device::tx_dropped_edge()
+void h8_sci_device::tx_async_tick()
{
- if(V>=2) logerror("tx_dropped_edge state=%s bit=%d\n", state_names[m_tx_state], m_tx_bit);
+ m_tx_clock_counter = (m_tx_clock_counter + 1) & 15;
+ LOGMASKED(LOG_TICK, "tx_async_tick %x\n", m_tx_clock_counter);
+ if(m_tx_clock_counter == 0) {
+ tx_async_step();
+
+ if(m_clock_mode == INTERNAL_ASYNC_OUT)
+ m_cpu->do_sci_clk(m_id, 0);
+
+ } else if(m_tx_clock_counter == 8 && m_clock_mode == INTERNAL_ASYNC_OUT)
+ m_cpu->do_sci_clk(m_id, 1);
+}
+
+void h8_sci_device::tx_async_step()
+{
+ LOGMASKED(LOG_STATE, "tx_async_step state=%s bit=%d\n", state_names[m_tx_state], m_tx_bit);
switch(m_tx_state) {
case ST_START:
m_cpu->do_sci_tx(m_id, false);
@@ -676,7 +568,7 @@ void h8_sci_device::tx_dropped_edge()
m_tx_bit--;
if(!m_tx_bit) {
if(!(m_ssr & SSR_TDRE))
- tx_start();
+ tx_start();
else {
m_tx_state = ST_LAST_TICK;
m_tx_bit = 0;
@@ -701,14 +593,49 @@ void h8_sci_device::tx_dropped_edge()
default:
abort();
}
- if(V>=2) logerror(" -> state=%s bit=%d\n", state_names[m_tx_state], m_tx_bit);
+ LOGMASKED(LOG_STATE, " -> state=%s bit=%d\n", state_names[m_tx_state], m_tx_bit);
+}
+
+void h8_sci_device::tx_sync_tick()
+{
+ m_tx_clock_counter = (m_tx_clock_counter + 1) & 1;
+ LOGMASKED(LOG_TICK, "tx_sync_tick %x\n", m_tx_clock_counter);
+ if(m_tx_clock_counter == 0) {
+ tx_sync_step();
+
+ if(m_clock_mode == INTERNAL_SYNC_OUT && m_tx_state != ST_IDLE)
+ m_cpu->do_sci_clk(m_id, 0);
+
+ } else if(m_tx_clock_counter == 1 && m_clock_mode == INTERNAL_SYNC_OUT)
+ m_cpu->do_sci_clk(m_id, 1);
+}
+
+void h8_sci_device::tx_sync_step()
+{
+ LOGMASKED(LOG_STATE, "tx_sync_step bit=%d\n", m_tx_bit);
+ if(!m_tx_bit) {
+ m_tx_state = ST_IDLE;
+ clock_stop(CLK_TX);
+ m_cpu->do_sci_tx(m_id, 1);
+ m_ssr |= SSR_TEND;
+ if(m_scr & SCR_TEIE)
+ m_intc->internal_interrupt(m_tei_int);
+
+ // if there's more to send, start the transmitter
+ if((m_scr & SCR_TE) && !(m_ssr & SSR_TDRE))
+ tx_start();
+ } else {
+ m_cpu->do_sci_tx(m_id, m_tsr & 1);
+ m_tsr >>= 1;
+ m_tx_bit--;
+ }
}
void h8_sci_device::rx_start()
{
m_rx_parity = m_smr & SMR_OE ? 0 : 1;
m_rsr = 0x00;
- if(V>=2) logerror("start receive\n");
+ LOGMASKED(LOG_STATE, "start receive\n");
if(m_smr & SMR_CA) {
m_rx_state = ST_BIT;
m_rx_bit = 8;
@@ -726,13 +653,13 @@ void h8_sci_device::rx_done()
if(!(m_ssr & SSR_FER)) {
if((m_smr & SMR_PE) && m_rx_parity) {
m_ssr |= SSR_PER;
- if(V>=1) logerror("Receive parity error\n");
+ LOGMASKED(LOG_DATA, "Receive parity error\n");
} else if(m_ssr & SSR_RDRF) {
m_ssr |= SSR_ORER;
- if(V>=1) logerror("Receive overrun\n");
+ LOGMASKED(LOG_DATA, "Receive overrun\n");
} else {
m_ssr |= SSR_RDRF;
- if(V>=1) logerror("Received %02x '%c'\n", m_rsr, m_rsr >= 32 && m_rsr < 127 ? m_rsr : '.');
+ LOGMASKED(LOG_DATA, "Received %02x '%c'\n", m_rsr, m_rsr >= 32 && m_rsr < 127 ? m_rsr : '.');
m_rdr = m_rsr;
}
}
@@ -750,9 +677,17 @@ void h8_sci_device::rx_done()
}
}
-void h8_sci_device::rx_raised_edge()
+void h8_sci_device::rx_async_tick()
+{
+ m_rx_clock_counter = (m_rx_clock_counter + 1) & 15;
+ LOGMASKED(LOG_TICK, "rx_async_tick %x\n", m_rx_clock_counter);
+ if(m_rx_clock_counter == 8)
+ rx_async_step();
+}
+
+void h8_sci_device::rx_async_step()
{
- if(V>=2) logerror("rx_raised_edge state=%s bit=%d\n", state_names[m_rx_state], m_rx_bit);
+ LOGMASKED(LOG_STATE, "rx_async_step state=%s bit=%d\n", state_names[m_rx_state], m_rx_bit);
switch(m_rx_state) {
case ST_START:
if(m_rx_value) {
@@ -803,5 +738,33 @@ void h8_sci_device::rx_raised_edge()
default:
abort();
}
- if(V>=2) logerror(" -> state=%s, bit=%d\n", state_names[m_rx_state], m_rx_bit);
+ LOGMASKED(LOG_STATE, " -> state=%s, bit=%d\n", state_names[m_rx_state], m_rx_bit);
+}
+
+void h8_sci_device::rx_sync_tick()
+{
+ m_rx_clock_counter = (m_rx_clock_counter + 1) & 1;
+ LOGMASKED(LOG_TICK, "rx_sync_tick %x\n", m_rx_clock_counter);
+
+ if(m_rx_clock_counter == 0 && m_clock_mode == INTERNAL_SYNC_OUT)
+ m_cpu->do_sci_clk(m_id, 0);
+
+ else if(m_rx_clock_counter == 1) {
+ if(m_clock_mode == INTERNAL_SYNC_OUT)
+ m_cpu->do_sci_clk(m_id, 1);
+
+ rx_sync_step();
+ }
+}
+
+void h8_sci_device::rx_sync_step()
+{
+ LOGMASKED(LOG_STATE, "rx_sync_step bit=%d\n", m_rx_value);
+ m_rsr >>= 1;
+ if(m_rx_value)
+ m_rsr |= 0x80;
+ m_rx_bit--;
+
+ if(!m_rx_bit)
+ rx_done();
}
diff --git a/src/devices/cpu/h8/h8_sci.h b/src/devices/cpu/h8/h8_sci.h
index 170745fa668d8..5a3671e63abf4 100644
--- a/src/devices/cpu/h8/h8_sci.h
+++ b/src/devices/cpu/h8/h8_sci.h
@@ -52,6 +52,7 @@ class h8_sci_device : public device_t {
void do_clk_w(int state);
u64 internal_update(u64 current_time);
+ void notify_standby(int state);
protected:
enum {
@@ -65,7 +66,7 @@ class h8_sci_device : public device_t {
CLK_RX = 2
};
- enum class clock_mode_t {
+ enum {
INTERNAL_ASYNC,
INTERNAL_ASYNC_OUT,
EXTERNAL_ASYNC,
@@ -106,35 +107,42 @@ class h8_sci_device : public device_t {
required_device m_cpu;
required_device m_intc;
- attotime m_external_clock_period, m_cur_sync_time;
+ attotime m_external_clock_period;
double m_external_to_internal_ratio, m_internal_to_external_ratio;
emu_timer *m_sync_timer;
int m_id, m_eri_int, m_rxi_int, m_txi_int, m_tei_int;
- int m_tx_state, m_rx_state, m_tx_bit, m_rx_bit, m_clock_state, m_tx_parity, m_rx_parity, m_tx_ext_clock_counter, m_rx_ext_clock_counter;
- clock_mode_t m_clock_mode;
- bool m_tx_clock_value, m_rx_clock_value, m_ext_clock_value, m_rx_value;
+ int m_tx_state, m_rx_state, m_tx_bit, m_rx_bit, m_clock_state, m_tx_parity, m_rx_parity, m_tx_clock_counter, m_rx_clock_counter;
+ u32 m_clock_mode;
+ bool m_ext_clock_value, m_rx_value;
u8 m_rdr, m_tdr, m_smr, m_scr, m_ssr, m_brr, m_rsr, m_tsr;
- u64 m_tx_clock_base, m_rx_clock_base, m_divider;
+ u64 m_clock_event, m_clock_step, m_divider;
std::string m_last_clock_message;
void device_start() override;
void device_reset() override;
- void device_post_load() override;
TIMER_CALLBACK_MEMBER(sync_tick);
void clock_start(int mode);
void clock_stop(int mode);
void clock_update();
+
void tx_start();
- void tx_dropped_edge();
+ void tx_async_tick();
+ void tx_async_step();
+ void tx_sync_tick();
+ void tx_sync_step();
+
void rx_start();
void rx_done();
- void rx_raised_edge();
+ void rx_async_tick();
+ void rx_async_step();
+ void rx_sync_tick();
+ void rx_sync_step();
bool is_sync_start() const;
bool has_recv_error() const;
diff --git a/src/devices/cpu/h8/h8_timer16.cpp b/src/devices/cpu/h8/h8_timer16.cpp
index 20ef62a7fbd45..d7aa2c2a8cfb3 100644
--- a/src/devices/cpu/h8/h8_timer16.cpp
+++ b/src/devices/cpu/h8/h8_timer16.cpp
@@ -12,12 +12,16 @@
Or if it's edge triggered, will it trigger an IRQ on rising edge of
(irq_enable & flag)? Note that mu100 will lock up at boot if it's
triggered at rising edge of (flag) or (irq_enable & flag).
+ - When writing 0 to the status register(s), the overflow/compare match
+ flags will only be cleared after a read access was done while they
+ were set? It's how the databook explains it, similar to HD6301.
- H8/325 16-bit timer is shoehorned in and may have a bug lurking?
It doesn't have TGR registers, but functionally equivalent OCR/ICR.
- Make the base class more generic, and derive the devices from that,
so they don't have to jumble so much with the IRQ/flag bits. The
overflow IRQ/flag being hardcoded on bit 4 is also problematic.
- Proper support for input capture registers.
+ - Add support for chained timers.
***************************************************************************/
@@ -122,7 +126,8 @@ void h8_timer16_channel_device::tier_w(u8 data)
u8 h8_timer16_channel_device::tsr_r()
{
- update_counter();
+ if(!machine().side_effects_disabled())
+ update_counter();
return isr_to_sr();
}
@@ -136,7 +141,8 @@ void h8_timer16_channel_device::tsr_w(u8 data)
u16 h8_timer16_channel_device::tcnt_r()
{
- update_counter();
+ if(!machine().side_effects_disabled())
+ update_counter();
return m_tcnt;
}
@@ -163,7 +169,7 @@ void h8_timer16_channel_device::tgr_w(offs_t offset, u16 data, u16 mem_mask)
u16 h8_timer16_channel_device::tbr_r(offs_t offset)
{
- return m_tgr[offset+m_tgr_count];
+ return m_tgr[offset + m_tgr_count];
}
void h8_timer16_channel_device::tbr_w(offs_t offset, u16 data, u16 mem_mask)
@@ -196,7 +202,7 @@ void h8_timer16_channel_device::device_start()
void h8_timer16_channel_device::device_reset()
{
- // Don't touch channel_active here, top level device handles it
+ // Don't touch channel_active here, top level device handles it.
m_tcr = 0;
m_tcnt = 0;
memset(m_tgr, 0xff, sizeof(m_tgr));
@@ -215,14 +221,23 @@ void h8_timer16_channel_device::device_reset()
u64 h8_timer16_channel_device::internal_update(u64 current_time)
{
- if(m_event_time && current_time >= m_event_time) {
- update_counter(current_time);
- recalc_event(current_time);
+ while(m_event_time && current_time >= m_event_time) {
+ update_counter(m_event_time);
+ recalc_event(m_event_time);
}
return m_event_time;
}
+void h8_timer16_channel_device::notify_standby(int state)
+{
+ if(!state && m_event_time) {
+ u64 delta = m_cpu->total_cycles() - m_cpu->standby_time();
+ m_event_time += delta;
+ m_last_clock_update += delta;
+ }
+}
+
void h8_timer16_channel_device::update_counter(u64 cur_time)
{
if(m_clock_type != DIV_1)
@@ -237,29 +252,58 @@ void h8_timer16_channel_device::update_counter(u64 cur_time)
}
u64 base_time = m_last_clock_update;
+ m_last_clock_update = cur_time;
u64 new_time = cur_time;
if(m_clock_divider) {
base_time = (base_time + m_phase) >> m_clock_divider;
new_time = (new_time + m_phase) >> m_clock_divider;
}
+ if(new_time == base_time)
+ return;
+
if(m_counter_incrementing) {
- int tt = m_tcnt + new_time - base_time;
- m_tcnt = tt % m_counter_cycle;
+ u16 prev = m_tcnt;
+ u64 delta = new_time - base_time;
+ u64 tt = m_tcnt + delta;
+
+ if(prev >= m_counter_cycle) {
+ if(tt >= 0x10000)
+ m_tcnt = (tt - 0x10000) % m_counter_cycle;
+ else
+ m_tcnt = tt;
+ }
+ else
+ m_tcnt = tt % m_counter_cycle;
+
+ for(int i = 0; i < m_tgr_count; i++) {
+ bool match = m_tcnt == m_tgr[i] || (tt == m_tgr[i] && tt == m_counter_cycle);
+ if(!match) {
+ // Need to do additional checks here for software that polls the flags with interrupts disabled,
+ // since recalc_event only schedules IRQ events.
+ if(prev >= m_counter_cycle)
+ match = (m_tgr[i] > prev && tt >= m_tgr[i]) || (m_tgr[i] <= m_counter_cycle && m_tcnt < m_counter_cycle && (delta - (0x10000 - prev)) >= m_tgr[i]);
+ else if(m_tgr[i] <= m_counter_cycle)
+ match = delta >= m_counter_cycle || (prev < m_tgr[i] && tt >= m_tgr[i]) || (m_tcnt <= prev && m_tcnt >= m_tgr[i]);
+
+ if(match && BIT(m_ier, i) && m_interrupt[i] != -1)
+ logerror("update_counter unexpected TGR %d IRQ\n, i");
+ }
- for(int i=0; iinternal_interrupt(m_interrupt[i]);
}
- if(tt >= 0x10000) {
+ }
+ if(tt >= 0x10000 && (m_counter_cycle == 0x10000 || prev >= m_counter_cycle)) {
m_isr |= IRQ_V;
- if (m_ier & IRQ_V && m_interrupt[4] != -1)
+ if(m_ier & IRQ_V && m_interrupt[4] != -1)
m_intc->internal_interrupt(m_interrupt[4]);
}
- } else
- m_tcnt = (((m_tcnt ^ 0xffff) + new_time - base_time) % m_counter_cycle) ^ 0xffff;
- m_last_clock_update = cur_time;
+ } else {
+ logerror("decrementing counter\n");
+ exit(1);
+ }
}
void h8_timer16_channel_device::recalc_event(u64 cur_time)
@@ -287,16 +331,13 @@ void h8_timer16_channel_device::recalc_event(u64 cur_time)
u32 event_delay = 0xffffffff;
if(m_tgr_clearing >= 0 && m_tgr[m_tgr_clearing])
m_counter_cycle = m_tgr[m_tgr_clearing];
- else {
+ else
m_counter_cycle = 0x10000;
- if(m_ier & IRQ_V) {
- event_delay = m_counter_cycle - m_tcnt;
- if(!event_delay)
- event_delay = m_counter_cycle;
- }
- }
- for(int i=0; i= m_counter_cycle))
+ event_delay = 0x10000 - m_tcnt;
+
+ for(int i = 0; i < m_tgr_count; i++)
+ if(BIT(m_ier, i) && m_interrupt[i] != -1) {
u32 new_delay = 0xffffffff;
if(m_tgr[i] > m_tcnt) {
if(m_tcnt >= m_counter_cycle || m_tgr[i] <= m_counter_cycle)
@@ -316,7 +357,6 @@ void h8_timer16_channel_device::recalc_event(u64 cur_time)
m_event_time = ((((cur_time + (1ULL << m_clock_divider) - m_phase) >> m_clock_divider) + event_delay - 1) << m_clock_divider) + m_phase;
else
m_event_time = 0;
-
} else {
logerror("decrementing counter\n");
exit(1);
@@ -339,10 +379,10 @@ void h8_timer16_device::device_start()
save_item(NAME(m_tstr));
}
-void h8_timer16_device::device_reset()
+void h8_timer16_device::device_reset_after_children()
{
m_tstr = m_default_tstr;
- for(int i=0; iset_enable((m_tstr >> i) & 1);
}
@@ -356,7 +396,7 @@ void h8_timer16_device::tstr_w(u8 data)
{
if(V>=1) logerror("tstr_w %02x\n", data);
m_tstr = data;
- for(int i=0; iset_enable((m_tstr >> i) & 1);
}
@@ -413,9 +453,9 @@ void h8_timer16_device::tocr_w(u8 data)
u8 h8_timer16_device::tisr_r(offs_t offset)
{
u8 r = 0;
- for(int i=0; itisr_r(offset) << i;
- for(int i=m_timer_count; i<4; i++)
+ for(int i = m_timer_count; i < 4; i++)
r |= 0x11 <=1) logerror("tisr%c_r %02x\n", 'a'+offset, r);
@@ -426,7 +466,7 @@ u8 h8_timer16_device::tisr_r(offs_t offset)
void h8_timer16_device::tisr_w(offs_t offset, u8 data)
{
if(V>=1) logerror("tisr%c_w %02x\n", 'a'+offset, data);
- for(int i=0; itisr_w(offset, data >> i);
}
@@ -579,7 +619,7 @@ void h8325_timer16_channel_device::isr_update(u8 val)
{
m_tcsr = val;
- if (val & 1)
+ if(val & 1)
m_tgr_clearing = 0;
else
m_tgr_clearing = TGR_CLEAR_NONE;
diff --git a/src/devices/cpu/h8/h8_timer16.h b/src/devices/cpu/h8/h8_timer16.h
index fb53e0bfc217c..2051bbe59fdd0 100644
--- a/src/devices/cpu/h8/h8_timer16.h
+++ b/src/devices/cpu/h8/h8_timer16.h
@@ -91,6 +91,7 @@ class h8_timer16_channel_device : public device_t {
void tbr_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u64 internal_update(u64 current_time);
+ void notify_standby(int state);
void set_ier(u8 value);
void set_enable(bool enable);
void tisr_w(int offset, u8 data);
@@ -271,7 +272,7 @@ class h8_timer16_device : public device_t {
u8 m_tstr;
virtual void device_start() override;
- virtual void device_reset() override;
+ virtual void device_reset_after_children() override;
};
DECLARE_DEVICE_TYPE(H8_TIMER16, h8_timer16_device)
diff --git a/src/devices/cpu/h8/h8_timer8.cpp b/src/devices/cpu/h8/h8_timer8.cpp
index 1af76263a71d8..c35310df25552 100644
--- a/src/devices/cpu/h8/h8_timer8.cpp
+++ b/src/devices/cpu/h8/h8_timer8.cpp
@@ -11,6 +11,9 @@
while an overflow or compare match flag is 1, will it trigger an IRQ?
Or if it's edge triggered, will it trigger an IRQ on rising edge of
(irq_enable & flag)?
+ - When writing 0 to the status register(s), the overflow/compare match
+ flags will only be cleared after a read access was done while they
+ were set? It's how the databook explains it, similar to HD6301.
***************************************************************************/
@@ -169,8 +172,10 @@ void h8_timer8_channel_device::tcor_w(offs_t offset, u8 data)
u8 h8_timer8_channel_device::tcnt_r()
{
- update_counter();
- recalc_event();
+ if(!machine().side_effects_disabled()) {
+ update_counter();
+ recalc_event();
+ }
return m_tcnt;
}
@@ -204,29 +209,51 @@ void h8_timer8_channel_device::device_reset()
u64 h8_timer8_channel_device::internal_update(u64 current_time)
{
- if(m_event_time && current_time >= m_event_time) {
- update_counter(current_time);
- recalc_event(current_time);
+ while(m_event_time && current_time >= m_event_time) {
+ update_counter(m_event_time);
+ recalc_event(m_event_time);
}
return m_event_time;
}
-void h8_timer8_channel_device::update_counter(u64 cur_time)
+void h8_timer8_channel_device::notify_standby(int state)
{
- if(m_clock_type != DIV)
- return;
+ if(!state && m_event_time) {
+ u64 delta = m_cpu->total_cycles() - m_cpu->standby_time();
+ m_event_time += delta;
+ m_last_clock_update += delta;
+ }
+}
- if(!cur_time)
- cur_time = m_cpu->total_cycles();
+void h8_timer8_channel_device::update_counter(u64 cur_time, u64 delta)
+{
+ if(m_clock_type == DIV) {
+ if(!cur_time)
+ cur_time = m_cpu->total_cycles();
+
+ u64 base_time = (m_last_clock_update + m_clock_divider/2) / m_clock_divider;
+ m_last_clock_update = cur_time;
+ u64 new_time = (cur_time + m_clock_divider/2) / m_clock_divider;
+ delta = new_time - base_time;
+ }
+
+ if(!delta)
+ return;
- u64 base_time = (m_last_clock_update + m_clock_divider/2) / m_clock_divider;
- u64 new_time = (cur_time + m_clock_divider/2) / m_clock_divider;
+ u8 prev = m_tcnt;
+ u64 tt = m_tcnt + delta;
- int tt = m_tcnt + new_time - base_time;
- m_tcnt = tt % m_counter_cycle;
+ if(prev >= m_counter_cycle) {
+ if(tt >= 0x100)
+ m_tcnt = (tt - 0x100) % m_counter_cycle;
+ else
+ m_tcnt = tt;
+ }
+ else
+ m_tcnt = tt % m_counter_cycle;
- if(tt == m_tcor[0] || m_tcnt == m_tcor[0]) {
+ if(m_tcnt == m_tcor[0] || (tt == m_tcor[0] && tt == m_counter_cycle)) {
if(m_chained_timer)
m_chained_timer->chained_timer_tcora();
@@ -243,7 +270,7 @@ void h8_timer8_channel_device::update_counter(u64 cur_time)
m_intc->internal_interrupt(m_irq_cb);
}
- if(tt >= 0x100) {
+ if(tt >= 0x100 && (m_counter_cycle == 0x100 || prev >= m_counter_cycle)) {
if(m_chained_timer)
m_chained_timer->chained_timer_overflow();
if(!(m_tcsr & TCSR_OVF)) {
@@ -252,7 +279,6 @@ void h8_timer8_channel_device::update_counter(u64 cur_time)
m_intc->internal_interrupt(m_irq_v);
}
}
- m_last_clock_update = cur_time;
}
void h8_timer8_channel_device::recalc_event(u64 cur_time)
@@ -273,12 +299,10 @@ void h8_timer8_channel_device::recalc_event(u64 cur_time)
u32 event_delay = 0xffffffff;
if((m_clear_type == CLEAR_A || m_clear_type == CLEAR_B) && m_tcor[m_clear_type - CLEAR_A])
m_counter_cycle = m_tcor[m_clear_type - CLEAR_A];
- else {
+ else
m_counter_cycle = 0x100;
- event_delay = m_counter_cycle - m_tcnt;
- if(!event_delay)
- event_delay = m_counter_cycle;
- }
+ if(m_counter_cycle == 0x100 || m_tcnt >= m_counter_cycle)
+ event_delay = 0x100 - m_tcnt;
for(auto &elem : m_tcor) {
u32 new_delay = 0xffffffff;
@@ -307,45 +331,13 @@ void h8_timer8_channel_device::recalc_event(u64 cur_time)
void h8_timer8_channel_device::chained_timer_overflow()
{
if(m_clock_type == CHAIN_OVERFLOW)
- timer_tick();
+ update_counter(0, 1);
}
void h8_timer8_channel_device::chained_timer_tcora()
{
if(m_clock_type == CHAIN_A)
- timer_tick();
-}
-
-void h8_timer8_channel_device::timer_tick()
-{
- m_tcnt++;
-
- if(m_tcnt == m_tcor[0]) {
- if(m_chained_timer)
- m_chained_timer->chained_timer_tcora();
-
- if(!(m_tcsr & TCSR_CMFA)) {
- m_tcsr |= TCSR_CMFA;
- if(m_tcr & TCR_CMIEA)
- m_intc->internal_interrupt(m_irq_ca);
- }
- }
-
- if(!(m_tcsr & TCSR_CMFB) && m_tcnt == m_tcor[1]) {
- m_tcsr |= TCSR_CMFB;
- if(m_tcr & TCR_CMIEB)
- m_intc->internal_interrupt(m_irq_cb);
- }
-
- if(m_tcnt == 0x00) {
- if(m_chained_timer)
- m_chained_timer->chained_timer_overflow();
- if(!(m_tcsr & TCSR_OVF)) {
- m_tcsr |= TCSR_OVF;
- if(m_tcr & TCR_OVIE)
- m_intc->internal_interrupt(m_irq_v);
- }
- }
+ update_counter(0, 1);
}
h8h_timer8_channel_device::h8h_timer8_channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
diff --git a/src/devices/cpu/h8/h8_timer8.h b/src/devices/cpu/h8/h8_timer8.h
index c5f6dd98f39eb..65468a76a5d41 100644
--- a/src/devices/cpu/h8/h8_timer8.h
+++ b/src/devices/cpu/h8/h8_timer8.h
@@ -56,6 +56,7 @@ class h8_timer8_channel_device : public device_t {
void tcnt_w(u8 data);
u64 internal_update(u64 current_time);
+ void notify_standby(int state);
void set_extra_clock_bit(bool bit);
void chained_timer_overflow();
@@ -100,10 +101,9 @@ class h8_timer8_channel_device : public device_t {
virtual void device_start() override;
virtual void device_reset() override;
- void update_counter(u64 cur_time = 0);
+ void update_counter(u64 cur_time = 0, u64 delta = 0);
void recalc_event(u64 cur_time = 0);
- void timer_tick();
void update_tcr();
};
diff --git a/src/devices/cpu/h8/h8_watchdog.cpp b/src/devices/cpu/h8/h8_watchdog.cpp
index cecc47bb579aa..a998c95437760 100644
--- a/src/devices/cpu/h8/h8_watchdog.cpp
+++ b/src/devices/cpu/h8/h8_watchdog.cpp
@@ -1,13 +1,25 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ h8_watchdog.cpp
+
+ H8 watchdog/timer
+
+ TODO:
+ - add RSTCSR for MCUs that have it (reset is only enabled when RSTI is 1)
+ - It will only clear the overflow flag when writing 0 after reading it
+ when it's set? It's how the databook explains it, similar to HD6301.
+
+***************************************************************************/
#include "emu.h"
#include "h8_watchdog.h"
DEFINE_DEVICE_TYPE(H8_WATCHDOG, h8_watchdog_device, "h8_watchdog", "H8 watchdog")
-const int h8_watchdog_device::div_bh[8] = { 1, 6, 7, 9, 11, 13, 15, 17 };
-const int h8_watchdog_device::div_s [8] = { 1, 5, 6, 7, 8, 9, 11, 12 };
+const int h8_watchdog_device::div_bh[8] = { 1, 5, 6, 7, 8, 9, 11, 12 };
+const int h8_watchdog_device::div_s [8] = { 1, 6, 7, 9, 11, 13, 15, 17 };
h8_watchdog_device::h8_watchdog_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, H8_WATCHDOG, tag, owner, clock),
@@ -24,11 +36,18 @@ u64 h8_watchdog_device::internal_update(u64 current_time)
int shift = (m_type == S ? div_s : div_bh)[m_tcsr & TCSR_CKS];
u64 spos = m_tcnt_cycle_base >> shift;
return (spos + 0x100 - m_tcnt) << shift;
-
} else
return 0;
}
+void h8_watchdog_device::notify_standby(int state)
+{
+ if(state)
+ tcnt_update();
+ else
+ m_tcnt_cycle_base = m_cpu->total_cycles();
+}
+
void h8_watchdog_device::tcnt_update(u64 cur_time)
{
if(m_tcsr & TCSR_TME) {
@@ -38,7 +57,7 @@ void h8_watchdog_device::tcnt_update(u64 cur_time)
u64 spos = m_tcnt_cycle_base >> shift;
u64 epos = cur_time >> shift;
- int next_tcnt = m_tcnt + int(epos - spos);
+ u64 next_tcnt = m_tcnt + (epos - spos);
m_tcnt = next_tcnt;
m_tcnt_cycle_base = cur_time;
//logerror("%10lld tcnt %02x -> %03x shift=%d\n", cur_time, m_tcnt, next_tcnt, shift);
@@ -59,14 +78,15 @@ void h8_watchdog_device::tcnt_update(u64 cur_time)
}
} else
m_tcnt = 0;
-
}
u16 h8_watchdog_device::wd_r()
{
if(!machine().side_effects_disabled())
tcnt_update();
- return (m_tcsr << 8) | m_tcnt;
+
+ u8 tcsr_mask = m_type == B ? 0x10 : 0x18;
+ return ((m_tcsr | tcsr_mask) << 8) | m_tcnt;
}
void h8_watchdog_device::wd_w(offs_t offset, u16 data, u16 mem_mask)
@@ -78,8 +98,7 @@ void h8_watchdog_device::wd_w(offs_t offset, u16 data, u16 mem_mask)
tcnt_update();
if(!(m_tcsr & TCSR_TME) && (data & TCSR_TME))
m_tcnt_cycle_base = m_cpu->total_cycles();
- m_tcsr = data & 0xff;
- m_tcsr |= m_type == B ? 0x10 : 0x18;
+ m_tcsr = (m_tcsr & data & TCSR_OVF) | (data & 0x7f);
m_cpu->internal_update();
}
@@ -97,11 +116,16 @@ u16 h8_watchdog_device::rst_r()
{
if(!machine().side_effects_disabled())
logerror("rst_r\n");
- return 0;
+
+ u8 rst_mask = m_type == S ? 0x1f : 0x3f;
+ return m_rst | rst_mask;
}
-void h8_watchdog_device::rst_w(u16 data)
+void h8_watchdog_device::rst_w(offs_t offset, u16 data, u16 mem_mask)
{
+ if(mem_mask != 0xffff)
+ return;
+
if((data & 0xff00) == 0xa500)
logerror("wowf_w %02x\n", data & 0xff);
if((data & 0xff00) == 0x5a00)
@@ -118,8 +142,8 @@ void h8_watchdog_device::device_start()
void h8_watchdog_device::device_reset()
{
- m_tcnt = 0x00;
m_tcnt_cycle_base = m_cpu->total_cycles();
- m_tcsr = m_type == B ? 0x10 : 0x18;
- m_rst = m_type == S ? 0x1f : 0x3f;
+ m_tcnt = 0x00;
+ m_tcsr = 0x00;
+ m_rst = 0x00;
}
diff --git a/src/devices/cpu/h8/h8_watchdog.h b/src/devices/cpu/h8/h8_watchdog.h
index c6882fb1d5bba..7516816f3bc8b 100644
--- a/src/devices/cpu/h8/h8_watchdog.h
+++ b/src/devices/cpu/h8/h8_watchdog.h
@@ -31,11 +31,12 @@ class h8_watchdog_device : public device_t {
}
u64 internal_update(u64 current_time);
+ void notify_standby(int state);
u16 wd_r();
void wd_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 rst_r();
- void rst_w(u16 data);
+ void rst_w(offs_t offset, u16 data, u16 mem_mask = ~0);
protected:
virtual void device_start() override;
diff --git a/src/devices/cpu/h8/h8s2245.cpp b/src/devices/cpu/h8/h8s2245.cpp
index fe93cbca22630..a7a51c26f3a98 100644
--- a/src/devices/cpu/h8/h8s2245.cpp
+++ b/src/devices/cpu/h8/h8s2245.cpp
@@ -73,8 +73,7 @@ void h8s2245_device::map(address_map &map)
map(0xfffebd, 0xfffebd).w(m_porte, FUNC(h8_port_device::ddr_w));
map(0xfffebe, 0xfffebe).w(m_portf, FUNC(h8_port_device::ddr_w));
map(0xfffebf, 0xfffebf).w(m_portg, FUNC(h8_port_device::ddr_w));
- map(0xfffec0, 0xfffec1).rw(m_intc, FUNC(h8s_intc_device::icr_r), FUNC(h8s_intc_device::icr_w));
- map(0xfffec2, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icrc_r), FUNC(h8s_intc_device::icrc_w));
+ map(0xfffec0, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icr_r), FUNC(h8s_intc_device::icr_w));
map(0xffff2c, 0xffff2c).rw(m_intc, FUNC(h8s_intc_device::iscrh_r), FUNC(h8s_intc_device::iscrh_w));
map(0xffff2d, 0xffff2d).rw(m_intc, FUNC(h8s_intc_device::iscrl_r), FUNC(h8s_intc_device::iscrl_w));
map(0xffff2e, 0xffff2e).rw(m_intc, FUNC(h8s_intc_device::ier_r), FUNC(h8s_intc_device::ier_w));
@@ -190,36 +189,36 @@ void h8s2245_device::device_add_mconfig(machine_config &config)
H8_PORT(config, m_porte, *this, h8_device::PORT_E, 0x00, 0x00);
H8_PORT(config, m_portf, *this, h8_device::PORT_F, 0x00, 0x00);
H8_PORT(config, m_portg, *this, h8_device::PORT_G, 0xe0, 0x00);
- H8H_TIMER8_CHANNEL(config, m_timer8_0, *this, m_intc, 64, 65, 66, m_timer8_1, h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
- H8H_TIMER8_CHANNEL(config, m_timer8_1, *this, m_intc, 68, 69, 70, m_timer8_0, h8_timer8_channel_device::CHAIN_A, false, false);
+ H8H_TIMER8_CHANNEL(config, m_timer8_0, *this, m_intc, 64, 65, 66, m_timer8_1, h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
+ H8H_TIMER8_CHANNEL(config, m_timer8_1, *this, m_intc, 68, 69, 70, m_timer8_0, h8_timer8_channel_device::CHAIN_A, false, false);
H8_TIMER16(config, m_timer16, *this, 3, 0x00);
H8S_TIMER16_CHANNEL(config, m_timer16_0, *this, 4, 0x60, m_intc, 32,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::INPUT_D);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::INPUT_D);
H8S_TIMER16_CHANNEL(config, m_timer16_1, *this, 2, 0x4c, m_intc, 40,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::CHAIN).set_chain(m_timer16_2);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::CHAIN).set_chain(m_timer16_2);
H8S_TIMER16_CHANNEL(config, m_timer16_2, *this, 2, 0x4c, m_intc, 44,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_1024);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_1024);
H8_SCI(config, m_sci[0], 0, *this, m_intc, 80, 81, 82, 83);
H8_SCI(config, m_sci[1], 1, *this, m_intc, 84, 85, 86, 87);
H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
@@ -300,6 +299,20 @@ void h8s2245_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h8s2245_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_sci[2]->notify_standby(state);
+ m_timer8_0->notify_standby(state);
+ m_timer8_1->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h8s2245_device::device_start()
{
h8s2000_device::device_start();
diff --git a/src/devices/cpu/h8/h8s2245.h b/src/devices/cpu/h8/h8s2245.h
index 14744418a4e39..fd01c71b928d3 100644
--- a/src/devices/cpu/h8/h8s2245.h
+++ b/src/devices/cpu/h8/h8s2245.h
@@ -102,6 +102,7 @@ class h8s2245_device : public h8s2000_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h8s2319.cpp b/src/devices/cpu/h8/h8s2319.cpp
new file mode 100644
index 0000000000000..8a439404f4277
--- /dev/null
+++ b/src/devices/cpu/h8/h8s2319.cpp
@@ -0,0 +1,458 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, hap
+/***************************************************************************
+
+ h8s2319.cpp
+
+ H8S-2319 family emulation
+
+***************************************************************************/
+
+#include "emu.h"
+#include "h8s2319.h"
+
+DEFINE_DEVICE_TYPE(H8S2310, h8s2310_device, "h8s2310", "Hitachi H8S/2310")
+DEFINE_DEVICE_TYPE(H8S2311, h8s2311_device, "h8s2311", "Hitachi H8S/2311")
+DEFINE_DEVICE_TYPE(H8S2312, h8s2312_device, "h8s2312", "Hitachi H8S/2312")
+DEFINE_DEVICE_TYPE(H8S2313, h8s2313_device, "h8s2313", "Hitachi H8S/2313")
+DEFINE_DEVICE_TYPE(H8S2315, h8s2315_device, "h8s2315", "Hitachi H8S/2315")
+DEFINE_DEVICE_TYPE(H8S2316, h8s2316_device, "h8s2316", "Hitachi H8S/2316")
+DEFINE_DEVICE_TYPE(H8S2317, h8s2317_device, "h8s2317", "Hitachi H8S/2317")
+DEFINE_DEVICE_TYPE(H8S2318, h8s2318_device, "h8s2318", "Hitachi H8S/2318")
+DEFINE_DEVICE_TYPE(H8S2319, h8s2319_device, "h8s2319", "Hitachi H8S/2319")
+
+
+h8s2319_device::h8s2319_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map_delegate, u32 start) :
+ h8s2000_device(mconfig, type, tag, owner, clock, map_delegate),
+ m_intc(*this, "intc"),
+ m_adc(*this, "adc"),
+ m_dtc(*this, "dtc"),
+ m_portn(*this, "port%u", 1),
+ m_porta(*this, "port%c", 'a'),
+ m_timer8(*this, "timer8_%u", 0),
+ m_timer16(*this, "timer16"),
+ m_timer16c(*this, "timer16:%u", 0),
+ m_watchdog(*this, "watchdog"),
+ m_ram_view(*this, "ram_view"),
+ m_ram_start(start)
+{
+}
+
+h8s2319_device::h8s2319_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start) :
+ h8s2319_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h8s2319_device::map), this), start)
+{
+}
+
+h8s2319_device::h8s2319_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2319, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2310_device::h8s2310_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2310, tag, owner, clock, 0xfff400)
+{
+}
+
+h8s2311_device::h8s2311_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2311, tag, owner, clock, 0xfff400)
+{
+}
+
+h8s2312_device::h8s2312_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2312, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2313_device::h8s2313_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2313, tag, owner, clock, 0xfff400)
+{
+}
+
+h8s2315_device::h8s2315_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2315, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2316_device::h8s2316_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2316, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2317_device::h8s2317_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2317, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2318_device::h8s2318_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2319_device(mconfig, H8S2318, tag, owner, clock, 0xffdc00)
+{
+}
+
+void h8s2319_device::map(address_map &map)
+{
+ map(m_ram_start, 0xfffbff).view(m_ram_view);
+ m_ram_view[0](m_ram_start, 0xfffbff).ram().share(m_internal_ram);
+
+ map(0xfffe80, 0xfffe80).rw(m_timer16c[3], FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
+ map(0xfffe81, 0xfffe81).rw(m_timer16c[3], FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
+ map(0xfffe82, 0xfffe83).rw(m_timer16c[3], FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
+ map(0xfffe84, 0xfffe84).rw(m_timer16c[3], FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
+ map(0xfffe85, 0xfffe85).rw(m_timer16c[3], FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
+ map(0xfffe86, 0xfffe87).rw(m_timer16c[3], FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
+ map(0xfffe88, 0xfffe8f).rw(m_timer16c[3], FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
+ map(0xfffe90, 0xfffe90).rw(m_timer16c[4], FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
+ map(0xfffe91, 0xfffe91).rw(m_timer16c[4], FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
+ map(0xfffe92, 0xfffe92).rw(m_timer16c[4], FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
+ map(0xfffe94, 0xfffe94).rw(m_timer16c[4], FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
+ map(0xfffe95, 0xfffe95).rw(m_timer16c[4], FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
+ map(0xfffe96, 0xfffe97).rw(m_timer16c[4], FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
+ map(0xfffe98, 0xfffe9b).rw(m_timer16c[4], FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
+ map(0xfffea0, 0xfffea0).rw(m_timer16c[5], FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
+ map(0xfffea1, 0xfffea1).rw(m_timer16c[5], FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
+ map(0xfffea2, 0xfffea2).rw(m_timer16c[5], FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
+ map(0xfffea4, 0xfffea4).rw(m_timer16c[5], FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
+ map(0xfffea5, 0xfffea5).rw(m_timer16c[5], FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
+ map(0xfffea6, 0xfffea7).rw(m_timer16c[5], FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
+ map(0xfffea8, 0xfffeab).rw(m_timer16c[5], FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
+
+ map(0xfffeb0, 0xfffeb0).w(m_portn[0], FUNC(h8_port_device::ddr_w));
+ map(0xfffeb1, 0xfffeb1).w(m_portn[1], FUNC(h8_port_device::ddr_w));
+ map(0xfffeb2, 0xfffeb2).w(m_portn[2], FUNC(h8_port_device::ddr_w));
+ map(0xfffeb9, 0xfffeb9).w(m_porta[0], FUNC(h8_port_device::ddr_w));
+ map(0xfffeba, 0xfffeba).w(m_porta[1], FUNC(h8_port_device::ddr_w));
+ map(0xfffebb, 0xfffebb).w(m_porta[2], FUNC(h8_port_device::ddr_w));
+ map(0xfffebc, 0xfffebc).w(m_porta[3], FUNC(h8_port_device::ddr_w));
+ map(0xfffebd, 0xfffebd).w(m_porta[4], FUNC(h8_port_device::ddr_w));
+ map(0xfffebe, 0xfffebe).w(m_porta[5], FUNC(h8_port_device::ddr_w));
+ map(0xfffebf, 0xfffebf).w(m_porta[6], FUNC(h8_port_device::ddr_w));
+
+ map(0xfffec4, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
+ map(0xffff2c, 0xffff2c).rw(m_intc, FUNC(h8s_intc_device::iscrh_r), FUNC(h8s_intc_device::iscrh_w));
+ map(0xffff2d, 0xffff2d).rw(m_intc, FUNC(h8s_intc_device::iscrl_r), FUNC(h8s_intc_device::iscrl_w));
+ map(0xffff2e, 0xffff2e).rw(m_intc, FUNC(h8s_intc_device::ier_r), FUNC(h8s_intc_device::ier_w));
+ map(0xffff2f, 0xffff2f).rw(m_intc, FUNC(h8s_intc_device::isr_r), FUNC(h8s_intc_device::isr_w));
+ map(0xffff30, 0xffff34).rw(m_dtc, FUNC(h8_dtc_device::dtcer_r), FUNC(h8_dtc_device::dtcer_w));
+ map(0xffff37, 0xffff37).rw(m_dtc, FUNC(h8_dtc_device::dtvecr_r), FUNC(h8_dtc_device::dtvecr_w));
+ map(0xffff38, 0xffff38).rw(FUNC(h8s2319_device::sbycr_r), FUNC(h8s2319_device::sbycr_w));
+ map(0xffff39, 0xffff39).rw(FUNC(h8s2319_device::syscr_r), FUNC(h8s2319_device::syscr_w));
+
+ map(0xffff50, 0xffff50).r(m_portn[0], FUNC(h8_port_device::port_r));
+ map(0xffff51, 0xffff51).r(m_portn[1], FUNC(h8_port_device::port_r));
+ map(0xffff52, 0xffff52).r(m_portn[2], FUNC(h8_port_device::port_r));
+ map(0xffff53, 0xffff53).r(m_portn[3], FUNC(h8_port_device::port_r));
+ map(0xffff59, 0xffff59).r(m_porta[0], FUNC(h8_port_device::port_r));
+ map(0xffff5a, 0xffff5a).r(m_porta[1], FUNC(h8_port_device::port_r));
+ map(0xffff5b, 0xffff5b).r(m_porta[2], FUNC(h8_port_device::port_r));
+ map(0xffff5c, 0xffff5c).r(m_porta[3], FUNC(h8_port_device::port_r));
+ map(0xffff5d, 0xffff5d).r(m_porta[4], FUNC(h8_port_device::port_r));
+ map(0xffff5e, 0xffff5e).r(m_porta[5], FUNC(h8_port_device::port_r));
+ map(0xffff5f, 0xffff5f).r(m_porta[6], FUNC(h8_port_device::port_r));
+ map(0xffff60, 0xffff60).rw(m_portn[0], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff61, 0xffff61).rw(m_portn[1], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff62, 0xffff62).rw(m_portn[2], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff69, 0xffff69).rw(m_porta[0], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff6a, 0xffff6a).rw(m_porta[1], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff6b, 0xffff6b).rw(m_porta[2], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff6c, 0xffff6c).rw(m_porta[3], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff6d, 0xffff6d).rw(m_porta[4], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff6e, 0xffff6e).rw(m_porta[5], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff6f, 0xffff6f).rw(m_porta[6], FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff70, 0xffff70).rw(m_porta[0], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffff71, 0xffff71).rw(m_porta[1], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffff72, 0xffff72).rw(m_porta[2], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffff73, 0xffff73).rw(m_porta[3], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffff74, 0xffff74).rw(m_porta[4], FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
+ map(0xffff76, 0xffff76).rw(m_portn[2], FUNC(h8_port_device::odr_r), FUNC(h8_port_device::odr_w));
+ map(0xffff77, 0xffff77).rw(m_porta[0], FUNC(h8_port_device::odr_r), FUNC(h8_port_device::odr_w));
+
+ map(0xffff78, 0xffff78).rw(m_sci[0], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
+ map(0xffff79, 0xffff79).rw(m_sci[0], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
+ map(0xffff7a, 0xffff7a).rw(m_sci[0], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
+ map(0xffff7b, 0xffff7b).rw(m_sci[0], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
+ map(0xffff7c, 0xffff7c).rw(m_sci[0], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
+ map(0xffff7d, 0xffff7d).r(m_sci[0], FUNC(h8_sci_device::rdr_r));
+ map(0xffff7e, 0xffff7e).rw(m_sci[0], FUNC(h8_sci_device::scmr_r), FUNC(h8_sci_device::scmr_w));
+ map(0xffff80, 0xffff80).rw(m_sci[1], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
+ map(0xffff81, 0xffff81).rw(m_sci[1], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
+ map(0xffff82, 0xffff82).rw(m_sci[1], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
+ map(0xffff83, 0xffff83).rw(m_sci[1], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
+ map(0xffff84, 0xffff84).rw(m_sci[1], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
+ map(0xffff85, 0xffff85).r(m_sci[1], FUNC(h8_sci_device::rdr_r));
+ map(0xffff86, 0xffff86).rw(m_sci[1], FUNC(h8_sci_device::scmr_r), FUNC(h8_sci_device::scmr_w));
+
+ map(0xffff90, 0xffff97).r(m_adc, FUNC(h8_adc_device::addr8_r));
+ map(0xffff98, 0xffff98).rw(m_adc, FUNC(h8_adc_device::adcsr_r), FUNC(h8_adc_device::adcsr_w));
+ map(0xffff99, 0xffff99).rw(m_adc, FUNC(h8_adc_device::adcr_r), FUNC(h8_adc_device::adcr_w));
+
+ map(0xffffb0, 0xffffb0).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
+ map(0xffffb1, 0xffffb1).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
+ map(0xffffb2, 0xffffb2).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
+ map(0xffffb3, 0xffffb3).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
+ map(0xffffb4, 0xffffb7).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w)).umask16(0xff00);
+ map(0xffffb4, 0xffffb7).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w)).umask16(0x00ff);
+ map(0xffffb8, 0xffffb8).rw(m_timer8[0], FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
+ map(0xffffb9, 0xffffb9).rw(m_timer8[1], FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
+
+ map(0xffffbc, 0xffffbd).rw(m_watchdog, FUNC(h8_watchdog_device::wd_r), FUNC(h8_watchdog_device::wd_w));
+ map(0xffffbe, 0xffffbf).rw(m_watchdog, FUNC(h8_watchdog_device::rst_r), FUNC(h8_watchdog_device::rst_w));
+ map(0xffffc0, 0xffffc0).rw(m_timer16, FUNC(h8_timer16_device::tstr_r), FUNC(h8_timer16_device::tstr_w));
+ map(0xffffc1, 0xffffc1).rw(m_timer16, FUNC(h8_timer16_device::tsyr_r), FUNC(h8_timer16_device::tsyr_w));
+
+ map(0xffffd0, 0xffffd0).rw(m_timer16c[0], FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
+ map(0xffffd1, 0xffffd1).rw(m_timer16c[0], FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
+ map(0xffffd2, 0xffffd3).rw(m_timer16c[0], FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
+ map(0xffffd4, 0xffffd4).rw(m_timer16c[0], FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
+ map(0xffffd5, 0xffffd5).rw(m_timer16c[0], FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
+ map(0xffffd6, 0xffffd7).rw(m_timer16c[0], FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
+ map(0xffffd8, 0xffffdf).rw(m_timer16c[0], FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
+ map(0xffffe0, 0xffffe0).rw(m_timer16c[1], FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
+ map(0xffffe1, 0xffffe1).rw(m_timer16c[1], FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
+ map(0xffffe2, 0xffffe2).rw(m_timer16c[1], FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
+ map(0xffffe4, 0xffffe4).rw(m_timer16c[1], FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
+ map(0xffffe5, 0xffffe5).rw(m_timer16c[1], FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
+ map(0xffffe6, 0xffffe7).rw(m_timer16c[1], FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
+ map(0xffffe8, 0xffffeb).rw(m_timer16c[1], FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
+ map(0xfffff0, 0xfffff0).rw(m_timer16c[2], FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
+ map(0xfffff1, 0xfffff1).rw(m_timer16c[2], FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
+ map(0xfffff2, 0xfffff2).rw(m_timer16c[2], FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
+ map(0xfffff4, 0xfffff4).rw(m_timer16c[2], FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
+ map(0xfffff5, 0xfffff5).rw(m_timer16c[2], FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
+ map(0xfffff6, 0xfffff7).rw(m_timer16c[2], FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
+ map(0xfffff8, 0xfffffb).rw(m_timer16c[2], FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
+}
+
+void h8s2319_device::device_add_mconfig(machine_config &config)
+{
+ H8S_INTC(config, m_intc, *this);
+ H8_ADC_2319(config, m_adc, *this, m_intc, 28);
+ H8_DTC(config, m_dtc, *this, m_intc, 24);
+ H8_PORT(config, m_portn[0], *this, h8_device::PORT_1, 0x00, 0x00);
+ H8_PORT(config, m_portn[1], *this, h8_device::PORT_2, 0x00, 0x00);
+ H8_PORT(config, m_portn[2], *this, h8_device::PORT_3, 0x00, 0xc0);
+ H8_PORT(config, m_portn[3], *this, h8_device::PORT_4, 0x00, 0x00);
+ H8_PORT(config, m_porta[0], *this, h8_device::PORT_A, 0x00, 0xf0);
+ H8_PORT(config, m_porta[1], *this, h8_device::PORT_B, 0x00, 0x00);
+ H8_PORT(config, m_porta[2], *this, h8_device::PORT_C, 0x00, 0x00);
+ H8_PORT(config, m_porta[3], *this, h8_device::PORT_D, 0x00, 0x00);
+ H8_PORT(config, m_porta[4], *this, h8_device::PORT_E, 0x00, 0x00);
+ H8_PORT(config, m_porta[5], *this, h8_device::PORT_F, 0x00, 0x00);
+ H8_PORT(config, m_porta[6], *this, h8_device::PORT_G, 0x00, 0xe0);
+ H8H_TIMER8_CHANNEL(config, m_timer8[0], *this, m_intc, 64, 65, 66, m_timer8[1], h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
+ H8H_TIMER8_CHANNEL(config, m_timer8[1], *this, m_intc, 68, 69, 70, m_timer8[0], h8_timer8_channel_device::CHAIN_A, false, false);
+ H8_TIMER16(config, m_timer16, *this, 6, 0x00);
+ H8S_TIMER16_CHANNEL(config, m_timer16c[0], *this, 4, 0x60, m_intc, 32,
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::INPUT_D);
+ H8S_TIMER16_CHANNEL(config, m_timer16c[1], *this, 2, 0x4c, m_intc, 40,
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::CHAIN).set_chain(m_timer16c[2]);
+ H8S_TIMER16_CHANNEL(config, m_timer16c[2], *this, 2, 0x4c, m_intc, 44,
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_1024);
+ H8S_TIMER16_CHANNEL(config, m_timer16c[3], *this, 4, 0x60, m_intc, 48,
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::DIV_1024,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::DIV_4096);
+ H8S_TIMER16_CHANNEL(config, m_timer16c[4], *this, 2, 0x4c, m_intc, 56,
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_1024,
+ h8_timer16_channel_device::CHAIN).set_chain(m_timer16c[5]);
+ H8S_TIMER16_CHANNEL(config, m_timer16c[5], *this, 2, 0x4c, m_intc, 60,
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::INPUT_D);
+ H8_SCI(config, m_sci[0], 0, *this, m_intc, 80, 81, 82, 83);
+ H8_SCI(config, m_sci[1], 1, *this, m_intc, 84, 85, 86, 87);
+ H8_WATCHDOG(config, m_watchdog, *this, m_intc, 25, h8_watchdog_device::S);
+}
+
+void h8s2319_device::execute_set_input(int inputnum, int state)
+{
+ m_intc->set_input(inputnum, state);
+}
+
+bool h8s2319_device::exr_in_stack() const
+{
+ return m_syscr & 0x20;
+}
+
+int h8s2319_device::trace_setup()
+{
+ m_CCR |= F_I;
+ m_EXR &= ~EXR_T;
+ return 5;
+}
+
+int h8s2319_device::trapa_setup()
+{
+ m_CCR |= F_I;
+ if(m_syscr & 0x20)
+ m_EXR &= ~EXR_T;
+ return 8;
+}
+
+void h8s2319_device::irq_setup()
+{
+ switch(m_syscr & 0x30) {
+ case 0x00:
+ m_CCR |= F_I;
+ break;
+ case 0x20:
+ m_EXR = m_EXR & (EXR_NC);
+ if(m_taken_irq_level == 8)
+ m_EXR |= 7;
+ else
+ m_EXR |= m_taken_irq_level;
+ break;
+ }
+}
+
+void h8s2319_device::update_irq_filter()
+{
+ switch(m_syscr & 0x30) {
+ case 0x00:
+ if(m_CCR & F_I)
+ m_intc->set_filter(2, -1);
+ else
+ m_intc->set_filter(0, -1);
+ break;
+ case 0x20:
+ m_intc->set_filter(0, m_EXR & 7);
+ break;
+ }
+}
+
+void h8s2319_device::interrupt_taken()
+{
+ standard_irq_callback(m_intc->interrupt_taken(m_taken_irq_vector), m_NPC);
+}
+
+void h8s2319_device::internal_update(u64 current_time)
+{
+ u64 event_time = 0;
+
+ add_event(event_time, m_adc->internal_update(current_time));
+ add_event(event_time, m_sci[0]->internal_update(current_time));
+ add_event(event_time, m_sci[1]->internal_update(current_time));
+
+ // SCI2 used by H8S-2329
+ if (m_sci[2])
+ add_event(event_time, m_sci[2]->internal_update(current_time));
+
+ add_event(event_time, m_timer8[0]->internal_update(current_time));
+ add_event(event_time, m_timer8[1]->internal_update(current_time));
+ add_event(event_time, m_timer16c[0]->internal_update(current_time));
+ add_event(event_time, m_timer16c[1]->internal_update(current_time));
+ add_event(event_time, m_timer16c[2]->internal_update(current_time));
+ add_event(event_time, m_timer16c[3]->internal_update(current_time));
+ add_event(event_time, m_timer16c[4]->internal_update(current_time));
+ add_event(event_time, m_timer16c[5]->internal_update(current_time));
+ add_event(event_time, m_watchdog->internal_update(current_time));
+
+ recompute_bcount(event_time);
+}
+
+void h8s2319_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_timer8[0]->notify_standby(state);
+ m_timer8[1]->notify_standby(state);
+
+ for (auto & timer16c : m_timer16c)
+ timer16c->notify_standby(state);
+
+ m_watchdog->notify_standby(state);
+}
+
+void h8s2319_device::device_start()
+{
+ h8s2000_device::device_start();
+ m_dtc_device = m_dtc;
+
+ m_sbycr = 0;
+ m_syscr = 0;
+
+ save_item(NAME(m_sbycr));
+ save_item(NAME(m_syscr));
+}
+
+void h8s2319_device::device_reset()
+{
+ h8s2000_device::device_reset();
+
+ m_sbycr = 0x08;
+ m_syscr = 0x01;
+ m_ram_view.select(0);
+}
+
+u8 h8s2319_device::sbycr_r()
+{
+ return m_sbycr;
+}
+
+void h8s2319_device::sbycr_w(u8 data)
+{
+ logerror("sbycr = %02x\n", data);
+
+ // SSBY
+ m_standby_pending = bool(data & 0x80);
+
+ m_sbycr = data & 0xf9;
+}
+
+u8 h8s2319_device::syscr_r()
+{
+ return m_syscr;
+}
+
+void h8s2319_device::syscr_w(u8 data)
+{
+ logerror("syscr = %02x\n", data);
+
+ // RAME
+ if (data & 1)
+ m_ram_view.select(0);
+ else
+ m_ram_view.disable();
+
+ // NMIEG
+ m_intc->set_nmi_edge(BIT(data, 3));
+
+ m_syscr = data;
+ update_irq_filter();
+}
diff --git a/src/devices/cpu/h8/h8s2319.h b/src/devices/cpu/h8/h8s2319.h
new file mode 100644
index 0000000000000..a782d03d33bab
--- /dev/null
+++ b/src/devices/cpu/h8/h8s2319.h
@@ -0,0 +1,158 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, hap
+/***************************************************************************
+
+ h8s2319.h
+
+ H8S-2319 family emulation
+
+ H8S/2000-based mcus.
+
+ Variant ROM RAM
+ H8S/2310 - 2K
+ H8S/2311 32K 2K
+ H8S/2312 - 8K
+ H8S/2313 64K 2K
+ H8S/2315 384K 8K
+ H8S/2316 64K 8K
+ H8S/2317 128K 8K
+ H8S/2318 256K 8K
+ H8S/2319 512K 8K
+
+***************************************************************************/
+
+#ifndef MAME_CPU_H8_H8S2319_H
+#define MAME_CPU_H8_H8S2319_H
+
+#pragma once
+
+#include "h8s2000.h"
+#include "h8_intc.h"
+#include "h8_adc.h"
+#include "h8_dtc.h"
+#include "h8_port.h"
+#include "h8_timer8.h"
+#include "h8_timer16.h"
+#include "h8_sci.h"
+#include "h8_watchdog.h"
+
+class h8s2319_device : public h8s2000_device {
+public:
+ h8s2319_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // I/O ports
+ auto read_port1() { return m_read_port [PORT_1].bind(); }
+ auto write_port1() { return m_write_port[PORT_1].bind(); }
+ auto read_port2() { return m_read_port [PORT_2].bind(); }
+ auto write_port2() { return m_write_port[PORT_2].bind(); }
+ auto read_port3() { return m_read_port [PORT_3].bind(); }
+ auto write_port3() { return m_write_port[PORT_3].bind(); }
+ auto read_port4() { return m_read_port [PORT_4].bind(); }
+
+ auto read_porta() { return m_read_port [PORT_A].bind(); }
+ auto write_porta() { return m_write_port[PORT_A].bind(); }
+ auto read_portb() { return m_read_port [PORT_B].bind(); }
+ auto write_portb() { return m_write_port[PORT_B].bind(); }
+ auto read_portc() { return m_read_port [PORT_C].bind(); }
+ auto write_portc() { return m_write_port[PORT_C].bind(); }
+ auto read_portd() { return m_read_port [PORT_D].bind(); }
+ auto write_portd() { return m_write_port[PORT_D].bind(); }
+ auto read_porte() { return m_read_port [PORT_E].bind(); }
+ auto write_porte() { return m_write_port[PORT_E].bind(); }
+ auto read_portf() { return m_read_port [PORT_F].bind(); }
+ auto write_portf() { return m_write_port[PORT_F].bind(); }
+ auto read_portg() { return m_read_port [PORT_G].bind(); }
+ auto write_portg() { return m_write_port[PORT_G].bind(); }
+
+ u8 sbycr_r();
+ void sbycr_w(u8 data);
+ u8 syscr_r();
+ void syscr_w(u8 data);
+
+protected:
+ required_device m_intc;
+ required_device m_adc;
+ required_device m_dtc;
+ required_device_array m_portn;
+ required_device_array m_porta;
+ required_device_array m_timer8;
+ required_device m_timer16;
+ required_device_array m_timer16c;
+ required_device m_watchdog;
+
+ memory_view m_ram_view;
+
+ u32 m_ram_start;
+ u8 m_sbycr;
+ u8 m_syscr;
+
+ h8s2319_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map_delegate, u32 start);
+ h8s2319_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start);
+
+ virtual bool exr_in_stack() const override;
+ virtual void update_irq_filter() override;
+ virtual void interrupt_taken() override;
+ virtual int trace_setup() override;
+ virtual int trapa_setup() override;
+ virtual void irq_setup() override;
+ virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ void map(address_map &map);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void execute_set_input(int inputnum, int state) override;
+};
+
+class h8s2310_device : public h8s2319_device {
+public:
+ h8s2310_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2311_device : public h8s2319_device {
+public:
+ h8s2311_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2312_device : public h8s2319_device {
+public:
+ h8s2312_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2313_device : public h8s2319_device {
+public:
+ h8s2313_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2315_device : public h8s2319_device {
+public:
+ h8s2315_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2316_device : public h8s2319_device {
+public:
+ h8s2316_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2317_device : public h8s2319_device {
+public:
+ h8s2317_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2318_device : public h8s2319_device {
+public:
+ h8s2318_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+DECLARE_DEVICE_TYPE(H8S2310, h8s2310_device)
+DECLARE_DEVICE_TYPE(H8S2311, h8s2311_device)
+DECLARE_DEVICE_TYPE(H8S2312, h8s2312_device)
+DECLARE_DEVICE_TYPE(H8S2313, h8s2313_device)
+DECLARE_DEVICE_TYPE(H8S2315, h8s2315_device)
+DECLARE_DEVICE_TYPE(H8S2316, h8s2316_device)
+DECLARE_DEVICE_TYPE(H8S2317, h8s2317_device)
+DECLARE_DEVICE_TYPE(H8S2318, h8s2318_device)
+DECLARE_DEVICE_TYPE(H8S2319, h8s2319_device)
+
+#endif // MAME_CPU_H8_H8S2319_H
diff --git a/src/devices/cpu/h8/h8s2320.cpp b/src/devices/cpu/h8/h8s2320.cpp
deleted file mode 100644
index b853310a79ebf..0000000000000
--- a/src/devices/cpu/h8/h8s2320.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert
-#include "emu.h"
-#include "h8s2320.h"
-
-DEFINE_DEVICE_TYPE(H8S2320, h8s2320_device, "h8s2320", "Hitachi H8S/2320")
-DEFINE_DEVICE_TYPE(H8S2321, h8s2321_device, "h8s2321", "Hitachi H8S/2321")
-DEFINE_DEVICE_TYPE(H8S2322, h8s2322_device, "h8s2322", "Hitachi H8S/2322")
-DEFINE_DEVICE_TYPE(H8S2323, h8s2323_device, "h8s2323", "Hitachi H8S/2323")
-DEFINE_DEVICE_TYPE(H8S2324, h8s2324_device, "h8s2324", "Hitachi H8S/2324")
-DEFINE_DEVICE_TYPE(H8S2326, h8s2326_device, "h8s2326", "Hitachi H8S/2326")
-DEFINE_DEVICE_TYPE(H8S2327, h8s2327_device, "h8s2327", "Hitachi H8S/2327")
-DEFINE_DEVICE_TYPE(H8S2328, h8s2328_device, "h8s2328", "Hitachi H8S/2328")
-DEFINE_DEVICE_TYPE(H8S2329, h8s2329_device, "h8s2329", "Hitachi H8S/2329")
-
-
-h8s2320_device::h8s2320_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start) :
- h8s2000_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h8s2320_device::map), this)),
- m_intc(*this, "intc"),
- m_adc(*this, "adc"),
- m_dma(*this, "dma"),
- m_dma0(*this, "dma:0"),
- m_dma1(*this, "dma:1"),
- m_dtc(*this, "dtc"),
- m_port1(*this, "port1"),
- m_port2(*this, "port2"),
- m_port3(*this, "port3"),
- m_port4(*this, "port4"),
- m_port5(*this, "port5"),
- m_port6(*this, "port6"),
- m_porta(*this, "porta"),
- m_portb(*this, "portb"),
- m_portc(*this, "portc"),
- m_portd(*this, "portd"),
- m_porte(*this, "porte"),
- m_portf(*this, "portf"),
- m_portg(*this, "portg"),
- m_timer8_0(*this, "timer8_0"),
- m_timer8_1(*this, "timer8_1"),
- m_timer16(*this, "timer16"),
- m_timer16_0(*this, "timer16:0"),
- m_timer16_1(*this, "timer16:1"),
- m_timer16_2(*this, "timer16:2"),
- m_timer16_3(*this, "timer16:3"),
- m_timer16_4(*this, "timer16:4"),
- m_timer16_5(*this, "timer16:5"),
- m_watchdog(*this, "watchdog"),
- m_tend_cb(*this),
- m_ram_start(start),
- m_syscr(0)
-{
-}
-
-h8s2320_device::h8s2320_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2320, tag, owner, clock, 0xffec00)
-{
-}
-
-h8s2321_device::h8s2321_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2321, tag, owner, clock, 0xffec00)
-{
-}
-
-h8s2322_device::h8s2322_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2322, tag, owner, clock, 0xffdc00)
-{
-}
-
-h8s2323_device::h8s2323_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2323, tag, owner, clock, 0xffdc00)
-{
-}
-
-h8s2324_device::h8s2324_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2324, tag, owner, clock, 0xff7c00)
-{
-}
-
-h8s2326_device::h8s2326_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2326, tag, owner, clock, 0xffdc00)
-{
-}
-
-h8s2327_device::h8s2327_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2327, tag, owner, clock, 0xffdc00)
-{
-}
-
-h8s2328_device::h8s2328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2328, tag, owner, clock, 0xffdc00)
-{
-}
-
-h8s2329_device::h8s2329_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
- h8s2320_device(mconfig, H8S2329, tag, owner, clock, 0xff7c00)
-{
-}
-
-void h8s2320_device::map(address_map &map)
-{
- map(m_ram_start, 0xfffbff).ram();
-
- map(0xfffe80, 0xfffe80).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
- map(0xfffe81, 0xfffe81).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
- map(0xfffe82, 0xfffe83).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
- map(0xfffe84, 0xfffe84).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
- map(0xfffe85, 0xfffe85).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
- map(0xfffe86, 0xfffe87).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
- map(0xfffe88, 0xfffe8f).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
- map(0xfffe90, 0xfffe90).rw(m_timer16_4, FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
- map(0xfffe91, 0xfffe91).rw(m_timer16_4, FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
- map(0xfffe92, 0xfffe92).rw(m_timer16_4, FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
- map(0xfffe94, 0xfffe94).rw(m_timer16_4, FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
- map(0xfffe95, 0xfffe95).rw(m_timer16_4, FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
- map(0xfffe96, 0xfffe97).rw(m_timer16_4, FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
- map(0xfffe98, 0xfffe9b).rw(m_timer16_4, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
- map(0xfffea0, 0xfffea0).rw(m_timer16_5, FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
- map(0xfffea1, 0xfffea1).rw(m_timer16_5, FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
- map(0xfffea2, 0xfffea2).rw(m_timer16_5, FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
- map(0xfffea4, 0xfffea4).rw(m_timer16_5, FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
- map(0xfffea5, 0xfffea5).rw(m_timer16_5, FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
- map(0xfffea6, 0xfffea7).rw(m_timer16_5, FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
- map(0xfffea8, 0xfffeab).rw(m_timer16_5, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
- map(0xfffeb0, 0xfffeb0).w(m_port1, FUNC(h8_port_device::ddr_w));
- map(0xfffeb1, 0xfffeb1).w(m_port2, FUNC(h8_port_device::ddr_w));
- map(0xfffeb2, 0xfffeb2).w(m_port3, FUNC(h8_port_device::ddr_w));
- map(0xfffeb4, 0xfffeb4).w(m_port5, FUNC(h8_port_device::ddr_w));
- map(0xfffeb5, 0xfffeb5).w(m_port6, FUNC(h8_port_device::ddr_w));
- map(0xfffeb9, 0xfffeb9).w(m_porta, FUNC(h8_port_device::ddr_w));
- map(0xfffeba, 0xfffeba).w(m_portb, FUNC(h8_port_device::ddr_w));
- map(0xfffebb, 0xfffebb).w(m_portc, FUNC(h8_port_device::ddr_w));
- map(0xfffebc, 0xfffebc).w(m_portd, FUNC(h8_port_device::ddr_w));
- map(0xfffebd, 0xfffebd).w(m_porte, FUNC(h8_port_device::ddr_w));
- map(0xfffebe, 0xfffebe).w(m_portf, FUNC(h8_port_device::ddr_w));
- map(0xfffebf, 0xfffebf).w(m_portg, FUNC(h8_port_device::ddr_w));
- map(0xfffec0, 0xfffec1).rw(m_intc, FUNC(h8s_intc_device::icr_r), FUNC(h8s_intc_device::icr_w));
- map(0xfffec2, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icrc_r), FUNC(h8s_intc_device::icrc_w));
- map(0xfffec4, 0xfffecd).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
- map(0xfffece, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::iprk_r), FUNC(h8s_intc_device::iprk_w));
-
- if(type() != H8S2321) {
- map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w));
- map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w));
- map(0xfffee4, 0xfffee5).rw(m_dma0, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w));
- map(0xfffee6, 0xfffee7).rw(m_dma0, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w));
- map(0xfffee8, 0xfffee9).rw(m_dma0, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w));
- map(0xfffeea, 0xfffeeb).rw(m_dma0, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w));
- map(0xfffeec, 0xfffeed).rw(m_dma0, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w));
- map(0xfffeee, 0xfffeef).rw(m_dma0, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w));
- map(0xfffef0, 0xfffef1).rw(m_dma1, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w));
- map(0xfffef2, 0xfffef3).rw(m_dma1, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w));
- map(0xfffef4, 0xfffef5).rw(m_dma1, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w));
- map(0xfffef6, 0xfffef7).rw(m_dma1, FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w));
- map(0xfffef8, 0xfffef9).rw(m_dma1, FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w));
- map(0xfffefa, 0xfffefb).rw(m_dma1, FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w));
- map(0xfffefc, 0xfffefd).rw(m_dma1, FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w));
- map(0xfffefe, 0xfffeff).rw(m_dma1, FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w));
- map(0xffff00, 0xffff00).rw(m_dma, FUNC(h8s_dma_device::dmawer_r), FUNC(h8s_dma_device::dmawer_w));
- map(0xffff01, 0xffff01).rw(m_dma, FUNC(h8s_dma_device::dmatcr_r), FUNC(h8s_dma_device::dmatcr_w));
- map(0xffff02, 0xffff03).rw(m_dma0, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w));
- map(0xffff04, 0xffff05).rw(m_dma1, FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w));
- map(0xffff06, 0xffff07).rw(m_dma, FUNC(h8s_dma_device::dmabcr_r), FUNC(h8s_dma_device::dmabcr_w));
- }
- map(0xffff2c, 0xffff2c).rw(m_intc, FUNC(h8s_intc_device::iscrh_r), FUNC(h8s_intc_device::iscrh_w));
- map(0xffff2d, 0xffff2d).rw(m_intc, FUNC(h8s_intc_device::iscrl_r), FUNC(h8s_intc_device::iscrl_w));
- map(0xffff2e, 0xffff2e).rw(m_intc, FUNC(h8s_intc_device::ier_r), FUNC(h8s_intc_device::ier_w));
- map(0xffff2f, 0xffff2f).rw(m_intc, FUNC(h8s_intc_device::isr_r), FUNC(h8s_intc_device::isr_w));
- map(0xffff30, 0xffff35).rw(m_dtc, FUNC(h8_dtc_device::dtcer_r), FUNC(h8_dtc_device::dtcer_w));
- map(0xffff37, 0xffff37).rw(m_dtc, FUNC(h8_dtc_device::dtvecr_r), FUNC(h8_dtc_device::dtvecr_w));
- map(0xffff39, 0xffff39).rw(FUNC(h8s2320_device::syscr_r), FUNC(h8s2320_device::syscr_w));
-
- map(0xffff50, 0xffff50).r(m_port1, FUNC(h8_port_device::port_r));
- map(0xffff51, 0xffff51).r(m_port2, FUNC(h8_port_device::port_r));
- map(0xffff52, 0xffff52).r(m_port3, FUNC(h8_port_device::port_r));
- map(0xffff53, 0xffff53).r(m_port4, FUNC(h8_port_device::port_r));
- map(0xffff54, 0xffff54).r(m_port5, FUNC(h8_port_device::port_r));
- map(0xffff55, 0xffff55).r(m_port6, FUNC(h8_port_device::port_r));
- map(0xffff59, 0xffff59).r(m_porta, FUNC(h8_port_device::port_r));
- map(0xffff5a, 0xffff5a).r(m_portb, FUNC(h8_port_device::port_r));
- map(0xffff5b, 0xffff5b).r(m_portc, FUNC(h8_port_device::port_r));
- map(0xffff5c, 0xffff5c).r(m_portd, FUNC(h8_port_device::port_r));
- map(0xffff5d, 0xffff5d).r(m_porte, FUNC(h8_port_device::port_r));
- map(0xffff5e, 0xffff5e).r(m_portf, FUNC(h8_port_device::port_r));
- map(0xffff5f, 0xffff5f).r(m_portg, FUNC(h8_port_device::port_r));
- map(0xffff60, 0xffff60).rw(m_port1, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff61, 0xffff61).rw(m_port2, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff62, 0xffff62).rw(m_port3, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff64, 0xffff64).rw(m_port5, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff65, 0xffff65).rw(m_port6, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff69, 0xffff69).rw(m_porta, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff6a, 0xffff6a).rw(m_portb, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff6b, 0xffff6b).rw(m_portc, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff6c, 0xffff6c).rw(m_portd, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff6d, 0xffff6d).rw(m_porte, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff6e, 0xffff6e).rw(m_portf, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff6f, 0xffff6f).rw(m_portg, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
- map(0xffff70, 0xffff70).rw(m_porta, FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
- map(0xffff71, 0xffff71).rw(m_portb, FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
- map(0xffff72, 0xffff72).rw(m_portc, FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
- map(0xffff73, 0xffff73).rw(m_portd, FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
- map(0xffff74, 0xffff74).rw(m_porte, FUNC(h8_port_device::pcr_r), FUNC(h8_port_device::pcr_w));
- map(0xffff76, 0xffff76).rw(m_port3, FUNC(h8_port_device::odr_r), FUNC(h8_port_device::odr_w));
- map(0xffff77, 0xffff77).rw(m_porta, FUNC(h8_port_device::odr_r), FUNC(h8_port_device::odr_w));
- map(0xffff78, 0xffff78).rw(m_sci[0], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
- map(0xffff79, 0xffff79).rw(m_sci[0], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
- map(0xffff7a, 0xffff7a).rw(m_sci[0], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
- map(0xffff7b, 0xffff7b).rw(m_sci[0], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
- map(0xffff7c, 0xffff7c).rw(m_sci[0], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
- map(0xffff7d, 0xffff7d).r(m_sci[0], FUNC(h8_sci_device::rdr_r));
- map(0xffff7e, 0xffff7e).rw(m_sci[0], FUNC(h8_sci_device::scmr_r), FUNC(h8_sci_device::scmr_w));
- map(0xffff80, 0xffff80).rw(m_sci[1], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
- map(0xffff81, 0xffff81).rw(m_sci[1], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
- map(0xffff82, 0xffff82).rw(m_sci[1], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
- map(0xffff83, 0xffff83).rw(m_sci[1], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
- map(0xffff84, 0xffff84).rw(m_sci[1], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
- map(0xffff85, 0xffff85).r(m_sci[1], FUNC(h8_sci_device::rdr_r));
- map(0xffff86, 0xffff86).rw(m_sci[1], FUNC(h8_sci_device::scmr_r), FUNC(h8_sci_device::scmr_w));
- map(0xffff88, 0xffff88).rw(m_sci[2], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
- map(0xffff89, 0xffff89).rw(m_sci[2], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
- map(0xffff8a, 0xffff8a).rw(m_sci[2], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
- map(0xffff8b, 0xffff8b).rw(m_sci[2], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
- map(0xffff8c, 0xffff8c).rw(m_sci[2], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
- map(0xffff8d, 0xffff8d).r(m_sci[2], FUNC(h8_sci_device::rdr_r));
- map(0xffff8e, 0xffff8e).rw(m_sci[2], FUNC(h8_sci_device::scmr_r), FUNC(h8_sci_device::scmr_w));
- map(0xffff90, 0xffff97).r(m_adc, FUNC(h8_adc_device::addr8_r));
- map(0xffff98, 0xffff98).rw(m_adc, FUNC(h8_adc_device::adcsr_r), FUNC(h8_adc_device::adcsr_w));
- map(0xffff99, 0xffff99).rw(m_adc, FUNC(h8_adc_device::adcr_r), FUNC(h8_adc_device::adcr_w));
-
- map(0xffffb0, 0xffffb0).rw(m_timer8_0, FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
- map(0xffffb1, 0xffffb1).rw(m_timer8_1, FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
- map(0xffffb2, 0xffffb2).rw(m_timer8_0, FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
- map(0xffffb3, 0xffffb3).rw(m_timer8_1, FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
- map(0xffffb4, 0xffffb7).rw(m_timer8_0, FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w)).umask16(0xff00);
- map(0xffffb4, 0xffffb7).rw(m_timer8_1, FUNC(h8_timer8_channel_device::tcor_r), FUNC(h8_timer8_channel_device::tcor_w)).umask16(0x00ff);
- map(0xffffb8, 0xffffb8).rw(m_timer8_0, FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
- map(0xffffb9, 0xffffb9).rw(m_timer8_1, FUNC(h8_timer8_channel_device::tcnt_r), FUNC(h8_timer8_channel_device::tcnt_w));
- map(0xffffbc, 0xffffbd).rw(m_watchdog, FUNC(h8_watchdog_device::wd_r), FUNC(h8_watchdog_device::wd_w));
- map(0xffffbe, 0xffffbf).rw(m_watchdog, FUNC(h8_watchdog_device::rst_r), FUNC(h8_watchdog_device::rst_w));
- map(0xffffc0, 0xffffc0).rw(m_timer16, FUNC(h8_timer16_device::tstr_r), FUNC(h8_timer16_device::tstr_w));
- map(0xffffc1, 0xffffc1).rw(m_timer16, FUNC(h8_timer16_device::tsyr_r), FUNC(h8_timer16_device::tsyr_w));
-
- map(0xffffd0, 0xffffd0).rw(m_timer16_0, FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
- map(0xffffd1, 0xffffd1).rw(m_timer16_0, FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
- map(0xffffd2, 0xffffd3).rw(m_timer16_0, FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
- map(0xffffd4, 0xffffd4).rw(m_timer16_0, FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
- map(0xffffd5, 0xffffd5).rw(m_timer16_0, FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
- map(0xffffd6, 0xffffd7).rw(m_timer16_0, FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
- map(0xffffd8, 0xffffdf).rw(m_timer16_0, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
- map(0xffffe0, 0xffffe0).rw(m_timer16_1, FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
- map(0xffffe1, 0xffffe1).rw(m_timer16_1, FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
- map(0xffffe2, 0xffffe2).rw(m_timer16_1, FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
- map(0xffffe4, 0xffffe4).rw(m_timer16_1, FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
- map(0xffffe5, 0xffffe5).rw(m_timer16_1, FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
- map(0xffffe6, 0xffffe7).rw(m_timer16_1, FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
- map(0xffffe8, 0xffffeb).rw(m_timer16_1, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
- map(0xfffff0, 0xfffff0).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
- map(0xfffff1, 0xfffff1).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
- map(0xfffff2, 0xfffff2).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
- map(0xfffff4, 0xfffff4).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tier_r), FUNC(h8_timer16_channel_device::tier_w));
- map(0xfffff5, 0xfffff5).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
- map(0xfffff6, 0xfffff7).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
- map(0xfffff8, 0xfffffb).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
-}
-
-void h8s2320_device::device_add_mconfig(machine_config &config)
-{
- H8S_INTC(config, m_intc, *this);
- H8_ADC_2320(config, m_adc, *this, m_intc, 28);
- if(type() != H8S2321) {
- H8S_DMA(config, m_dma, *this);
- H8S_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc);
- H8S_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc);
- }
- H8_DTC(config, m_dtc, *this, m_intc, 24);
- H8_PORT(config, m_port1, *this, h8_device::PORT_1, 0x00, 0x00);
- H8_PORT(config, m_port2, *this, h8_device::PORT_2, 0x00, 0x00);
- H8_PORT(config, m_port3, *this, h8_device::PORT_3, 0xc0, 0xc0);
- H8_PORT(config, m_port4, *this, h8_device::PORT_4, 0x00, 0x00);
- H8_PORT(config, m_port5, *this, h8_device::PORT_5, 0xf0, 0xf0);
- H8_PORT(config, m_port6, *this, h8_device::PORT_6, 0x00, 0x00);
- H8_PORT(config, m_porta, *this, h8_device::PORT_A, 0x00, 0x00);
- H8_PORT(config, m_portb, *this, h8_device::PORT_B, 0x00, 0x00);
- H8_PORT(config, m_portc, *this, h8_device::PORT_C, 0x00, 0x00);
- H8_PORT(config, m_portd, *this, h8_device::PORT_D, 0x00, 0x00);
- H8_PORT(config, m_porte, *this, h8_device::PORT_E, 0x00, 0x00);
- H8_PORT(config, m_portf, *this, h8_device::PORT_F, 0x00, 0x00);
- H8_PORT(config, m_portg, *this, h8_device::PORT_G, 0xe0, 0xe0);
- H8H_TIMER8_CHANNEL(config, m_timer8_0, *this, m_intc, 64, 65, 66, m_timer8_1, h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
- H8H_TIMER8_CHANNEL(config, m_timer8_1, *this, m_intc, 68, 69, 70, m_timer8_0, h8_timer8_channel_device::CHAIN_A, false, false);
- H8_TIMER16(config, m_timer16, *this, 6, 0x00);
- H8S_TIMER16_CHANNEL(config, m_timer16_0, *this, 4, 0x60, m_intc, 32,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::INPUT_D);
- H8S_TIMER16_CHANNEL(config, m_timer16_1, *this, 2, 0x4c, m_intc, 40,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::CHAIN).set_chain(m_timer16_2);
- H8S_TIMER16_CHANNEL(config, m_timer16_2, *this, 2, 0x4c, m_intc, 44,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_1024);
- H8S_TIMER16_CHANNEL(config, m_timer16_3, *this, 4, 0x60, m_intc, 48,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::DIV_1024,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::DIV_4096);
- H8S_TIMER16_CHANNEL(config, m_timer16_4, *this, 2, 0x4c, m_intc, 56,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_1024,
- h8_timer16_channel_device::CHAIN).set_chain(m_timer16_5);
- H8S_TIMER16_CHANNEL(config, m_timer16_5, *this, 2, 0x4c, m_intc, 60,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::INPUT_D);
- H8_SCI(config, m_sci[0], 0, *this, m_intc, 80, 81, 82, 83);
- H8_SCI(config, m_sci[1], 1, *this, m_intc, 84, 85, 86, 87);
- H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
- H8_WATCHDOG(config, m_watchdog, *this, m_intc, 25, h8_watchdog_device::H);
-}
-
-void h8s2320_device::execute_set_input(int inputnum, int state)
-{
- if(inputnum == H8_INPUT_LINE_TEND0 || inputnum == H8_INPUT_LINE_TEND1)
- m_tend_cb[inputnum - H8_INPUT_LINE_TEND0](state);
- else if(inputnum == H8_INPUT_LINE_DREQ0 || inputnum == H8_INPUT_LINE_DREQ1)
- m_dma->set_input(inputnum, state);
- else
- m_intc->set_input(inputnum, state);
-}
-
-bool h8s2320_device::exr_in_stack() const
-{
- return m_syscr & 0x20;
-}
-
-int h8s2320_device::trace_setup()
-{
- m_CCR |= F_I;
- m_EXR &= ~EXR_T;
- return 5;
-}
-
-int h8s2320_device::trapa_setup()
-{
- m_CCR |= F_I;
- if(m_syscr & 0x20)
- m_EXR &= ~EXR_T;
- return 8;
-}
-
-void h8s2320_device::irq_setup()
-{
- switch(m_syscr & 0x30) {
- case 0x00:
- m_CCR |= F_I;
- break;
- case 0x20:
- m_EXR = m_EXR & (EXR_NC);
- if(m_taken_irq_level == 8)
- m_EXR |= 7;
- else
- m_EXR |= m_taken_irq_level;
- break;
- }
-}
-
-void h8s2320_device::update_irq_filter()
-{
- switch(m_syscr & 0x30) {
- case 0x00:
- if(m_CCR & F_I)
- m_intc->set_filter(2, -1);
- else
- m_intc->set_filter(0, -1);
- break;
- case 0x20:
- m_intc->set_filter(0, m_EXR & 7);
- break;
- }
-}
-
-void h8s2320_device::interrupt_taken()
-{
- standard_irq_callback(m_intc->interrupt_taken(m_taken_irq_vector), m_NPC);
-}
-
-void h8s2320_device::internal_update(u64 current_time)
-{
- u64 event_time = 0;
-
- add_event(event_time, m_adc->internal_update(current_time));
- add_event(event_time, m_sci[0]->internal_update(current_time));
- add_event(event_time, m_sci[1]->internal_update(current_time));
- add_event(event_time, m_sci[2]->internal_update(current_time));
- add_event(event_time, m_timer8_0->internal_update(current_time));
- add_event(event_time, m_timer8_1->internal_update(current_time));
- add_event(event_time, m_timer16_0->internal_update(current_time));
- add_event(event_time, m_timer16_1->internal_update(current_time));
- add_event(event_time, m_timer16_2->internal_update(current_time));
- add_event(event_time, m_timer16_3->internal_update(current_time));
- add_event(event_time, m_timer16_4->internal_update(current_time));
- add_event(event_time, m_timer16_5->internal_update(current_time));
- add_event(event_time, m_watchdog->internal_update(current_time));
-
- recompute_bcount(event_time);
-}
-
-void h8s2320_device::device_start()
-{
- h8s2000_device::device_start();
- m_dma_device = m_dma;
- m_dtc_device = m_dtc;
-
- save_item(NAME(m_syscr));
-}
-
-void h8s2320_device::device_reset()
-{
- h8s2000_device::device_reset();
- m_syscr = 0x01;
-}
-
-u8 h8s2320_device::syscr_r()
-{
- return m_syscr;
-}
-
-void h8s2320_device::syscr_w(u8 data)
-{
- m_syscr = data;
- m_mac_saturating = m_syscr & 0x80;
- update_irq_filter();
- logerror("syscr = %02x\n", data);
-}
diff --git a/src/devices/cpu/h8/h8s2320.h b/src/devices/cpu/h8/h8s2320.h
deleted file mode 100644
index 7caea73ae4fe2..0000000000000
--- a/src/devices/cpu/h8/h8s2320.h
+++ /dev/null
@@ -1,181 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert
-/***************************************************************************
-
- h8s2320.h
-
- H8S-2320 family emulation
-
- H8S/2600-based mcus.
-
- Variant ROM RAM
- H8S/2320 - 4K
- H8S/2321 - 4K
- H8S/2322 - 8K
- H8S/2323 32K 8K
- H8S/2324 - 32K
- H8S/2326 512K 8K
- H8S/2327 128K 8K
- H8S/2328 256K 8K
- H8S/2329 384K 32K
-
-
-
-***************************************************************************/
-
-#ifndef MAME_CPU_H8_H8S2320_H
-#define MAME_CPU_H8_H8S2320_H
-
-#pragma once
-
-#include "h8s2000.h"
-#include "h8_intc.h"
-#include "h8_adc.h"
-#include "h8_dma.h"
-#include "h8_dtc.h"
-#include "h8_port.h"
-#include "h8_timer8.h"
-#include "h8_timer16.h"
-#include "h8_sci.h"
-#include "h8_watchdog.h"
-
-class h8s2320_device : public h8s2000_device {
-public:
- h8s2320_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-
- auto read_port1() { return m_read_port [PORT_1].bind(); }
- auto write_port1() { return m_write_port[PORT_1].bind(); }
- auto read_port2() { return m_read_port [PORT_2].bind(); }
- auto write_port2() { return m_write_port[PORT_2].bind(); }
- auto read_port3() { return m_read_port [PORT_3].bind(); }
- auto write_port3() { return m_write_port[PORT_3].bind(); }
- auto read_port4() { return m_read_port [PORT_4].bind(); }
- auto read_port5() { return m_read_port [PORT_5].bind(); }
- auto write_port5() { return m_write_port[PORT_5].bind(); }
- auto read_port6() { return m_read_port [PORT_6].bind(); }
- auto write_port6() { return m_write_port[PORT_6].bind(); }
- auto read_porta() { return m_read_port [PORT_A].bind(); }
- auto write_porta() { return m_write_port[PORT_A].bind(); }
- auto read_portb() { return m_read_port [PORT_B].bind(); }
- auto write_portb() { return m_write_port[PORT_B].bind(); }
- auto read_portc() { return m_read_port [PORT_C].bind(); }
- auto write_portc() { return m_write_port[PORT_C].bind(); }
- auto read_portd() { return m_read_port [PORT_D].bind(); }
- auto write_portd() { return m_write_port[PORT_D].bind(); }
- auto read_porte() { return m_read_port [PORT_E].bind(); }
- auto write_porte() { return m_write_port[PORT_E].bind(); }
- auto read_portf() { return m_read_port [PORT_F].bind(); }
- auto write_portf() { return m_write_port[PORT_F].bind(); }
- auto read_portg() { return m_read_port [PORT_G].bind(); }
- auto write_portg() { return m_write_port[PORT_G].bind(); }
-
- auto tend0_cb() { return m_tend_cb[0].bind(); }
- auto tend1_cb() { return m_tend_cb[1].bind(); }
-
- u8 syscr_r();
- void syscr_w(u8 data);
-
-protected:
- required_device m_intc;
- required_device m_adc;
- optional_device m_dma;
- optional_device m_dma0;
- optional_device m_dma1;
- required_device m_dtc;
- required_device m_port1;
- required_device m_port2;
- required_device m_port3;
- required_device m_port4;
- required_device m_port5;
- required_device m_port6;
- required_device m_porta;
- required_device m_portb;
- required_device m_portc;
- required_device m_portd;
- required_device m_porte;
- required_device m_portf;
- required_device m_portg;
- required_device m_timer8_0;
- required_device m_timer8_1;
- required_device m_timer16;
- required_device m_timer16_0;
- required_device m_timer16_1;
- required_device m_timer16_2;
- required_device m_timer16_3;
- required_device m_timer16_4;
- required_device m_timer16_5;
- required_device m_watchdog;
-
- devcb_write_line::array<2> m_tend_cb;
-
- u32 m_ram_start;
- u8 m_syscr;
-
- h8s2320_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start);
-
- virtual bool exr_in_stack() const override;
- virtual void update_irq_filter() override;
- virtual void interrupt_taken() override;
- virtual int trace_setup() override;
- virtual int trapa_setup() override;
- virtual void irq_setup() override;
- virtual void internal_update(u64 current_time) override;
- virtual void device_add_mconfig(machine_config &config) override;
- void map(address_map &map);
-
- virtual void device_start() override;
- virtual void device_reset() override;
- virtual void execute_set_input(int inputnum, int state) override;
-};
-
-class h8s2321_device : public h8s2320_device {
-public:
- h8s2321_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-class h8s2322_device : public h8s2320_device {
-public:
- h8s2322_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-class h8s2323_device : public h8s2320_device {
-public:
- h8s2323_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-class h8s2324_device : public h8s2320_device {
-public:
- h8s2324_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-class h8s2326_device : public h8s2320_device {
-public:
- h8s2326_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-class h8s2327_device : public h8s2320_device {
-public:
- h8s2327_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-class h8s2328_device : public h8s2320_device {
-public:
- h8s2328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-class h8s2329_device : public h8s2320_device {
-public:
- h8s2329_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
-};
-
-DECLARE_DEVICE_TYPE(H8S2320, h8s2320_device)
-DECLARE_DEVICE_TYPE(H8S2321, h8s2321_device)
-DECLARE_DEVICE_TYPE(H8S2322, h8s2322_device)
-DECLARE_DEVICE_TYPE(H8S2323, h8s2323_device)
-DECLARE_DEVICE_TYPE(H8S2324, h8s2324_device)
-DECLARE_DEVICE_TYPE(H8S2326, h8s2326_device)
-DECLARE_DEVICE_TYPE(H8S2327, h8s2327_device)
-DECLARE_DEVICE_TYPE(H8S2328, h8s2328_device)
-DECLARE_DEVICE_TYPE(H8S2329, h8s2329_device)
-
-#endif // MAME_CPU_H8_H8S2320_H
diff --git a/src/devices/cpu/h8/h8s2329.cpp b/src/devices/cpu/h8/h8s2329.cpp
new file mode 100644
index 0000000000000..e7908131039ea
--- /dev/null
+++ b/src/devices/cpu/h8/h8s2329.cpp
@@ -0,0 +1,179 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ h8s2329.cpp
+
+ H8S-2329 family emulation
+ Subdevice of h8s2319.cpp
+
+***************************************************************************/
+
+#include "emu.h"
+#include "h8s2329.h"
+
+DEFINE_DEVICE_TYPE(H8S2320, h8s2320_device, "h8s2320", "Hitachi H8S/2320")
+DEFINE_DEVICE_TYPE(H8S2321, h8s2321_device, "h8s2321", "Hitachi H8S/2321")
+DEFINE_DEVICE_TYPE(H8S2322, h8s2322_device, "h8s2322", "Hitachi H8S/2322")
+DEFINE_DEVICE_TYPE(H8S2323, h8s2323_device, "h8s2323", "Hitachi H8S/2323")
+DEFINE_DEVICE_TYPE(H8S2324, h8s2324_device, "h8s2324", "Hitachi H8S/2324")
+DEFINE_DEVICE_TYPE(H8S2326, h8s2326_device, "h8s2326", "Hitachi H8S/2326")
+DEFINE_DEVICE_TYPE(H8S2327, h8s2327_device, "h8s2327", "Hitachi H8S/2327")
+DEFINE_DEVICE_TYPE(H8S2328, h8s2328_device, "h8s2328", "Hitachi H8S/2328")
+DEFINE_DEVICE_TYPE(H8S2329, h8s2329_device, "h8s2329", "Hitachi H8S/2329")
+
+
+h8s2321_device::h8s2321_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map_delegate, u32 start) :
+ h8s2319_device(mconfig, type, tag, owner, clock, map_delegate, start),
+ m_port5(*this, "port5"),
+ m_port6(*this, "port6")
+{
+}
+
+h8s2321_device::h8s2321_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2321_device(mconfig, H8S2321, tag, owner, clock, address_map_constructor(FUNC(h8s2321_device::map_2321), this), 0xffec00)
+{
+}
+
+
+h8s2320_device::h8s2320_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start) :
+ h8s2321_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(h8s2320_device::map_2320), this), start),
+ m_dma(*this, "dma"),
+ m_dmac(*this, "dma:%u", 0),
+ m_tend_cb(*this)
+{
+}
+
+h8s2320_device::h8s2320_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2320, tag, owner, clock, 0xffec00)
+{
+}
+
+
+h8s2322_device::h8s2322_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2322, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2323_device::h8s2323_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2323, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2324_device::h8s2324_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2324, tag, owner, clock, 0xff7c00)
+{
+}
+
+h8s2326_device::h8s2326_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2326, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2327_device::h8s2327_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2327, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2328_device::h8s2328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2328, tag, owner, clock, 0xffdc00)
+{
+}
+
+h8s2329_device::h8s2329_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ h8s2320_device(mconfig, H8S2329, tag, owner, clock, 0xff7c00)
+{
+}
+
+void h8s2321_device::map_2321(address_map &map)
+{
+ h8s2319_device::map(map);
+
+ map(0xfffeb4, 0xfffeb4).w(m_port5, FUNC(h8_port_device::ddr_w));
+ map(0xfffeb5, 0xfffeb5).w(m_port6, FUNC(h8_port_device::ddr_w));
+
+ map(0xffff30, 0xffff35).rw(m_dtc, FUNC(h8_dtc_device::dtcer_r), FUNC(h8_dtc_device::dtcer_w));
+
+ map(0xffff54, 0xffff54).r(m_port5, FUNC(h8_port_device::port_r));
+ map(0xffff55, 0xffff55).r(m_port6, FUNC(h8_port_device::port_r));
+ map(0xffff64, 0xffff64).rw(m_port5, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+ map(0xffff65, 0xffff65).rw(m_port6, FUNC(h8_port_device::dr_r), FUNC(h8_port_device::dr_w));
+
+ map(0xffff88, 0xffff88).rw(m_sci[2], FUNC(h8_sci_device::smr_r), FUNC(h8_sci_device::smr_w));
+ map(0xffff89, 0xffff89).rw(m_sci[2], FUNC(h8_sci_device::brr_r), FUNC(h8_sci_device::brr_w));
+ map(0xffff8a, 0xffff8a).rw(m_sci[2], FUNC(h8_sci_device::scr_r), FUNC(h8_sci_device::scr_w));
+ map(0xffff8b, 0xffff8b).rw(m_sci[2], FUNC(h8_sci_device::tdr_r), FUNC(h8_sci_device::tdr_w));
+ map(0xffff8c, 0xffff8c).rw(m_sci[2], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
+ map(0xffff8d, 0xffff8d).r(m_sci[2], FUNC(h8_sci_device::rdr_r));
+ map(0xffff8e, 0xffff8e).rw(m_sci[2], FUNC(h8_sci_device::scmr_r), FUNC(h8_sci_device::scmr_w));
+}
+
+void h8s2320_device::map_2320(address_map &map)
+{
+ map_2321(map);
+
+ map(0xfffee0, 0xfffee1).rw(m_dmac[0], FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w));
+ map(0xfffee2, 0xfffee3).rw(m_dmac[0], FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w));
+ map(0xfffee4, 0xfffee5).rw(m_dmac[0], FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w));
+ map(0xfffee6, 0xfffee7).rw(m_dmac[0], FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w));
+ map(0xfffee8, 0xfffee9).rw(m_dmac[0], FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w));
+ map(0xfffeea, 0xfffeeb).rw(m_dmac[0], FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w));
+ map(0xfffeec, 0xfffeed).rw(m_dmac[0], FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w));
+ map(0xfffeee, 0xfffeef).rw(m_dmac[0], FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w));
+ map(0xfffef0, 0xfffef1).rw(m_dmac[1], FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w));
+ map(0xfffef2, 0xfffef3).rw(m_dmac[1], FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w));
+ map(0xfffef4, 0xfffef5).rw(m_dmac[1], FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w));
+ map(0xfffef6, 0xfffef7).rw(m_dmac[1], FUNC(h8s_dma_channel_device::etcra_r), FUNC(h8s_dma_channel_device::etcra_w));
+ map(0xfffef8, 0xfffef9).rw(m_dmac[1], FUNC(h8s_dma_channel_device::marbh_r), FUNC(h8s_dma_channel_device::marbh_w));
+ map(0xfffefa, 0xfffefb).rw(m_dmac[1], FUNC(h8s_dma_channel_device::marbl_r), FUNC(h8s_dma_channel_device::marbl_w));
+ map(0xfffefc, 0xfffefd).rw(m_dmac[1], FUNC(h8s_dma_channel_device::ioarb_r), FUNC(h8s_dma_channel_device::ioarb_w));
+ map(0xfffefe, 0xfffeff).rw(m_dmac[1], FUNC(h8s_dma_channel_device::etcrb_r), FUNC(h8s_dma_channel_device::etcrb_w));
+ map(0xffff00, 0xffff00).rw(m_dma, FUNC(h8s_dma_device::dmawer_r), FUNC(h8s_dma_device::dmawer_w));
+ map(0xffff01, 0xffff01).rw(m_dma, FUNC(h8s_dma_device::dmatcr_r), FUNC(h8s_dma_device::dmatcr_w));
+ map(0xffff02, 0xffff03).rw(m_dmac[0], FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w));
+ map(0xffff04, 0xffff05).rw(m_dmac[1], FUNC(h8s_dma_channel_device::dmacr_r), FUNC(h8s_dma_channel_device::dmacr_w));
+ map(0xffff06, 0xffff07).rw(m_dma, FUNC(h8s_dma_device::dmabcr_r), FUNC(h8s_dma_device::dmabcr_w));
+}
+
+void h8s2321_device::notify_standby(int state)
+{
+ h8s2319_device::notify_standby(state);
+ m_sci[2]->notify_standby(state);
+}
+
+void h8s2321_device::device_add_mconfig(machine_config &config)
+{
+ h8s2319_device::device_add_mconfig(config);
+
+ H8_PORT(config, m_port5, *this, h8_device::PORT_5, 0x00, 0xf0);
+ H8_PORT(config, m_port6, *this, h8_device::PORT_6, 0x00, 0x00);
+ H8_PORT(config.replace(), m_porta[0], *this, h8_device::PORT_A, 0x00, 0x00);
+
+ H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
+}
+
+void h8s2320_device::device_add_mconfig(machine_config &config)
+{
+ h8s2321_device::device_add_mconfig(config);
+
+ H8S_DMA(config, m_dma, *this);
+ H8S_DMA_CHANNEL(config, m_dmac[0], *this, m_dma, m_intc);
+ H8S_DMA_CHANNEL(config, m_dmac[1], *this, m_dma, m_intc);
+}
+
+void h8s2320_device::execute_set_input(int inputnum, int state)
+{
+ // TEND and DREQ pins are not supported on H8S/2321
+ if(inputnum == H8_INPUT_LINE_TEND0 || inputnum == H8_INPUT_LINE_TEND1)
+ m_tend_cb[inputnum - H8_INPUT_LINE_TEND0](state);
+ else if(inputnum == H8_INPUT_LINE_DREQ0 || inputnum == H8_INPUT_LINE_DREQ1)
+ m_dma->set_input(inputnum, state);
+ else
+ h8s2319_device::execute_set_input(inputnum, state);
+}
+
+void h8s2320_device::device_start()
+{
+ h8s2319_device::device_start();
+ m_dma_device = m_dma;
+}
diff --git a/src/devices/cpu/h8/h8s2329.h b/src/devices/cpu/h8/h8s2329.h
new file mode 100644
index 0000000000000..fcee3b2b0078d
--- /dev/null
+++ b/src/devices/cpu/h8/h8s2329.h
@@ -0,0 +1,121 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ h8s2329.h
+
+ H8S-2329 family emulation
+ (compared to H8S-2319 family: adds DMA, 1 more SCI)
+
+ H8S/2000-based mcus.
+
+ Variant ROM RAM note
+ H8S/2320 - 4K
+ H8S/2321 - 4K no DMA
+ H8S/2322 - 8K
+ H8S/2323 32K 8K
+ H8S/2324 - 32K
+ H8S/2326 512K 8K
+ H8S/2327 128K 8K
+ H8S/2328 256K 8K
+ H8S/2329 384K 32K
+
+***************************************************************************/
+
+#ifndef MAME_CPU_H8_H8S2329_H
+#define MAME_CPU_H8_H8S2329_H
+
+#pragma once
+
+#include "h8s2319.h"
+#include "h8_dma.h"
+
+class h8s2321_device : public h8s2319_device {
+public:
+ h8s2321_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // see h8s2319.h for more
+ auto read_port5() { return m_read_port [PORT_5].bind(); }
+ auto write_port5() { return m_write_port[PORT_5].bind(); }
+ auto read_port6() { return m_read_port [PORT_6].bind(); }
+ auto write_port6() { return m_write_port[PORT_6].bind(); }
+
+protected:
+ h8s2321_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map_delegate, u32 start);
+
+ required_device m_port5;
+ required_device m_port6;
+
+ virtual void notify_standby(int state) override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ void map_2321(address_map &map);
+};
+
+class h8s2320_device : public h8s2321_device {
+public:
+ h8s2320_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ auto tend0_cb() { return m_tend_cb[0].bind(); }
+ auto tend1_cb() { return m_tend_cb[1].bind(); }
+
+protected:
+ required_device m_dma;
+ required_device_array m_dmac;
+
+ devcb_write_line::array<2> m_tend_cb;
+
+ h8s2320_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 start);
+
+ virtual void device_add_mconfig(machine_config &config) override;
+ void map_2320(address_map &map);
+
+ virtual void device_start() override;
+ virtual void execute_set_input(int inputnum, int state) override;
+};
+
+class h8s2322_device : public h8s2320_device {
+public:
+ h8s2322_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2323_device : public h8s2320_device {
+public:
+ h8s2323_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2324_device : public h8s2320_device {
+public:
+ h8s2324_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2326_device : public h8s2320_device {
+public:
+ h8s2326_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2327_device : public h8s2320_device {
+public:
+ h8s2327_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2328_device : public h8s2320_device {
+public:
+ h8s2328_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+class h8s2329_device : public h8s2320_device {
+public:
+ h8s2329_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+};
+
+DECLARE_DEVICE_TYPE(H8S2320, h8s2320_device)
+DECLARE_DEVICE_TYPE(H8S2321, h8s2321_device)
+DECLARE_DEVICE_TYPE(H8S2322, h8s2322_device)
+DECLARE_DEVICE_TYPE(H8S2323, h8s2323_device)
+DECLARE_DEVICE_TYPE(H8S2324, h8s2324_device)
+DECLARE_DEVICE_TYPE(H8S2326, h8s2326_device)
+DECLARE_DEVICE_TYPE(H8S2327, h8s2327_device)
+DECLARE_DEVICE_TYPE(H8S2328, h8s2328_device)
+DECLARE_DEVICE_TYPE(H8S2329, h8s2329_device)
+
+#endif // MAME_CPU_H8_H8S2329_H
diff --git a/src/devices/cpu/h8/h8s2357.cpp b/src/devices/cpu/h8/h8s2357.cpp
index b8378575c8409..1f0baa0e1d1ed 100644
--- a/src/devices/cpu/h8/h8s2357.cpp
+++ b/src/devices/cpu/h8/h8s2357.cpp
@@ -111,8 +111,7 @@ void h8s2357_device::map(address_map &map)
map(0xfffebd, 0xfffebd).w(m_porte, FUNC(h8_port_device::ddr_w));
map(0xfffebe, 0xfffebe).w(m_portf, FUNC(h8_port_device::ddr_w));
map(0xfffebf, 0xfffebf).w(m_portg, FUNC(h8_port_device::ddr_w));
- map(0xfffec4, 0xfffecd).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
- map(0xfffece, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::iprk_r), FUNC(h8s_intc_device::iprk_w));
+ map(0xfffec4, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w));
map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w));
map(0xfffee4, 0xfffee5).rw(m_dma0, FUNC(h8s_dma_channel_device::ioara_r), FUNC(h8s_dma_channel_device::ioara_w));
@@ -250,63 +249,63 @@ void h8s2357_device::device_add_mconfig(machine_config &config)
H8_PORT(config, m_porte, *this, h8_device::PORT_E, 0x00, 0x00);
H8_PORT(config, m_portf, *this, h8_device::PORT_F, 0x00, 0x00);
H8_PORT(config, m_portg, *this, h8_device::PORT_G, 0xe0, 0xe0);
- H8H_TIMER8_CHANNEL(config, m_timer8_0, *this, m_intc, 64, 65, 66, m_timer8_1, h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
- H8H_TIMER8_CHANNEL(config, m_timer8_1, *this, m_intc, 68, 69, 70, m_timer8_0, h8_timer8_channel_device::CHAIN_A, false, false);
+ H8H_TIMER8_CHANNEL(config, m_timer8_0, *this, m_intc, 64, 65, 66, m_timer8_1, h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
+ H8H_TIMER8_CHANNEL(config, m_timer8_1, *this, m_intc, 68, 69, 70, m_timer8_0, h8_timer8_channel_device::CHAIN_A, false, false);
H8_TIMER16(config, m_timer16, *this, 6, 0x00);
H8S_TIMER16_CHANNEL(config, m_timer16_0, *this, 4, 0x60, m_intc, 32,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::INPUT_D);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::INPUT_D);
H8S_TIMER16_CHANNEL(config, m_timer16_1, *this, 2, 0x4c, m_intc, 40,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::CHAIN).set_chain(m_timer16_2);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::CHAIN).set_chain(m_timer16_2);
H8S_TIMER16_CHANNEL(config, m_timer16_2, *this, 2, 0x4c, m_intc, 44,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_1024);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_1024);
H8S_TIMER16_CHANNEL(config, m_timer16_3, *this, 4, 0x60, m_intc, 48,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::DIV_1024,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::DIV_4096);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::DIV_1024,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::DIV_4096);
H8S_TIMER16_CHANNEL(config, m_timer16_4, *this, 2, 0x4c, m_intc, 56,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_1024,
- h8_timer16_channel_device::CHAIN).set_chain(m_timer16_5);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_1024,
+ h8_timer16_channel_device::CHAIN).set_chain(m_timer16_5);
H8S_TIMER16_CHANNEL(config, m_timer16_5, *this, 2, 0x4c, m_intc, 60,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::INPUT_D);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::INPUT_D);
H8_SCI(config, m_sci[0], 0, *this, m_intc, 80, 81, 82, 83);
H8_SCI(config, m_sci[1], 1, *this, m_intc, 84, 85, 86, 87);
H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
@@ -395,6 +394,23 @@ void h8s2357_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h8s2357_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_sci[2]->notify_standby(state);
+ m_timer8_0->notify_standby(state);
+ m_timer8_1->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_timer16_5->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h8s2357_device::device_start()
{
h8s2000_device::device_start();
diff --git a/src/devices/cpu/h8/h8s2357.h b/src/devices/cpu/h8/h8s2357.h
index a328e948868c3..3217f8dbf878f 100644
--- a/src/devices/cpu/h8/h8s2357.h
+++ b/src/devices/cpu/h8/h8s2357.h
@@ -110,6 +110,7 @@ class h8s2357_device : public h8s2000_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/h8s2655.cpp b/src/devices/cpu/h8/h8s2655.cpp
index 54a644ded0621..ab4fb1fc8eb67 100644
--- a/src/devices/cpu/h8/h8s2655.cpp
+++ b/src/devices/cpu/h8/h8s2655.cpp
@@ -88,10 +88,8 @@ void h8s2655_device::map(address_map &map)
map(0xfffebd, 0xfffebd).w(m_porte, FUNC(h8_port_device::ddr_w));
map(0xfffebe, 0xfffebe).w(m_portf, FUNC(h8_port_device::ddr_w));
map(0xfffebf, 0xfffebf).w(m_portg, FUNC(h8_port_device::ddr_w));
- map(0xfffec0, 0xfffec1).rw(m_intc, FUNC(h8s_intc_device::icr_r), FUNC(h8s_intc_device::icr_w));
- map(0xfffec2, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icrc_r), FUNC(h8s_intc_device::icrc_w));
- map(0xfffec4, 0xfffecd).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
- map(0xfffece, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::iprk_r), FUNC(h8s_intc_device::iprk_w));
+ map(0xfffec0, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icr_r), FUNC(h8s_intc_device::icr_w));
+ map(0xfffec4, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w));
map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w));
@@ -230,63 +228,63 @@ void h8s2655_device::device_add_mconfig(machine_config &config)
H8_PORT(config, m_porte, *this, h8_device::PORT_E, 0x00, 0x00);
H8_PORT(config, m_portf, *this, h8_device::PORT_F, 0x00, 0x00);
H8_PORT(config, m_portg, *this, h8_device::PORT_G, 0xe0, 0xe0);
- H8H_TIMER8_CHANNEL(config, m_timer8_0, *this, m_intc, 64, 65, 66, m_timer8_1, h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
- H8H_TIMER8_CHANNEL(config, m_timer8_1, *this, m_intc, 68, 69, 70, m_timer8_0, h8_timer8_channel_device::CHAIN_A, false, false);
+ H8H_TIMER8_CHANNEL(config, m_timer8_0, *this, m_intc, 64, 65, 66, m_timer8_1, h8_timer8_channel_device::CHAIN_OVERFLOW, true, false);
+ H8H_TIMER8_CHANNEL(config, m_timer8_1, *this, m_intc, 68, 69, 70, m_timer8_0, h8_timer8_channel_device::CHAIN_A, false, false);
H8_TIMER16(config, m_timer16, *this, 6, 0x00);
H8S_TIMER16_CHANNEL(config, m_timer16_0, *this, 4, 0x60, m_intc, 32,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::INPUT_D);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::INPUT_D);
H8S_TIMER16_CHANNEL(config, m_timer16_1, *this, 2, 0x4c, m_intc, 40,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::CHAIN).set_chain(m_timer16_2);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::CHAIN).set_chain(m_timer16_2);
H8S_TIMER16_CHANNEL(config, m_timer16_2, *this, 2, 0x4c, m_intc, 44,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_B,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_1024);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_B,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_1024);
H8S_TIMER16_CHANNEL(config, m_timer16_3, *this, 4, 0x60, m_intc, 48,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::DIV_1024,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::DIV_4096);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::DIV_1024,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::DIV_4096);
H8S_TIMER16_CHANNEL(config, m_timer16_4, *this, 2, 0x4c, m_intc, 56,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_1024,
- h8_timer16_channel_device::CHAIN).set_chain(m_timer16_5);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_1024,
+ h8_timer16_channel_device::CHAIN).set_chain(m_timer16_5);
H8S_TIMER16_CHANNEL(config, m_timer16_5, *this, 2, 0x4c, m_intc, 60,
- h8_timer16_channel_device::DIV_1,
- h8_timer16_channel_device::DIV_4,
- h8_timer16_channel_device::DIV_16,
- h8_timer16_channel_device::DIV_64,
- h8_timer16_channel_device::INPUT_A,
- h8_timer16_channel_device::INPUT_C,
- h8_timer16_channel_device::DIV_256,
- h8_timer16_channel_device::INPUT_D);
+ h8_timer16_channel_device::DIV_1,
+ h8_timer16_channel_device::DIV_4,
+ h8_timer16_channel_device::DIV_16,
+ h8_timer16_channel_device::DIV_64,
+ h8_timer16_channel_device::INPUT_A,
+ h8_timer16_channel_device::INPUT_C,
+ h8_timer16_channel_device::DIV_256,
+ h8_timer16_channel_device::INPUT_D);
H8_SCI(config, m_sci[0], 0, *this, m_intc, 80, 81, 82, 83);
H8_SCI(config, m_sci[1], 1, *this, m_intc, 84, 85, 86, 87);
H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
@@ -408,6 +406,23 @@ void h8s2655_device::internal_update(u64 current_time)
recompute_bcount(event_time);
}
+void h8s2655_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_sci[2]->notify_standby(state);
+ m_timer8_0->notify_standby(state);
+ m_timer8_1->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_timer16_5->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void h8s2655_device::device_start()
{
h8s2600_device::device_start();
diff --git a/src/devices/cpu/h8/h8s2655.h b/src/devices/cpu/h8/h8s2655.h
index cd393b38deec0..d92a1e8c5bc64 100644
--- a/src/devices/cpu/h8/h8s2655.h
+++ b/src/devices/cpu/h8/h8s2655.h
@@ -101,6 +101,7 @@ class h8s2655_device : public h8s2600_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
void map(address_map &map);
diff --git a/src/devices/cpu/h8/swx00.cpp b/src/devices/cpu/h8/swx00.cpp
index c65a10e301c20..e06780fb83ed3 100644
--- a/src/devices/cpu/h8/swx00.cpp
+++ b/src/devices/cpu/h8/swx00.cpp
@@ -8,7 +8,6 @@ DEFINE_DEVICE_TYPE(SWX00, swx00_device, "swx00", "Yamaha SWX00")
swx00_device::swx00_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, u8 mode) :
h8s2000_device(mconfig, SWX00, tag, owner, clock, address_map_constructor(FUNC(swx00_device::map), this)),
m_intc(*this, "intc"),
-#if 0
m_adc(*this, "adc"),
m_dma(*this, "dma"),
m_dma0(*this, "dma:0"),
@@ -36,7 +35,6 @@ swx00_device::swx00_device(const machine_config &mconfig, const char *tag, devic
m_timer16_4(*this, "timer16:4"),
m_timer16_5(*this, "timer16:5"),
m_watchdog(*this, "watchdog"),
-#endif
m_data_config(mode & MODE_DUAL ? "s" : "c", ENDIANNESS_BIG, 16, mode & MODE_DUAL ? 24 : 22),
m_mode(mode),
m_syscr(0)
@@ -46,8 +44,7 @@ swx00_device::swx00_device(const machine_config &mconfig, const char *tag, devic
void swx00_device::map(address_map &map)
{
- map(0xffec00, 0xfffbff).ram();
-#if 0
+ map(0xffe100, 0xfffbff).ram();
map(0xfffe80, 0xfffe80).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tcr_r), FUNC(h8_timer16_channel_device::tcr_w));
map(0xfffe81, 0xfffe81).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tmdr_r), FUNC(h8_timer16_channel_device::tmdr_w));
map(0xfffe82, 0xfffe83).rw(m_timer16_3, FUNC(h8_timer16_channel_device::tior_r), FUNC(h8_timer16_channel_device::tior_w));
@@ -81,10 +78,8 @@ void swx00_device::map(address_map &map)
map(0xfffebd, 0xfffebd).w(m_porte, FUNC(h8_port_device::ddr_w));
map(0xfffebe, 0xfffebe).w(m_portf, FUNC(h8_port_device::ddr_w));
map(0xfffebf, 0xfffebf).w(m_portg, FUNC(h8_port_device::ddr_w));
- map(0xfffec0, 0xfffec1).rw(m_intc, FUNC(h8s_intc_device::icr_r), FUNC(h8s_intc_device::icr_w));
- map(0xfffec2, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icrc_r), FUNC(h8s_intc_device::icrc_w));
- map(0xfffec4, 0xfffecd).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
- map(0xfffece, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::iprk_r), FUNC(h8s_intc_device::iprk_w));
+ map(0xfffec0, 0xfffec2).rw(m_intc, FUNC(h8s_intc_device::icr_r), FUNC(h8s_intc_device::icr_w));
+ map(0xfffec4, 0xfffece).rw(m_intc, FUNC(h8s_intc_device::ipr_r), FUNC(h8s_intc_device::ipr_w));
map(0xfffee0, 0xfffee1).rw(m_dma0, FUNC(h8s_dma_channel_device::marah_r), FUNC(h8s_dma_channel_device::marah_w));
map(0xfffee2, 0xfffee3).rw(m_dma0, FUNC(h8s_dma_channel_device::maral_r), FUNC(h8s_dma_channel_device::maral_w));
@@ -165,9 +160,9 @@ void swx00_device::map(address_map &map)
map(0xffff8c, 0xffff8c).rw(m_sci[2], FUNC(h8_sci_device::ssr_r), FUNC(h8_sci_device::ssr_w));
map(0xffff8d, 0xffff8d).r(m_sci[2], FUNC(h8_sci_device::rdr_r));
map(0xffff8e, 0xffff8e).rw(m_sci[2], FUNC(h8_sci_device::scmr_r), FUNC(h8_sci_device::scmr_w));
- map(0xffff90, 0xffff9f).r(m_adc, FUNC(h8_adc_device::addr16_r));
- map(0xffffa0, 0xffffa0).rw(m_adc, FUNC(h8_adc_device::adcsr_r), FUNC(h8_adc_device::adcsr_w));
- map(0xffffa1, 0xffffa1).rw(m_adc, FUNC(h8_adc_device::adcr_r), FUNC(h8_adc_device::adcr_w));
+ map(0xffff90, 0xffff97).r(m_adc, FUNC(h8_adc_device::addr8_r));
+ map(0xffff98, 0xffff98).rw(m_adc, FUNC(h8_adc_device::adcsr_r), FUNC(h8_adc_device::adcsr_w));
+ map(0xffff99, 0xffff99).rw(m_adc, FUNC(h8_adc_device::adcr_r), FUNC(h8_adc_device::adcr_w));
map(0xffffb0, 0xffffb0).rw(m_timer8_0, FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
map(0xffffb1, 0xffffb1).rw(m_timer8_1, FUNC(h8_timer8_channel_device::tcr_r), FUNC(h8_timer8_channel_device::tcr_w));
map(0xffffb2, 0xffffb2).rw(m_timer8_0, FUNC(h8_timer8_channel_device::tcsr_r), FUNC(h8_timer8_channel_device::tcsr_w));
@@ -201,14 +196,12 @@ void swx00_device::map(address_map &map)
map(0xfffff5, 0xfffff5).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tsr_r), FUNC(h8_timer16_channel_device::tsr_w));
map(0xfffff6, 0xfffff7).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tcnt_r), FUNC(h8_timer16_channel_device::tcnt_w));
map(0xfffff8, 0xfffffb).rw(m_timer16_2, FUNC(h8_timer16_channel_device::tgr_r), FUNC(h8_timer16_channel_device::tgr_w));
-#endif
}
void swx00_device::device_add_mconfig(machine_config &config)
{
H8S_INTC(config, m_intc, *this);
-#if 0
- H8_ADC_2655(config, m_adc, *this, m_intc, 28);
+ H8_ADC_2357(config, m_adc, *this, m_intc, 28);
H8S_DMA(config, m_dma, *this);
H8S_DMA_CHANNEL(config, m_dma0, *this, m_dma, m_intc);
H8S_DMA_CHANNEL(config, m_dma1, *this, m_dma, m_intc);
@@ -284,7 +277,6 @@ void swx00_device::device_add_mconfig(machine_config &config)
h8_timer16_channel_device::INPUT_D);
H8_SCI(config, m_sci[2], 2, *this, m_intc, 88, 89, 90, 91);
H8_WATCHDOG(config, m_watchdog, *this, m_intc, 25, h8_watchdog_device::S);
-#endif
H8_SCI(config, m_sci[0], 0, *this, m_intc, 80, 81, 82, 83);
H8_SCI(config, m_sci[1], 1, *this, m_intc, 84, 85, 86, 87);
}
@@ -395,7 +387,6 @@ void swx00_device::interrupt_taken()
void swx00_device::internal_update(u64 current_time)
{
u64 event_time = 0;
-#if 0
add_event(event_time, m_adc->internal_update(current_time));
add_event(event_time, m_sci[0]->internal_update(current_time));
add_event(event_time, m_sci[1]->internal_update(current_time));
@@ -409,11 +400,27 @@ void swx00_device::internal_update(u64 current_time)
add_event(event_time, m_timer16_4->internal_update(current_time));
add_event(event_time, m_timer16_5->internal_update(current_time));
add_event(event_time, m_watchdog->internal_update(current_time));
-#endif
recompute_bcount(event_time);
}
+void swx00_device::notify_standby(int state)
+{
+ m_adc->notify_standby(state);
+ m_sci[0]->notify_standby(state);
+ m_sci[1]->notify_standby(state);
+ m_sci[2]->notify_standby(state);
+ m_timer8_0->notify_standby(state);
+ m_timer8_1->notify_standby(state);
+ m_timer16_0->notify_standby(state);
+ m_timer16_1->notify_standby(state);
+ m_timer16_2->notify_standby(state);
+ m_timer16_3->notify_standby(state);
+ m_timer16_4->notify_standby(state);
+ m_timer16_5->notify_standby(state);
+ m_watchdog->notify_standby(state);
+}
+
void swx00_device::device_start()
{
h8s2000_device::device_start();
diff --git a/src/devices/cpu/h8/swx00.h b/src/devices/cpu/h8/swx00.h
index aad63bcfced9a..3fb2426cc9245 100644
--- a/src/devices/cpu/h8/swx00.h
+++ b/src/devices/cpu/h8/swx00.h
@@ -50,7 +50,6 @@ class swx00_device : public h8s2000_device {
int s_bus_id() const { return m_mode & MODE_DUAL ? AS_DATA : AS_PROGRAM; }
int c_bus_id() const { return m_mode & MODE_DUAL ? AS_PROGRAM : AS_DATA; }
-#if 0
auto read_port1() { return m_read_port [PORT_1].bind(); }
auto write_port1() { return m_write_port[PORT_1].bind(); }
auto read_port2() { return m_read_port [PORT_2].bind(); }
@@ -76,14 +75,12 @@ class swx00_device : public h8s2000_device {
auto write_portf() { return m_write_port[PORT_F].bind(); }
auto read_portg() { return m_read_port [PORT_G].bind(); }
auto write_portg() { return m_write_port[PORT_G].bind(); }
-#endif
u8 syscr_r();
void syscr_w(u8 data);
protected:
required_device m_intc;
-#if 0
required_device m_adc;
required_device m_dma;
required_device m_dma0;
@@ -111,7 +108,6 @@ class swx00_device : public h8s2000_device {
required_device m_timer16_4;
required_device m_timer16_5;
required_device m_watchdog;
-#endif
address_space_config m_data_config;
@@ -125,6 +121,7 @@ class swx00_device : public h8s2000_device {
virtual int trapa_setup() override;
virtual void irq_setup() override;
virtual void internal_update(u64 current_time) override;
+ virtual void notify_standby(int state) override;
virtual void device_add_mconfig(machine_config &config) override;
virtual space_config_vector memory_space_config() const override;
diff --git a/src/devices/cpu/hcd62121/hcd62121.cpp b/src/devices/cpu/hcd62121/hcd62121.cpp
index 00faac4f7a204..67d5452ebb222 100644
--- a/src/devices/cpu/hcd62121/hcd62121.cpp
+++ b/src/devices/cpu/hcd62121/hcd62121.cpp
@@ -61,6 +61,7 @@ hcd62121_cpu_device::hcd62121_cpu_device(const machine_config &mconfig, const ch
, m_dseg(0)
, m_sseg(0)
, m_f(0)
+ , m_time(0)
, m_lar(0)
, m_opt(0)
, m_port(0)
@@ -1443,11 +1444,18 @@ void hcd62121_cpu_device::execute_run()
break;
case 0xB1: /* unk_B1 reg/i8 - PORTx control/direction? */
- case 0xB3: /* unk_B3 reg/i8 - timer/irq related? */
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
read_op();
break;
+ case 0xB3: /* timer_set i8 */
+ {
+ u8 arg = read_op();
+
+ m_time = arg;
+ }
+ break;
+
case 0xB4: /* out koh,reg */
m_koh_cb(m_reg[read_op() & 0x7f]);
break;
@@ -1710,6 +1718,15 @@ void hcd62121_cpu_device::execute_run()
}
break;
+ case 0xEA: /* movw reg,pc */
+ {
+ u8 reg1 = read_op();
+
+ m_reg[reg1 & 0x7f] = m_ip & 0xff;
+ m_reg[(reg1 + 1) & 0x7f] = m_ip >> 8;
+ }
+ break;
+
case 0xEB: /* movw reg,sp */
{
u8 reg1 = read_op();
@@ -1719,6 +1736,14 @@ void hcd62121_cpu_device::execute_run()
}
break;
+ case 0xED: /* movb reg,ds */
+ m_reg[read_op() & 0x7f] = m_dseg;
+ break;
+
+ case 0xEE: /* movb reg,cs */
+ m_reg[read_op() & 0x7f] = m_cseg;
+ break;
+
case 0xEF: /* movb reg,ss */
m_reg[read_op() & 0x7f] = m_sseg;
break;
@@ -1736,20 +1761,164 @@ void hcd62121_cpu_device::execute_run()
case 0xF1: /* unk_F1 reg/i8 (out?) */
case 0xF3: /* unk_F3 reg/i8 (out?) */
case 0xF5: /* unk_F5 reg/i8 (out?) */
- case 0xF7: /* unk_F7 reg/i8 (out?) */
+ case 0xF7: /* timer_ctrl i8 */
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
read_op();
break;
case 0xFC: /* unk_FC - disable interrupts/stop timer?? */
case 0xFD: /* unk_FD */
- case 0xFE: /* unk_FE - wait for/start timer */
- if (op == 0xFE)
- m_icount -= 75000; // TODO: temporary value that makes emulation speed acceptable
-
logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op);
break;
+ case 0xFE: /* timer_wait */
+ if (m_time & 0x01) {
+ /*
+ When timer control is set with operand 0xC0, the CPU periodically reads
+ from external RAM (address range 0x7c00..0x7fff) at an interval of
+ 832 clock cycles, with the reads themselves taking another 64 clock cycles.
+ This needs to be explicitly setup, involving writes to unknown segments
+ 0x11 and 0xE1 (see cfx9850.bin @ 00:00fe), otherwise there's only activity
+ on address lines without any reads.
+
+ The total sum of these state reads can be approximated to the closest
+ power of two to define timeout values. Multiple samples were averaged,
+ as the state read interval can start at a distinct point in time from
+ the timer wait execution.
+ */
+ const u64 TIMER_STATE_READ_CYCLES = 832 + 64;
+ u64 cycles_until_timeout = 0;
+ switch (m_time) {
+ case 0x11:
+ case 0x13:
+ case 0x15:
+ case 0x17:
+ case 0x19:
+ case 0x1b:
+ case 0x1d:
+ case 0x1f:
+ case 0x31:
+ case 0x33:
+ case 0x35:
+ case 0x37:
+ case 0x39:
+ case 0x3b:
+ case 0x3d:
+ case 0x3f:
+ case 0x51:
+ case 0x53:
+ case 0x55:
+ case 0x57:
+ case 0x59:
+ case 0x5b:
+ case 0x5d:
+ case 0x5f:
+ case 0x71:
+ case 0x73:
+ case 0x75:
+ case 0x77:
+ case 0x79:
+ case 0x7b:
+ case 0x7d:
+ case 0x7f:
+ case 0x91:
+ case 0x93:
+ case 0x95:
+ case 0x97:
+ case 0x99:
+ case 0x9b:
+ case 0x9d:
+ case 0x9f:
+ case 0xb1:
+ case 0xb3:
+ case 0xb5:
+ case 0xb7:
+ case 0xb9:
+ case 0xbb:
+ case 0xbd:
+ case 0xbf:
+ case 0xd1:
+ case 0xd3:
+ case 0xd5:
+ case 0xd7:
+ case 0xd9:
+ case 0xdb:
+ case 0xdd:
+ case 0xdf:
+ // Approximately 814.32us
+ cycles_until_timeout = 0x4 * TIMER_STATE_READ_CYCLES;
+ break;
+ case 0x21:
+ case 0x23:
+ case 0x25:
+ case 0x27:
+ case 0x29:
+ case 0x2b:
+ case 0x2d:
+ case 0x2f:
+ case 0x61:
+ case 0x63:
+ case 0x65:
+ case 0x67:
+ case 0x69:
+ case 0x6b:
+ case 0x6d:
+ case 0x6f:
+ case 0xa1:
+ case 0xa3:
+ case 0xa5:
+ case 0xa7:
+ case 0xa9:
+ case 0xab:
+ case 0xad:
+ case 0xaf:
+ // Approximately 1.63ms
+ cycles_until_timeout = 0x8 * TIMER_STATE_READ_CYCLES;
+ break;
+ case 0x05:
+ case 0x07:
+ case 0x0d:
+ case 0x0f:
+ case 0x45:
+ case 0x47:
+ case 0x4d:
+ case 0x4f:
+ case 0xc5:
+ case 0xc7:
+ case 0xcd:
+ case 0xcf:
+ // Approximately 209.34ms
+ cycles_until_timeout = 0x400 * TIMER_STATE_READ_CYCLES;
+ break;
+ case 0x49:
+ case 0x4b:
+ case 0xc9:
+ case 0xcb:
+ // Approximately 837.61ms
+ cycles_until_timeout = 0x1000 * TIMER_STATE_READ_CYCLES;
+ break;
+ case 0x41:
+ case 0x43:
+ case 0xc1:
+ case 0xc3:
+ // Approximately 1.68s
+ cycles_until_timeout = 0x2000 * TIMER_STATE_READ_CYCLES;
+ break;
+ case 0x81:
+ case 0x83:
+ // Approximately 100.58s
+ cycles_until_timeout = 0x7a800 * TIMER_STATE_READ_CYCLES;
+ break;
+ default:
+ logerror("%02x:%04x: unimplemented timer value %02x encountered\n", m_cseg, m_ip-1, m_time);
+ break;
+ }
+ m_icount -= cycles_until_timeout;
+ } else {
+ logerror("%02x:%04x: wait for disabled timer? value %02x\n", m_cseg, m_ip-1, m_time);
+ }
+ break;
+
case 0xFF: /* nop */
break;
diff --git a/src/devices/cpu/hcd62121/hcd62121.h b/src/devices/cpu/hcd62121/hcd62121.h
index d7d35a881dd1e..785a283076ae1 100644
--- a/src/devices/cpu/hcd62121/hcd62121.h
+++ b/src/devices/cpu/hcd62121/hcd62121.h
@@ -91,6 +91,7 @@ class hcd62121_cpu_device : public cpu_device
u8 m_dseg;
u8 m_sseg;
u8 m_f;
+ u8 m_time;
u16 m_lar;
u8 m_reg[0x80];
diff --git a/src/devices/cpu/m68000/tmp68301.cpp b/src/devices/cpu/m68000/tmp68301.cpp
index dcbd3a4a4a700..5063f50413840 100644
--- a/src/devices/cpu/m68000/tmp68301.cpp
+++ b/src/devices/cpu/m68000/tmp68301.cpp
@@ -1099,8 +1099,15 @@ void tmp68301_device::serial_tx_update(int ch)
nstate = m_smr[ch] & SMR_PEN ? SR_PARITY : SR_STOP;
break;
- case SR_PARITY:
- abort();
+ case SR_PARITY: {
+ u32 parity = m_smr[ch] & SMR_PEO ? 0 : 1;
+ for(u32 i = 0; i != 5 + ((m_smr[ch] >> SMR_CL_SFT) & 3); i++)
+ if((m_serial_tx[ch] >> i) & 1)
+ parity = parity ^ 1;
+ m_tx_cb[ch](parity);
+ nstate = SR_STOP;
+ break;
+ }
case SR_STOP:
m_tx_cb[ch](1);
diff --git a/src/devices/cpu/ns32000/common.h b/src/devices/cpu/ns32000/common.h
index a93259617c96f..fa978729b4970 100644
--- a/src/devices/cpu/ns32000/common.h
+++ b/src/devices/cpu/ns32000/common.h
@@ -32,38 +32,6 @@ namespace ns32000
};
}
-class ns32000_state_interface
-{
-public:
- virtual void state_add(device_state_interface &parent, int &index) = 0;
-};
-
-class ns32000_fpu_interface
- : public device_interface
- , public ns32000_state_interface
-{
-protected:
- ns32000_fpu_interface(machine_config const &mconfig, device_t &device)
- : device_interface(device, "ns32000_fpu")
- {
- }
-};
-
-class ns32000_mmu_interface
- : public device_interface
- , public ns32000_state_interface
-{
-public:
- enum translate_result : unsigned { COMPLETE, CANCEL, ABORT };
- virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool flag = false, bool suppress = false) = 0;
-
-protected:
- ns32000_mmu_interface(machine_config const &mconfig, device_t &device)
- : device_interface(device, "ns32000_mmu")
- {
- }
-};
-
class ns32000_slave_interface : public device_interface
{
public:
@@ -75,6 +43,14 @@ class ns32000_slave_interface : public device_interface
{
}
+ enum slave_idbyte : u8
+ {
+ FORMAT_9 = 0x3e, // fpu
+ FORMAT_11 = 0xbe, // fpu
+ FORMAT_12 = 0xfe, // fpu
+ FORMAT_14 = 0x1e, // mmu
+ };
+
enum slave_status : u16
{
SLAVE_Q = 0x0001, // quit (1=error)
@@ -87,6 +63,8 @@ class ns32000_slave_interface : public device_interface
SLAVE_OK = 0,
};
+ virtual void state_add(device_state_interface &parent, int &index) = 0;
+
protected:
ns32000_slave_interface(machine_config const &mconfig, device_t &device, char const *type)
: device_interface(device, type)
@@ -97,31 +75,52 @@ class ns32000_slave_interface : public device_interface
devcb_write_line m_out_scb;
};
-class ns32000_slow_slave_interface : public ns32000_slave_interface
+class ns32000_fpu_interface : public ns32000_slave_interface
+{
+protected:
+ ns32000_fpu_interface(machine_config const &mconfig, device_t &device)
+ : ns32000_slave_interface(mconfig, device)
+ {
+ }
+};
+
+class ns32000_mmu_interface : public ns32000_slave_interface
{
public:
- virtual void write_id(u16 data) = 0;
- virtual void write_op(u16 data) = 0;
- virtual u16 read_st(int *icount = nullptr) = 0;
- virtual u16 read_op() = 0;
+ enum translate_result : unsigned { COMPLETE, CANCEL, ABORT };
+ virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool flag = false, bool suppress = false) = 0;
protected:
- ns32000_slow_slave_interface(machine_config const &mconfig, device_t &device)
+ ns32000_mmu_interface(machine_config const &mconfig, device_t &device)
: ns32000_slave_interface(mconfig, device)
{
}
};
-class ns32000_fast_slave_interface : public ns32000_slave_interface
+class ns32000_slow_slave_interface : public device_interface
+{
+public:
+ virtual u16 slow_status(int *icount = nullptr) = 0;
+ virtual u16 slow_read() = 0;
+ virtual void slow_write(u16 data) = 0;
+
+protected:
+ ns32000_slow_slave_interface(machine_config const &mconfig, device_t &device)
+ : device_interface(device, "ns32000_slave_slow")
+ {
+ }
+};
+
+class ns32000_fast_slave_interface : public device_interface
{
public:
- virtual u32 read_st32(int *icount = nullptr) = 0;
- virtual u32 read() = 0;
- virtual void write(u32 data) = 0;
+ virtual u32 fast_status(int *icount = nullptr) = 0;
+ virtual u32 fast_read() = 0;
+ virtual void fast_write(u32 data) = 0;
protected:
ns32000_fast_slave_interface(machine_config const &mconfig, device_t &device)
- : ns32000_slave_interface(mconfig, device)
+ : device_interface(device, "ns32000_slave_fast")
{
}
};
diff --git a/src/devices/cpu/ns32000/ns32000.cpp b/src/devices/cpu/ns32000/ns32000.cpp
index d28d25b03ad9e..6fef593dfd8a8 100644
--- a/src/devices/cpu/ns32000/ns32000.cpp
+++ b/src/devices/cpu/ns32000/ns32000.cpp
@@ -3128,14 +3128,14 @@ template void ns32000_device::execute
}
}
break;
- case 0x3e:
+ case ns32000_slave_interface::FORMAT_9:
// format 9: xxxx xyyy yyoo ofii 0011 1110
if (m_cfg & CFG_F)
{
u16 const opword = fetch(bytes);
addr_mode mode[] = { addr_mode(BIT(opword, 11, 5)), addr_mode(BIT(opword, 6, 5)) };
- size_code const size_f = BIT(opword, 0) ? SIZE_D : SIZE_Q;
+ size_code const size_f = BIT(opword, 2) ? SIZE_D : SIZE_Q;
size_code const size = size_code(opword & 3);
switch (BIT(opword, 3, 3))
@@ -3234,7 +3234,7 @@ template void ns32000_device::execute
case 0x7e: // format 10
interrupt(UND);
break;
- case 0xbe:
+ case ns32000_slave_interface::FORMAT_11:
// format 11: xxxx xyyy yyoo oo0f 1011 1110
if (m_cfg & CFG_F)
{
@@ -3366,7 +3366,7 @@ template void ns32000_device::execute
else
interrupt(UND);
break;
- case 0xfe:
+ case ns32000_slave_interface::FORMAT_12:
// format 12: xxxx xyyy yyoo oo0f 1111 1110
if ((m_cfg & CFG_F) && type() == NS32332)
{
@@ -3459,7 +3459,7 @@ template void ns32000_device::execute
case 0x9e: // format 13
interrupt(UND);
break;
- case 0x1e:
+ case ns32000_slave_interface::FORMAT_14:
// format 14: xxxx xsss s0oo ooii 0001 1110
if (!(m_psr & PSR_U))
{
@@ -3671,7 +3671,7 @@ template u16 ns32000_device::slave(u8
{
switch (opbyte)
{
- case 0x1e:
+ case ns32000_slave_interface::FORMAT_14:
if (!m_mmu)
fatalerror("slave mmu coprocessor not configured (%s)\n", machine().describe_context());
@@ -3681,9 +3681,9 @@ template u16 ns32000_device::slave(u8
return slave_slow(dynamic_cast(*m_mmu), opbyte, opword, op1, op2);
break;
- case 0x3e:
- case 0xbe:
- case 0xfe:
+ case ns32000_slave_interface::FORMAT_9:
+ case ns32000_slave_interface::FORMAT_11:
+ case ns32000_slave_interface::FORMAT_12:
if (!m_fpu)
fatalerror("slave fpu coprocessor not configured (%s)\n", machine().describe_context());
@@ -3701,8 +3701,8 @@ template u16 ns32000_device::slave(u8
template u16 ns32000_device::slave_slow(ns32000_slow_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2)
{
- slave.write_id(opbyte);
- slave.write_op(swapendian_int16(opword));
+ slave.slow_write(opbyte);
+ slave.slow_write(swapendian_int16(opword));
if ((op1.access == READ || op1.access == RMW) && !(op1.type == REG && op1.slave))
{
@@ -3711,20 +3711,20 @@ template u16 ns32000_device::slave_sl
switch (op1.size)
{
case SIZE_B:
- slave.write_op(u8(data));
+ slave.slow_write(u8(data));
break;
case SIZE_W:
- slave.write_op(u16(data));
+ slave.slow_write(u16(data));
break;
case SIZE_D:
- slave.write_op(u16(data >> 0));
- slave.write_op(u16(data >> 16));
+ slave.slow_write(u16(data >> 0));
+ slave.slow_write(u16(data >> 16));
break;
case SIZE_Q:
- slave.write_op(u16(data >> 0));
- slave.write_op(u16(data >> 16));
- slave.write_op(u16(data >> 32));
- slave.write_op(u16(data >> 48));
+ slave.slow_write(u16(data >> 0));
+ slave.slow_write(u16(data >> 16));
+ slave.slow_write(u16(data >> 32));
+ slave.slow_write(u16(data >> 48));
break;
}
}
@@ -3732,8 +3732,8 @@ template u16 ns32000_device::slave_sl
{
u32 const data = ea(op1);
- slave.write_op(u16(data >> 0));
- slave.write_op(u16(data >> 16));
+ slave.slow_write(u16(data >> 0));
+ slave.slow_write(u16(data >> 16));
// single-byte memory read cycle
mem_read(ns32000::ST_ODT, data, true);
@@ -3746,41 +3746,41 @@ template u16 ns32000_device::slave_sl
switch (op2.size)
{
case SIZE_B:
- slave.write_op(u8(data));
+ slave.slow_write(u8(data));
break;
case SIZE_W:
- slave.write_op(u16(data));
+ slave.slow_write(u16(data));
break;
case SIZE_D:
- slave.write_op(u16(data >> 0));
- slave.write_op(u16(data >> 16));
+ slave.slow_write(u16(data >> 0));
+ slave.slow_write(u16(data >> 16));
break;
case SIZE_Q:
- slave.write_op(u16(data >> 0));
- slave.write_op(u16(data >> 16));
- slave.write_op(u16(data >> 32));
- slave.write_op(u16(data >> 48));
+ slave.slow_write(u16(data >> 0));
+ slave.slow_write(u16(data >> 16));
+ slave.slow_write(u16(data >> 32));
+ slave.slow_write(u16(data >> 48));
break;
}
}
- u16 const status = slave.read_st(&m_icount);
+ u16 const status = slave.slow_status(&m_icount);
if (!(status & ns32000_slave_interface::SLAVE_Q))
{
if ((op2.access == WRITE || op2.access == RMW) && !(op2.type == REG && op2.slave))
{
- u64 data = slave.read_op();
+ u64 data = slave.slow_read();
switch (op2.size)
{
case SIZE_D:
- data |= u64(slave.read_op()) << 16;
+ data |= u64(slave.slow_read()) << 16;
break;
case SIZE_Q:
- data |= u64(slave.read_op()) << 16;
- data |= u64(slave.read_op()) << 32;
- data |= u64(slave.read_op()) << 48;
+ data |= u64(slave.slow_read()) << 16;
+ data |= u64(slave.slow_read()) << 32;
+ data |= u64(slave.slow_read()) << 48;
break;
default:
break;
@@ -3795,7 +3795,7 @@ template u16 ns32000_device::slave_sl
template u16 ns32000_device::slave_fast(ns32000_fast_slave_interface &slave, u8 opbyte, u16 opword, addr_mode op1, addr_mode op2)
{
- slave.write(u32(opbyte) << 24 | u32(swapendian_int16(opword)) << 8);
+ slave.fast_write(u32(opbyte) << 24 | u32(swapendian_int16(opword)) << 8);
if ((op1.access == READ || op1.access == RMW) && !(op1.type == REG && op1.slave))
{
@@ -3804,17 +3804,17 @@ template u16 ns32000_device::slave_fa
switch (op1.size)
{
case SIZE_B:
- slave.write(u8(data));
+ slave.fast_write(u8(data));
break;
case SIZE_W:
- slave.write(u16(data));
+ slave.fast_write(u16(data));
break;
case SIZE_D:
- slave.write(u32(data));
+ slave.fast_write(u32(data));
break;
case SIZE_Q:
- slave.write(u32(data >> 0));
- slave.write(u32(data >> 32));
+ slave.fast_write(u32(data >> 0));
+ slave.fast_write(u32(data >> 32));
break;
}
}
@@ -3822,7 +3822,7 @@ template u16 ns32000_device::slave_fa
{
u32 const data = ea(op1);
- slave.write(u32(data));
+ slave.fast_write(u32(data));
// single-byte memory read cycle
mem_read(ns32000::ST_ODT, data, true);
@@ -3835,32 +3835,32 @@ template u16 ns32000_device::slave_fa
switch (op2.size)
{
case SIZE_B:
- slave.write(u8(data));
+ slave.fast_write(u8(data));
break;
case SIZE_W:
- slave.write(u16(data));
+ slave.fast_write(u16(data));
break;
case SIZE_D:
- slave.write(u32(data));
+ slave.fast_write(u32(data));
break;
case SIZE_Q:
- slave.write(u32(data >> 0));
- slave.write(u32(data >> 32));
+ slave.fast_write(u32(data >> 0));
+ slave.fast_write(u32(data >> 32));
break;
}
}
// TODO: status is optional in fast protocol
- u32 const status = slave.read_st32(&m_icount);
+ u32 const status = slave.fast_status(&m_icount);
if (!(status & ns32000_slave_interface::SLAVE_Q))
{
if ((op2.access == WRITE || op2.access == RMW) && !(op2.type == REG && op2.slave))
{
- u64 data = slave.read();
+ u64 data = slave.fast_read();
if (op2.size == SIZE_Q)
- data |= u64(slave.read()) << 32;
+ data |= u64(slave.fast_read()) << 32;
gen_write(op2, data);
}
@@ -4162,7 +4162,7 @@ void ns32532_device::spr(unsigned reg, addr_mode const mode, bool user, unsigned
u16 ns32532_device::slave(u8 opbyte, u16 opword, addr_mode op1, addr_mode op2)
{
- if (opbyte == 0x1e)
+ if (opbyte == FORMAT_14)
{
switch (BIT(opword, 2, 4))
{
diff --git a/src/devices/cpu/ns32000/ns32000d.cpp b/src/devices/cpu/ns32000/ns32000d.cpp
index 4b9c49f813d40..170e2c7ae88eb 100644
--- a/src/devices/cpu/ns32000/ns32000d.cpp
+++ b/src/devices/cpu/ns32000/ns32000d.cpp
@@ -461,7 +461,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
u16 const opword = opcodes.r16(pc + bytes); bytes += 2;
addr_mode mode[] = { addr_mode(BIT(opword, 11, 5)), addr_mode(BIT(opword, 6, 5)) };
- size_code const size_f = BIT(opword, 0) ? SIZE_D : SIZE_Q;
+ size_code const size_f = BIT(opword, 2) ? SIZE_D : SIZE_Q;
size_code const size = size_code(opword & 3);
switch (BIT(opword, 3, 3))
@@ -473,7 +473,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_i(size);
mode[1].size_f(size_f);
decode(mode, pc, opcodes, bytes);
- util::stream_format(stream, "MOV%c%c %s, %s", size_char[size], BIT(opword, 0) ? 'F' : 'L', mode[0].mode, mode[1].mode);
+ util::stream_format(stream, "MOV%c%c %s, %s", size_char[size], BIT(opword, 2) ? 'F' : 'L', mode[0].mode, mode[1].mode);
break;
case 1:
// LFSR src
@@ -508,7 +508,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_f(size_f);
mode[1].size_i(size);
decode(mode, pc, opcodes, bytes);
- util::stream_format(stream, "ROUND%c%c %s, %s", BIT(opword, 0) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
+ util::stream_format(stream, "ROUND%c%c %s, %s", BIT(opword, 2) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
break;
case 5:
// TRUNCfi src,dst
@@ -517,7 +517,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_f(size_f);
mode[1].size_i(size);
decode(mode, pc, opcodes, bytes);
- util::stream_format(stream, "TRUNC%c%c %s, %s", BIT(opword, 0) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
+ util::stream_format(stream, "TRUNC%c%c %s, %s", BIT(opword, 2) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
break;
case 6:
// SFSR dst
@@ -534,7 +534,7 @@ offs_t ns32000_disassembler::disassemble(std::ostream &stream, offs_t pc, data_b
mode[0].size_f(size_f);
mode[1].size_i(size);
decode(mode, pc, opcodes, bytes);
- util::stream_format(stream, "FLOOR%c%c %s, %s", BIT(opword, 0) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
+ util::stream_format(stream, "FLOOR%c%c %s, %s", BIT(opword, 2) ? 'F' : 'L', size_char[size], mode[0].mode, mode[1].mode);
break;
}
}
diff --git a/src/devices/cpu/sh/sh7042.cpp b/src/devices/cpu/sh/sh7042.cpp
index 35f559b47ce12..7ef10f19ce112 100644
--- a/src/devices/cpu/sh/sh7042.cpp
+++ b/src/devices/cpu/sh/sh7042.cpp
@@ -21,13 +21,61 @@ sh7043_device::sh7043_device(const machine_config &mconfig, const char *tag, dev
sh7042_device::sh7042_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
sh2_device(mconfig, type, tag, owner, clock, CPU_TYPE_SH2, address_map_constructor(FUNC(sh7042_device::map), this), 32, 0xffffffff),
+ m_intc(*this, "intc"),
+ m_adc(*this, "adc"),
+ m_cmt(*this, "cmt"),
+ m_porta(*this, "porta"),
+ m_portb(*this, "portb"),
+ m_portc(*this, "portc"),
+ m_portd(*this, "portd"),
+ m_porte(*this, "porte"),
+ m_portf(*this, "portf"),
m_read_adc(*this, 0),
- m_sci_tx(*this)
+ m_sci_tx(*this),
+ m_read_port16(*this, 0xffff),
+ m_write_port16(*this),
+ m_read_port32(*this, 0xffffffff),
+ m_write_port32(*this)
{
+ m_port16_names = "bcef";
+ m_port32_names = "ad";
for(unsigned int i=0; i != m_read_adc.size(); i++)
m_read_adc[i].bind().set([this, i]() { return adc_default(i); });
+ for(unsigned int i=0; i != m_read_port16.size(); i++) {
+ m_read_port16[i].bind().set([this, i]() { return port16_default_r(i); });
+ m_write_port16[i].bind().set([this, i](u16 data) { port16_default_w(i, data); });
+ }
+ for(unsigned int i=0; i != m_read_port32.size(); i++) {
+ m_read_port32[i].bind().set([this, i]() { return port32_default_r(i); });
+ m_write_port32[i].bind().set([this, i](u32 data) { port32_default_w(i, data); });
+ }
}
+u16 sh7042_device::port16_default_r(int port)
+{
+ if(!machine().side_effects_disabled())
+ logerror("read of un-hooked port %c\n", m_port16_names[port]);
+ return 0xffff;
+}
+
+void sh7042_device::port16_default_w(int port, u16 data)
+{
+ logerror("write of un-hooked port %c %04x\n", m_port16_names[port], data);
+}
+
+u32 sh7042_device::port32_default_r(int port)
+{
+ if(!machine().side_effects_disabled())
+ logerror("read of un-hooked port %c\n", m_port32_names[port]);
+ return 0xffff;
+}
+
+void sh7042_device::port32_default_w(int port, u32 data)
+{
+ logerror("write of un-hooked port %c %04x\n", m_port32_names[port], data);
+}
+
+
u16 sh7042_device::adc_default(int adc)
{
logerror("read of un-hooked adc %d\n", adc);
@@ -38,70 +86,214 @@ void sh7042_device::device_start()
{
sh2_device::device_start();
- save_item(NAME(m_addr));
- save_item(NAME(m_adcsr));
- save_item(NAME(m_adcr));
+ m_event_timer = timer_alloc(FUNC(sh7042_device::event_timer_tick), this);
+
+ save_item(NAME(m_pcf_ah));
+ save_item(NAME(m_pcf_al));
+ save_item(NAME(m_pcf_b));
+ save_item(NAME(m_pcf_c));
+ save_item(NAME(m_pcf_dh));
+ save_item(NAME(m_pcf_dl));
+ save_item(NAME(m_pcf_e));
+ save_item(NAME(m_pcf_if));
+
+ m_pcf_ah = 0;
+ m_pcf_al = 0;
+ m_pcf_b = 0;
+ m_pcf_c = 0;
+ m_pcf_dh = 0;
+ m_pcf_dl = 0;
+ m_pcf_e = 0;
+ m_pcf_if = 0;
}
void sh7042_device::device_reset()
{
sh2_device::device_reset();
-
- memset(m_addr, 0, sizeof(m_addr));
- m_adcsr = m_adcr = 0;
}
+
void sh7042_device::map(address_map &map)
{
- map(0xffff83e0, 0xffff83e0).rw(FUNC(sh7042_device::adcsr_r), FUNC(sh7042_device::adcsr_w));
- map(0xffff83e1, 0xffff83e1).rw(FUNC(sh7042_device::adcr_r), FUNC(sh7042_device::adcr_w));
- map(0xffff83f0, 0xffff83ff).r(FUNC(sh7042_device::addr_r));
+ map(0xffff8348, 0xffff8357).rw(m_intc, FUNC(sh_intc_device::ipr_r), FUNC(sh_intc_device::ipr_w));
+ map(0xffff8358, 0xffff8359).rw(m_intc, FUNC(sh_intc_device::icr_r), FUNC(sh_intc_device::icr_w));
+ map(0xffff835a, 0xffff835b).rw(m_intc, FUNC(sh_intc_device::isr_r), FUNC(sh_intc_device::isr_w));
+
+ map(0xffff8380, 0xffff8383).rw(m_porta, FUNC(sh_port32_device::dr_r), FUNC(sh_port32_device::dr_w));
+ map(0xffff8384, 0xffff8387).rw(m_porta, FUNC(sh_port32_device::io_r), FUNC(sh_port32_device::io_w));
+ map(0xffff8388, 0xffff8389).rw(FUNC(sh7042_device::pcf_ah_r), FUNC(sh7042_device::pcf_ah_w));
+ map(0xffff838c, 0xffff838f).rw(FUNC(sh7042_device::pcf_al_r), FUNC(sh7042_device::pcf_al_w));
+ map(0xffff8390, 0xffff8391).rw(m_portb, FUNC(sh_port16_device::dr_r), FUNC(sh_port16_device::dr_w));
+ map(0xffff8392, 0xffff8393).rw(m_portc, FUNC(sh_port16_device::dr_r), FUNC(sh_port16_device::dr_w));
+ map(0xffff8394, 0xffff8395).rw(m_portb, FUNC(sh_port16_device::io_r), FUNC(sh_port16_device::io_w));
+ map(0xffff8396, 0xffff8397).rw(m_portc, FUNC(sh_port16_device::io_r), FUNC(sh_port16_device::io_w));
+ map(0xffff8398, 0xffff839b).rw(FUNC(sh7042_device::pcf_b_r), FUNC(sh7042_device::pcf_b_w));
+ map(0xffff839c, 0xffff839d).rw(FUNC(sh7042_device::pcf_c_r), FUNC(sh7042_device::pcf_c_w));
+ map(0xffff83a0, 0xffff83a3).rw(m_portd, FUNC(sh_port32_device::dr_r), FUNC(sh_port32_device::dr_w));
+ map(0xffff83a4, 0xffff83a7).rw(m_portd, FUNC(sh_port32_device::io_r), FUNC(sh_port32_device::io_w));
+ map(0xffff83a8, 0xffff83ab).rw(FUNC(sh7042_device::pcf_dh_r), FUNC(sh7042_device::pcf_dh_w));
+ map(0xffff83ac, 0xffff83ad).rw(FUNC(sh7042_device::pcf_dl_r), FUNC(sh7042_device::pcf_dl_w));
+ map(0xffff83b0, 0xffff83b1).rw(m_porte, FUNC(sh_port16_device::dr_r), FUNC(sh_port16_device::dr_w));
+ map(0xffff83b2, 0xffff83b3).r (m_portf, FUNC(sh_port16_device::dr_r));
+ map(0xffff83b4, 0xffff83b5).rw(m_porte, FUNC(sh_port16_device::io_r), FUNC(sh_port16_device::io_w));
+ map(0xffff83b8, 0xffff83bb).rw(FUNC(sh7042_device::pcf_e_r), FUNC(sh7042_device::pcf_e_w));
+ map(0xffff83c8, 0xffff83c9).rw(FUNC(sh7042_device::pcf_if_r), FUNC(sh7042_device::pcf_if_w));
+
+ map(0xffff83d0, 0xffff83d1).rw(m_cmt, FUNC(sh_cmt_device::cmstr_r), FUNC(sh_cmt_device::cmstr_w));
+ map(0xffff83d2, 0xffff83d3).rw(m_cmt, FUNC(sh_cmt_device::cmcsr0_r), FUNC(sh_cmt_device::cmcsr0_w));
+ map(0xffff83d4, 0xffff83d5).rw(m_cmt, FUNC(sh_cmt_device::cmcnt0_r), FUNC(sh_cmt_device::cmcnt0_w));
+ map(0xffff83d6, 0xffff83d7).rw(m_cmt, FUNC(sh_cmt_device::cmcor0_r), FUNC(sh_cmt_device::cmcor0_w));
+ map(0xffff83d8, 0xffff83d9).rw(m_cmt, FUNC(sh_cmt_device::cmcsr1_r), FUNC(sh_cmt_device::cmcsr1_w));
+ map(0xffff83da, 0xffff83db).rw(m_cmt, FUNC(sh_cmt_device::cmcnt1_r), FUNC(sh_cmt_device::cmcnt1_w));
+ map(0xffff83dc, 0xffff83dd).rw(m_cmt, FUNC(sh_cmt_device::cmcor1_r), FUNC(sh_cmt_device::cmcor1_w));
+
+ map(0xffff83e0, 0xffff83e0).rw(m_adc, FUNC(sh_adc_device::adcsr_r), FUNC(sh_adc_device::adcsr_w));
+ map(0xffff83e1, 0xffff83e1).rw(m_adc, FUNC(sh_adc_device::adcr_r), FUNC(sh_adc_device::adcr_w));
+ map(0xffff83f0, 0xffff83ff).r(m_adc, FUNC(sh_adc_device::addr_r));
map(0xfffff000, 0xffffffff).ram();
}
+void sh7042_device::device_add_mconfig(machine_config &config)
+{
+ SH_INTC(config, m_intc, *this);
+ SH_ADC(config, m_adc, *this, m_intc, 136);
+ SH_CMT(config, m_cmt, *this, m_intc, 144, 148);
+ SH_PORT32(config, m_porta, *this, 0, 0x00000000, 0xff000000);
+ SH_PORT16(config, m_portb, *this, 0, 0x0000, 0xfc00);
+ SH_PORT16(config, m_portc, *this, 1, 0x0000, 0x0000);
+ SH_PORT32(config, m_portd, *this, 1, 0x0000, 0x0000);
+ SH_PORT16(config, m_porte, *this, 2, 0x0000, 0x0000);
+ SH_PORT16(config, m_portf, *this, 3, 0x0000, 0xff00);
+}
-// ADC section
+void sh7042_device::do_sci_w(int sci, int state)
+{
+ logerror("sci %d %d\n", sci, state);
+}
-u16 sh7042_device::addr_r(offs_t offset)
+void sh7042_device::internal_update()
{
- logerror("addr16_r %d %03x\n", offset, m_addr[offset]);
- return m_addr[offset];
+ internal_update(current_cycles());
}
-u8 sh7042_device::adcsr_r()
+void sh7042_device::add_event(u64 &event_time, u64 new_event)
{
- logerror("adcsr_r %02x\n", m_adcsr);
- return m_adcsr;
+ if(!new_event)
+ return;
+ if(!event_time || event_time > new_event)
+ event_time = new_event;
}
-u8 sh7042_device::adcr_r()
+void sh7042_device::recompute_timer(u64 event_time)
{
- logerror("adcr_r %02x\n", m_adcr);
- return m_adcr;
+ if(!event_time) {
+ m_event_timer->adjust(attotime::never);
+ return;
+ }
+
+ m_event_timer->adjust(attotime::from_ticks(2*event_time + 1, 2*clock()) - machine().time());
}
-void sh7042_device::adcsr_w(u8 data)
+TIMER_CALLBACK_MEMBER(sh7042_device::event_timer_tick)
{
- logerror("adcsr_w %02x\n", data);
- // u8 prev = m_adcsr;
- m_adcsr = (data & 0x7f) | (m_adcsr & data & CSR_ADF);
+ internal_update();
}
-void sh7042_device::adcr_w(u8 data)
+void sh7042_device::internal_update(u64 current_time)
{
- static const char *const tg_modes[4] = { "soft", "mtu", "?", "external" };
- static const char *const buf_modes[4] = { "normal", "a->b", "a,b->c,d", "a->b->c->d" };
- logerror("adcr_w speed=%d trigger=%s mode=%s sampling=%s buffering=%s\n",
- BIT(data, 6) ? "high" : "low",
- tg_modes[(data >> 4) & 3],
- BIT(data, 3) ? "scan" : "single",
- BIT(data, 2) ? "simultaneous" : "normal",
- buf_modes[data & 3]);
- m_adcr = data;
+ u64 event_time = 0;
+
+ add_event(event_time, m_adc->internal_update(current_time));
+ add_event(event_time, m_cmt->internal_update(current_time));
+
+ recompute_timer(event_time);
}
-void sh7042_device::do_sci_w(int sci, int state)
+u16 sh7042_device::pcf_ah_r()
{
- logerror("sci %d %d\n", sci, state);
+ return m_pcf_ah;
+}
+
+void sh7042_device::pcf_ah_w(offs_t, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_ah);
+ logerror("pcf ah = %04x\n", m_pcf_ah);
+}
+
+u32 sh7042_device::pcf_al_r()
+{
+ return m_pcf_al;
+}
+
+void sh7042_device::pcf_al_w(offs_t, u32 data, u32 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_al);
+ logerror("pcf al = %08x\n", m_pcf_al);
+}
+
+u32 sh7042_device::pcf_b_r()
+{
+ return m_pcf_b;
+}
+
+void sh7042_device::pcf_b_w(offs_t, u32 data, u32 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_b);
+ logerror("pcf b = %08x\n", m_pcf_b);
+}
+
+u16 sh7042_device::pcf_c_r()
+{
+ return m_pcf_c;
+}
+
+void sh7042_device::pcf_c_w(offs_t, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_c);
+ logerror("pcf c = %04x\n", m_pcf_c);
+}
+
+u32 sh7042_device::pcf_dh_r()
+{
+ return m_pcf_dh;
+}
+
+void sh7042_device::pcf_dh_w(offs_t, u32 data, u32 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_dh);
+ logerror("pcf dh = %08x\n", m_pcf_dh);
+}
+
+u16 sh7042_device::pcf_dl_r()
+{
+ return m_pcf_dl;
+}
+
+void sh7042_device::pcf_dl_w(offs_t, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_dl);
+ logerror("pcf dl = %04x\n", m_pcf_dl);
+}
+
+u32 sh7042_device::pcf_e_r()
+{
+ return m_pcf_e;
+}
+
+void sh7042_device::pcf_e_w(offs_t, u32 data, u32 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_e);
+ logerror("pcf e = %08x\n", m_pcf_e);
+}
+
+u16 sh7042_device::pcf_if_r()
+{
+ return m_pcf_if;
+}
+
+void sh7042_device::pcf_if_w(offs_t, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_pcf_if);
+ logerror("pcf if = %04x\n", m_pcf_if);
}
diff --git a/src/devices/cpu/sh/sh7042.h b/src/devices/cpu/sh/sh7042.h
index dabcb7c272b4b..55795fd8282fb 100644
--- a/src/devices/cpu/sh/sh7042.h
+++ b/src/devices/cpu/sh/sh7042.h
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
-// SH7042, sh2 variant
+// SH704x, sh2 variant
#ifndef MAME_CPU_SH_SH7042_H
#define MAME_CPU_SH_SH7042_H
@@ -9,6 +9,10 @@
#pragma once
#include "sh2.h"
+#include "sh_intc.h"
+#include "sh_adc.h"
+#include "sh_cmt.h"
+#include "sh_port.h"
class sh7042_device : public sh2_device
{
@@ -19,8 +23,30 @@ class sh7042_device : public sh2_device
template void sci_rx_w(int state) { do_sci_w(Sci, state); }
template auto write_sci_tx() { return m_sci_tx[Sci].bind(); }
+ auto read_porta() { return m_read_port32 [0].bind(); }
+ auto write_porta() { return m_write_port32[0].bind(); }
+ auto read_portb() { return m_read_port16 [0].bind(); }
+ auto write_portb() { return m_write_port16[0].bind(); }
+ auto read_portc() { return m_read_port16 [1].bind(); }
+ auto write_portc() { return m_write_port16[1].bind(); }
+ auto read_portd() { return m_read_port32 [1].bind(); }
+ auto write_portd() { return m_write_port32[1].bind(); }
+ auto read_porte() { return m_read_port16 [2].bind(); }
+ auto write_porte() { return m_write_port16[2].bind(); }
+ auto read_portf() { return m_read_port16 [3].bind(); }
+
+ void internal_update();
+ u16 do_read_adc(int port) { return m_read_adc[port](); }
+ u16 do_read_port16(int port) { return m_read_port16[port](); }
+ void do_write_port16(int port, u16 data, u16 ddr) { m_write_port16[port](0, data, ddr); }
+ u32 do_read_port32(int port) { return m_read_port32[port](); }
+ void do_write_port32(int port, u32 data, u32 ddr) { m_write_port32[port](0, data, ddr); }
+
+ u64 current_cycles() { return machine().time().as_ticks(clock()); }
protected:
+ const char *m_port16_names;
+ const char *m_port32_names;
enum {
CSR_ADF = 0x80,
CSR_ADIE = 0x40,
@@ -42,25 +68,68 @@ class sh7042_device : public sh2_device
virtual void device_start() override;
virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
private:
+ required_device m_intc;
+ required_device m_adc;
+ required_device m_cmt;
+ required_device m_porta;
+ required_device m_portb;
+ required_device m_portc;
+ required_device m_portd;
+ required_device m_porte;
+ required_device m_portf;
+
devcb_read16::array<8> m_read_adc;
devcb_write_line::array<2> m_sci_tx;
+ devcb_read16::array<4> m_read_port16;
+ devcb_write16::array<4> m_write_port16;
+ devcb_read32::array<2> m_read_port32;
+ devcb_write32::array<2> m_write_port32;
+
+ emu_timer *m_event_timer;
+
+ u16 m_pcf_ah;
+ u32 m_pcf_al;
+ u32 m_pcf_b;
+ u16 m_pcf_c;
+ u32 m_pcf_dh;
+ u16 m_pcf_dl;
+ u32 m_pcf_e;
+ u16 m_pcf_if;
void map(address_map &map);
- // ADC section
- uint16_t m_addr[8];
- uint8_t m_adcsr, m_adcr;
-
u16 adc_default(int adc);
- u16 addr_r(offs_t offset);
- u8 adcsr_r();
- u8 adcr_r();
- void adcsr_w(u8 data);
- void adcr_w(u8 data);
-
+ u16 port16_default_r(int port);
+ void port16_default_w(int port, u16 data);
+ u32 port32_default_r(int port);
+ void port32_default_w(int port, u32 data);
+
+ void add_event(u64 &event_time, u64 new_event);
+ void recompute_timer(u64 event_time);
+ TIMER_CALLBACK_MEMBER(event_timer_tick);
+ void internal_update(u64 current_time);
+
void do_sci_w(int sci, int state);
+
+ u16 pcf_ah_r();
+ void pcf_ah_w(offs_t, u16 data, u16 mem_mask);
+ u32 pcf_al_r();
+ void pcf_al_w(offs_t, u32 data, u32 mem_mask);
+ u32 pcf_b_r();
+ void pcf_b_w(offs_t, u32 data, u32 mem_mask);
+ u16 pcf_c_r();
+ void pcf_c_w(offs_t, u16 data, u16 mem_mask);
+ u32 pcf_dh_r();
+ void pcf_dh_w(offs_t, u32 data, u32 mem_mask);
+ u16 pcf_dl_r();
+ void pcf_dl_w(offs_t, u16 data, u16 mem_mask);
+ u32 pcf_e_r();
+ void pcf_e_w(offs_t, u32 data, u32 mem_mask);
+ u16 pcf_if_r();
+ void pcf_if_w(offs_t, u16 data, u16 mem_mask);
};
class sh7043_device : public sh7042_device
diff --git a/src/devices/cpu/sh/sh_adc.cpp b/src/devices/cpu/sh/sh_adc.cpp
new file mode 100644
index 0000000000000..d9e1da0192102
--- /dev/null
+++ b/src/devices/cpu/sh/sh_adc.cpp
@@ -0,0 +1,315 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+#include "emu.h"
+#include "sh_adc.h"
+#include "sh7042.h"
+#include "sh_intc.h"
+
+// Verbosity level
+// 0 = no messages
+// 1 = everything
+static constexpr int V = 0;
+
+DEFINE_DEVICE_TYPE(SH_ADC, sh_adc_device, "sh_adc", "SH2/704x ADC")
+
+sh_adc_device::sh_adc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SH_ADC, tag, owner, clock),
+ m_cpu(*this, finder_base::DUMMY_TAG),
+ m_intc(*this, finder_base::DUMMY_TAG),
+ m_intc_vector(0), m_adcsr(0), m_adcr(0), m_register_mask(0), m_trigger(0), m_start_mode(0), m_start_channel(0),
+ m_end_channel(0), m_start_count(0), m_mode(0), m_channel(0), m_count(0), m_analog_powered(false), m_adtrg(false), m_next_event(0)
+{
+ m_suspend_on_interrupt = true;
+ m_register_mask = 7;
+ m_analog_power_control = false;
+}
+
+u16 sh_adc_device::addr_r(offs_t offset)
+{
+ if(V>=1) logerror("addr_r %d %03x\n", offset, m_addr[offset]);
+ return m_addr[offset];
+}
+
+u8 sh_adc_device::adcsr_r()
+{
+ if(V>=1) logerror("adcsr_r %02x\n", m_adcsr);
+ return m_adcsr;
+}
+
+u8 sh_adc_device::adcr_r()
+{
+ if(V>=1) logerror("adcr_r %02x\n", m_adcr);
+ return m_adcr;
+}
+
+void sh_adc_device::adcsr_w(u8 data)
+{
+ if(V>=1) logerror("adcsr_w %02x\n", data);
+ u8 prev = m_adcsr;
+ m_adcsr = (data & 0x7f) | (m_adcsr & data & F_ADF);
+ mode_update();
+ if((prev & F_ADF) && !(m_adcsr & F_ADF)) {
+ if(m_mode & HALTED) {
+ m_mode &= ~HALTED;
+ if(!(m_adcsr & F_ADST)) {
+ sampling();
+ conversion_wait(false, false);
+ } else
+ done();
+ }
+ }
+
+ if(!(prev & F_ADST) && (m_adcsr & F_ADST))
+ start_conversion();
+}
+
+void sh_adc_device::adcr_w(u8 data)
+{
+ if(V>=1) logerror("adcr_w %02x\n", data);
+ m_adcr = data;
+ mode_update();
+}
+
+void sh_adc_device::adtrg_w(int state)
+{
+ if(state != m_adtrg) {
+ m_adtrg = state;
+ if(!m_adtrg && (m_trigger & T_EXT) && !(m_adcsr & F_ADST)) {
+ m_adcsr |= F_ADST;
+ start_conversion();
+ }
+ }
+}
+
+void sh_adc_device::set_suspend(bool suspend)
+{
+}
+
+void sh_adc_device::device_start()
+{
+ save_item(NAME(m_addr));
+ save_item(NAME(m_buf));
+ save_item(NAME(m_adcsr));
+ save_item(NAME(m_adcr));
+ save_item(NAME(m_trigger));
+ save_item(NAME(m_start_mode));
+ save_item(NAME(m_start_channel));
+ save_item(NAME(m_end_channel));
+ save_item(NAME(m_start_count));
+ save_item(NAME(m_suspend_on_interrupt));
+ save_item(NAME(m_analog_power_control));
+ save_item(NAME(m_mode));
+ save_item(NAME(m_channel));
+ save_item(NAME(m_count));
+ save_item(NAME(m_analog_powered));
+ save_item(NAME(m_next_event));
+ save_item(NAME(m_adtrg));
+}
+
+void sh_adc_device::device_reset()
+{
+ memset(m_addr, 0, sizeof(m_addr));
+ memset(m_buf, 0, sizeof(m_buf));
+ m_adcsr = m_adcr = 0;
+ m_trigger = T_SOFT;
+ m_start_mode = IDLE;
+ m_start_channel = m_end_channel = 0;
+ m_start_count = 1;
+ m_mode = IDLE;
+ m_channel = 0;
+ m_count = 0;
+ m_next_event = 0;
+ mode_update();
+ m_analog_powered = !m_analog_power_control;
+ m_adtrg = true;
+}
+
+void sh_adc_device::done()
+{
+ m_mode = IDLE;
+ m_adcsr &= ~F_ADST;
+ if(m_analog_power_control)
+ m_analog_powered = false;
+}
+
+u64 sh_adc_device::internal_update(u64 current_time)
+{
+ if(m_next_event && m_next_event <= current_time) {
+ m_next_event = 0;
+ timeout(current_time);
+ }
+ return m_next_event;
+}
+
+void sh_adc_device::conversion_wait(bool first, bool poweron, u64 current_time)
+{
+ if(current_time)
+ m_next_event = current_time + conversion_time(first, poweron);
+ else {
+ m_next_event = m_cpu->total_cycles() + conversion_time(first, poweron);
+ m_cpu->internal_update();
+ }
+}
+
+void sh_adc_device::buffer_value(int port, int buffer)
+{
+ m_buf[buffer] = m_cpu->do_read_adc(port);
+ if(V>=1) logerror("adc buffer %d -> %d:%03x\n", port, buffer, m_buf[buffer]);
+}
+
+void sh_adc_device::commit_value(int reg, int buffer)
+{
+ reg &= m_register_mask;
+ if(V>=1) logerror("adc commit %d -> %d:%03x\n", buffer, reg, m_buf[buffer]);
+ m_addr[reg] = m_buf[buffer];
+}
+
+void sh_adc_device::sampling()
+{
+ if(m_mode & COUNTED)
+ m_channel = get_channel_index(m_start_count - m_count);
+ if(m_mode & DUAL) {
+ buffer_value(m_channel, 0);
+ buffer_value(m_channel+1, 1);
+ } else
+ buffer_value(m_channel);
+}
+
+void sh_adc_device::start_conversion()
+{
+ m_mode = m_start_mode;
+ m_channel = m_start_channel;
+ m_count = m_start_count;
+ sampling();
+ conversion_wait(true, !m_analog_powered);
+ m_analog_powered = true;
+}
+
+void sh_adc_device::timeout(u64 current_time)
+{
+ if(m_mode & BUFFER) {
+ do_buffering((m_mode & DUAL) && (m_channel & 1));
+ if((m_mode & DUAL) && !(m_channel & 1)) {
+ m_channel++;
+ conversion_wait(false, false, current_time);
+ return;
+ }
+ } else {
+ if(m_mode & DUAL) {
+ if(m_channel & 1)
+ commit_value(m_channel, 1);
+ else {
+ commit_value(m_channel, 0);
+ m_channel++;
+ conversion_wait(false, false, current_time);
+ return;
+ }
+ } else
+ commit_value(m_channel);
+ }
+
+ if(m_mode & ROTATE) {
+ if(m_channel != m_end_channel) {
+ m_channel++;
+ sampling();
+ conversion_wait(false, false, current_time);
+ return;
+ }
+ m_channel = m_start_channel;
+ }
+
+ if(m_mode & COUNTED) {
+ m_count--;
+ if(m_count) {
+ sampling();
+ conversion_wait(false, false, current_time);
+ return;
+ }
+ }
+
+ m_adcsr |= F_ADF;
+ if(m_adcsr & F_ADIE)
+ m_intc->internal_interrupt(m_intc_vector);
+
+ if(m_mode & REPEAT) {
+ if(m_suspend_on_interrupt && (m_adcsr & F_ADIE)) {
+ m_mode |= HALTED;
+ return;
+ }
+ m_channel = m_start_channel;
+ m_count = m_start_count;
+ sampling();
+ conversion_wait(false, false, current_time);
+ return;
+ }
+
+ done();
+}
+
+int sh_adc_device::conversion_time(bool first, bool poweron)
+{
+ int tm = m_adcsr & 0x10 ? 44 : 24;
+ if(first)
+ tm += m_adcsr & 0x10 ? 20 : 10;
+ if(poweron)
+ tm += 200;
+ return tm;
+}
+
+void sh_adc_device::mode_update()
+{
+ m_trigger = 1 << ((m_adcr >> 4) & 3);
+ m_analog_power_control = !(m_adcr & 0x40);
+
+ m_mode = ACTIVE | (m_adcr & 0x08 ? REPEAT : 0);
+
+ if(m_adcsr & 0x03) {
+ m_mode |= BUFFER;
+
+ }
+
+ if(m_adcsr & 0x08) {
+ m_mode |= ROTATE;
+ m_start_channel = 0;
+ if(m_adcr & 0x04) {
+ m_mode |= DUAL;
+ m_end_channel = (m_adcsr & 6)+1;
+ } else
+ m_end_channel = m_adcsr & 7;
+ } else
+ m_start_channel = m_end_channel = m_adcsr & 7;
+
+}
+
+void sh_adc_device::do_buffering(int buffer)
+{
+ if((m_mode & COUNTED) && m_channel >= 2) {
+ commit_value(m_channel, buffer);
+ return;
+ }
+ switch(m_adcsr & 3) {
+ case 0:
+ commit_value(m_channel, buffer);
+ break;
+ case 1:
+ m_addr[1] = m_addr[0];
+ commit_value(0, buffer);
+ break;
+ case 2:
+ m_addr[2+buffer] = m_addr[buffer];
+ commit_value(buffer, buffer);
+ break;
+ case 3:
+ m_addr[3] = m_addr[2];
+ m_addr[2] = m_addr[1];
+ m_addr[1] = m_addr[0];
+ commit_value(0, buffer);
+ break;
+ }
+}
+
+int sh_adc_device::get_channel_index(int count)
+{
+ abort();
+}
diff --git a/src/devices/cpu/sh/sh_adc.h b/src/devices/cpu/sh/sh_adc.h
new file mode 100644
index 0000000000000..9a48e3f804b2c
--- /dev/null
+++ b/src/devices/cpu/sh/sh_adc.h
@@ -0,0 +1,100 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_adc.h
+
+ SH Analog to Digital Converter subsystem
+
+
+***************************************************************************/
+
+#ifndef MAME_CPU_SH_SH_ADC_H
+#define MAME_CPU_SH_SH_ADC_H
+
+#pragma once
+
+class sh7042_device;
+class sh_intc_device;
+
+class sh_adc_device : public device_t {
+public:
+ sh_adc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+
+ template sh_adc_device(const machine_config &mconfig, const char *tag, device_t *owner,
+ T &&cpu, U &&intc, int vect) :
+ sh_adc_device(mconfig, tag, owner)
+ {
+ m_cpu.set_tag(std::forward(cpu));
+ m_intc.set_tag(std::forward(intc));
+ m_intc_vector = vect;
+ }
+
+ u16 addr_r(offs_t offset);
+ u8 adcsr_r();
+ u8 adcr_r();
+ void adcsr_w(u8 data);
+ void adcr_w(u8 data);
+ void adtrg_w(int state);
+
+ void set_suspend(bool suspend);
+ u64 internal_update(u64 current_time);
+
+protected:
+ required_device m_cpu;
+ required_device m_intc;
+ int m_intc_vector;
+
+ enum {
+ T_SOFT = 1<<0,
+ T_TPU = 1<<1,
+ T_TIMER = 1<<2,
+ T_EXT = 1<<3
+ };
+
+ enum {
+ F_ADF = 0x80,
+ F_ADIE = 0x40,
+ F_ADST = 0x20
+ };
+
+ enum {
+ IDLE = 0,
+ ACTIVE = 1,
+ HALTED = 2,
+ REPEAT = 4,
+ ROTATE = 8,
+ DUAL = 16,
+ BUFFER = 32,
+ COUNTED = 64
+ };
+
+ u16 m_addr[8], m_buf[2];
+ u8 m_adcsr, m_adcr;
+ int m_register_mask;
+ int m_trigger, m_start_mode, m_start_channel, m_end_channel, m_start_count;
+ bool m_suspend_on_interrupt, m_analog_power_control;
+ int m_mode, m_channel, m_count;
+ bool m_analog_powered, m_adtrg;
+ u64 m_next_event;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ void sampling();
+ void start_conversion();
+ void conversion_wait(bool first, bool poweron, u64 current_time = 0);
+ void buffer_value(int port, int buffer = 0);
+ void commit_value(int reg, int buffer = 0);
+ void timeout(u64 current_time);
+ void done();
+
+ int conversion_time(bool first, bool poweron);
+ void mode_update();
+ void do_buffering(int buffer);
+ int get_channel_index(int count);
+};
+
+DECLARE_DEVICE_TYPE(SH_ADC, sh_adc_device)
+
+#endif // MAME_CPU_SH_SH_ADC_H
diff --git a/src/devices/cpu/sh/sh_cmt.cpp b/src/devices/cpu/sh/sh_cmt.cpp
new file mode 100644
index 0000000000000..1e659080e7533
--- /dev/null
+++ b/src/devices/cpu/sh/sh_cmt.cpp
@@ -0,0 +1,197 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_cmt.h
+
+ SH Compare/Match timer subsystem
+
+
+***************************************************************************/
+
+#include "emu.h"
+#include "sh7042.h"
+#include "sh_intc.h"
+
+DEFINE_DEVICE_TYPE(SH_CMT, sh_cmt_device, "sh_cmt", "SH2/704x CMT")
+
+sh_cmt_device::sh_cmt_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SH_CMT, tag, owner, clock),
+ m_cpu(*this, finder_base::DUMMY_TAG),
+ m_intc(*this, finder_base::DUMMY_TAG),
+ m_intc_vector{0, 0},
+ m_str(0),
+ m_csr{ 0, 0 },
+ m_cnt{ 0, 0 },
+ m_cor{ 0xffff, 0xffff }
+{
+}
+
+void sh_cmt_device::device_start()
+{
+}
+
+void sh_cmt_device::device_reset()
+{
+}
+
+u64 sh_cmt_device::internal_update(u64 current_time)
+{
+ u64 next = 0;
+ for(int i = 0; i != 2; i++) {
+ if(m_next_event[i] && current_time >= m_next_event[i]) {
+ m_csr[i] |= 0x80;
+ if(BIT(m_csr[i], 6))
+ m_intc->internal_interrupt(m_intc_vector[i]);
+ cnt_update(i, current_time);
+ }
+ if(!next || (m_next_event[i] && m_next_event[i] < next))
+ next = m_next_event[i];
+ }
+ return next;
+}
+
+
+u16 sh_cmt_device::cmstr_r()
+{
+ return m_str;
+}
+
+u16 sh_cmt_device::cmcsr0_r()
+{
+ return m_csr[0];
+}
+
+u16 sh_cmt_device::cmcnt0_r()
+{
+ cnt_update(0, m_cpu->current_cycles());
+ return m_cnt[0];
+}
+
+u16 sh_cmt_device::cmcor0_r()
+{
+ return m_cor[0];
+}
+
+u16 sh_cmt_device::cmcsr1_r()
+{
+ return m_csr[1];
+}
+
+u16 sh_cmt_device::cmcnt1_r()
+{
+ cnt_update(1, m_cpu->current_cycles());
+ return m_cnt[1];
+}
+
+u16 sh_cmt_device::cmcor1_r()
+{
+ return m_cor[1];
+}
+
+void sh_cmt_device::cmcsr0_w(offs_t, u16 data, u16 mem_mask)
+{
+ csr_w(0, data, mem_mask);
+}
+
+void sh_cmt_device::cmcsr1_w(offs_t, u16 data, u16 mem_mask)
+{
+ csr_w(1, data, mem_mask);
+}
+
+void sh_cmt_device::cmcnt0_w(offs_t, u16 data, u16 mem_mask)
+{
+ cnt_w(0, data, mem_mask);
+}
+
+void sh_cmt_device::cmcnt1_w(offs_t, u16 data, u16 mem_mask)
+{
+ cnt_w(1, data, mem_mask);
+}
+
+void sh_cmt_device::cmcor0_w(offs_t, u16 data, u16 mem_mask)
+{
+ cor_w(0, data, mem_mask);
+}
+
+void sh_cmt_device::cmcor1_w(offs_t, u16 data, u16 mem_mask)
+{
+ cor_w(1, data, mem_mask);
+}
+
+void sh_cmt_device::cmstr_w(offs_t, u16 data, u16 mem_mask)
+{
+ cnt_update(0, m_cpu->current_cycles());
+ cnt_update(1, m_cpu->current_cycles());
+ u16 old = m_str;
+ COMBINE_DATA(&m_str);
+ logerror("active %c %c\n", m_str & 1 ? '0' : '-', m_str & 2 ? '1' : '-');
+ for(int i=0; i != 2; i++)
+ if(!BIT(old, i) && BIT(m_str, i))
+ clock_start(i);
+ else if(!BIT(m_str, i))
+ m_next_event[i] = 0;
+ m_cpu->internal_update();
+}
+
+void sh_cmt_device::csr_w(int reg, u16 data, u16 mem_mask)
+{
+ cnt_update(reg, m_cpu->current_cycles());
+ u16 old = m_csr[reg];
+ COMBINE_DATA(&m_csr[reg]);
+ if(!(old & 0x80))
+ m_csr[reg] &= ~0x80;
+ if((old ^ m_csr[reg]) & 0x7f)
+ logerror("csr_w %d f=%d ie=%d div=%d\n", reg, BIT(m_csr[reg], 7), BIT(m_csr[reg], 6), 8 << (2*BIT(m_csr[reg], 0, 2)));
+}
+
+void sh_cmt_device::cnt_w(int reg, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_cnt[reg]);
+ logerror("cnt_w %d, %04x\n", reg, m_cnt[reg]);
+ if((m_str >> reg) & 1) {
+ compute_next_event(reg);
+ m_cpu->internal_update();
+ }
+}
+
+void sh_cmt_device::cor_w(int reg, u16 data, u16 mem_mask)
+{
+ cnt_update(reg, m_cpu->current_cycles());
+ COMBINE_DATA(&m_cor[reg]);
+ logerror("cor_w %d, %04x\n", reg, m_cor[reg]);
+ if((m_str >> reg) & 1) {
+ compute_next_event(reg);
+ m_cpu->internal_update();
+ }
+}
+
+void sh_cmt_device::clock_start(int clk)
+{
+ logerror("start clock %d %dHz\n", clk, (m_cpu->clock() >> (3 + 2*BIT(m_csr[clk], 0, 2))) / (m_cor[clk] + 1));
+ compute_next_event(clk);
+}
+
+void sh_cmt_device::compute_next_event(int clk)
+{
+ u64 step1 = 1 << (3 + 2*BIT(m_csr[clk], 0, 2));
+ u64 time = m_cpu->current_cycles();
+ if(time & (step1 - 1))
+ time = (time | (step1 - 1)) + 1;
+ s32 counts = m_cor[clk] + 1 - m_cnt[clk];
+ if(counts < 0)
+ counts += 0x10000;
+ time += step1 * counts;
+ m_next_event[clk] = time;
+}
+
+void sh_cmt_device::cnt_update(int clk, u64 current_time)
+{
+ if(!((m_str >> clk) & 1))
+ return;
+ u64 step = (m_cor[clk] + 1) << (3 + 2*BIT(m_csr[clk], 0, 2));
+ while(current_time >= m_next_event[clk])
+ m_next_event[clk] += step;
+ u64 delta = m_next_event[clk] - current_time;
+ m_cnt[clk] = m_cor[clk] - ((delta - 1) >> (3 + 2*BIT(m_csr[clk], 0, 2)));
+}
diff --git a/src/devices/cpu/sh/sh_cmt.h b/src/devices/cpu/sh/sh_cmt.h
new file mode 100644
index 0000000000000..e365be37fb1ed
--- /dev/null
+++ b/src/devices/cpu/sh/sh_cmt.h
@@ -0,0 +1,75 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_cmt.h
+
+ SH Compare/Match timer subsystem
+
+
+***************************************************************************/
+
+#ifndef MAME_CPU_SH_SH_CMT_H
+#define MAME_CPU_SH_SH_CMT_H
+
+#pragma once
+
+class sh7042_device;
+class sh_intc_device;
+
+class sh_cmt_device : public device_t {
+public:
+ sh_cmt_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+
+ template sh_cmt_device(const machine_config &mconfig, const char *tag, device_t *owner,
+ T &&cpu, U &&intc, int vect0, int vect1) :
+ sh_cmt_device(mconfig, tag, owner)
+ {
+ m_cpu.set_tag(std::forward(cpu));
+ m_intc.set_tag(std::forward(intc));
+ m_intc_vector[0] = vect0;
+ m_intc_vector[1] = vect1;
+ }
+
+ u64 internal_update(u64 current_time);
+
+ u16 cmstr_r();
+ void cmstr_w(offs_t, u16 data, u16 mem_mask);
+ u16 cmcsr0_r();
+ void cmcsr0_w(offs_t, u16 data, u16 mem_mask);
+ u16 cmcnt0_r();
+ void cmcnt0_w(offs_t, u16 data, u16 mem_mask);
+ u16 cmcor0_r();
+ void cmcor0_w(offs_t, u16 data, u16 mem_mask);
+ u16 cmcsr1_r();
+ void cmcsr1_w(offs_t, u16 data, u16 mem_mask);
+ u16 cmcnt1_r();
+ void cmcnt1_w(offs_t, u16 data, u16 mem_mask);
+ u16 cmcor1_r();
+ void cmcor1_w(offs_t, u16 data, u16 mem_mask);
+
+protected:
+ required_device m_cpu;
+ required_device m_intc;
+ std::array m_next_event;
+ std::array m_intc_vector;
+ u16 m_str;
+ std::array m_csr;
+ std::array m_cnt;
+ std::array m_cor;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ void csr_w(int reg, u16 data, u16 mem_mask);
+ void cnt_w(int reg, u16 data, u16 mem_mask);
+ void cor_w(int reg, u16 data, u16 mem_mask);
+
+ void clock_start(int clk);
+ void compute_next_event(int clk);
+ void cnt_update(int clk, u64 current_time);
+};
+
+DECLARE_DEVICE_TYPE(SH_CMT, sh_cmt_device)
+
+#endif // MAME_CPU_SH_SH_CMT_H
diff --git a/src/devices/cpu/sh/sh_intc.cpp b/src/devices/cpu/sh/sh_intc.cpp
new file mode 100644
index 0000000000000..d13f8f55853fe
--- /dev/null
+++ b/src/devices/cpu/sh/sh_intc.cpp
@@ -0,0 +1,75 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_intc.cpp
+
+ SH interrupt controllers family
+
+***************************************************************************/
+
+#include "emu.h"
+#include "sh_intc.h"
+
+#include "sh7042.h"
+
+DEFINE_DEVICE_TYPE(SH_INTC, sh_intc_device, "sh_intc", "SH interrupt controller")
+
+sh_intc_device::sh_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SH_INTC, tag, owner, clock),
+ m_cpu(*this, finder_base::DUMMY_TAG)
+{
+}
+
+void sh_intc_device::device_start()
+{
+}
+
+void sh_intc_device::device_reset()
+{
+}
+
+int sh_intc_device::interrupt_taken(int vector)
+{
+ return 0;
+}
+
+void sh_intc_device::internal_interrupt(int vector)
+{
+ logerror("Internal interrupt %d\n", vector);
+}
+
+void sh_intc_device::set_input(int inputnum, int state)
+{
+}
+
+u16 sh_intc_device::icr_r()
+{
+ return 0;
+}
+
+void sh_intc_device::icr_w(offs_t, u16 data, u16 mem_mask)
+{
+ logerror("icr_w %04x @ %04x\n", data, mem_mask);
+}
+
+u16 sh_intc_device::isr_r()
+{
+ return 0;
+}
+
+void sh_intc_device::isr_w(offs_t, u16 data, u16 mem_mask)
+{
+ logerror("isr_w %04x @ %04x\n", data, mem_mask);
+}
+
+u16 sh_intc_device::ipr_r(offs_t offset)
+{
+ return 0;
+}
+
+void sh_intc_device::ipr_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ logerror("ipr_w %x, %04x @ %04x\n", offset, data, mem_mask);
+}
+
diff --git a/src/devices/cpu/sh/sh_intc.h b/src/devices/cpu/sh/sh_intc.h
new file mode 100644
index 0000000000000..b93444d8e3254
--- /dev/null
+++ b/src/devices/cpu/sh/sh_intc.h
@@ -0,0 +1,47 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_intc.h
+
+ SH interrupt controllers family
+
+***************************************************************************/
+
+#ifndef MAME_CPU_SH_SH_INTC_H
+#define MAME_CPU_SH_SH_INTC_H
+
+#pragma once
+
+class sh7042_device;
+
+class sh_intc_device : public device_t {
+public:
+ sh_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ template sh_intc_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu) :
+ sh_intc_device(mconfig, tag, owner)
+ {
+ m_cpu.set_tag(std::forward(cpu));
+ }
+
+ int interrupt_taken(int vector);
+ void internal_interrupt(int vector);
+ void set_input(int inputnum, int state);
+
+ u16 icr_r();
+ void icr_w(offs_t, u16 data, u16 mem_mask);
+ u16 isr_r();
+ void isr_w(offs_t, u16 data, u16 mem_mask);
+ u16 ipr_r(offs_t offset);
+ void ipr_w(offs_t offset, u16 data, u16 mem_mask);
+
+protected:
+ required_device m_cpu;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+};
+
+DECLARE_DEVICE_TYPE(SH_INTC, sh_intc_device)
+
+#endif // MAME_CPU_SH_SH_INTC_H
diff --git a/src/devices/cpu/sh/sh_port.cpp b/src/devices/cpu/sh/sh_port.cpp
new file mode 100644
index 0000000000000..ddd93a1a4e23e
--- /dev/null
+++ b/src/devices/cpu/sh/sh_port.cpp
@@ -0,0 +1,109 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_port.h
+
+ SH i/o ports
+
+***************************************************************************/
+
+#include "emu.h"
+#include "sh_intc.h"
+
+#include "sh7042.h"
+
+DEFINE_DEVICE_TYPE(SH_PORT16, sh_port16_device, "sh_port16", "SH 16-bits port")
+DEFINE_DEVICE_TYPE(SH_PORT32, sh_port32_device, "sh_port32", "SH 32-bits port")
+
+sh_port16_device::sh_port16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SH_PORT16, tag, owner, clock),
+ m_cpu(*this, finder_base::DUMMY_TAG)
+{
+}
+
+void sh_port16_device::device_start()
+{
+ m_io = m_default_io;
+ save_item(NAME(m_dr));
+ save_item(NAME(m_io));
+}
+
+void sh_port16_device::device_reset()
+{
+}
+
+u16 sh_port16_device::dr_r()
+{
+ if(~m_io & ~m_mask)
+ return (m_dr & m_io) | (m_cpu->do_read_port16(m_index) & ~m_io);
+ return m_dr;
+}
+
+void sh_port16_device::dr_w(offs_t, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_dr);
+ m_dr &= ~m_mask;
+ if(m_io)
+ m_cpu->do_write_port16(m_index, m_dr & m_io, m_io);
+}
+
+u16 sh_port16_device::io_r()
+{
+ return m_io;
+}
+
+void sh_port16_device::io_w(offs_t, u16 data, u16 mem_mask)
+{
+ COMBINE_DATA(&m_io);
+ m_io &= ~m_mask;
+ if(m_io)
+ m_cpu->do_write_port16(m_index, m_dr & m_io, m_io);
+}
+
+
+sh_port32_device::sh_port32_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SH_PORT32, tag, owner, clock),
+ m_cpu(*this, finder_base::DUMMY_TAG)
+{
+}
+
+void sh_port32_device::device_start()
+{
+ m_io = m_default_io;
+ save_item(NAME(m_dr));
+ save_item(NAME(m_io));
+}
+
+void sh_port32_device::device_reset()
+{
+}
+
+u32 sh_port32_device::dr_r()
+{
+ if((~m_io) & (~m_mask))
+ return (m_dr & m_io) | (m_cpu->do_read_port32(m_index) & ~m_io);
+ return m_dr;
+}
+
+void sh_port32_device::dr_w(offs_t, u32 data, u32 mem_mask)
+{
+ COMBINE_DATA(&m_dr);
+ m_dr &= ~m_mask;
+ if(m_io)
+ m_cpu->do_write_port32(m_index, m_dr & m_io, m_io);
+}
+
+u32 sh_port32_device::io_r()
+{
+ return m_io;
+}
+
+void sh_port32_device::io_w(offs_t, u32 data, u32 mem_mask)
+{
+ COMBINE_DATA(&m_io);
+ m_io &= ~m_mask;
+ if(m_io)
+ m_cpu->do_write_port32(m_index, m_dr & m_io, m_io);
+}
+
diff --git a/src/devices/cpu/sh/sh_port.h b/src/devices/cpu/sh/sh_port.h
new file mode 100644
index 0000000000000..ec2a19228ee59
--- /dev/null
+++ b/src/devices/cpu/sh/sh_port.h
@@ -0,0 +1,75 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+/***************************************************************************
+
+ sh_port.h
+
+ SH i/o ports
+
+***************************************************************************/
+
+#ifndef MAME_CPU_SH_SH_PORT_H
+#define MAME_CPU_SH_SH_PORT_H
+
+#pragma once
+
+class sh7042_device;
+
+class sh_port16_device : public device_t {
+public:
+ sh_port16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ template sh_port16_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu, int index, u16 default_io, u16 mask) :
+ sh_port16_device(mconfig, tag, owner)
+ {
+ m_index = index;
+ m_default_io = default_io;
+ m_mask = mask;
+ m_cpu.set_tag(std::forward(cpu));
+ }
+
+ u16 dr_r();
+ void dr_w(offs_t, u16 data, u16 mem_mask);
+ u16 io_r();
+ void io_w(offs_t, u16 data, u16 mem_mask);
+
+protected:
+ required_device m_cpu;
+ int m_index;
+ u16 m_default_io, m_mask;
+ u16 m_dr, m_io;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+};
+
+class sh_port32_device : public device_t {
+public:
+ sh_port32_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ template sh_port32_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu, int index, u32 default_io, u32 mask) :
+ sh_port32_device(mconfig, tag, owner)
+ {
+ m_index = index;
+ m_default_io = default_io;
+ m_mask = mask;
+ m_cpu.set_tag(std::forward(cpu));
+ }
+
+ u32 dr_r();
+ void dr_w(offs_t, u32 data, u32 mem_mask);
+ u32 io_r();
+ void io_w(offs_t, u32 data, u32 mem_mask);
+
+protected:
+ required_device m_cpu;
+ int m_index;
+ u32 m_default_io, m_mask;
+ u32 m_dr, m_io;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+};
+
+DECLARE_DEVICE_TYPE(SH_PORT16, sh_port16_device)
+DECLARE_DEVICE_TYPE(SH_PORT32, sh_port32_device)
+
+#endif // MAME_CPU_SH_SH_PORT_H
diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp
index 3f822838894fb..62c8954e93e10 100644
--- a/src/devices/imagedev/midiin.cpp
+++ b/src/devices/imagedev/midiin.cpp
@@ -10,8 +10,10 @@
#include "emu.h"
#include "midiin.h"
+
#include "osdepend.h"
+
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
@@ -183,11 +185,9 @@ std::pair midiin_device::call_load()
}
else
{
- m_midi = machine().osd().create_midi_device();
-
- if (!m_midi->open_input(filename()))
+ m_midi = machine().osd().create_midi_input(filename());
+ if (!m_midi)
{
- m_midi.reset();
return std::make_pair(image_error::UNSPECIFIED, std::string());
}
@@ -202,11 +202,7 @@ std::pair midiin_device::call_load()
void midiin_device::call_unload()
{
- if (m_midi)
- {
- m_midi->close();
- }
- else
+ if (!m_midi)
{
// send "all notes off" CC if unloading a MIDI file
for (u8 channel = 0; channel < 0x10; channel++)
diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h
index 2bcba3720cccb..d557a47b7c412 100644
--- a/src/devices/imagedev/midiin.h
+++ b/src/devices/imagedev/midiin.h
@@ -15,6 +15,8 @@
#include "diserial.h"
+#include "interface/midiport.h"
+
#include
#include
#include
@@ -67,7 +69,7 @@ class midiin_device : public device_t,
void xmit_char(uint8_t data);
- std::unique_ptr m_midi;
+ std::unique_ptr m_midi;
required_ioport m_config;
emu_timer *m_timer;
devcb_write_line m_input_cb;
diff --git a/src/devices/imagedev/midiout.cpp b/src/devices/imagedev/midiout.cpp
index 89ac487233266..67efce46f93e1 100644
--- a/src/devices/imagedev/midiout.cpp
+++ b/src/devices/imagedev/midiout.cpp
@@ -10,8 +10,10 @@
#include "emu.h"
#include "midiout.h"
+
#include "osdepend.h"
+
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
@@ -57,11 +59,9 @@ void midiout_device::device_reset()
std::pair midiout_device::call_load()
{
- m_midi = machine().osd().create_midi_device();
-
- if (!m_midi->open_output(filename()))
+ m_midi = machine().osd().create_midi_output(filename());
+ if (!m_midi)
{
- m_midi.reset();
return std::make_pair(image_error::UNSPECIFIED, std::string());
}
@@ -74,11 +74,7 @@ std::pair midiout_device::call_load()
void midiout_device::call_unload()
{
- if (m_midi)
- {
- m_midi->close();
- m_midi.reset();
- }
+ m_midi.reset();
}
void midiout_device::rcv_complete() // Rx completed receiving byte
diff --git a/src/devices/imagedev/midiout.h b/src/devices/imagedev/midiout.h
index 67a572fd5e241..e22c92e87a49e 100644
--- a/src/devices/imagedev/midiout.h
+++ b/src/devices/imagedev/midiout.h
@@ -15,6 +15,8 @@
#include "diserial.h"
+#include "interface/midiport.h"
+
#include
#include
#include
@@ -59,7 +61,7 @@ class midiout_device : public device_t,
virtual void rcv_complete() override; // Rx completed receiving byte
private:
- std::unique_ptr m_midi;
+ std::unique_ptr m_midi;
};
// device type definition
diff --git a/src/devices/machine/1801vp128.cpp b/src/devices/machine/1801vp128.cpp
new file mode 100644
index 0000000000000..58d399dbd2df9
--- /dev/null
+++ b/src/devices/machine/1801vp128.cpp
@@ -0,0 +1,785 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/**********************************************************************
+
+ 1801VP1-128 gate array (MFM codec for floppy controllers)
+
+ https://github.com/1801BM1/k1801/tree/master/128
+ https://felixl.com/UKNC_FDD_1801vp1-128
+ https://zx-pk.ru/threads/20406-emulyatsiya-1801vp1-128-v-plis.html
+
+ To do:
+ - DRQ status in read and write modes is tracked separately (TR bit)
+ - missing MFM clock is added by MFM encoder for every 00 sequence
+ - deep internals of CRC, GDR bits; read/write mode switching
+ - optional external timer for PY device
+
+**********************************************************************/
+
+#include "emu.h"
+#include "1801vp128.h"
+
+#define LOG_WARN (1U << 1) // Show warnings
+#define LOG_SHIFT (1U << 2) // Shows shift register contents
+#define LOG_REGS (1U << 6) // Register I/O
+#define LOG_STATE (1U << 11) // State machine
+#define LOG_LIVE (1U << 12) // Live states
+
+//#define VERBOSE (LOG_GENERAL | LOG_REGS | LOG_STATE)
+#include "logmacro.h"
+
+#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
+#define LOGSHIFT(...) LOGMASKED(LOG_SHIFT, __VA_ARGS__)
+#define LOGREGS(...) LOGMASKED(LOG_REGS, __VA_ARGS__)
+#define LOGLIVE(...) LOGMASKED(LOG_LIVE, __VA_ARGS__)
+#define LOGSTATE(...) LOGMASKED(LOG_STATE, __VA_ARGS__)
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(K1801VP128, k1801vp128_device, "1801vp1-128", "1801VP1-128")
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// k1801vp128_device - constructor
+//-------------------------------------------------
+
+k1801vp128_device::k1801vp128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, K1801VP128, tag, owner, clock)
+ , m_connectors(*this, "%u", 0U)
+ , m_read_ds(*this, -1)
+{
+ memset(&cur_live, 0x00, sizeof(cur_live));
+ cur_live.tm = attotime::never;
+ cur_live.state = IDLE;
+ cur_live.next_state = -1;
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void k1801vp128_device::device_start()
+{
+ for (int i = 0; i != 4; i++)
+ {
+ flopi[i].tm = timer_alloc(FUNC(k1801vp128_device::update_floppy), this);
+ flopi[i].id = i;
+ if (m_connectors[i])
+ {
+ flopi[i].dev = m_connectors[i]->get_device();
+ if (flopi[i].dev != nullptr)
+ flopi[i].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&k1801vp128_device::index_callback, this));
+ }
+ else
+ flopi[i].dev = nullptr;
+
+ flopi[i].main_state = IDLE;
+ flopi[i].sub_state = IDLE;
+ flopi[i].live = false;
+ }
+
+ m_wbuf = m_rbuf = 0;
+
+ // register for state saving
+ save_item(NAME(selected_drive));
+ save_item(NAME(m_cr));
+ save_item(NAME(m_sr));
+ save_item(NAME(m_rbuf));
+ save_item(NAME(m_wbuf));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void k1801vp128_device::device_reset()
+{
+ for (int i = 0; i < 4; i++)
+ {
+ flopi[i].main_state = IDLE;
+ flopi[i].sub_state = IDLE;
+ flopi[i].live = false;
+ }
+ live_abort();
+ m_cr = m_sr = 0;
+ set_ds(-1);
+}
+
+//-------------------------------------------------
+// read - register read
+//-------------------------------------------------
+
+uint16_t k1801vp128_device::read(offs_t offset)
+{
+ uint16_t data = 0;
+
+ switch (offset & 1)
+ {
+ case 0:
+ data = m_sr;
+ if (selected_drive != -1)
+ {
+ floppy_info &fi = flopi[selected_drive];
+ data = (fi.dev->trk00_r() ^ 1) | (fi.dev->ready_r() << 1) | (fi.dev->wpt_r() << 2) | (fi.dev->idx_r() << 15) | m_sr;
+ }
+ break;
+
+ case 1:
+ data = m_rbuf;
+ if (!machine().side_effects_disabled())
+ {
+ m_sr &= ~CSR_R_TR;
+ if (selected_drive != -1)
+ {
+ floppy_info &fi = flopi[selected_drive];
+ if (fi.main_state == WRITE_DATA)
+ {
+ // semi-read mode
+ live_abort();
+ fi.main_state = READ_DATA;
+ fi.sub_state = SCAN_ID;
+ read_data_continue(fi);
+ }
+ }
+ }
+ break;
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// write - register write
+//-------------------------------------------------
+
+void k1801vp128_device::write(offs_t offset, uint16_t data)
+{
+ LOGREGS("%s W %06o <- %06o\n", machine().describe_context(), 0177130 + (offset << 1), data);
+
+ switch (offset & 1)
+ {
+ case 0:
+ set_ds((int16_t)m_read_ds(data & (CSR_W_DS | CSR_W_REZ)));
+ if (selected_drive != -1)
+ {
+ floppy_info &fi = flopi[selected_drive];
+ fi.dev->mon_w(!BIT(data, 4));
+ fi.dev->ss_w(BIT(data, 5));
+ if (BIT(data, 7))
+ {
+ LOG("COMMAND STEP %d %s\n", fi.id, BIT(data, 6) ? "+1" : "-1");
+ execute_command(CMD_SEEK);
+ }
+ if (BIT(m_cr ^ data, 8) && !BIT(data, 8))
+ {
+ LOG("COMMAND READ drive %d c:h %d:%d\n", selected_drive, fi.dev->get_cyl(), BIT(data, 5));
+ m_sr &= ~CSR_R_TR;
+ execute_command(CMD_READ);
+ }
+ }
+ m_cr = data;
+ break;
+
+ case 1:
+ m_wbuf = data;
+ m_sr &= ~CSR_R_TR;
+ if (selected_drive != -1)
+ {
+ floppy_info &fi = flopi[selected_drive];
+ if (fi.main_state != WRITE_DATA)
+ {
+ LOG("COMMAND WRITE drive %d c:h %d:%d\n", selected_drive, fi.dev->get_cyl(), BIT(m_cr, 5));
+ execute_command(CMD_WRITE);
+ }
+ }
+ break;
+ }
+}
+
+void k1801vp128_device::execute_command(int command)
+{
+ live_abort();
+
+ switch (command)
+ {
+ case CMD_READ:
+ read_data_start(flopi[selected_drive]);
+ break;
+
+ case CMD_WRITE:
+ write_data_start(flopi[selected_drive]);
+ break;
+
+ case CMD_SEEK:
+ seek_start(flopi[selected_drive]);
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// update_tick - pump the device life cycle
+//-------------------------------------------------
+
+TIMER_CALLBACK_MEMBER(k1801vp128_device::update_floppy)
+{
+ live_sync();
+
+ floppy_info &fi = flopi[param];
+ switch (fi.sub_state)
+ {
+ case SEEK_WAIT_STEP_SIGNAL_TIME:
+ fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME_DONE;
+ break;
+ case SEEK_WAIT_STEP_TIME:
+ fi.sub_state = SEEK_WAIT_STEP_TIME_DONE;
+ break;
+ }
+
+ general_continue(fi);
+}
+
+void k1801vp128_device::live_start(floppy_info &fi, int state)
+{
+ cur_live.tm = machine().time();
+ cur_live.state = state;
+ cur_live.next_state = -1;
+ cur_live.fi = &fi;
+ cur_live.shift_reg = 0;
+ cur_live.crc = 0xffff;
+ cur_live.crc_init = false;
+ cur_live.bit_counter = 0;
+ cur_live.data_separator_phase = false;
+ cur_live.data_reg = 0;
+ cur_live.data_bit_context = false;
+ cur_live.pll.reset(cur_live.tm);
+ cur_live.pll.set_clock(attotime::from_hz(500000));
+ checkpoint_live = cur_live;
+ fi.live = true;
+
+ live_run();
+}
+
+void k1801vp128_device::checkpoint()
+{
+ if (cur_live.fi)
+ cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
+ checkpoint_live = cur_live;
+}
+
+void k1801vp128_device::rollback()
+{
+ cur_live = checkpoint_live;
+}
+
+void k1801vp128_device::live_delay(int state)
+{
+ cur_live.next_state = state;
+ if (cur_live.tm != machine().time())
+ cur_live.fi->tm->adjust(cur_live.tm - machine().time(), cur_live.fi->id);
+ else
+ live_sync();
+}
+
+void k1801vp128_device::live_sync()
+{
+ if (!cur_live.tm.is_never())
+ {
+ if (cur_live.tm > machine().time())
+ {
+ rollback();
+ live_run(machine().time());
+ cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
+ }
+ else
+ {
+ cur_live.pll.commit(cur_live.fi->dev, cur_live.tm);
+ if (cur_live.next_state != -1)
+ {
+ cur_live.state = cur_live.next_state;
+ cur_live.next_state = -1;
+ }
+ if (cur_live.state == IDLE)
+ {
+ cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
+ cur_live.tm = attotime::never;
+ cur_live.fi->live = false;
+ cur_live.fi = nullptr;
+ }
+ }
+ cur_live.next_state = -1;
+ checkpoint();
+ }
+}
+
+void k1801vp128_device::live_abort()
+{
+ if (!cur_live.tm.is_never() && cur_live.tm > machine().time())
+ {
+ rollback();
+ live_run(machine().time());
+ }
+
+ if (cur_live.fi)
+ {
+ cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm);
+ cur_live.fi->live = false;
+ cur_live.fi = nullptr;
+ }
+
+ cur_live.tm = attotime::never;
+ cur_live.state = IDLE;
+ cur_live.next_state = -1;
+}
+
+void k1801vp128_device::live_run(attotime limit)
+{
+ if (cur_live.state == IDLE || cur_live.next_state != -1)
+ return;
+
+ if (limit == attotime::never)
+ {
+ if (cur_live.fi->dev)
+ limit = cur_live.fi->dev->time_next_index();
+ if (limit == attotime::never)
+ {
+ // Happens when there's no disk or if the fdc is not
+ // connected to a drive, hence no index pulse. Force a
+ // sync from time to time in that case, so that the main
+ // cpu timeout isn't too painful. Avoids looping into
+ // infinity looking for data too.
+
+ limit = machine().time() + attotime::from_msec(1);
+ cur_live.fi->tm->adjust(attotime::from_msec(1), cur_live.fi->id);
+ }
+ }
+
+ for (;;)
+ {
+ switch (cur_live.state)
+ {
+ case SEARCH_ADDRESS_MARK_HEADER:
+ if (read_one_bit(limit))
+ return;
+
+ if (!(cur_live.bit_counter & 255))
+ {
+ LOGSHIFT("%s (%s): shift = %04x data=%02x c=%d\n", cur_live.tm.to_string(), limit.to_string(), cur_live.shift_reg,
+ bitswap<8>(cur_live.shift_reg, 14, 12, 10, 8, 6, 4, 2, 0), cur_live.bit_counter);
+ }
+
+ if (cur_live.shift_reg == 0x4489)
+ {
+ LOGLIVE("%s: Found A1\n", cur_live.tm.to_string());
+ cur_live.crc = 0x443b;
+ cur_live.data_separator_phase = false;
+ cur_live.bit_counter = 0;
+ cur_live.state = READ_DATA_LOW;
+ cur_live.data_reg = 0xa1;
+ m_sr &= ~CSR_R_CRC;
+ checkpoint();
+ }
+ break;
+
+ case READ_DATA_HIGH:
+ if (read_one_bit(limit))
+ return;
+ if (cur_live.bit_counter & 15)
+ break;
+ live_delay(READ_DATA_HIGH_BYTE);
+ return;
+
+ case READ_DATA_HIGH_BYTE:
+ cur_live.state = READ_DATA_LOW;
+ checkpoint();
+ break;
+
+ case READ_DATA_LOW:
+ if (read_one_bit(limit))
+ return;
+ if (cur_live.bit_counter & 15)
+ break;
+ live_delay(READ_DATA_LOW_BYTE);
+ return;
+
+ case READ_DATA_LOW_BYTE:
+ m_rbuf = cur_live.data_reg;
+ if (cur_live.crc == 0)
+ {
+ m_sr |= CSR_R_CRC;
+ }
+ m_sr |= CSR_R_TR;
+ LOGLIVE("%s: Read %04x (CRC %04x)\n", cur_live.tm.to_string(), cur_live.data_reg, cur_live.crc);
+ cur_live.state = READ_DATA_HIGH;
+ checkpoint();
+ break;
+
+ case WRITE_MFM_DATA_LOW:
+ if ((m_wbuf & 255) == 0xa1 && cur_live.crc_init == false && !(m_sr & CSR_R_CRC))
+ {
+ cur_live.crc_init = true;
+ cur_live.crc = 0xffff;
+ }
+ // if DRQ has not been serviced, write CRC
+ // if DRQ has not been serviced AND CRC has been written, write zeros
+ if (m_sr & CSR_R_TR)
+ {
+ if (cur_live.crc_init)
+ {
+ LOGLIVE("%s: Write CRC %04x\n", cur_live.tm.to_string(), cur_live.crc);
+ m_sr |= CSR_R_CRC;
+ m_sr &= ~CSR_R_TR;
+ cur_live.crc_init = false;
+ }
+ else
+ {
+ LOGLIVE("%s: Write after CRC\n", cur_live.tm.to_string());
+ m_wbuf = 0;
+ }
+ }
+ live_write_mfm((m_sr & CSR_R_CRC) ? (cur_live.crc >> 8) : m_wbuf, BIT(m_cr, 9));
+ cur_live.state++;
+ cur_live.bit_counter = 16;
+ checkpoint();
+ break;
+
+ case WRITE_MFM_DATA_HIGH:
+ live_write_mfm((m_sr & CSR_R_CRC) ? cur_live.crc : (m_wbuf >> 8), BIT(m_cr, 9));
+ LOGLIVE("%s: Write next %s\n", cur_live.tm.to_string(), (m_sr & CSR_R_TR)?"TR":"");
+ if (!(m_sr & CSR_R_CRC))
+ m_sr |= CSR_R_TR;
+ cur_live.state++;
+ cur_live.bit_counter = 16;
+ checkpoint();
+ break;
+
+ case WRITE_MFM_DATA_LOW_BYTE:
+ if (write_one_bit(limit))
+ return;
+ if (cur_live.bit_counter == 0)
+ {
+ live_delay(WRITE_MFM_DATA_HIGH);
+ return;
+ }
+ break;
+
+ case WRITE_MFM_DATA_HIGH_BYTE:
+ if (write_one_bit(limit))
+ return;
+ if (cur_live.bit_counter == 0)
+ {
+ live_delay(WRITE_MFM_DATA_LOW);
+ m_sr &= ~CSR_R_CRC;
+ return;
+ }
+ break;
+
+ default:
+ LOGWARN("%s: Unknown live state %d\n", cur_live.tm.to_string(), cur_live.state);
+ return;
+ }
+ }
+}
+
+
+void k1801vp128_device::seek_start(floppy_info &fi)
+{
+ fi.sub_state = SEEK_MOVE;
+ fi.dir = !BIT(m_cr, 6);
+ general_continue(fi);
+}
+
+
+void k1801vp128_device::read_data_start(floppy_info &fi)
+{
+ fi.main_state = READ_DATA;
+ fi.sub_state = WAIT_INDEX_DONE;
+ m_sr &= ~CSR_R_CRC;
+ read_data_continue(fi);
+}
+
+void k1801vp128_device::read_data_continue(floppy_info &fi)
+{
+ for (;;)
+ {
+ switch (fi.sub_state)
+ {
+ case SEEK_MOVE:
+ LOGSTATE("sub %d SEEK_MOVE\n", fi.id);
+ fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME;
+ fi.tm->adjust(attotime::from_msec(2), fi.id);
+ return;
+
+ case SEEK_WAIT_STEP_SIGNAL_TIME:
+ LOGSTATE("sub %d SEEK_WAIT_STEP_SIGNAL_TIME\n", fi.id);
+ return;
+
+ case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
+ LOGSTATE("sub %d SEEK_WAIT_STEP_SIGNAL_TIME_DONE\n", fi.id);
+ if (fi.dev)
+ {
+ fi.dev->dir_w(fi.dir);
+ fi.dev->stp_w(0);
+ fi.dev->stp_w(1);
+ fi.sub_state = WAIT_INDEX_DONE;
+ }
+ else
+ fi.main_state = fi.sub_state = IDLE;
+ break;
+
+ case WAIT_INDEX:
+ LOGSTATE("sub %d WAIT_INDEX\n", fi.id);
+ return;
+
+ case WAIT_INDEX_DONE:
+ LOGSTATE("sub %d WAIT_INDEX_DONE\n", fi.id);
+ fi.counter = 0;
+ fi.sub_state = SCAN_ID;
+ LOGSTATE("live %d SEARCH_ADDRESS_MARK_HEADER\n", fi.id);
+ live_start(fi, SEARCH_ADDRESS_MARK_HEADER);
+ return;
+
+ case SCAN_ID:
+ LOGSTATE("sub %d SCAN_ID\n", fi.id);
+ fi.sub_state = TRACK_READ;
+ LOGSTATE("live %d READ_DATA_HIGH\n", fi.id);
+ live_start(fi, READ_DATA_HIGH);
+ return;
+
+ case SCAN_ID_FAILED:
+ LOGSTATE("sub %d SCAN_ID_FAILED\n", fi.id);
+ fi.sub_state = COMMAND_DONE;
+ break;
+
+ case TRACK_READ:
+ LOGSTATE("sub %d TRACK_READ\n", fi.id);
+ fi.sub_state = COMMAND_DONE;
+ break;
+
+ case COMMAND_DONE:
+ LOGSTATE("sub %d COMMAND_DONE\n", fi.id);
+ fi.main_state = fi.sub_state = IDLE;
+ return;
+
+ default:
+ LOGWARN("%s: read sector unknown sub-state %d\n", ttsn(), fi.sub_state);
+ return;
+ }
+ }
+}
+
+void k1801vp128_device::write_data_start(floppy_info &fi)
+{
+ fi.main_state = WRITE_DATA;
+ fi.sub_state = WAIT_INDEX_DONE;
+ m_sr &= ~CSR_R_CRC;
+ write_data_continue(fi);
+}
+
+void k1801vp128_device::write_data_continue(floppy_info &fi)
+{
+ for (;;)
+ {
+ switch (fi.sub_state)
+ {
+ case WAIT_INDEX:
+ LOGSTATE("sub %d WAIT_INDEX\n", fi.id);
+ return;
+
+ case WAIT_INDEX_DONE:
+ LOGSTATE("sub %d WAIT_INDEX_DONE\n", fi.id);
+ fi.sub_state = TRACK_WRITTEN;
+ LOGSTATE("live %d WRITE_MFM_DATA_LOW\n", fi.id);
+ live_start(fi, WRITE_MFM_DATA_LOW);
+ return;
+
+ case TRACK_WRITTEN:
+ LOGSTATE("sub %d TRACK_WRITTEN\n", fi.id);
+ fi.sub_state = COMMAND_DONE;
+ break;
+
+ case COMMAND_DONE:
+ LOGSTATE("sub %d COMMAND_DONE\n", fi.id);
+ fi.main_state = fi.sub_state = IDLE;
+ return;
+
+ default:
+ LOGWARN("%s: write sector unknown sub-state %d\n", ttsn(), fi.sub_state);
+ return;
+ }
+ }
+}
+
+
+void k1801vp128_device::index_callback(floppy_image_device *floppy, int state)
+{
+ LOGLIVE("%s: Pulse %d\n", machine().time().to_string(), state);
+ for (floppy_info &fi : flopi)
+ {
+ if (fi.dev != floppy)
+ continue;
+
+ if (!state)
+ {
+ general_continue(fi);
+ continue;
+ }
+
+ switch (fi.sub_state)
+ {
+ case IDLE:
+ case SEEK_MOVE:
+ case SEEK_WAIT_STEP_SIGNAL_TIME:
+ case SEEK_WAIT_STEP_SIGNAL_TIME_DONE:
+ case SEEK_WAIT_STEP_TIME:
+ case SEEK_WAIT_STEP_TIME_DONE:
+ case HEAD_LOAD:
+ case HEAD_LOAD_DONE:
+ case SCAN_ID:
+ case SCAN_ID_FAILED:
+ break;
+
+ case TRACK_READ:
+ fi.sub_state = IDLE;
+ break;
+
+ case WAIT_INDEX:
+ fi.sub_state = WAIT_INDEX_DONE;
+ live_abort();
+ break;
+
+ default:
+ LOGWARN("%s: Index pulse on unknown sub-state %d\n", ttsn(), fi.sub_state);
+ break;
+ }
+
+ general_continue(fi);
+ }
+}
+
+
+void k1801vp128_device::general_continue(floppy_info &fi)
+{
+ if (fi.live && cur_live.state != IDLE)
+ {
+ live_run();
+ if (cur_live.state != IDLE)
+ return;
+ }
+
+ switch (fi.main_state)
+ {
+ case IDLE:
+ break;
+
+ case READ_DATA:
+ read_data_continue(fi);
+ break;
+
+ case WRITE_DATA:
+ write_data_continue(fi);
+ break;
+
+ default:
+ LOGWARN("%s: general_continue on unknown main-state %d\n", ttsn(), fi.main_state);
+ break;
+ }
+}
+
+
+bool k1801vp128_device::read_one_bit(const attotime &limit)
+{
+ int bit = cur_live.pll.get_next_bit(cur_live.tm, cur_live.fi->dev, limit);
+ if (bit < 0)
+ return true;
+ cur_live.shift_reg = (cur_live.shift_reg << 1) | bit;
+ cur_live.bit_counter++;
+ if (cur_live.data_separator_phase)
+ {
+ cur_live.data_reg = (cur_live.data_reg << 1) | bit;
+ if ((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
+ cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
+ else
+ cur_live.crc = cur_live.crc << 1;
+ }
+ cur_live.data_separator_phase = !cur_live.data_separator_phase;
+ return false;
+}
+
+bool k1801vp128_device::write_one_bit(const attotime &limit)
+{
+ bool bit = cur_live.shift_reg & 0x8000;
+ if (cur_live.pll.write_next_bit(bit, cur_live.tm, cur_live.fi->dev, limit))
+ return true;
+ if ((cur_live.bit_counter & 1) && cur_live.crc_init)
+ {
+ if ((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
+ cur_live.crc = (cur_live.crc << 1) ^ 0x1021;
+ else
+ cur_live.crc = cur_live.crc << 1;
+ }
+ cur_live.shift_reg = cur_live.shift_reg << 1;
+ cur_live.bit_counter--;
+ return false;
+}
+
+void k1801vp128_device::live_write_mfm(uint8_t mfm, bool marker)
+{
+ bool context = cur_live.data_bit_context;
+ uint16_t raw = 0;
+ for (int i = 0; i < 8; i++)
+ {
+ bool bit = mfm & (0x80 >> i);
+ if (!(bit || context))
+ raw |= 0x8000 >> (2*i);
+ if (bit)
+ raw |= 0x4000 >> (2*i);
+ context = bit;
+ }
+ if (marker && (mfm & 0xc) == 0) raw &= 0xffdf; // A1 and C2 sync sequences
+ cur_live.data_reg = mfm;
+ cur_live.shift_reg = raw;
+ cur_live.data_bit_context = context;
+ LOGLIVE("%s: write %02x %04x %04x\n", cur_live.tm.to_string(), mfm, cur_live.crc, raw);
+}
+
+
+void k1801vp128_device::set_ds(int fid)
+{
+ if (selected_drive == fid)
+ return;
+
+ live_abort();
+
+ // pass drive select to connected drives
+ for (floppy_info &fi : flopi)
+ if (fi.dev)
+ fi.dev->ds_w(fid);
+
+ // record selected drive
+ selected_drive = fid;
+
+ if (fid != -1)
+ {
+ LOG("COMMAND ~READ drive %d c:h %d:%d\n", selected_drive, flopi[fid].dev->get_cyl(), BIT(m_cr, 5));
+ m_sr &= ~CSR_R_TR;
+ execute_command(CMD_READ);
+ }
+}
diff --git a/src/devices/machine/1801vp128.h b/src/devices/machine/1801vp128.h
new file mode 100644
index 0000000000000..339ddcbd423cb
--- /dev/null
+++ b/src/devices/machine/1801vp128.h
@@ -0,0 +1,209 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/**********************************************************************
+
+ 1801VP1-128 gate array (MFM codec for floppy controllers)
+
+**********************************************************************
+ _____ _____
+ _AD0 1 |* \_/ | 42 +5V
+ _AD1 2 | | 41 _DS0
+ _AD2 3 | | 30 _DS1
+ _AD3 4 | | 39 _DS2
+ _AD4 5 | | 38 _DS3
+ _AD5 6 | | 37 _MSW
+ _AD6 7 | | 36 HS
+ _AD7 8 | | 35 DIR
+ _AD8 9 | | 34 _ST
+ _AD9 10 | | 33 TR0
+ _AD10 11 | 1801VP1-128 | 32 RDY
+ _AD11 12 | | 31 WPR
+ _AD12 13 | | 30 _REZ
+ _AD13 14 | | 29 DI
+ _AD14 15 | | 28 _WRE
+ _AD15 16 | | 27 _D01
+ _SYNC 17 | | 26 _D02
+ _DIN 18 | | 25 _D03
+ _DOUT 19 | | 24 IND
+ _INIT 20 | | 23 _RPLY
+ GND 21 |_____________| 22 CLC
+
+**********************************************************************/
+
+#ifndef MAME_MACHINE_1801VP128_H
+#define MAME_MACHINE_1801VP128_H
+
+#pragma once
+
+#include "imagedev/floppy.h"
+#include "machine/pdp11.h"
+
+#include "fdc_pll.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> k1801vp128_device
+
+class k1801vp128_device : public device_t
+{
+public:
+ // construction/destruction
+ k1801vp128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ auto ds_in_callback() { return m_read_ds.bind(); }
+
+ uint16_t read(offs_t offset);
+ void write(offs_t offset, uint16_t data);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ TIMER_CALLBACK_MEMBER(update_floppy);
+
+private:
+ enum {
+ CMD_READ,
+ CMD_WRITE,
+ CMD_SEEK
+ };
+
+ enum {
+ IDLE,
+
+ // Main states
+ READ_DATA,
+ WRITE_DATA,
+
+ // Sub-states
+ COMMAND_DONE,
+
+ SEEK_MOVE,
+ SEEK_WAIT_STEP_SIGNAL_TIME,
+ SEEK_WAIT_STEP_SIGNAL_TIME_DONE,
+ SEEK_WAIT_STEP_TIME,
+ SEEK_WAIT_STEP_TIME_DONE,
+ SEEK_WAIT_DONE,
+ SEEK_DONE,
+
+ HEAD_LOAD,
+ HEAD_LOAD_DONE,
+
+ WAIT_INDEX,
+ WAIT_INDEX_DONE,
+
+ SCAN_ID,
+ SCAN_ID_FAILED,
+
+ TRACK_READ,
+ TRACK_WRITTEN,
+
+ // Live states
+ SEARCH_ADDRESS_MARK_HEADER,
+ READ_DATA_HIGH,
+ READ_DATA_HIGH_BYTE,
+ READ_DATA_LOW,
+ READ_DATA_LOW_BYTE,
+
+ WRITE_MFM_DATA_HIGH,
+ WRITE_MFM_DATA_HIGH_BYTE,
+ WRITE_MFM_DATA_LOW,
+ WRITE_MFM_DATA_LOW_BYTE,
+ };
+
+ enum {
+ CSR_R_TR0 = 0000001,
+ CSR_R_RDY = 0000002,
+ CSR_R_WPR = 0000004,
+ CSR_R_TR = CSR_DONE,
+ CSR_R_CRC = 0040000,
+ CSR_R_IND = 0100000,
+
+ CSR_W_DS0 = 0000001,
+ CSR_W_DS1 = 0000002,
+ CSR_W_DS2 = 0000004,
+ CSR_W_DS3 = 0000010,
+ CSR_W_MSW = 0000020, // motor
+ CSR_W_HS = 0000040, // head select
+ CSR_W_DIR = 0000100, // step direction
+ CSR_W_ST = 0000200, // step pulse
+ CSR_W_GDR = 0000400,
+ CSR_W_WM = 0001000,
+ CSR_W_REZ = 0002000,
+ CSR_W_DS = 0000017,
+ };
+
+ struct floppy_info
+ {
+ emu_timer *tm;
+ floppy_image_device *dev;
+ int id;
+ int main_state, sub_state;
+ int dir, counter;
+ bool live, index;
+ };
+
+ struct live_info
+ {
+ attotime tm;
+ int state, next_state;
+ floppy_info *fi;
+ uint16_t shift_reg, crc;
+ int bit_counter;
+ bool data_separator_phase, data_bit_context, crc_init;
+ uint16_t data_reg;
+ fdc_pll_t pll;
+ };
+
+ required_device_array m_connectors;
+ devcb_read16 m_read_ds;
+
+ std::string ttsn() const;
+
+ floppy_info flopi[4];
+ int selected_drive;
+
+ uint16_t m_cr;
+ uint16_t m_sr;
+ uint16_t m_rbuf;
+ uint16_t m_wbuf;
+
+ live_info cur_live, checkpoint_live;
+
+ void execute_command(int command);
+ void set_ds(int fid);
+
+ void seek_start(floppy_info &fi);
+ void seek_continue(floppy_info &fi);
+
+ void read_data_start(floppy_info &fi);
+ void read_data_continue(floppy_info &fi);
+
+ void write_data_start(floppy_info &fi);
+ void write_data_continue(floppy_info &fi);
+
+ void general_continue(floppy_info &fi);
+ void index_callback(floppy_image_device *floppy, int state);
+
+ void live_start(floppy_info &fi, int live_state);
+ void live_abort();
+ void checkpoint();
+ void rollback();
+ void live_delay(int state);
+ void live_sync();
+ void live_run(attotime limit = attotime::never);
+ void live_write_mfm(uint8_t mfm, bool marker);
+
+ bool read_one_bit(const attotime &limit);
+ bool write_one_bit(const attotime &limit);
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(K1801VP128, k1801vp128_device)
+
+#endif // MAME_MACHINE_1801VP128_H
diff --git a/src/devices/machine/ns32081.cpp b/src/devices/machine/ns32081.cpp
index ca64842370177..ab406a84d04bd 100644
--- a/src/devices/machine/ns32081.cpp
+++ b/src/devices/machine/ns32081.cpp
@@ -8,7 +8,9 @@
* - Microprocessor Databook, Series 32000, NSC800, 1989 Edition, National Semiconductor
*
* TODO:
- * - NS32381
+ * - poly/scalb/logb/dot
+ * - ns32381 timing
+ * - no-result operations
*/
#include "emu.h"
@@ -21,6 +23,7 @@
#include "logmacro.h"
DEFINE_DEVICE_TYPE(NS32081, ns32081_device, "ns32081", "National Semiconductor NS32081 Floating-Point Unit")
+DEFINE_DEVICE_TYPE(NS32381, ns32381_device, "ns32381", "National Semiconductor NS32381 Floating-Point Unit")
enum fsr_mask : u32
{
@@ -31,6 +34,7 @@ enum fsr_mask : u32
FSR_IF = 0x00000040, // inexact result flag
FSR_RM = 0x00000180, // rounding mode
FSR_SWF = 0x0000fe00, // software field
+ FSR_RMB = 0x00010000, // (32381 only) register modify bit
};
enum rm_mask : u32
@@ -61,149 +65,159 @@ enum state : unsigned
RESULT = 5, // result word available
};
-enum idbyte : u8
-{
- FORMAT_9 = 0x3e,
- FORMAT_11 = 0xbe,
-};
-
enum operand_length : unsigned
{
LENGTH_F = 4, // single precision
LENGTH_L = 8, // double precision
};
-enum size_code : unsigned
-{
- SIZE_B = 0,
- SIZE_W = 1,
- SIZE_D = 3,
-};
-
-ns32081_device::ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
- : device_t(mconfig, NS32081, tag, owner, clock)
- , ns32000_slow_slave_interface(mconfig, *this)
+ns32081_device_base::ns32081_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock)
, ns32000_fpu_interface(mconfig, *this)
{
}
-void ns32081_device::device_start()
+void ns32081_device_base::device_start()
{
save_item(NAME(m_fsr));
- save_item(NAME(m_f));
+ save_item(NAME(m_state));
save_item(NAME(m_idbyte));
save_item(NAME(m_opword));
+
save_item(STRUCT_MEMBER(m_op, expected));
save_item(STRUCT_MEMBER(m_op, issued));
save_item(STRUCT_MEMBER(m_op, value));
- save_item(NAME(m_status));
- save_item(NAME(m_state));
+ save_item(NAME(m_status));
save_item(NAME(m_tcy));
m_complete = timer_alloc(FUNC(ns32081_device::complete), this);
}
-void ns32081_device::device_reset()
+void ns32081_device_base::device_reset()
{
m_fsr = 0;
- std::fill(std::begin(m_f), std::end(m_f), 0);
-
m_state = IDLE;
+ m_idbyte = 0;
+ m_opword = 0;
+ m_status = 0;
+ m_tcy = 0;
}
-void ns32081_device::state_add(device_state_interface &parent, int &index)
+void ns32081_device_base::state_add(device_state_interface &parent, int &index)
{
parent.state_add(index++, "FSR", m_fsr).formatstr("%04X");
-
- for (unsigned i = 0; i < 8; i++)
- parent.state_add(index++, util::string_format("F%d", i).c_str(), m_f[i]).formatstr("%08X");
}
-u16 ns32081_device::read_st(int *icount)
+template T ns32081_device_base::read()
{
- if (m_state == STATUS)
+ if (m_state == RESULT && m_op[2].issued < m_op[2].expected)
{
- m_state = (m_op[2].issued == m_op[2].expected) ? IDLE : RESULT;
+ T const data = m_op[2].value >> (m_op[2].issued * 8);
- if (icount)
- *icount -= m_tcy;
+ m_op[2].issued += sizeof(T);
- LOG("read_st status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy,
- (m_state == RESULT ? "results pending" : "complete"), machine().describe_context());
+ LOG("read %d data 0x%0*x (%s)\n",
+ m_op[2].issued / sizeof(T), sizeof(T) * 2, data, machine().describe_context());
- return m_status;
+ if (m_op[2].issued == m_op[2].expected)
+ {
+ LOG("read complete\n");
+ m_state = IDLE;
+ }
+
+ return data;
}
- logerror("protocol error reading status word (%s)\n", machine().describe_context());
+ logerror("read protocol error (%s)\n", machine().describe_context());
return 0;
}
-u16 ns32081_device::read_op()
+template void ns32081_device_base::write(T data)
{
- if (m_state == RESULT && m_op[2].issued < m_op[2].expected)
+ switch (m_state)
{
- u16 const data = u16(m_op[2].value >> (m_op[2].issued * 8));
- LOG("read_op word %d data 0x%04x (%s)\n", m_op[2].issued >> 1, data, machine().describe_context());
-
- m_op[2].issued += 2;
+ case IDLE:
+ if (sizeof(T) == 4)
+ {
+ // decode instruction
+ if (!decode(BIT(data, 24, 8), swapendian_int16(BIT(data, 8, 16))))
+ return;
- if (m_op[2].issued == m_op[2].expected)
+ m_state = OPERAND;
+ }
+ else
{
- LOG("read_op last result word issued\n");
- m_state = IDLE;
+ LOG("write idbyte 0x%04x (%s)\n", data, machine().describe_context());
+ if ((data == FORMAT_9) || (data == FORMAT_11) || (type() == NS32381 && data == FORMAT_12))
+ {
+ // record idbyte
+ m_idbyte = data;
+
+ m_state = OPERATION;
+ }
}
+ break;
- return data;
- }
+ case OPERATION:
+ LOG("write opword 0x%0*x (%s)\n", sizeof(T) * 2, data, machine().describe_context());
- logerror("protocol error reading result word (%s)\n", machine().describe_context());
- return 0;
-}
+ // decode instruction
+ decode(m_idbyte, swapendian_int16(data));
-void ns32081_device::write_id(u16 data)
-{
- bool const match = (data == FORMAT_9) || (data == FORMAT_11);
+ m_state = OPERAND;
+ break;
- if (match)
- {
- LOG("write_id match 0x%04x (%s)\n", data, machine().describe_context());
- m_state = OPERATION;
- }
- else
- {
- LOG("write_id ignore 0x%04x (%s)\n", data, machine().describe_context());
- m_state = IDLE;
+ case OPERAND:
+ // check awaiting operand data
+ if (m_op[0].issued < m_op[0].expected || m_op[1].issued < m_op[1].expected)
+ {
+ unsigned const n = (m_op[0].issued < m_op[0].expected) ? 0 : 1;
+ operand &op = m_op[n];
+
+ LOG("write operand %d data 0x%0*x (%s)\n",
+ n, sizeof(T) * 2, data, machine().describe_context());
+
+ // insert data into operand value
+ op.value |= u64(data) << (op.issued * 8);
+ op.issued += sizeof(T);
+ }
+ else
+ logerror("write protocol error unexpected operand data 0x%0*x (%s)\n",
+ sizeof(T) * 2, data, machine().describe_context());
+ break;
}
- m_idbyte = u8(data);
+ // start execution when all operands are available
+ if (m_state == OPERAND && m_op[0].issued >= m_op[0].expected && m_op[1].issued >= m_op[1].expected)
+ execute();
}
-void ns32081_device::write_op(u16 data)
+bool ns32081_device_base::decode(u8 const idbyte, u16 const opword)
{
- switch (m_state)
- {
- case OPERATION:
- m_opword = swapendian_int16(data);
- LOG("write_op opword 0x%04x (%s)\n", m_opword, machine().describe_context());
+ LOG("decode idbyte 0x%02x opword 0x%04x (%s)\n", idbyte, opword, machine().describe_context());
- // initialize operands
- for (operand &op : m_op)
- {
- op.expected = 0;
- op.issued = 0;
- op.value = 0;
- }
+ m_idbyte = idbyte;
+ m_opword = opword;
+
+ // initialize operands
+ for (operand &op : m_op)
+ {
+ op.expected = 0;
+ op.issued = 0;
+ op.value = 0;
+ }
- // decode operands
- if (m_idbyte == FORMAT_9)
+ switch (m_idbyte)
+ {
+ case FORMAT_9:
{
// format 9: 1111 1222 22oo ofii
unsigned const f_length = BIT(m_opword, 2) ? LENGTH_F : LENGTH_L;
unsigned const size = m_opword & 3;
- switch ((m_opword >> 3) & 7)
+ switch (BIT(m_opword, 3, 3))
{
case 0: // movif
m_op[0].expected = size + 1;
@@ -231,10 +245,11 @@ void ns32081_device::write_op(u16 data)
break;
}
}
- else if (m_idbyte == FORMAT_11)
+ break;
+ case FORMAT_11:
{
// format 11: 1111 1222 22oo oo0f
- unsigned const opcode = (m_opword >> 2) & 15;
+ unsigned const opcode = BIT(m_opword, 2, 4);
unsigned const f_length = BIT(m_opword, 0) ? LENGTH_F : LENGTH_L;
m_op[0].expected = f_length;
@@ -247,69 +262,65 @@ void ns32081_device::write_op(u16 data)
if (opcode != 2)
m_op[2].expected = f_length;
}
-
- // operand 1 in register
- if (m_op[0].expected && !(m_opword & 0xc000))
+ break;
+ case FORMAT_12:
{
- // exclude integer operands
- if (m_idbyte == FORMAT_11 || ((m_opword >> 3) & 7) > 1)
- {
- unsigned const reg = (m_opword >> 11) & 7;
- LOG("write_op read f%d\n", reg);
-
- m_op[0].value = m_f[reg ^ 0];
- if (m_op[0].expected == 8)
- m_op[0].value |= u64(m_f[reg ^ 1]) << 32;
+ // format 12: 1111 1222 22oo oo0f
+ unsigned const f_length = BIT(m_opword, 0) ? LENGTH_F : LENGTH_L;
- m_op[0].issued = m_op[0].expected;
+ switch (BIT(m_opword, 2, 4))
+ {
+ case 2: // polyf
+ case 3: // dotf
+ m_op[0].expected = f_length;
+ m_op[1].expected = f_length;
+ break;
+ case 4: // scalbf
+ m_op[0].expected = f_length;
+ m_op[1].expected = f_length;
+ m_op[2].expected = f_length;
+ break;
+ case 5: // logbf
+ m_op[0].expected = f_length;
+ m_op[2].expected = f_length;
+ break;
}
}
+ break;
+ default:
+ LOG("decode idbyte 0x%02x unknown (%s)\n", m_idbyte, machine().describe_context());
+ return false;
+ }
- // operand 2 in register
- if (m_op[1].expected && !(m_opword & 0x0600))
+ // operand 1 in register
+ if (m_op[0].expected && !BIT(m_opword, 14, 2))
+ {
+ // exclude integer operands
+ if (m_idbyte != FORMAT_9 || (BIT(m_opword, 3, 3) > 1))
{
- unsigned const reg = (m_opword >> 6) & 7;
- LOG("write_op read f%d\n", reg);
+ reg_get(m_op[0].expected, m_op[0].value, BIT(m_opword, 11, 3));
- m_op[1].value = m_f[reg ^ 0];
- if (m_op[1].expected == 8)
- m_op[1].value |= u64(m_f[reg ^ 1]) << 32;
-
- m_op[1].issued = m_op[1].expected;
+ m_op[0].issued = m_op[0].expected;
}
+ }
- m_state = OPERAND;
- break;
-
- case OPERAND:
- // check awaiting operand word
- if (m_op[0].issued < m_op[0].expected || m_op[1].issued < m_op[1].expected)
- {
- unsigned const n = (m_op[0].issued < m_op[0].expected) ? 0 : 1;
- operand &op = m_op[n];
-
- LOG("write_op op%d data 0x%04x (%s)\n", n, data, machine().describe_context());
+ // operand 2 in register
+ if (m_op[1].expected && !BIT(m_opword, 9, 2))
+ {
+ reg_get(m_op[1].expected, m_op[1].value, BIT(m_opword, 6, 3));
- // insert word into operand value
- op.value |= u64(data) << (op.issued * 8);
- op.issued += 2;
- }
- else
- logerror("protocol error unexpected operand word 0x%04x (%s)\n", data, machine().describe_context());
- break;
+ m_op[1].issued = m_op[1].expected;
}
- // start execution when all operands are available
- if (m_state == OPERAND && m_op[0].issued >= m_op[0].expected && m_op[1].issued >= m_op[1].expected)
- execute();
+ return true;
}
-void ns32081_device::execute()
+void ns32081_device_base::execute()
{
- softfloat_exceptionFlags = 0;
u32 const fsr = m_fsr;
m_fsr &= ~FSR_TT;
+ softfloat_exceptionFlags = 0;
m_status = 0;
m_tcy = 0;
@@ -317,235 +328,247 @@ void ns32081_device::execute()
{
case FORMAT_9:
// format 9: 1111 1222 22oo ofii
+ switch (BIT(m_opword, 3, 3))
{
- bool const single = BIT(m_opword, 2);
- unsigned const f_length = single ? LENGTH_F : LENGTH_L;
- unsigned const size = m_opword & 3;
-
- switch ((m_opword >> 3) & 7)
+ case 0:
+ // MOVif src,dest
+ // gen,gen
+ // read.i,write.f
{
- case 0:
- // MOVif src,dest
- // gen,gen
- // read.i,write.f
- {
- s32 const src =
- (size == SIZE_D) ? s32(m_op[0].value) :
- (size == SIZE_W) ? s16(m_op[0].value) :
- s8(m_op[0].value);
-
- if (single)
- m_op[2].value = i32_to_f32(src).v;
- else
- m_op[2].value = i32_to_f64(src).v;
- m_op[2].expected = f_length;
- m_tcy = 53;
- }
- break;
- case 1:
- // LFSR src
- // gen
- // read.D
- m_fsr = u16(m_op[0].value);
-
- switch (m_fsr & FSR_RM)
- {
- case RM_N: softfloat_roundingMode = softfloat_round_near_even; break;
- case RM_Z: softfloat_roundingMode = softfloat_round_minMag; break;
- case RM_U: softfloat_roundingMode = softfloat_round_max; break;
- case RM_D: softfloat_roundingMode = softfloat_round_min; break;
- }
- m_tcy = 18;
- break;
- case 2:
- // MOVLF src,dest
- // gen,gen
- // read.L,write.F
- m_op[2].value = f64_to_f32(float64_t{ m_op[0].value }).v;
- m_op[2].expected = f_length;
- m_tcy = (m_opword & 0xc000) ? 23 : 27;
- break;
- case 3:
- // MOVFL src,dest
- // gen,gen
- // read.F,write.L
- m_op[2].value = f32_to_f64(float32_t{ u32(m_op[0].value) }).v;
- m_op[2].expected = f_length;
- m_tcy = (m_opword & 0xc000) ? 22 : 26;
- break;
- case 4:
- // ROUNDfi src,dest
- // gen,gen
- // read.f,write.i
- if (single)
- m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_near_even, true);
- else
- m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_near_even, true);
-
- if ((size == SIZE_D && s64(m_op[2].value) != s32(m_op[2].value))
- || (size == SIZE_W && s64(m_op[2].value) != s16(m_op[2].value))
- || (size == SIZE_B && s64(m_op[2].value) != s8(m_op[2].value)))
- softfloat_exceptionFlags |= softfloat_flag_overflow;
+ s32 const src = util::sext(m_op[0].value, m_op[0].expected * 8);
- m_op[2].expected = size + 1;
- m_tcy = (m_opword & 0xc000) ? 53 : 66;
- break;
- case 5:
- // TRUNCfi src,dest
- // gen,gen
- // read.f,write.i
- if (single)
- m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_minMag, true);
+ if (m_op[2].expected == LENGTH_F)
+ m_op[2].value = i32_to_f32(src).v;
else
- m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_minMag, true);
+ m_op[2].value = i32_to_f64(src).v;
- if ((size == SIZE_D && s64(m_op[2].value) != s32(m_op[2].value))
- || (size == SIZE_W && s64(m_op[2].value) != s16(m_op[2].value))
- || (size == SIZE_B && s64(m_op[2].value) != s8(m_op[2].value)))
- softfloat_exceptionFlags |= softfloat_flag_overflow;
-
- m_op[2].expected = size + 1;
- m_tcy = (m_opword & 0xc000) ? 53 : 66;
- break;
- case 6:
- // SFSR dest
- // gen
- // write.D
- m_op[2].value = fsr;
- m_op[2].expected = 4;
- m_tcy = 13;
- break;
- case 7:
- // FLOORfi src,dest
- // gen,gen
- // read.f,write.i
- if (single)
- m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_min, true);
- else
- m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_min, true);
-
- if ((size == SIZE_D && s64(m_op[2].value) != s32(m_op[2].value))
- || (size == SIZE_W && s64(m_op[2].value) != s16(m_op[2].value))
- || (size == SIZE_B && s64(m_op[2].value) != s8(m_op[2].value)))
- softfloat_exceptionFlags |= softfloat_flag_overflow;
-
- m_op[2].expected = size + 1;
- m_tcy = (m_opword & 0xc000) ? 53 : 66;
- break;
+ m_tcy = 53;
+ }
+ break;
+ case 1:
+ // LFSR src
+ // gen
+ // read.D
+ m_fsr = u16(m_op[0].value);
+
+ switch (m_fsr & FSR_RM)
+ {
+ case RM_N: softfloat_roundingMode = softfloat_round_near_even; break;
+ case RM_Z: softfloat_roundingMode = softfloat_round_minMag; break;
+ case RM_U: softfloat_roundingMode = softfloat_round_max; break;
+ case RM_D: softfloat_roundingMode = softfloat_round_min; break;
}
+ m_tcy = 18;
+ break;
+ case 2:
+ // MOVLF src,dest
+ // gen,gen
+ // read.L,write.F
+ m_op[2].value = f64_to_f32(float64_t{ m_op[0].value }).v;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 23 : 27;
+ break;
+ case 3:
+ // MOVFL src,dest
+ // gen,gen
+ // read.F,write.L
+ m_op[2].value = f32_to_f64(float32_t{ u32(m_op[0].value) }).v;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 22 : 26;
+ break;
+ case 4:
+ // ROUNDfi src,dest
+ // gen,gen
+ // read.f,write.i
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_near_even, true);
+ else
+ m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_near_even, true);
+
+ if (s64(m_op[2].value) != util::sext(m_op[2].value, m_op[2].expected * 8))
+ softfloat_exceptionFlags |= softfloat_flag_overflow;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 53 : 66;
+ break;
+ case 5:
+ // TRUNCfi src,dest
+ // gen,gen
+ // read.f,write.i
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_minMag, true);
+ else
+ m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_minMag, true);
+
+ if (s64(m_op[2].value) != util::sext(m_op[2].value, m_op[2].expected * 8))
+ softfloat_exceptionFlags |= softfloat_flag_overflow;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 53 : 66;
+ break;
+ case 6:
+ // SFSR dest
+ // gen
+ // write.D
+ m_op[2].value = fsr;
+
+ m_tcy = 13;
+ break;
+ case 7:
+ // FLOORfi src,dest
+ // gen,gen
+ // read.f,write.i
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_to_i64(float32_t{ u32(m_op[0].value) }, softfloat_round_min, true);
+ else
+ m_op[2].value = f64_to_i64(float64_t{ m_op[0].value }, softfloat_round_min, true);
+
+ if (s64(m_op[2].value) != util::sext(m_op[2].value, m_op[2].expected * 8))
+ softfloat_exceptionFlags |= softfloat_flag_overflow;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 53 : 66;
+ break;
}
break;
case FORMAT_11:
- // format 11: 1111122222oooo0f
+ // format 11: 1111 1222 22oo oo0f
+ switch (BIT(m_opword, 2, 4))
{
- bool const single = BIT(m_opword, 0);
- unsigned const f_length = single ? LENGTH_F : LENGTH_L;
-
- switch ((m_opword >> 2) & 15)
- {
- case 0x0:
- // ADDf src,dest
- // gen,gen
- // read.f,rmw.f
- if (single)
- m_op[2].value = f32_add(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
- else
- m_op[2].value = f64_add(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
- m_op[2].expected = f_length;
- m_tcy = (m_opword & 0xc600) ? 70 : 74;
- break;
- case 0x1:
- // MOVf src,dest
- // gen,gen
- // read.f,write.f
- m_op[2].value = m_op[0].value;
- m_op[2].expected = f_length;
- m_tcy = (m_opword & 0xc000) ? 23 : 27;
- break;
- case 0x2:
- // CMPf src1,src2
- // gen,gen
- // read.f,read.f
- if (m_op[0].value == m_op[1].value)
- m_status |= SLAVE_Z;
- if ((single && f32_le(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }))
- || (!single && f64_le(float64_t{ m_op[1].value }, float64_t{ m_op[0].value })))
- m_status |= SLAVE_N;
- m_tcy = (m_opword & 0xc600) ? 45 : 49;
- break;
- case 0x3:
- // Trap(SLAVE)
- m_fsr |= TT_ILL;
- m_status = SLAVE_Q;
- break;
- case 0x4:
- // SUBf src,dest
- // gen,gen
- // read.f,rmw.f
- if (single)
- m_op[2].value = f32_sub(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
- else
- m_op[2].value = f64_sub(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
- m_op[2].expected = f_length;
- m_tcy = (m_opword & 0xc600) ? 70 : 74;
- break;
- case 0x5:
- // NEGf src,dest
- // gen,gen
- // read.f,write.f
- if (single)
+ case 0x0:
+ // ADDf src,dest
+ // gen,gen
+ // read.f,rmw.f
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_add(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
+ else
+ m_op[2].value = f64_add(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
+
+ m_tcy = (m_opword & 0xc600) ? 70 : 74;
+ break;
+ case 0x1:
+ // MOVf src,dest
+ // gen,gen
+ // read.f,write.f
+ m_op[2].value = m_op[0].value;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 23 : 27;
+ break;
+ case 0x2:
+ // CMPf src1,src2
+ // gen,gen
+ // read.f,read.f
+ if (m_op[0].value == m_op[1].value)
+ m_status |= SLAVE_Z;
+ if ((m_op[0].expected == LENGTH_F && f32_le(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }))
+ || (m_op[0].expected == LENGTH_L && f64_le(float64_t{ m_op[1].value }, float64_t{ m_op[0].value })))
+ m_status |= SLAVE_N;
+
+ m_tcy = (m_opword & 0xc600) ? 45 : 49;
+ break;
+ case 0x3:
+ // Trap(SLAVE)
+ m_fsr |= TT_ILL;
+ m_status = SLAVE_Q;
+ break;
+ case 0x4:
+ // SUBf src,dest
+ // gen,gen
+ // read.f,rmw.f
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_sub(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
+ else
+ m_op[2].value = f64_sub(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
+
+ m_tcy = (m_opword & 0xc600) ? 70 : 74;
+ break;
+ case 0x5:
+ // NEGf src,dest
+ // gen,gen
+ // read.f,write.f
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_mul(float32_t{ u32(m_op[0].value) }, i32_to_f32(-1)).v;
+ else
+ m_op[2].value = f64_mul(float64_t{ m_op[0].value }, i32_to_f64(-1)).v;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 20 : 24;
+ break;
+ case 0x8:
+ // DIVf src,dest
+ // gen,gen
+ // read.f,rmw.f
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_div(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
+ else
+ m_op[2].value = f64_div(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
+
+ m_tcy = ((m_opword & 0xc600) ? 55 : 59) + (m_op[0].expected == LENGTH_F ? 30 : 60);
+ break;
+ case 0x9:
+ // Trap(SLAVE)
+ m_fsr |= TT_ILL;
+ m_status = SLAVE_Q;
+ break;
+ case 0xc:
+ // MULf src,dest
+ // gen,gen
+ // read.f,rmw.f
+ if (m_op[0].expected == LENGTH_F)
+ m_op[2].value = f32_mul(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
+ else
+ m_op[2].value = f64_mul(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
+
+ m_tcy = ((m_opword & 0xc600) ? 30 : 34) + (m_op[0].expected == LENGTH_F ? 14 : 28);
+ break;
+ case 0xd:
+ // ABSf src,dest
+ // gen,gen
+ // read.f,write.f
+ if (m_op[0].expected == LENGTH_F)
+ if (f32_lt(float32_t{ u32(m_op[0].value) }, float32_t{ 0 }))
m_op[2].value = f32_mul(float32_t{ u32(m_op[0].value) }, i32_to_f32(-1)).v;
else
+ m_op[2].value = float32_t{ u32(m_op[0].value) }.v;
+ else
+ if (f64_lt(float64_t{ m_op[0].value }, float64_t{ 0 }))
m_op[2].value = f64_mul(float64_t{ m_op[0].value }, i32_to_f64(-1)).v;
- m_op[2].expected = f_length;
- m_tcy = (m_opword & 0xc000) ? 20 : 24;
- break;
- case 0x8:
- // DIVf src,dest
- // gen,gen
- // read.f,rmw.f
- if (single)
- m_op[2].value = f32_div(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
else
- m_op[2].value = f64_div(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
- m_op[2].expected = f_length;
- m_tcy = ((m_opword & 0xc600) ? 55 : 59) + (single ? 30 : 60);
- break;
- case 0x9:
- // Trap(SLAVE)
- m_fsr |= TT_ILL;
- m_status = SLAVE_Q;
- break;
- case 0xc:
- // MULf src,dest
- // gen,gen
- // read.f,rmw.f
- if (single)
- m_op[2].value = f32_mul(float32_t{ u32(m_op[1].value) }, float32_t{ u32(m_op[0].value) }).v;
- else
- m_op[2].value = f64_mul(float64_t{ m_op[1].value }, float64_t{ m_op[0].value }).v;
- m_op[2].expected = f_length;
- m_tcy = ((m_opword & 0xc600) ? 30 : 34) + (single ? 14 : 28);
- break;
- case 0xd:
- // ABSf src,dest
- // gen,gen
- // read.f,write.f
- if (single)
- if (f32_lt(float32_t{ u32(m_op[0].value) }, float32_t{ 0 }))
- m_op[2].value = f32_mul(float32_t{ u32(m_op[0].value) }, i32_to_f32(-1)).v;
- else
- m_op[2].value = float32_t{ u32(m_op[0].value) }.v;
- else
- if (f64_lt(float64_t{ m_op[0].value }, float64_t{ 0 }))
- m_op[2].value = f64_mul(float64_t{ m_op[0].value }, i32_to_f64(-1)).v;
- else
- m_op[2].value = float64_t{ m_op[0].value }.v;
- m_op[2].expected = f_length;
- m_tcy = (m_opword & 0xc000) ? 20 : 24;
- break;
- }
+ m_op[2].value = float64_t{ m_op[0].value }.v;
+
+ m_tcy = BIT(m_opword, 14, 2) ? 20 : 24;
+ break;
+ }
+ break;
+
+ case FORMAT_12:
+ // format 12: 1111 1222 22oo oo0f
+ switch (BIT(m_opword, 2, 4))
+ {
+ case 0x2:
+ // POLYf src1,src2
+ // gen,gen
+ // read.f,read.f
+ m_fsr |= FSR_RMB;
+ break;
+ case 0x3:
+ // DOTf src1,src2
+ // gen,gen
+ // read.f,read.f
+ m_fsr |= FSR_RMB;
+ break;
+ case 0x4:
+ // SCALBf src,dest
+ // gen,gen
+ // read.f,rmw.f
+ break;
+ case 0x5:
+ // LOGBf src,dest
+ // gen,gen
+ // read.f,write.f
+ break;
+ default:
+ // Trap(SLAVE)
+ m_fsr |= TT_ILL;
+ m_status = SLAVE_Q;
+ break;
}
break;
}
@@ -595,47 +618,177 @@ void ns32081_device::execute()
"addf", "movf", "cmpf", nullptr, "subf", "negf", nullptr, nullptr,
"divf", nullptr, nullptr, nullptr, "mulf", "absf", nullptr, nullptr
};
+ static char const *format12[] =
+ {
+ nullptr, nullptr, "polyf", "dotf", "scalbf", "logbf", nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
+ };
+
+ char const *operation = nullptr;
+ switch (m_idbyte)
+ {
+ case FORMAT_9: operation = format9[BIT(m_opword, 3, 3)]; break;
+ case FORMAT_11: operation = format11[BIT(m_opword, 2, 4)]; break;
+ case FORMAT_12: operation = format12[BIT(m_opword, 2, 4)]; break;
+ }
if (m_status & SLAVE_Q)
- LOG("execute %s 0x%x,0x%x exception\n",
- (m_idbyte == FORMAT_9)
- ? format9[(m_opword >> 3) & 7]
- : format11[(m_opword >> 2) & 15],
- m_op[0].value, m_op[1].value);
+ LOG("execute %s 0x%x,0x%x exception\n", operation, m_op[0].value, m_op[1].value);
else
- LOG("execute %s 0x%x,0x%x result 0x%x\n",
- (m_idbyte == FORMAT_9)
- ? format9[(m_opword >> 3) & 7]
- : format11[(m_opword >> 2) & 15],
- m_op[0].value, m_op[1].value, m_op[2].value);
+ LOG("execute %s 0x%x,0x%x result 0x%x\n", operation, m_op[0].value, m_op[1].value, m_op[2].value);
}
// write-back floating point register results
- if (m_op[2].expected && !(m_opword & 0x0600))
+ if (m_op[2].expected && !BIT(m_opword, 9, 2))
{
// exclude integer results (roundfi, truncfi, sfsr, floorfi)
- if (m_idbyte == FORMAT_11 || ((m_opword >> 3) & 7) < 4)
+ if (m_idbyte != FORMAT_9 || (BIT(m_opword, 3, 3) < 4))
{
- unsigned const reg = (m_opword >> 6) & 7;
+ reg_set(BIT(m_opword, 6, 3), m_op[2].expected, m_op[2].value);
- LOG("execute write-back f%d\n", reg);
-
- m_f[reg ^ 0] = u32(m_op[2].value >> 0);
- if (m_op[2].expected == 8)
- m_f[reg ^ 1] = u32(m_op[2].value >> 32);
+ if (type() == NS32381)
+ m_fsr |= FSR_RMB;
m_op[2].issued = m_op[2].expected;
}
}
- m_state = STATUS;
-
if (!m_out_scb.isunset())
m_complete->adjust(attotime::from_ticks(m_tcy, clock()));
+
+ m_state = STATUS;
+}
+
+u16 ns32081_device_base::status(int *icount)
+{
+ if (m_state == STATUS)
+ {
+ m_state = (m_op[2].issued == m_op[2].expected) ? IDLE : RESULT;
+
+ if (icount)
+ *icount -= m_tcy;
+
+ LOG("status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy,
+ (m_state == RESULT ? "results pending" : "complete"), machine().describe_context());
+
+ return m_status;
+ }
+
+ logerror("status protocol error (%s)\n", machine().describe_context());
+ return 0;
}
-void ns32081_device::complete(s32 param)
+void ns32081_device_base::complete(s32 param)
{
m_out_scb(0);
m_out_scb(1);
}
+
+ns32081_device::ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ : ns32081_device_base(mconfig, NS32081, tag, owner, clock)
+ , ns32000_slow_slave_interface(mconfig, *this)
+{
+}
+
+void ns32081_device::device_start()
+{
+ ns32081_device_base::device_start();
+
+ save_item(NAME(m_f));
+}
+
+void ns32081_device::device_reset()
+{
+ ns32081_device_base::device_reset();
+
+ std::fill(std::begin(m_f), std::end(m_f), 0);
+}
+
+void ns32081_device::state_add(device_state_interface &parent, int &index)
+{
+ ns32081_device_base::state_add(parent, index);
+
+ for (unsigned i = 0; i < 8; i++)
+ parent.state_add(index++, util::string_format("F%d", i).c_str(), m_f[i]).formatstr("%08X");
+}
+
+void ns32081_device::reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const
+{
+ op_value = m_f[reg ^ 0];
+ if (op_size == LENGTH_L)
+ op_value |= u64(m_f[reg ^ 1]) << 32;
+
+ if (op_size == LENGTH_L)
+ LOG("reg_get f%d:%d data 0x%016x\n", reg ^ 1, reg ^ 0, op_value);
+ else
+ LOG("reg_get f%d data 0x%08x\n", reg, op_value);
+}
+
+void ns32081_device::reg_set(unsigned const reg, unsigned const op_size, u64 const op_value)
+{
+ if (op_size == LENGTH_L)
+ LOG("reg_set f%d:%d data 0x%016x\n", reg ^ 1, reg ^ 0, op_value);
+ else
+ LOG("reg_set f%d data 0x%08x\n", reg, op_value);
+
+ m_f[reg ^ 0] = u32(op_value >> 0);
+ if (op_size == LENGTH_L)
+ m_f[reg ^ 1] = u32(op_value >> 32);
+}
+
+ns32381_device::ns32381_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ : ns32081_device_base(mconfig, NS32381, tag, owner, clock)
+ , ns32000_slow_slave_interface(mconfig, *this)
+ , ns32000_fast_slave_interface(mconfig, *this)
+{
+}
+
+void ns32381_device::device_start()
+{
+ ns32081_device_base::device_start();
+
+ save_item(NAME(m_l));
+}
+
+void ns32381_device::device_reset()
+{
+ std::fill(std::begin(m_l), std::end(m_l), 0);
+}
+
+void ns32381_device::state_add(device_state_interface &parent, int &index)
+{
+ ns32081_device_base::state_add(parent, index);
+
+ for (unsigned i = 0; i < 8; i++)
+ parent.state_add(index++, util::string_format("L%d", i).c_str(), m_l[i]).formatstr("%016X");
+}
+
+void ns32381_device::reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const
+{
+ if (op_size == LENGTH_L)
+ op_value = m_l[reg];
+ else if (reg & 1)
+ op_value = m_l[reg & 6] >> 32;
+ else
+ op_value = u32(m_l[reg & 6]);
+
+ if (op_size == LENGTH_L)
+ LOG("reg_get l%d data 0x%016x\n", reg, op_value);
+ else
+ LOG("reg_get f%d data 0x%08x\n", reg, op_value);
+}
+
+void ns32381_device::reg_set(unsigned const reg, unsigned const op_size, u64 const op_value)
+{
+ if (op_size == LENGTH_L)
+ LOG("reg_set l%d data 0x%016x\n", reg, op_value);
+ else
+ LOG("reg_set f%d data 0x%08x\n", reg, op_value);
+
+ if (op_size == LENGTH_L)
+ m_l[reg] = op_value;
+ else if (reg & 1)
+ m_l[reg & 6] = (op_value << 32) | u32(m_l[reg & 6]);
+ else
+ m_l[reg & 6] = (m_l[reg & 6] & 0xffff'ffff'0000'0000ULL) | u32(op_value);
+}
diff --git a/src/devices/machine/ns32081.h b/src/devices/machine/ns32081.h
index 89847175e43f9..12a50d9434dd0 100644
--- a/src/devices/machine/ns32081.h
+++ b/src/devices/machine/ns32081.h
@@ -8,54 +8,119 @@
#include "cpu/ns32000/common.h"
-class ns32081_device
+class ns32081_device_base
: public device_t
- , public ns32000_slow_slave_interface
, public ns32000_fpu_interface
{
-public:
- ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
-
- virtual void state_add(device_state_interface &parent, int &index) override;
-
- virtual u16 read_st(int *icount = nullptr) override;
- virtual u16 read_op() override;
-
- virtual void write_id(u16 data) override;
- virtual void write_op(u16 data) override;
-
protected:
+ ns32081_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
+
// device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
+ // ns32000_slave_interface implementation
+ virtual void state_add(device_state_interface &parent, int &index) override;
+
+ // slave interface handlers
+ template T read();
+ template void write(T data);
+
+ // execution helpers
+ bool decode(u8 const idbyte, u16 const opword);
void execute();
+ u16 status(int *icount);
void complete(s32 param);
+ // register helpers
+ virtual void reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const = 0;
+ virtual void reg_set(unsigned const reg, unsigned const op_size, u64 const op_value) = 0;
+
private:
emu_timer *m_complete;
- // registers
- u32 m_fsr;
- u32 m_f[8];
+ u32 m_fsr; // floating-point status register
// operating state
+ u32 m_state;
u8 m_idbyte;
u16 m_opword;
struct operand
{
- unsigned expected;
- unsigned issued;
+ u32 expected;
+ u32 issued;
u64 value;
}
m_op[3];
u16 m_status;
+ u32 m_tcy;
+};
- // implementation state
- unsigned m_state;
- unsigned m_tcy;
+class ns32081_device
+ : public ns32081_device_base
+ , public ns32000_slow_slave_interface
+{
+public:
+ ns32081_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+ // ns32000_slave_interface implementation
+ virtual void state_add(device_state_interface &parent, int &index) override;
+
+ // ns32000_slow_slave_interface implementation
+ virtual u16 slow_status(int *icount = nullptr) override { return status(icount); }
+ virtual u16 slow_read() override { return read(); }
+ virtual void slow_write(u16 data) override { write(data); }
+
+protected:
+ // device_t implementation
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // register helpers
+ virtual void reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const override;
+ virtual void reg_set(unsigned const reg, unsigned const op_size, u64 const op_value) override;
+
+private:
+ // registers
+ u32 m_f[8];
+};
+
+class ns32381_device
+ : public ns32081_device_base
+ , public ns32000_slow_slave_interface
+ , public ns32000_fast_slave_interface
+{
+public:
+ ns32381_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+ // ns32000_slave_interface implementation
+ virtual void state_add(device_state_interface &parent, int &index) override;
+
+ // ns32000_slow_slave_interface implementation
+ virtual u16 slow_status(int *icount = nullptr) override { return status(icount); }
+ virtual u16 slow_read() override { return read(); }
+ virtual void slow_write(u16 data) override { write(data); }
+
+ // ns32000_fast_slave_interface implementation
+ virtual u32 fast_status(int *icount = nullptr) override { return status(icount); }
+ virtual u32 fast_read() override { return read(); }
+ virtual void fast_write(u32 data) override { write(data); }
+
+protected:
+ // device_t implementation
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // register helpers
+ virtual void reg_get(unsigned const op_size, u64 &op_value, unsigned const reg) const override;
+ virtual void reg_set(unsigned const reg, unsigned const op_size, u64 const op_value) override;
+
+private:
+ // registers
+ u64 m_l[8];
};
DECLARE_DEVICE_TYPE(NS32081, ns32081_device)
+DECLARE_DEVICE_TYPE(NS32381, ns32381_device)
#endif // MAME_MACHINE_NS32081_H
diff --git a/src/devices/machine/ns32082.cpp b/src/devices/machine/ns32082.cpp
index e58cf546e62f0..4fb26bf5219f1 100644
--- a/src/devices/machine/ns32082.cpp
+++ b/src/devices/machine/ns32082.cpp
@@ -34,11 +34,6 @@ enum state : unsigned
RESULT = 6, // result word available
};
-enum idbyte : u8
-{
- FORMAT_14 = 0x1e,
-};
-
enum reg_mask : unsigned
{
BPR0 = 0x0, // breakpoint register 0
@@ -127,8 +122,8 @@ enum eia_mask : u32
ns32082_device::ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: device_t(mconfig, NS32082, tag, owner, clock)
- , ns32000_slow_slave_interface(mconfig, *this)
, ns32000_mmu_interface(mconfig, *this)
+ , ns32000_slow_slave_interface(mconfig, *this)
, m_bpr{}
, m_pf{}
, m_sc(0)
@@ -172,7 +167,7 @@ void ns32082_device::state_add(device_state_interface &parent, int &index)
parent.state_add(index++, "MSR", m_msr).formatstr("%08X");
}
-u16 ns32082_device::read_st(int *icount)
+u16 ns32082_device::slow_status(int *icount)
{
if (m_state == STATUS)
{
@@ -181,63 +176,54 @@ u16 ns32082_device::read_st(int *icount)
if (icount)
*icount -= m_tcy;
- LOG("read_st status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy,
+ LOG("status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy,
(m_state == RESULT ? "results pending" : "complete"), machine().describe_context());
return m_status;
}
- logerror("read_st protocol error reading status word (%s)\n", machine().describe_context());
+ logerror("status protocol error (%s)\n", machine().describe_context());
return 0;
}
-u16 ns32082_device::read_op()
+u16 ns32082_device::slow_read()
{
if (m_state == RESULT && m_op[2].issued < m_op[2].expected)
{
u16 const data = u16(m_op[2].value >> (m_op[2].issued * 8));
- LOG("read_op word %d data 0x%04x (%s)\n", m_op[2].issued >> 1, data, machine().describe_context());
+ LOG("read %d data 0x%04x (%s)\n", m_op[2].issued >> 1, data, machine().describe_context());
m_op[2].issued += 2;
if (m_op[2].issued == m_op[2].expected)
{
- LOG("read_op last result word issued\n");
+ LOG("read complete\n");
m_state = IDLE;
}
return data;
}
- logerror("read_op protocol error reading result word (%s)\n", machine().describe_context());
+ logerror("read protocol error (%s)\n", machine().describe_context());
return 0;
}
-void ns32082_device::write_id(u16 data)
-{
- bool const match = (data == FORMAT_14);
-
- if (match)
- {
- LOG("write_id match 0x%04x (%s)\n", data, machine().describe_context());
- m_state = OPERATION;
- }
- else
- {
- LOG("write_id ignore 0x%04x (%s)\n", data, machine().describe_context());
- m_state = IDLE;
- }
-
- m_idbyte = u8(data);
-}
-
-void ns32082_device::write_op(u16 data)
+void ns32082_device::slow_write(u16 data)
{
switch (m_state)
{
+ case IDLE:
+ LOG("write idbyte 0x%04x (%s)\n", data, machine().describe_context());
+ if (data == FORMAT_14)
+ {
+ m_idbyte = u8(data);
+ m_state = OPERATION;
+ }
+ break;
+
case OPERATION:
m_opword = swapendian_int16(data);
- LOG("write_op opword 0x%04x (%s)\n", m_opword, machine().describe_context());
+ LOG("write opword 0x%04x (%s)\n", m_opword, machine().describe_context());
m_tcy = 0;
@@ -282,14 +268,16 @@ void ns32082_device::write_op(u16 data)
unsigned const n = (m_op[0].issued < m_op[0].expected) ? 0 : 1;
operand &op = m_op[n];
- LOG("write_op op%d data 0x%04x (%s)\n", n, data, machine().describe_context());
+ LOG("write operand %d data 0x%04x (%s)\n",
+ n, data, machine().describe_context());
// insert word into operand value
op.value |= u64(data) << (op.issued * 8);
op.issued += 2;
}
else
- logerror("write_op protocol error unexpected operand word 0x%04x (%s)\n", data, machine().describe_context());
+ logerror("write protocol error unexpected operand data 0x%04x (%s)\n",
+ data, machine().describe_context());
break;
}
diff --git a/src/devices/machine/ns32082.h b/src/devices/machine/ns32082.h
index 41986941bb2f8..b8232e2511617 100644
--- a/src/devices/machine/ns32082.h
+++ b/src/devices/machine/ns32082.h
@@ -10,24 +10,25 @@
class ns32082_device
: public device_t
- , public ns32000_slow_slave_interface
, public ns32000_mmu_interface
+ , public ns32000_slow_slave_interface
{
public:
ns32082_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+ // ns32000_slave_interface implementation
virtual void state_add(device_state_interface &parent, int &index) override;
- virtual u16 read_st(int *icount = nullptr) override;
- virtual u16 read_op() override;
-
- virtual void write_id(u16 data) override;
- virtual void write_op(u16 data) override;
+ // ns32000_slow_slave_interface implementation
+ virtual u16 slow_status(int *icount = nullptr) override;
+ virtual u16 slow_read() override;
+ virtual void slow_write(u16 data) override;
+ // ns32000_mmu_interface implementation
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool suppress = false) override;
protected:
- // device_t overrides
+ // device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
@@ -51,16 +52,16 @@ class ns32082_device
u16 m_opword;
struct operand
{
- unsigned expected;
- unsigned issued;
+ u32 expected;
+ u32 issued;
u64 value;
}
m_op[3];
u16 m_status;
// implementation state
- unsigned m_state;
- unsigned m_tcy;
+ u32 m_state;
+ u32 m_tcy;
};
DECLARE_DEVICE_TYPE(NS32082, ns32082_device)
diff --git a/src/devices/machine/ns32382.cpp b/src/devices/machine/ns32382.cpp
index 18250bb80dd51..105bc55b1a28c 100644
--- a/src/devices/machine/ns32382.cpp
+++ b/src/devices/machine/ns32382.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Patrick Mackinlay
/*
- * National Semiconductor 32382 Memory Management Unit.
+ * National Semiconductor NS32382 Memory Management Unit.
*
* Sources:
* - Microprocessor Databook, Series 32000, NSC800, 1989 Edition, National Semiconductor
@@ -23,7 +23,7 @@
#include "logmacro.h"
-DEFINE_DEVICE_TYPE(NS32382, ns32382_device, "ns32382", "National Semiconductor 32382 Memory Management Unit")
+DEFINE_DEVICE_TYPE(NS32382, ns32382_device, "ns32382", "National Semiconductor NS32382 Memory Management Unit")
enum state : unsigned
{
@@ -35,11 +35,6 @@ enum state : unsigned
RESULT = 6, // result word available
};
-enum idbyte : u8
-{
- FORMAT_14 = 0x1e,
-};
-
enum reg_mask : unsigned
{
BAR = 0x0, // breakpoint address register
@@ -125,8 +120,8 @@ enum va_mask : u32
ns32382_device::ns32382_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: device_t(mconfig, NS32382, tag, owner, clock)
- , ns32000_fast_slave_interface(mconfig, *this)
, ns32000_mmu_interface(mconfig, *this)
+ , ns32000_fast_slave_interface(mconfig, *this)
{
}
@@ -165,7 +160,7 @@ void ns32382_device::state_add(device_state_interface &parent, int &index)
parent.state_add(index++, "MSR", m_msr).formatstr("%08X");
}
-u32 ns32382_device::read_st32(int *icount)
+u32 ns32382_device::fast_status(int *icount)
{
if (m_state == STATUS)
{
@@ -174,48 +169,49 @@ u32 ns32382_device::read_st32(int *icount)
if (icount)
*icount -= m_tcy;
- LOG("read_st status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy,
+ LOG("status 0x%04x tcy %d %s (%s)\n", m_status, m_tcy,
(m_state == RESULT ? "results pending" : "complete"), machine().describe_context());
return m_status;
}
- logerror("read_st protocol error reading status (%s)\n", machine().describe_context());
+ logerror("status protocol error (%s)\n", machine().describe_context());
return 0;
}
-u32 ns32382_device::read()
+u32 ns32382_device::fast_read()
{
if (m_state == RESULT && m_op[2].issued < m_op[2].expected)
{
u32 const data = u32(m_op[2].value >> (m_op[2].issued * 8));
- LOG("read_op dword %d data 0x%08x (%s)\n", m_op[2].issued >> 2, data, machine().describe_context());
+ LOG("read %d data 0x%08x (%s)\n", m_op[2].issued >> 2, data, machine().describe_context());
m_op[2].issued += 4;
if (m_op[2].issued == m_op[2].expected)
{
- LOG("read_op last result dword issued\n");
+ LOG("read complete\n");
m_state = IDLE;
}
return data;
}
- logerror("read_op protocol error reading result dword (%s)\n", machine().describe_context());
+ logerror("read protocol error (%s)\n", machine().describe_context());
return 0;
}
-void ns32382_device::write(u32 data)
+void ns32382_device::fast_write(u32 data)
{
switch (m_state)
{
case IDLE:
if (BIT(data, 24, 8) == FORMAT_14)
{
- LOG("write_fast match 0x%08x (%s)\n", data, machine().describe_context());
-
m_opword = swapendian_int16(data >> 8);
+
+ LOG("write idbyte 0x%02x opword 0x%04x (%s)\n", FORMAT_14, m_opword, machine().describe_context());
+
m_tcy = 0;
// initialize operands
@@ -254,14 +250,15 @@ void ns32382_device::write(u32 data)
unsigned const n = (m_op[0].issued < m_op[0].expected) ? 0 : 1;
operand &op = m_op[n];
- LOG("write_op op%d data 0x%04x (%s)\n", n, data, machine().describe_context());
+ LOG("write opword 0x%08x (%s)\n", data, machine().describe_context());
// insert dword into operand value
op.value |= u64(data) << (op.issued * 8);
op.issued += 4;
}
else
- logerror("write_fast protocol error unexpected operand 0x%08x (%s)\n", data, machine().describe_context());
+ logerror("write protocol error unexpected operand data 0x%08x (%s)\n",
+ data, machine().describe_context());
break;
}
@@ -274,7 +271,7 @@ void ns32382_device::execute()
{
m_status = 0;
- // format 14: xxxx xsss s0oo ooii 0001 1110
+ // format 14: xxxx xsss s0oo ooii
unsigned const quick = BIT(m_opword, 7, 4);
switch (BIT(m_opword, 2, 4))
diff --git a/src/devices/machine/ns32382.h b/src/devices/machine/ns32382.h
index eea3a0ef7d43e..a60c6d27f5fbf 100644
--- a/src/devices/machine/ns32382.h
+++ b/src/devices/machine/ns32382.h
@@ -10,25 +10,25 @@
class ns32382_device
: public device_t
- , public ns32000_fast_slave_interface
, public ns32000_mmu_interface
+ , public ns32000_fast_slave_interface
{
public:
ns32382_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
- // ns32000_slave_interface overrides
+ // ns32000_slave_interface implementation
virtual void state_add(device_state_interface &parent, int &index) override;
- // ns32000_fast_slave_interface overrides
- virtual u32 read_st32(int *icount = nullptr) override;
- virtual void write(u32 data) override;
- virtual u32 read() override;
+ // ns32000_fast_slave_interface implementation
+ virtual u32 fast_status(int *icount = nullptr) override;
+ virtual u32 fast_read() override;
+ virtual void fast_write(u32 data) override;
- // ns32000_mmu_interface overrides
+ // ns32000_mmu_interface implementation
virtual translate_result translate(address_space &space, unsigned st, u32 &address, bool user, bool write, bool pfs = false, bool debug = false) override;
protected:
- // device_t overrides
+ // device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
diff --git a/src/devices/machine/pc87306.cpp b/src/devices/machine/pc87306.cpp
index bc26d2e5c8218..8512e44d084c2 100644
--- a/src/devices/machine/pc87306.cpp
+++ b/src/devices/machine/pc87306.cpp
@@ -1,13 +1,14 @@
// license:BSD-3-Clause
// copyright-holders: Angelo Salese
-/***************************************************************************
+/**************************************************************************************************
National Semiconductor PC87306 Super I/O
TODO:
-- Barely enough to make it surpass POST test 0x05 in misc/odyssey.cpp
+- Barely enough to make it surpass POST test 0x05 in misc/odyssey.cpp;
+- COM1/COM2/LPT1 address and irq select;
-***************************************************************************/
+**************************************************************************************************/
#include "emu.h"
#include "bus/isa/isa.h"
@@ -32,18 +33,19 @@ pc87306_device::pc87306_device(const machine_config &mconfig, const char *tag, d
, m_space_config("superio_config_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(pc87306_device::config_map), this))
, m_kbdc(*this, "pc_kbdc")
, m_rtc(*this, "rtc")
- //, m_logical_view(*this, "logical_view")
+ , m_pc_com(*this, "uart%d", 0U)
+ , m_pc_lpt(*this, "lpta")
, m_gp20_reset_callback(*this)
, m_gp25_gatea20_callback(*this)
, m_irq1_callback(*this)
, m_irq8_callback(*this)
, m_irq9_callback(*this)
-// , m_txd1_callback(*this)
-// , m_ndtr1_callback(*this)
-// , m_nrts1_callback(*this)
-// , m_txd2_callback(*this)
-// , m_ndtr2_callback(*this)
-// , m_nrts2_callback(*this)
+ , m_txd1_callback(*this)
+ , m_ndtr1_callback(*this)
+ , m_nrts1_callback(*this)
+ , m_txd2_callback(*this)
+ , m_ndtr2_callback(*this)
+ , m_nrts2_callback(*this)
{ }
@@ -89,6 +91,21 @@ void pc87306_device::device_add_mconfig(machine_config &config)
at_keyboard_device &at_keyb(AT_KEYB(config, "at_keyboard", pc_keyboard_device::KEYBOARD_TYPE::AT, 1));
at_keyb.keypress().set(m_kbdc, FUNC(kbdc8042_device::keyboard_w));
+
+ PC_LPT(config, m_pc_lpt);
+ m_pc_lpt->irq_handler().set(FUNC(pc87306_device::irq_parallel_w));
+
+ NS16550(config, m_pc_com[0], XTAL(1'843'200));
+ m_pc_com[0]->out_int_callback().set(FUNC(pc87306_device::irq_serial1_w));
+ m_pc_com[0]->out_tx_callback().set(FUNC(pc87306_device::txd_serial1_w));
+ m_pc_com[0]->out_dtr_callback().set(FUNC(pc87306_device::dtr_serial1_w));
+ m_pc_com[0]->out_rts_callback().set(FUNC(pc87306_device::rts_serial1_w));
+
+ NS16550(config, m_pc_com[1], XTAL(1'843'200));
+ m_pc_com[1]->out_int_callback().set(FUNC(pc87306_device::irq_serial2_w));
+ m_pc_com[1]->out_tx_callback().set(FUNC(pc87306_device::txd_serial2_w));
+ m_pc_com[1]->out_dtr_callback().set(FUNC(pc87306_device::dtr_serial2_w));
+ m_pc_com[1]->out_rts_callback().set(FUNC(pc87306_device::rts_serial2_w));
}
void pc87306_device::remap(int space_id, offs_t start, offs_t end)
@@ -107,6 +124,16 @@ void pc87306_device::remap(int space_id, offs_t start, offs_t end)
if (BIT(m_krr, 3))
m_isa->install_device(0x70, 0x71, read8sm_delegate(*this, FUNC(pc87306_device::rtc_r)), write8sm_delegate(*this, FUNC(pc87306_device::rtc_w)));
+
+ if (BIT(m_fer, 0))
+ m_isa->install_device(0x378, 0x37f, read8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::read)), write8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::write)));
+
+ if (BIT(m_fer, 1))
+ m_isa->install_device(0x3f8, 0x3ff, read8sm_delegate(*m_pc_com[0], FUNC(ns16450_device::ins8250_r)), write8sm_delegate(*m_pc_com[0], FUNC(ns16450_device::ins8250_w)));
+
+ if (BIT(m_fer, 2))
+ m_isa->install_device(0x2f8, 0x2ff, read8sm_delegate(*m_pc_com[1], FUNC(ns16450_device::ins8250_r)), write8sm_delegate(*m_pc_com[1], FUNC(ns16450_device::ins8250_w)));
+
}
}
@@ -140,8 +167,8 @@ void pc87306_device::write(offs_t offset, u8 data)
void pc87306_device::config_map(address_map &map)
{
-// map(0x00, 0x00) FER Function Enable Register
-// map(0x01, 0x01) FAR Function Address Register
+ map(0x00, 0x00).rw(FUNC(pc87306_device::fer_r), FUNC(pc87306_device::fer_w));
+ map(0x01, 0x01).rw(FUNC(pc87306_device::far_r), FUNC(pc87306_device::far_w));
// map(0x02, 0x02) PTR Power and Test Register
// map(0x03, 0x03) FCR Function Control Register
// map(0x04, 0x04) PCR Printer Control Register
@@ -171,8 +198,49 @@ void pc87306_device::config_map(address_map &map)
// map(0x1c, 0x1c) PNP1 Plug and Play Configuration 1 Register
}
-// [0x05] KRR KBC and RTC Control Register
/*
+ * [0x00] FER Function Enable Register
+ * x--- ---- IDE address select
+ * -x-- ---- IDE i/f enable
+ * --x- ---- FDC address select
+ * ---x ---- (0) x2 floppy drives (1) x4 floppy drives
+ * ---- x--- FDC enable
+ * ---- -x-- UART2 enable
+ * ---- --x- UART1 enable
+ * ---- ---x Parallel Port enable
+ */
+u8 pc87306_device::fer_r(offs_t offset)
+{
+ return m_fer;
+}
+
+void pc87306_device::fer_w(offs_t offset, u8 data)
+{
+ m_fer = data;
+ remap(AS_IO, 0, 0x400);
+}
+
+/*
+ * [0x01] FAR Function Address Register
+ * xxxx ---- UART2 address select
+ * xx-- xx-- UART1 address select
+ * ---- --xx parallel address select
+ */
+u8 pc87306_device::far_r(offs_t offset)
+{
+ return m_far;
+}
+
+void pc87306_device::far_w(offs_t offset, u8 data)
+{
+ m_far = data;
+ remap(AS_IO, 0, 0x400);
+}
+
+
+/*
+ * [0x05] KRR KBC and RTC Control Register
+ *
* x--- ---- KBC clock source select (0) X1 clock (1) SYSCLK
* --x- ---- RAMSREL RTC bank select
* ---- x--- RTC enable bit
@@ -254,6 +322,128 @@ void pc87306_device::irq_mouse_w(int state)
request_irq(12, state ? ASSERT_LINE : CLEAR_LINE);
}
+/*
+ * Serial
+ */
+
+void pc87306_device::irq_serial1_w(int state)
+{
+ if (!(BIT(m_fer, 1)))
+ return;
+ request_irq(3, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void pc87306_device::irq_serial2_w(int state)
+{
+ if (!(BIT(m_fer, 2)))
+ return;
+ request_irq(4, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void pc87306_device::txd_serial1_w(int state)
+{
+ if (!(BIT(m_fer, 1)))
+ return;
+ m_txd1_callback(state);
+}
+
+void pc87306_device::txd_serial2_w(int state)
+{
+ if (!(BIT(m_fer, 2)))
+ return;
+ m_txd2_callback(state);
+}
+
+void pc87306_device::dtr_serial1_w(int state)
+{
+ if (!(BIT(m_fer, 1)))
+ return;
+ m_ndtr1_callback(state);
+}
+
+void pc87306_device::dtr_serial2_w(int state)
+{
+ if (!(BIT(m_fer, 2)))
+ return;
+ m_ndtr2_callback(state);
+}
+
+void pc87306_device::rts_serial1_w(int state)
+{
+ if (!(BIT(m_fer, 1)))
+ return;
+ m_nrts1_callback(state);
+}
+
+void pc87306_device::rts_serial2_w(int state)
+{
+ if (!(BIT(m_fer, 2)))
+ return;
+ m_nrts2_callback(state);
+}
+
+void pc87306_device::rxd1_w(int state)
+{
+ m_pc_com[0]->rx_w(state);
+}
+
+void pc87306_device::ndcd1_w(int state)
+{
+ m_pc_com[0]->dcd_w(state);
+}
+
+void pc87306_device::ndsr1_w(int state)
+{
+ m_pc_com[0]->dsr_w(state);
+}
+
+void pc87306_device::nri1_w(int state)
+{
+ m_pc_com[0]->ri_w(state);
+}
+
+void pc87306_device::ncts1_w(int state)
+{
+ m_pc_com[0]->cts_w(state);
+}
+
+void pc87306_device::rxd2_w(int state)
+{
+ m_pc_com[1]->rx_w(state);
+}
+
+void pc87306_device::ndcd2_w(int state)
+{
+ m_pc_com[1]->dcd_w(state);
+}
+
+void pc87306_device::ndsr2_w(int state)
+{
+ m_pc_com[1]->dsr_w(state);
+}
+
+void pc87306_device::nri2_w(int state)
+{
+ m_pc_com[1]->ri_w(state);
+}
+
+void pc87306_device::ncts2_w(int state)
+{
+ m_pc_com[1]->cts_w(state);
+}
+
+/*
+ * Parallel
+ */
+
+void pc87306_device::irq_parallel_w(int state)
+{
+ if (!(BIT(m_fer, 0)))
+ return;
+ request_irq(5, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
+
void pc87306_device::request_irq(int irq, int state)
{
switch (irq)
diff --git a/src/devices/machine/pc87306.h b/src/devices/machine/pc87306.h
index 1ab9c5826277c..4b1256e1e5284 100644
--- a/src/devices/machine/pc87306.h
+++ b/src/devices/machine/pc87306.h
@@ -9,6 +9,8 @@
#include "bus/isa/isa.h"
#include "machine/8042kbdc.h"
#include "machine/ds128x.h"
+#include "machine/ins8250.h"
+#include "machine/pc_lpt.h"
class pc87306_device : public device_t,
public device_isa16_card_interface,
@@ -25,12 +27,23 @@ class pc87306_device : public device_t,
auto irq1() { return m_irq1_callback.bind(); }
auto irq8() { return m_irq8_callback.bind(); }
auto irq9() { return m_irq9_callback.bind(); }
-// auto txd1() { return m_txd1_callback.bind(); }
-// auto ndtr1() { return m_ndtr1_callback.bind(); }
-// auto nrts1() { return m_nrts1_callback.bind(); }
-// auto txd2() { return m_txd2_callback.bind(); }
-// auto ndtr2() { return m_ndtr2_callback.bind(); }
-// auto nrts2() { return m_nrts2_callback.bind(); }
+ auto txd1() { return m_txd1_callback.bind(); }
+ auto ndtr1() { return m_ndtr1_callback.bind(); }
+ auto nrts1() { return m_nrts1_callback.bind(); }
+ auto txd2() { return m_txd2_callback.bind(); }
+ auto ndtr2() { return m_ndtr2_callback.bind(); }
+ auto nrts2() { return m_nrts2_callback.bind(); }
+
+ void rxd1_w(int state);
+ void ndcd1_w(int state);
+ void ndsr1_w(int state);
+ void nri1_w(int state);
+ void ncts1_w(int state);
+ void rxd2_w(int state);
+ void ndcd2_w(int state);
+ void ndsr2_w(int state);
+ void nri2_w(int state);
+ void ncts2_w(int state);
protected:
virtual void device_start() override;
@@ -44,19 +57,20 @@ class pc87306_device : public device_t,
required_device m_kbdc;
required_device m_rtc;
-// memory_view m_logical_view;
+ required_device_array m_pc_com;
+ required_device m_pc_lpt;
devcb_write_line m_gp20_reset_callback;
devcb_write_line m_gp25_gatea20_callback;
devcb_write_line m_irq1_callback;
devcb_write_line m_irq8_callback;
devcb_write_line m_irq9_callback;
-// devcb_write_line m_txd1_callback;
-// devcb_write_line m_ndtr1_callback;
-// devcb_write_line m_nrts1_callback;
-// devcb_write_line m_txd2_callback;
-// devcb_write_line m_ndtr2_callback;
-// devcb_write_line m_nrts2_callback;
+ devcb_write_line m_txd1_callback;
+ devcb_write_line m_ndtr1_callback;
+ devcb_write_line m_nrts1_callback;
+ devcb_write_line m_txd2_callback;
+ devcb_write_line m_ndtr2_callback;
+ devcb_write_line m_nrts2_callback;
void request_irq(int irq, int state);
@@ -65,6 +79,12 @@ class pc87306_device : public device_t,
void config_map(address_map &map);
+ u8 far_r(offs_t offset);
+ void far_w(offs_t offset, u8 data);
+
+ u8 fer_r(offs_t offset);
+ void fer_w(offs_t offset, u8 data);
+
u8 keybc_status_r(offs_t offset);
void keybc_command_w(offs_t offset, u8 data);
u8 rtc_r(offs_t offset);
@@ -79,10 +99,23 @@ class pc87306_device : public device_t,
u8 krr_r(offs_t offset);
void krr_w(offs_t offset, u8 data);
+ void irq_parallel_w(int state);
+
+ void irq_serial1_w(int state);
+ void txd_serial1_w(int state);
+ void dtr_serial1_w(int state);
+ void rts_serial1_w(int state);
+ void irq_serial2_w(int state);
+ void txd_serial2_w(int state);
+ void dtr_serial2_w(int state);
+ void rts_serial2_w(int state);
+
u8 m_index = 0;
u8 m_locked_state = 2;
u8 m_krr = 0;
+ u8 m_fer = 0;
+ u8 m_far = 0;
};
DECLARE_DEVICE_TYPE(PC87306, pc87306_device);
diff --git a/src/devices/machine/sis5513_ide.cpp b/src/devices/machine/sis5513_ide.cpp
index de0167fc5e7fc..f29c91fecf019 100644
--- a/src/devices/machine/sis5513_ide.cpp
+++ b/src/devices/machine/sis5513_ide.cpp
@@ -144,6 +144,7 @@ void sis5513_ide_device::device_reset()
pci_device::device_reset();
command = 0x0000;
+ command_mask = 5;
status = 0x0000;
pclass = 0x01018a;
m_ide_ctrl0 = 0;
diff --git a/src/devices/machine/sis5513_ide.h b/src/devices/machine/sis5513_ide.h
index 89d4916c47bd4..58a1ef0beb6ba 100644
--- a/src/devices/machine/sis5513_ide.h
+++ b/src/devices/machine/sis5513_ide.h
@@ -7,7 +7,7 @@
#pragma once
#include "pci.h"
-#include "machine/pci-ide.h"
+#include "idectrl.h"
class sis5513_ide_device : public pci_device
{
@@ -40,11 +40,6 @@ class sis5513_ide_device : public pci_device
virtual void config_map(address_map &map) override;
- void ide1_command_map(address_map &map);
- void ide1_control_map(address_map &map);
- void ide2_command_map(address_map &map);
- void ide2_control_map(address_map &map);
- void bus_master_ide_control_map(address_map &map);
private:
required_device m_ide1;
required_device m_ide2;
@@ -52,6 +47,12 @@ class sis5513_ide_device : public pci_device
devcb_write_line m_irq_sec_callback;
required_address_space m_bus_master_space;
+ void ide1_command_map(address_map &map);
+ void ide1_control_map(address_map &map);
+ void ide2_command_map(address_map &map);
+ void ide2_control_map(address_map &map);
+ void bus_master_ide_control_map(address_map &map);
+
bool ide1_mode();
bool ide2_mode();
diff --git a/src/devices/machine/sis85c496.cpp b/src/devices/machine/sis85c496.cpp
index 45cc3c9ae664a..bc2f52e547d28 100644
--- a/src/devices/machine/sis85c496.cpp
+++ b/src/devices/machine/sis85c496.cpp
@@ -34,6 +34,7 @@ void sis85c496_host_device::config_map(address_map &map)
);
map(0x58, 0x59).rw(FUNC(sis85c496_host_device::ide_vesa_config_r), FUNC(sis85c496_host_device::ide_vesa_config_w));
map(0x5a, 0x5a).rw(FUNC(sis85c496_host_device::smram_ctrl_r), FUNC(sis85c496_host_device::smram_ctrl_w));
+ map(0xc0, 0xc3).rw(FUNC(sis85c496_host_device::pirqrc_r), FUNC(sis85c496_host_device::pirqrc_w));
map(0xc8, 0xcb).rw(FUNC(sis85c496_host_device::mailbox_r), FUNC(sis85c496_host_device::mailbox_w));
map(0xd0, 0xd0).rw(FUNC(sis85c496_host_device::bios_config_r), FUNC(sis85c496_host_device::bios_config_w));
map(0xd1, 0xd1).rw(FUNC(sis85c496_host_device::isa_decoder_r), FUNC(sis85c496_host_device::isa_decoder_w));
@@ -43,14 +44,15 @@ void sis85c496_host_device::internal_io_map(address_map &map)
{
pci_host_device::io_configuration_access_map(map);
map(0x0000, 0x001f).rw("dma8237_1", FUNC(am9517a_device::read), FUNC(am9517a_device::write));
- map(0x0020, 0x003f).rw("pic8259_master", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
+ map(0x0020, 0x0021).rw("pic8259_master", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
+// map(0x0022, 0x0023) 85C497 super I/O
map(0x0040, 0x005f).rw("pit8254", FUNC(pit8254_device::read), FUNC(pit8254_device::write));
map(0x0060, 0x0063).rw(FUNC(sis85c496_host_device::at_keybc_r), FUNC(sis85c496_host_device::at_keybc_w));
map(0x0064, 0x0067).rw("keybc", FUNC(at_keyboard_controller_device::status_r), FUNC(at_keyboard_controller_device::command_w));
- map(0x0070, 0x007f).w(FUNC(sis85c496_host_device::rtc_nmi_w)).umask32(0x00ff00ff);
- map(0x0070, 0x007f).rw("rtc", FUNC(ds12885_device::data_r), FUNC(ds12885_device::data_w)).umask32(0xff00ff00);
+ map(0x0070, 0x0070).lr8(NAME([this] () { return m_ds12885->get_address(); })).w(FUNC(sis85c496_host_device::rtc_address_nmi_w));
+ map(0x0071, 0x0071).rw("rtc", FUNC(ds12885_device::data_r), FUNC(ds12885_device::data_w));
map(0x0080, 0x009f).rw(FUNC(sis85c496_host_device::at_page8_r), FUNC(sis85c496_host_device::at_page8_w));
- map(0x00a0, 0x00bf).rw("pic8259_slave", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
+ map(0x00a0, 0x00a1).rw("pic8259_slave", FUNC(pic8259_device::read), FUNC(pic8259_device::write));
map(0x00c0, 0x00df).rw(FUNC(sis85c496_host_device::at_dma8237_2_r), FUNC(sis85c496_host_device::at_dma8237_2_w));
map(0x00e0, 0x00ef).noprw();
}
@@ -127,6 +129,25 @@ void sis85c496_host_device::device_add_mconfig(machine_config &config)
ISA16(config, m_isabus, 0);
m_isabus->set_memspace(m_maincpu, AS_PROGRAM);
m_isabus->set_iospace(m_maincpu, AS_IO);
+ m_isabus->irq3_callback().set(FUNC(sis85c496_host_device::pc_irq3_w));
+ m_isabus->irq4_callback().set(FUNC(sis85c496_host_device::pc_irq4_w));
+ m_isabus->irq5_callback().set(FUNC(sis85c496_host_device::pc_irq5_w));
+ m_isabus->irq6_callback().set(FUNC(sis85c496_host_device::pc_irq6_w));
+ m_isabus->irq7_callback().set(FUNC(sis85c496_host_device::pc_irq7_w));
+ m_isabus->irq2_callback().set(FUNC(sis85c496_host_device::pc_irq9_w));
+ m_isabus->irq10_callback().set(FUNC(sis85c496_host_device::pc_irq10_w));
+ m_isabus->irq11_callback().set(FUNC(sis85c496_host_device::pc_irq11_w));
+ m_isabus->irq12_callback().set(FUNC(sis85c496_host_device::pc_irq12m_w));
+ m_isabus->irq14_callback().set(FUNC(sis85c496_host_device::pc_irq14_w));
+ m_isabus->irq15_callback().set(FUNC(sis85c496_host_device::pc_irq15_w));
+ m_isabus->drq0_callback().set(m_dma8237_1, FUNC(am9517a_device::dreq0_w));
+ m_isabus->drq1_callback().set(m_dma8237_1, FUNC(am9517a_device::dreq1_w));
+ m_isabus->drq2_callback().set(m_dma8237_1, FUNC(am9517a_device::dreq2_w));
+ m_isabus->drq3_callback().set(m_dma8237_1, FUNC(am9517a_device::dreq3_w));
+ m_isabus->drq5_callback().set(m_dma8237_2, FUNC(am9517a_device::dreq1_w));
+ m_isabus->drq6_callback().set(m_dma8237_2, FUNC(am9517a_device::dreq2_w));
+ m_isabus->drq7_callback().set(m_dma8237_2, FUNC(am9517a_device::dreq3_w));
+ m_isabus->iochck_callback().set(FUNC(sis85c496_host_device::iochck_w));
IDE_CONTROLLER_32(config, m_ide[0]).options(ata_devices, "hdd", nullptr, false);
m_ide[0]->irq_handler().set(m_pic8259_slave, FUNC(pic8259_device::ir6_w));
@@ -174,6 +195,9 @@ void sis85c496_host_device::device_start()
set_spaces(&m_maincpu->space(AS_PROGRAM), &m_maincpu->space(AS_IO));
+ m_pci_root->set_pin_mapper(pci_pin_mapper(*this, FUNC(sis85c496_host_device::pin_mapper)));
+ m_pci_root->set_irq_handler(pci_irq_handler(*this, FUNC(sis85c496_host_device::irq_handler)));
+
memory_window_start = 0;
memory_window_end = 0xffffffff;
memory_offset = 0;
@@ -215,6 +239,8 @@ void sis85c496_host_device::device_reset()
m_shadctrl = 0;
m_smramctrl = 0;
m_ide_vesa_ctrl = 0;
+
+ memset(m_pirqrc, 0x80, sizeof(m_pirqrc));
}
void sis85c496_host_device::device_config_complete()
@@ -562,6 +588,129 @@ void sis85c496_host_device::pc_dack5_w(int state) { pc_select_dma_channel(5, sta
void sis85c496_host_device::pc_dack6_w(int state) { pc_select_dma_channel(6, state); }
void sis85c496_host_device::pc_dack7_w(int state) { pc_select_dma_channel(7, state); }
+void sis85c496_host_device::pc_irq1_w(int state) { m_pic8259_master->ir1_w(state); }
+void sis85c496_host_device::pc_irq3_w(int state) { m_pic8259_master->ir3_w(state); }
+void sis85c496_host_device::pc_irq4_w(int state) { m_pic8259_master->ir4_w(state); }
+void sis85c496_host_device::pc_irq5_w(int state) { m_pic8259_master->ir5_w(state); }
+void sis85c496_host_device::pc_irq6_w(int state) { m_pic8259_master->ir6_w(state); }
+void sis85c496_host_device::pc_irq7_w(int state) { m_pic8259_master->ir7_w(state); }
+void sis85c496_host_device::pc_irq8n_w(int state) { m_pic8259_slave->ir0_w(state); }
+void sis85c496_host_device::pc_irq9_w(int state) { m_pic8259_slave->ir1_w(state); }
+void sis85c496_host_device::pc_irq10_w(int state) { m_pic8259_slave->ir2_w(state); }
+void sis85c496_host_device::pc_irq11_w(int state) { m_pic8259_slave->ir3_w(state); }
+void sis85c496_host_device::pc_irq12m_w(int state) { m_pic8259_slave->ir4_w(state); }
+void sis85c496_host_device::pc_irq14_w(int state) { m_pic8259_slave->ir6_w(state); }
+void sis85c496_host_device::pc_irq15_w(int state) { m_pic8259_slave->ir7_w(state); }
+
+uint8_t sis85c496_host_device::pirqrc_r(offs_t offset)
+{
+ return m_pirqrc[offset];
+}
+
+void sis85c496_host_device::pirqrc_w(offs_t offset, uint8_t data)
+{
+ m_pirqrc[offset] = data;
+ logerror("pirqrc[%d] = %02x\n", offset, m_pirqrc[offset]);
+}
+
+int sis85c496_host_device::pin_mapper(int pin)
+{
+ if(pin < 0 || pin >= 4 || (m_pirqrc[pin] & 0x80))
+ return -1;
+ return m_pirqrc[pin];
+}
+
+void sis85c496_host_device::irq_handler(int line, int state)
+{
+ if(line < 0 && line >= 16)
+ return;
+
+ logerror("irq_handler %d %d\n", line, state);
+ redirect_irq(line, state);
+}
+
+void sis85c496_host_device::pc_pirqa_w(int state)
+{
+ int irq = m_pirqrc[0] & 15;
+
+ if (!(BIT(m_pirqrc[0], 7)))
+ return;
+ redirect_irq(irq, state);
+}
+
+void sis85c496_host_device::pc_pirqb_w(int state)
+{
+ int irq = m_pirqrc[1] & 15;
+
+ if (!(BIT(m_pirqrc[1], 7)))
+ return;
+ redirect_irq(irq, state);
+}
+
+void sis85c496_host_device::pc_pirqc_w(int state)
+{
+ int irq = m_pirqrc[2] & 15;
+
+ if (!(BIT(m_pirqrc[2], 7)))
+ return;
+ redirect_irq(irq, state);
+}
+
+void sis85c496_host_device::pc_pirqd_w(int state)
+{
+ int irq = m_pirqrc[3] & 15;
+
+ if (!(BIT(m_pirqrc[3], 7)))
+ return;
+ redirect_irq(irq, state);
+}
+
+void sis85c496_host_device::redirect_irq(int irq, int state)
+{
+ switch (irq)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 8:
+ case 13:
+ break;
+ case 3:
+ m_pic8259_master->ir3_w(state);
+ break;
+ case 4:
+ m_pic8259_master->ir4_w(state);
+ break;
+ case 5:
+ m_pic8259_master->ir5_w(state);
+ break;
+ case 6:
+ m_pic8259_master->ir6_w(state);
+ break;
+ case 7:
+ m_pic8259_master->ir7_w(state);
+ break;
+ case 9:
+ m_pic8259_slave->ir1_w(state);
+ break;
+ case 10:
+ m_pic8259_slave->ir2_w(state);
+ break;
+ case 11:
+ m_pic8259_slave->ir3_w(state);
+ break;
+ case 12:
+ m_pic8259_slave->ir4_w(state);
+ break;
+ case 14:
+ m_pic8259_slave->ir6_w(state);
+ break;
+ case 15:
+ m_pic8259_slave->ir7_w(state);
+ break;
+ }
+}
+
uint8_t sis85c496_host_device::at_portb_r()
{
uint8_t data = m_at_speaker;
@@ -584,17 +733,24 @@ void sis85c496_host_device::at_portb_w(uint8_t data)
m_pit8254->write_gate2(BIT(data, 0));
at_speaker_set_spkrdata( BIT(data, 1));
m_channel_check = BIT(data, 3);
- //m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
+ if (m_channel_check)
+ m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
+}
+
+void sis85c496_host_device::iochck_w(int state)
+{
+ if (!state && !m_channel_check && m_nmi_enabled)
+ m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
}
uint8_t sis85c496_host_device::at_dma8237_2_r(offs_t offset)
{
- return m_dma8237_2->read( offset / 2);
+ return m_dma8237_2->read(offset / 2);
}
void sis85c496_host_device::at_dma8237_2_w(offs_t offset, uint8_t data)
{
- m_dma8237_2->write( offset / 2, data);
+ m_dma8237_2->write(offset / 2, data);
}
uint8_t sis85c496_host_device::at_keybc_r(offs_t offset)
@@ -617,10 +773,9 @@ void sis85c496_host_device::at_keybc_w(offs_t offset, uint8_t data)
}
}
-
-void sis85c496_host_device::rtc_nmi_w(uint8_t data)
+void sis85c496_host_device::rtc_address_nmi_w(uint8_t data)
{
- m_nmi_enabled = BIT(data,7);
+ m_nmi_enabled = BIT(data, 7);
//m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0));
m_ds12885->address_w(data);
}
diff --git a/src/devices/machine/sis85c496.h b/src/devices/machine/sis85c496.h
index 1636b2177e0bd..47cb0729655bb 100644
--- a/src/devices/machine/sis85c496.h
+++ b/src/devices/machine/sis85c496.h
@@ -46,6 +46,25 @@ class sis85c496_host_device : public pci_host_device {
void set_cpu_tag(const char *tag);
void set_ram_size(int ram_size);
+ void pc_pirqa_w(int state);
+ void pc_pirqb_w(int state);
+ void pc_pirqc_w(int state);
+ void pc_pirqd_w(int state);
+
+ void pc_irq1_w(int state);
+ void pc_irq3_w(int state);
+ void pc_irq4_w(int state);
+ void pc_irq5_w(int state);
+ void pc_irq6_w(int state);
+ void pc_irq7_w(int state);
+ void pc_irq8n_w(int state);
+ void pc_irq9_w(int state);
+ void pc_irq10_w(int state);
+ void pc_irq11_w(int state);
+ void pc_irq12m_w(int state);
+ void pc_irq14_w(int state);
+ void pc_irq15_w(int state);
+
protected:
virtual void device_start() override;
virtual void device_reset() override;
@@ -90,6 +109,8 @@ class sis85c496_host_device : public pci_host_device {
uint8_t m_channel_check;
uint8_t m_nmi_enabled;
+ uint8_t m_pirqrc[4];
+
int ram_size;
std::vector ram;
uint32_t m_mailbox;
@@ -150,15 +171,24 @@ class sis85c496_host_device : public pci_host_device {
void pc_dack7_w(int state);
uint8_t at_dma8237_2_r(offs_t offset);
void at_dma8237_2_w(offs_t offset, uint8_t data);
+ void iochck_w(int state);
uint8_t at_keybc_r(offs_t offset);
void at_keybc_w(offs_t offset, uint8_t data);
- void rtc_nmi_w(uint8_t data);
+ u8 rtc_address_r();
+ void rtc_address_nmi_w(uint8_t data);
uint8_t pc_dma_read_byte(offs_t offset);
void pc_dma_write_byte(offs_t offset, uint8_t data);
uint8_t pc_dma_read_word(offs_t offset);
void pc_dma_write_word(offs_t offset, uint8_t data);
void cpu_a20_w(int state);
void cpu_reset_w(int state);
+
+ uint8_t pirqrc_r(offs_t offset);
+ void pirqrc_w(offs_t offset, uint8_t data);
+ void redirect_irq(int irq, int state);
+
+ int pin_mapper(int pin);
+ void irq_handler(int line, int state);
};
DECLARE_DEVICE_TYPE(SIS85C496_HOST, sis85c496_host_device)
diff --git a/src/devices/machine/spi_sdcard.cpp b/src/devices/machine/spi_sdcard.cpp
index 57ef4e8796994..5ceb121108cfb 100644
--- a/src/devices/machine/spi_sdcard.cpp
+++ b/src/devices/machine/spi_sdcard.cpp
@@ -34,8 +34,8 @@
#define LOG_COMMAND (1U << 1)
#define LOG_SPI (1U << 2)
-//#define VERBOSE (LOG_COMMAND)
-#define LOG_OUTPUT_FUNC osd_printf_info
+//#define VERBOSE (LOG_GENERAL | LOG_COMMAND)
+//#define LOG_OUTPUT_FUNC osd_printf_info
#include "logmacro.h"
@@ -259,8 +259,43 @@ void spi_sdcard_device::do_command()
break;
case 9: // CMD9 - SEND_CSD
- m_data[0] = 0x00; // TODO
- send_data(1, SD_STATE_STBY);
+ m_data[0] = 0x00;
+ m_data[1] = 0xff;
+ m_data[2] = 0xfe;
+
+ //if (m_type == SD_TYPE_V2) // CSD Version 1.0
+ {
+ u8 block_len = 9;
+ for (auto i = m_blksize >> 10; i; i >>= 1, ++block_len);
+
+ m_data[3] = 0x00; // 127: CSD_STRUCTURE:2 (00b) 0:6
+ m_data[4] = 0x0e; // 119: TAAC:8
+ m_data[5] = 0x00; // 111: NSAC:8
+ m_data[6] = 0x32; // 103: TRAN_SPEED:8 (32h or 5Ah)
+ m_data[7] = 0x5b; // 95: CCC:12 (01x110110101b)
+ m_data[8] = 0x50; // .. READ_BL_LN:4
+ m_data[8] |= block_len;
+ m_data[9] = 0x83; // 79: READ_BL_PARTIAL:1 (1b) WRITE_BLK_MISALIGN:1 READ_BLK_MISALIGN:1 DSR_IMP:1 0:2 C_SIZE:12
+ m_data[10] = 0xff; // ..
+ m_data[11] = 0xed; // .. VDD_R_CURR_MIN:3 VDD_R_CURR_MAX:3
+ m_data[12] = 0xb7; // 55: VDD_W_CURR_MIN:3 VDD_W_CURR_MAX:3 C_SIZE_MUL:3
+ m_data[13] = 0xbf; // .. ERASE_BLK_EN:1 SECTOR_SIZE:7
+ m_data[14] = 0xbf; // .. WP_GRP_SIZE:7
+ m_data[15] = 0x04; // 31: WP_GRP_ENABLE:1 0:2 R2W_FACTOR:3 WRITE_BL_LEN:4
+ m_data[15] |= (block_len >> 2);
+ m_data[16] = 0x00; /// .. WRITE_BL_PARTIAL:1 0:5
+ m_data[16] |= (block_len & 3) << 6;
+ m_data[17] = 0x00; // 15: FILE_FORMAT_GRP:1 COPY:1 PERM_WRITE_PROTECT:1 TMP_WRITE_PROTECT:1 FILE_FORMAT:2 WP_UPC:1 0:1
+ m_data[18] = 0x01; // 7: CRC7 1:1
+ }
+ /*
+ else // SD_TYPE_HC: CSD Version 2.0
+ {
+ m_data[3] = 0x40;
+ }
+ */
+
+ send_data(3 + 16, SD_STATE_STBY);
break;
case 10: // CMD10 - SEND_CID
diff --git a/src/devices/machine/w83787f.cpp b/src/devices/machine/w83787f.cpp
new file mode 100644
index 0000000000000..03ea4d935442d
--- /dev/null
+++ b/src/devices/machine/w83787f.cpp
@@ -0,0 +1,346 @@
+// license:BSD-3-Clause
+// copyright-holders: Angelo Salese
+/**************************************************************************************************
+
+Winbond W83787IF / W83787F
+
+'F is the base, 'IF adds IrDA.
+Looks similar in design to National PC87306 (including similar reg names)
+
+**************************************************************************************************/
+
+#include "emu.h"
+#include "bus/isa/isa.h"
+#include "machine/w83787f.h"
+
+#define LOG_WARN (1U << 1)
+
+#define VERBOSE (LOG_GENERAL | LOG_WARN)
+//#define LOG_OUTPUT_FUNC osd_printf_info
+#include "logmacro.h"
+
+#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
+
+DEFINE_DEVICE_TYPE(W83787F, w83787f_device, "w83787f", "National Semiconductor W83787F Super I/O Enhanced Sidewinder Lite")
+
+w83787f_device::w83787f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, W83787F, tag, owner, clock)
+ , device_isa16_card_interface(mconfig, *this)
+ , device_memory_interface(mconfig, *this)
+ , m_space_config("superio_config_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(w83787f_device::config_map), this))
+ , m_pc_com(*this, "uart%d", 0U)
+ , m_pc_lpt(*this, "lpta")
+ , m_irq1_callback(*this)
+ , m_irq8_callback(*this)
+ , m_irq9_callback(*this)
+ , m_txd1_callback(*this)
+ , m_ndtr1_callback(*this)
+ , m_nrts1_callback(*this)
+ , m_txd2_callback(*this)
+ , m_ndtr2_callback(*this)
+ , m_nrts2_callback(*this)
+{ }
+
+
+void w83787f_device::device_start()
+{
+ set_isa_device();
+ //m_isa->set_dma_channel(0, this, true);
+ //m_isa->set_dma_channel(1, this, true);
+ //m_isa->set_dma_channel(2, this, true);
+ //m_isa->set_dma_channel(3, this, true);
+ remap(AS_IO, 0, 0x400);
+}
+
+void w83787f_device::device_reset()
+{
+ m_locked_state = true;
+ m_cr1 = 0;
+}
+
+device_memory_interface::space_config_vector w83787f_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+void w83787f_device::device_add_mconfig(machine_config &config)
+{
+ PC_LPT(config, m_pc_lpt);
+ m_pc_lpt->irq_handler().set(FUNC(w83787f_device::irq_parallel_w));
+
+ NS16550(config, m_pc_com[0], XTAL(1'843'200));
+ m_pc_com[0]->out_int_callback().set(FUNC(w83787f_device::irq_serial1_w));
+ m_pc_com[0]->out_tx_callback().set(FUNC(w83787f_device::txd_serial1_w));
+ m_pc_com[0]->out_dtr_callback().set(FUNC(w83787f_device::dtr_serial1_w));
+ m_pc_com[0]->out_rts_callback().set(FUNC(w83787f_device::rts_serial1_w));
+
+ NS16550(config, m_pc_com[1], XTAL(1'843'200));
+ m_pc_com[1]->out_int_callback().set(FUNC(w83787f_device::irq_serial2_w));
+ m_pc_com[1]->out_tx_callback().set(FUNC(w83787f_device::txd_serial2_w));
+ m_pc_com[1]->out_dtr_callback().set(FUNC(w83787f_device::dtr_serial2_w));
+ m_pc_com[1]->out_rts_callback().set(FUNC(w83787f_device::rts_serial2_w));
+}
+
+void w83787f_device::remap(int space_id, offs_t start, offs_t end)
+{
+ if (space_id == AS_IO)
+ {
+ m_isa->install_device(0x0250, 0x0252, read8sm_delegate(*this, FUNC(w83787f_device::read)), write8sm_delegate(*this, FUNC(w83787f_device::write)));
+
+ //if (BIT(m_fer, 0))
+ const u8 lpt_setting = (m_cr1 >> 4) & 3;
+ if (lpt_setting != 3)
+ {
+ const u16 lpt_port[3] = { 0x3bc, 0x278, 0x378 };
+ const u16 lpt_addr = lpt_port[lpt_setting & 3];
+ LOG("Map LPT1 to I/O port %04x-%04x\n", lpt_addr, lpt_addr + 3);
+
+ m_isa->install_device(lpt_addr, lpt_addr + 3, read8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::read)), write8sm_delegate(*m_pc_lpt, FUNC(pc_lpt_device::write)));
+ }
+
+ for (int i = 0; i < 2; i++)
+ {
+ const u8 uart_setting = (BIT(m_cr1, 2 + i) >> 1) | (BIT(m_cr1, i));
+ if (uart_setting != 3)
+ {
+ const u16 uart_port[3] = { 0x2e8, 0x3e8, 0x3f8 };
+ const u16 uart_addr = uart_port[uart_setting & 3] ^ (i ? 0x100 : 0x000);
+ LOG("Map UART%c to I/O port %04x-%04x\n", i ? 'A' : 'B', uart_addr, uart_addr + 7);
+ m_isa->install_device(uart_addr, uart_addr + 7, read8sm_delegate(*m_pc_com[i], FUNC(ns16450_device::ins8250_r)), write8sm_delegate(*m_pc_com[i], FUNC(ns16450_device::ins8250_w)));
+ }
+ }
+ }
+}
+
+u8 w83787f_device::read(offs_t offset)
+{
+ if (offset != 2 && !machine().side_effects_disabled())
+ {
+ LOGWARN("Invalid %s access read\n", offset & 1 ? "EFIR" : "EFIR");
+ return space().unmap();
+ }
+
+ if (m_locked_state)
+ return space().unmap();
+
+ return space().read_byte(m_index);
+}
+
+void w83787f_device::write(offs_t offset, u8 data)
+{
+ switch (offset)
+ {
+ // EFER
+ // TODO: 0x89 with GMRD# pin
+ case 0: m_locked_state = (data != 0x88); break;
+ // EFIR
+ case 1: m_index = data; break;
+ // EFDR
+ case 2:
+ if (!m_locked_state)
+ space().write_byte(m_index, data);
+ break;
+ }
+}
+
+// none of these regs have a real naming, they are all CR*
+void w83787f_device::config_map(address_map &map)
+{
+// map(0x00, 0x00) IDE & FDC
+ map(0x01, 0x01).lrw8(
+ NAME([this] (offs_t offset) {
+ return m_cr1;
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ m_cr1 = data;
+ remap(AS_IO, 0, 0x400);
+ })
+ );
+// map(0x02, 0x02) extension adapter mode
+// map(0x03, 0x03) game port, UART clocks
+// map(0x04, 0x04) game port, UARTA/B power-down tristate
+// map(0x05, 0x05) ECP FIFO threshold
+// map(0x06, 0x06) 2x / x4 FDD select, FDC power-down tristate, IDE power-down tristate
+// map(0x07, 0x07) FDDs type
+// map(0x08, 0x08) automatic power-down, FDD write protect
+// map(0x09, 0x09) CHIP ID, lock alias, operating mode
+// map(0x0a, 0x0a) LPT pins
+// map(0x0c, 0x0c) UARTA/B clock source, lock select
+// map(0x0d, 0x0d) IrDA select
+// map(0x0e, 0x0f)
+// map(0x10, 0x10) GIO0 address select 7-0
+// map(0x11, 0x11) GIO0 address select 10-8, GI0 address MODE0-1
+// map(0x12, 0x12) GIO1 address select 7-0
+// map(0x13, 0x13) GIO1 address select 10-8, GI0 address MODE0-1
+// map(0x14, 0x14) GIO0 ddr/mode
+// map(0x15, 0x15) GIO1 ddr/mode
+}
+
+/*
+ * Serial
+ */
+
+void w83787f_device::irq_serial1_w(int state)
+{
+ if ((m_cr1 & 0x05) == 0x05)
+ return;
+ request_irq(3, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void w83787f_device::irq_serial2_w(int state)
+{
+ if ((m_cr1 & 0x0a) == 0x0a)
+ return;
+ request_irq(4, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void w83787f_device::txd_serial1_w(int state)
+{
+ if ((m_cr1 & 0x05) == 0x05)
+ return;
+ m_txd1_callback(state);
+}
+
+void w83787f_device::txd_serial2_w(int state)
+{
+ if ((m_cr1 & 0x0a) == 0x0a)
+ return;
+ m_txd2_callback(state);
+}
+
+void w83787f_device::dtr_serial1_w(int state)
+{
+ if ((m_cr1 & 0x05) == 0x05)
+ return;
+ m_ndtr1_callback(state);
+}
+
+void w83787f_device::dtr_serial2_w(int state)
+{
+ if ((m_cr1 & 0x0a) == 0x0a)
+ return;
+ m_ndtr2_callback(state);
+}
+
+void w83787f_device::rts_serial1_w(int state)
+{
+ if ((m_cr1 & 0x05) == 0x05)
+ return;
+ m_nrts1_callback(state);
+}
+
+void w83787f_device::rts_serial2_w(int state)
+{
+ if ((m_cr1 & 0x0a) == 0x0a)
+ return;
+ m_nrts2_callback(state);
+}
+
+void w83787f_device::rxd1_w(int state)
+{
+ m_pc_com[0]->rx_w(state);
+}
+
+void w83787f_device::ndcd1_w(int state)
+{
+ m_pc_com[0]->dcd_w(state);
+}
+
+void w83787f_device::ndsr1_w(int state)
+{
+ m_pc_com[0]->dsr_w(state);
+}
+
+void w83787f_device::nri1_w(int state)
+{
+ m_pc_com[0]->ri_w(state);
+}
+
+void w83787f_device::ncts1_w(int state)
+{
+ m_pc_com[0]->cts_w(state);
+}
+
+void w83787f_device::rxd2_w(int state)
+{
+ m_pc_com[1]->rx_w(state);
+}
+
+void w83787f_device::ndcd2_w(int state)
+{
+ m_pc_com[1]->dcd_w(state);
+}
+
+void w83787f_device::ndsr2_w(int state)
+{
+ m_pc_com[1]->dsr_w(state);
+}
+
+void w83787f_device::nri2_w(int state)
+{
+ m_pc_com[1]->ri_w(state);
+}
+
+void w83787f_device::ncts2_w(int state)
+{
+ m_pc_com[1]->cts_w(state);
+}
+
+/*
+ * Parallel
+ */
+
+void w83787f_device::irq_parallel_w(int state)
+{
+ if ((m_cr1 & 0x30) == 0x30)
+ return;
+ request_irq(5, state ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void w83787f_device::request_irq(int irq, int state)
+{
+ switch (irq)
+ {
+ case 1:
+ m_irq1_callback(state);
+ break;
+ case 3:
+ m_isa->irq3_w(state);
+ break;
+ case 4:
+ m_isa->irq4_w(state);
+ break;
+ case 5:
+ m_isa->irq5_w(state);
+ break;
+ case 6:
+ m_isa->irq6_w(state);
+ break;
+ case 7:
+ m_isa->irq7_w(state);
+ break;
+ case 8:
+ m_irq8_callback(state);
+ break;
+ case 9:
+ m_irq9_callback(state);
+ break;
+ case 10:
+ m_isa->irq10_w(state);
+ break;
+ case 11:
+ m_isa->irq11_w(state);
+ break;
+ case 12:
+ m_isa->irq12_w(state);
+ break;
+ case 14:
+ m_isa->irq14_w(state);
+ break;
+ case 15:
+ m_isa->irq15_w(state);
+ break;
+ }
+}
diff --git a/src/devices/machine/w83787f.h b/src/devices/machine/w83787f.h
new file mode 100644
index 0000000000000..3fa9e6e4b8c50
--- /dev/null
+++ b/src/devices/machine/w83787f.h
@@ -0,0 +1,95 @@
+// license:BSD-3-Clause
+// copyright-holders: Angelo Salese
+
+#ifndef MAME_MACHINE_W83787F_H
+#define MAME_MACHINE_W83787F_H
+
+#pragma once
+
+#include "bus/isa/isa.h"
+#include "machine/ins8250.h"
+#include "machine/pc_lpt.h"
+
+class w83787f_device : public device_t,
+ public device_isa16_card_interface,
+ public device_memory_interface
+{
+public:
+ w83787f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ ~w83787f_device() {}
+
+ void remap(int space_id, offs_t start, offs_t end) override;
+
+// auto gp20_reset() { return m_gp20_reset_callback.bind(); }
+// auto gp25_gatea20() { return m_gp25_gatea20_callback.bind(); }
+ auto irq1() { return m_irq1_callback.bind(); }
+ auto irq8() { return m_irq8_callback.bind(); }
+ auto irq9() { return m_irq9_callback.bind(); }
+ auto txd1() { return m_txd1_callback.bind(); }
+ auto ndtr1() { return m_ndtr1_callback.bind(); }
+ auto nrts1() { return m_nrts1_callback.bind(); }
+ auto txd2() { return m_txd2_callback.bind(); }
+ auto ndtr2() { return m_ndtr2_callback.bind(); }
+ auto nrts2() { return m_nrts2_callback.bind(); }
+
+ void rxd1_w(int state);
+ void ndcd1_w(int state);
+ void ndsr1_w(int state);
+ void nri1_w(int state);
+ void ncts1_w(int state);
+ void rxd2_w(int state);
+ void ndcd2_w(int state);
+ void ndsr2_w(int state);
+ void nri2_w(int state);
+ void ncts2_w(int state);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual space_config_vector memory_space_config() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ const address_space_config m_space_config;
+
+ required_device_array m_pc_com;
+ required_device m_pc_lpt;
+
+ devcb_write_line m_irq1_callback;
+ devcb_write_line m_irq8_callback;
+ devcb_write_line m_irq9_callback;
+ devcb_write_line m_txd1_callback;
+ devcb_write_line m_ndtr1_callback;
+ devcb_write_line m_nrts1_callback;
+ devcb_write_line m_txd2_callback;
+ devcb_write_line m_ndtr2_callback;
+ devcb_write_line m_nrts2_callback;
+
+ void request_irq(int irq, int state);
+
+ u8 read(offs_t offset);
+ void write(offs_t offset, u8 data);
+
+ void config_map(address_map &map);
+
+ void irq_parallel_w(int state);
+
+ void irq_serial1_w(int state);
+ void txd_serial1_w(int state);
+ void dtr_serial1_w(int state);
+ void rts_serial1_w(int state);
+ void irq_serial2_w(int state);
+ void txd_serial2_w(int state);
+ void dtr_serial2_w(int state);
+ void rts_serial2_w(int state);
+
+ u8 m_index = 0;
+
+ bool m_locked_state = true;
+ u8 m_cr1 = 0;
+};
+
+DECLARE_DEVICE_TYPE(W83787F, w83787f_device);
+
+#endif // MAME_MACHINE_W83787F_H
diff --git a/src/devices/sound/okim6258.cpp b/src/devices/sound/okim6258.cpp
index 349fe9ca13c91..171100e208097 100644
--- a/src/devices/sound/okim6258.cpp
+++ b/src/devices/sound/okim6258.cpp
@@ -2,15 +2,15 @@
// copyright-holders:Barry Rodewald
/**********************************************************************************************
*
- * OKI MSM6258 ADPCM
+ * OKI MSM6258 ADPCM Speech Processor
*
* TODO:
- * 3-bit ADPCM support
- * Recording?
+ * - 3-bit ADPCM support
+ * - Use okiadpcm.* helper?
+ * - Recording?
*
**********************************************************************************************/
-
#include "emu.h"
#include "okim6258.h"
@@ -46,19 +46,19 @@ DEFINE_DEVICE_TYPE(OKIM6258, okim6258_device, "okim6258", "OKI MSM6258 ADPCM")
// okim6258_device - constructor
//-------------------------------------------------
-okim6258_device::okim6258_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, OKIM6258, tag, owner, clock),
- device_sound_interface(mconfig, *this),
- m_status(0),
- m_start_divider(0),
- m_divider(512),
- m_adpcm_type(0),
- m_data_in(0),
- m_nibble_shift(0),
- m_stream(nullptr),
- m_output_bits(0),
- m_signal(0),
- m_step(0)
+okim6258_device::okim6258_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, OKIM6258, tag, owner, clock),
+ device_sound_interface(mconfig, *this),
+ m_status(0),
+ m_start_divider(0),
+ m_divider(512),
+ m_adpcm_type(0),
+ m_data_in(0),
+ m_nibble_shift(0),
+ m_stream(nullptr),
+ m_output_bits(0),
+ m_signal(0),
+ m_step(0)
{
}
@@ -93,7 +93,7 @@ static void compute_tables()
for (nib = 0; nib < 16; nib++)
{
diff_lookup[step*16 + nib] = nbl2bit[nib][0] *
- (stepval * nbl2bit[nib][1] +
+ (stepval * nbl2bit[nib][1] +
stepval/2 * nbl2bit[nib][2] +
stepval/4 * nbl2bit[nib][3] +
stepval/8);
@@ -119,7 +119,13 @@ void okim6258_device::device_start()
m_signal = -2;
m_step = 0;
- state_save_register();
+ // register for savestates
+ save_item(NAME(m_status));
+ save_item(NAME(m_divider));
+ save_item(NAME(m_data_in));
+ save_item(NAME(m_nibble_shift));
+ save_item(NAME(m_signal));
+ save_item(NAME(m_step));
}
@@ -171,25 +177,6 @@ void okim6258_device::sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) override;
private:
- void state_save_register();
int16_t clock_adpcm(uint8_t nibble);
uint8_t m_status;
uint32_t m_start_divider;
- uint32_t m_divider; /* master clock divider */
- uint8_t m_adpcm_type; /* 3/4 bit ADPCM select */
- uint8_t m_data_in; /* ADPCM data-in register */
- uint8_t m_nibble_shift; /* nibble select */
- sound_stream *m_stream; /* which stream are we playing on? */
-
- uint8_t m_output_bits; /* D/A precision is 10-bits but 12-bit data can be
- output serially to an external DAC */
+ uint32_t m_divider; // master clock divider
+ uint8_t m_adpcm_type; // 3/4 bit ADPCM select
+ uint8_t m_data_in; // ADPCM data-in register
+ uint8_t m_nibble_shift; // nibble select
+ sound_stream *m_stream; // which stream are we playing on?
+
+ uint8_t m_output_bits; // D/A precision is 10-bits but 12-bit data can be output serially to an external DAC
int32_t m_signal;
int32_t m_step;
diff --git a/src/devices/sound/okim6588.cpp b/src/devices/sound/okim6588.cpp
new file mode 100644
index 0000000000000..84b1a9a303380
--- /dev/null
+++ b/src/devices/sound/okim6588.cpp
@@ -0,0 +1,230 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+OKI MSM6588 ADPCM Recorder
+
+It has similar functionality to MSM6258.
+
+TODO:
+- it only supports MCU mode EXT playback, nothing else emulated yet
+- status register read (eg. BUSY flag)
+
+*/
+
+#include "emu.h"
+#include "okim6588.h"
+
+
+DEFINE_DEVICE_TYPE(OKIM6588, okim6588_device, "okim6588", "OKI MSM6588 ADPCM Recorder")
+
+//-------------------------------------------------
+// constructor
+//-------------------------------------------------
+
+okim6588_device::okim6588_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, OKIM6588, tag, owner, clock),
+ device_sound_interface(mconfig, *this),
+ m_write_mon(*this),
+ m_chip_mode(CHIP_MODE_STANDALONE)
+{ }
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+// allow save_item on a non-fundamental type
+ALLOW_SAVE_TYPE(okim6588_device::chip_mode);
+ALLOW_SAVE_TYPE(okim6588_device::command_state);
+ALLOW_SAVE_TYPE(okim6588_device::run_state);
+
+void okim6588_device::device_start()
+{
+ // initialize
+ m_stream = stream_alloc(0, 1, clock() / 128);
+
+ m_adpcm_timer = timer_alloc(FUNC(okim6588_device::clock_adpcm), this);
+ m_mon_timer = timer_alloc(FUNC(okim6588_device::set_mon), this);
+
+ m_command_state = COMMAND_READY;
+ m_run_state = RUN_STOP;
+ m_adpcm_data = 0;
+
+ m_vds_bit = (m_chip_mode == CHIP_MODE_MCU) ? 1 : 0;
+ m_samp_fdiv = 512;
+ m_rec_mode = false;
+
+ // register for savestates
+ save_item(NAME(m_chip_mode));
+ save_item(NAME(m_command_state));
+ save_item(NAME(m_run_state));
+ save_item(NAME(m_adpcm_data));
+ save_item(NAME(m_adpcm.m_signal));
+ save_item(NAME(m_adpcm.m_step));
+ save_item(NAME(m_rec_mode));
+ save_item(NAME(m_samp_fdiv));
+ save_item(NAME(m_vds_bit));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void okim6588_device::device_reset()
+{
+ m_command_state = COMMAND_READY;
+ m_run_state = RUN_STOP;
+ reset_adpcm();
+
+ m_adpcm_timer->adjust(attotime::never);
+ m_mon_timer->adjust(attotime::never);
+ m_write_mon(0);
+}
+
+
+//-------------------------------------------------
+// internal handlers
+//-------------------------------------------------
+
+void okim6588_device::sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs)
+{
+ // simply fill the buffer with the current sample
+ outputs[0].fill(m_adpcm.output() / 2048.0);
+}
+
+TIMER_CALLBACK_MEMBER(okim6588_device::clock_adpcm)
+{
+ switch (m_run_state)
+ {
+ case RUN_STOP:
+ reset_adpcm();
+ break;
+
+ case RUN_PLAY_EXT:
+ // strobe MON
+ m_write_mon(1);
+ m_mon_timer->adjust(attotime::from_ticks(m_samp_fdiv / 4, clock()), 0);
+ m_command_state = COMMAND_EXT;
+
+ m_stream->update();
+ get_adpcm_sample(m_adpcm_data);
+ break;
+
+ default:
+ break;
+ }
+
+ if (m_run_state != RUN_STOP && m_run_state != RUN_PAUSE)
+ m_adpcm_timer->adjust(attotime::from_ticks(m_samp_fdiv, clock()));
+}
+
+TIMER_CALLBACK_MEMBER(okim6588_device::set_mon)
+{
+ m_write_mon(param ? 1 : 0);
+}
+
+s16 okim6588_device::get_adpcm_sample(u8 data)
+{
+ // 4-bit or 3-bit input
+ if (m_vds_bit)
+ return m_adpcm.clock(data & 0xf);
+ else
+ return m_adpcm.clock((data & 0xc) | (data >> 1 & 1));
+}
+
+void okim6588_device::reset_adpcm()
+{
+ m_stream->update();
+ m_adpcm_data = 0;
+ m_adpcm.reset();
+}
+
+
+//-------------------------------------------------
+// public handlers
+//-------------------------------------------------
+
+u8 okim6588_device::data_r()
+{
+ if (m_chip_mode != CHIP_MODE_MCU)
+ return 0;
+
+ return 0;
+}
+
+void okim6588_device::data_w(u8 data)
+{
+ if (m_chip_mode != CHIP_MODE_MCU)
+ return;
+
+ data &= 0xf;
+
+ switch (m_command_state)
+ {
+ case COMMAND_READY:
+ switch (data & 0xf)
+ {
+ // NOP
+ case 0x0:
+ break;
+
+ // PLAY/REC
+ case 0x2: case 0x3:
+ m_rec_mode = bool(data & 1);
+ break;
+
+ // STOP
+ case 0x5:
+ m_run_state = RUN_STOP;
+ break;
+
+ // SAMP
+ case 0x6:
+ m_command_state = COMMAND_SAMP;
+ break;
+
+ // VDS
+ case 0xc:
+ m_command_state = COMMAND_VDS;
+ break;
+
+ // EXT
+ case 0xb:
+ m_run_state = m_rec_mode ? RUN_RECORD_EXT : RUN_PLAY_EXT;
+ reset_adpcm();
+
+ // minimum delay is 1 sample
+ m_adpcm_timer->adjust(attotime::from_ticks(m_samp_fdiv, clock()));
+ m_command_state = COMMAND_EXT;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case COMMAND_SAMP:
+ {
+ static const u16 div[4] = { 1024, 768, 640, 512 };
+ m_samp_fdiv = div[data & 3];
+ m_command_state = COMMAND_READY;
+ break;
+ }
+
+ case COMMAND_EXT:
+ m_adpcm_data = data;
+ m_command_state = COMMAND_READY;
+ break;
+
+ case COMMAND_VDS:
+ m_vds_bit = BIT(data, 2);
+ m_command_state = COMMAND_READY;
+ break;
+
+ default:
+ // shouldn't get here
+ break;
+ }
+}
diff --git a/src/devices/sound/okim6588.h b/src/devices/sound/okim6588.h
new file mode 100644
index 0000000000000..28bcec029aabc
--- /dev/null
+++ b/src/devices/sound/okim6588.h
@@ -0,0 +1,88 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ OKI MSM6588 ADPCM Recorder
+
+*/
+
+#ifndef MAME_SOUND_OKIM6588_H
+#define MAME_SOUND_OKIM6588_H
+
+#pragma once
+
+#include "sound/okiadpcm.h"
+
+
+class okim6588_device : public device_t, public device_sound_interface
+{
+public:
+ okim6588_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ auto write_mon() { return m_write_mon.bind(); }
+ void set_mcum_pin(int state) { m_chip_mode = state ? CHIP_MODE_MCU : CHIP_MODE_STANDALONE; }
+
+ // D0-D3 (MCU mode)
+ void data_w(u8 data);
+ u8 data_r();
+
+protected:
+ // device_t implementation
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) override;
+
+private:
+ enum chip_mode : u8
+ {
+ CHIP_MODE_STANDALONE = 0,
+ CHIP_MODE_MCU
+ };
+
+ enum command_state : u8
+ {
+ COMMAND_READY = 0,
+ COMMAND_SAMP,
+ COMMAND_EXT,
+ COMMAND_VDS
+ };
+
+ enum run_state : u8
+ {
+ RUN_STOP = 0,
+ RUN_PAUSE,
+ RUN_PLAY_SERIAL,
+ RUN_PLAY_EXT,
+ RUN_RECORD_SERIAL,
+ RUN_RECORD_EXT,
+ };
+
+ devcb_write_line m_write_mon;
+
+ chip_mode m_chip_mode;
+ command_state m_command_state;
+ run_state m_run_state;
+
+ sound_stream *m_stream;
+
+ u8 m_adpcm_data;
+ oki_adpcm_state m_adpcm;
+ bool m_rec_mode;
+ u16 m_samp_fdiv;
+ u8 m_vds_bit;
+
+ emu_timer *m_adpcm_timer;
+ emu_timer *m_mon_timer;
+
+ TIMER_CALLBACK_MEMBER(clock_adpcm);
+ TIMER_CALLBACK_MEMBER(set_mon);
+ s16 get_adpcm_sample(u8 data);
+ void reset_adpcm();
+};
+
+
+DECLARE_DEVICE_TYPE(OKIM6588, okim6588_device)
+
+#endif // MAME_SOUND_OKIM6588_H
diff --git a/src/devices/video/hd61603.cpp b/src/devices/video/hd61603.cpp
index bdc2cd7aa6637..d9187fd78fa66 100644
--- a/src/devices/video/hd61603.cpp
+++ b/src/devices/video/hd61603.cpp
@@ -14,7 +14,7 @@ Hitachi HD61603 LCD Driver
*/
#include "emu.h"
-#include "video/hd61603.h"
+#include "hd61603.h"
DEFINE_DEVICE_TYPE(HD61603, hd61603_device, "hd61603", "Hitachi HD61603 LCD Driver")
diff --git a/src/devices/video/hd61603.h b/src/devices/video/hd61603.h
index 8de7c8797612b..bffb2b73848a0 100644
--- a/src/devices/video/hd61603.h
+++ b/src/devices/video/hd61603.h
@@ -45,7 +45,7 @@ class hd61603_device : public device_t
void data_w(u8 data);
protected:
- // device-level overrides
+ // device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
diff --git a/src/devices/video/lc7580.cpp b/src/devices/video/lc7580.cpp
index 81b705769f945..42b2a6783d7b9 100644
--- a/src/devices/video/lc7580.cpp
+++ b/src/devices/video/lc7580.cpp
@@ -134,7 +134,7 @@ void lc7580_device::clk_w(int state)
state = (state) ? 1 : 0;
// clock shift register
- if (!state && m_clk)
+ if (state && !m_clk)
m_shift = m_shift >> 1 | u64(m_data) << 55;
m_clk = state;
diff --git a/src/devices/video/pc_vga_ati.cpp b/src/devices/video/pc_vga_ati.cpp
index 171ab494a375c..39564407f46e2 100644
--- a/src/devices/video/pc_vga_ati.cpp
+++ b/src/devices/video/pc_vga_ati.cpp
@@ -12,7 +12,7 @@
#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
-DEFINE_DEVICE_TYPE(ATI_VGA, ati_vga_device, "ati_vga", "ATi VGA")
+DEFINE_DEVICE_TYPE(ATI_VGA, ati_vga_device, "ati_vga", "ATi VGA i/f")
ati_vga_device::ati_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ati_vga_device(mconfig, ATI_VGA, tag, owner, clock)
diff --git a/src/devices/video/pc_vga_cirrus.cpp b/src/devices/video/pc_vga_cirrus.cpp
index 4240eea56806c..deda877381e42 100644
--- a/src/devices/video/pc_vga_cirrus.cpp
+++ b/src/devices/video/pc_vga_cirrus.cpp
@@ -51,9 +51,9 @@
#define TEXT_COPY_9COLUMN(ch) (((ch & 0xe0) == 0xc0)&&(vga.attribute.data[0x10]&4))
-DEFINE_DEVICE_TYPE(CIRRUS_GD5428, cirrus_gd5428_device, "clgd5428", "Cirrus Logic GD5428")
-DEFINE_DEVICE_TYPE(CIRRUS_GD5430, cirrus_gd5430_device, "clgd5430", "Cirrus Logic GD5430")
-DEFINE_DEVICE_TYPE(CIRRUS_GD5446, cirrus_gd5446_device, "clgd5446", "Cirrus Logic GD5446")
+DEFINE_DEVICE_TYPE(CIRRUS_GD5428, cirrus_gd5428_device, "clgd5428", "Cirrus Logic GD5428 i/f")
+DEFINE_DEVICE_TYPE(CIRRUS_GD5430, cirrus_gd5430_device, "clgd5430", "Cirrus Logic GD5430 i/f")
+DEFINE_DEVICE_TYPE(CIRRUS_GD5446, cirrus_gd5446_device, "clgd5446", "Cirrus Logic GD5446 i/f")
cirrus_gd5428_device::cirrus_gd5428_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
diff --git a/src/devices/video/pc_vga_matrox.cpp b/src/devices/video/pc_vga_matrox.cpp
index 1d2650fb5832b..181c2581a2c7a 100644
--- a/src/devices/video/pc_vga_matrox.cpp
+++ b/src/devices/video/pc_vga_matrox.cpp
@@ -6,7 +6,7 @@
#define DEBUG_VRAM_VIEWER 0
-DEFINE_DEVICE_TYPE(MATROX_VGA, matrox_vga_device, "matrox_vga", "Matrox MGA2064W VGA")
+DEFINE_DEVICE_TYPE(MATROX_VGA, matrox_vga_device, "matrox_vga", "Matrox MGA2064W VGA i/f")
matrox_vga_device::matrox_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: svga_device(mconfig, MATROX_VGA, tag, owner, clock)
diff --git a/src/devices/video/pc_vga_oak.cpp b/src/devices/video/pc_vga_oak.cpp
index e5654a14b0c0c..88245f9cf5196 100644
--- a/src/devices/video/pc_vga_oak.cpp
+++ b/src/devices/video/pc_vga_oak.cpp
@@ -13,7 +13,7 @@
#define LOGBANK(...) LOGMASKED(LOG_BANK, __VA_ARGS__)
-DEFINE_DEVICE_TYPE(OTI111, oak_oti111_vga_device, "oti111_vga", "Oak Technologies Spitfire 64111")
+DEFINE_DEVICE_TYPE(OTI111, oak_oti111_vga_device, "oti111_vga", "Oak Technologies Spitfire 64111 i/f")
oak_oti111_vga_device::oak_oti111_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: svga_device(mconfig, OTI111, tag, owner, clock)
diff --git a/src/devices/video/pc_vga_paradise.cpp b/src/devices/video/pc_vga_paradise.cpp
index 006eb812944c5..6c2d543429dc1 100644
--- a/src/devices/video/pc_vga_paradise.cpp
+++ b/src/devices/video/pc_vga_paradise.cpp
@@ -44,12 +44,12 @@ Paradise / Western Digital (S)VGA chipsets
#define LOGLOCKED(...) LOGMASKED(LOG_LOCKED, __VA_ARGS__)
-DEFINE_DEVICE_TYPE(PVGA1A, pvga1a_vga_device, "pvga1a_vga", "Paradise Systems PVGA1A")
-DEFINE_DEVICE_TYPE(WD90C00, wd90c00_vga_device, "wd90c00_vga", "Western Digital WD90C00 \"PVGA1B\" VGA Controller")
-DEFINE_DEVICE_TYPE(WD90C11A, wd90c11a_vga_device, "wd90c11a_vga", "Western Digital WD90C11A \"PVGA1C\" VGA Controller")
-DEFINE_DEVICE_TYPE(WD90C30, wd90c30_vga_device, "wd90c30_vga", "Western Digital WD90C30 \"PVGA1D\" VGA Controller")
-DEFINE_DEVICE_TYPE(WD90C31, wd90c31_vga_device, "wd90c31_vga", "Western Digital WD90C31 VGA Controller")
-DEFINE_DEVICE_TYPE(WD90C33, wd90c33_vga_device, "wd90c33_vga", "Western Digital WD90C33 VGA Controller")
+DEFINE_DEVICE_TYPE(PVGA1A, pvga1a_vga_device, "pvga1a_vga", "Paradise Systems PVGA1A i/f")
+DEFINE_DEVICE_TYPE(WD90C00, wd90c00_vga_device, "wd90c00_vga", "Western Digital WD90C00 \"PVGA1B\" VGA i/f")
+DEFINE_DEVICE_TYPE(WD90C11A, wd90c11a_vga_device, "wd90c11a_vga", "Western Digital WD90C11A \"PVGA1C\" VGA i/f")
+DEFINE_DEVICE_TYPE(WD90C30, wd90c30_vga_device, "wd90c30_vga", "Western Digital WD90C30 \"PVGA1D\" VGA i/f")
+DEFINE_DEVICE_TYPE(WD90C31, wd90c31_vga_device, "wd90c31_vga", "Western Digital WD90C31 VGA i/f")
+DEFINE_DEVICE_TYPE(WD90C33, wd90c33_vga_device, "wd90c33_vga", "Western Digital WD90C33 VGA i/f")
pvga1a_vga_device::pvga1a_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
diff --git a/src/devices/video/pc_vga_s3.cpp b/src/devices/video/pc_vga_s3.cpp
index 2bab4deef24bb..4dc582141ed10 100644
--- a/src/devices/video/pc_vga_s3.cpp
+++ b/src/devices/video/pc_vga_s3.cpp
@@ -21,39 +21,44 @@ enum
MACH8_DRAWING_SCAN
};
+DEFINE_DEVICE_TYPE(S3_VISION864_VGA, s3vision864_vga_device, "s3_86c864_vga", "S3 86c864 Vision864 VGA i/f")
+DEFINE_DEVICE_TYPE(S3_VISION964_VGA, s3vision964_vga_device, "s3_86c964_vga", "S3 86c964 Vision964 VGA i/f")
+DEFINE_DEVICE_TYPE(S3_VISION968_VGA, s3vision968_vga_device, "s3_86c968_vga", "S3 86c968 Vision968 VGA i/f")
+DEFINE_DEVICE_TYPE(S3_TRIO64_VGA, s3trio64_vga_device, "s3_86c764_vga", "S3 86c764 Trio64 VGA i/f")
-DEFINE_DEVICE_TYPE(S3_VGA, s3_vga_device, "s3_vga", "S3 Graphics VGA")
-
-s3_vga_device::s3_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : s3_vga_device(mconfig, S3_VGA, tag, owner, clock)
+s3vision864_vga_device::s3vision864_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : s3vision864_vga_device(mconfig, S3_VISION864_VGA, tag, owner, clock)
{
-
}
-s3_vga_device::s3_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+s3vision864_vga_device::s3vision864_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: svga_device(mconfig, type, tag, owner, clock)
{
- m_crtc_space_config = address_space_config("crtc_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(s3_vga_device::crtc_map), this));
- m_seq_space_config = address_space_config("sequencer_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(s3_vga_device::sequencer_map), this));
+ m_crtc_space_config = address_space_config("crtc_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(s3vision864_vga_device::crtc_map), this));
+ m_seq_space_config = address_space_config("sequencer_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(s3vision864_vga_device::sequencer_map), this));
}
-void s3_vga_device::device_add_mconfig(machine_config &config)
+void s3vision864_vga_device::device_add_mconfig(machine_config &config)
{
IBM8514A(config, "8514a", 0).set_vga_owner();
}
-TIMER_CALLBACK_MEMBER(s3_vga_device::vblank_timer_cb)
+TIMER_CALLBACK_MEMBER(s3vision864_vga_device::vblank_timer_cb)
{
- // not sure if this is correct, but XF86_S3 seems to expect the viewport scrolling to be faster
if(s3.memory_config & 0x08)
- vga.crtc.start_addr = vga.crtc.start_addr_latch << 2;
+ {
+ // - SDD scrolling test expects a << 2 for 8bpp and no shift for anything else
+ // - Slackware 3.x XF86_S3 expect a << 2 shift (to be confirmed)
+ // - przonegd expect no shift (RGB16)
+ vga.crtc.start_addr = vga.crtc.start_addr_latch << (svga.rgb8_en ? 2 : 0);
+ }
else
vga.crtc.start_addr = vga.crtc.start_addr_latch;
vga.attribute.pel_shift = vga.attribute.pel_shift_latch;
m_vblank_timer->adjust( screen().time_until_pos(vga.crtc.vert_blank_start + vga.crtc.vert_blank_end) );
}
-void s3_vga_device::device_start()
+void s3vision864_vga_device::device_start()
{
svga_device::device_start();
memset(&s3, 0, sizeof(s3));
@@ -65,30 +70,29 @@ void s3_vga_device::device_start()
s3.cursor_bg[x] = 0x00;
}
m_8514 = subdevice("8514a");
- // set device ID
- s3.id_high = 0x88; // CR2D
- s3.id_low = 0x11; // CR2E
- s3.revision = 0x00; // CR2F
- s3.id_cr30 = 0xe1; // CR30
+
+ s3.id_high = s3.id_low = s3.revision = 0; //
+ s3.id_cr30 = 0xc1;
}
-void s3_vga_device::device_reset()
+void s3vision864_vga_device::device_reset()
{
vga_device::device_reset();
// Power-on strapping bits. Sampled at reset, but can be modified later.
// These are just assumed defaults.
+ // TODO: expose as configuration option (PD pins)
s3.strapping = 0x000f0b1e;
s3.sr10 = 0x42;
s3.sr11 = 0x41;
}
-u16 s3_vga_device::line_compare_mask()
+u16 s3vision864_vga_device::line_compare_mask()
{
// TODO: pinpoint condition
return svga.rgb8_en ? 0x7ff : 0x3ff;
}
-uint16_t s3_vga_device::offset()
+uint16_t s3vision864_vga_device::offset()
{
//popmessage("Offset: %04x %s %s %s",vga.crtc.offset,vga.crtc.dw?"DW":"--",vga.crtc.word_mode?"BYTE":"WORD",(s3.memory_config & 0x08)?"31":"--");
if(s3.memory_config & 0x08)
@@ -96,7 +100,7 @@ uint16_t s3_vga_device::offset()
return vga_device::offset();
}
-void s3_vga_device::s3_define_video_mode()
+void s3vision864_vga_device::s3_define_video_mode()
{
int divisor = 1;
int xtal = ((vga.miscellaneous_output & 0xc) ? XTAL(28'636'363) : XTAL(25'174'800)).value();
@@ -115,17 +119,32 @@ void s3_vga_device::s3_define_video_mode()
svga.rgb15_en = 0;
svga.rgb16_en = 0;
svga.rgb32_en = 0;
+ // FIXME: vision864 has only first 7 modes
switch((s3.ext_misc_ctrl_2) >> 4)
{
+ // 0001 Mode 8: 2x 8-bit 1 VCLK/2 pixels
case 0x01: svga.rgb8_en = 1; break;
+ // 0010 Mode 1: 15-bit 2 VCLK/pixel
+ case 0x02: svga.rgb15_en = 1; break;
+ // 0011 Mode 9: 15-bit 1 VCLK/pixel
case 0x03: svga.rgb15_en = 1; divisor = 2; break;
+ // 0100 Mode 2: 24-bit 3 VCLK/pixel
+ case 0x04: svga.rgb24_en = 1; break;
+ // 0101 Mode 10: 16-bit 1 VCLK/pixel
case 0x05: svga.rgb16_en = 1; divisor = 2; break;
+ // 0110 Mode 3: 16-bit 2 VCLK/pixel
+ case 0x06: svga.rgb16_en = 1; break;
+ // 0111 Mode 11: 24/32-bit 2 VCLK/pixel
+ case 0x07: svga.rgb32_en = 1; divisor = 4; break;
case 0x0d: svga.rgb32_en = 1; divisor = 1; break;
- default: fatalerror("TODO: S3 colour mode not implemented %02x\n",((s3.ext_misc_ctrl_2) >> 4));
+ default:
+ popmessage("pc_vga_s3: PA16B-COLOR-MODE %02x\n",((s3.ext_misc_ctrl_2) >> 4));
+ break;
}
}
else
{
+ // 0000: Mode 0 8-bit 1 VCLK/pixel
svga.rgb8_en = (s3.memory_config & 8) >> 3;
svga.rgb15_en = 0;
svga.rgb16_en = 0;
@@ -134,7 +153,7 @@ void s3_vga_device::s3_define_video_mode()
recompute_params_clock(divisor, xtal);
}
-void s3_vga_device::refresh_pitch_offset()
+void s3vision864_vga_device::refresh_pitch_offset()
{
// bit 2 = bit 8 of offset register, but only if bits 4-5 of CR51 are 00h.
vga.crtc.offset &= 0xff;
@@ -144,7 +163,7 @@ void s3_vga_device::refresh_pitch_offset()
vga.crtc.offset |= (s3.cr51 & 0x30) << 4;
}
-void s3_vga_device::crtc_map(address_map &map)
+void s3vision864_vga_device::crtc_map(address_map &map)
{
svga_device::crtc_map(map);
map(0x2d, 0x2d).lr8(
@@ -180,6 +199,7 @@ void s3_vga_device::crtc_map(address_map &map)
s3_define_video_mode();
})
);
+ // TODO: CR32, CR33 & CR34 (backward compatibility)
map(0x35, 0x35).lrw8(
NAME([this] (offs_t offset) {
return s3.crt_reg_lock;
@@ -213,6 +233,7 @@ void s3_vga_device::crtc_map(address_map &map)
return (s3.strapping & 0x0000ff00) >> 8; // enable chipset, 64k BIOS size, internal DCLK/MCLK
}),
NAME([this] (offs_t offset, u8 data) {
+ // TODO: monitor ID at 7-5 (PD15-13)
if(s3.reg_lock2 == 0xa5)
{
s3.strapping = (s3.strapping & 0xffff00ff) | (data << 8);
@@ -516,6 +537,7 @@ bit 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the
s3.extended_dac_ctrl = data;
})
);
+ // TODO: bits 7-4 (w/o?) for GPIO
map(0x5c, 0x5c).lr8(
NAME([this] (offs_t offset) {
u8 res = 0;
@@ -645,9 +667,10 @@ bit 0 Vertical Total bit 10. Bit 10 of the Vertical Total register (3d4h
);
}
-void s3_vga_device::sequencer_map(address_map &map)
+void s3vision864_vga_device::sequencer_map(address_map &map)
{
svga_device::sequencer_map(map);
+ // TODO: SR8 (unlocks SRD)
// Memory CLK PLL
map(0x10, 0x10).lrw8(
NAME([this] (offs_t offset) { return s3.sr10; }),
@@ -700,7 +723,7 @@ void s3_vga_device::sequencer_map(address_map &map)
);
}
-uint8_t s3_vga_device::mem_r(offs_t offset)
+uint8_t s3vision864_vga_device::mem_r(offs_t offset)
{
if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb32_en)
{
@@ -734,7 +757,7 @@ uint8_t s3_vga_device::mem_r(offs_t offset)
return 0xff;
}
-void s3_vga_device::mem_w(offs_t offset, uint8_t data)
+void s3vision864_vga_device::mem_w(offs_t offset, uint8_t data)
{
ibm8514a_device* dev = get_8514();
// bit 4 of CR53 enables memory-mapped I/O
@@ -1004,7 +1027,7 @@ void s3_vga_device::mem_w(offs_t offset, uint8_t data)
}
-uint32_t s3_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+uint32_t s3vision864_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
svga_device::screen_update(screen, bitmap, cliprect);
@@ -1127,3 +1150,76 @@ uint32_t s3_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
}
return 0;
}
+
+/******************
+ *
+ * Vision 964
+ *
+ *****************/
+
+s3vision964_vga_device::s3vision964_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : s3vision964_vga_device(mconfig, S3_VISION964_VGA, tag, owner, clock)
+{
+}
+
+s3vision964_vga_device::s3vision964_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : s3vision864_vga_device(mconfig, type, tag, owner, clock)
+{
+}
+
+void s3vision964_vga_device::device_start()
+{
+ s3vision864_vga_device::device_start();
+ s3.id_high = s3.id_low = s3.revision = 0; //
+ s3.id_cr30 = 0xd0; // CR30, assume rev 0
+}
+
+/******************
+ *
+ * Vision968
+ *
+ *****************/
+
+s3vision968_vga_device::s3vision968_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : s3vision968_vga_device(mconfig, S3_VISION968_VGA, tag, owner, clock)
+{
+}
+
+s3vision968_vga_device::s3vision968_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : s3vision964_vga_device(mconfig, type, tag, owner, clock)
+{
+}
+
+void s3vision968_vga_device::device_start()
+{
+ s3vision964_vga_device::device_start();
+ s3.id_high = 0x88; // CR2D
+ s3.id_low = 0xf0; // CR2E
+ s3.revision = 0x00; // CR2F
+ s3.id_cr30 = 0xe1; // CR30
+}
+
+/******************
+ *
+ * Trio 64
+ *
+ *****************/
+
+s3trio64_vga_device::s3trio64_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : s3trio64_vga_device(mconfig, S3_TRIO64_VGA, tag, owner, clock)
+{
+}
+
+s3trio64_vga_device::s3trio64_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : s3vision968_vga_device(mconfig, type, tag, owner, clock)
+{
+}
+
+void s3trio64_vga_device::device_start()
+{
+ s3vision968_vga_device::device_start();
+ s3.id_high = 0x88; // CR2D
+ s3.id_low = 0x11; // CR2E
+ s3.revision = 0x00; // CR2F
+ s3.id_cr30 = 0xe1; // CR30
+}
diff --git a/src/devices/video/pc_vga_s3.h b/src/devices/video/pc_vga_s3.h
index b3a4060a67df7..90d54dbad85e6 100644
--- a/src/devices/video/pc_vga_s3.h
+++ b/src/devices/video/pc_vga_s3.h
@@ -10,12 +10,11 @@
#include "screen.h"
-
-class s3_vga_device : public svga_device
+class s3vision864_vga_device : public svga_device
{
public:
// construction/destruction
- s3_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ s3vision864_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual uint8_t mem_r(offs_t offset) override;
virtual void mem_w(offs_t offset, uint8_t data) override;
@@ -27,7 +26,7 @@ class s3_vga_device : public svga_device
ibm8514a_device* get_8514() { return m_8514; }
protected:
- s3_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ s3vision864_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
@@ -97,7 +96,40 @@ class s3_vga_device : public svga_device
void refresh_pitch_offset();
};
+class s3vision964_vga_device : public s3vision864_vga_device
+{
+public:
+ s3vision964_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ s3vision964_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ virtual void device_start() override;
+};
+
+class s3vision968_vga_device : public s3vision964_vga_device
+{
+public:
+ s3vision968_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ s3vision968_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ virtual void device_start() override;
+};
+
+class s3trio64_vga_device : public s3vision968_vga_device
+{
+public:
+ s3trio64_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ s3trio64_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ virtual void device_start() override;
+};
+
// device type definition
-DECLARE_DEVICE_TYPE(S3_VGA, s3_vga_device)
+DECLARE_DEVICE_TYPE(S3_VISION864_VGA, s3vision864_vga_device)
+DECLARE_DEVICE_TYPE(S3_VISION964_VGA, s3vision964_vga_device)
+DECLARE_DEVICE_TYPE(S3_VISION968_VGA, s3vision968_vga_device)
+DECLARE_DEVICE_TYPE(S3_TRIO64_VGA, s3trio64_vga_device)
#endif // MAME_VIDEO_PC_VGA_S3_H
diff --git a/src/devices/video/pc_vga_sis.cpp b/src/devices/video/pc_vga_sis.cpp
index ee1a1d04f7f06..944034613b483 100644
--- a/src/devices/video/pc_vga_sis.cpp
+++ b/src/devices/video/pc_vga_sis.cpp
@@ -34,7 +34,7 @@ VBE 3.0, Multi Buffering & Virtual Scrolling available
// TODO: later variant of 5598
// (definitely doesn't have dual segment mode for instance)
-DEFINE_DEVICE_TYPE(SIS630_SVGA, sis630_svga_device, "sis630_svga", "SiS 630 SVGA")
+DEFINE_DEVICE_TYPE(SIS630_SVGA, sis630_svga_device, "sis630_svga", "SiS 630 VGA i/f")
sis630_svga_device::sis630_svga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: svga_device(mconfig, SIS630_SVGA, tag, owner, clock)
diff --git a/src/devices/video/pc_vga_trident.cpp b/src/devices/video/pc_vga_trident.cpp
index 7d45171c50afc..f12c03e46c3e6 100644
--- a/src/devices/video/pc_vga_trident.cpp
+++ b/src/devices/video/pc_vga_trident.cpp
@@ -41,8 +41,8 @@
#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__)
#define LOGCRTC(...) LOGMASKED(LOG_CRTC, __VA_ARGS__)
-DEFINE_DEVICE_TYPE(TRIDENT_VGA, tgui9860_device, "trident_vga", "Trident TGUI9860")
-DEFINE_DEVICE_TYPE(TVGA9000_VGA, tvga9000_device, "tvga9000_vga", "Trident TVGA9000")
+DEFINE_DEVICE_TYPE(TRIDENT_VGA, tgui9860_device, "trident_vga", "Trident TGUI9860 VGA i/f")
+DEFINE_DEVICE_TYPE(TVGA9000_VGA, tvga9000_device, "tvga9000_vga", "Trident TVGA9000 VGA i/f")
trident_vga_device::trident_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: svga_device(mconfig, type, tag, owner, clock)
diff --git a/src/devices/video/pc_vga_tseng.cpp b/src/devices/video/pc_vga_tseng.cpp
index 9d85a96c37e5a..288ac1bc85081 100644
--- a/src/devices/video/pc_vga_tseng.cpp
+++ b/src/devices/video/pc_vga_tseng.cpp
@@ -19,7 +19,7 @@
// TODO: refactor this macro
#define GRAPHIC_MODE (vga.gc.alpha_dis) /* else text mode */
-DEFINE_DEVICE_TYPE(TSENG_VGA, tseng_vga_device, "tseng_vga", "Tseng Labs ET4000AX SVGA")
+DEFINE_DEVICE_TYPE(TSENG_VGA, tseng_vga_device, "tseng_vga", "Tseng Labs ET4000AX VGA i/f")
tseng_vga_device::tseng_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: svga_device(mconfig, TSENG_VGA, tag, owner, clock)
diff --git a/src/devices/video/s3virge.cpp b/src/devices/video/s3virge.cpp
index 86bb320af0b7d..0c433b718643d 100644
--- a/src/devices/video/s3virge.cpp
+++ b/src/devices/video/s3virge.cpp
@@ -62,7 +62,7 @@ s3virge_vga_device::s3virge_vga_device(const machine_config &mconfig, const char
}
s3virge_vga_device::s3virge_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : s3_vga_device(mconfig, type, tag, owner, clock)
+ : s3trio64_vga_device(mconfig, type, tag, owner, clock)
, m_linear_config_changed_cb(*this)
{
}
@@ -169,7 +169,7 @@ void s3virge_vga_device::s3d_reset()
void s3virge_vga_device::device_reset()
{
- s3_vga_device::device_reset();
+ s3trio64_vga_device::device_reset();
// Power-on strapping bits. Sampled at reset, but can be modified later.
// These are just assumed defaults.
s3.strapping = 0x000f0912;
@@ -200,12 +200,12 @@ uint16_t s3virge_vga_device::offset()
// this breaks VBETest, which detects these VESA modes as 32bpp.
if(svga.rgb24_en)
return vga.crtc.offset * 6;
- return s3_vga_device::offset();
+ return s3trio64_vga_device::offset();
}
void s3virge_vga_device::crtc_map(address_map &map)
{
- s3_vga_device::crtc_map(map);
+ s3trio64_vga_device::crtc_map(map);
// TODO: verify these overrides
map(0x3a, 0x3a).lw8(
NAME([this] (offs_t offset, u8 data) {
diff --git a/src/devices/video/s3virge.h b/src/devices/video/s3virge.h
index 00fe1282241dc..d1288abcc0b90 100644
--- a/src/devices/video/s3virge.h
+++ b/src/devices/video/s3virge.h
@@ -16,7 +16,7 @@
// ======================> s3virge_vga_device
-class s3virge_vga_device : public s3_vga_device
+class s3virge_vga_device : public s3trio64_vga_device
{
public:
// construction/destruction
diff --git a/src/devices/video/scn2674.cpp b/src/devices/video/scn2674.cpp
index b3b8af01388da..ed34dfa85b27a 100644
--- a/src/devices/video/scn2674.cpp
+++ b/src/devices/video/scn2674.cpp
@@ -49,7 +49,7 @@ scn2674_device::scn2674_device(const machine_config &mconfig, device_type type,
, m_mbc_char_cb(*this, 0)
, m_mbc_attr_cb(*this, 0)
, m_IR_pointer(0)
- , m_screen1_address(0), m_screen2_address(0)
+ , m_screen1_address(0), m_screen2_address(0), m_screen2_address_start(0)
, m_cursor_address(0)
, m_irq_register(0), m_status_register(0), m_irq_mask(0)
, m_gfx_enabled(false)
@@ -121,6 +121,7 @@ void scn2674_device::device_start()
save_item(NAME(m_linecounter));
save_item(NAME(m_screen1_address));
save_item(NAME(m_screen2_address));
+ save_item(NAME(m_screen2_address_start));
save_item(NAME(m_cursor_address));
save_item(NAME(m_IR_pointer));
save_item(NAME(m_irq_register));
@@ -174,6 +175,7 @@ void scn2674_device::device_reset()
{
m_screen1_address = 0;
m_screen2_address = 0;
+ m_screen2_address_start = 0;
m_cursor_address = 0;
m_irq_register = 0;
m_status_register = 0;
@@ -975,6 +977,7 @@ void scn2674_device::write_screen2_address(bool msb, uint8_t data)
}
else
m_screen2_address = (m_screen2_address & 0x3f00) | data;
+ m_screen2_address_start = m_screen2_address;
}
void scn2672_device::write_screen2_address(bool msb, uint8_t data)
@@ -1197,6 +1200,7 @@ TIMER_CALLBACK_MEMBER(scn2674_device::vblank_timer)
m_irq_register |= 0x10;
m_intr_cb(ASSERT_LINE);
}
+ m_screen2_address = m_screen2_address_start;
}
uint32_t scn2674_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
diff --git a/src/devices/video/scn2674.h b/src/devices/video/scn2674.h
index 0304982bbc087..8654cd839c4f5 100644
--- a/src/devices/video/scn2674.h
+++ b/src/devices/video/scn2674.h
@@ -62,6 +62,7 @@ class scn2674_device : public device_t,
uint8_t m_IR_pointer;
uint16_t m_screen1_address;
uint16_t m_screen2_address;
+ uint16_t m_screen2_address_start;
uint16_t m_cursor_address;
uint8_t m_irq_register;
uint8_t m_status_register;
diff --git a/src/devices/video/voodoo_pci.cpp b/src/devices/video/voodoo_pci.cpp
index 864be7c6b1be5..69d5eb51451a7 100644
--- a/src/devices/video/voodoo_pci.cpp
+++ b/src/devices/video/voodoo_pci.cpp
@@ -122,13 +122,25 @@ void voodoo_1_pci_device::device_start()
void voodoo_2_pci_device::device_start()
{
- // FIXME: proper PCI values (check manual)
+ // TODO: straps class code from fb_addr_a[6] (if =1 then 0x040000)
set_ids(0x121a0002, 0x02, 0x038000, 0x000000);
voodoo_pci_device::device_start();
add_map(16 * 1024 * 1024, M_MEM | M_PREF, *m_voodoo, FUNC(voodoo_2_device::core_map));
bank_infos[0].adr = 0xff000000;
+
+ command = 0;
+ command_mask = 2;
+ // FIXME: straps from fb_addr_b[1] (AGP) / fb_addr_a[8]
+ // (fast back-to-back & fast/medium DEVSEL#)
+ //status = 0x0280;
+ status = 0;
+
+ // reported with default 0
+ intr_line = 0;
+ // INTA#
+ intr_pin = 1;
}
void voodoo_banshee_pci_device::device_start()
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 5c5a186e2aa1d..fd0093bd28323 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -25,7 +25,6 @@
#include "uiinput.h"
#include "corestr.h"
-#include "coreutil.h"
#include "osdepend.h"
#include "xmlfile.h"
@@ -1727,7 +1726,7 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const
buffer.data_get(pc, dasmresult & util::disasm_interface::LENGTHMASK, true, opbuf);
// return a CRC of the exact count of opcode bytes
- return core_crc32(0, &opbuf[0], opbuf.size());
+ return util::crc32_creator::simple(&opbuf[0], opbuf.size());
}
diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h
index fe6ae26cb2ccf..89e15e4c54140 100644
--- a/src/emu/emufwd.h
+++ b/src/emu/emufwd.h
@@ -38,7 +38,6 @@ class output_module;
// declared in osdepend.h
class osd_font;
class osd_interface;
-class osd_midi_device;
diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp
index 2712a5121a707..60ea12f9400e2 100644
--- a/src/emu/rendfont.cpp
+++ b/src/emu/rendfont.cpp
@@ -16,7 +16,6 @@
#include "render.h"
#include "corestr.h"
-#include "coreutil.h"
#include "multibyte.h"
#include "path.h"
@@ -883,7 +882,7 @@ bool render_font::load_cached_bdf(std::string_view filename)
m_rawdata.clear();
return false;
}
- u32 const hash(core_crc32(0, reinterpret_cast(&m_rawdata[0]), bytes));
+ u32 const hash(util::crc32_creator::simple(&m_rawdata[0], bytes));
// create the cached filename, changing the 'F' to a 'C' on the extension
std::string cachedname(filename, 0, filename.length() - ((4U < filename.length()) && core_filename_ends_with(filename, ".bdf") ? 4 : 0));
diff --git a/src/emu/save.cpp b/src/emu/save.cpp
index 6f49e6b2b0614..8c3329e7b38b7 100644
--- a/src/emu/save.cpp
+++ b/src/emu/save.cpp
@@ -27,7 +27,6 @@
#include "main.h"
-#include "util/coreutil.h"
#include "util/ioprocs.h"
#include "util/ioprocsfilter.h"
@@ -495,11 +494,11 @@ inline save_error save_manager::do_read(T check_length, U read_block, V start_he
u32 save_manager::signature() const
{
// iterate over entries
- u32 crc = 0;
+ util::crc32_creator crc;
for (auto &entry : m_entry_list)
{
// add the entry name to the CRC
- crc = core_crc32(crc, (u8 *)entry->m_name.c_str(), entry->m_name.length());
+ crc.append(entry->m_name.data(), entry->m_name.length());
// add the type and size to the CRC
u32 temp[4];
@@ -507,9 +506,9 @@ u32 save_manager::signature() const
temp[1] = little_endianize_int32(entry->m_typecount);
temp[2] = little_endianize_int32(entry->m_blockcount);
temp[3] = little_endianize_int32(entry->m_stride);
- crc = core_crc32(crc, (u8 *)&temp[0], sizeof(temp));
+ crc.append(&temp[0], sizeof(temp));
}
- return crc;
+ return crc.finish();
}
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp
index c05d01159fa2c..8ed4e64fac3d8 100644
--- a/src/frontend/mame/ui/miscmenu.cpp
+++ b/src/frontend/mame/ui/miscmenu.cpp
@@ -200,19 +200,21 @@ bool menu_network_devices::handle(event const *ev)
}
else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT)
{
+ // FIXME: this conflates presumably arbitrary interface ID numbers with 0-based indices
device_network_interface *const network = (device_network_interface *)ev->itemref;
+ auto const &interfaces = get_netdev_list();
int curr = network->get_interface();
if (ev->iptkey == IPT_UI_LEFT)
curr--;
else
curr++;
if (curr == -2)
- curr = netdev_count() - 1;
+ curr = interfaces.size() - 1;
network->set_interface(curr);
curr = network->get_interface();
const char *title = nullptr;
- for (auto &entry : get_netdev_list())
+ for (auto &entry : interfaces)
{
if (entry->id == curr)
{
diff --git a/src/lib/formats/flopimg.cpp b/src/lib/formats/flopimg.cpp
index ec978817a6e36..cb18b2036c9fa 100644
--- a/src/lib/formats/flopimg.cpp
+++ b/src/lib/formats/flopimg.cpp
@@ -864,7 +864,7 @@ void floppy_image_format_t::generate_track_from_bitstream(int track, int head, c
normalize_times(dest, track_size*2);
- if(splice >= 0 || splice < track_size) {
+ if(splice >= 0 && splice < track_size) {
int splpos = uint64_t(200000000) * splice / track_size;
image.set_write_splice_position(track, head, splpos, subtrack);
}
diff --git a/src/lib/util/bitstream.h b/src/lib/util/bitstream.h
index 2866d28c20d39..eb8b200532973 100644
--- a/src/lib/util/bitstream.h
+++ b/src/lib/util/bitstream.h
@@ -175,6 +175,10 @@ inline uint32_t bitstream_in::read_offset() const
result--;
bits -= 8;
}
+
+ if (m_dbitoffs > bits)
+ result++;
+
return result;
}
@@ -190,7 +194,11 @@ inline uint32_t bitstream_in::flush()
m_doffset--;
m_bits -= 8;
}
- m_bits = m_buffer = 0;
+
+ if (m_dbitoffs > m_bits)
+ m_doffset++;
+
+ m_bits = m_buffer = m_dbitoffs = 0;
return m_doffset;
}
diff --git a/src/lib/util/coreutil.cpp b/src/lib/util/coreutil.cpp
index 94ec6dec27364..cebbceb037e66 100644
--- a/src/lib/util/coreutil.cpp
+++ b/src/lib/util/coreutil.cpp
@@ -10,7 +10,6 @@
#include "coreutil.h"
#include
-#include
/***************************************************************************
@@ -55,14 +54,3 @@ uint32_t bcd_2_dec(uint32_t a)
}
return result;
}
-
-
-
-/***************************************************************************
- MISC
-***************************************************************************/
-
-uint32_t core_crc32(uint32_t crc, const uint8_t *buf, uint32_t len)
-{
- return crc32(crc, buf, len);
-}
diff --git a/src/lib/util/coreutil.h b/src/lib/util/coreutil.h
index 1f487232619ef..813deb27a837f 100644
--- a/src/lib/util/coreutil.h
+++ b/src/lib/util/coreutil.h
@@ -72,11 +72,4 @@ inline int gregorian_days_in_month(int month, int year)
return result;
}
-
-/***************************************************************************
- MISC
-***************************************************************************/
-
-uint32_t core_crc32(uint32_t crc, const uint8_t *buf, uint32_t len);
-
#endif // MAME_UTIL_COREUTIL_H
diff --git a/src/mame/apple/maclc.cpp b/src/mame/apple/maclc.cpp
index 7be70f0efc4b1..05bc7205cca41 100644
--- a/src/mame/apple/maclc.cpp
+++ b/src/mame/apple/maclc.cpp
@@ -3,11 +3,21 @@
/****************************************************************************
maclc.cpp
- Mac LC, LC II, Classic II, Color Classic
+ Mac LC, LC II, Classic II, Color Classic, Macintosh TV
By R. Belmont
These are all lower-end machines based on versions of the "V8" system
- controller, which has a 10 MB hard limit on RAM.
+ controller, which has a 10 MB hard limit on RAM (8MB in the Mac TV).
+
+ Mac TV video input chips:
+ TEA63330T - Sound fader control unit for car stereos
+ I2C: address 1000000x
+ TDA8708BT - Video analog input interface
+ SAA7197 T - Clock signal generator circuit for desktop video systems
+ SAA7191 WP - Digital multistandard colour decoder
+ I2C: address 1000101x
+ SAA7186 H - Digital video scaler
+ I2C: address 1011100x
****************************************************************************/
@@ -39,7 +49,6 @@
#include "screen.h"
#include "softlist_dev.h"
-
namespace {
#define C32M (31.3344_MHz_XTAL)
@@ -73,6 +82,7 @@ class maclc_state : public driver_device
void maclc2(machine_config &config);
void macclas2(machine_config &config);
void maccclas(machine_config &config);
+ void mactv(machine_config &config);
void maclc_map(address_map &map);
void maccclassic_map(address_map &map);
@@ -335,7 +345,7 @@ void maclc_state::maclc_base(machine_config &config)
m_scsihelp->timeout_error_callback().set(FUNC(maclc_state::scsi_berr_w));
SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd");
- SOFTWARE_LIST(config, "cd_list").set_original("mac_cdrom").set_filter("MC68020");
+ SOFTWARE_LIST(config, "cd_list").set_original("mac_cdrom").set_filter("MC68020,MC68020_32");
SOFTWARE_LIST(config, "flop35hd_list").set_original("mac_hdflop");
SCC85C30(config, m_scc, C7M);
@@ -416,7 +426,7 @@ void maclc_state::maclc2(machine_config &config)
m_ram->set_extra_options("6M,8M,10M");
m_v8->set_baseram_is_4M(true);
- SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030");
+ SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
}
void maclc_state::maccclas(machine_config &config)
@@ -454,7 +464,46 @@ void maclc_state::maccclas(machine_config &config)
m_ram->set_extra_options("6M,8M,10M");
m_v8->set_baseram_is_4M(true);
- SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030");
+ SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
+}
+
+void maclc_state::mactv(machine_config &config)
+{
+ maclc_base(config);
+
+ M68030(config.replace(), m_maincpu, C32M);
+ m_maincpu->set_addrmap(AS_PROGRAM, &maclc_state::maccclassic_map);
+ m_maincpu->set_dasm_override(std::function(&mac68k_dasm_override), "mac68k_dasm_override");
+
+ config.device_remove("egret");
+ config.device_remove("fdc");
+
+ CUDA_V2XX(config, m_cuda, XTAL(32'768));
+ m_cuda->set_default_bios_tag("341s0788");
+ m_cuda->reset_callback().set(FUNC(maclc_state::egret_reset_w));
+ m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
+ m_cuda->via_clock_callback().set(m_v8, FUNC(v8_device::cb1_w));
+ m_cuda->via_data_callback().set(m_v8, FUNC(v8_device::cb2_w));
+ m_macadb->adb_data_callback().set(m_cuda, FUNC(cuda_device::set_adb_line));
+ config.set_perfect_quantum(m_maincpu);
+
+ TINKERBELL(config.replace(), m_v8, C15M);
+ m_v8->set_maincpu_tag("maincpu");
+ m_v8->set_rom_tag("bootrom");
+ m_v8->hdsel_callback().set(FUNC(maclc_state::hdsel_w));
+ m_v8->pb3_callback().set(m_cuda, FUNC(cuda_device::get_treq));
+ m_v8->pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
+ m_v8->pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
+ m_v8->cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
+
+ // Mac TV doesn't have an LC PDS
+ config.device_remove("pds");
+
+ m_ram->set_default_size("4M");
+ m_ram->set_extra_options("5M,6M,8M");
+ m_v8->set_baseram_is_4M(true);
+
+ SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
}
void maclc_state::macclas2(machine_config &config)
@@ -481,7 +530,7 @@ void maclc_state::macclas2(machine_config &config)
m_ram->set_extra_options("6M,8M,10M");
m_v8->set_baseram_is_4M(true);
- SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030");
+ SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
}
ROM_START(maclc)
@@ -510,9 +559,15 @@ ROM_START(maccclas)
ROM_LOAD("ecd99dc0.rom", 0x000000, 0x100000, CRC(c84c3aa5) SHA1(fd9e852e2d77fe17287ba678709b9334d4d74f1e))
ROM_END
+ROM_START(mactv)
+ ROM_REGION32_BE(0x100000, "bootrom", 0)
+ ROM_LOAD("eaf1678d.bin", 0x000000, 0x100000, CRC(0644f05b) SHA1(74975c60d3a560fac9ad63125bb65a750fceaede))
+ROM_END
+
} // anonymous namespace
COMP(1990, maclc, 0, 0, maclc, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh LC", MACHINE_SUPPORTS_SAVE)
COMP(1991, maclc2, 0, 0, maclc2, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh LC II", MACHINE_SUPPORTS_SAVE)
COMP(1991, macclas2, 0, 0, macclas2, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh Classic II", MACHINE_SUPPORTS_SAVE)
COMP(1993, maccclas, 0, 0, maccclas, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh Color Classic", MACHINE_SUPPORTS_SAVE)
+COMP(1994, mactv, 0, 0, mactv, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh TV", MACHINE_SUPPORTS_SAVE)
diff --git a/src/mame/apple/v8.cpp b/src/mame/apple/v8.cpp
index 02ecfbb4b8d2d..485c83762cfb1 100644
--- a/src/mame/apple/v8.cpp
+++ b/src/mame/apple/v8.cpp
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/*
- Apple "V8", "Eagle", and "Spice" system ASICs
+ Apple "V8", "Eagle", "Spice", and "Tinkerbell" system ASICs
Emulation by R. Belmont
V8 (343S0116 or 343-0155) contains the following:
@@ -22,6 +22,10 @@
and adds the option for an optional ROM expansion plus support for pushbutton sound volume
and display intensity controls and power saver mode.
+ Tinker Bell (343S1109) is an evolution of Spice with a simpler memory controller that has
+ an 8MB limit (4MB on the motherboard, 1, 2, or 4MB in the SIMM slot) and support for the
+ Macintosh TV's video input feature.
+
VISA (343S0101) is a predecessor of V8 and Eagle without support for dedicated VRAM banks
or VGA modes. It was coupled to a non-customized Bt450 RAMDAC on the Elsie prototype, and
did not offer video modes with more than 4 bits per pixel.
@@ -34,12 +38,13 @@
#include "emu.h"
#include "v8.h"
+#include "cpu/m68000/m68030.h"
#include "formats/ap_dsk35.h"
#include "layout/generic.h"
#define LOG_RAM (1U << 1)
-#define VERBOSE (LOG_RAM)
+#define VERBOSE (0)
#include "logmacro.h"
static constexpr u32 C7M = 7833600;
@@ -52,6 +57,7 @@ static constexpr u32 C15M = (C7M * 2);
DEFINE_DEVICE_TYPE(V8, v8_device, "v8", "Apple V8 system ASIC")
DEFINE_DEVICE_TYPE(EAGLE, eagle_device, "v8eagle", "Apple Eagle system ASIC")
DEFINE_DEVICE_TYPE(SPICE, spice_device, "v8spice", "Apple Spice system ASIC")
+DEFINE_DEVICE_TYPE(TINKERBELL, tinkerbell_device, "v8tkbell", "Apple Tinker Bell system ASIC")
static INPUT_PORTS_START( v8 )
PORT_START("MONTYPE")
@@ -94,8 +100,6 @@ void v8_device::device_add_mconfig(machine_config &config)
{
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(25175000, 800, 0, 640, 525, 0, 480);
- m_screen->set_size(1024, 768);
- m_screen->set_visarea(0, 640 - 1, 0, 480 - 1);
m_screen->set_screen_update(FUNC(v8_device::screen_update));
m_screen->screen_vblank().set(FUNC(v8_device::slot_irq_w<0x40>));
config.set_default_layout(layout_monitors);
@@ -133,6 +137,7 @@ v8_device::v8_device(const machine_config &mconfig, device_type type, const char
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_asc(*this, "asc"),
+ m_overlay(false),
write_pb4(*this),
write_pb5(*this),
write_cb2(*this),
@@ -142,7 +147,6 @@ v8_device::v8_device(const machine_config &mconfig, device_type type, const char
m_montype(*this, "MONTYPE"),
m_via1(*this, "via1"),
m_rom(*this, finder_base::DUMMY_TAG),
- m_overlay(false),
m_baseIs4M(false)
{
}
@@ -966,12 +970,17 @@ void spice_device::device_add_mconfig(machine_config &config)
applefdintf_device::add_35_nc(config, m_floppy[1]);
}
+spice_device::spice_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : v8_device(mconfig, type, tag, owner, clock),
+ m_fdc(*this, "fdc"),
+ m_floppy(*this, "fdc:%d", 0U),
+ m_cur_floppy(nullptr),
+ m_hdsel(0)
+{
+}
+
spice_device::spice_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : v8_device(mconfig, SPICE, tag, owner, clock),
- m_fdc(*this, "fdc"),
- m_floppy(*this, "fdc:%d", 0U),
- m_cur_floppy(nullptr),
- m_hdsel(0)
+ : spice_device(mconfig, SPICE, tag, owner, clock)
{
}
@@ -1166,3 +1175,181 @@ void spice_device::bright_contrast_w(offs_t offset, u8 data)
// offset 1 = contrast (0-255)
}
+// ================ tinkerbell_device
+
+void tinkerbell_device::device_add_mconfig(machine_config &config)
+{
+ spice_device::device_add_mconfig(config);
+ m_screen->set_raw(25175000, 800, 0, 640, 525, 0, 480);
+}
+
+tinkerbell_device::tinkerbell_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : spice_device(mconfig, TINKERBELL, tag, owner, clock)
+{
+}
+
+u8 tinkerbell_device::via_in_a()
+{
+ return 0x84;
+}
+
+u8 tinkerbell_device::pseudovia_r(offs_t offset)
+{
+ if (offset < 0x100)
+ {
+ if (offset == 0x10)
+ {
+ return 0x06 << 3; // ID as an Apple 13" 640x480 monitor
+ }
+ }
+
+ return v8_device::pseudovia_r(offset);
+}
+
+u32 tinkerbell_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ int hres, vres;
+ hres = 640;
+ vres = 480;
+
+ const pen_t *pens = m_palette->pens();
+ switch (m_pseudovia_regs[0x10] & 7)
+ {
+ case 0: // 1bpp
+ {
+ auto const vram8 = util::big_endian_cast(&m_vram[0]);
+
+ for (int y = 0; y < vres; y++)
+ {
+ u32 *scanline = &bitmap.pix(y);
+ for (int x = 0; x < hres; x += 8)
+ {
+ u8 const pixels = vram8[(y * 1024) + (x / 8)];
+
+ *scanline++ = pens[0x7f | (pixels & 0x80)];
+ *scanline++ = pens[0x7f | ((pixels << 1) & 0x80)];
+ *scanline++ = pens[0x7f | ((pixels << 2) & 0x80)];
+ *scanline++ = pens[0x7f | ((pixels << 3) & 0x80)];
+ *scanline++ = pens[0x7f | ((pixels << 4) & 0x80)];
+ *scanline++ = pens[0x7f | ((pixels << 5) & 0x80)];
+ *scanline++ = pens[0x7f | ((pixels << 6) & 0x80)];
+ *scanline++ = pens[0x7f | ((pixels << 7) & 0x80)];
+ }
+ }
+ }
+ break;
+
+ case 1: // 2bpp
+ {
+ auto const vram8 = util::big_endian_cast(&m_vram[0]);
+
+ for (int y = 0; y < vres; y++)
+ {
+ u32 *scanline = &bitmap.pix(y);
+ for (int x = 0; x < hres / 4; x++)
+ {
+ u8 const pixels = vram8[(y * 1024) + x];
+
+ *scanline++ = pens[0x3f | (pixels & 0xc0)];
+ *scanline++ = pens[0x3f | ((pixels << 2) & 0xc0)];
+ *scanline++ = pens[0x3f | ((pixels << 4) & 0xc0)];
+ *scanline++ = pens[0x3f | ((pixels << 6) & 0xc0)];
+ }
+ }
+ }
+ break;
+
+ case 2: // 4bpp
+ {
+ auto const vram8 = util::big_endian_cast(&m_vram[0]);
+
+ for (int y = 0; y < vres; y++)
+ {
+ u32 *scanline = &bitmap.pix(y);
+
+ for (int x = 0; x < hres / 2; x++)
+ {
+ u8 const pixels = vram8[(y * 1024) + x];
+
+ *scanline++ = pens[0x0f | (pixels & 0xf0)];
+ *scanline++ = pens[0x0f | ((pixels << 4) & 0xf0)];
+ }
+ }
+ }
+ break;
+
+ case 3: // 8bpp
+ {
+ auto const vram8 = util::big_endian_cast(&m_vram[0]);
+
+ for (int y = 0; y < vres; y++)
+ {
+ u32 *scanline = &bitmap.pix(y);
+
+ for (int x = 0; x < hres; x++)
+ {
+ u8 const pixels = vram8[(y * 1024) + x];
+ *scanline++ = pens[pixels];
+ }
+ }
+ }
+ break;
+
+ case 4: // 16bpp
+ {
+ auto const vram16 = util::big_endian_cast(&m_vram[0]);
+
+ for (int y = 0; y < vres; y++)
+ {
+ u32 *scanline = &bitmap.pix(y);
+ for (int x = 0; x < hres; x++)
+ {
+ u16 const pixels = vram16[(y * hres) + x];
+ *scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3);
+ }
+ }
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ Tinker Bell is different from the V8, but it still needs to kind of act like one.
+ The major difference: the RAM limit is 8MB instead of 10, and no RAM appears
+ above 0x7FFFFFFF. Also, when the bits are set for what on V8 would be 8MB SIMM
+ and no motherboard RAM except the 0x800000 image, that means 4MB of motherboard
+ and 4MB of SIMM here.
+*/
+void tinkerbell_device::ram_size(u8 config)
+{
+ if (!m_overlay)
+ {
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+ const void *mb_ram = m_ram_ptr;
+ u32 simm_size = m_ram_size - 0x400000;
+ void *simm_ram = &m_ram_ptr[0x400000 / 4];
+
+ space.unmap_readwrite(0x000000, 0x9fffff);
+
+ // place the motherboard RAM at 0
+ LOGMASKED(LOG_RAM, "Motherboard RAM at 0x00000000 to 0x003fffff\n");
+ space.install_ram(0, 0x3fffff, 0, (void *)mb_ram);
+
+ // is SIMM RAM present? it always goes at 0x400000
+ if (simm_size > 0)
+ {
+ if ((config & 0xc0) != 0)
+ {
+ LOGMASKED(LOG_RAM, "SIMM RAM at 0x400000 to %x\n", simm_size - 1);
+ space.install_ram(0x400000, (0x400000 + simm_size) - 1, 0, (void *)simm_ram);
+ }
+ }
+ else
+ {
+ LOGMASKED(LOG_RAM, "Base config, no SIMM\n");
+ }
+ }
+}
+
diff --git a/src/mame/apple/v8.h b/src/mame/apple/v8.h
index 411250f29e285..10cc8ec4cb72a 100644
--- a/src/mame/apple/v8.h
+++ b/src/mame/apple/v8.h
@@ -52,6 +52,8 @@ class v8_device : public device_t
u8 m_pseudovia_regs[256];
u32 *m_ram_ptr;
+ u32 m_ram_size;
+ bool m_overlay;
v8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
@@ -65,6 +67,8 @@ class v8_device : public device_t
void asc_irq(int state);
+ virtual void ram_size(u8 config);
+
private:
devcb_write_line write_pb4, write_pb5, write_cb2, write_hdsel, write_hmmu_enable;
devcb_read_line read_pb3;
@@ -77,13 +81,10 @@ class v8_device : public device_t
int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt;
u8 m_pseudovia_ier, m_pseudovia_ifr;
u8 m_pal_address, m_pal_idx, m_pal_control, m_pal_colkey;
- bool m_overlay;
- u32 m_ram_size;
bool m_baseIs4M;
u32 rom_switch_r(offs_t offset);
- void ram_size(u8 config);
void pseudovia_w(offs_t offset, u8 data);
void pseudovia_recalc_irqs();
@@ -140,30 +141,52 @@ class spice_device : public v8_device
required_device_array m_floppy;
protected:
+ spice_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
virtual void device_start() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
+ void phases_w(u8 phases);
+ void devsel_w(u8 devsel);
+
private:
floppy_image_device *m_cur_floppy = nullptr;
int m_hdsel;
- u8 via_in_a() override;
+ virtual u8 via_in_a() override;
virtual void via_out_a(u8 data) override;
- u8 pseudovia_r(offs_t offset) override;
+ virtual u8 pseudovia_r(offs_t offset) override;
virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
- void phases_w(u8 phases);
- void devsel_w(u8 devsel);
u16 swim_r(offs_t offset, u16 mem_mask);
void swim_w(offs_t offset, u16 data, u16 mem_mask);
void bright_contrast_w(offs_t offset, u8 data);
};
+// ======================> tinkerbell_device
+
+class tinkerbell_device : public spice_device
+{
+public:
+ tinkerbell_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual void ram_size(u8 config) override;
+
+private:
+ virtual u8 via_in_a() override;
+ virtual u8 pseudovia_r(offs_t offset) override;
+ virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
+};
+
// device type definition
DECLARE_DEVICE_TYPE(V8, v8_device)
DECLARE_DEVICE_TYPE(EAGLE, eagle_device)
DECLARE_DEVICE_TYPE(SPICE, spice_device)
+DECLARE_DEVICE_TYPE(TINKERBELL, tinkerbell_device)
#endif // MAME_APPLE_V8_H
diff --git a/src/mame/appliedconcepts/ggm.cpp b/src/mame/appliedconcepts/ggm.cpp
index c18609978a148..5451f8dcd8c96 100644
--- a/src/mame/appliedconcepts/ggm.cpp
+++ b/src/mame/appliedconcepts/ggm.cpp
@@ -463,7 +463,7 @@ static INPUT_PORTS_START( overlay_lasvegas )
PORT_MODIFY("IN.3")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x04) PORT_CODE(KEYCODE_L) PORT_NAME("Split")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x04) PORT_CODE(KEYCODE_U) PORT_NAME("Shuffle Point")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x04) PORT_CODE(KEYCODE_P) PORT_NAME("Shuffle Point")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x04) PORT_CODE(KEYCODE_A) PORT_NAME("Audio")
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x04) PORT_CODE(KEYCODE_T) PORT_NAME("Total")
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x04) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
@@ -485,7 +485,7 @@ static INPUT_PORTS_START( overlay_odin )
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x05) PORT_CODE(KEYCODE_U) PORT_NAME("Audio")
PORT_MODIFY("IN.2")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x05) PORT_CODE(KEYCODE_Y) PORT_NAME("Play / -")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x05) PORT_CODE(KEYCODE_P) PORT_NAME("Play / -")
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x05) PORT_CODE(KEYCODE_W) PORT_NAME("B/W")
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x05) PORT_CODE(KEYCODE_K) PORT_NAME("Rank")
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x05) PORT_CODE(KEYCODE_T) PORT_NAME("Time")
diff --git a/src/mame/misc/cave.cpp b/src/mame/atlus/cave.cpp
similarity index 99%
rename from src/mame/misc/cave.cpp
rename to src/mame/atlus/cave.cpp
index 19760b7e05050..c5193da93b4a4 100644
--- a/src/mame/misc/cave.cpp
+++ b/src/mame/atlus/cave.cpp
@@ -46,6 +46,9 @@ Year + Game License PCB Tilemaps Sprites
To Do:
+- Modernize state objects for each PCB sub-variant, rename to something more
+ apt than "cave_state";
+
- Sprite lag in some games (e.g. metmqstr). The sprites chip probably
generates interrupts (unknown_irq)
diff --git a/src/mame/misc/cave.h b/src/mame/atlus/cave.h
similarity index 99%
rename from src/mame/misc/cave.h
rename to src/mame/atlus/cave.h
index 09e875d701086..04cc9772cedab 100644
--- a/src/mame/misc/cave.h
+++ b/src/mame/atlus/cave.h
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
-#ifndef MAME_MISC_CAVE_H
-#define MAME_MISC_CAVE_H
+#ifndef MAME_ATLUS_CAVE_H
+#define MAME_ATLUS_CAVE_H
#pragma once
@@ -391,4 +391,4 @@ class ppsatan_state : public cave_state
void ppsatan_map(address_map &map);
};
-#endif // MAME_MISC_CAVE_H
+#endif // MAME_ATLUS_CAVE_H
diff --git a/src/mame/misc/cave_v.cpp b/src/mame/atlus/cave_v.cpp
similarity index 100%
rename from src/mame/misc/cave_v.cpp
rename to src/mame/atlus/cave_v.cpp
diff --git a/src/mame/casio/cfx9850.cpp b/src/mame/casio/cfx9850.cpp
index 1eba48b0037b4..bb3bcf98069ab 100644
--- a/src/mame/casio/cfx9850.cpp
+++ b/src/mame/casio/cfx9850.cpp
@@ -308,10 +308,12 @@ void cfx9850_state::cfx9850(machine_config &config)
PALETTE(config, "palette", FUNC(cfx9850_state::cfx9850_palette), 4);
}
+#define ROM_MAINCPU \
+ ROM_REGION(0x8000, "maincpu", 0) \
+ ROM_LOAD("hcd62121.bin", 0x0000, 0x8000, CRC(e72075f8) SHA1(f50d176e1c225dab69abfc67702c9dfb296b6a78))
ROM_START(cfx9850)
- ROM_REGION(0x8000, "maincpu", 0)
- ROM_LOAD("hcd62121.bin", 0x0000, 0x8000, CRC(e72075f8) SHA1(f50d176e1c225dab69abfc67702c9dfb296b6a78))
+ ROM_MAINCPU
ROM_REGION(0x80000, "bios", 0)
// Unknown yet which rom is which version.
@@ -321,7 +323,18 @@ ROM_START(cfx9850)
ROMX_LOAD("cfx9850b.bin", 0x00000, 0x80000, CRC(cd3c497f) SHA1(1d1aa38205eec7aba3ed6bef7389767e38afe075), ROM_BIOS(1))
ROM_END
+ROM_START(cfx9850gb)
+ ROM_MAINCPU
+
+ ROM_REGION(0x100000, "bios", 0)
+ // White model
+ // Back case revision: G359-21
+ // PCB revision: PWB-GY355-E4 RJA509401-1 / PWB-GY357-1 RJA509402-1
+ ROM_LOAD("r27v802d-34.lsi2", 0x00000, 0x100000, CRC(7ad44c51) SHA1(7cde6074758b5ae474b4eb3ee7396dbfb481ddcf))
+ROM_END
+
} // anonymous namespace
-COMP(1996, cfx9850, 0, 0, cfx9850, cfx9850, cfx9850_state, empty_init, "Casio", "CFX-9850G", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
+COMP(1996, cfx9850, 0, 0, cfx9850, cfx9850, cfx9850_state, empty_init, "Casio", "CFX-9850G", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
+COMP(1996, cfx9850gb, cfx9850, 0, cfx9850, cfx9850, cfx9850_state, empty_init, "Casio", "CFX-9850GB Plus", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
diff --git a/src/mame/misc/cavepc.cpp b/src/mame/cave/cavepc.cpp
similarity index 100%
rename from src/mame/misc/cavepc.cpp
rename to src/mame/cave/cavepc.cpp
diff --git a/src/mame/misc/cv1k.cpp b/src/mame/cave/cv1k.cpp
similarity index 99%
rename from src/mame/misc/cv1k.cpp
rename to src/mame/cave/cv1k.cpp
index c1e65968362c7..503b199a06025 100644
--- a/src/mame/misc/cv1k.cpp
+++ b/src/mame/cave/cv1k.cpp
@@ -190,12 +190,13 @@ Timing
#include "emu.h"
+#include "ep1c12.h"
+
#include "cpu/sh/sh3comn.h"
#include "cpu/sh/sh4.h"
#include "machine/nandflash.h"
#include "machine/rtc9701.h"
#include "sound/ymz770.h"
-#include "video/epic12.h"
#include "screen.h"
#include "speaker.h"
@@ -234,7 +235,7 @@ class cv1k_state : public driver_device
private:
required_device m_maincpu;
- required_device m_blitter;
+ required_device m_blitter;
required_device