diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml index 397dce08615..b27d8c2025b 100644 --- a/android-project/app/src/main/AndroidManifest.xml +++ b/android-project/app/src/main/AndroidManifest.xml @@ -4,8 +4,8 @@ --> diff --git a/hash/hp85_rom.xml b/hash/hp85_rom.xml index 9208db26d8e..370702d02a8 100644 --- a/hash/hp85_rom.xml +++ b/hash/hp85_rom.xml @@ -67,4 +67,17 @@ + + Mass storage ROM + 1979 + Hewlett-Packard + + + + + + + + + diff --git a/language/Chinese_Simplified/strings.po b/language/Chinese_Simplified/strings.po index a807b405ab9..edb0fb1461a 100644 --- a/language/Chinese_Simplified/strings.po +++ b/language/Chinese_Simplified/strings.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: MAME\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-10-03 10:32+1100\n" -"PO-Revision-Date: 2017-09-29 15:23+0800\n" +"PO-Revision-Date: 2017-10-03 22:56+0800\n" "Last-Translator: YuiFAN\n" "Language-Team: MAME Language Team\n" "Language: zh_CN\n" @@ -181,6 +181,7 @@ msgid "" "complete. There is nothing you can do to fix this problem except wait for " "the developers to improve the emulation.\n" msgstr "" +"\n" "此机械无法执行,机械的模拟还不完全。除了等待开发人员改良模拟之外,没有方法可" "以解决这个问题。\n" @@ -1016,7 +1017,7 @@ msgstr "档案已存在 — 是否覆写?" #: src/frontend/mame/ui/filecreate.cpp:171 msgid "New Image Name:" -msgstr "新映象档名称:" +msgstr "新映像档名称:" #: src/frontend/mame/ui/filecreate.cpp:177 msgid "Image Format:" @@ -1244,51 +1245,51 @@ msgstr "计时\t不完美\n" #: src/frontend/mame/ui/selgame.cpp:945 msgid "Mechanical Machine\tYes\n" -msgstr "" +msgstr "机械式机台\t是\n" #: src/frontend/mame/ui/selgame.cpp:945 msgid "Mechanical Machine\tNo\n" -msgstr "" +msgstr "机械式机台\t否\n" #: src/frontend/mame/ui/selgame.cpp:946 msgid "Requires Artwork\tYes\n" -msgstr "" +msgstr "需要装饰图\t是\n" #: src/frontend/mame/ui/selgame.cpp:946 msgid "Requires Artwork\tNo\n" -msgstr "" +msgstr "需要装饰图\t否\n" #: src/frontend/mame/ui/selgame.cpp:947 msgid "Requires Clickable Artwork\tYes\n" -msgstr "" +msgstr "需要可点击的装饰图\t是\n" #: src/frontend/mame/ui/selgame.cpp:947 msgid "Requires Clickable Artwork\tNo\n" -msgstr "" +msgstr "需要可点击的装饰图\t否\n" #: src/frontend/mame/ui/selgame.cpp:948 msgid "Support Cocktail\tYes\n" -msgstr "" +msgstr "支援檯面型筐体\t是\n" #: src/frontend/mame/ui/selgame.cpp:948 msgid "Support Cocktail\tNo\n" -msgstr "" +msgstr "支援檯面型筐体\t否\n" #: src/frontend/mame/ui/selgame.cpp:949 msgid "Driver is BIOS\tYes\n" -msgstr "" +msgstr "驱动程式为 BIOS\t是\n" #: src/frontend/mame/ui/selgame.cpp:949 msgid "Driver is BIOS\tNo\n" -msgstr "" +msgstr "驱动程式为 BIOS\t否\n" #: src/frontend/mame/ui/selgame.cpp:950 msgid "Support Save\tYes\n" -msgstr "" +msgstr "支援即时存档\t是\n" #: src/frontend/mame/ui/selgame.cpp:950 msgid "Support Save\tNo\n" -msgstr "" +msgstr "支援即时存档\t否\n" #: src/frontend/mame/ui/selgame.cpp:951 msgid "Screen Orientation\tVertical\n" @@ -1300,37 +1301,39 @@ msgstr "画面方向\t水平\n" #: src/frontend/mame/ui/selgame.cpp:961 msgid "Requires CHD\tYes\n" -msgstr "" +msgstr "需要 CHD\t是\n" #: src/frontend/mame/ui/selgame.cpp:961 msgid "Requires CHD\tNo\n" -msgstr "" +msgstr "需要 CHD\t否\n" #: src/frontend/mame/ui/selgame.cpp:974 msgid "ROM Audit Result\tOK\n" -msgstr "" +msgstr "ROM 校验结果\tOK\n" #: src/frontend/mame/ui/selgame.cpp:976 msgid "ROM Audit Result\tBAD\n" -msgstr "" +msgstr "ROM 校验结果\t错误\n" #: src/frontend/mame/ui/selgame.cpp:979 msgid "Samples Audit Result\tNone Needed\n" -msgstr "" +msgstr "样本档校验结果\t不需要\n" #: src/frontend/mame/ui/selgame.cpp:981 msgid "Samples Audit Result\tOK\n" -msgstr "" +msgstr "样本档校验结果\tOK\n" #: src/frontend/mame/ui/selgame.cpp:983 msgid "Samples Audit Result\tBAD\n" -msgstr "" +msgstr "样本档校验结果\t错误\n" #: src/frontend/mame/ui/selgame.cpp:987 msgid "" "ROM Audit Disabled\t\n" "Samples Audit Disabled\t\n" msgstr "" +"ROM 校验已停用\t\n" +"样本档校验已停用\t\n" #: src/frontend/mame/ui/selgame.cpp:1171 #, c-format @@ -2495,27 +2498,27 @@ msgstr "设定热键" #: plugins/cheat/init.lua:668 #, lua-format msgid "Activated: %s = %s" -msgstr "" +msgstr "已激活: %s = %s" #: plugins/cheat/init.lua:671 plugins/cheat/init.lua:729 #, lua-format msgid "Activated: %s" -msgstr "" +msgstr "已激活: %s" #: plugins/cheat/init.lua:733 #, lua-format msgid "Enabled: %s" -msgstr "" +msgstr "启用: %s" #: plugins/cheat/init.lua:738 #, lua-format msgid "Disabled: %s" -msgstr "" +msgstr "停用: %s" #: plugins/cheat/init.lua:776 #, lua-format msgid "%s added" -msgstr "" +msgstr "%s 已加入" #: plugins/data/data_command.lua:19 msgid "Command" @@ -2523,7 +2526,7 @@ msgstr "出招表" #: plugins/data/data_gameinit.lua:16 msgid "Gameinit" -msgstr "" +msgstr "Gameinit" #: plugins/data/data_hiscore.lua:770 plugins/data/data_hiscore.lua:818 msgid "High Scores" @@ -2563,7 +2566,7 @@ msgstr "系统信息" #: plugins/data/data_marp.lua:129 msgid "MARPScore" -msgstr "MARPScore" +msgstr "MARP得分" #: plugins/cheatfind/init.lua:344 msgid "Save Cheat" @@ -2584,7 +2587,7 @@ msgstr "作弊码名称" #: plugins/cheatfind/init.lua:354 #, lua-format msgid "Default name is %s" -msgstr "" +msgstr "缺省名称为 %s" #: plugins/cheatfind/init.lua:362 msgid "Player" @@ -2601,7 +2604,7 @@ msgstr "储存" #: plugins/cheatfind/init.lua:399 #, lua-format msgid "Cheat written to %s and added to cheat.simple" -msgstr "" +msgstr "作弊码已写入至 %s 且已加入至 cheat.simple" #: plugins/cheatfind/init.lua:407 msgid "Cheat added to cheat.simple" @@ -2612,6 +2615,8 @@ msgid "" "Unable to write file\n" "Ensure that cheatpath folder exists" msgstr "" +"无法写入档案\n" +"确认 cheatpath 资料夹是否存在" #: plugins/cheatfind/init.lua:421 msgid "Cancel" diff --git a/language/Chinese_Traditional/strings.po b/language/Chinese_Traditional/strings.po index dac042151ee..77c88a84479 100644 --- a/language/Chinese_Traditional/strings.po +++ b/language/Chinese_Traditional/strings.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: MAME\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-10-03 10:32+1100\n" -"PO-Revision-Date: 2017-09-29 15:22+0800\n" +"PO-Revision-Date: 2017-10-03 22:41+0800\n" "Last-Translator: YuiFAN\n" "Language-Team: MAME Language Team\n" "Language: zh_TW\n" @@ -181,6 +181,7 @@ msgid "" "complete. There is nothing you can do to fix this problem except wait for " "the developers to improve the emulation.\n" msgstr "" +"\n" "此機台無法執行,機台的模擬還不完全。除了等待開發人員改良模擬之外,沒有方法可" "以解決這個問題。\n" @@ -1016,7 +1017,7 @@ msgstr "檔案已存在 — 是否覆蓋?" #: src/frontend/mame/ui/filecreate.cpp:171 msgid "New Image Name:" -msgstr "新映象檔名稱:" +msgstr "新映像檔名稱:" #: src/frontend/mame/ui/filecreate.cpp:177 msgid "Image Format:" @@ -1244,51 +1245,51 @@ msgstr "計時\t不完美\n" #: src/frontend/mame/ui/selgame.cpp:945 msgid "Mechanical Machine\tYes\n" -msgstr "" +msgstr "機械式機台\t是\n" #: src/frontend/mame/ui/selgame.cpp:945 msgid "Mechanical Machine\tNo\n" -msgstr "" +msgstr "機械式機台\t否\n" #: src/frontend/mame/ui/selgame.cpp:946 msgid "Requires Artwork\tYes\n" -msgstr "" +msgstr "需要裝飾圖\t是\n" #: src/frontend/mame/ui/selgame.cpp:946 msgid "Requires Artwork\tNo\n" -msgstr "" +msgstr "需要裝飾圖\t否\n" #: src/frontend/mame/ui/selgame.cpp:947 msgid "Requires Clickable Artwork\tYes\n" -msgstr "" +msgstr "需要可點擊的裝飾圖\t是\n" #: src/frontend/mame/ui/selgame.cpp:947 msgid "Requires Clickable Artwork\tNo\n" -msgstr "" +msgstr "需要可點擊的裝飾圖\t否\n" #: src/frontend/mame/ui/selgame.cpp:948 msgid "Support Cocktail\tYes\n" -msgstr "" +msgstr "支援檯面型筐體\t是\n" #: src/frontend/mame/ui/selgame.cpp:948 msgid "Support Cocktail\tNo\n" -msgstr "" +msgstr "支援檯面型筐體\t否\n" #: src/frontend/mame/ui/selgame.cpp:949 msgid "Driver is BIOS\tYes\n" -msgstr "" +msgstr "驅動程式為 BIOS\t是\n" #: src/frontend/mame/ui/selgame.cpp:949 msgid "Driver is BIOS\tNo\n" -msgstr "" +msgstr "驅動程式為 BIOS\t否\n" #: src/frontend/mame/ui/selgame.cpp:950 msgid "Support Save\tYes\n" -msgstr "" +msgstr "支援即時存檔\t是\n" #: src/frontend/mame/ui/selgame.cpp:950 msgid "Support Save\tNo\n" -msgstr "" +msgstr "支援即時存檔\t否\n" #: src/frontend/mame/ui/selgame.cpp:951 msgid "Screen Orientation\tVertical\n" @@ -1300,37 +1301,39 @@ msgstr "畫面方向\t水平\n" #: src/frontend/mame/ui/selgame.cpp:961 msgid "Requires CHD\tYes\n" -msgstr "" +msgstr "需要 CHD\t是\n" #: src/frontend/mame/ui/selgame.cpp:961 msgid "Requires CHD\tNo\n" -msgstr "" +msgstr "需要 CHD\t否\n" #: src/frontend/mame/ui/selgame.cpp:974 msgid "ROM Audit Result\tOK\n" -msgstr "" +msgstr "ROM 驗證結果\tOK\n" #: src/frontend/mame/ui/selgame.cpp:976 msgid "ROM Audit Result\tBAD\n" -msgstr "" +msgstr "ROM 驗證結果\t錯誤\n" #: src/frontend/mame/ui/selgame.cpp:979 msgid "Samples Audit Result\tNone Needed\n" -msgstr "" +msgstr "樣本檔驗證結果\t不需要\n" #: src/frontend/mame/ui/selgame.cpp:981 msgid "Samples Audit Result\tOK\n" -msgstr "" +msgstr "樣本檔驗證結果\tOK\n" #: src/frontend/mame/ui/selgame.cpp:983 msgid "Samples Audit Result\tBAD\n" -msgstr "" +msgstr "樣本檔驗證結果\t錯誤\n" #: src/frontend/mame/ui/selgame.cpp:987 msgid "" "ROM Audit Disabled\t\n" "Samples Audit Disabled\t\n" msgstr "" +"ROM 驗證已停用\t\n" +"樣本檔驗證已停用\t\n" #: src/frontend/mame/ui/selgame.cpp:1171 #, c-format @@ -2495,27 +2498,27 @@ msgstr "設定熱鍵" #: plugins/cheat/init.lua:668 #, lua-format msgid "Activated: %s = %s" -msgstr "" +msgstr "已啟動: %s = %s" #: plugins/cheat/init.lua:671 plugins/cheat/init.lua:729 #, lua-format msgid "Activated: %s" -msgstr "" +msgstr "已啟動: %s" #: plugins/cheat/init.lua:733 #, lua-format msgid "Enabled: %s" -msgstr "" +msgstr "啟用: %s" #: plugins/cheat/init.lua:738 #, lua-format msgid "Disabled: %s" -msgstr "" +msgstr "已停用: %s" #: plugins/cheat/init.lua:776 #, lua-format msgid "%s added" -msgstr "" +msgstr "$s 已加入" #: plugins/data/data_command.lua:19 msgid "Command" @@ -2584,7 +2587,7 @@ msgstr "作弊碼名稱" #: plugins/cheatfind/init.lua:354 #, lua-format msgid "Default name is %s" -msgstr "" +msgstr "預設名稱為 %s" #: plugins/cheatfind/init.lua:362 msgid "Player" @@ -2601,7 +2604,7 @@ msgstr "儲存" #: plugins/cheatfind/init.lua:399 #, lua-format msgid "Cheat written to %s and added to cheat.simple" -msgstr "" +msgstr "作弊碼已寫入至 %s 且已加入 cheat.simple" #: plugins/cheatfind/init.lua:407 msgid "Cheat added to cheat.simple" @@ -2612,6 +2615,8 @@ msgid "" "Unable to write file\n" "Ensure that cheatpath folder exists" msgstr "" +"無法寫入檔案\n" +"確認 cheatpath 資料夾是否存在" #: plugins/cheatfind/init.lua:421 msgid "Cancel" diff --git a/language/Russian/strings.po b/language/Russian/strings.po index 7741a5afa36..aa4e050c7d1 100644 --- a/language/Russian/strings.po +++ b/language/Russian/strings.po @@ -1576,12 +1576,12 @@ msgstr "" #: src/frontend/mame/ui/miscmenu.cpp:253 msgid "Coin %1$c: NA%3$s\n" -msgstr "Монетопримник %1$c: НД%3$s\n" +msgstr "Монетоприемник %1$c: НД%3$s\n" #: src/frontend/mame/ui/miscmenu.cpp:253 #, c-format msgid "Coin %1$c: %2$d%3$s\n" -msgstr "Монетопримник %1$c: %2$d%3$s\n" +msgstr "Монетоприемник %1$c: %2$d%3$s\n" #: src/frontend/mame/ui/miscmenu.cpp:256 msgid " (locked)" diff --git a/makefile b/makefile index cb15cb3f511..c16d8bb06ec 100644 --- a/makefile +++ b/makefile @@ -1547,14 +1547,14 @@ endif ifeq (posix,$(SHELLTYPE)) $(GENDIR)/version.cpp: $(GENDIR)/git_desc | $(GEN_FOLDERS) - @echo '#define BARE_BUILD_VERSION "0.190"' > $@ + @echo '#define BARE_BUILD_VERSION "0.191"' > $@ @echo 'extern const char bare_build_version[];' >> $@ @echo 'extern const char build_version[];' >> $@ @echo 'const char bare_build_version[] = BARE_BUILD_VERSION;' >> $@ @echo 'const char build_version[] = BARE_BUILD_VERSION " ($(NEW_GIT_VERSION))";' >> $@ else $(GENDIR)/version.cpp: $(GENDIR)/git_desc - @echo #define BARE_BUILD_VERSION "0.190" > $@ + @echo #define BARE_BUILD_VERSION "0.191" > $@ @echo extern const char bare_build_version[]; >> $@ @echo extern const char build_version[]; >> $@ @echo const char bare_build_version[] = BARE_BUILD_VERSION; >> $@ diff --git a/roms/dir.txt b/roms/dir.txt new file mode 100644 index 00000000000..6a07c924677 --- /dev/null +++ b/roms/dir.txt @@ -0,0 +1 @@ +Place ROM directories here diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 29605ec7213..d838b8bfa2a 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3162,6 +3162,18 @@ if (BUSES["HP80_OPTROM"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/bus/hp80_io/hp80_io.h,BUSES["HP80_IO"] = true +--------------------------------------------------- + +if (BUSES["HP80_IO"]~=null) then + files { + MAME_DIR .. "src/devices/bus/hp80_io/hp80_io.cpp", + MAME_DIR .. "src/devices/bus/hp80_io/82937.cpp", + } +end + --------------------------------------------------- -- --@src/devices/bus/hp9845_io/hp9845_io.h,BUSES["HP9845_IO"] = true @@ -3238,3 +3250,33 @@ if (BUSES["PSI_KEYBOARD"]~=null) then MAME_DIR .. "src/devices/bus/psi_kbd/hle.h", } end + +--------------------------------------------------- +-- +--@src/devices/bus/interpro/sr/sr.h,BUSES["INTERPRO_SR"] = true +--------------------------------------------------- + +if (BUSES["INTERPRO_SR"]~=null) then + files { + MAME_DIR .. "src/devices/bus/interpro/sr/sr.cpp", + MAME_DIR .. "src/devices/bus/interpro/sr/sr.h", + MAME_DIR .. "src/devices/bus/interpro/sr/sr_cards.cpp", + MAME_DIR .. "src/devices/bus/interpro/sr/sr_cards.h", + MAME_DIR .. "src/devices/bus/interpro/sr/gt.cpp", + MAME_DIR .. "src/devices/bus/interpro/sr/gt.h", + } +end + +--------------------------------------------------- +-- +--@src/devices/bus/interpro/keyboard/keyboard.h,BUSES["INTERPRO_KEYBOARD"] = true +--------------------------------------------------- + +if (BUSES["INTERPRO_KEYBOARD"]~=null) then + files { + MAME_DIR .. "src/devices/bus/interpro/keyboard/keyboard.cpp", + MAME_DIR .. "src/devices/bus/interpro/keyboard/keyboard.h", + MAME_DIR .. "src/devices/bus/interpro/keyboard/hle.cpp", + MAME_DIR .. "src/devices/bus/interpro/keyboard/hle.h" + } +end diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index f0bb0db561b..d5a30d27756 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -1036,6 +1036,18 @@ if (MACHINES["1MA6"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/1mb5.h,MACHINES["1MB5"] = true +--------------------------------------------------- + +if (MACHINES["1MB5"]~=null) then + files { + MAME_DIR .. "src/devices/machine/1mb5.cpp", + MAME_DIR .. "src/devices/machine/1mb5.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/i2cmem.h,MACHINES["I2CMEM"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index a3df4b152e3..040371bd0fb 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -418,6 +418,7 @@ MACHINES["HD63450"] = true MACHINES["HD64610"] = true MACHINES["HP_TACO"] = true MACHINES["1MA6"] = true +MACHINES["1MB5"] = true MACHINES["I2CMEM"] = true MACHINES["I7220"] = true MACHINES["I80130"] = true @@ -675,6 +676,8 @@ BUSES["HPDIO"] = true BUSES["IEEE488"] = true BUSES["IMI7000"] = true BUSES["INTELLEC4"] = true +BUSES["INTERPRO_SR"] = true +BUSES["INTERPRO_KEYBOARD"] = true BUSES["INTV"] = true BUSES["INTV_CTRL"] = true BUSES["IQ151"] = true @@ -682,6 +685,7 @@ BUSES["ISA"] = true BUSES["ISBX"] = true BUSES["HP_OPTROM"] = true BUSES["HP80_OPTROM"] = true +BUSES["HP80_IO"] = true BUSES["HP9845_IO"] = true BUSES["KC"] = true BUSES["LPCI"] = true @@ -3565,6 +3569,7 @@ files { MAME_DIR .. "src/mame/drivers/tavernie.cpp", MAME_DIR .. "src/mame/drivers/tecnbras.cpp", MAME_DIR .. "src/mame/drivers/terak.cpp", + MAME_DIR .. "src/mame/drivers/terco.cpp", MAME_DIR .. "src/mame/drivers/ti630.cpp", MAME_DIR .. "src/mame/drivers/trs80dt1.cpp", MAME_DIR .. "src/mame/drivers/tsispch.cpp", diff --git a/src/devices/bus/gamate/gamate_protection.cpp b/src/devices/bus/gamate/gamate_protection.cpp index 4128b554cd1..4218a237a3f 100644 --- a/src/devices/bus/gamate/gamate_protection.cpp +++ b/src/devices/bus/gamate/gamate_protection.cpp @@ -4,6 +4,10 @@ #include "emu.h" #include "gamate_protection.h" +//#define VERBOSE 1 +#include "logmacro.h" + + DEFINE_DEVICE_TYPE(GAMATE_PROT, gamate_protection_device, "gamate_prot", "Gamate Protection Mapper") gamate_protection_device::gamate_protection_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : @@ -44,7 +48,7 @@ bool gamate_protection_device::is_protection_passed() WRITE_LINE_MEMBER(gamate_protection_device::prot_w) { - logerror("write to protection %01x\n", state); + LOG("write to protection %01x\n", state); if (m_inpos < 8) { @@ -53,7 +57,7 @@ WRITE_LINE_MEMBER(gamate_protection_device::prot_w) } else { - logerror("byte in was %c\n", m_inbyte); + LOG("byte in was %c\n", m_inbyte); if (!m_has_failed) { @@ -61,7 +65,7 @@ WRITE_LINE_MEMBER(gamate_protection_device::prot_w) { if (m_inbyte == m_prot_string[m_inseq]) { - logerror("OK\n"); + LOG("OK\n"); } else { @@ -78,7 +82,7 @@ WRITE_LINE_MEMBER(gamate_protection_device::prot_w) if (!m_has_failed && m_inseq == 15) { m_inbyte = 0x47; - logerror("setting byte to output\n"); + LOG("setting byte to output\n"); m_passed_write = 1; } } @@ -92,11 +96,11 @@ READ_LINE_MEMBER(gamate_protection_device::prot_r) int retval = (m_inbyte >> (7 - m_inpos)) & 1; m_inpos++; - logerror("read from protection %01x\n", retval); + LOG("read from protection %01x\n", retval); if (m_inpos == 8) { - logerror("unlocking ROM\n"); + LOG("unlocking ROM\n"); m_is_protection_passed = 1; m_inpos = 0; m_inbyte = 0; @@ -106,7 +110,7 @@ READ_LINE_MEMBER(gamate_protection_device::prot_r) } else { - logerror("read from protection when not ready\n"); + LOG("read from protection when not ready\n"); } return 0x0; diff --git a/src/devices/bus/hp80_io/82937.cpp b/src/devices/bus/hp80_io/82937.cpp new file mode 100644 index 00000000000..afeb561b8bc --- /dev/null +++ b/src/devices/bus/hp80_io/82937.cpp @@ -0,0 +1,354 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + 82937.cpp + + 82937 module (HPIB interface) + + TODO: Implement Parallel Poll response + + Thanks to Tim Nye & Everett Kaser for dumping the 8049 ROM + + Main reference for this module is: + HP 82937-90007, oct 80, HP82937A HP-IB Installation and theory + of operation manual + +*********************************************************************/ + +#include "emu.h" +#include "82937.h" +#include "coreutil.h" + +// Debugging +#define VERBOSE 0 +#include "logmacro.h" + +// Bit manipulation +namespace { + static constexpr unsigned BIT_MASK(unsigned n) + { + return 1U << n; + } + + template void BIT_SET(T& w , unsigned n) + { + w |= (T)BIT_MASK(n); + } +} + +// Bits in U3 (m_latch) +static constexpr unsigned LATCH_CA_BIT = 5; // Controller Active +static constexpr unsigned LATCH_TA_BIT = 4; // Talker Active +static constexpr unsigned LATCH_EN_IFC_INT_BIT = 3; // Enable IFC interrupt +static constexpr unsigned LATCH_EN_REN_INT_BIT = 2; // Enable REN interrupt +static constexpr unsigned LATCH_EN_ATN_INT_BIT = 1; // Enable ATN interrupt +static constexpr unsigned LATCH_EN_NDAC_BIT = 0; // Enable NDAC + +// Bits on P1 port of 8049 +static constexpr unsigned P1_IFC_BIT = 7; +static constexpr unsigned P1_REN_BIT = 6; +static constexpr unsigned P1_SRQ_BIT = 5; +static constexpr unsigned P1_ATN_BIT = 4; +static constexpr unsigned P1_EOI_BIT = 3; +static constexpr unsigned P1_DAV_BIT = 2; +static constexpr unsigned P1_NDAC_BIT = 1; +static constexpr unsigned P1_NRFD_BIT = 0; + +hp82937_io_card_device::hp82937_io_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : hp80_io_card_device(mconfig , HP82937_IO_CARD , tag , owner , clock), + m_cpu(*this , "cpu"), + m_translator(*this , "xlator"), + m_sw1(*this , "sw1"), + m_ieee488(*this , IEEE488_TAG) +{ +} + +hp82937_io_card_device::~hp82937_io_card_device() +{ +} + +void hp82937_io_card_device::install_read_write_handlers(address_space& space , uint16_t base_addr) +{ + space.install_readwrite_handler(base_addr , base_addr + 1 , READ8_DEVICE_DELEGATE(m_translator , hp_1mb5_device , cpu_r) , WRITE8_DEVICE_DELEGATE(m_translator , hp_1mb5_device , cpu_w)); +} + +void hp82937_io_card_device::inten() +{ + m_translator->inten(); +} + +void hp82937_io_card_device::clear_service() +{ + m_translator->clear_service(); +} + +WRITE_LINE_MEMBER(hp82937_io_card_device::reset_w) +{ + m_cpu->set_input_line(INPUT_LINE_RESET , state); + if (state) { + // When reset is asserted, clear state + device_reset(); + } +} + +READ_LINE_MEMBER(hp82937_io_card_device::t0_r) +{ + return m_iatn; +} + +READ8_MEMBER(hp82937_io_card_device::p1_r) +{ + uint8_t res = 0; + + if (BIT(m_sw1->read() , 5)) { + // System controller + BIT_SET(res , P1_IFC_BIT); + BIT_SET(res , P1_REN_BIT); + } else { + // Not system controller + if (m_ieee488->ifc_r()) { + BIT_SET(res , P1_IFC_BIT); + } + if (m_ieee488->ren_r()) { + BIT_SET(res , P1_REN_BIT); + } + } + if (!BIT(m_latch , LATCH_CA_BIT) || m_ieee488->srq_r()) { + BIT_SET(res , P1_SRQ_BIT); + } + if (m_iatn) { + BIT_SET(res , P1_ATN_BIT); + } + bool ndac = !BIT(m_latch , LATCH_EN_NDAC_BIT) || m_iatn; + if (m_talker_out) { + BIT_SET(res , P1_EOI_BIT); + BIT_SET(res , P1_DAV_BIT); + if (ndac && m_ieee488->ndac_r()) { + BIT_SET(res , P1_NDAC_BIT); + } + if (m_ieee488->nrfd_r()) { + BIT_SET(res , P1_NRFD_BIT); + } + } else { + if (m_ieee488->eoi_r()) { + BIT_SET(res , P1_EOI_BIT); + } + if (m_ieee488->dav_r()) { + BIT_SET(res , P1_DAV_BIT); + } + if (ndac) { + BIT_SET(res , P1_NDAC_BIT); + } + BIT_SET(res , P1_NRFD_BIT); + } + + return res; +} + +WRITE8_MEMBER(hp82937_io_card_device::p1_w) +{ + update_signals(); + update_data_out(); +} + +READ8_MEMBER(hp82937_io_card_device::dio_r) +{ + if (m_dio_out) { + return 0xff; + } else { + return m_ieee488->dio_r(); + } +} + +WRITE8_MEMBER(hp82937_io_card_device::dio_w) +{ + update_data_out(); +} + +READ8_MEMBER(hp82937_io_card_device::switch_r) +{ + return m_sw1->read() | 0xc0; +} + +WRITE8_MEMBER(hp82937_io_card_device::latch_w) +{ + LOG("latch=%02x\n" , data); + m_latch = data; + update_signals(); + update_data_out(); +} + +WRITE_LINE_MEMBER(hp82937_io_card_device::ieee488_ctrl_w) +{ + update_signals(); + update_data_out(); +} + +static INPUT_PORTS_START(hp82937_port) + MCFG_HP80_IO_SC(7) + PORT_START("sw1") + PORT_DIPNAME(0x1f , 0x15 , "HPIB address") + PORT_DIPLOCATION("S1:7,6,5,4,3") + PORT_DIPSETTING(0x00 , "0") + PORT_DIPSETTING(0x01 , "1") + PORT_DIPSETTING(0x02 , "2") + PORT_DIPSETTING(0x03 , "3") + PORT_DIPSETTING(0x04 , "4") + PORT_DIPSETTING(0x05 , "5") + PORT_DIPSETTING(0x06 , "6") + PORT_DIPSETTING(0x07 , "7") + PORT_DIPSETTING(0x08 , "8") + PORT_DIPSETTING(0x09 , "9") + PORT_DIPSETTING(0x0a , "10") + PORT_DIPSETTING(0x0b , "11") + PORT_DIPSETTING(0x0c , "12") + PORT_DIPSETTING(0x0d , "13") + PORT_DIPSETTING(0x0e , "14") + PORT_DIPSETTING(0x0f , "15") + PORT_DIPSETTING(0x10 , "16") + PORT_DIPSETTING(0x11 , "17") + PORT_DIPSETTING(0x12 , "18") + PORT_DIPSETTING(0x13 , "19") + PORT_DIPSETTING(0x14 , "20") + PORT_DIPSETTING(0x15 , "21") + PORT_DIPSETTING(0x16 , "22") + PORT_DIPSETTING(0x17 , "23") + PORT_DIPSETTING(0x18 , "24") + PORT_DIPSETTING(0x19 , "25") + PORT_DIPSETTING(0x1a , "26") + PORT_DIPSETTING(0x1b , "27") + PORT_DIPSETTING(0x1c , "28") + PORT_DIPSETTING(0x1d , "29") + PORT_DIPSETTING(0x1e , "30") + PORT_DIPSETTING(0x1f , "31") + PORT_DIPNAME(0x20 , 0x20 , "Sys. controller") + PORT_DIPLOCATION("S1:2") + PORT_DIPSETTING(0x00 , DEF_STR(Off)) + PORT_DIPSETTING(0x20 , DEF_STR(On)) +INPUT_PORTS_END + +ioport_constructor hp82937_io_card_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(hp82937_port); +} + +void hp82937_io_card_device::device_start() +{ + save_item(NAME(m_dio_out)); + save_item(NAME(m_talker_out)); + save_item(NAME(m_iatn)); + save_item(NAME(m_latch)); +} + +void hp82937_io_card_device::device_reset() +{ + hp80_io_card_device::device_reset(); + + m_latch = 0; + m_updating = false; + update_signals(); + update_data_out(); +} + +void hp82937_io_card_device::update_data_out() +{ + m_ieee488->dio_w(m_dio_out ? m_cpu->p2_r(machine().dummy_space() , 0) : 0xff); +} + +void hp82937_io_card_device::update_signals() +{ + // Avoid recursive re-enter when writing to IEEE488 signals + if (m_updating) { + return; + } + m_updating = true; + bool ctrl_active = BIT(m_latch , LATCH_CA_BIT); + uint8_t p1 = m_cpu->p1_r(machine().dummy_space() , 0); + m_iatn = BIT(p1 , P1_ATN_BIT); + if (ctrl_active) { + m_ieee488->atn_w(m_iatn); + m_ieee488->srq_w(1); + } else { + m_ieee488->atn_w(1); + m_iatn = m_iatn && m_ieee488->atn_r(); + m_ieee488->srq_w(BIT(p1 , P1_SRQ_BIT)); + } + m_talker_out = (ctrl_active && !m_iatn) || (BIT(m_latch , LATCH_TA_BIT) && m_iatn); + if (m_talker_out) { + m_ieee488->nrfd_w(1); + m_ieee488->dav_w(BIT(p1 , P1_DAV_BIT)); + m_ieee488->eoi_w(BIT(p1 , P1_EOI_BIT)); + m_ieee488->ndac_w(1); + + } else { + m_ieee488->nrfd_w(BIT(p1 , P1_NRFD_BIT)); + m_ieee488->dav_w(1); + m_ieee488->eoi_w(1); + bool ndac = BIT(p1 , P1_NDAC_BIT); + if (BIT(m_latch , LATCH_EN_NDAC_BIT) && !m_iatn) { + ndac = false; + } + m_ieee488->ndac_w(ndac); + } + bool iren = BIT(p1 , P1_REN_BIT); + if (BIT(m_sw1->read() , 5)) { + // System controller + m_ieee488->ren_w(iren); + m_ieee488->ifc_w(BIT(p1 , P1_IFC_BIT)); + } else { + // Not system controller + m_ieee488->ren_w(1); + iren = iren && m_ieee488->ren_r(); + m_ieee488->ifc_w(1); + } + bool not_u8_1 = m_iatn || m_ieee488->eoi_r(); + m_dio_out = not_u8_1 && m_talker_out; + bool irq = (BIT(m_latch , LATCH_EN_IFC_INT_BIT) && !m_ieee488->ifc_r()) || + (BIT(m_latch , LATCH_EN_REN_INT_BIT) && iren) || + (BIT(m_latch , LATCH_EN_ATN_INT_BIT) && !m_iatn); + m_cpu->set_input_line(MCS48_INPUT_IRQ , irq); + m_updating = false; +} + +ROM_START(hp82937) + ROM_REGION(0x800 , "cpu" , 0) + ROM_LOAD("1820-2437.bin" , 0 , 0x800 , CRC(687d1559) SHA1(44dfc8c3f431cd37a270b094f1db751214009214)) +ROM_END + +static ADDRESS_MAP_START(cpu_io_map , AS_IO , 8 , hp82937_io_card_device) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x00 , 0x01) AM_DEVREADWRITE("xlator" , hp_1mb5_device , uc_r , uc_w) + AM_RANGE(0x03 , 0x03) AM_READWRITE(switch_r , latch_w) +ADDRESS_MAP_END + +const tiny_rom_entry *hp82937_io_card_device::device_rom_region() const +{ + return ROM_NAME(hp82937); +} + +MACHINE_CONFIG_MEMBER(hp82937_io_card_device::device_add_mconfig) + MCFG_CPU_ADD("cpu" , I8049 , XTAL_11MHz) + MCFG_CPU_IO_MAP(cpu_io_map) + MCFG_MCS48_PORT_T0_IN_CB(READLINE(hp82937_io_card_device , t0_r)) + MCFG_MCS48_PORT_T1_IN_CB(DEVREADLINE("xlator" , hp_1mb5_device , int_r)) + MCFG_MCS48_PORT_P1_IN_CB(READ8(hp82937_io_card_device , p1_r)) + MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(hp82937_io_card_device , p1_w)) + MCFG_MCS48_PORT_P2_IN_CB(READ8(hp82937_io_card_device , dio_r)) + MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(hp82937_io_card_device , dio_w)) + + MCFG_DEVICE_ADD("xlator" , HP_1MB5 , 0) + MCFG_1MB5_IRL_HANDLER(WRITELINE(hp82937_io_card_device , irl_w)) + MCFG_1MB5_HALT_HANDLER(WRITELINE(hp82937_io_card_device , halt_w)) + MCFG_1MB5_RESET_HANDLER(WRITELINE(hp82937_io_card_device , reset_w)) + + MCFG_IEEE488_SLOT_ADD("ieee_dev" , 0 , hp_ieee488_devices , nullptr) + MCFG_IEEE488_BUS_ADD() + MCFG_IEEE488_IFC_CALLBACK(WRITELINE(hp82937_io_card_device , ieee488_ctrl_w)) + MCFG_IEEE488_ATN_CALLBACK(WRITELINE(hp82937_io_card_device , ieee488_ctrl_w)) + MCFG_IEEE488_REN_CALLBACK(WRITELINE(hp82937_io_card_device , ieee488_ctrl_w)) + MCFG_IEEE488_EOI_CALLBACK(WRITELINE(hp82937_io_card_device , ieee488_ctrl_w)) +MACHINE_CONFIG_END + +// device type definition +DEFINE_DEVICE_TYPE(HP82937_IO_CARD, hp82937_io_card_device, "hp82937", "HP82937 card") diff --git a/src/devices/bus/hp80_io/82937.h b/src/devices/bus/hp80_io/82937.h new file mode 100644 index 00000000000..4402eee8a13 --- /dev/null +++ b/src/devices/bus/hp80_io/82937.h @@ -0,0 +1,71 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + 82937.h + + 82937 module (HPIB interface) + +*********************************************************************/ + +#ifndef MAME_BUS_HP80_IO_82937_H +#define MAME_BUS_HP80_IO_82937_H + +#pragma once + +#include "hp80_io.h" +#include "cpu/mcs48/mcs48.h" +#include "bus/ieee488/ieee488.h" +#include "machine/1mb5.h" + +class hp82937_io_card_device : public hp80_io_card_device +{ +public: + // construction/destruction + hp82937_io_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~hp82937_io_card_device(); + + virtual void install_read_write_handlers(address_space& space , uint16_t base_addr) override; + + virtual void inten() override; + virtual void clear_service() override; + + DECLARE_WRITE_LINE_MEMBER(reset_w); + DECLARE_READ_LINE_MEMBER(t0_r); + DECLARE_READ8_MEMBER(p1_r); + DECLARE_WRITE8_MEMBER(p1_w); + DECLARE_READ8_MEMBER(dio_r); + DECLARE_WRITE8_MEMBER(dio_w); + DECLARE_READ8_MEMBER(switch_r); + DECLARE_WRITE8_MEMBER(latch_w); + DECLARE_WRITE_LINE_MEMBER(ieee488_ctrl_w); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // device-level overrides + virtual ioport_constructor device_input_ports() const override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + +private: + required_device m_cpu; + required_device m_translator; + required_ioport m_sw1; + required_device m_ieee488; + + bool m_dio_out; // U8-4 + bool m_talker_out; // U7-6 + bool m_iatn; + uint8_t m_latch; // U3 + bool m_updating; + + void update_data_out(); + void update_signals(); +}; + +// device type definition +DECLARE_DEVICE_TYPE(HP82937_IO_CARD, hp82937_io_card_device) + +#endif // MAME_BUS_HP80_IO_82937_H diff --git a/src/devices/bus/hp80_io/hp80_io.cpp b/src/devices/bus/hp80_io/hp80_io.cpp new file mode 100644 index 00000000000..e9ab08bb43c --- /dev/null +++ b/src/devices/bus/hp80_io/hp80_io.cpp @@ -0,0 +1,150 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp80_io.cpp + + I/O bus of HP80 systems + +*********************************************************************/ + +#include "emu.h" +#include "hp80_io.h" + +// Debugging +#define VERBOSE 0 +#include "logmacro.h" + +// device type definition +DEFINE_DEVICE_TYPE(HP80_IO_SLOT, hp80_io_slot_device, "hp80_io_slot", "HP80 I/O Slot") + +// +-------------------+ +// |hp80_io_slot_device| +// +-------------------+ +hp80_io_slot_device::hp80_io_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, HP80_IO_SLOT, tag, owner, clock), + device_slot_interface(mconfig, *this), + m_irl_cb_func(*this), + m_halt_cb_func(*this), + m_slot_no(0) +{ +} + +hp80_io_slot_device::~hp80_io_slot_device() +{ +} + +void hp80_io_slot_device::device_start() +{ + m_irl_cb_func.resolve_safe(); + m_halt_cb_func.resolve_safe(); +} + +WRITE_LINE_MEMBER(hp80_io_slot_device::irl_w) +{ + LOG("irl_w slot %u=%d\n" , m_slot_no , state); + m_irl_cb_func(m_slot_no , state , 0xff); +} + +WRITE_LINE_MEMBER(hp80_io_slot_device::halt_w) +{ + LOG("halt_w slot %u=%d\n" , m_slot_no , state); + m_halt_cb_func(m_slot_no , state , 0xff); +} + +void hp80_io_slot_device::inten() +{ + hp80_io_card_device *card = downcast(get_card_device()); + + if (card != nullptr) { + card->inten(); + } +} + +void hp80_io_slot_device::clear_service() +{ + hp80_io_card_device *card = downcast(get_card_device()); + + if (card != nullptr) { + card->clear_service(); + } +} + +void hp80_io_slot_device::install_read_write_handlers(address_space& space) +{ + hp80_io_card_device *card = downcast(get_card_device()); + + if (card != nullptr) { + card->install_read_write_handlers(space , get_base_addr()); + } +} + +uint8_t hp80_io_slot_device::get_sc() const +{ + const hp80_io_card_device *card = downcast(get_card_device()); + + if (card != nullptr) { + return card->get_sc(); + } else { + return 0; + } +} + +uint16_t hp80_io_slot_device::get_base_addr() const +{ + const hp80_io_card_device *card = downcast(get_card_device()); + + if (card != nullptr) { + uint16_t addr = ((uint16_t)(card->get_sc() - HP80_IO_FIRST_SC) << 1) | 0xff50; + return addr; + } else { + return 0; + } +} + +// +-------------------+ +// |hp80_io_card_device| +// +-------------------+ +uint8_t hp80_io_card_device::get_sc() const +{ + return m_select_code_port->read() + HP80_IO_FIRST_SC; +} + +void hp80_io_card_device::inten() +{ +} + +void hp80_io_card_device::clear_service() +{ +} + +hp80_io_card_device::hp80_io_card_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_slot_card_interface(mconfig, *this), + m_select_code_port(*this , "SC") +{ +} + +hp80_io_card_device::~hp80_io_card_device() +{ +} + +WRITE_LINE_MEMBER(hp80_io_card_device::irl_w) +{ + LOG("irl_w card=%d\n" , state); + hp80_io_slot_device *slot = downcast(owner()); + slot->irl_w(state); +} + +WRITE_LINE_MEMBER(hp80_io_card_device::halt_w) +{ + LOG("halt_w card=%d\n" , state); + hp80_io_slot_device *slot = downcast(owner()); + slot->halt_w(state); +} + +#include "82937.h" + +SLOT_INTERFACE_START(hp80_io_slot_devices) +SLOT_INTERFACE("82937_hpib" , HP82937_IO_CARD) +SLOT_INTERFACE_END diff --git a/src/devices/bus/hp80_io/hp80_io.h b/src/devices/bus/hp80_io/hp80_io.h new file mode 100644 index 00000000000..64430f8b6b4 --- /dev/null +++ b/src/devices/bus/hp80_io/hp80_io.h @@ -0,0 +1,107 @@ +// license:BSD-3-Clause +// copyright-holders: F. Ulivi +/********************************************************************* + + hp80_io.h + + I/O bus of HP80 systems + +*********************************************************************/ + +#ifndef MAME_BUS_HP80_IO_HP80_IO_H +#define MAME_BUS_HP80_IO_HP80_IO_H + +#pragma once + +#define MCFG_HP80_IO_SLOT_ADD(_tag , _idx) \ + MCFG_DEVICE_ADD(_tag, HP80_IO_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(hp80_io_slot_devices, nullptr, false) \ + hp80_io_slot_device::set_slot_no(*device , _idx); + +#define MCFG_HP80_IO_IRL_CB(_devcb) \ + devcb = &hp80_io_slot_device::set_irl_cb_func(*device , DEVCB_##_devcb); + +#define MCFG_HP80_IO_HALT_CB(_devcb) \ + devcb = &hp80_io_slot_device::set_halt_cb_func(*device , DEVCB_##_devcb); + +#define HP80_IO_FIRST_SC 3 // Lowest SC used by I/O cards + +#define MCFG_HP80_IO_SC(_default_sc) \ + PORT_START("SC") \ + PORT_CONFNAME(0xf , (_default_sc) - HP80_IO_FIRST_SC , "Select Code") \ + PORT_CONFSETTING(0 , "3")\ + PORT_CONFSETTING(1 , "4")\ + PORT_CONFSETTING(2 , "5")\ + PORT_CONFSETTING(3 , "6")\ + PORT_CONFSETTING(4 , "7")\ + PORT_CONFSETTING(5 , "8")\ + PORT_CONFSETTING(6 , "9")\ + PORT_CONFSETTING(7 , "10") + +class hp80_io_slot_device : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + hp80_io_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~hp80_io_slot_device(); + + // static configuration helpers + static void set_slot_no(device_t &device, unsigned slot_no) { downcast(device).m_slot_no = slot_no; } + + // device-level overrides + virtual void device_start() override; + + // Callback setups + template static devcb_base &set_irl_cb_func(device_t &device, Object &&cb) { return downcast(device).m_irl_cb_func.set_callback(std::forward(cb)); } + template static devcb_base &set_halt_cb_func(device_t &device, Object &&cb) { return downcast(device).m_halt_cb_func.set_callback(std::forward(cb)); } + + // SC getter + uint8_t get_sc() const; + + uint16_t get_base_addr() const; + + void install_read_write_handlers(address_space& space); + + DECLARE_WRITE_LINE_MEMBER(irl_w); + DECLARE_WRITE_LINE_MEMBER(halt_w); + + void inten(); + void clear_service(); + +private: + devcb_write8 m_irl_cb_func; + devcb_write8 m_halt_cb_func; + unsigned m_slot_no; +}; + +class hp80_io_card_device : public device_t, + public device_slot_card_interface +{ +public: + // SC getter + uint8_t get_sc() const; + + virtual void install_read_write_handlers(address_space& space , uint16_t base_addr) = 0; + + virtual void inten(); + virtual void clear_service(); + +protected: + // construction/destruction + hp80_io_card_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual ~hp80_io_card_device(); + + required_ioport m_select_code_port; + + // card device handling + DECLARE_WRITE_LINE_MEMBER(irl_w); + DECLARE_WRITE_LINE_MEMBER(halt_w); +}; + +// device type definition +DECLARE_DEVICE_TYPE(HP80_IO_SLOT, hp80_io_slot_device) + +SLOT_INTERFACE_EXTERN(hp80_io_slot_devices); + +#endif // MAME_BUS_HP80_IO_HP80_IO_H diff --git a/src/devices/bus/ieee488/hp9895.cpp b/src/devices/bus/ieee488/hp9895.cpp index a3a52535f23..2d2d623aadf 100644 --- a/src/devices/bus/ieee488/hp9895.cpp +++ b/src/devices/bus/ieee488/hp9895.cpp @@ -484,6 +484,10 @@ WRITE8_MEMBER(hp9895_device::phi_dio_w) WRITE_LINE_MEMBER(hp9895_device::phi_int_w) { m_cpu->set_input_line(INPUT_LINE_NMI , state); + if (state) { + // Ensure the event queue is emptied before executing any other instruction + m_cpu->yield(); + } } READ8_MEMBER(hp9895_device::phi_reg_r) diff --git a/src/devices/bus/interpro/keyboard/hle.cpp b/src/devices/bus/interpro/keyboard/hle.cpp new file mode 100644 index 00000000000..a455f9227e3 --- /dev/null +++ b/src/devices/bus/interpro/keyboard/hle.cpp @@ -0,0 +1,461 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * A high level emulation implementation of the Intergraph InterPro keyboard, + * largely copied from the sunkbd and psi hle implementations. + * + * These keyboards have two primary banks of keys. The lower bank consists of + * a total of 67 regular keyboard keyswitches plus a numeric keypad with a + * further 18 keys. The upper bank consists of 57 membrane-style programmable + * function keys in groups of 9, 36 and 12 from left to right. + * + * The following describes the key labels and positions according to the + * standard US English keyboard layout. It's unknown what other variations + * existed at this point. + * + * Upper bank keys indicated here with asterisks are printed in white, as are + * all the A*, B* and C* keys; all the others are printed in brown. + * + * Setup* Home* 2nd A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 2nd + * Help Clear F* F* + * Screen + * + * Find Insert Print B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15 B16 + * Here Screen* + * Remove + * + * Select Prev Next C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15 C16 + * Screen Screen + * + * + * In between the banks on the right hand side, there is a row of LEDs, the + * first three are pictures, rather than the descriptions given here). + * + * Disk Lock ----- L1 L2 L3 L4 + * + * Lower bank keys have up to 3 labels, in shifted and unshifted positions, and + * in red on the front face of the key-cap. + * + * Esc ~ ! @ # $ % ^ & * ( ) _ + Back Delete PF1 PF2 PF3 PF4 + * ` 1 2 3 4 5 6 7 8 9 0 - = Space ± ÷ × + + * Esc Num Lk ScrlLk Sys + * + * Alt Tab Q W E R T Y U I O P { } 7 8 9 _ + * Mode [ ] + * Home ↑ Pg Up Prt Sc + * + * Ctrl Caps A S D F G H J K L : " | Return 4 5 6 , + * Lock + * ← → − + * + * Shift > Z X C V B N M , . ? Shift ▲ 1 2 3 = + * < ■ + * End ↓ Pg Dn + * + * Hold Super- Line Repeat ◄ ■ ► 0 ◦ + * Screen impose Feed ▼ . Enter + * Ins Del + + * + * Alt Mode and Caps Lock keys have locking switches, capturing the key in the + * depressed position, as well as physical leds visible on the keycaps + * themselves. The keyboard also has two physical buttons on the back face of + * the keyboard, circular button labelled Boot, and a square one labelled Reset. + * + * The keyboard uses a 1200bps serial protocol to communicate with the host, + * with 1 start bit, 8 data bits, 1 stop bit, and even parity. The protocol + * as far as is known consists of the following sequences: + * + * From Host Purpose Expected Response + * --------- ------- ----------------- + * D Diagnostic 0xff , where status bits are set to + * indicate diagnostic failure source: 0x8=EPROM + * checksum, 0x10=RAM error, 0x20=ROM checksum + * + * B ( Bell On None + * + * B ) Bell Off None + * + * B Unknown None + * + * The keyboard has a keyboard click function, and the LED indicators described + * earlier, meaning that there are additional commands to enable and disable + * these functions. + * + * The keyboard transmits ASCII codes corresponding to the keycap labels for + * keys which map to the ASCII character set. Modifiers are applied by the + * keyboard itself, and do not generate make/break codes of their own. + * + * The following non-ASCII sequences are recognised in the system software, + * and likely correspond to specific keyboard keys or buttons: + * + * Sequence Function + * -------- -------- + * ^L Reboot, possibly maps to Reboot button + * ^M Unknown + * ^N Unknown, but operates as a toggle + * ^U Unknown + * + * TODO + * - unmapped keys + * - auto-repeat + * - key click and LED commands + * - alternative layouts + * + */ +#include "emu.h" +#include "hle.h" + +#include "machine/keyboard.ipp" +#include "speaker.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE_NS(INTERPRO_HLE_EN_US_KEYBOARD, bus::interpro::keyboard, hle_en_us_device, "kbd_hle_en_us", "InterPro Keyboard (HLE, US English)") + +namespace bus { namespace interpro { namespace keyboard { + +namespace { + + u8 const TRANSLATION_TABLE[4][5][16] = + { + // unshifted + { + { 0x1b, 0x60, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2d, 0x3d, 0x08, 0x7f }, // 0 + { 0x00, 0x09, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6f, 0x70, 0x5b, 0x5d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6c, 0x3b, 0x27, 0x5c, 0x0d, 0x00 }, // 2 + { 0x00, 0x3c, 0x7a, 0x78, 0x63, 0x76, 0x62, 0x6e, 0x6d, 0x2c, 0x2e, 0x2f, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + }, + // shifted + { + { 0x1b, 0x7e, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5e, 0x26, 0x2a, 0x28, 0x29, 0x5f, 0x2b, 0x08, 0x7f }, // 0 + { 0x00, 0x09, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4f, 0x50, 0x7b, 0x7d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0x3a, 0x22, 0x7c, 0x0d, 0x00 }, // 2 + { 0x00, 0x3e, 0x5a, 0x58, 0x43, 0x56, 0x42, 0x4e, 0x4d, 0x2c, 0x2e, 0x3f, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + }, + // unshifted-control + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0 + { 0x00, 0x00, 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, 0x0f, 0x10, 0x1b, 0x1d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x01, 0x13, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00 }, // 2 + { 0x00, 0x00, 0x1a, 0x18, 0x03, 0x16, 0x02, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + }, + // shifted-control + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 0 + { 0x00, 0x00, 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, 0x0f, 0x10, 0x1b, 0x1d, 0x00, 0x00 }, // 1 + { 0x00, 0x00, 0x01, 0x13, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00 }, // 2 + { 0x00, 0x00, 0x1a, 0x18, 0x03, 0x16, 0x02, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 3 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // 4 + } + }; + +INPUT_PORTS_START(interpro_en_us) + + PORT_START("modifiers") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_NAME("Control") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Shift") PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps Lock") PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + + PORT_START("row_0") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_NAME("Esc") PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Backspace") PORT_CHAR(8) + PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Delete") PORT_CHAR(UCHAR_MAMEKEY(DEL)) + + PORT_START("row_1") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // "Alt Mode" + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_NAME("Tab") PORT_CHAR(9) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + + PORT_START("row_2") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // CTRL + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) // LOCK + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return") PORT_CHAR(13) + + PORT_START("row_3") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // LSHIFT + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('<') PORT_CHAR('>') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_UNUSED) // RSHIFT + PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") PORT_CHAR(UCHAR_MAMEKEY(UP)) + + PORT_START("row_4") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_UNUSED) // "Hold Screen" + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_UNUSED) // "Superimpose" + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNUSED) // "Line Feed" + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Space") PORT_CHAR(UCHAR_MAMEKEY(SPACE)) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNUSED) // "Repeat" + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + +INPUT_PORTS_END + +INPUT_PORTS_START(hle_en_us_device) + PORT_INCLUDE(interpro_en_us) +INPUT_PORTS_END + +} // anonymous namespace + +hle_device_base::hle_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_buffered_serial_interface(mconfig, *this) + , device_interpro_keyboard_port_interface(mconfig, *this) + , device_matrix_keyboard_interface(mconfig, *this, "row_0", "row_1", "row_2", "row_3", "row_4") + , m_click_timer(nullptr) + , m_beeper(*this, "beeper") + , m_make_count(0U) + , m_rx_state(RX_IDLE) + , m_keyclick(0U) + , m_beeper_state(0U) +{ +} + +hle_device_base::~hle_device_base() +{ +} + +WRITE_LINE_MEMBER(hle_device_base::input_txd) +{ + device_buffered_serial_interface::rx_w(state); +} + +MACHINE_CONFIG_MEMBER(hle_device_base::device_add_mconfig) + MCFG_SPEAKER_STANDARD_MONO("bell") + MCFG_SOUND_ADD("beeper", BEEP, ATTOSECONDS_TO_HZ(480 * ATTOSECONDS_PER_MICROSECOND)) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "bell", 1.0) +MACHINE_CONFIG_END + +void hle_device_base::device_start() +{ + m_click_timer = timer_alloc(CLICK_TIMER_ID); + + save_item(NAME(m_make_count)); + save_item(NAME(m_rx_state)); + save_item(NAME(m_keyclick)); + save_item(NAME(m_beeper_state)); +} + +void hle_device_base::device_reset() +{ + // initialise state + clear_fifo(); + m_make_count = 0U; + m_rx_state = RX_IDLE; + m_keyclick = 0U; + m_beeper_state = 0x00U; + + // configure device_buffered_serial_interface + set_data_frame(START_BIT_COUNT, DATA_BIT_COUNT, PARITY, STOP_BITS); + set_rate(BAUD); + receive_register_reset(); + transmit_register_reset(); + + // start with keyboard LEDs off + machine().output().set_led_value(LED_DISK, 0); + machine().output().set_led_value(LED_LOCK, 0); + machine().output().set_led_value(LED_UNKNOWN, 0); + machine().output().set_led_value(LED_L1, 0); + machine().output().set_led_value(LED_L2, 0); + machine().output().set_led_value(LED_L3, 0); + machine().output().set_led_value(LED_L4, 0); + + // no beep + m_click_timer->reset(); + + // kick the base + reset_key_state(); + start_processing(attotime::from_hz(1'200)); +} + +void hle_device_base::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case CLICK_TIMER_ID: + m_beeper_state &= ~u8(BEEPER_CLICK); + m_beeper->set_state(m_beeper_state ? 1 : 0); + break; + + default: + break; + } +} + +void hle_device_base::tra_callback() +{ + output_rxd(transmit_register_get_data_bit()); +} + +void hle_device_base::tra_complete() +{ + if (fifo_full()) + start_processing(attotime::from_hz(1'200)); + + device_buffered_serial_interface::tra_complete(); +} + +void hle_device_base::key_make(u8 row, u8 column) +{ + // we should have stopped processing if we filled the FIFO + assert(!fifo_full()); + + // send the make code, click if desired + transmit_byte(translate(row, column)); + if (m_keyclick) + { + m_beeper_state |= u8(BEEPER_CLICK); + m_beeper->set_state(m_beeper_state ? 1 : 0); + m_click_timer->reset(attotime::from_msec(5)); + } + + // count keys + ++m_make_count; + assert(m_make_count); +} + +void hle_device_base::key_break(u8 row, u8 column) +{ + // we should have stopped processing if we filled the FIFO + assert(!fifo_full()); + assert(m_make_count); + + --m_make_count; + + // check our counting + assert(are_all_keys_up() == !bool(m_make_count)); +} + +void hle_device_base::transmit_byte(u8 byte) +{ + LOG("transmit_byte 0x%02x\n", byte); + device_buffered_serial_interface::transmit_byte(byte); + if (fifo_full()) + stop_processing(); +} + +void hle_device_base::received_byte(u8 byte) +{ + LOG("received_byte 0x%02x\n", byte); + + switch (m_rx_state) + { + case RX_ESC: + switch (byte) + { + case 'B': // bell + m_rx_state = RX_BELL; + break; + + case 'D': // diagnostic + transmit_byte(0xff); + transmit_byte(0x00); + + m_rx_state = RX_IDLE; + break; + } + break; + + case RX_BELL: + switch (byte) + { + case '(': + LOG("bell on\n"); + m_beeper_state |= u8(BEEPER_BELL); + m_beeper->set_state(m_beeper_state ? 1 : 0); + break; + + case ')': + LOG("bell off\n"); + m_beeper_state &= ~u8(BEEPER_BELL); + m_beeper->set_state(m_beeper_state ? 1 : 0); + break; + + default: + // FIXME: boot code sends 0x8, unknown meaning + break; + } + m_rx_state = RX_IDLE; + break; + + case RX_IDLE: + if (byte == 0x1b) + m_rx_state = RX_ESC; + break; + } +} + +hle_en_us_device::hle_en_us_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) + : hle_device_base(mconfig, INTERPRO_HLE_EN_US_KEYBOARD, tag, owner, clock), + m_modifiers(*this, "modifiers") +{ +} + +ioport_constructor hle_en_us_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(hle_en_us_device); +} + +u8 hle_en_us_device::translate(u8 row, u8 column) +{ + u8 const modifiers(m_modifiers->read()); + + bool const ctrl(modifiers & 0x01); + bool const shift(bool(modifiers & 0x02) || (bool(modifiers & 0x04))); + bool const ctrl_shift(ctrl && shift); + + unsigned const map(ctrl_shift ? 3 : ctrl ? 2 : shift ? 1 : 0); + + return TRANSLATION_TABLE[map][row][column]; +} + +} } } // namespace bus::interpro::keyboard diff --git a/src/devices/bus/interpro/keyboard/hle.h b/src/devices/bus/interpro/keyboard/hle.h new file mode 100644 index 00000000000..fac0b48d3be --- /dev/null +++ b/src/devices/bus/interpro/keyboard/hle.h @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay +#ifndef MAME_DEVICES_INTERPRO_KEYBOARD_HLE_H +#define MAME_DEVICES_INTERPRO_KEYBOARD_HLE_H + +#pragma once + +#include "keyboard.h" +#include "machine/keyboard.h" +#include "sound/beep.h" + +namespace bus { namespace interpro { namespace keyboard { + +class hle_device_base + : public device_t + , public device_buffered_serial_interface<16U> + , public device_interpro_keyboard_port_interface + , protected device_matrix_keyboard_interface<5U> +{ +public: + virtual ~hle_device_base() override; + + virtual DECLARE_WRITE_LINE_MEMBER(input_txd) override; + +protected: + // constructor/destructor + hle_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); + + // device overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + + // device_buffered_serial_interface overrides + virtual void tra_callback() override; + virtual void tra_complete() override; + + // device_matrix_keyboard_interface overrides + virtual void key_make(u8 row, u8 column) override; + virtual void key_break(u8 row, u8 column) override; + + // customised transmit_byte method + void transmit_byte(u8 byte); + virtual u8 translate(u8 row, u8 column) = 0; + +private: + enum { + CLICK_TIMER_ID = 30'000 + }; + + enum : int { + LED_DISK = 0, + LED_LOCK, + LED_UNKNOWN, + LED_L1, + LED_L2, + LED_L3, + LED_L4 + }; + + enum : u8 { + BEEPER_BELL = 0x01U, + BEEPER_CLICK = 0x02U + }; + + enum : u8 { + RX_IDLE, + RX_ESC, + RX_BELL + }; + + enum : u8 { + COMMAND_RESET = 0x01U, + COMMAND_BELL_ON = 0x02U, + COMMAND_BELL_OFF = 0x03U, + COMMAND_CLICK_ON = 0x0aU, + COMMAND_CLICK_OFF = 0x0bU, + COMMAND_LED = 0x0eU, + COMMAND_LAYOUT = 0x0fU + }; + + // device_buffered_serial_interface overrides + virtual void received_byte(u8 byte) override; + + emu_timer *m_click_timer; + required_device m_beeper; + + u8 m_make_count; + u8 m_rx_state; + + u8 m_keyclick; + u8 m_beeper_state; +}; + + +class hle_en_us_device : public hle_device_base +{ +public: + hle_en_us_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + + virtual ioport_constructor device_input_ports() const override; + + virtual u8 translate(u8 row, u8 column) override; + + required_ioport m_modifiers; +}; + +} } } // namespace bus::interpro::keyboard + +DECLARE_DEVICE_TYPE_NS(INTERPRO_HLE_EN_US_KEYBOARD, bus::interpro::keyboard, hle_en_us_device) + +#endif // MAME_DEVICES_INTERPRO_KEYBOARD_HLE_H diff --git a/src/devices/bus/interpro/keyboard/keyboard.cpp b/src/devices/bus/interpro/keyboard/keyboard.cpp new file mode 100644 index 00000000000..210b509277c --- /dev/null +++ b/src/devices/bus/interpro/keyboard/keyboard.cpp @@ -0,0 +1,67 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#include "emu.h" +#include "keyboard.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(INTERPRO_KEYBOARD_PORT, interpro_keyboard_port_device, "interpro_keyboard_port", "InterPro Keyboard Port") + +int const device_interpro_keyboard_port_interface::START_BIT_COUNT; +int const device_interpro_keyboard_port_interface::DATA_BIT_COUNT; +device_serial_interface::parity_t const device_interpro_keyboard_port_interface::PARITY; +device_serial_interface::stop_bits_t const device_interpro_keyboard_port_interface::STOP_BITS; +int const device_interpro_keyboard_port_interface::BAUD; + +interpro_keyboard_port_device::interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) + : interpro_keyboard_port_device(mconfig, INTERPRO_KEYBOARD_PORT, tag, owner, clock) +{ +} + +interpro_keyboard_port_device::interpro_keyboard_port_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, type, tag, owner, clock) + , device_slot_interface(mconfig, *this) + , m_rxd_handler(*this) + , m_dev(nullptr) +{ +} + +interpro_keyboard_port_device::~interpro_keyboard_port_device() +{ +} + +void interpro_keyboard_port_device::device_config_complete() +{ + m_dev = dynamic_cast(get_card_device()); +} + +void interpro_keyboard_port_device::device_start() +{ + m_rxd_handler.resolve_safe(); + + save_item(NAME(m_rxd)); +} + +WRITE_LINE_MEMBER(interpro_keyboard_port_device::write_txd) +{ + if (m_dev) + m_dev->input_txd(state); +} + +device_interpro_keyboard_port_interface::device_interpro_keyboard_port_interface(machine_config const &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) + , m_port(dynamic_cast(device.owner())) +{ +} + +device_interpro_keyboard_port_interface::~device_interpro_keyboard_port_interface() +{ +} + +#include "hle.h" + +SLOT_INTERFACE_START(interpro_keyboard_devices) + SLOT_INTERFACE("hle_en_us", INTERPRO_HLE_EN_US_KEYBOARD) +SLOT_INTERFACE_END diff --git a/src/devices/bus/interpro/keyboard/keyboard.h b/src/devices/bus/interpro/keyboard/keyboard.h new file mode 100644 index 00000000000..ca3b1a2eb82 --- /dev/null +++ b/src/devices/bus/interpro/keyboard/keyboard.h @@ -0,0 +1,71 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay +#ifndef MAME_BUS_INTERPRO_KEYBOARD_KEYBOARD_H +#define MAME_BUS_INTERPRO_KEYBOARD_KEYBOARD_H + +#pragma once + +#define MCFG_INTERPRO_KEYBOARD_PORT_ADD(tag, slot_intf, def_slot) \ + MCFG_DEVICE_ADD(tag, INTERPRO_KEYBOARD_PORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(slot_intf, def_slot, false) + +#define MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(cb) \ + devcb = &interpro_keyboard_port_device::set_rxd_handler(*device, DEVCB_##cb); + +class device_interpro_keyboard_port_interface; + +class interpro_keyboard_port_device : public device_t, public device_slot_interface +{ + friend class device_interpro_keyboard_port_interface; + +public: + interpro_keyboard_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + virtual ~interpro_keyboard_port_device(); + + // static configuration helpers + template static devcb_base &set_rxd_handler(device_t &device, Object &&cb) { return downcast(device).m_rxd_handler.set_callback(std::forward(cb)); } + + DECLARE_WRITE_LINE_MEMBER(write_txd); + +protected: + interpro_keyboard_port_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + virtual void device_config_complete() override; + + int m_rxd; + + devcb_write_line m_rxd_handler; + +private: + device_interpro_keyboard_port_interface *m_dev; +}; + +class device_interpro_keyboard_port_interface : public device_slot_card_interface +{ + friend class interpro_keyboard_port_device; + +public: + virtual ~device_interpro_keyboard_port_interface() override; + + virtual DECLARE_WRITE_LINE_MEMBER(input_txd) { } + + DECLARE_WRITE_LINE_MEMBER(output_rxd) { m_port->m_rxd = state; m_port->m_rxd_handler(state); } + +protected: + device_interpro_keyboard_port_interface(machine_config const &mconfig, device_t &device); + + interpro_keyboard_port_device *m_port; + + static constexpr int START_BIT_COUNT = 1; + static constexpr int DATA_BIT_COUNT = 8; + static constexpr device_serial_interface::parity_t PARITY = device_serial_interface::PARITY_EVEN; + static constexpr device_serial_interface::stop_bits_t STOP_BITS = device_serial_interface::STOP_BITS_1; + static constexpr int BAUD = 1'200; +}; + +DECLARE_DEVICE_TYPE(INTERPRO_KEYBOARD_PORT, interpro_keyboard_port_device) + +SLOT_INTERFACE_EXTERN(interpro_keyboard_devices); + +#endif // MAME_BUS_INTERPRO_KEYBOARD_KEYBOARD_H diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp new file mode 100644 index 00000000000..c4ed9109792 --- /dev/null +++ b/src/devices/bus/interpro/sr/gt.cpp @@ -0,0 +1,193 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * An emulation of GT graphics for Intergraph InterPro. + * + * TODO + * - control register (including primary/secondary buffer selection) + * - DP8510V BITBLT unit + * - custom Bresenham line drawing ASIC + * - support GT+, GTII, GTII+ + * - reset behaviour + */ + +#include "emu.h" +#include "screen.h" + +#include "gt.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEVICE_ADDRESS_MAP_START(map, 32, mpcb963_device) + AM_RANGE(0x00000000, 0x0000007f) AM_READ(idprom_r) + AM_RANGE(0x00000080, 0x0000008f) AM_DEVICE8("ramdac0", bt459_device, map, 0xff) + AM_RANGE(0x000000b0, 0x000000b3) AM_READWRITE16(control_r, control_w, 0xffff) + //AM_RANGE(0x000000d4, 0x000000d7) AM_READWRITE8(, 0xff) // currently unknown + //AM_RANGE(0x000000a0, 0x000000a0) AM_READWRITE8(, 0xff) // currently unknown + AM_RANGE(0x00400000, 0x005fffff) AM_READWRITE(vram_r, vram_w) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(map, 32, mpcba79_device) + AM_RANGE(0x00000000, 0x0000007f) AM_READ(idprom_r) + AM_RANGE(0x00000080, 0x0000008f) AM_DEVICE8("ramdac0", bt459_device, map, 0xff) + AM_RANGE(0x00000090, 0x0000009f) AM_DEVICE8("ramdac1", bt459_device, map, 0xff) + AM_RANGE(0x000000b0, 0x000000b3) AM_READWRITE16(control_r, control_w, 0xffff) + //AM_RANGE(0x000000d4, 0x000000d7) AM_READWRITE8(, 0xff) // currently unknown + //AM_RANGE(0x000000a0, 0x000000a0) AM_READWRITE8(, 0xff) // currently unknown + AM_RANGE(0x00400000, 0x007fffff) AM_READWRITE(vram_r, vram_w) +ADDRESS_MAP_END + +ROM_START(mpcb963) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcb963a.bin", 0x0, 0x20, CRC(4cf4562d) SHA1(58bcc2afb66168f1d44a0366b6a5ccc4c22e0f32)) +ROM_END + +ROM_START(mpcba79) + ROM_REGION(0x80, "idprom", 0) + ROM_LOAD32_BYTE("mpcba79a.bin", 0x0, 0x20, CRC(b3b98324) SHA1(77b4ed0bbc6ed19646c4536d9976563f78961408)) +ROM_END + +DEFINE_DEVICE_TYPE(MPCB963, mpcb963_device, "mpcb963", "2000 Graphics f/1 1Mp Monitor") +DEFINE_DEVICE_TYPE(MPCBA79, mpcba79_device, "mpcba79", "2000 Graphics f/2 1Mp Monitors") + +/* + * The raw screen data here is just a guess for now. Real values will need to + * be determined to ensure the cursor positions generated by the Bt459 are + * aligned properly on the screen. + */ +MACHINE_CONFIG_MEMBER(mpcb963_device::device_add_mconfig) + MCFG_SCREEN_ADD("screen0", RASTER) + MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS) + MCFG_SCREEN_UPDATE_DEVICE("", mpcb963_device, screen_update0) + MCFG_DEVICE_ADD("ramdac0", BT459, 0) +MACHINE_CONFIG_END + +MACHINE_CONFIG_MEMBER(mpcba79_device::device_add_mconfig) + MCFG_SCREEN_ADD("screen0", RASTER) + MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS) + MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update0) + MCFG_DEVICE_ADD("ramdac0", BT459, 0) + + MCFG_SCREEN_ADD("screen1", RASTER) + MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS) + MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update1) + MCFG_DEVICE_ADD("ramdac1", BT459, 0) +MACHINE_CONFIG_END + +gt_device_base::gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : sr_card_device_base(mconfig, type, tag, owner, clock) +{ +} + +mpcb963_device::mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : gt_device_base(mconfig, MPCB963, tag, owner, clock) + , m_screen{ { { *this, "ramdac0" }, {}, true } } +{ +} + +const tiny_rom_entry *mpcb963_device::device_rom_region() const +{ + return ROM_NAME(mpcb963); +} + +void mpcb963_device::device_start() +{ + gt_device_base::device_start(); + + // allocate double-buffered vram + m_screen[0].vram.reset(new u8[GT_VRAM_SIZE]); + + save_item(NAME(m_control)); + save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM_SIZE); +} + + +WRITE16_MEMBER(mpcb963_device::control_w) +{ + LOG("control_w 0x%04x\n", data); + + m_control = data; +} + +READ32_MEMBER(mpcb963_device::vram_r) const +{ + return ((u32 *)m_screen[(offset >> 19) & 1].vram.get())[offset & 0x7ffff]; +} + +WRITE32_MEMBER(mpcb963_device::vram_w) +{ + const gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; + + ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask); +} + +u32 mpcb963_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + const gt_screen_t >_screen = m_screen[0]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]); + + return 0; +} + +mpcba79_device::mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : gt_device_base(mconfig, MPCBA79, tag, owner, clock) + , m_screen { { { *this, "ramdac0" }, {}, true }, { { *this, "ramdac1" }, {}, true } } +{ +} + +const tiny_rom_entry *mpcba79_device::device_rom_region() const +{ + return ROM_NAME(mpcba79); +} + +void mpcba79_device::device_start() +{ + gt_device_base::device_start(); + + m_screen[0].vram.reset(new u8[GT_VRAM_SIZE]); + m_screen[1].vram.reset(new u8[GT_VRAM_SIZE]); + + save_item(NAME(m_control)); + save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM_SIZE); + save_pointer(NAME(m_screen[1].vram.get()), GT_VRAM_SIZE); +} + +WRITE16_MEMBER(mpcba79_device::control_w) +{ + LOG("control_w 0x%04x\n", data); + + m_control = data; +} + +READ32_MEMBER(mpcba79_device::vram_r) const +{ + return ((u32 *)m_screen[(offset >> 19) & 1].vram.get())[offset & 0x7ffff]; +} + +WRITE32_MEMBER(mpcba79_device::vram_w) +{ + const gt_screen_t >_screen = m_screen[(offset >> 19) & 1]; + + ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask); +} + +u32 mpcba79_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + const gt_screen_t >_screen = m_screen[0]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]); + + return 0; +} + +u32 mpcba79_device::screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + const gt_screen_t >_screen = m_screen[1]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]); + + return 0; +} diff --git a/src/devices/bus/interpro/sr/gt.h b/src/devices/bus/interpro/sr/gt.h new file mode 100644 index 00000000000..c572772ccda --- /dev/null +++ b/src/devices/bus/interpro/sr/gt.h @@ -0,0 +1,102 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay +#ifndef MAME_BUS_INTERPRO_SR_GT_H +#define MAME_BUS_INTERPRO_SR_GT_H + +#pragma once + +#include "sr.h" +#include "video/bt459.h" + +class gt_device_base : public sr_card_device_base +{ +protected: + gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + +public: + static const u32 GT_PIXCLOCK = 80'000'000; // just a guess + static const int GT_XPIXELS = 1184; + static const int GT_YPIXELS = 884; + static const int GT_BUFFER_SIZE = 0x100000; // 1 megabyte + static const int GT_VRAM_SIZE = 0x200000; // 1 megabyte double buffered + + enum control_mask + { + CONTROL_SCREEN = 0x1000, // possibly selects screen 0 or 1? + CONTROL_BUSY = 0x8000 + }; + + virtual DECLARE_READ16_MEMBER(control_r) const = 0; + virtual DECLARE_WRITE16_MEMBER(control_w) = 0; + virtual DECLARE_READ32_MEMBER(vram_r) const = 0; + virtual DECLARE_WRITE32_MEMBER(vram_w) = 0; + +protected: + typedef struct + { + required_device ramdac; + std::unique_ptr vram; + + bool primary; + } gt_screen_t; +}; + +class mpcb963_device : public gt_device_base +{ +public: + mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + static const int GT_SCREEN_COUNT = 1; + + virtual DECLARE_ADDRESS_MAP(map, 32) override; + + virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } + virtual DECLARE_WRITE16_MEMBER(control_w) override; + virtual DECLARE_READ32_MEMBER(vram_r) const override; + virtual DECLARE_WRITE32_MEMBER(vram_w) override; + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + + u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +private: + u16 m_control; + + gt_screen_t m_screen[GT_SCREEN_COUNT]; +}; + +class mpcba79_device : public gt_device_base +{ +public: + mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + static const int GT_SCREEN_COUNT = 2; + + virtual DECLARE_ADDRESS_MAP(map, 32) override; + + virtual DECLARE_READ16_MEMBER(control_r) const override { return m_control; } + virtual DECLARE_WRITE16_MEMBER(control_w) override; + virtual DECLARE_READ32_MEMBER(vram_r) const override; + virtual DECLARE_WRITE32_MEMBER(vram_w) override; + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + + u32 screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + u32 screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +private: + u16 m_control; + gt_screen_t m_screen[GT_SCREEN_COUNT]; +}; + +// device type definition +DECLARE_DEVICE_TYPE(MPCB963, mpcb963_device) +DECLARE_DEVICE_TYPE(MPCBA79, mpcba79_device) + +#endif // MAME_BUS_INTERPRO_SR_GT_H diff --git a/src/devices/bus/interpro/sr/sr.cpp b/src/devices/bus/interpro/sr/sr.cpp new file mode 100644 index 00000000000..d27609d117d --- /dev/null +++ b/src/devices/bus/interpro/sr/sr.cpp @@ -0,0 +1,363 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * An initial very primitive emulation of the SR bus for the Intergraph + * InterPro. + * + * The bus is referred to by several different names at different places + * in the system code, such as SR, SR bus, SRX, SRX/C bus, CBUS and some + * variations on those. It's likely that SRX is an enhanced version of the + * original SR bus implementation, and that CBUS is an alternate name. + * + * SR bus devices are mapped into the host memory map at a fixed address + * range per slot, starting at 0x87000000 and incrementing by 0x08000000. + * Within this address range, the first 32 double words provide access to + * a 32 byte board signature area, with a format as follows. + * + * u8 board[8] first four bytes typically zero, next three bytes + * contain a board number (in ASCII) from the list + * below, last byte contains a revision character + * u8 eco[8] engineering change order bits; these are initially + * all set, and are cleared starting from the least + * significant bit of the first byte onward to indicate + * board level changes + * u8 feature[8] used for different purposes by different boards + * u8 reserved[2] always set to 0xff + * u16 family indicate the board type from the list below + * u8 footprint[4] the first three bytes contain the magic number 0x55 + * 0xaa 0x55, the last byte contains the ones-complement + * of the sum of the other bytes as a checksum + * + * The following are the board families taken from the system boot ROM. + * + * Family Description + * ------ ----------- + * 0x0000 I/O processor + * 0x0001 CLIX engine + * 0x0002 expansion memory + * 0x0003 floating-point engine + * 0x0004 pipe-starter + * 0x0005 integrated frame buffer + * 0x0006 32/CGX + * 0x0007 GRE integrated frame buffer + * 0x0008 hardcopy/digitizer + * 0x0009 plotter DMA I/F + * 0x000a A/V mux + * 0x000b image subsystem I/F + * 0x000c VME adapter + * 0x000d I/O processor + * 0x000e CLIX engine + * 0x000f frame grabber + * 0x0010 screen generator subsystem + * 0x0011 scanner I/F + * 0x0012 convolution filter + * 0x0013 non-linear filter + * 0x0014 run-length encoder + * 0x0015 color setter data board + * 0x0016 EDGE I + * 0x0017 6000-series system board + * 0x0018 32-channel async I/F + * 0x0019 SR QUAD SCSI I/F + * 0x001a FDDI I/F + * 0x001b EDGE II processor + * 0x001c EDGE II frame buffer + * 0x001d IOI + * 0x001e IOI Clix Engine + * 0x001f MAYA bus I/F unit + * 0x0020 comp/decomp group 4 + * 0x0021 QWIC/SRX I/F + * 0x0022 SRX test board + * 0x0023 QWIC bus CPU + * 0x0024 2000-series system board + * 0x0025 2000-series graphics board + * 0x0026 E100/SRX device I/F + * 0x0027 IKOS H/W simulator I/F + * 0x0028 enhanced VME adapter + * 0x0029 QWIC expansion memory + * 0x002a image comp/decomp + * 0x002b teleconferencing controller + * 0x002c Sky 8115-I interface + * 0x002d C-bus token ring + * 0x002e Screen IV PressFax Subsystem + * 0x002f C400E CPU + * 0x0030 C-bus exp Ethernet + * 0x0031 2400-series CPU + * 0x0032 6400-series CPU + * 0x0033 6000-series GT Graphics + * 0x0034 C4K QWIC bus processor + * 0x0038 Visualization Processor + * 0x0039 2700-series CPU + * 0x0040 6700-series CPU + * 0x0041 2800-series CPU + * 0x0042 6700-series CPU + * + * The following are the board names taken from the showconfig.dat file + * shipped with the operating system. + * + * # Description + * --- ----------- + * 004 EDGE-2 Processor f/2 2Mp-FB's + * 008 Image Memory VRAM Board + * 009 EDGE II Frame Buffer for ImageStation + * 010 VI50 Image Processor + * 014 SRX Quad-SCSI Controller + * 019 C4E CPU Assembly + * 030 EDGE-2 Processor f/1 or 2 1Mp-FB's + * 031 EDGE-2 Processor f/1 2Mp-FB + * 032 CBUS Token Ring + * 034 256MB QWIC Bus Expansion Memory + * 046 6400 36-MHz Series System Board + * 047 2400 Series System Board + * 068 2400 Graphics f/1 1Mp Monitor (V-60) + * 069 2400 Graphics f/2 1Mp Monitors (V-60) + * 070 2400 Graphics f/1 1Mp Monitor (V-76) + * 071 2400 Graphics f/2 1Mp Monitors (V-76) + * 081 2400 Graphics f/1 2Mp Monitor (V-60/76) + * 083 SRX Hard PC Option / 8 Mb + * 093 EDGE-2 Plus Processor f/1 or 2 1Mp-FB's + * 094 EDGE-2 Plus Processor f/1 2Mp-FB + * 095 EDGE-2 Plus Processor f/2 2Mp-FB's + * 096 EDGE-2 Plus Frame Buffer f/1Mp Monitor + * 098 6400 32-MHz Sapphire System Board + * 101 2400 Graphics f/1 1Mp Monitor (V-76) + * 100 2500 Series System Board + * 102 2400 Graphics f/2 1Mp Monitors (V-76) + * 106 C-Bus Series Hard PC Option / 8 Mb + * 112 SRX Fast Quad-SCSI Controller + * 115 Edge III Processor + * 116 Edge III-C Single Ramdac + * 126 SRX Enhanced VME Adapter + * 127 6700 Series System Board + * 128 2700 Series System Board + * 129 6800 Series System Board + * 135 GT II Graphics f/1 2Mp Monitor (V-60/76) + * 136 GT II Graphics f/2 2Mp Monitor (V-60/76) + * 144 6800 Series System Board + * 145 2800 Series System Board + * 217 C-Bus Hard PC Option / 16 Mb + * 218 SRX Hard PC Option / 16 Mb + * 512 32C Clix Engine w/6MB + * 543 Floating Point Engine + * 548 80386 I/O Processor + * 577 Analog Video Mux/Summer + * 588 80186 I/O Processor + * 595 Pipe Starter + * 604 Digitizer/HardCopy Controller + * 605 300 Series Clix Engine w/16MB + * 617 300 Series SR VME-Adapter + * 633 32MB Expansion Memory + * 636 80186 I/O Processor w/CoProcessor + * 641 Image Subsystem Interface + * 643 8Mb Integrated Frame Buffer f/1Mp + * 650 2Mb Integrated Frame Buffer f/1Mp + * 652 2Mb Integrated Frame Buffer f/1Mp + * 657 32C Clix Engine w/8MB + * 663 200 Series SR VME-Adapter + * 664 32C Clix Engine w/16MB + * 675 SR Plotter-DMA-Interface + * 677 32C Clix Engine w/6MB + * 686 8Mb Integrated Frame Buffer f/2Mp + * 693 Clix Engine w/8MB + * 694 Clix Engine w/16MB + * 722 SR Frame Grabber NTSC + * 730 300/400 Series Clix Engine w/8MB + * 732 Clix Engine w/16MB + * 739 16MB Expansion Memory + * 765 6000 System Board w/16MB + * 776 Runlength Encoder + * 777 Scanner Interface + * 778 Nonlinear Filter + * 779 SIP Convolution Filter + * 789 32C Clix Engine w/6MB + * 792 Digitizer/HardCopy Controller Plus + * 796 2Mb Integrated Frame Buffer f/1Mp -T + * 799 80386 I/O Processor -T + * 801 Clix Engine w/8MB + * 819 QWIC Bus Clix Engine w/256K CB CACHE + * 820 QWIC System Interface w/64MB ECC + * 821 SRX 32 Channel RS232 Controller + * 822 300 Series Clix Engine w/16MB ECC + * 823 300/400 Series Clix Engine w/8MB ECC + * 825 32C Clix Engine w/12MB + * 826 FDDI Communications Processor + * 828 EDGE-1 Graphics f/1 1Mp Monitor (55K/60) + * 837 Analog Video Mux/Summer -T + * 838 Floating Point Engine -T + * 844 32MB Expansion Memory -T + * 849 EDGE-1 Graphics f/1 2Mp Monitor (55K/60) + * 851 Clix Engine w/16MB ECC -T + * 852 Digitizer/HardCopy Controller Plus -T + * 853 Clix Engine w/16MB ECC -T + * 883 6000 System Board w/8MB + * 887 SR Frame Grabber PAL + * 894 Clix Engine w/16MB ECC + * 896 EDGE-2/Plus Frame Buffer f/2Mp Monitor (V-60) + * 897 EDGE-2 Processor f/1 2Mp-FB + * 904 EDGE-1 Graphics f/2 1Mp Monitors (55K/60) + * 905 SRX Frame Grabber NTSC + * 906 SRX Frame Grabber PAL + * 915 64MB QWIC Bus Expansion Memory + * 917 Input Output Interface + * 932 IOI Clix Engine w/16MB ECC + * 956 SRX Enhanced VME-Adapter + * 958 VME-Controller f/SRX Interface + * 962 2000 System Board + * 963 2000 Graphics f/1 1Mp Monitor + * 965 EDGE-1 Graphics f/1 1Mp Monitor (66K/72) + * 966 EDGE-1 Graphics f/2 1Mp Monitors (66K/72) + * 977 6000 System Board w/32MB parity + * 978 6000 System Board w/48MB parity + * 979 6000 System Board w/64MB parity + * 980 6200 System Board w/8MB parity + * 981 6200 System Board w/16MB parity + * 982 6200 System Board w/32MB parity + * 983 6200 System Board w/48MB parity + * 984 6200 System Board w/64MB parity + * 31275 Raster Data Board + * 31277 Screener III A Board + * 31277/8 Screener III A+B Board + * A59 200 Series Clix Engine w/16MB parity + * A61 200 Series Clix Engine w/8MB parity + * A63 EDGE-2 Frame Buffer f/1Mp Monitor (55K/60) + * A77 200 Series Clix Engine w/16MB + * A79 2000 Graphics f/2 1Mp Monitors + * A80 QWIC System Interface w/16MB ECC + * A81 300 Series Clix Engine w/16MB ECC + * A86 SRX Teleconferencing Controller + * A95 IOI Clix Engine w/32MB ECC + * A96 IOI Clix Engine w/64MB ECC + * B13 System Board w/16MB parity -T + * B14 System Board w/48MB parity -T + * B15 EDGE-1 Graphics f/1 1Mp Monitor (55K/60) -T + * B16 EDGE-1 Graphics f/2 1Mp Monitors (55K/60) -T + * B17 IOI Clix Engine w/16MB ECC -T + * B18 Input Output Interface -T + * B20 SRX 32 Channel RS232 Controller -T + * B21 FDDI Communications Processor -T + * B22 SRX Quad-SCSI Controller -T + * b23 JPEG Compression/Decompression I/F + * B50 Application-Specific Acceleration Proc. II + * B63 IOI Clix Engine w/64MB ECC -T + * B67 GT Plus Graphics f/1 1Mp Monitor (V-76) + * B68 GT II Graphics f/1 1Mp Monitor (V-76) + * B70 GT II Graphics f/2 1Mp Monitors (V-76) + * B92 GT II Graphics f/1 2Mp Monitor (V-60/76) + * B93 GT II Graphics f/2 2Mp Monitors (V-60/76) + * B99 NTSC Frame Grabber for 3000 Series + * C01 PAL Frame Grabber for 3000 series + * C02 NTSC Frame Grabber for 6000 series + * C03 PAL Frame Grabber for 6000 series + * c05 25Mhz GTII Graphics f/1 1Mp Monitor + * c06 25Mhz GTII Graphics f/2 1Mp Monitors + * C41 GTII 60/76Hz Graphics f/1 2Mp Monitor + * C42 GTII 60/76Hz Graphics f/2 2Mp Monitor + */ + +#include "emu.h" +#include "sr.h" + +#define VERBOSE 0 +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(SR_SLOT, sr_slot_device, "sr_slot", "InterPro SR bus slot") + +sr_slot_device::sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SR_SLOT, tag, owner, clock) + , device_slot_interface(mconfig, *this) + , m_sr_tag(nullptr) + , m_sr_slottag(nullptr) +{ +} + +void sr_slot_device::static_set_sr_slot(device_t &device, const char *tag, const char *slottag) +{ + sr_slot_device &sr_card = dynamic_cast(device); + + sr_card.m_sr_tag = tag; + sr_card.m_sr_slottag = slottag; +} + +void sr_slot_device::device_start() +{ + device_sr_card_interface *dev = dynamic_cast(get_card_device()); + + if (dev) + device_sr_card_interface::static_set_sr_tag(*dev, m_sr_tag, m_sr_slottag); +} + +DEFINE_DEVICE_TYPE(SR, sr_device, "sr", "InterPro SR bus") + +sr_device::sr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SR, tag, owner, clock) + , m_data_space(nullptr) + , m_io_space(nullptr) + , m_out_irq0_cb(*this) + , m_out_irq1_cb(*this) + , m_out_irq2_cb(*this) +{ +} + +void sr_device::device_start() +{ + // grab the main memory space from the mmu + device_memory_interface *mmu; + siblingdevice("mmu")->interface(mmu); + m_data_space = &mmu->space(0); + m_io_space = &mmu->space(1); + + // resolve callbacks + m_out_irq0_cb.resolve_safe(); + m_out_irq1_cb.resolve_safe(); + m_out_irq2_cb.resolve_safe(); + + // empty the slots + m_slot_count = 0; + for (device_sr_card_interface *slot : m_slot) + slot = nullptr; +} + +void sr_device::device_reset() +{ +} + +device_sr_card_interface::device_sr_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) + , m_sr(nullptr) + , m_sr_tag(nullptr) + , m_sr_slottag(nullptr) +{ +} + +device_sr_card_interface::~device_sr_card_interface() +{ +} + +void device_sr_card_interface::static_set_sr_tag(device_t &device, const char *tag, const char *slottag) +{ + device_sr_card_interface &sr_card = dynamic_cast(device); + + sr_card.m_sr_tag = tag; + sr_card.m_sr_slottag = slottag; +} + +void device_sr_card_interface::set_sr_device() +{ + // get a reference to the bus + m_sr = dynamic_cast(device().machine().device(m_sr_tag)); + + // install the card in the next available slot + m_sr->install_card(*this, &device_sr_card_interface::map); +} + +sr_card_device_base::sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const char *idprom_region) + : device_t(mconfig, type, tag, owner, clock) + , device_sr_card_interface(mconfig, *this) + , m_idprom_region(idprom_region) +{ +} + +void sr_card_device_base::device_start() +{ + set_sr_device(); +} diff --git a/src/devices/bus/interpro/sr/sr.h b/src/devices/bus/interpro/sr/sr.h new file mode 100644 index 00000000000..236b4ea674b --- /dev/null +++ b/src/devices/bus/interpro/sr/sr.h @@ -0,0 +1,141 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_BUS_INTERPRO_SR_SR_H +#define MAME_BUS_INTERPRO_SR_SR_H + +#pragma once + +#define MCFG_SR_OUT_IRQ0_CB(_devcb) \ + devcb = &sr_device::set_out_irq0_callback(*device, DEVCB_##_devcb); + +#define MCFG_SR_OUT_IRQ1_CB(_devcb) \ + devcb = &sr_device::set_out_irq1_callback(*device, DEVCB_##_devcb); + +#define MCFG_SR_OUT_IRQ2_CB(_devcb) \ + devcb = &sr_device::set_out_irq2_callback(*device, DEVCB_##_devcb); + +#define MCFG_SR_SLOT_ADD(_srtag, _tag, _slot_intf, _def_slot, _fixed) \ + MCFG_DEVICE_ADD(_tag, SR_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) \ + sr_slot_device::static_set_sr_slot(*device, _srtag, _tag); + +#define MCFG_SR_SLOT_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +class sr_slot_device : public device_t, public device_slot_interface +{ +public: + // construction/destruction + sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // inline configuration + static void static_set_sr_slot(device_t &device, const char *tag, const char *slottag); +protected: + sr_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; + + // configuration + const char *m_sr_tag, *m_sr_slottag; +}; + +class device_sr_card_interface; + +class sr_device : public device_t +{ +public: + // construction/destruction + sr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // inline configuration + template static devcb_base &set_out_irq0_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq0_cb.set_callback(std::forward(cb)); } + template static devcb_base &set_out_irq1_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq1_cb.set_callback(std::forward(cb)); } + template static devcb_base &set_out_irq2_callback(device_t &device, Object &&cb) { return downcast(device).m_out_irq2_cb.set_callback(std::forward(cb)); } + + static const u32 SR_BASE = 0x87000000; + static const u32 SR_SIZE = 0x08000000; + static const int SR_COUNT = 16; + + DECLARE_WRITE_LINE_MEMBER(irq0_w) { m_out_irq0_cb(state); } + DECLARE_WRITE_LINE_MEMBER(irq1_w) { m_out_irq1_cb(state); } + DECLARE_WRITE_LINE_MEMBER(irq2_w) { m_out_irq2_cb(state); } + + // installation function for card devices + template void install_card(T &device, void (T::*map)(address_map &map)) + { + // record the device in the next free slot + m_slot[m_slot_count] = &device; + + // compute slot base address + offs_t start = SR_BASE + m_slot_count * SR_SIZE; + offs_t end = start + (SR_SIZE - 1); + + // install the device address map + m_data_space->install_device(start, end, device, map, 32); + m_io_space->install_device(start, end, device, map, 32); + + m_slot_count++; + } + +protected: + sr_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // internal state + address_space *m_data_space; + address_space *m_io_space; + + devcb_write_line m_out_irq0_cb; + devcb_write_line m_out_irq1_cb; + devcb_write_line m_out_irq2_cb; + +private: + device_sr_card_interface *m_slot[SR_COUNT]; + int m_slot_count; +}; + +class device_sr_card_interface : public device_slot_card_interface +{ +public: + // construction/destruction + virtual ~device_sr_card_interface(); + + virtual DECLARE_ADDRESS_MAP(map, 32) = 0; + + void set_sr_device(); + + // inline configuration + static void static_set_sr_tag(device_t &device, const char *tag, const char *slottag); + +protected: + device_sr_card_interface(const machine_config &mconfig, device_t &device); + + sr_device *m_sr; + const char *m_sr_tag, *m_sr_slottag; +}; + +class sr_card_device_base : public device_t, public device_sr_card_interface +{ +protected: + sr_card_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const char *idprom_region = "idprom"); + +public: + READ32_MEMBER(idprom_r) { return device().memregion(m_idprom_region)->as_u32(offset); } + +protected: + // device-level overrides + virtual void device_start() override; + +private: + const char *const m_idprom_region; +}; + +DECLARE_DEVICE_TYPE(SR, sr_device) +DECLARE_DEVICE_TYPE(SR_SLOT, sr_slot_device) + +#endif // MAME_BUS_INTERPRO_SR_SR_H diff --git a/src/devices/bus/interpro/sr/sr_cards.cpp b/src/devices/bus/interpro/sr/sr_cards.cpp new file mode 100644 index 00000000000..9a626b04a6e --- /dev/null +++ b/src/devices/bus/interpro/sr/sr_cards.cpp @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#include "emu.h" +#include "sr_cards.h" + +// video +#include "gt.h" + +// storage + +// sound + +// network + +// communication ports + +// other + + +SLOT_INTERFACE_START(sr_cards) + SLOT_INTERFACE("mpcb963", MPCB963) + SLOT_INTERFACE("mpcba79", MPCBA79) +SLOT_INTERFACE_END diff --git a/src/devices/bus/interpro/sr/sr_cards.h b/src/devices/bus/interpro/sr/sr_cards.h new file mode 100644 index 00000000000..b7f552173d4 --- /dev/null +++ b/src/devices/bus/interpro/sr/sr_cards.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_BUS_INTERPRO_SR_SR_CARDS_H +#define MAME_BUS_INTERPRO_SR_SR_CARDS_H + +#pragma once + +// supported devices +SLOT_INTERFACE_EXTERN(sr_cards); + +#endif // MAME_BUS_INTERPRO_SR_SR_CARDS_H diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 0fae144e945..4e11ddec049 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -62,6 +62,8 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, const char *tag, arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint8_t archFlags, endianness_t endianness) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", endianness, 32, 32, 0) + , m_prefetch_word0_shift(endianness == ENDIANNESS_LITTLE ? 0 : 16) + , m_prefetch_word1_shift(endianness == ENDIANNESS_LITTLE ? 16 : 0) , m_endian(endianness) , m_archRev(archRev) , m_archFlags(archFlags) @@ -342,7 +344,7 @@ int arm7_cpu_device::detect_fault(int desc_lvl1, int ap, int flags) } -bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) +bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_exception) { if (addr < 0x2000000) { @@ -374,6 +376,9 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) } else { + if (no_exception) + return false; + if (flags & ARM7_TLB_ABORT_D) { uint8_t domain = (desc_lvl1 >> 5) & 0xF; @@ -397,6 +402,9 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) } else if (tlb_type == COPRO_TLB_UNMAPPED) { + if (no_exception) + return false; + // Unmapped, generate a translation fault if (flags & ARM7_TLB_ABORT_D) { @@ -428,6 +436,9 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) switch( desc_lvl2 & 3 ) { case COPRO_TLB_UNMAPPED: + if (no_exception) + return false; + // Unmapped, generate a translation fault if (flags & ARM7_TLB_ABORT_D) { @@ -458,6 +469,10 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags) { addr = ( desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK ) | ( addr & ~COPRO_TLB_SMALL_PAGE_MASK ); } + else if (no_exception) + { + return false; + } else { if (flags & ARM7_TLB_ABORT_D) @@ -669,7 +684,7 @@ void arm7_cpu_device::update_insn_prefetch(uint32_t curr_pc) for (uint32_t i = 0; i < to_fetch; i++) { uint32_t index = (i + start_index) % m_insn_prefetch_depth; - if ((m_control & COPRO_CTRL_MMU_EN) && !arm7_tlb_translate(pc, ARM7_TLB_ABORT_P | ARM7_TLB_READ)) + if ((m_control & COPRO_CTRL_MMU_EN) && !arm7_tlb_translate(pc, ARM7_TLB_ABORT_P | ARM7_TLB_READ, true)) { break; } @@ -686,12 +701,12 @@ uint16_t arm7_cpu_device::insn_fetch_thumb(uint32_t pc) { if (pc & 2) { - uint16_t insn = (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> 16); + uint16_t insn = (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word1_shift); m_insn_prefetch_index = (m_insn_prefetch_index + 1) % m_insn_prefetch_count; m_insn_prefetch_count--; return insn; } - return (uint16_t)m_insn_prefetch_buffer[m_insn_prefetch_index]; + return (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word0_shift); } uint32_t arm7_cpu_device::insn_fetch_arm(uint32_t pc) @@ -936,20 +951,14 @@ offs_t arm7_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons { if (m_endian == ENDIANNESS_BIG) { - if (pc & 1) - { - fetched_op[1] = op & 0xff; - fetched_op[0] = (op >> 8) & 0xff; - } - else - { - fetched_op[1] = op & 0xff; - fetched_op[0] = (op >> 8) & 0xff; - } + op >>= ((pc & 2) ? 0 : 16); + fetched_op[1] = op & 0xff; + fetched_op[0] = (op >> 8) & 0xff; return CPU_DISASSEMBLE_NAME(arm7thumb_be)(this, stream, pc, fetched_op, opram, options); } else { + op >>= ((pc & 2) ? 16 : 0); fetched_op[0] = op & 0xff; fetched_op[1] = (op >> 8) & 0xff; return CPU_DISASSEMBLE_NAME(arm7thumb)(this, stream, pc, fetched_op, opram, options); diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index 65ebd9ad35f..e6777b39227 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -139,6 +139,8 @@ protected: uint32_t m_insn_prefetch_index; uint32_t m_insn_prefetch_buffer[3]; uint32_t m_insn_prefetch_address[3]; + const uint32_t m_prefetch_word0_shift; + const uint32_t m_prefetch_word1_shift; bool m_pendingIrq; bool m_pendingFiq; @@ -213,7 +215,7 @@ protected: void arm9ops_e(uint32_t insn); void set_cpsr(uint32_t val); - bool arm7_tlb_translate(offs_t &addr, int flags); + bool arm7_tlb_translate(offs_t &addr, int flags, bool no_exception = false); uint32_t arm7_tlb_get_second_level_descriptor( uint32_t granularity, uint32_t first_desc, uint32_t vaddr ); int detect_fault(int desc_lvl1, int ap, int flags); void arm7_check_irq_state(); diff --git a/src/devices/machine/1mb5.cpp b/src/devices/machine/1mb5.cpp new file mode 100644 index 00000000000..0aa151251d2 --- /dev/null +++ b/src/devices/machine/1mb5.cpp @@ -0,0 +1,295 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +/********************************************************************* + + 1mb5.cpp + + HP-8x I/O Translator chip (1MB5-0101) + + Reference for this chip: + HP, aug 79, 1MB5 Detailed specification - Translator chip + +*********************************************************************/ + +#include "emu.h" +#include "1mb5.h" + +// Debugging +#define VERBOSE 0 +#include "logmacro.h" + +// device type definition +DEFINE_DEVICE_TYPE(HP_1MB5, hp_1mb5_device, "hp_1mb5", "HP 1MB5") + +// Bit manipulation +namespace { + static constexpr unsigned BIT_MASK(unsigned n) + { + return 1U << n; + } + + template void BIT_CLR(T& w , unsigned n) + { + w &= ~(T)BIT_MASK(n); + } + + template void BIT_SET(T& w , unsigned n) + { + w |= (T)BIT_MASK(n); + } + + template void COPY_BIT(bool bit , T& w , unsigned n) + { + if (bit) { + BIT_SET(w , n); + } else { + BIT_CLR(w , n); + } + } +} + +hp_1mb5_device::hp_1mb5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +: device_t(mconfig , HP_1MB5 , tag , owner , clock), + m_irl_handler(*this), + m_halt_handler(*this), + m_reset_handler(*this), + m_int_handler(*this) +{ +} + +READ8_MEMBER(hp_1mb5_device::cpu_r) +{ + uint8_t res = 0; + + switch (offset) { + case 0: + // Read SR + res = m_sr & 0x7e; + if (m_obf) { + BIT_SET(res , 7); + } + if (m_ibf) { + BIT_SET(res , 0); + } + break; + + case 1: + // Read IB + res = m_ib; + m_ibf = false; + update_halt(); + break; + } + + //LOG("RD %u=%02x\n" , offset , res); + return res; +} + +WRITE8_MEMBER(hp_1mb5_device::cpu_w) +{ + //LOG("WR %u=%02x\n" , offset , data); + bool need_resched = false; + + switch (offset) { + case 0: + // Write CR + m_cr = data; + need_resched |= set_reset(BIT(m_cr , 7)); + need_resched |= set_int(!BIT(m_cr , 0)); + break; + + case 1: + // Write OB + m_ob = data; + m_obf = true; + update_halt(); + break; + } + if (need_resched) { + LOG("resched %s\n" , space.device().tag()); + space.device().execute().yield(); + } +} + +READ8_MEMBER(hp_1mb5_device::uc_r) +{ + uint8_t res = 0; + bool need_resched = false; + + switch (offset) { + case 0: + // Read CR + res = m_cr & 0x7e; + if (m_obf) { + BIT_SET(res , 7); + } + if (m_ibf) { + BIT_SET(res , 0); + } + break; + + case 1: + // Read OB + res = m_ob; + m_obf = false; + need_resched |= update_halt(); + break; + } + + if (need_resched) { + LOG("resched %s\n" , space.device().tag()); + space.device().execute().spin(); + } + //LOG("RDU %u=%02x\n" , offset , res); + return res; +} + +WRITE8_MEMBER(hp_1mb5_device::uc_w) +{ + //LOG("WRU %u=%02x SR=%02x\n" , offset , data , m_sr); + bool need_resched = false; + + switch (offset) { + case 0: + // Write SR + if (!BIT(m_sr , 0) && BIT(data , 0)) { + need_resched |= set_service(true); + } + m_sr = data; + m_hlten = BIT(m_sr , 7); + if (update_halt() && !m_halt) { + need_resched = true; + } + break; + + case 1: + // Write IB + m_ib = data; + m_ibf = true; + need_resched |= update_halt(); + break; + } + if (need_resched) { + LOG("resched %s\n" , space.device().tag()); + space.device().execute().spin(); + } +} + +READ_LINE_MEMBER(hp_1mb5_device::irl_r) +{ + return m_service; +} + +READ_LINE_MEMBER(hp_1mb5_device::halt_r) +{ + return m_halt; +} + +READ_LINE_MEMBER(hp_1mb5_device::reset_r) +{ + return m_reset; +} + +READ_LINE_MEMBER(hp_1mb5_device::int_r) +{ + return m_cint; +} + +void hp_1mb5_device::inten() +{ + // Enabling interrupts (i.e. writing to 0xff40) removes uC reset + set_reset(false); +} + +void hp_1mb5_device::clear_service() +{ + set_service(false); +} + +void hp_1mb5_device::device_start() +{ + m_irl_handler.resolve_safe(); + m_halt_handler.resolve_safe(); + m_reset_handler.resolve_safe(); + m_int_handler.resolve_safe(); + + save_item(NAME(m_sr)); + save_item(NAME(m_cr)); + save_item(NAME(m_ib)); + save_item(NAME(m_ob)); + save_item(NAME(m_ibf)); + save_item(NAME(m_obf)); + save_item(NAME(m_hlten)); + save_item(NAME(m_service)); + save_item(NAME(m_cint)); + save_item(NAME(m_reset)); + save_item(NAME(m_halt)); +} + +void hp_1mb5_device::device_reset() +{ + m_sr = 0; + m_cr = 0; + m_ib = 0; + m_ob = 0; + m_ibf = false; + m_obf = false; + m_hlten = false; + m_service = false; + m_cint = true; + m_reset = true; + m_halt = false; + + m_irl_handler(false); + m_halt_handler(false); + m_reset_handler(true); + m_int_handler(true); +} + +bool hp_1mb5_device::set_service(bool new_service) +{ + if (new_service != m_service) { + m_service = new_service; + //LOG("irl=%d\n" , m_service); + m_irl_handler(m_service); + return true; + } else { + return false; + } +} + +bool hp_1mb5_device::update_halt() +{ + bool new_halt = m_hlten && m_obf && !m_ibf; + if (new_halt != m_halt) { + //LOG("HALT=%d\n" , new_halt); + m_halt = new_halt; + m_halt_handler(m_halt); + return true; + } else { + return false; + } +} + +bool hp_1mb5_device::set_reset(bool new_reset) +{ + if (new_reset != m_reset) { + m_reset = new_reset; + m_reset_handler(m_reset); + return true; + } else { + return false; + } +} + +bool hp_1mb5_device::set_int(bool new_int) +{ + if (new_int != m_cint) { + m_cint = new_int; + LOG("cint=%d\n" , m_cint); + m_int_handler(m_cint); + return true; + } else { + return false; + } +} diff --git a/src/devices/machine/1mb5.h b/src/devices/machine/1mb5.h new file mode 100644 index 00000000000..3350e4a968c --- /dev/null +++ b/src/devices/machine/1mb5.h @@ -0,0 +1,95 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +/********************************************************************* + + 1mb5.h + + HP-8x I/O Translator chip (1MB5-0101) + +*********************************************************************/ + +#ifndef MAME_MACHINE_1MB5_H +#define MAME_MACHINE_1MB5_H + +#pragma once + +#define MCFG_1MB5_IRL_HANDLER(_devcb) \ + devcb = &hp_1mb5_device::set_irl_handler(*device , DEVCB_##_devcb); + +#define MCFG_1MB5_HALT_HANDLER(_devcb) \ + devcb = &hp_1mb5_device::set_halt_handler(*device , DEVCB_##_devcb); + +#define MCFG_1MB5_RESET_HANDLER(_devcb) \ + devcb = &hp_1mb5_device::set_reset_handler(*device , DEVCB_##_devcb); + +#define MCFG_1MB5_INT_HANDLER(_devcb) \ + devcb = &hp_1mb5_device::set_int_handler(*device , DEVCB_##_devcb); + +class hp_1mb5_device : public device_t +{ +public: + // construction/destruction + hp_1mb5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // static configuration helpers + template static devcb_base &set_irl_handler(device_t &device, Object &&cb) { return downcast(device).m_irl_handler.set_callback(std::forward(cb)); } + template static devcb_base &set_halt_handler(device_t &device, Object &&cb) { return downcast(device).m_halt_handler.set_callback(std::forward(cb)); } + template static devcb_base &set_reset_handler(device_t &device, Object &&cb) { return downcast(device).m_reset_handler.set_callback(std::forward(cb)); } + template static devcb_base &set_int_handler(device_t &device, Object &&cb) { return downcast(device).m_int_handler.set_callback(std::forward(cb)); } + + // CPU access + DECLARE_READ8_MEMBER(cpu_r); + DECLARE_WRITE8_MEMBER(cpu_w); + + // uC access + DECLARE_READ8_MEMBER(uc_r); + DECLARE_WRITE8_MEMBER(uc_w); + + // Signals to CPU + DECLARE_READ_LINE_MEMBER(irl_r); + DECLARE_READ_LINE_MEMBER(halt_r); + + // Signals to uC + DECLARE_READ_LINE_MEMBER(reset_r); + DECLARE_READ_LINE_MEMBER(int_r); + + // Interrupt enable + void inten(); + + // Interrupt clearing + void clear_service(); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + devcb_write_line m_irl_handler; + devcb_write_line m_halt_handler; + devcb_write_line m_reset_handler; + devcb_write_line m_int_handler; + + // Registers + uint8_t m_sr; + uint8_t m_cr; + uint8_t m_ib; + uint8_t m_ob; + bool m_ibf; + bool m_obf; + bool m_hlten; + bool m_service; + bool m_cint; + bool m_reset; + bool m_halt; + + bool set_service(bool new_service); + bool update_halt(); + bool set_reset(bool new_reset); + bool set_int(bool new_int); +}; + +// device type definition +DECLARE_DEVICE_TYPE(HP_1MB5, hp_1mb5_device) + +#endif /* MAME_MACHINE_1MB5_H */ diff --git a/src/devices/machine/6522via.cpp b/src/devices/machine/6522via.cpp index 6ce5e514a7e..ae1b7da0f61 100644 --- a/src/devices/machine/6522via.cpp +++ b/src/devices/machine/6522via.cpp @@ -347,12 +347,17 @@ void via6522_device::clear_int(int data) { if (m_ifr & data) { + LOGINT("cleared\n"); m_ifr &= ~data; output_irq(); LOG("%s:6522VIA chip %s: IFR = %02X\n", machine().describe_context(), tag(), m_ifr); } + else + { + LOGINT("not cleared\n"); + } } @@ -559,6 +564,7 @@ READ8_MEMBER( via6522_device::read ) val = m_latch_b; } + LOGINT("PB INT "); CLR_PB_INT(); break; @@ -573,6 +579,7 @@ READ8_MEMBER( via6522_device::read ) val = m_latch_a; } + LOGINT("PA INT "); CLR_PA_INT(); if (m_out_ca2 && (CA2_PULSE_OUTPUT(m_pcr) || CA2_AUTO_HS(m_pcr))) @@ -607,6 +614,7 @@ READ8_MEMBER( via6522_device::read ) break; case VIA_T1CL: + LOGINT("T1CL INT "); clear_int(INT_T1); val = get_counter1_value() & 0xFF; break; @@ -624,6 +632,7 @@ READ8_MEMBER( via6522_device::read ) break; case VIA_T2CL: + LOGINT("T2CL INT "); clear_int(INT_T2); if (m_t2_active) { @@ -666,6 +675,7 @@ READ8_MEMBER( via6522_device::read ) m_out_cb1 = 1; m_cb1_handler(m_out_cb1); m_shift_counter = 0x0f; + LOGINT("SR INT "); clear_int(INT_SR); LOGSHIFT(" - ACR: %02x ", m_acr); if (SI_O2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr)) @@ -730,6 +740,7 @@ WRITE8_MEMBER( via6522_device::write ) output_pb(); } + LOGINT("PB INT "); CLR_PB_INT(); if (m_out_cb2 && CB2_AUTO_HS(m_pcr)) @@ -747,6 +758,7 @@ WRITE8_MEMBER( via6522_device::write ) output_pa(); } + LOGINT("PA INT "); CLR_PA_INT(); if (m_out_ca2 && (CA2_PULSE_OUTPUT(m_pcr) || CA2_AUTO_HS(m_pcr))) @@ -795,6 +807,7 @@ WRITE8_MEMBER( via6522_device::write ) case VIA_T1LH: m_t1lh = data; + LOGINT("T1LH INT "); clear_int(INT_T1); break; @@ -802,6 +815,7 @@ WRITE8_MEMBER( via6522_device::write ) m_t1ch = m_t1lh = data; m_t1cl = m_t1ll; + LOGINT("T1CH INT "); clear_int(INT_T1); m_t1_pb7 = 0; @@ -823,6 +837,7 @@ WRITE8_MEMBER( via6522_device::write ) m_t2ch = m_t2lh = data; m_t2cl = m_t2ll; + LOGINT("T2 INT "); clear_int(INT_T2); if (!T2_COUNT_PB6(m_acr)) @@ -851,6 +866,7 @@ WRITE8_MEMBER( via6522_device::write ) } m_shift_counter = 0x0f; + LOGINT("SR INT "); clear_int(INT_SR); LOGSHIFT(" - ACR is: %02x ", m_acr); if (SO_O2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr)) @@ -940,6 +956,7 @@ WRITE8_MEMBER( via6522_device::write ) { data = 0x7f; } + LOGINT("IFR INT "); clear_int(data); break; } diff --git a/src/devices/machine/phi.cpp b/src/devices/machine/phi.cpp index 42cede7e6d8..e86a7bb72ce 100644 --- a/src/devices/machine/phi.cpp +++ b/src/devices/machine/phi.cpp @@ -1246,7 +1246,7 @@ bool phi_device::if_cmd_received(uint8_t byte) } } else { // command is a secondary address - if (m_t_state == PHI_T_ID1 && my_addr) { + if (m_t_state == PHI_T_ID1 && (m_l_state == PHI_L_LADS) == !!lon_msg() && my_addr) { // Start IDENTIFY sequence m_t_state = PHI_T_ID2; } else if (m_t_state >= PHI_T_ID2 && m_t_state <= PHI_T_ID6 && !my_addr) { diff --git a/src/lib/formats/dsk_dsk.cpp b/src/lib/formats/dsk_dsk.cpp index 08f76c90127..493c503c223 100644 --- a/src/lib/formats/dsk_dsk.cpp +++ b/src/lib/formats/dsk_dsk.cpp @@ -398,6 +398,11 @@ bool dsk_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) continue; track_header tr; io_generic_read(io, &tr,track_offsets[(track<<1)+side],sizeof(tr)); + + // skip if there are no sectors in this track + if (tr.number_of_sector == 0) + continue; + desc_pc_sector sects[256]; uint8_t sect_data[65536]; int sdatapos = 0; diff --git a/src/mame/drivers/alphatpx.cpp b/src/mame/drivers/alphatpx.cpp index a7028cd1420..5c31f58cae0 100644 --- a/src/mame/drivers/alphatpx.cpp +++ b/src/mame/drivers/alphatpx.cpp @@ -28,11 +28,11 @@ class alphatpx_state : public driver_device { public: alphatpx_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_bankdev(*this, "bankdev"), - m_palette(*this, "palette"), - m_vram(*this, "vram"), - m_gfx(*this, "gfx") + driver_device(mconfig, type, tag), + m_bankdev(*this, "bankdev"), + m_palette(*this, "palette"), + m_vram(*this, "vram"), + m_gfx(*this, "gfx") { } uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -225,7 +225,7 @@ ROM_START( alphatp3 ) ROM_LOAD("caap36_02_19.bin", 0x0000, 0x1000, CRC(23df6666) SHA1(5ea04cd299dec9951425eb91ecceb4818c4c6378)) ROM_REGION(0x400, "mcu", 0) - ROM_LOAD("p3_8041.bin", 0x000, 0x400, CRC(97206ad7) SHA1(e4e6b2ebf87ae9dc0b051f3f478496109d124896)) + ROM_LOAD("p3_8041.bin", 0x000, 0x400, NO_DUMP) ROM_REGION(0x800, "gfx", 0) ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) diff --git a/src/mame/drivers/atarittl.cpp b/src/mame/drivers/atarittl.cpp index 04d9c1e7aff..23a83e7292f 100644 --- a/src/mame/drivers/atarittl.cpp +++ b/src/mame/drivers/atarittl.cpp @@ -393,6 +393,14 @@ ROM_START( gtrak10 ) ROM_END +ROM_START( gtrak10a ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) + + ROM_REGION( 0x0800, "racetrack", ROMREGION_ERASE00 ) + ROM_LOAD( "074181.j5", 0x0000, 0x0800, CRC(f564c58a) SHA1(8097419e22bd8b5fd2a9fe4ea89302046c42e583) ) // not actually a SN74181 but an Electronic Arrays, Inc. EA4800 16K (2048 x 8) ROM. TI TMS4800 clone (EA4800). Intentionally mislabeled by Atari. +ROM_END + + ROM_START( gtrak20 ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) @@ -639,6 +647,7 @@ ROM_END GAME(1975, antiairc, 0, atarikee, 0, atarikee_state, 0, ROT0, "Atari", "Anti-Aircraft [TTL]", MACHINE_IS_SKELETON) GAME(1975, crashnsc, 0, atarikee, 0, atarikee_state, 0, ROT0, "Atari", "Crash 'n Score/Stock Car [TTL]", MACHINE_IS_SKELETON) GAME(1974, gtrak10, 0, atarikee, 0, atarikee_state, 0, ROT0, "Atari/Kee", "Gran Trak 10/Trak 10/Formula K [TTL]", MACHINE_IS_SKELETON) +GAME(1974, gtrak10a, gtrak10, atarikee, 0, atarikee_state, 0, ROT0, "Atari/Kee", "Gran Trak 10/Trak 10/Formula K (older) [TTL]", MACHINE_IS_SKELETON) GAME(1974, gtrak20, 0, atarikee, 0, atarikee_state, 0, ROT0, "Atari/Kee", "Gran Trak 20/Trak 20/Twin Racer [TTL]", MACHINE_IS_SKELETON) GAME(1976, indy4, 0, atarikee, 0, atarikee_state, 0, ROT0, "Atari/Kee", "Indy 4 [TTL]", MACHINE_IS_SKELETON) GAME(1975, indy800, 0, atarikee, 0, atarikee_state, 0, ROT90, "Atari/Kee", "Indy 800 [TTL]", MACHINE_IS_SKELETON) diff --git a/src/mame/drivers/hp80.cpp b/src/mame/drivers/hp80.cpp index 4a0060726df..64c7d3d5d4d 100644 --- a/src/mame/drivers/hp80.cpp +++ b/src/mame/drivers/hp80.cpp @@ -19,6 +19,7 @@ #include "bus/hp80_optroms/hp80_optrom.h" #include "softlist.h" #include "machine/bankdev.h" +#include "bus/hp80_io/hp80_io.h" // Debugging #define VERBOSE 1 @@ -72,7 +73,8 @@ static constexpr unsigned IRQ_KEYBOARD_BIT = 0; static constexpr unsigned IRQ_TIMER0_BIT = 1; static constexpr unsigned TIMER_COUNT = 4; static constexpr unsigned IRQ_IOP0_BIT = IRQ_TIMER0_BIT + TIMER_COUNT; -static constexpr unsigned IOP_COUNT = 0; +// Maximum count of I/O processors (the same thing as count of I/O slots) +static constexpr unsigned IOP_COUNT = 4; static constexpr unsigned IRQ_BIT_COUNT = IRQ_IOP0_BIT + IOP_COUNT; static constexpr unsigned NO_IRQ = IRQ_BIT_COUNT; @@ -105,11 +107,17 @@ public: DECLARE_READ8_MEMBER(clkdat_r); DECLARE_WRITE8_MEMBER(clkdat_w); DECLARE_WRITE8_MEMBER(rselec_w); + DECLARE_READ8_MEMBER(intrsc_r); + DECLARE_WRITE8_MEMBER(intrsc_w); TIMER_DEVICE_CALLBACK_MEMBER(kb_scan); TIMER_DEVICE_CALLBACK_MEMBER(vm_timer); TIMER_DEVICE_CALLBACK_MEMBER(timer_update); TIMER_DEVICE_CALLBACK_MEMBER(clk_busy_timer); + + DECLARE_WRITE8_MEMBER(irl_w); + DECLARE_WRITE8_MEMBER(halt_w); + protected: required_device m_cpu; required_device m_screen; @@ -124,6 +132,7 @@ protected: required_ioport m_io_modkeys; required_device_array m_rom_drawers; required_device m_rombank; + required_device_array m_io_slots; // Character generator required_region_ptr m_chargen; @@ -137,11 +146,11 @@ protected: uint8_t m_crt_read_byte; uint8_t m_crt_write_byte; bool m_global_int_en; - uint16_t m_int_req; uint16_t m_int_serv; unsigned m_top_pending; uint16_t m_int_acked; uint16_t m_int_en; + uint8_t m_halt_lines; // State of keyboard ioport_value m_kb_state[ 3 ]; @@ -192,6 +201,7 @@ hp85_state::hp85_state(const machine_config &mconfig, device_type type, const ch m_io_modkeys(*this, "MODKEYS"), m_rom_drawers(*this , "drawer%u" , 1), m_rombank(*this , "rombank"), + m_io_slots(*this , "slot%u" , 1), m_chargen(*this , "chargen") { } @@ -210,7 +220,6 @@ void hp85_state::machine_reset() m_crt_ctl = BIT_MASK(CRT_CTL_POWERDN_BIT) | BIT_MASK(CRT_CTL_WIPEOUT_BIT); m_crt_read_byte = 0; m_crt_write_byte = 0; - m_int_req = 0; m_int_serv = 0; m_top_pending = NO_IRQ; m_int_acked = 0; @@ -235,6 +244,8 @@ void hp85_state::machine_reset() m_timer_idx = 0; m_clk_busy = false; update_irl(); + m_halt_lines = 0; + m_cpu->set_input_line(INPUT_LINE_HALT , CLEAR_LINE); // Load optional ROMs (if any) // All entries in rombanks [01..FF] initially not present @@ -245,6 +256,12 @@ void hp85_state::machine_reset() } // Clear RSELEC m_rombank->set_bank(0xff); + + // Mount I/O slots in address space + m_cpu->space(AS_PROGRAM).unmap_readwrite(0xff50 , 0xff5f); + for (auto& io : m_io_slots) { + io->install_read_write_handlers(m_cpu->space(AS_PROGRAM)); + } } uint32_t hp85_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -307,13 +324,24 @@ static const uint8_t vector_table[] = { 0x08, // Timer 0 0x0a, // Timer 1 0x0c, // Timer 2 - 0x0e // Timer 3 + 0x0e, // Timer 3 + 0x10, // Slot 1 + 0x10, // Slot 2 + 0x10, // Slot 3 + 0x10 // Slot 4 }; IRQ_CALLBACK_MEMBER(hp85_state::irq_callback) { logerror("IRQ ACK %u\n" , m_top_pending); BIT_SET(m_int_acked , m_top_pending); + if (m_top_pending > IRQ_IOP0_BIT && m_top_pending < IRQ_BIT_COUNT) { + // Interrupts are disabled in all I/O translators of higher priority than + // the one being serviced + for (unsigned i = m_top_pending - 1; i >= IRQ_IOP0_BIT; i--) { + irq_en_w(i , false); + } + } update_irl(); return vector_table[ m_top_pending ]; } @@ -539,6 +567,30 @@ WRITE8_MEMBER(hp85_state::rselec_w) m_rombank->set_bank(data); } +READ8_MEMBER(hp85_state::intrsc_r) +{ + if (m_top_pending >= IRQ_IOP0_BIT && m_top_pending < IRQ_BIT_COUNT && BIT(m_int_acked , m_top_pending)) { + return (uint8_t)m_io_slots[ m_top_pending - IRQ_IOP0_BIT ]->get_base_addr(); + } else { + // Probably.. + return 0xff; + } +} + +WRITE8_MEMBER(hp85_state::intrsc_w) +{ + if (m_top_pending >= IRQ_IOP0_BIT && m_top_pending < IRQ_BIT_COUNT && BIT(m_int_acked , m_top_pending)) { + // Clear interrupt request in the slot being serviced + m_io_slots[ m_top_pending - IRQ_IOP0_BIT ]->clear_service(); + } + for (auto& iop: m_io_slots) { + iop->inten(); + } + for (unsigned i = IRQ_IOP0_BIT; i < (IRQ_IOP0_BIT + IOP_COUNT); i++) { + irq_en_w(i , true); + } +} + // Outer index: key position [0..79] = r * 8 + c // Inner index: SHIFT state (0 = no SHIFT, 1 = SHIFT) static const uint8_t keyboard_table[ 80 ][ 2 ] = { @@ -790,6 +842,24 @@ TIMER_DEVICE_CALLBACK_MEMBER(hp85_state::clk_busy_timer) m_clk_busy = false; } +WRITE8_MEMBER(hp85_state::irl_w) +{ + //LOG("irl_w %u=%u\n" , offset , data); + irq_w(offset + IRQ_IOP0_BIT , data != 0); +} + +WRITE8_MEMBER(hp85_state::halt_w) +{ + //LOG("halt_w %u=%u\n" , offset , data); + bool prev_halt = m_halt_lines != 0; + COPY_BIT(data != 0 , m_halt_lines , offset); + bool new_halt = m_halt_lines != 0; + if (prev_halt != new_halt) { + LOG("halt=%d hl=%x\n" , new_halt , m_halt_lines); + m_cpu->set_input_line(INPUT_LINE_HALT , new_halt); + } +} + attotime hp85_state::time_to_video_mem_availability() const { if (BIT(m_crt_ctl , CRT_CTL_WIPEOUT_BIT) || BIT(m_crt_ctl , CRT_CTL_POWERDN_BIT)) { @@ -880,6 +950,7 @@ void hp85_state::video_mem_write() void hp85_state::irq_w(unsigned n_irq , bool state) { + //LOG("irq_w %u=%d GIE=%d SRV=%03x ACK=%03x IE=%03x\n" , n_irq , state , m_global_int_en , m_int_serv , m_int_acked , m_int_en); if (state && !BIT(m_int_serv , n_irq)) { // Set service request BIT_SET(m_int_serv , n_irq); @@ -908,6 +979,7 @@ void hp85_state::update_int_bits() void hp85_state::update_irl() { + //LOG("irl GIE=%d top=%u ACK=%03x\n" , m_global_int_en , m_top_pending , m_int_acked); m_cpu->set_input_line(0 , m_global_int_en && m_top_pending < IRQ_BIT_COUNT && !BIT(m_int_acked , m_top_pending)); } @@ -1024,6 +1096,7 @@ static ADDRESS_MAP_START(cpu_mem_map , AS_PROGRAM , 8 , hp85_state) AM_RANGE(0xff0a , 0xff0a) AM_READWRITE(clksts_r , clksts_w) AM_RANGE(0xff0b , 0xff0b) AM_READWRITE(clkdat_r , clkdat_w) AM_RANGE(0xff18 , 0xff18) AM_WRITE(rselec_w) + AM_RANGE(0xff40 , 0xff40) AM_READWRITE(intrsc_r , intrsc_w) ADDRESS_MAP_END static ADDRESS_MAP_START(rombank_mem_map , AS_PROGRAM , 8 , hp85_state) @@ -1042,7 +1115,7 @@ static MACHINE_CONFIG_START(hp85) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(21) - MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) + MCFG_ADDRESS_MAP_BANK_STRIDE(HP80_OPTROM_SIZE) MCFG_SCREEN_ADD("screen" , RASTER) MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK / 2 , 312 , 0 , 256 , 256 , 0 , 192) @@ -1085,6 +1158,20 @@ static MACHINE_CONFIG_START(hp85) MCFG_DEVICE_ADD("drawer6", HP80_OPTROM_SLOT, 0) MCFG_DEVICE_SLOT_INTERFACE(hp80_optrom_slot_device, NULL, false) + // I/O slots + MCFG_HP80_IO_SLOT_ADD("slot1" , 0) + MCFG_HP80_IO_IRL_CB(WRITE8(hp85_state , irl_w)) + MCFG_HP80_IO_HALT_CB(WRITE8(hp85_state , halt_w)) + MCFG_HP80_IO_SLOT_ADD("slot2" , 1) + MCFG_HP80_IO_IRL_CB(WRITE8(hp85_state , irl_w)) + MCFG_HP80_IO_HALT_CB(WRITE8(hp85_state , halt_w)) + MCFG_HP80_IO_SLOT_ADD("slot3" , 2) + MCFG_HP80_IO_IRL_CB(WRITE8(hp85_state , irl_w)) + MCFG_HP80_IO_HALT_CB(WRITE8(hp85_state , halt_w)) + MCFG_HP80_IO_SLOT_ADD("slot4" , 3) + MCFG_HP80_IO_IRL_CB(WRITE8(hp85_state , irl_w)) + MCFG_HP80_IO_HALT_CB(WRITE8(hp85_state , halt_w)) + MCFG_SOFTWARE_LIST_ADD("optrom_list" , "hp85_rom") MACHINE_CONFIG_END diff --git a/src/mame/drivers/piggypas.cpp b/src/mame/drivers/piggypas.cpp index 3e74b7215eb..121150f25a7 100644 --- a/src/mame/drivers/piggypas.cpp +++ b/src/mame/drivers/piggypas.cpp @@ -12,6 +12,7 @@ game details unknown #include "emu.h" #include "cpu/mcs51/mcs51.h" #include "machine/i8255.h" +#include "machine/nvram.h" #include "machine/ticket.h" #include "sound/okim6295.h" #include "video/hd44780.h" @@ -57,6 +58,7 @@ WRITE8_MEMBER(piggypas_state::ctrl_w) WRITE8_MEMBER(piggypas_state::mcs51_tx_callback) { + // Serial output driver is UCN5833A output().set_digit_value(m_digit_idx++, BITSWAP8(data,7,6,4,3,2,1,0,5) & 0x7f); } @@ -65,7 +67,7 @@ static ADDRESS_MAP_START( piggypas_map, AS_PROGRAM, 8, piggypas_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( piggypas_io, AS_IO, 8, piggypas_state ) - AM_RANGE(0x0000, 0x07ff) AM_RAM + AM_RANGE(0x0000, 0x07ff) AM_RAM AM_SHARE("nvram") AM_RANGE(0x0800, 0x0803) AM_DEVREADWRITE("ppi", i8255_device, read, write) AM_RANGE(0x1000, 0x1000) AM_DEVREADWRITE("oki", okim6295_device, read, write) AM_RANGE(0x1800, 0x1801) AM_DEVWRITE("hd44780", hd44780_device, write) @@ -125,12 +127,14 @@ HD44780_PIXEL_UPDATE(piggypas_state::piggypas_pixel_update) static MACHINE_CONFIG_START( piggypas ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", I8031, 8000000) // unknown variant + MCFG_CPU_ADD("maincpu", I80C31, XTAL_8_448MHz) // OKI M80C31F or M80C154S MCFG_CPU_PROGRAM_MAP(piggypas_map) MCFG_CPU_IO_MAP(piggypas_io) MCFG_MCS51_SERIAL_TX_CB(WRITE8(piggypas_state, mcs51_tx_callback)) // MCFG_CPU_VBLANK_INT_DRIVER("screen", piggypas_state, irq0_line_hold) + MCFG_NVRAM_ADD_0FILL("nvram") // DS1220AD + MCFG_SCREEN_ADD("screen", LCD) MCFG_SCREEN_REFRESH_RATE(50) MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update) @@ -148,10 +152,10 @@ static MACHINE_CONFIG_START( piggypas ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_OKIM6295_ADD("oki", 1000000, PIN7_HIGH) // not verified + MCFG_OKIM6295_ADD("oki", XTAL_8_448MHz / 8, PIN7_HIGH) // clock and pin 7 not verified MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) - MCFG_DEVICE_ADD("ppi", I8255, 0) + MCFG_DEVICE_ADD("ppi", I8255A, 0) // OKI M82C55A-2 MCFG_I8255_IN_PORTA_CB(IOPORT("IN1")) MCFG_I8255_OUT_PORTB_CB(WRITE8(piggypas_state, ctrl_w)) MCFG_I8255_IN_PORTC_CB(IOPORT("IN0")) diff --git a/src/mame/drivers/prodigy.cpp b/src/mame/drivers/prodigy.cpp index 292c4cef699..1b0c2e46808 100644 --- a/src/mame/drivers/prodigy.cpp +++ b/src/mame/drivers/prodigy.cpp @@ -2,9 +2,16 @@ // copyright-holders:Joakim Larsson Edstrom /****************************************************************************** - ACI Prodigy chess computer driver + ACI Prodigy chess computer driver. - TODO: Everything + http://www.spacious-mind.com/html/destiny_prodigy.html + Morphy software ELO rating: 1559 + + TODO: + - Sound + - Row/column LEDs + - Chess board sensors + - Support for SVG/CSS based browser UI +-------------------------------------------------------------------------------------+ |LEDS--------------------------------------------+ +-----------------+ | @@ -28,7 +35,7 @@ | | || 74145N | | RAM | |LS| | | | A B C D E F G H |+--------+ | M58725P | |00| | | +--------------------------------------------+ +-------------+ +--+ | - |LEDS-> O O O O O O O O OOOOOOOOOOO KPDCN | + |LEDS-> O O O O O O O O OOOOOOOOOOOO KPDCN | +-------------------------------------------------------------------------------------+ Tracing the image shows that VIA Port A is used on the ROWCN and Port B on COLCN @@ -49,6 +56,15 @@ ||||||||||||||||||| PB2--->|145|=/4/=/R/=>b(4x )c=/4/==============> +---+ (PN2907)e=+ anodes |+5v + + The keypad is connected to the 12 pin KPDCN connector left to right KP1: + + Pin #: KP1 KP2 KP3 KP4 KP5 KP6 KP7 KP8 KP9 KP10 KP11 K12 + VIA : PB4 PB5 PA0 PA1 PA2 PA3 PA4 PA5 PA6 PA7 + 74145: Q8 Q9 - used to decode/ground one half of the KPAD at a time + + Q7 is suspected to be ground for the chessboard buttons + *******************************************************************************************/ #include "emu.h" @@ -57,6 +73,7 @@ #include "machine/netlist.h" #include "machine/nl_prodigy.h" #include "machine/6522via.h" + // Generated artwork includes #include "prodigy.lh" @@ -65,9 +82,11 @@ #define LOG_BCD (1U << 3) #define LOG_NETLIST (1U << 4) #define LOG_CLK (1U << 5) +#define LOG_KBD (1U << 6) +#define LOG_AW (1U << 7) -//#define VERBOSE (LOG_BCD|LOG_NETLIST|LOG_SETUP) -//#define LOG_OUTPUT_FUNC printf +//#define VERBOSE (LOG_KBD|LOG_AW) // (LOG_BCD|LOG_NETLIST|LOG_SETUP) +//#define LOG_OUTPUT_STREAM std::cout #include "logmacro.h" @@ -76,6 +95,8 @@ #define LOGBCD(...) LOGMASKED(LOG_BCD, __VA_ARGS__) #define LOGNL(...) LOGMASKED(LOG_NETLIST, __VA_ARGS__) #define LOGCLK(...) LOGMASKED(LOG_CLK, __VA_ARGS__) +#define LOGKBD(...) LOGMASKED(LOG_KBD, __VA_ARGS__) +#define LOGAW(...) LOGMASKED(LOG_AW, __VA_ARGS__) #ifdef _MSC_VER #define FUNCNAME __func__ @@ -84,7 +105,6 @@ #endif #define NETLIST_TAG "bcd" -#define TTL74164DEV 0 class prodigy_state : public driver_device { @@ -99,6 +119,7 @@ public: , m_cb1(*this, "bcd:cb1") , m_cb2(*this, "bcd:cb2") , m_digit(0.0) + , m_io_line(*this, "LINE%u", 0) { } NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit0_cb); @@ -110,6 +131,9 @@ public: NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit6_cb); NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit7_cb); + DECLARE_READ8_MEMBER( via_pa_r ); + DECLARE_READ8_MEMBER( via_pb_r ); + DECLARE_WRITE8_MEMBER( via_pa_w ); DECLARE_WRITE8_MEMBER( via_pb_w ); DECLARE_WRITE_LINE_MEMBER(via_cb1_w); DECLARE_WRITE_LINE_MEMBER(via_cb2_w); @@ -120,17 +144,15 @@ private: required_device m_74145; uint8_t m_segments; required_device m_via; -#if TTL74164DEV - required_device m_shift; -#else required_device m_bcd; required_device m_cb1; required_device m_cb2; -#endif uint8_t m_digit; void update_bcd(); - virtual void device_reset() override; + virtual void device_start() override; + required_ioport_array<5> m_io_line; + uint16_t m_line[5]; }; NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit0_cb) { if (data != 0) m_digit |= 0x01; else m_digit &= ~(0x01); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } @@ -142,12 +164,9 @@ NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit5_cb) { if (data != 0) m_digi NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit6_cb) { if (data != 0) m_digit |= 0x40; else m_digit &= ~(0x40); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit7_cb) { if (data != 0) m_digit |= 0x80; else m_digit &= ~(0x80); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } -void prodigy_state::device_reset() +void prodigy_state::device_start() { -#if TTL74164DEV - m_shift->b_w(1); - m_shift->clear_w(1); -#endif + memset(m_line, 0, sizeof(m_line)); } WRITE_LINE_MEMBER(prodigy_state::via_cb1_w) @@ -175,20 +194,61 @@ WRITE_LINE_MEMBER(prodigy_state::irq_handler) PB2 and PB3 is also connected to the 74145, usage to be traced.... */ -WRITE8_MEMBER( prodigy_state::via_pb_w ) // Needs to trace which port decides what digit + +READ8_MEMBER( prodigy_state::via_pa_r ) { - LOGBCD("%s: %02x ANODE %02x\n", FUNCNAME, data, data & 0x03); - m_74145->write( data & 0x0f ); // Write PB0-PB3 to the 74145 + LOGKBD("%s: Port A <- %02x\n", FUNCNAME, 0); + uint16_t ttl74145_data = m_74145->read(); + + LOGKBD(" - 74145: %03x\n", ttl74145_data); + if (ttl74145_data & 0x100) return (m_line[0] | m_line[1]); + if (ttl74145_data & 0x200) return (m_line[4] | m_line[3]); + + return 0xff; +} + +READ8_MEMBER( prodigy_state::via_pb_r ) +{ + LOGKBD("%s: Port B <- %02x\n", FUNCNAME, 0); + uint16_t ttl74145_data = m_74145->read(); + if (ttl74145_data & 0x100) return (((m_line[2] >> 8) & 3) << 4); + if (ttl74145_data & 0x200) return (((m_line[2] >> 10) & 3) << 4); + + return 0xff; +} + +WRITE8_MEMBER( prodigy_state::via_pa_w ) +{ + LOGKBD("%s: Port A -> %02x\n", FUNCNAME, data); +} + +WRITE8_MEMBER( prodigy_state::via_pb_w ) +{ + LOGBCD("%s: %02x ANODE %c\n", FUNCNAME, data, (data & 0x0f) <= 3 ? ('0' + (data & 0x03)) : 'x'); + LOGKBD("%s: %02x KBD Q8:%c Q9:%c\n", FUNCNAME, data, (data & 0x0f) == 8 ? '0' : '1', (data & 0x0f) == 9 ? '0' : '1'); + // Write PB0-PB3 to the 74145 + // Q0-Q3 => BCD0-BCD3 (PB0-PB1, PB2=0 PB3=0) + // Q8-Q9 => KPDCN (PB0:0=Q8 1=Q9, PB1=0 PB2=0 PB3=1) + m_74145->write( data & 0x0f ); + + // Read the artwork + int i = 0; + for (auto & elem : m_io_line) + { + m_line[i] = elem->read(); + LOGAW("-LINE%u: %02x\n", i, m_line[i]); + i++; + } } void prodigy_state::update_bcd() { LOGBCD("%s\n", FUNCNAME); - uint8_t ttl74145_data; + uint16_t ttl74145_data; uint8_t digit_nbr = 4; ttl74145_data = m_74145->read(); - LOGBCD(" - 74145: %02x\n", ttl74145_data); + LOGBCD(" - 74145: %03x\n", ttl74145_data); if ((ttl74145_data & 0x0f) != 0x00) { @@ -215,7 +275,64 @@ static ADDRESS_MAP_START( maincpu_map, AS_PROGRAM, 8, prodigy_state ) AM_RANGE(0x6000, 0x7fff) AM_ROM AM_REGION("roms", 0x0000) AM_MIRROR(0x8000) ADDRESS_MAP_END +/* + * The keypad was modelled after the physical appearance but altered after finding out how it was working so + * LINE0 to LINE4 has no correlation to the actual keypad anymore, which is connected like this: + * + * con KP1/KP11 + *----------------------- + * KP1 GND/HIZ + * KP2 GO/BLACK + * KP3 A1/B2 + * KP4 D4/E5 + * KP5 G7/E8 + * KP6 RESTORE/HALT&HINT + * KP7 CE/AUDIO + * KP8 LEVEL/TIME&NUMBER + * KP9 CHANGE BOARD/F6 + * KP10 VERIFY/C3 + * KP11 HIZ/GND + * KP12 ENTER/WHITE + *----------------------- + * KP1 and KP11 alternates as GND enabling 10 pads at a time which are read on VIA port A and B. + * TODO: Refactor as two 10 bit LINEs rather then matrix in order to match circuit + * +*/ static INPUT_PORTS_START( prodigy ) + PORT_START("LINE0") /* KEY ROW 0 */ + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D_4") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('4') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G_7") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('7') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RESTORE") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CE") PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT(0xc00, 0x00, IPT_UNUSED ) + + PORT_START("LINE1") /* KEY ROW 1 */ + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LEVEL") PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CHANGE_BOARD") PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("VERIFY") PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT(0xc00, 0x00, IPT_UNUSED ) + + PORT_START("LINE2") /* KEY ROW 2 */ + PORT_BIT(0x100, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("GO") PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT(0x200, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A_1") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('1') + PORT_BIT(0x400, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BLACK") PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT(0x800, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B_2") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('2') + PORT_BIT(0x000, 0x00, IPT_UNUSED ) + + PORT_START("LINE3") /* KEY ROW 3 */ + PORT_BIT(0x001, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E_5") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('5') + PORT_BIT(0x002, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H_8") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('8') + PORT_BIT(0x004, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("HALT_HINT") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT(0x008, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("AUDIO") PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT(0xc00, 0x00, IPT_UNUSED ) + + PORT_START("LINE4") /* KEY ROW 4 */ + PORT_BIT(0x010, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("TIME_NUMBER") PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT(0x020, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F_6") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('6') + PORT_BIT(0x040, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C_3") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('3') + PORT_BIT(0x080, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("WHITE") PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT(0xc00, 0x00, IPT_UNUSED ) INPUT_PORTS_END static MACHINE_CONFIG_START( prodigy ) @@ -228,7 +345,10 @@ static MACHINE_CONFIG_START( prodigy ) MCFG_DEVICE_ADD("via", VIA6522, XTAL_2MHz) MCFG_VIA6522_IRQ_HANDLER(WRITELINE(prodigy_state, irq_handler)); + MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(prodigy_state, via_pa_w)) MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(prodigy_state, via_pb_w)) + MCFG_VIA6522_READPA_HANDLER(READ8(prodigy_state, via_pa_r)) + MCFG_VIA6522_READPB_HANDLER(READ8(prodigy_state, via_pb_r)) MCFG_VIA6522_CB1_HANDLER(WRITELINE(prodigy_state, via_cb1_w)) MCFG_VIA6522_CB2_HANDLER(WRITELINE(prodigy_state, via_cb2_w)) @@ -294,4 +414,4 @@ ROM_START(prodigy) ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS -CONS( 1981, prodigy, 0, 0, prodigy, prodigy, prodigy_state, 0, "Applied Concepts Inc", "ACI Destiny Prodigy", MACHINE_IS_SKELETON ) +CONS( 1981, prodigy, 0, 0, prodigy, prodigy, prodigy_state, 0, "Applied Concepts Inc", "ACI Destiny Prodigy", MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/ptcsol.cpp b/src/mame/drivers/ptcsol.cpp index 7777959b7c2..3e7fa3ed6e1 100644 --- a/src/mame/drivers/ptcsol.cpp +++ b/src/mame/drivers/ptcsol.cpp @@ -733,7 +733,7 @@ void sol20_state::kbd_put(u8 data) static MACHINE_CONFIG_START( sol20 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",I8080, XTAL_14_31818MHz/7) + MCFG_CPU_ADD("maincpu",I8080, XTAL_14_31818MHz / 7) // divider selectable as 5, 6 or 7 through jumpers MCFG_CPU_PROGRAM_MAP(sol20_mem) MCFG_CPU_IO_MAP(sol20_io) MCFG_I8085A_INTE(DEVWRITELINE("speaker", speaker_sound_device, level_w)) diff --git a/src/mame/drivers/rmnimbus.cpp b/src/mame/drivers/rmnimbus.cpp index 005b2fd374c..c7bd3504d30 100644 --- a/src/mame/drivers/rmnimbus.cpp +++ b/src/mame/drivers/rmnimbus.cpp @@ -100,14 +100,6 @@ static ADDRESS_MAP_START( nimbus_iocpu_io , AS_IO, 8, rmnimbus_state ) AM_RANGE(0x20000, 0x20004) AM_READWRITE(nimbus_pc8031_port_r, nimbus_pc8031_port_w) ADDRESS_MAP_END -static const uint16_t def_config[16] = -{ - 0x0280, 0x017F, 0xE824, 0x8129, - 0x0329, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x8893, 0x2025, 0xB9E6 -}; - static MACHINE_CONFIG_START( nimbus ) /* basic machine hardware */ MCFG_CPU_ADD(MAINCPU_TAG, I80186, 16000000) // the cpu is a 10Mhz part but the serial clocks are wrong unless it runs at 8Mhz @@ -180,7 +172,6 @@ static MACHINE_CONFIG_START( nimbus ) MCFG_RS232_CTS_HANDLER(DEVWRITELINE(Z80SIO_TAG, z80dart_device, ctsb_w)) MCFG_EEPROM_SERIAL_93C06_ADD(ER59256_TAG) - MCFG_EEPROM_DATA(def_config,sizeof(def_config)) MCFG_DEVICE_ADD(VIA_TAG, VIA6522, 1000000) MCFG_VIA6522_WRITEPA_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) @@ -227,6 +218,9 @@ ROM_START( nimbus ) ROM_REGION( 0x4000, IOCPU_TAG, 0 ) ROM_LOAD("hexec-v1.02u-13488-1985-10-29.rom", 0x0000, 0x1000, CRC(75c6adfd) SHA1(0f11e0b7386c6368d20e1fc7a6196d670f924825)) + + ROM_REGION16_LE( 0x20, ER59256_TAG, 0 ) // default eeprom data + ROM_LOAD("er59256", 0x00, 0x20, CRC(1a39de76) SHA1(0b6607f008dd92d6ab9af62b0b042fc3f5f4461c)) ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS diff --git a/src/mame/drivers/tceptor.cpp b/src/mame/drivers/tceptor.cpp index e04ac7de1b7..0b03349fc0a 100644 --- a/src/mame/drivers/tceptor.cpp +++ b/src/mame/drivers/tceptor.cpp @@ -22,6 +22,8 @@ #include "rendlay.h" #include "speaker.h" +#include "tceptor2.lh" + /*******************************************************************/ @@ -141,11 +143,6 @@ READ8_MEMBER(tceptor_state::input1_r) return fix_input1(ioport("BUTTONS")->read(), ioport("SERVICE")->read()); } -READ8_MEMBER(tceptor_state::readFF) -{ - return 0xff; -} - /*******************************************************************/ static ADDRESS_MAP_START( m6809_map, AS_PROGRAM, 8, tceptor_state ) @@ -154,7 +151,7 @@ static ADDRESS_MAP_START( m6809_map, AS_PROGRAM, 8, tceptor_state ) AM_RANGE(0x1c00, 0x1fff) AM_RAM_WRITE(tceptor_tile_attr_w) AM_SHARE("tile_attr") AM_RANGE(0x2000, 0x3fff) AM_RAM_WRITE(tceptor_bg_ram_w) AM_SHARE("bg_ram") // background (VIEW RAM) AM_RANGE(0x4000, 0x43ff) AM_DEVREADWRITE("namco", namco_cus30_device, namcos1_cus30_r, namcos1_cus30_w) - AM_RANGE(0x4800, 0x4800) AM_WRITENOP // 3D scope left/right? + AM_RANGE(0x4800, 0x4800) AM_WRITE(tceptor2_shutter_w) AM_RANGE(0x4f00, 0x4f00) AM_READNOP // unknown AM_RANGE(0x4f01, 0x4f01) AM_READ_PORT("PEDAL") // analog input (accel) AM_RANGE(0x4f02, 0x4f02) AM_READ_PORT("STICKX") // analog input (left/right) @@ -222,8 +219,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( mcu_io_map, AS_IO, 8, tceptor_state ) - AM_RANGE(M6801_PORT1, M6801_PORT1) AM_READ(readFF) AM_WRITENOP - AM_RANGE(M6801_PORT2, M6801_PORT2) AM_READ(readFF) AM_WRITENOP + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(M6801_PORT1, M6801_PORT1) AM_WRITENOP + AM_RANGE(M6801_PORT2, M6801_PORT2) AM_WRITENOP ADDRESS_MAP_END @@ -290,7 +288,7 @@ static INPUT_PORTS_START( tceptor2 ) PORT_INCLUDE( tceptor ) PORT_MODIFY("DSW2") - PORT_DIPNAME( 0x04, 0x00, "Mode" ) // NOTE: factory default is actually 3D + PORT_DIPNAME( 0x04, 0x04, "Mode" ) PORT_DIPSETTING( 0x00, "2D" ) PORT_DIPSETTING( 0x04, "3D" ) PORT_BIT( 0xf8, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -520,4 +518,4 @@ ROM_END // ( YEAR NAME PARENT MACHINE INPUT STATE INIT MONITOR COMPANY FULLNAME FLAGS ) GAME ( 1986, tceptor, 0, tceptor, tceptor, tceptor_state, 0, ROT0, "Namco", "Thunder Ceptor", 0) -GAME ( 1986, tceptor2, tceptor, tceptor, tceptor2, tceptor_state, 0, ROT0, "Namco", "3-D Thunder Ceptor II", 0) +GAMEL( 1986, tceptor2, tceptor, tceptor, tceptor2, tceptor_state, 0, ROT0, "Namco", "3-D Thunder Ceptor II", 0, layout_tceptor2) diff --git a/src/mame/drivers/terco.cpp b/src/mame/drivers/terco.cpp new file mode 100644 index 00000000000..e027b23aefb --- /dev/null +++ b/src/mame/drivers/terco.cpp @@ -0,0 +1,314 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edstrom +/* + * The 4490 CNC Mill Control unit + * + * History of Terco + *------------------ + * Terco, founded 1963, is a privatelly held company in Sweden that develops and distribute equipment for + * technical vocational educations worldwide. In the mid 80:ies they had a number of state of the art + * products for educations on CNC machines, both mill and lathe, all based on Motorola 8-bit CPU:s. + * + * Known products + * -------------- + * T4426 - CNC Programming Station, a ruggedized Tandy Color Computer + monitor in a metal case (see coco12.cpp) + * T4490 - CNC Control System, a complete system including a small milling machine, can be programmed by T4426 + * T???? - A CAD/CAM sold in small numbers, an office computer based on a Tandy Color Computer PCB + two floppy drives + * + * Misc links about the machines supported by this driver. + *-------------------------------------------------------- + * https://www.westauction.com/auction/712/item/terco-cnc-programming-system-37047 + * https://kiertonet.fi/tyokalut-ja-koneet/koneet-ja-laitteet/cnc-pora-45-terco-4403 + * http://www.repair--parts.com/Repair-Electronics-/Rectifiers-/Terco-table-top-cnc-mill.php5 + * + * TODO: + * ------ + * - Display + * - Clickable Artwork + * - Serial communication for printer, plotter, paper tape and downlaod from the T4426 + * - Identify expansion bus + * - Keyboard Controller + * - Dump keyboard ROM + * - Cassette i/f + */ + +#include "emu.h" +#include "cpu/m6800/m6800.h" +#include "machine/6821pia.h" +//#include "machine/6850acia.h" +//#include "machine/kb3600.h" +//#include "machine/mc14411.h" + +#define LOG_SETUP (1U << 1) +#define LOG_READ (1U << 2) +#define LOG_BCD (1U << 3) + +//#define VERBOSE (LOG_BCD|LOG_SETUP) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" + +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) +#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__) +#define LOGBCD(...) LOGMASKED(LOG_BCD, __VA_ARGS__) + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif +/* + * Identified Chips + * ---------------- + * 11442 - 7-seg driver + * 14411 - Bit Rate Generator + * 1488 - Quad Line EIA-232D Driver + * 1489 - Quad Line EIA-232D Receivers + * 15005 - Reed relay + * 2114 - 4 x 1024 bits of data + * 2732 - 4KB EPROM + * 4527 - BCD Rate Multiplexer + * 555 - analog timer circuit + * 6800 - 8 bit CPU + * 6821 - PIA paralell interface + * 6850 - ACIA serial interface + * 7400 - Quad 2 input NAND gates + * 7402 - Quad 2 input NOR gates + * 7408 - Quad 2 input AND gates + * 7414 - 6 hex schmitt trigger inverters + * 7420 - Dual 4 input NAND gates + * 7421 - Dual 4 input AND gates + * 7476 - Dual JK flip flops with preset and clear + * 7490 - Decade Counters, divide by 2 and divide by 5 outputs + * 74116 - Dual 4-bit latches + * 74138 - 3 to 8 line decoder/demultiplexer + * 74139 - Dual 2 to 4 line decoder/demultiplexer + * 74154 - 4 line to 16 line decoders/multiplexers + * 74164 - 8 bit paralell output serial shift register + * 74174 - 6 D-type flip flops + * 74240 - Inverted 3-state outputs + * 74244 - Non-inverted 3-state outputs + * AY3600 - Keyboard Controller + * CA339 - Quad Voltage Comparators + * CD4050B - CMOS Hex Non-Inverting Buffer and Converter + * CIC2414 - CMOS RAM suspects + * DS1210 - NVRAM controller, inhibits access and supply battery power on power down + * MC6875 - Phase clock generator + * + * Board Layouts + * ------------- + * + * T4490 CPU board + * ______________________________________________________________ + * |\ .. .---. _o|__ + * ||o+----------+ +---+ +---+ .------. +-------+ |470| | | | + * || | 2732 | |CIC| |CIC| |battery |74LS240| | uF| | | | + * ///> | 4490-F | 2414E 2414E | | +-------+ | | | | | + * | +----------+ | | | | | | +-------+ | | | | | + * | | | | | | | |74LS240| | | | | | + * | +----------+ +---+ +---+ | | +-------+ .___. | | | + * | | 2732 | .______. o | | | + * | | 4490-E | +-----+ +-------+ | | | + * | +----------+ |DS1210 |4527BE | +-----------+ | | | + * | +-----+ +-------+ | | | | | + * | +----------+ | 74116N | | | | + * | | 2732 | +-----------+ | | | + * | | 4490-D | +-------+ +-------+ | | | + * | +----------+ |74LS90N| |4527BE | | | | + * | +-------+ +-------+ | | | + * | +----------+ +-----------+ |_| | + * | | 2732 | +-------+ +-------+ | | |___| + * | | 4490-C | | 7476 | |4527BE | | 74116N | o| + * | +----------+ +-------+ +-------+ +-----------+ | + * | | + * | R2 varistor | + * | +---+ R1 +---------+ +-------+ | + * | |555| 3.9K | 74LS244 | |74LS00 | | + * | +---+ +---------+ +-------+ | + * | C1 0.01uF | + * | C2 0.01uF o|__ + * | +----+ _| | + * | -|XTAL| | | | + * | -|8MHz| | | | + * | +----+ +-----------------+ | | | + * | | CPU | +-------+ | | | + * | +-------+ | 68B00 | |74LS139| | | | + * | | 6875L | +-----------------+ +-------+ | | | + * | +-------+ | | | + * | | | | + * | +-------+ +--------+ +--------+ +-------+ | | | + * | | 74LS08| |74LS244 | |74LS244 | |74LS138| | | | + * | +-------+ +--------+ +--------+ +-------+ | | | + * | | | | + * | | | | + * | +-------+ +-------++-------+ +-------+ +-------+ | | | + * | |74LS164| |74LS14 ||74LS02N| |74LS20N| |74LS138| | | | + * \\\> +-------+ +-------++-------+ +-------+ +-------+ |_| | + * || |___| + * ||o o| + * |/---------------------------------------------------------------+ + * + * + * T4490 I/O board + * . ______________________________________________________________ + * |\ o o _o|__ + * ||o 96..+------+.----. +-------+ | | | + * || 72..|BRG ||XTAL| +74LS240| | | | + * ///> +-------+ 48..|14411 ||1.84| +-------+ | | | + * +-+|O|+------+ |CA339A | 36..| || 320| | | | + * +-| ||15005B| +-------+ 24..| |.____. +-------+ | | | + * | | ==|+------+ 18..| | |74LS240| | | | + * | | ==| 12..| | +-------+ | | | + * | | ==| 6..+------+ | | | + * | | ==| +-------+ 3.. .----------. | | | + * | | ==| |1488P | 2..o| 470uF |o +-------+ | | | + * | | ==| +-------+ 1.5 .__________. |74LS244| | | | + * | | ==| 1.1 +----------+ +-------+ | | | + * | | ==| | 2732A | | | | + * +-| |+-------+ +-------+ | 4490-B | | | | + * +-+==||CD4050BE |1489P | +----------+ +-------+ | | | + * \\ |O|+-------+ +-------+ |74LS244| |_| | + * \\---++------+ +------+ +-------+ |___| + * --+ O|PIA | |PIA | +------+ +-----------+ o| + * | ||68B21P| |68B21P| |ACIA | | 2732A | | + * | || | | | |68B50P| | 4490-A | | + * +-+ || | | | | | +-----------+ | + * --| || | | | | | | + * +-+ || | | | | | +-----------+ +-------+ | + * | || | | | +------+ | 2732A | |74LS139| | + * | || | | | | 4490-3 | +-------+ | + * | |+------+ +------+ +-----------+ o|__ + * --+ O +-------+ _| | + * //---+ |74LS00N| | | | + * // ==o== +-------+ | | | + * ==o== | | | + * | +-------+ +-------+ +-------+ +-------+ +-------+ | | | + * | | 2114 | | 2114 | | 2114 | | 2114 | |74LS21N| | | | + * | +-------+ +-------+ +-------+ +-------+ +-------+ | | | + * | | | | + * | +-------+ +-------+ +-------+ +-------+ | | | + * | | 2114 | | 2114 | | 2114 | | 2114 | | | | + * | +-------+ +-------+ +-------+ +-------+ +-------+ | | | + * | |74LS08N| | | | + * | +-------+ +-------+ +-------+ +-------+ +-------+ | | | + * | | 2114 | | 2114 | | 2114 | | 2114 | | | | + * | +-------+ +-------+ +-------+ +-------+ | | | + * | | | | + * \\\> +-------+ +-------+ +-------+ +-------+ +-------+ |_| | + * || | 2114 | | 2114 | | 2114 | | 2114 | |74LS138| |___| + * ||o +-------+ +-------+ +-------+ +-------+ +-------+ o| + * |/---------------------------------------------------------------+ + * + * + * T4490 Front Panel PCB + * .--------------------------------------------------------------------------------------------------------------------. + * | +--------+| + * |+-----+-----+-----+-----+-----+-----+-----+-----+-----+ +-----+ +-----+-----+ | || + * ||11442|11442|11442|11442|11442|11442|11442|11442|11442| |11442| |11442|11442| |74116N || + * |+-----+-----+-----+-----+-----+-----+-----+-----+-----+ +-----+ +-----+-----+ POSITION REGISTER +--------+| + * | +---+---+---+ +---+---+ +---+---+---+ +---+ +---+ +---+---+ +------+ +---+---+---+---+---+---+| + * N |7sg|7sg|7sg| G |7sg|7sg| F |7sg|7sg|7sg| S |7sg| T |7sg| M |7sg|7sg| |sparse| |7sg|7sg|7sg|7sg|7sg|7sg|| + * | |BCD|BCD|BCD| |BCD|BCD| |BCD|BCD|BCD| |BCD| |BCD| |BCD|BCD| |DotLed| |BCD|BCD|BCD|BCD|BCD|BCD|| + * | +---+---+---+ +---+---+ +---+---+---+ +---+ +---+ +---+---+ |matrix| +---+---+---+---+---+---+| + * | BLOCK NBR G-FUNCT FEED-SPEED+-------+SPIN- TOOL +-------+ F- +------++---+---+---+---+---+---+ | + * |PWR RUN MAN EXA LOAD DUMP BBB FULL PAR | 74116 | DLE NBR | 74116 | FUNCT |114|114|114|114|114|114| | + * | O O O O O O O O O +-------+ +-------+ | 42| 42| 42| 42| 42| 42| | + * | +------+ +--------+ +--------+ SYSTEM STATUS | | | | | | | | + * | |74LS00| |74LS240N| |74LS240N| +---+---+---+---+---+---+ | + * | +------+ +--------+ +--------+ | + * ---------------------------------------------------------------------------------------------------------------------- + * O O O O + * ---------------------------------------------------------------------------------------------------------------------- + * |.----.----.----.----.----.----.----.----. .----.----.----.----.----.----.----.----. +-------+ | + * ||STOP|STRT|PROG|EXAM|LOAD|DUMP|BLK |TO | |RST |SET |READ|CHNG|INS |ERA |END |END | |74154J | | + * || | | | |TAPE|TAPE|BBLK| REF| | | REF| | | BLK| BLK| BLK| PRG| DATA +-------+ | + * |'----'----'----'----'----'----'----'----' '----'----'----'----'----'----'----'----' .----.----.----. | + * | +--------+ SYSTEM CONTROL PROGRAMMING CONTROL | | | | | + * | |74LS244N| | 7 | 8 | 9 | | + * | +--------+ +----+----+----+ | + * | | | | | | + * | JOG CONTROL FUNCTION COORDINATE | 4 | 5 | 6 | | + * |.----.----.----. +--------+ .----.----.----. .----.----.----. +----+----+----+ | + * || | | | |74LS174N| | | | | | | | | | | | | | + * || X+ | Y+ | Z+ | +--------+.--. |CTRL| G | F | | X | Y | Z | | 1 | 2 | 3 | | + * |+----+----+----+ | | +----+----+----+ +----+----+----+ +----+----+----+ | + * || | | | +--------+'--' | | | | | | | | | | | | | + * || X- | Y- | Z- | |74LS240N| | S | T | M | | I | J | K | | + | 0 | - | | + * |+----+----+----+ +--------+ +----+---++----+ +----+----+----+ '----'----'----' | + * | +---+ | + * | .-------------------. |74 | | + * | | o o | |240| | + * | | +----+o o+----+|+-----+ | | .-----------------------------------------' + * | | |AY-5|o o| |||PIA | +---+ | + * | | |3600|o o|2732|||68B21| | + * | | |PRO-|o o|TBORD|| | FEED OVERRIDE % | + * | | | 50 |o o| ||| | | + * | | | |o o+----+|| | .--. | + * | | | |o o || | | | | + * | | +----+o o |+-----+ '--' | + * | '-------------------' | + * ---------------------------------------------------------------------------'------------------------------------------ + * O O O O + * ---------------------------------------------------------------------------------------------------------------------- + */ +/* Terco CNC Control Station 4490 */ +class t4490_state : public driver_device +{ +public: + t4490_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + ,m_maincpu(*this, "maincpu") + ,m_pia1(*this, "pia1") + ,m_pia2(*this, "pia2") + //,m_pia3(*this, "pia3") + //,m_acia(*this, "acia") + //,m_brg(*this, "brg") + //,m_ay3600(*this, "ay3600") + { } +private: + required_device m_maincpu; + // virtual void machine_reset() override { m_maincpu->reset(); LOG("--->%s()\n", FUNCNAME); }; + required_device m_pia1; + required_device m_pia2; + //required_device m_pia3; + //required_device m_acia; + //required_device m_brg; + //required_device m_ay3600; +}; + +static ADDRESS_MAP_START( t4490_map, AS_PROGRAM, 8, t4490_state ) + AM_RANGE(0x0000, 0x1fff) AM_RAM + AM_RANGE(0x3000, 0x3fff) AM_ROM AM_REGION("maincpu", 0x3000) + AM_RANGE(0x9500, 0x95ff) AM_RAM + AM_RANGE(0x9036, 0x9037) AM_DEVREADWRITE("pia1", pia6821_device, read, write) + AM_RANGE(0x903a, 0x903b) AM_DEVREADWRITE("pia2", pia6821_device, read, write) +// AM_RANGE(0xc820, 0xc823) AM_DEVREADWRITE("acia", acia6850_device, read, write) + AM_RANGE(0xa000, 0xffff) AM_ROM AM_REGION("maincpu", 0xa000) +ADDRESS_MAP_END + +/* Input ports */ +static INPUT_PORTS_START( t4490 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( t4490 ) + MCFG_CPU_ADD("maincpu", M6800, XTAL_8MHz/4) // divided by a MC6875 + MCFG_CPU_PROGRAM_MAP(t4490_map) + + /* devices */ + MCFG_DEVICE_ADD("pia1", PIA6821, 0) + MCFG_DEVICE_ADD("pia2", PIA6821, 0) +MACHINE_CONFIG_END + +ROM_START( t4490 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "terco4490-3861104.bin", 0x3000, 0x1000, CRC(d5fd17cc) SHA1(9a3564fa69b897ec51b49ad34f2d2696cb78ee9b) ) + ROM_LOAD( "terco4490-A861104.bin", 0xa000, 0x1000, CRC(65b8e7d0) SHA1(633217fc4aa301d87790bb8744b72ef030a4c262) ) + ROM_LOAD( "terco4490-B861104.bin", 0xb000, 0x1000, CRC(5a0ce3f2) SHA1(7ec455b9075454ce5943011a1dfb5725857168f5) ) + ROM_LOAD( "terco4490-C861104.bin", 0xc000, 0x1000, CRC(0627c68c) SHA1(bf733d3ffad3f1e75684e833afc9d10d33ca870f) ) + ROM_LOAD( "terco4490-D861104.bin", 0xd000, 0x1000, CRC(2156476d) SHA1(0d70c6285541746ef15cad0d47b2d752e228abfc) ) + ROM_LOAD( "terco4490-E861104.bin", 0xe000, 0x1000, CRC(b317fa37) SHA1(a2e037a3a88b5d780067a86e52c6f7c103711a98) ) + ROM_LOAD( "terco4490-F861104.bin", 0xf000, 0x1000, CRC(a45bc3e7) SHA1(e12efa9a4c72e4bce1d59ad359ee66d7c3babfa6) ) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1986, t4490, 0, 0, t4490, t4490, t4490_state, 0, "Terco AB", "Terco 4490 Mill CNC Control", MACHINE_IS_SKELETON ) diff --git a/src/mame/includes/tceptor.h b/src/mame/includes/tceptor.h index 8518a4f09a1..9ea6ccb945e 100644 --- a/src/mame/includes/tceptor.h +++ b/src/mame/includes/tceptor.h @@ -57,11 +57,11 @@ public: DECLARE_READ8_MEMBER(dsw1_r); DECLARE_READ8_MEMBER(input0_r); DECLARE_READ8_MEMBER(input1_r); - DECLARE_READ8_MEMBER(readFF); DECLARE_WRITE8_MEMBER(tceptor_tile_ram_w); DECLARE_WRITE8_MEMBER(tceptor_tile_attr_w); DECLARE_WRITE8_MEMBER(tceptor_bg_ram_w); DECLARE_WRITE8_MEMBER(tceptor_bg_scroll_w); + DECLARE_WRITE8_MEMBER(tceptor2_shutter_w); void tile_mark_dirty(int offset); required_device m_c45_road; diff --git a/src/mame/layout/prodigy.lay b/src/mame/layout/prodigy.lay index fee2ebe74ce..1c8c63cf598 100644 --- a/src/mame/layout/prodigy.lay +++ b/src/mame/layout/prodigy.lay @@ -1,25 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/sms1.lay b/src/mame/layout/sms1.lay index 3275da610d6..c6988743e6f 100644 --- a/src/mame/layout/sms1.lay +++ b/src/mame/layout/sms1.lay @@ -1,9 +1,14 @@ + + + + + diff --git a/src/mame/layout/tceptor2.lay b/src/mame/layout/tceptor2.lay new file mode 100644 index 00000000000..c1dbad97422 --- /dev/null +++ b/src/mame/layout/tceptor2.lay @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 804851f6342..e9100ad0f4c 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -2483,6 +2483,7 @@ laststar // (proto) (c) 1984 antiairc // (c) 1975 Atari crashnsc // (c) 1975 Atari gtrak10 // (c) 1974 Atari / Kee +gtrak10a // (c) 1974 Atari / Kee gtrak20 // (c) 1974 Atari / Kee indy4 // (c) 1976 Atari / Kee indy800 // (c) 1975 Atari / Kee @@ -9785,7 +9786,7 @@ cocoe // Color Computer (Extended BASIC 1.0) cp400 // Prologica CP400 lzcolor64 // Digiponto LZ Color64 mx1600 // Dynacom MX-1600 -t4426 // Terco T4426 CNC programming station +t4426 // Terco 4426 CNC programming station @source:coco3.cpp coco3 // Color Computer 3 (NTSC) @@ -36220,6 +36221,9 @@ temptube // (hack) @source:terak.cpp terak // +@source:terco.cpp +t4490 // Terco 4490 Mill CNC Control (c) 1986 + @source:terracre.cpp amatelas // (c) 1986 amazon // (c) 1986 diff --git a/src/mame/video/tceptor.cpp b/src/mame/video/tceptor.cpp index 77713a138f8..3e344fbd576 100644 --- a/src/mame/video/tceptor.cpp +++ b/src/mame/video/tceptor.cpp @@ -529,7 +529,6 @@ uint32_t tceptor_state::screen_update_tceptor(screen_device &screen, bitmap_ind1 return 0; } - WRITE_LINE_MEMBER(tceptor_state::screen_vblank_tceptor) { // rising edge @@ -538,3 +537,9 @@ WRITE_LINE_MEMBER(tceptor_state::screen_vblank_tceptor) memcpy(m_sprite_ram_buffered.get(), m_sprite_ram, 0x200); } } + +WRITE8_MEMBER(tceptor_state::tceptor2_shutter_w) +{ + // 3D scope shutter control + output().set_value("shutter", data & 1); +}