From 47079db1b013aacfb92073483a4a9c4bd611e21f Mon Sep 17 00:00:00 2001 From: wilbertpol Date: Wed, 30 Dec 2020 06:27:25 +0100 Subject: WonderSwan updates: (#7428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bus/wswan: Add preliminary support for wonderwitch. [Wilbert Pol] cpu/v30mz: [Wilbert Pol] - Rename segment registers. - Add a callback to retrieve the interrupt vector. - Add prefetch queue and PFP register. - Add 1 cycle penalty when reading or writing a word from an unaligned address. - Add 1 cycle penalty when calculating effective address from multiple registers. - Removed not supported nec extended instructions. - Change address space width to word. wswan: [Wilbert Pol] - Adjust cpu cycles when performing DMA. - Updated default internal eeprom for WonderSwan Color with name ‘WONDERSWANCOLOR’. - Fix off-by-one error in window drawing. - Major update to the software lists documenting hardware and rom labels and locations. wscolor - New working software list additions ---------------------------------------------- Digimon Adventure 02 - D1 Tamers (Rev 1) Digital Monster Card Game - Ver. WonderSwan Color (Rev 2) Digital Monster - D-Project (Rev 1) Digimon Tamers - Digimon Medley Hunter X Hunter - Greed Island (Rev 1) From TV Animation One Piece - Treasure Wars (Rev 1) wscolor - New not working software list additions ------------------------------------------------- mama Mitte' wscolor - Replaced software list items -------------------------------------- Dicing Knight. [anon] Judgement Silversword - Rebirth Edition (Rev. SC21) wswan - New working software list additions --------------------------------------------- Chocobo no Fushigi na Dungeon for WonderSwan (Rev 3) Chocobo no Fushigi na Dungeon for WonderSwan (Rev 1) Digimon Adventure 02 - Tag Tamers (Rev 0) Digimon Adventure - Anode Tamer (Rev 1) Digimon Adventure Campaign Limited Version Keitai Gyogun Tanchiki - WonderSwan Handy Sonar (Rev 2) Harobots (Rev 1) Hunter X Hunter - Ishi o Tsugu Mono (Rev 1) Mahjong Touryuumon (Rev 1) Super Robot Taisen Compact (Rev 1) SD Gundam - Emotional Jam (Rev 2) SD Gundam Gashapon Senki - Episode 1 (alt) wscolor - Software list items promoted to working -------------------------------------------------- Super Robot Taisen Compact for WonderSwan Color Cardcaptor Sakura - Sakura to Fushigi na Clow Card wswan - Replaced software list items ------------------------------------- Armored Unit Crazy Climber Clock Tower for WonderSwan Glocal Hexcite Gomoku Narabe & Reversi - Touryuumon Hanafuda Shiyouyo Keiba Yosou Shien Soft - Yosou Shinkaron Morita Shougi for WonderSwan Nobunaga no Yabou for WonderSwan Sangokushi II for WonderSwan Shougi Touryuumon Slither Link Soccer Yarou! - Challenge the World Taikyoku Igo - Heisei Kiin Trump Collection 2 - Bottom-Up Teki Sekaiisshuu no Tabi Trump Collection - Bottom-Up Teki Trump Seikatsu wswan - Software list items promoted to working ------------------------------------------------- Clock Tower for WonderSwan Meitantei Conan - Nishi no Meitantei Saidai no Kiki! Super Robot Taisen Compact 2 - Dai-1-bu - Chijou Gekidou Hen Super Robot Taisen Compact 2 - Dai-2-bu - Uchuu Gekishin Hen (Rev 4) Super Robot Taisen Compact 2 - Dai-3-bu - Ginga Kessen Hen (Rev 2) Super Robot Taisen Compact (Rev 0) wswan - Software list items demoted to not working ---------------------------------------------------- Magical Drop for WonderSwan MobileWonderGate (Rev 1) Wonder Borg Robot Works Robot Works (Asia) --- hash/wscolor.xml | 1354 +++++++++++++----- hash/wswan.xml | 1861 +++++++++++++++++++------ src/devices/bus/wswan/rom.cpp | 579 +++++--- src/devices/bus/wswan/rom.h | 96 +- src/devices/bus/wswan/slot.cpp | 125 +- src/devices/bus/wswan/slot.h | 59 +- src/devices/cpu/v30mz/v30mz.cpp | 2860 ++++++++++++++++++--------------------- src/devices/cpu/v30mz/v30mz.h | 198 +-- src/mame/audio/wswan.cpp | 374 +++-- src/mame/audio/wswan.h | 70 +- src/mame/drivers/wswan.cpp | 816 ++++++----- src/mame/video/wswan.cpp | 787 +++++------ src/mame/video/wswan.h | 118 +- 13 files changed, 5608 insertions(+), 3689 deletions(-) diff --git a/hash/wscolor.xml b/hash/wscolor.xml index 0502cfb1e98..46f7ae7e20f 100644 --- a/hash/wscolor.xml +++ b/hash/wscolor.xml @@ -2,8 +2,10 @@ +See the wswan software list for the full game list. + +--> @@ -14,12 +16,15 @@ license:CC0 + + + + - - - + + - + @@ -33,11 +38,16 @@ license:CC0 + + + + + - - + + - + @@ -51,33 +61,68 @@ license:CC0 + + + + + - - + + - + - Battle Spirit - Digimon Frontier + Battle Spirit - Digimon Frontier (Rev 1) 2002 Bandai + + + + + - - + + + - + + + Blue Wing Blitz @@ -87,11 +132,16 @@ license:CC0 + + + + + - - + + - + @@ -105,11 +155,16 @@ license:CC0 + + + + + - - + + - + @@ -123,11 +178,16 @@ license:CC0 + + + + + - - + + - + @@ -140,30 +200,63 @@ license:CC0 + + + + + - - + + - + - Digimon Adventure 02 - D1 Tamers + Digimon Adventure 02 - D1 Tamers (Rev 1) + 2000 + Bandai + + + + + + + + + + + + + + + + + + + + + Digimon Adventure 02 - D1 Tamers (Rev 0) 2000 Bandai + + + + + - - + + - + @@ -175,37 +268,91 @@ license:CC0 Bandai + + + + + - - + + - + - Digital Monster Card Game - Ver. WonderSwan Color + Digital Monster Card Game - Ver. WonderSwan Color (Rev 2) + 2002 + Bandai + + + + + + + + + + + + + + + + + + + + Digital Monster Card Game - Ver. WonderSwan Color (Rev 0) 2002 Bandai + + + + - - - + + + + + + + + + - Digital Monster - D-Project + Digital Monster - D-Project (Rev 1) 2002 Bandai @@ -213,10 +360,33 @@ license:CC0 - - + + - + + + + + + + + Digital Monster - D-Project (Rev 0) + 2002 + Bandai + + + + + + + + + + + + + + @@ -230,11 +400,16 @@ license:CC0 + + + + + - - + + - + @@ -248,18 +423,24 @@ license:CC0 + + + + + - - + + - + + Digimon Tamers - Brave Tamer 2001 Bandai @@ -267,11 +448,15 @@ license:CC0 + + + + - - + + - + @@ -285,17 +470,44 @@ license:CC0 + + + + + + + + + + + + + + + + Digimon Tamers - Digimon Medley (alt) + 2001 + Bandai + + + + + + + + - - + + - + + Dokodemo Hamster 3 - Odekake Saffron 2000 BEC @@ -303,12 +515,18 @@ license:CC0 + + + + + + - - + + - + @@ -322,11 +540,15 @@ license:CC0 + + + + - - + + - + @@ -340,9 +562,14 @@ license:CC0 + + + + + - - + + @@ -356,11 +583,16 @@ license:CC0 + + + + + - - + + - + @@ -374,11 +606,16 @@ license:CC0 + + + + + - - + + - + @@ -392,11 +629,16 @@ license:CC0 + + + + + - - + + - + @@ -410,11 +652,15 @@ license:CC0 + + + + - - + + - + @@ -428,11 +674,15 @@ license:CC0 + + + + - - + + - + @@ -446,11 +696,16 @@ license:CC0 + + + + + - - + + - + @@ -463,17 +718,22 @@ license:CC0 + + + + - - + + - + + Gensou Maden Saiyuuki Retribution - Hi no Ataru Basho de 2001 Movic ~ Soeishinsha @@ -481,11 +741,15 @@ license:CC0 + + + + - - + + - + @@ -499,11 +763,16 @@ license:CC0 + + + + + - - + + - + @@ -517,11 +786,16 @@ license:CC0 + + + + + - - + + - + @@ -535,11 +809,16 @@ license:CC0 + + + + + - - + + - + @@ -553,11 +832,16 @@ license:CC0 + + + + + - - + + - + @@ -571,11 +855,16 @@ license:CC0 + + + + + - - + + - + @@ -589,11 +878,16 @@ license:CC0 + + + + + - - + + - + @@ -607,11 +901,16 @@ license:CC0 + + + + + - - + + - + @@ -625,11 +924,16 @@ license:CC0 + + + + + - - + + - + @@ -643,18 +947,26 @@ license:CC0 + + + + - - - + + - + - + + + + Hanjuku Hero - Ah, Sekai yo Hanjuku Nare...!! 2002 Square @@ -662,11 +974,16 @@ license:CC0 + + + + + - - + + - + @@ -680,29 +997,62 @@ license:CC0 + + + + + - - + + - + - Hunter X Hunter - Greed Island + Hunter X Hunter - Greed Island (Rev 1) + 2003 + Bandai + + + + + + + + + + + + + + + + + + + + + Hunter X Hunter - Greed Island (Rev 0) 2003 Bandai + + + + + - - + + - + @@ -716,11 +1066,15 @@ license:CC0 + + + + - - + + - + @@ -734,11 +1088,15 @@ license:CC0 + + + + - - + + - + @@ -752,11 +1110,16 @@ license:CC0 + + + + + - - + + - + @@ -770,12 +1133,18 @@ license:CC0 + + + + + + - - + + - + @@ -789,11 +1158,15 @@ license:CC0 + + + + - - + + - + @@ -807,11 +1180,10 @@ license:CC0 - - + - + @@ -819,17 +1191,19 @@ license:CC0 Judgement Silversword - Rebirth Edition (Rev. SC21) - 2004 + 2005 Qute + + + - - - + + - + @@ -843,11 +1217,15 @@ license:CC0 + + + + - - + + - + @@ -861,17 +1239,22 @@ license:CC0 + + + + - - + + - + + Kurupara! 2001 Tom Create @@ -879,12 +1262,15 @@ license:CC0 + + + + - - - + + - + @@ -898,12 +1284,41 @@ license:CC0 + + + + - - - + + - + + + + + + + + + mama Mitte' + 2002 + Tanita + + + + + + + + + + + + + + + + @@ -917,11 +1332,16 @@ license:CC0 + + + + + - - + + - + @@ -935,11 +1355,16 @@ license:CC0 + + + + + - - + + - + @@ -953,11 +1378,16 @@ license:CC0 + + + + + - - + + - + @@ -971,12 +1401,15 @@ license:CC0 + + + + - - - + + - + @@ -990,11 +1423,16 @@ license:CC0 + + + + + - - + + - + @@ -1008,11 +1446,16 @@ license:CC0 + + + + + - - + + - + @@ -1026,14 +1469,43 @@ license:CC0 + + + + + + + + + + + + + + + @@ -1044,11 +1516,16 @@ license:CC0 + + + + + - - + + - + @@ -1062,29 +1539,62 @@ license:CC0 + + + + + - - + + - + - From TV Animation One Piece - Treasure Wars + From TV Animation One Piece - Treasure Wars (Rev 1) + 2002 + Bandai + + + + + + + + + + + + + + + + + + + + + From TV Animation One Piece - Treasure Wars (Rev 0) 2002 Bandai + + + + + - - + + - + @@ -1098,12 +1608,17 @@ license:CC0 + + + + + - - + + - + @@ -1117,11 +1632,15 @@ license:CC0 + + + + - - + + - + @@ -1135,11 +1654,16 @@ license:CC0 + + + + + - - + + - + @@ -1153,52 +1677,67 @@ license:CC0 + + + + + - - + + - + - Super Robot Taisen Compact 3 (v1.5) + Super Robot Taisen Compact 3 (Rev 5) 2003 Banpresto + + + + + - - + + - + - Super Robot Taisen Compact 3 (v1.6) + Super Robot Taisen Compact 3 (Rev 6) 2003 Banpresto + + + + + - - + + - + - + Super Robot Taisen Compact for WonderSwan Color 2001 @@ -1207,11 +1746,16 @@ license:CC0 + + + + + - - + + - + @@ -1225,17 +1769,23 @@ license:CC0 + + + + + - - + + - + + Rockman EXE - N1 Battle 2003 Capcom @@ -1243,11 +1793,16 @@ license:CC0 + + + + + - - + + - + @@ -1261,11 +1816,16 @@ license:CC0 + + + + + - - + + - + @@ -1279,11 +1839,16 @@ license:CC0 + + + + + - - + + - + @@ -1297,11 +1862,16 @@ license:CC0 + + + + + - - + + - + @@ -1315,11 +1885,16 @@ license:CC0 + + + + + - - + + - + @@ -1333,29 +1908,63 @@ license:CC0 + + + + + - - + + - + + + - SD Gundam G-Generation - Mono-Eye Gundams + SD Gundam G-Generation - Mono-Eye Gundams (Rev 0) 2002 Bandai + + + + + - - + + - + @@ -1369,11 +1978,16 @@ license:CC0 + + + + + - - + + - + @@ -1387,53 +2001,70 @@ license:CC0 + + + + + - - + + - + - Shaman King - Asu e no Ishi (v1.1) + Shaman King - Asu e no Ishi (Rev 1) 2002 Bandai + + + + + - - + + - + - Shaman King - Asu e no Ishi + Shaman King - Asu e no Ishi (Rev 0) 2002 Bandai + + + + + - - + + - + + + Sorobang 2000 Kaga Tech @@ -1441,12 +2072,16 @@ license:CC0 + + + + + - - - + + - + @@ -1460,9 +2095,14 @@ license:CC0 + + + + + - - + + @@ -1476,11 +2116,16 @@ license:CC0 + + + + + - - + + - + @@ -1491,11 +2136,16 @@ license:CC0 2001 Bandai + + + + + - - + + - + @@ -1509,11 +2159,16 @@ license:CC0 + + + + + - - + + - + @@ -1527,12 +2182,15 @@ license:CC0 + + + + - - - + + - + @@ -1546,17 +2204,21 @@ license:CC0 + + + + - - - + + - + - + + Tonpuusou 2001 @@ -1565,11 +2227,15 @@ license:CC0 + + + + - - + + - + @@ -1583,11 +2249,16 @@ license:CC0 + + + + + - - + + - + @@ -1601,11 +2272,16 @@ license:CC0 + + + + + - - + + - + @@ -1619,12 +2295,16 @@ license:CC0 + + + + + - - - + + - + @@ -1638,11 +2318,16 @@ license:CC0 + + + + + - - + + - + @@ -1656,11 +2341,15 @@ license:CC0 + + + + - - + + - + @@ -1674,11 +2363,16 @@ license:CC0 + + + + + - - + + - + @@ -1691,8 +2385,22 @@ license:CC0 - - + + + + + + + + + + + + + + + + @@ -1705,8 +2413,17 @@ license:CC0 - - + + + + + + + + + + + @@ -1720,11 +2437,15 @@ license:CC0 + + + + - - + + - + @@ -1738,11 +2459,16 @@ license:CC0 + + + + + - - + + - + diff --git a/hash/wswan.xml b/hash/wswan.xml index 512cac21c1d..dda6bcf55bb 100644 --- a/hash/wswan.xml +++ b/hash/wswan.xml @@ -2,6 +2,285 @@ @@ -13,11 +292,16 @@ license:CC0 + + + + + - - + + - + @@ -30,11 +314,16 @@ license:CC0 + + + + + - - + + - + @@ -47,11 +336,16 @@ license:CC0 + + + + + - - + + - + @@ -64,12 +358,16 @@ license:CC0 + + + + + - - - + + - + @@ -82,11 +380,15 @@ license:CC0 + + + + - - + + - + @@ -99,15 +401,18 @@ license:CC0 + + + + - - - + + - + Cardcaptor Sakura - Sakura to Fushigi na Clow Card 1999 Bandai @@ -115,11 +420,16 @@ license:CC0 + + + + + - - + + - + @@ -132,33 +442,88 @@ license:CC0 + + + + + - - + + - + - Chocobo no Fushigi na Dungeon for WonderSwan + Chocobo no Fushigi na Dungeon for WonderSwan (Rev 3) + 1999 + Bandai + + + + + + + + + + + + + + + + + + + + Chocobo no Fushigi na Dungeon for WonderSwan (Rev 2) 1999 Bandai + + + + + - - + + - + + + + + + + Chocobo no Fushigi na Dungeon for WonderSwan (Rev 1) + 1999 + Bandai + + + + + + + + + + + + + + + Chou Aniki - Otoko no Tamafuda 2000 Bandai @@ -166,16 +531,22 @@ license:CC0 + + + + + - - + + - + - + + Chou Denki Card Game - Youfu Makai - Kikuchi Shuukou 1999 Kobunsha @@ -183,16 +554,22 @@ license:CC0 + + + + + - - + + - + - + + Clock Tower for WonderSwan 1999 Kaga Tech @@ -200,11 +577,16 @@ license:CC0 + + + + + - - + + - + @@ -217,14 +599,19 @@ license:CC0 + + + + - - + + + Densha de Go! 1999 Taito @@ -232,43 +619,101 @@ license:CC0 + + + + - - + + - Digimon Adventure 02 - Tag Tamers + Digimon Adventure 02 - Tag Tamers (Rev 1) 2000 Bandai + + + + + - - + + - + + + + + + + Digimon Adventure 02 - Tag Tamers (Rev 0) + 2000 + Bandai + + + + + + + + + + + + + + - Digimon Adventure - Anode Tamer + Digimon Adventure - Anode Tamer (Rev 1) + 1999 + Bandai + + + + + + + + + + + + + + + + + + + + Digimon Adventure - Anode Tamer (Rev 0) 1999 Bandai + + + + + - - + + - + @@ -281,16 +726,45 @@ license:CC0 + + + + + + + + + + + + + + + + + Digital Monster - Ver. WonderSwan 1999 Bandai @@ -298,11 +772,16 @@ license:CC0 + + + + + - - + + - + @@ -314,11 +793,16 @@ license:CC0 Bandai + + + + + - - + + - + @@ -331,11 +815,16 @@ license:CC0 + + + + + - - + + - + @@ -348,11 +837,16 @@ license:CC0 + + + + + - - + + - + @@ -365,12 +859,15 @@ license:CC0 + + + + - - - + + - + @@ -383,11 +880,15 @@ license:CC0 + + + + - - + + - + @@ -400,11 +901,16 @@ license:CC0 + + + + + - - + + - + @@ -417,11 +923,15 @@ license:CC0 + + + + - - + + - + @@ -434,12 +944,16 @@ license:CC0 + + + + + - - - + + - + @@ -452,16 +966,21 @@ license:CC0 + + + + - - + + - + + Fire Pro Wrestling for WonderSwan 2000 Kaga Tech @@ -469,11 +988,16 @@ license:CC0 + + + + + - - + + - + @@ -486,9 +1010,13 @@ license:CC0 + + + + - - + + @@ -501,9 +1029,13 @@ license:CC0 + + + + - - + + @@ -516,16 +1048,22 @@ license:CC0 + + + + + - - + + - + + Goraku Ou Tango! 1999 Moebius @@ -533,11 +1071,15 @@ license:CC0 + + + + - - + + - + @@ -550,12 +1092,16 @@ license:CC0 + + + + + - - - + + - + @@ -568,12 +1114,14 @@ license:CC0 + + + - - - + + - + @@ -586,60 +1134,141 @@ license:CC0 + + + + + - - + + - + - Keitai Gyogun Tanchiki - WonderSwan Handy Sonar + Keitai Gyogun Tanchiki - WonderSwan Handy Sonar (Rev 2) 1999 Bandai + + + + - - + + + + Keitai Gyogun Tanchiki - WonderSwan Handy Sonar (Rev 1) + 1999 + Bandai + + + + + + + + + + + + + + + + - Harobots + Harobots (Rev 1) 1999 Sunrise Interactive + + + + + - - + + - + + + + + + + Harobots (Rev 0) + 1999 + Sunrise Interactive + + + + + + + + + + + + + + - Hunter X Hunter - Ishi o Tsugu Mono + Hunter X Hunter - Ishi o Tsugu Mono (Rev 2) + 2000 + Bandai + + + + + + + + + + + + + + + + + + + Hunter X Hunter - Ishi o Tsugu Mono (Rev 1) 2000 Bandai + + + + - - + + - + @@ -652,11 +1281,15 @@ license:CC0 + + + + - - + + - + @@ -669,11 +1302,16 @@ license:CC0 + + + + + - - + + - + @@ -686,17 +1324,22 @@ license:CC0 + + + + + - - - + + - + + Kiss Yori... - Seaside Serenade 1999 Kid @@ -704,11 +1347,16 @@ license:CC0 + + + + + - - + + - + @@ -721,11 +1369,16 @@ license:CC0 + + + + + - - + + - + @@ -738,16 +1391,22 @@ license:CC0 + + + + + - - + + - + + Kyousouba Ikusei Simulation - Keiba 1999 BEC @@ -755,16 +1414,22 @@ license:CC0 + + + + + - - + + - + + Langrisser Millennium WS - The Last Century 2000 Bandai @@ -772,11 +1437,16 @@ license:CC0 + + + + + - - + + - + @@ -789,11 +1459,16 @@ license:CC0 + + + + + - - + + - + @@ -806,11 +1481,15 @@ license:CC0 + + + + - - + + - + @@ -823,16 +1502,22 @@ license:CC0 + + + + + - - + + - + - + + Magical Drop for WonderSwan 1999 Data East Corp. @@ -840,27 +1525,57 @@ license:CC0 + + + + - - - + + - Mahjong Touryuumon + Mahjong Touryuumon (Rev 3) + 1999 + Sammy + + + + + + + + + + + + + + + + + + + + Mahjong Touryuumon (Rev 1) 1999 Sammy + + + + + - - + + - + @@ -873,11 +1588,16 @@ license:CC0 + + + + + - - + + - + @@ -890,16 +1610,21 @@ license:CC0 + + + + + - - + + - + - + Meitantei Conan - Nishi no Meitantei Saidai no Kiki! 2000 Bandai @@ -907,11 +1632,16 @@ license:CC0 + + + + + - - + + - + @@ -924,11 +1654,16 @@ license:CC0 + + + + + - - + + - + @@ -941,16 +1676,22 @@ license:CC0 + + + + + - - + + - + + Mingle Magnet 1999 Hal Corporation @@ -958,15 +1699,19 @@ license:CC0 + + + + - - - + + + Pro Mahjong Kiwame for WonderSwan 1999 Athena @@ -974,16 +1719,22 @@ license:CC0 + + + + + - - + + - + + Nihon Pro Mahjong Renmei Kounin Tetsuman 1999 Kaga Tech @@ -991,25 +1742,38 @@ license:CC0 + + + + + - - + + - + - - MobileWonderGate + + + + MobileWonderGate (Rev 1) 19?? <unknown> + + + + + + - - + + - + @@ -1022,11 +1786,16 @@ license:CC0 + + + + + - - + + - + @@ -1039,11 +1808,16 @@ license:CC0 + + + + + - - + + - + @@ -1056,11 +1830,16 @@ license:CC0 + + + + + - - + + - + @@ -1073,16 +1852,21 @@ license:CC0 + + + + - - + + - + + Nice On 1999 Sammy @@ -1090,11 +1874,15 @@ license:CC0 + + + + - - + + - + @@ -1107,11 +1895,16 @@ license:CC0 + + + + + - - + + - + @@ -1124,11 +1917,15 @@ license:CC0 + + + + - - + + - + @@ -1141,11 +1938,15 @@ license:CC0 + + + + - - + + - + @@ -1158,12 +1959,15 @@ license:CC0 + + + + - - - + + - + @@ -1176,11 +1980,16 @@ license:CC0 + + + + + - - + + - + @@ -1193,9 +2002,13 @@ license:CC0 + + + + - - + + @@ -1208,12 +2021,16 @@ license:CC0 + + + + + - - - + + - + @@ -1226,17 +2043,44 @@ license:CC0 + + + + - - - + + - + - + + Ring Infinity (alt) + 2000 + Kid + + + + + + + + + + + + + + + + + + + + + Super Robot Taisen Compact 2 - Dai-1-bu - Chijou Gekidou Hen 2000 Banpresto @@ -1244,62 +2088,126 @@ license:CC0 + + + + + - - + + - + - - Super Robot Taisen Compact 2 - Dai-2-bu - Uchuu Gekishin Hen + + Super Robot Taisen Compact 2 - Dai-2-bu - Uchuu Gekishin Hen (Rev 4) 2000 Banpresto + + + + + - - + + - + - - Super Robot Taisen Compact 2 - Dai-3-bu - Ginga Kessen Hen + + Super Robot Taisen Compact 2 - Dai-3-bu - Ginga Kessen Hen (Rev 2) 2001 Banpresto + + + + + + + + + + + + + + + + Super Robot Taisen Compact (Rev 2) + 1999 + Banpresto + + + + + + + + + + + + + + + + + + + + Super Robot Taisen Compact (Rev 1) + 1999 + Banpresto + + + + + + + + + - - + + - + - - Super Robot Taisen Compact + + Super Robot Taisen Compact (Rev 0) 1999 Banpresto + + + + + - - + + - + @@ -1309,7 +2217,7 @@ license:CC0 external robot (the Wonder Borg). The Wonder Borg itself uses an Elan EM78P451AQ MCU (undumped). --> - + Wonder Borg Robot Works 2000 Bandai @@ -1317,12 +2225,17 @@ license:CC0 + + + + + - - + + - + @@ -1332,7 +2245,8 @@ license:CC0 external robot (the Wonder Borg). The Wonder Borg itself uses an Elan EM78P451AQ MCU (undumped). --> - + + Robot Works (Asia) 2000 Bandai @@ -1340,12 +2254,17 @@ license:CC0 + + + + + - - + + - + @@ -1358,11 +2277,16 @@ license:CC0 + + + + + - - + + - + @@ -1375,11 +2299,16 @@ license:CC0 + + + + + - - + + - + @@ -1392,28 +2321,55 @@ license:CC0 + + + + + - - + + - + - SD Gundam - Emotional Jam + SD Gundam - Emotional Jam (Rev 3) 1999 Bandai + + + + + - - + + - + + + + + + + SD Gundam - Emotional Jam (Rev 2) + 1999 + Bandai + + + + + + + + + @@ -1426,11 +2382,38 @@ license:CC0 + + + + + - - + + - + + + + + + + SD Gundam Gashapon Senki - Episode 1 (alt) + 1999 + Bandai + + + + + + + + + + + + + + @@ -1443,11 +2426,16 @@ license:CC0 + + + + + - - + + - + @@ -1460,11 +2448,16 @@ license:CC0 + + + + + - - + + - + @@ -1477,12 +2470,15 @@ license:CC0 + + + + - - - + + - + @@ -1495,16 +2491,22 @@ license:CC0 + + + + + - - + + - + + Shin Nihon Pro Wrestling Toukon Retsuden 1999 Tomy @@ -1512,11 +2514,15 @@ license:CC0 + + + + - - + + - + @@ -1529,11 +2535,16 @@ license:CC0 + + + + + - - + + - + @@ -1546,9 +2557,13 @@ license:CC0 + + + + - - + + @@ -1561,12 +2576,15 @@ license:CC0 + + + + - - - + + - + @@ -1579,14 +2597,19 @@ license:CC0 + + + + - - + + + Sotsugyou for WonderSwan 1999 Bandai Visual @@ -1594,11 +2617,16 @@ license:CC0 + + + + + - - + + - + @@ -1611,9 +2639,13 @@ license:CC0 + + + + - - + + @@ -1626,11 +2658,16 @@ license:CC0 + + + + + - - + + - + @@ -1643,28 +2680,22 @@ license:CC0 + + + + + - - + + - + - - + Tanjou Debut for WonderSwan 2000 Bandai Visual @@ -1672,11 +2703,16 @@ license:CC0 + + + + + - - + + - + @@ -1689,11 +2725,16 @@ license:CC0 + + + + + - - + + - + @@ -1706,12 +2747,16 @@ license:CC0 + + + + + - - - + + - + @@ -1724,11 +2769,15 @@ license:CC0 + + + + - - + + - + @@ -1741,11 +2790,16 @@ license:CC0 + + + + + - - + + - + @@ -1758,12 +2812,16 @@ license:CC0 + + + + + - - - + + - + @@ -1776,17 +2834,21 @@ license:CC0 + + + + - - - + + - + + Trump Collection 2 - Bottom-Up Teki Sekaiisshuu no Tabi 2000 Bottom Up @@ -1794,26 +2856,19 @@ license:CC0 + + + + - - + + - - + Trump Collection - Bottom-Up Teki Trump Seikatsu 1999 Bottom Up @@ -1821,9 +2876,13 @@ license:CC0 + + + + - - + + @@ -1836,11 +2895,15 @@ license:CC0 + + + + - - + + - + @@ -1853,14 +2916,19 @@ license:CC0 + + + + - - + + + Uzumaki - Denshi Kaiki Hen 2000 Omage Micott, Inc. @@ -1868,17 +2936,21 @@ license:CC0 + + + + - - - + + - + + Vaitz Blade 1999 Bandai @@ -1886,11 +2958,16 @@ license:CC0 + + + + + - - + + - + @@ -1903,11 +2980,16 @@ license:CC0 + + + + + - - + + - + @@ -1920,11 +3002,16 @@ license:CC0 + + + + + - - + + - + diff --git a/src/devices/bus/wswan/rom.cpp b/src/devices/bus/wswan/rom.cpp index 68d4c1d0500..9b1501c885f 100644 --- a/src/devices/bus/wswan/rom.cpp +++ b/src/devices/bus/wswan/rom.cpp @@ -24,9 +24,10 @@ enum DEFINE_DEVICE_TYPE(WS_ROM_STD, ws_rom_device, "ws_rom", "Wonderswan Standard Carts") DEFINE_DEVICE_TYPE(WS_ROM_SRAM, ws_rom_sram_device, "ws_sram", "Wonderswan Carts w/SRAM") DEFINE_DEVICE_TYPE(WS_ROM_EEPROM, ws_rom_eeprom_device, "ws_eeprom", "Wonderswan Carts w/EEPROM") +DEFINE_DEVICE_TYPE(WS_ROM_WWITCH, ws_wwitch_device, "ws_wwitch", "WonderWitch") -ws_rom_device::ws_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : +ws_rom_device::ws_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock), device_ws_cart_interface(mconfig, *this), m_base20(0), @@ -45,25 +46,35 @@ ws_rom_device::ws_rom_device(const machine_config &mconfig, device_type type, co { } -ws_rom_device::ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +ws_rom_device::ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ws_rom_device(mconfig, WS_ROM_STD, tag, owner, clock) { } -ws_rom_sram_device::ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +ws_rom_sram_device::ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ws_rom_device(mconfig, WS_ROM_SRAM, tag, owner, clock), m_nvram_base(0) { } +ws_rom_sram_device::ws_rom_sram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + ws_rom_device(mconfig, type, tag, owner, clock), + m_nvram_base(0) +{ +} -ws_rom_eeprom_device::ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +ws_rom_eeprom_device::ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : ws_rom_device(mconfig, WS_ROM_EEPROM, tag, owner, clock), m_eeprom_mode(0), m_eeprom_address(0), m_eeprom_command(0), m_eeprom_start(0), m_eeprom_write_enabled(0) { } +ws_wwitch_device::ws_wwitch_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + ws_rom_sram_device(mconfig, WS_ROM_WWITCH, tag, owner, clock) +{ +} + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -91,15 +102,17 @@ void ws_rom_device::device_start() save_item(NAME(m_rtc_minute)); save_item(NAME(m_rtc_second)); save_item(NAME(m_rtc_index)); + save_item(NAME(m_rom_mask)); } void ws_rom_device::device_reset() { - m_base20 = ((0xff & m_bank_mask) << 16) & (m_rom_size - 1); - m_base30 = ((0xff & m_bank_mask) << 16) & (m_rom_size - 1); - m_base40 = (((0xf0 & m_bank_mask) | 4) << 16) & (m_rom_size - 1); + m_rom_mask = (m_rom_size >> 1) - 1; + m_base20 = ((0xff & m_bank_mask) << 15) & m_rom_mask; + m_base30 = ((0xff & m_bank_mask) << 15) & m_rom_mask; + m_base40 = (((0xf0 & m_bank_mask) | 4) << 15) & m_rom_mask; - memset(m_io_regs, 0, sizeof(m_io_regs)); + memset(m_io_regs, 0xff, sizeof(m_io_regs)); // Initialize RTC m_rtc_index = 0; @@ -135,6 +148,30 @@ void ws_rom_eeprom_device::device_start() save_item(NAME(m_eeprom_write_enabled)); } +void ws_wwitch_device::device_start() +{ + save_item(NAME(m_flash_seq)); + save_item(NAME(m_flash_command)); + save_item(NAME(m_write_flash)); + save_item(NAME(m_writing_flash)); + save_item(NAME(m_write_resetting)); + save_item(NAME(m_flash_mode)); + save_item(NAME(m_flash_status)); + ws_rom_sram_device::device_start(); +} + +void ws_wwitch_device::device_reset() +{ + m_flash_seq = 0; + m_flash_command = 0; + m_write_flash = false; + m_writing_flash = false; + m_write_resetting = false; + m_flash_mode = READ_MODE; + m_flash_status = 0; + ws_rom_sram_device::device_reset(); +} + void ws_rom_eeprom_device::device_reset() { m_eeprom_address = 0; @@ -205,48 +242,52 @@ void ws_rom_device::device_timer(emu_timer &timer, device_timer_id id, int param mapper specific handlers -------------------------------------------------*/ -uint8_t ws_rom_device::read_rom20(offs_t offset) +u16 ws_rom_device::read_rom20(offs_t offset, u16 mem_mask) { return m_rom[offset + m_base20]; } -uint8_t ws_rom_device::read_rom30(offs_t offset) +u16 ws_rom_device::read_rom30(offs_t offset, u16 mem_mask) { return m_rom[offset + m_base30]; } -uint8_t ws_rom_device::read_rom40(offs_t offset) +u16 ws_rom_device::read_rom40(offs_t offset, u16 mem_mask) { // we still need to mask in some cases, e.g. when game is 512K - return m_rom[(offset + m_base40) & (m_rom_size - 1)]; + return m_rom[(offset + m_base40) & m_rom_mask]; } -uint8_t ws_rom_device::read_io(offs_t offset) +u16 ws_rom_device::read_io(offs_t offset, u16 mem_mask) { - uint8_t value = m_io_regs[offset]; + u16 value = m_io_regs[offset]; switch (offset) { - case 0x0b: // RTC data + case 0x0a / 2: if (!m_has_rtc) break; - if (m_io_regs[0x0a] == 0x95 && (m_rtc_index < 7)) + // RTC data + if (ACCESSING_BITS_8_15) { - switch (m_rtc_index) + if ((m_io_regs[0x0a / 2] & 0xff) == 0x95 && (m_rtc_index < 7)) { - case 0: value = m_rtc_year; break; - case 1: value = m_rtc_month; break; - case 2: value = m_rtc_day; break; - case 3: value = m_rtc_day_of_week; break; - case 4: value = m_rtc_hour; break; - case 5: value = m_rtc_minute; break; - case 6: value = m_rtc_second; break; + switch (m_rtc_index) + { + case 0: value = (value & 0xff) | (m_rtc_year << 8); break; + case 1: value = (value & 0xff) | (m_rtc_month << 8); break; + case 2: value = (value & 0xff) | (m_rtc_day << 8); break; + case 3: value = (value & 0xff) | (m_rtc_day_of_week << 8); break; + case 4: value = (value & 0xff) | (m_rtc_hour << 8); break; + case 5: value = (value & 0xff) | (m_rtc_minute << 8); break; + case 6: value = (value & 0xff) | (m_rtc_second << 8); break; + } + m_rtc_index++; } - m_rtc_index++; } break; } @@ -254,146 +295,164 @@ uint8_t ws_rom_device::read_io(offs_t offset) return value; } -void ws_rom_device::write_io(offs_t offset, uint8_t data) +void ws_rom_device::write_io(offs_t offset, u16 data, u16 mem_mask) { switch (offset) { - case 0x00: - // Bit 0-3 - ROM bank base register for segments 3-15 + case 0x00 / 2: + // Bit 0-3 - ROM bank base register for segments 4-15 // Bit 4-7 - Unknown - data = ((data & 0x0f) << 4) | 4; - m_base40 = ((data & m_bank_mask) << 16) & (m_rom_size - 1); - break; - case 0x02: // ROM bank for segment 2 (0x20000 - 0x2ffff) - m_base20 = ((data & m_bank_mask) << 16) & (m_rom_size - 1); - break; - case 0x03: // ROM bank for segment 3 (0x30000 - 0x3ffff) - m_base30 = ((data & m_bank_mask) << 16) & (m_rom_size - 1); + if (ACCESSING_BITS_0_7) + { + m_base40 = (((((data & 0x0f) << 4) | 4) & m_bank_mask) << 15) & m_rom_mask; + } break; - case 0x0a: // RTC Command - // Bit 0-4 - RTC command - // 10000 - Reset - // 10010 - Write timer settings (alarm) - // 10011 - Read timer settings (alarm) - // 10100 - Set time/date - // 10101 - Get time/date - // Bit 5-6 - Unknown - // Bit 7 - Command done (read only) - if (!m_has_rtc) - break; - - switch (data) + case 0x02 / 2: + // ROM bank for segment 2 (0x20000 - 0x2ffff) + if (ACCESSING_BITS_0_7) { - case 0x10: // Reset - m_rtc_index = 8; - m_rtc_year = 0; - m_rtc_month = 1; - m_rtc_day = 1; - m_rtc_day_of_week = 0; - m_rtc_hour = 0; - m_rtc_minute = 0; - m_rtc_second = 0; - m_rtc_setting = 0xff; - data |= 0x80; - break; - case 0x12: // Write Timer Settings (Alarm) - m_rtc_index = 8; - m_rtc_setting = m_io_regs[0x0b]; - data |= 0x80; - break; - case 0x13: // Read Timer Settings (Alarm) - m_rtc_index = 8; - m_io_regs[0x0b] = m_rtc_setting; - data |= 0x80; - break; - case 0x14: // Set Time/Date - m_rtc_year = m_io_regs[0x0b]; - m_rtc_index = 1; - data |= 0x80; - break; - case 0x15: // Get Time/Date - m_rtc_index = 0; - data |= 0x80; - m_io_regs[0x0b] = m_rtc_year; - break; - default: - logerror( "Unknown RTC command (%X) requested\n", data); + m_base20 = (((data & 0xff) & m_bank_mask) << 15) & m_rom_mask; + } + // ROM bank for segment 3 (0x30000 - 0x3ffff) + if (ACCESSING_BITS_8_15) + { + m_base30 = (((data >> 8) & m_bank_mask) << 15) & m_rom_mask; } break; - case 0x0b: // RTC Data + case 0x0a / 2: if (!m_has_rtc) break; - - if (m_io_regs[0x0a] == 0x94 && m_rtc_index < 7) + // RTC Command + // Bit 0-4 - RTC command + // 10000 - Reset + // 10010 - Write timer settings (alarm) + // 10011 - Read timer settings (alarm) + // 10100 - Set time/date + // 10101 - Get time/date + // Bit 5-6 - Unknown + // Bit 7 - Command done (read only) + if (ACCESSING_BITS_0_7) + { + switch (data & 0xff) + { + case 0x10: // Reset + m_rtc_index = 8; + m_rtc_year = 0; + m_rtc_month = 1; + m_rtc_day = 1; + m_rtc_day_of_week = 0; + m_rtc_hour = 0; + m_rtc_minute = 0; + m_rtc_second = 0; + m_rtc_setting = 0xff; + data |= 0x80; + break; + case 0x12: // Write Timer Settings (Alarm) + m_rtc_index = 8; + m_rtc_setting = m_io_regs[0x0a / 2] >> 8; + data |= 0x80; + break; + case 0x13: // Read Timer Settings (Alarm) + m_rtc_index = 8; + m_io_regs[0x0a / 2] = (m_io_regs[0x0a / 2] & 0x00ff) | (m_rtc_setting << 8); + data |= 0x80; + break; + case 0x14: // Set Time/Date + m_rtc_year = m_io_regs[0x0a / 2] >> 8; + m_rtc_index = 1; + data |= 0x80; + break; + case 0x15: // Get Time/Date + m_rtc_index = 0; + data |= 0x80; + m_io_regs[0x0a / 2] = (m_io_regs[0x0a / 2] & 0x00ff) | (m_rtc_year << 8); + break; + default: + logerror( "Unknown RTC command (%X) requested\n", data & 0xff); + } + } + // RTC Data + if (ACCESSING_BITS_8_15) { - switch (m_rtc_index) + if ((m_io_regs[0x0a / 2] & 0xff) == 0x94 && m_rtc_index < 7) { - case 0: m_rtc_year = data; break; - case 1: m_rtc_month = data; break; - case 2: m_rtc_day = data; break; - case 3: m_rtc_day_of_week = data; break; - case 4: m_rtc_hour = data; break; - case 5: m_rtc_minute = data; break; - case 6: m_rtc_second = data; break; + switch (m_rtc_index) + { + case 0: m_rtc_year = data >> 8; break; + case 1: m_rtc_month = data >> 8; break; + case 2: m_rtc_day = data >> 8; break; + case 3: m_rtc_day_of_week = data >> 8; break; + case 4: m_rtc_hour = data >> 8; break; + case 5: m_rtc_minute = data >> 8; break; + case 6: m_rtc_second = data >> 8; break; + } + m_rtc_index++; } - m_rtc_index++; } break; } - m_io_regs[offset] = data; + COMBINE_DATA(&m_io_regs[offset]); } -uint8_t ws_rom_sram_device::read_ram(offs_t offset) +u16 ws_rom_sram_device::read_ram(offs_t offset, u16 mem_mask) { - return m_nvram[m_nvram_base + offset]; + u32 nvram_address = (m_nvram_base + (offset << 1)) & (m_nvram_size - 1); + return m_nvram[nvram_address] | (m_nvram[nvram_address + 1] << 8); } -void ws_rom_sram_device::write_ram(offs_t offset, uint8_t data) +void ws_rom_sram_device::write_ram(offs_t offset, u16 data, u16 mem_mask) { - m_nvram[m_nvram_base + offset] = data; + u32 nvram_address = (m_nvram_base + (offset << 1)) & (m_nvram_size - 1); + if (ACCESSING_BITS_0_7) + m_nvram[nvram_address] = data & 0xff; + if (ACCESSING_BITS_8_15) + m_nvram[nvram_address + 1] = data >> 8; } -void ws_rom_sram_device::write_io(offs_t offset, uint8_t data) +void ws_rom_sram_device::write_io(offs_t offset, u16 data, u16 mem_mask) { switch (offset) { - case 0x01: // SRAM bank to select - m_nvram_base = (data * 0x10000) & (m_nvram.size() - 1); + case 0x00 / 2: + // SRAM bank to select + if (ACCESSING_BITS_8_15) + { + m_nvram_base = ((data >> 8) * 0x10000) & (m_nvram.size() - 1); + } [[fallthrough]]; default: - ws_rom_device::write_io(offset, data); + ws_rom_device::write_io(offset, data, mem_mask); break; } } -uint8_t ws_rom_eeprom_device::read_io(offs_t offset) +u16 ws_rom_eeprom_device::read_io(offs_t offset, u16 mem_mask) { - uint8_t value = m_io_regs[offset]; + u16 value = m_io_regs[offset]; switch (offset) { - case 0x04: - case 0x05: - case 0x06: - case 0x07: - case 0x08: + case 0x04 / 2: + case 0x06 / 2: + case 0x08 / 2: // EEPROM reads, taken from regs break; default: - value = ws_rom_device::read_io(offset); + value = ws_rom_device::read_io(offset, mem_mask); break; } return value; } -void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data) +void ws_rom_eeprom_device::write_io(offs_t offset, u16 data, u16 mem_mask) { switch (offset) { - case 0x06: /* EEPROM address lower bits port/EEPROM address and command port + case 0x06 / 2: + /* EEPROM address lower bits port/EEPROM address and command port 1KBit EEPROM: Bit 0-5 - EEPROM address bit 1-6 Bit 6-7 - Command @@ -408,27 +467,28 @@ void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data) 16KBit EEPROM: Bit 0-7 - EEPROM address bit 1-8 */ - switch (m_eeprom_mode) + if (ACCESSING_BITS_0_7) { - case EEPROM_1K: + switch (m_eeprom_mode) + { + case EEPROM_1K: m_eeprom_address = data & 0x3f; - m_eeprom_command = data >> 4; - if ((m_eeprom_command & 0x0c) != 0x00) - m_eeprom_command = m_eeprom_command & 0x0c; - break; + m_eeprom_command = (data >> 4) & 0x0f; + if ((m_eeprom_command & 0x0c) != 0x00) + m_eeprom_command = m_eeprom_command & 0x0c; + break; - case EEPROM_8K: - case EEPROM_16K: - m_eeprom_address = (m_eeprom_address & 0xff00) | data; - break; + case EEPROM_8K: + case EEPROM_16K: + m_eeprom_address = (m_eeprom_address & 0xff00) | (data & 0xff); + break; - default: - logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" ); - break; + default: + logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" ); + break; + } } - break; - - case 0x07: /* EEPROM higher bits/command bits port + /* EEPROM higher bits/command bits port 1KBit EEPROM: Bit 0 - Start Bit 1-7 - Unknown @@ -446,35 +506,39 @@ void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data) Bit 4 - Start Bit 5-7 - Unknown */ - switch (m_eeprom_mode) + if (ACCESSING_BITS_8_15) { - case EEPROM_1K: - m_eeprom_start = data & 0x01; - break; + switch (m_eeprom_mode) + { + case EEPROM_1K: + m_eeprom_start = (data >> 8) & 0x01; + break; - case EEPROM_8K: - m_eeprom_address = ((data & 0x01) << 8) | (m_eeprom_address & 0xff); - m_eeprom_command = data & 0x0f; - if ((m_eeprom_command & 0x0c) != 0x00) - m_eeprom_command = m_eeprom_command & 0x0c; - m_eeprom_start = (data >> 4) & 0x01; - break; + case EEPROM_8K: + m_eeprom_address = (data & 0x0100) | (m_eeprom_address & 0xff); + m_eeprom_command = (data >> 8) & 0x0f; + if ((m_eeprom_command & 0x0c) != 0x00) + m_eeprom_command = m_eeprom_command & 0x0c; + m_eeprom_start = (data >> 12) & 0x01; + break; - case EEPROM_16K: - m_eeprom_address = ((data & 0x03) << 8) | (m_eeprom_address & 0xff); - m_eeprom_command = data & 0x0f; - if ((m_eeprom_command & 0x0c) != 0x00) - m_eeprom_command = m_eeprom_command & 0x0c; - m_eeprom_start = (data >> 4) & 0x01; - break; + case EEPROM_16K: + m_eeprom_address = (data & 0x0300) | (m_eeprom_address & 0xff); + m_eeprom_command = (data >> 8) & 0x0f; + if ((m_eeprom_command & 0x0c) != 0x00) + m_eeprom_command = m_eeprom_command & 0x0c; + m_eeprom_start = (data >> 12) & 0x01; + break; - default: - logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" ); - break; + default: + logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" ); + break; + } } break; - case 0x08: /* EEPROM command + case 0x08 / 2: + /* EEPROM command Bit 0 - Read complete (read only) Bit 1 - Write complete (read only) Bit 2-3 - Unknown @@ -483,57 +547,200 @@ void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data) Bit 6 - Protect Bit 7 - Initialize */ - if (data & 0x80) // Initialize - logerror("Unsupported EEPROM command 'Initialize'\n"); - - if (data & 0x40) // Protect + if (ACCESSING_BITS_0_7) { - switch (m_eeprom_command) - { - case 0x00: - m_eeprom_write_enabled = 0; - data |= 0x02; - break; - case 0x03: - m_eeprom_write_enabled = 1; - data |= 0x02; - break; - default: - logerror("Unsupported 'Protect' command %X\n", m_eeprom_command); - break; - } - } + if (data & 0x80) // Initialize + logerror("Unsupported EEPROM command 'Initialize'\n"); - if (data & 0x20) // Write - { - if (m_eeprom_write_enabled) + if (data & 0x40) // Protect { switch (m_eeprom_command) { - case 0x04: - m_nvram[(m_eeprom_address << 1) + 1] = m_io_regs[0x04]; - m_nvram[m_eeprom_address << 1] = m_io_regs[0x05]; + case 0x00: + m_eeprom_write_enabled = 0; + data |= 0x02; + break; + case 0x03: + m_eeprom_write_enabled = 1; data |= 0x02; break; default: - logerror("Unsupported 'Write' command %X\n", m_eeprom_command); + logerror("Unsupported 'Protect' command %X\n", m_eeprom_command); break; } } - } - if (data & 0x10) // Read - { - m_io_regs[0x04] = m_nvram[(m_eeprom_address << 1) + 1]; - m_io_regs[0x05] = m_nvram[m_eeprom_address << 1]; - data |= 0x01; + if (data & 0x20) // Write + { + if (m_eeprom_write_enabled) + { + switch (m_eeprom_command) + { + case 0x04: + m_nvram[(m_eeprom_address << 1) + 1] = m_io_regs[0x04 / 2] & 0xff; + m_nvram[m_eeprom_address << 1] = m_io_regs[0x04 / 2] >> 8; + data |= 0x02; + break; + default: + logerror("Unsupported 'Write' command %X\n", m_eeprom_command); + break; + } + } + } + + if (data & 0x10) // Read + { + m_io_regs[0x04] = m_nvram[(m_eeprom_address << 1) + 1]; + m_io_regs[0x05] = m_nvram[m_eeprom_address << 1]; + data |= 0x01; + } } break; default: - ws_rom_device::write_io(offset, data); + ws_rom_device::write_io(offset, data, mem_mask); break; } - m_io_regs[offset] = data; + COMBINE_DATA(&m_io_regs[offset]); +} + + +u16 ws_wwitch_device::read_ram(offs_t offset, u16 mem_mask) +{ + if (m_flash_mode == COMMAND_MODE) + { + if (!machine().side_effects_disabled()) + { + if (m_writing_flash) + { + m_flash_status ^= 0x40; + m_flash_count++; + if (m_flash_count > 4) { + m_writing_flash = false; + m_flash_mode = READ_MODE; + } + } + // After initiating an erase block command the wwitch expects to see bit 7 set + if (m_flash_command == 0x30) + { + m_flash_status |= 0x80; + m_flash_mode = READ_MODE; + } + } + return m_flash_status; + } + if (m_io_regs[0x01] >= 8 && m_io_regs[0x01] < 16) + { + return m_rom[((m_io_regs[0x01] * 0x8000) | offset) & m_rom_mask]; + } + if (m_io_regs[0x01] < 8) + { + return ws_rom_sram_device::read_ram(offset, mem_mask); + } + else + { + return 0xffff; + } +} + + +void ws_wwitch_device::write_ram(offs_t offset, u16 data, u16 mem_mask) +{ + if (m_flash_seq == 0 && offset == (0xaaa >> 1) && ACCESSING_BITS_0_7 && data == 0xaa) + { + m_flash_seq = 1; + } + else if (m_flash_seq == 1 && offset == (0x555 >> 1) && ACCESSING_BITS_8_15 && data == 0x55) + { + m_flash_seq = 2; + } + else if (m_flash_seq == 2 && offset == (0xaaa >> 1) && ACCESSING_BITS_0_7) + { + switch (data) + { + case 0x10: // Chip erase + if (m_flash_command == 0x80) + { + // TODO + } + break; + case 0x20: // Set to fast mode + m_flash_command = data; + m_flash_mode = COMMAND_MODE; + break; + case 0x30: // (Erase) block + // TODO: Any write to a block address triggers the block erase + if (m_flash_command == 0x80) + { + if ((m_io_regs[0x01] & 0x07) < 7) + { + u32 block_base = (m_io_regs[0x01] & 0x07) << 15; + for (u32 address = 0; address < 0x8000; address++) + { + m_rom[(block_base | address) & m_rom_mask] = 0xffff; + } + } + + m_flash_command = data; + m_flash_mode = COMMAND_MODE; + } + break; + case 0x80: // Erase (chip or block) + m_flash_command = data; + break; + default: // Unknown command + m_flash_command = 0; + } + m_flash_seq = 0; + } + else if (m_io_regs[0x01] >= 8 && m_io_regs[0x01] < 15) + { + if (m_write_flash) + { + // perform write + if (!ACCESSING_BITS_0_7) + data |= 0xff; + if (!ACCESSING_BITS_8_15) + data |= 0xff00; + m_rom[((m_io_regs[0x01] * 0x8000) | offset) & m_rom_mask] &= data; + m_flash_status = (m_flash_status & 0x7f) | ((data ^ 0x80) & 0x80); + m_writing_flash = true; + m_flash_count = 0; + m_write_flash = false; + } + else if (m_flash_command == 0x20) + { + switch (data) + { + case 0x00: + if (m_write_resetting) + { + m_write_flash = false; + m_write_resetting = false; + m_flash_mode = READ_MODE; + } + break; + case 0xF0: // Reset from fast mode #2 + m_write_flash = false; + m_write_resetting = false; + m_flash_mode = READ_MODE; + break; + case 0x90: // Reset from fast mode #1 + m_write_resetting = true; + break; + case 0xA0: // Fast program + if (m_flash_command == 0x20) + { + m_write_flash = true; + m_flash_mode = COMMAND_MODE; + } + break; + } + } + } + else if (m_io_regs[0x01] < 8) + { + ws_rom_sram_device::write_ram(offset, data, mem_mask); + } } diff --git a/src/devices/bus/wswan/rom.h b/src/devices/bus/wswan/rom.h index 916562ab6e2..e61efd904de 100644 --- a/src/devices/bus/wswan/rom.h +++ b/src/devices/bus/wswan/rom.h @@ -13,38 +13,39 @@ class ws_rom_device : public device_t, { public: // construction/destruction - ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // reading and writing - virtual uint8_t read_rom20(offs_t offset) override; - virtual uint8_t read_rom30(offs_t offset) override; - virtual uint8_t read_rom40(offs_t offset) override; - virtual uint8_t read_io(offs_t offset) override; - virtual void write_io(offs_t offset, uint8_t data) override; + virtual u16 read_rom20(offs_t offset, u16 mem_mask) override; + virtual u16 read_rom30(offs_t offset, u16 mem_mask) override; + virtual u16 read_rom40(offs_t offset, u16 mem_mask) override; + virtual u16 read_io(offs_t offset, u16 mem_mask) override; + virtual void write_io(offs_t offset, u16 data, u16 mem_mask) override; protected: static constexpr device_timer_id TIMER_RTC = 0; - ws_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + ws_rom_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; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; - uint8_t m_io_regs[0x10]; - uint32_t m_base20, m_base30, m_base40; + u16 m_io_regs[8]; + u32 m_base20, m_base30, m_base40; + u32 m_rom_mask; // RTC - uint8_t m_rtc_setting; /* Timer setting byte */ - uint8_t m_rtc_year; /* Year */ - uint8_t m_rtc_month; /* Month */ - uint8_t m_rtc_day; /* Day */ - uint8_t m_rtc_day_of_week; /* Day of the week */ - uint8_t m_rtc_hour; /* Hour, high bit = 0 => AM, high bit = 1 => PM */ - uint8_t m_rtc_minute; /* Minute */ - uint8_t m_rtc_second; /* Second */ - uint8_t m_rtc_index; /* index for reading/writing of current of alarm time */ + u8 m_rtc_setting; /* Timer setting byte */ + u8 m_rtc_year; /* Year */ + u8 m_rtc_month; /* Month */ + u8 m_rtc_day; /* Day */ + u8 m_rtc_day_of_week; /* Day of the week */ + u8 m_rtc_hour; /* Hour, high bit = 0 => AM, high bit = 1 => PM */ + u8 m_rtc_minute; /* Minute */ + u8 m_rtc_second; /* Second */ + u8 m_rtc_index; /* index for reading/writing of current of alarm time */ emu_timer *rtc_timer; }; @@ -56,20 +57,22 @@ class ws_rom_sram_device : public ws_rom_device { public: // construction/destruction - ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // reading and writing - virtual uint8_t read_ram(offs_t offset) override; - virtual void write_ram(offs_t offset, uint8_t data) override; - virtual void write_io(offs_t offset, uint8_t data) override; + virtual u16 read_ram(offs_t offset, u16 mem_mask) override; + virtual void write_ram(offs_t offset, u16 data, u16 mem_mask) override; + virtual void write_io(offs_t offset, u16 data, u16 mem_mask) override; protected: + ws_rom_sram_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; private: - uint32_t m_nvram_base; + u32 m_nvram_base; }; @@ -79,11 +82,11 @@ class ws_rom_eeprom_device : public ws_rom_device { public: // construction/destruction - ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // reading and writing - virtual uint8_t read_io(offs_t offset) override; - virtual void write_io(offs_t offset, uint8_t data) override; + virtual u16 read_io(offs_t offset, u16 mem_mask) override; + virtual void write_io(offs_t offset, u16 data, u16 mem_mask) override; protected: // device-level overrides @@ -91,18 +94,49 @@ protected: virtual void device_reset() override; private: - uint8_t m_eeprom_mode; /* eeprom mode */ - uint16_t m_eeprom_address; /* Read/write address */ - uint8_t m_eeprom_command; /* Commands: 00, 01, 02, 03, 04, 08, 0C */ - uint8_t m_eeprom_start; /* start bit */ - uint8_t m_eeprom_write_enabled; /* write enabled yes/no */ + u8 m_eeprom_mode; /* eeprom mode */ + u16 m_eeprom_address; /* Read/write address */ + u8 m_eeprom_command; /* Commands: 00, 01, 02, 03, 04, 08, 0C */ + u8 m_eeprom_start; /* start bit */ + u8 m_eeprom_write_enabled; /* write enabled yes/no */ }; +class ws_wwitch_device : public ws_rom_sram_device +{ +public: + // construction/destruction + ws_wwitch_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // reading and writing + virtual u16 read_ram(offs_t offset, u16 mem_mask) override; + virtual void write_ram(offs_t offset, u16 data, u16 mem_mask) override; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + enum { + READ_MODE = 0, + COMMAND_MODE + }; + u8 m_flash_seq; + u8 m_flash_command; + bool m_write_flash; + bool m_writing_flash; + bool m_write_resetting; + u8 m_flash_mode; + u8 m_flash_status; + u8 m_flash_count; +}; + // device type definition DECLARE_DEVICE_TYPE(WS_ROM_STD, ws_rom_device) DECLARE_DEVICE_TYPE(WS_ROM_SRAM, ws_rom_sram_device) DECLARE_DEVICE_TYPE(WS_ROM_EEPROM, ws_rom_eeprom_device) +DECLARE_DEVICE_TYPE(WS_ROM_WWITCH, ws_wwitch_device) #endif // MAME_BUS_WSWAN_ROM_H diff --git a/src/devices/bus/wswan/slot.cpp b/src/devices/bus/wswan/slot.cpp index fd0c8cdc9fa..7cb338e2cc9 100644 --- a/src/devices/bus/wswan/slot.cpp +++ b/src/devices/bus/wswan/slot.cpp @@ -29,9 +29,9 @@ device_ws_cart_interface::device_ws_cart_interface(const machine_config &mconfig device_interface(device, "wswancart"), m_rom(nullptr), m_rom_size(0), + m_nvram_size(0), m_bank_mask(0), - m_has_rtc(false), - m_is_rotated(false) + m_has_rtc(false) { } @@ -48,11 +48,11 @@ device_ws_cart_interface::~device_ws_cart_interface() // rom_alloc - alloc the space for the cart //------------------------------------------------- -void device_ws_cart_interface::rom_alloc(uint32_t size, const char *tag) +void device_ws_cart_interface::rom_alloc(u32 size, const char *tag) { if (m_rom == nullptr) { - m_rom = device().machine().memory().region_alloc(std::string(tag).append(WSSLOT_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base(); + m_rom = (u16 *)device().machine().memory().region_alloc(std::string(tag).append(WSSLOT_ROM_REGION_TAG).c_str(), size, 2, ENDIANNESS_LITTLE)->base(); m_rom_size = size; m_bank_mask = ((m_rom_size >> 16) - 1); } @@ -63,8 +63,9 @@ void device_ws_cart_interface::rom_alloc(uint32_t size, const char *tag) // nvram_alloc - alloc the space for the ram //------------------------------------------------- -void device_ws_cart_interface::nvram_alloc(uint32_t size) +void device_ws_cart_interface::nvram_alloc(u32 size) { + m_nvram_size = size; m_nvram.resize(size); } @@ -76,7 +77,7 @@ void device_ws_cart_interface::nvram_alloc(uint32_t size) //------------------------------------------------- // ws_cart_slot_device - constructor //------------------------------------------------- -ws_cart_slot_device::ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +ws_cart_slot_device::ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, WS_CART_SLOT, tag, owner, clock), device_image_interface(mconfig, *this), device_single_card_slot_interface(mconfig, *this), @@ -119,7 +120,8 @@ static const ws_slot slot_list[] = { { WS_STD, "ws_rom" }, { WS_SRAM, "ws_sram" }, - { WS_EEPROM, "ws_eeprom" } + { WS_EEPROM, "ws_eeprom" }, + { WWITCH, "wwitch"} }; static int ws_get_pcb_id(const char *slot) @@ -153,9 +155,9 @@ image_init_result ws_cart_slot_device::call_load() { if (m_cart) { - uint8_t *ROM; - uint32_t size = !loaded_through_softlist() ? length() : get_software_region_length("rom"); - uint32_t nvram_size = 0; + u16 *ROM; + u32 size = !loaded_through_softlist() ? length() : get_software_region_length("rom"); + u32 nvram_size = 0; m_cart->rom_alloc(size, tag()); ROM = m_cart->get_rom_base(); @@ -167,14 +169,11 @@ image_init_result ws_cart_slot_device::call_load() if (!loaded_through_softlist()) { - int chunks = size / 0x10000; // get cart type and nvram length m_type = get_cart_type(ROM, size, nvram_size); - if (ROM[(chunks - 1) * 0x10000 + 0xfffd]) + if (ROM[(size >> 1) - 2] & 0xff00) m_cart->set_has_rtc(true); - if (ROM[(chunks - 1) * 0x10000 + 0xfffc] & 0x01) - m_cart->set_is_rotated(true); } else { @@ -182,7 +181,7 @@ image_init_result ws_cart_slot_device::call_load() if (pcb_name) m_type = ws_get_pcb_id(pcb_name); - if (m_type == WS_SRAM) + if (m_type == WS_SRAM || m_type == WWITCH) nvram_size = get_software_region_length("sram"); if (m_type == WS_EEPROM) nvram_size = get_software_region_length("eeprom"); @@ -192,15 +191,8 @@ image_init_result ws_cart_slot_device::call_load() if (!core_stricmp(get_feature("rtc"), "yes")) m_cart->set_has_rtc(true); } - if (get_feature("rotated")) - { - if (!core_stricmp(get_feature("rotated"), "yes")) - m_cart->set_is_rotated(true); - } } - //printf("Type: %s\n", ws_get_slot(m_type)); - if (nvram_size) { // allocate NVRAM @@ -230,12 +222,11 @@ void ws_cart_slot_device::call_unload() get cart type from cart file -------------------------------------------------*/ -int ws_cart_slot_device::get_cart_type(const uint8_t *ROM, uint32_t len, uint32_t &nvram_len) const +int ws_cart_slot_device::get_cart_type(const u16 *ROM, u32 len, u32 &nvram_len) const { - int chunks = len / 0x10000; int type = WS_STD; - switch (ROM[(chunks - 1) * 0x10000 + 0xfffb]) + switch (ROM[(len >> 1) - 3] >> 8) { case 0x00: break; @@ -272,8 +263,7 @@ int ws_cart_slot_device::get_cart_type(const uint8_t *ROM, uint32_t len, uint32_ nvram_len = 0x800; break; default: - printf("Unknown RAM size [0x%X]\n", ROM[(chunks - 1) * 0x10000 + 0xfffb]); - logerror("Unknown RAM size [0x%X]\n", ROM[(chunks - 1) * 0x10000 + 0xfffb]); + logerror("Unknown RAM size [0x%X]\n", ROM[(len >> 1) - 3] >> 8); break; } @@ -289,10 +279,10 @@ std::string ws_cart_slot_device::get_default_card_software(get_default_card_soft if (hook.image_file()) { const char *slot_string; - uint32_t size = hook.image_file()->size(); - std::vector rom(size); + u32 size = hook.image_file()->size(); + std::vector rom(size); int type; - uint32_t nvram; + u32 nvram; hook.image_file()->read(&rom[0], size); @@ -300,8 +290,6 @@ std::string ws_cart_slot_device::get_default_card_software(get_default_card_soft type = get_cart_type(&rom[0], size, nvram); slot_string = ws_get_slot(type); - //printf("type: %s\n", slot_string); - return std::string(slot_string); } @@ -312,80 +300,80 @@ std::string ws_cart_slot_device::get_default_card_software(get_default_card_soft read_rom20 -------------------------------------------------*/ -uint8_t ws_cart_slot_device::read_rom20(offs_t offset) +u16 ws_cart_slot_device::read_rom20(offs_t offset, u16 mem_mask) { if (m_cart) - return m_cart->read_rom20(offset); + return m_cart->read_rom20(offset, mem_mask); else - return 0xff; + return 0xffff; } /*------------------------------------------------- read_rom30 -------------------------------------------------*/ -uint8_t ws_cart_slot_device::read_rom30(offs_t offset) +u16 ws_cart_slot_device::read_rom30(offs_t offset, u16 mem_mask) { if (m_cart) - return m_cart->read_rom30(offset); + return m_cart->read_rom30(offset, mem_mask); else - return 0xff; + return 0xffff; } /*------------------------------------------------- read_rom40 -------------------------------------------------*/ -uint8_t ws_cart_slot_device::read_rom40(offs_t offset) +u16 ws_cart_slot_device::read_rom40(offs_t offset, u16 mem_mask) { if (m_cart) - return m_cart->read_rom40(offset); + return m_cart->read_rom40(offset, mem_mask); else - return 0xff; + return 0xffff; } /*------------------------------------------------- read_ram -------------------------------------------------*/ -uint8_t ws_cart_slot_device::read_ram(offs_t offset) +u16 ws_cart_slot_device::read_ram(offs_t offset, u16 mem_mask) { if (m_cart) - return m_cart->read_ram(offset); + return m_cart->read_ram(offset, mem_mask); else - return 0xff; + return 0xffff; } /*------------------------------------------------- write_ram -------------------------------------------------*/ -void ws_cart_slot_device::write_ram(offs_t offset, uint8_t data) +void ws_cart_slot_device::write_ram(offs_t offset, u16 data, u16 mem_mask) { if (m_cart) - m_cart->write_ram(offset, data); + m_cart->write_ram(offset, data, mem_mask); } /*------------------------------------------------- read_io -------------------------------------------------*/ -uint8_t ws_cart_slot_device::read_io(offs_t offset) +u16 ws_cart_slot_device::read_io(offs_t offset, u16 mem_mask) { if (m_cart) - return m_cart->read_io(offset); + return m_cart->read_io(offset & 0x07, mem_mask); else - return 0xff; + return 0xffff; } /*------------------------------------------------- write_io -------------------------------------------------*/ -void ws_cart_slot_device::write_io(offs_t offset, uint8_t data) +void ws_cart_slot_device::write_io(offs_t offset, u16 data, u16 mem_mask) { if (m_cart) - m_cart->write_io(offset, data); + m_cart->write_io(offset & 0x07, data, mem_mask); } @@ -398,36 +386,37 @@ static const char *const sram_str[] = { "none", "64Kbit SRAM", "256Kbit SRAM", " static const char *const eeprom_str[] = { "none", "1Kbit EEPROM", "16Kbit EEPROM", "Unknown", "Unknown", "8Kbit EEPROM" }; static const char *const romsize_str[] = { "Unknown", "Unknown", "4Mbit", "8Mbit", "16Mbit", "Unknown", "32Mbit", "Unknown", "64Mbit", "128Mbit" }; -void ws_cart_slot_device::internal_header_logging(uint8_t *ROM, uint32_t offs, uint32_t len) +void ws_cart_slot_device::internal_header_logging(const u16 *ROM, u32 offs, u32 len) { - int sum = 0, banks = len / 0x10000; - uint8_t romsize, ramtype, ramsize; - romsize = ROM[offs + 0xfffa]; - ramtype = (ROM[offs + 0xfffb] & 0xf0) ? 1 : 0; // 1 = EEPROM, 0 = SRAM - ramsize = ramtype ? ((ROM[offs + 0xfffb] & 0xf0) >> 4) : (ROM[offs + 0xfffb] & 0x0f); - + const int banks = len / 0x10000; + const int words = len >> 1; + const u8 romsize = ROM[words - 3] & 0xff; + const u8 ramtype = (ROM[words - 3] & 0xf000) ? 1 : 0; // 1 = EEPROM, 0 = SRAM + const u8 ramsize = ramtype ? (((ROM[words - 3] >> 8) & 0xf0) >> 4) : ((ROM[words - 3] >> 8) & 0x0f); + u16 sum = 0; logerror( "ROM DETAILS\n" ); logerror( "===========\n\n" ); - logerror("\tDeveloper ID: %X\n", ROM[offs + 0xfff6]); - logerror("\tMinimum system: %s\n", ROM[offs + 0xfff7] ? "WonderSwan Color" : "WonderSwan"); - logerror("\tCart ID: %X\n", ROM[offs + 0xfff8]); + logerror("\tDeveloper ID: %X\n", ROM[words - 5] & 0xff); + logerror("\tMinimum system: %s\n", ROM[words - 5] & 0xff00 ? "WonderSwan Color" : "WonderSwan"); + logerror("\tCart ID: %X\n", ROM[words - 4] & 0xff); logerror("\tROM size: %s\n", romsize_str[romsize]); if (ramtype) logerror("\tEEPROM size: %s\n", (ramsize < 6) ? eeprom_str[ramsize] : "Unknown"); else logerror("\tSRAM size: %s\n", (ramsize < 6) ? sram_str[ramsize] : "Unknown"); - logerror("\tFeatures: %X\n", ROM[offs + 0xfffc]); - logerror("\tRTC: %s\n", ROM[offs + 0xfffd] ? "yes" : "no"); + logerror("\tFeatures: %X\n", ROM[words - 2] & 0xff); + logerror("\tRTC: %s\n", (ROM[words - 2] & 0xff00) ? "yes" : "no"); for (int i = 0; i < banks; i++) { - for (int count = 0; count < 0x10000; count++) + for (int count = 0; count < 0x8000; count++) { - sum += ROM[(i * 0x10000) + count]; + sum += ROM[i * 0x8000 + count] & 0xff; + sum += ROM[i * 0x8000 + count] >> 8; } } - sum -= ROM[offs + 0xffff]; - sum -= ROM[offs + 0xfffe]; + sum -= ROM[words - 1] & 0xff; + sum -= ROM[words - 1] >> 8; sum &= 0xffff; - logerror("\tChecksum: %.2X%.2X (calculated: %04X)\n", ROM[offs + 0xffff], ROM[offs + 0xfffe], sum); + logerror("\tChecksum: %04X (calculated: %04X)\n", ROM[words - 1], sum); } diff --git a/src/devices/bus/wswan/slot.h b/src/devices/bus/wswan/slot.h index 85bda911c89..21abdb7fc13 100644 --- a/src/devices/bus/wswan/slot.h +++ b/src/devices/bus/wswan/slot.h @@ -79,7 +79,8 @@ enum { WS_STD = 0, WS_SRAM, - WS_EEPROM + WS_EEPROM, + WWITCH }; @@ -92,36 +93,35 @@ public: virtual ~device_ws_cart_interface(); // reading and writing - virtual uint8_t read_rom20(offs_t offset) { return 0xff; } - virtual uint8_t read_rom30(offs_t offset) { return 0xff; } - virtual uint8_t read_rom40(offs_t offset) { return 0xff; } - virtual uint8_t read_ram(offs_t offset) { return 0xff; } - virtual void write_ram(offs_t offset, uint8_t data) {} - virtual uint8_t read_io(offs_t offset) { return 0xff; } - virtual void write_io(offs_t offset, uint8_t data) { } - - void rom_alloc(uint32_t size, const char *tag); - void nvram_alloc(uint32_t size); - uint8_t* get_rom_base() { return m_rom; } + virtual u16 read_rom20(offs_t offset, u16 mem_mask) { return 0xffff; } + virtual u16 read_rom30(offs_t offset, u16 mem_mask) { return 0xffff; } + virtual u16 read_rom40(offs_t offset, u16 mem_mask) { return 0xffff; } + virtual u16 read_ram(offs_t offset, u16 mem_mask) { return 0xffff; } + virtual void write_ram(offs_t offset, u16 data, u16 mem_mask) {} + virtual u16 read_io(offs_t offset, u16 mem_mask) { return 0xffff; } + virtual void write_io(offs_t offset, u16 data, u16 mem_mask) { } + + void rom_alloc(u32 size, const char *tag); + void nvram_alloc(u32 size); + u16* get_rom_base() { return m_rom; } uint8_t* get_nvram_base() { return &m_nvram[0]; } uint32_t get_rom_size() { return m_rom_size; } uint32_t get_nvram_size() { return m_nvram.size(); } void save_nvram() { device().save_item(NAME(m_nvram)); } void set_has_rtc(bool val) { m_has_rtc = val; } - void set_is_rotated(bool val) { m_is_rotated = val; } - int get_is_rotated() { return m_is_rotated ? 1 : 0; } protected: device_ws_cart_interface(const machine_config &mconfig, device_t &device); // internal state - uint8_t *m_rom; - uint32_t m_rom_size; - std::vector m_nvram; + u16 *m_rom; + u32 m_rom_size; + std::vector m_nvram; + u32 m_nvram_size; int m_bank_mask; - bool m_has_rtc, m_is_rotated; + bool m_has_rtc; }; @@ -134,7 +134,7 @@ class ws_cart_slot_device : public device_t, public: // construction/destruction template - ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&opts, const char *dflt) + ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&opts, const char *dflt) : ws_cart_slot_device(mconfig, tag, owner, clock) { option_reset(); @@ -142,7 +142,7 @@ public: set_default_option(dflt); set_fixed(false); } - ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual ~ws_cart_slot_device(); // image-level overrides @@ -162,20 +162,19 @@ public: virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; int get_type() { return m_type; } - int get_is_rotated() { return m_cart->get_is_rotated(); } - int get_cart_type(const uint8_t *ROM, uint32_t len, uint32_t &nvram_len) const; - void internal_header_logging(uint8_t *ROM, uint32_t offs, uint32_t len); + int get_cart_type(const u16 *ROM, u32 len, u32 &nvram_len) const; + void internal_header_logging(const u16 *ROM, u32 offs, u32 len); void save_nvram() { if (m_cart && m_cart->get_nvram_size()) m_cart->save_nvram(); } // reading and writing - virtual uint8_t read_rom20(offs_t offset); - virtual uint8_t read_rom30(offs_t offset); - virtual uint8_t read_rom40(offs_t offset); - virtual uint8_t read_ram(offs_t offset); - virtual void write_ram(offs_t offset, uint8_t data); - virtual uint8_t read_io(offs_t offset); - virtual void write_io(offs_t offset, uint8_t data); + virtual u16 read_rom20(offs_t offset, u16 mem_mask); + virtual u16 read_rom30(offs_t offset, u16 mem_mask); + virtual u16 read_rom40(offs_t offset, u16 mem_mask); + virtual u16 read_ram(offs_t offset, u16 mem_mask); + virtual void write_ram(offs_t offset, u16 data, u16 mem_mask); + virtual u16 read_io(offs_t offset, u16 mem_mask); + virtual void write_io(offs_t offset, u16 data, u16 mem_mask); protected: // device-level overrides diff --git a/src/devices/cpu/v30mz/v30mz.cpp b/src/devices/cpu/v30mz/v30mz.cpp index db96c6b92e5..2042932b1eb 100644 --- a/src/devices/cpu/v30mz/v30mz.cpp +++ b/src/devices/cpu/v30mz/v30mz.cpp @@ -2,43 +2,20 @@ // copyright-holders:Wilbert Pol,Bryan McPhail /**************************************************************************** - NEC V20/V30/V33 emulator modified to a v30mz emulator + v30mz emulator based on NEC V20/V30/V33 emulator. - (Re)Written June-September 2000 by Bryan McPhail (mish@tendril.co.uk) based - on code by Oliver Bergmann (Raul_Bloodworth@hotmail.com) who based code - on the i286 emulator by Fabrice Frances which had initial work based on - David Hedley's pcemu(!). - - This new core features 99% accurate cycle counts for each processor, - there are still some complex situations where cycle counts are wrong, - typically where a few instructions have differing counts for odd/even - source and odd/even destination memory operands. - - Flag settings are also correct for the NEC processors rather than the - I86 versions. - - Changelist: - - 22/02/2003: - Removed cycle counts from memory accesses - they are certainly wrong, - and there is already a memory access cycle penalty in the opcodes - using them. - - Fixed save states. - - Fixed ADJBA/ADJBS/ADJ4A/ADJ4S flags/return values for all situations. - (Fixes bugs in Geostorm and Thunderblaster) - - Fixed carry flag on NEG (I thought this had been fixed circa Mame 0.58, - but it seems I never actually submitted the fix). - - Fixed many cycle counts in instructions and bug in cycle count - macros (odd word cases were testing for odd instruction word address - not data address). + The internal details of the prefetch queue are not exactly known. We + keep a prefetch queue a 8 bytes even though the documentation mentions + a prefetch queue of 8 words/16 bytes. Using 8 bytes keeps the amount of + fetches limited on tight loops and is more than enough for the longest + instruction. Todo! - Double check cycle timing is 100%. - Fix memory interface (should be 16 bit). + - Double check cycle timing is 100%. + - Add penalties when BW, BP, SP, IX, IY etc are changed in the immediately + preceding instruction. + - wswan mjkiwame (at 0x40141) has rep in al,$b5 (f3 e4 b5). Should this + repeat the in instruction or is this a bug made by the programmer? ****************************************************************************/ @@ -48,11 +25,9 @@ #include "debugger.h" -enum SREGS { ES=0, CS, SS, DS }; +enum SREGS { DS1=0, PS, SS, DS0 }; enum WREGS { AW=0, CW, DW, BW, SP, BP, IX, IY }; -#define NEC_NMI_INT_VECTOR 2 - enum BREGS { AL = NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1), AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0), @@ -72,6 +47,15 @@ enum BREGS { IYH = NATIVE_ENDIAN_VALUE_LE_BE(0xf, 0xe) }; +enum nec_irqs { + DIVIDE_ERROR_INT = 0, + BREAK_INT = 1, + NMI_INT = 2, + BRK_3_INT = 3, + BRKV_INT = 4, + CHKIND_INT = 5 +}; + #define CF (m_CarryVal!=0) #define SF (m_SignVal<0) @@ -82,35 +66,30 @@ enum BREGS { #define MD (m_MF!=0) -/***************************************************************************/ -/* cpu state */ -/***************************************************************************/ - - -/* The interrupt number of a pending external interrupt pending NMI is 2. */ -/* For INTR interrupts, the level is caught on the bus during an INTA cycle */ +// The interrupt number of a pending external interrupt pending NMI is 2. +// For INTR interrupts, the level is caught on the bus during an INTA cycle #define INT_IRQ 0x01 #define NMI_IRQ 0x02 -/***************************************************************************/ DEFINE_DEVICE_TYPE(V30MZ, v30mz_cpu_device, "v30mz", "NEC V30MZ") v30mz_cpu_device::v30mz_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, V30MZ, tag, owner, clock) - , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0) - , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0) + , m_program_config("program", ENDIANNESS_LITTLE, 16, 20, 0) + , m_io_config("io", ENDIANNESS_LITTLE, 16, 16, 0) , m_ip(0) , m_TF(0) , m_int_vector(0) , m_pc(0) + , m_vector_func(*this) { static const BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH }; - /* Set up parity lookup table. */ - for (uint16_t i = 0;i < 256; i++) + // Set up parity lookup table. + for (uint16_t i = 0; i < 256; i++) { uint16_t c = 0; for (uint16_t j = i; j > 0; j >>= 1) @@ -128,11 +107,12 @@ v30mz_cpu_device::v30mz_cpu_device(const machine_config &mconfig, const char *ta for (uint16_t i = 0xc0; i < 0x100; i++) { - m_Mod_RM.RM.w[i] = (WREGS)( i & 7 ); + m_Mod_RM.RM.w[i] = (WREGS)(i & 7); m_Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7]; } - memset(&m_regs, 0x00, sizeof(m_regs)); + std::fill(std::begin(m_regs.w), std::end(m_regs.w), 0); + std::fill(std::begin(m_prefetch_queue), std::end(m_prefetch_queue), 0); } device_memory_interface::space_config_vector v30mz_cpu_device::memory_space_config() const @@ -150,6 +130,8 @@ void v30mz_cpu_device::device_start() space(AS_PROGRAM).specific(m_program); space(AS_IO).specific(m_io); + m_vector_func.resolve_safe(0); + save_item(NAME(m_regs.w)); save_item(NAME(m_sregs)); save_item(NAME(m_ip)); @@ -169,23 +151,28 @@ void v30mz_cpu_device::device_start() save_item(NAME(m_ParityVal)); save_item(NAME(m_seg_prefix)); save_item(NAME(m_seg_prefix_next)); + save_item(NAME(m_pfp)); + save_item(NAME(m_prefetch_queue)); + save_item(NAME(m_prefetch_queue_head)); + save_item(NAME(m_prefetch_queue_tail)); // Register state for debugger -// state_add( NEC_PC, "PC", m_PC ).callimport().callexport().formatstr("%04X"); - state_add( NEC_IP, "IP", m_ip ).callimport().callexport().formatstr("%04X"); - state_add( NEC_SP, "SP", m_regs.w[SP] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_AW, "AW", m_regs.w[AW] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_CW, "CW", m_regs.w[CS] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_DW, "DW", m_regs.w[DW] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_BW, "BW", m_regs.w[BW] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_BP, "BP", m_regs.w[BP] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_IX, "IX", m_regs.w[IX] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_IY, "IY", m_regs.w[IY] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_ES, "ES", m_sregs[ES] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_CS, "CS", m_sregs[CS] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_SS, "SS", m_sregs[SS] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_DS, "DS", m_sregs[DS] ).callimport().callexport().formatstr("%04X"); - state_add( NEC_VECTOR, "V", m_int_vector).callimport().callexport().formatstr("%02X"); + state_add(NEC_IP, "IP", m_ip).callimport().callexport().formatstr("%04X"); + state_add(NEC_SP, "SP", m_regs.w[SP]).callimport().callexport().formatstr("%04X"); + state_add(NEC_AW, "AW", m_regs.w[AW]).callimport().callexport().formatstr("%04X"); + state_add(NEC_BW, "BW", m_regs.w[BW]).callimport().callexport().formatstr("%04X"); + state_add(NEC_CW, "CW", m_regs.w[CW]).callimport().callexport().formatstr("%04X"); + state_add(NEC_DW, "DW", m_regs.w[DW]).callimport().callexport().formatstr("%04X"); + state_add(NEC_BP, "BP", m_regs.w[BP]).callimport().callexport().formatstr("%04X"); + state_add(NEC_IX, "IX", m_regs.w[IX]).callimport().callexport().formatstr("%04X"); + state_add(NEC_IY, "IY", m_regs.w[IY]).callimport().callexport().formatstr("%04X"); + state_add(NEC_PS, "PS", m_sregs[PS]).callimport().callexport().formatstr("%04X"); + state_add(NEC_SS, "SS", m_sregs[SS]).callimport().callexport().formatstr("%04X"); + state_add(NEC_DS0, "DS0", m_sregs[DS0]).callimport().callexport().formatstr("%04X"); + state_add(NEC_DS1, "DS1", m_sregs[DS1]).callimport().callexport().formatstr("%04X"); + state_add(NEC_FLAGS, "PSW", m_debugger_temp).callimport().callexport().formatstr("%04X"); + state_add(NEC_VECTOR, "V", m_int_vector).callimport().callexport().formatstr("%02X"); + state_add(NEC_PFP, "PFP", m_pfp).callimport().callexport().formatstr("%04X"); state_add(STATE_GENPC, "GENPC", m_pc).callexport().formatstr("%05X"); state_add(STATE_GENPCBASE, "CURPC", m_pc).callexport().formatstr("%05X"); @@ -195,18 +182,40 @@ void v30mz_cpu_device::device_start() } +void v30mz_cpu_device::state_import(const device_state_entry &entry) +{ + switch (entry.index()) + { + case NEC_FLAGS: + expand_flags(m_debugger_temp); + break; + } +} + + +void v30mz_cpu_device::state_export(const device_state_entry &entry) +{ + switch (entry.index()) + { + case NEC_FLAGS: + m_debugger_temp = compress_flags(); + break; + } +} + + void v30mz_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const { switch (entry.index()) { case STATE_GENPC: case STATE_GENPCBASE: - str = string_format("%08X", ( m_sregs[CS] << 4 ) + m_ip); + str = string_format("%08X", (m_sregs[PS] << 4) + m_ip); break; case STATE_GENFLAGS: { - uint16_t flags = CompressFlags(); + uint16_t flags = compress_flags(); str = string_format("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", flags & 0x8000 ? 'M':'.', flags & 0x4000 ? '?':'.', @@ -222,7 +231,7 @@ void v30mz_cpu_device::state_string_export(const device_state_entry &entry, std: flags & 0x0010 ? 'A':'.', flags & 0x0008 ? '?':'.', flags & 0x0004 ? 'P':'.', - flags & 0x0002 ? 'N':'.', + flags & 0x0002 ? '?':'.', flags & 0x0001 ? 'C':'.'); } break; @@ -242,11 +251,12 @@ void v30mz_cpu_device::device_reset() m_regs.w[BP] = 0; m_regs.w[IX] = 0; m_regs.w[IY] = 0; - m_sregs[ES] = 0; - m_sregs[CS] = 0xffff; + m_sregs[DS1] = 0; + m_sregs[PS] = 0xffff; m_sregs[SS] = 0; - m_sregs[DS] = 0; + m_sregs[DS0] = 0; m_ip = 0; + m_pfp = 0; m_SignVal = 0; m_AuxVal = 0; m_OverVal = 0; @@ -264,44 +274,77 @@ void v30mz_cpu_device::device_reset() m_prefix_base = 0; m_seg_prefix = false; m_seg_prefix_next = false; - m_ea = 0; + m_ea_seg = 0; m_eo = 0; - m_e16 = 0; m_modrm = 0; m_dst = 0; m_src = 0; + init_prefetch(); } -inline uint32_t v30mz_cpu_device::pc() +uint32_t v30mz_cpu_device::pc() { - m_pc = ( m_sregs[CS] << 4 ) + m_ip; + m_pc = (m_sregs[PS] << 4) + m_ip; return m_pc; } -inline uint8_t v30mz_cpu_device::read_byte(uint32_t addr) +void v30mz_cpu_device::read_prefetch() +{ + uint8_t data = m_cache.read_byte((m_sregs[PS] << 4) + m_pfp); + m_prefetch_queue[m_prefetch_queue_head] = data; + m_prefetch_queue_head = (m_prefetch_queue_head + 1) % PREFETCH_MAX_SIZE; + m_pfp++; +} + + +void v30mz_cpu_device::init_prefetch() { - return m_program.read_byte(addr); + m_pfp = m_ip; + m_prefetch_queue_tail = 0; + m_prefetch_queue_head = 0; + m_prefetch_fill_needed = true; + if (m_ip & 1) + clk(1); } -inline uint16_t v30mz_cpu_device::read_word(uint32_t addr) +inline uint8_t v30mz_cpu_device::read_byte(uint16_t segment, uint16_t addr) { - return m_program.read_byte(addr) | ( m_program.read_byte(addr+1) << 8 ); + return m_program.read_byte((segment << 4) + addr); } -inline void v30mz_cpu_device::write_byte(uint32_t addr, uint8_t data) +inline uint16_t v30mz_cpu_device::read_word(uint16_t segment, uint16_t addr) { - m_program.write_byte(addr, data); + if (addr & 1) { + // penalty cycle when reading from an unaligned address + clk(1); + return m_program.read_byte((segment << 4)+ addr) | + (m_program.read_byte((segment << 4) + ((addr + 1) & 0xffff)) << 8); + } else { + return m_program.read_word((segment << 4) + addr); + } } -inline void v30mz_cpu_device::write_word(uint32_t addr, uint16_t data) +inline void v30mz_cpu_device::write_byte(uint16_t segment, uint16_t addr, uint8_t data) { - m_program.write_byte( addr, data & 0xff ); - m_program.write_byte( addr + 1, data >> 8 ); + m_program.write_byte((segment << 4) + addr, data); +} + + +inline void v30mz_cpu_device::write_word(uint16_t segment, uint16_t addr, uint16_t data) +{ + if (addr & 1) { + m_program.write_byte((segment << 4) + addr, data); + m_program.write_byte((segment << 4) + ((addr + 1) & 0xffff), data >> 8); + // penalty cycle when writing to an unaligned address + clk(1); + } else { + m_program.write_word((segment << 4) + addr, data); + } } @@ -311,15 +354,35 @@ inline uint8_t v30mz_cpu_device::read_port(uint16_t port) } +inline uint16_t v30mz_cpu_device::read_port_word(uint16_t port) +{ + if (port & 1) + // penalty cycle when reading from an unaligned address + clk(1); + return m_io.read_word_unaligned(port); +} + + inline void v30mz_cpu_device::write_port(uint16_t port, uint8_t data) { m_io.write_byte(port, data); } +inline void v30mz_cpu_device::write_port_word(uint16_t port, uint16_t data) +{ + if (port & 1) + // penalty cycle when writing to an unaligned address + clk(1); + m_io.write_word_unaligned(port, data); +} + + inline uint8_t v30mz_cpu_device::fetch_op() { - uint8_t data = m_cache.read_byte( pc() ); + uint8_t data = m_prefetch_queue[m_prefetch_queue_tail]; + m_prefetch_queue_tail = (m_prefetch_queue_tail + 1) % PREFETCH_MAX_SIZE; + read_prefetch(); m_ip++; return data; } @@ -327,7 +390,9 @@ inline uint8_t v30mz_cpu_device::fetch_op() inline uint8_t v30mz_cpu_device::fetch() { - uint8_t data = m_cache.read_byte( pc() ); + uint8_t data = m_prefetch_queue[m_prefetch_queue_tail]; + m_prefetch_queue_tail = (m_prefetch_queue_tail + 1) % PREFETCH_MAX_SIZE; + read_prefetch(); m_ip++; return data; } @@ -336,7 +401,7 @@ inline uint8_t v30mz_cpu_device::fetch() inline uint16_t v30mz_cpu_device::fetch_word() { uint16_t data = fetch(); - data |= ( fetch() << 8 ); + data |= (fetch() << 8); return data; } @@ -351,11 +416,11 @@ inline uint8_t v30mz_cpu_device::repx_op() { case 0x26: seg_prefix = true; - seg = ES; + seg = DS1; break; case 0x2e: seg_prefix = true; - seg = CS; + seg = PS; break; case 0x36: seg_prefix = true; @@ -363,438 +428,430 @@ inline uint8_t v30mz_cpu_device::repx_op() break; case 0x3e: seg_prefix = true; - seg = DS; + seg = DS0; break; } - if ( seg_prefix ) + if (seg_prefix) { m_seg_prefix = true; m_seg_prefix_next = true; - m_prefix_base = m_sregs[seg] << 4; + m_prefix_base = m_sregs[seg]; next = fetch_op(); - CLK(2); + clk(2); } return next; } -inline void v30mz_cpu_device::CLK(uint32_t cycles) +inline void v30mz_cpu_device::clk(uint32_t cycles) { m_icount -= cycles; } -inline void v30mz_cpu_device::CLKM(uint32_t cycles_reg, uint32_t cycles_mem) +inline void v30mz_cpu_device::clkm(uint32_t cycles_reg, uint32_t cycles_mem) { - m_icount -= ( m_modrm >= 0xc0 ) ? cycles_reg : cycles_mem; + m_icount -= (m_modrm >= 0xc0) ? cycles_reg : cycles_mem; } -inline uint32_t v30mz_cpu_device::default_base(int seg) +inline uint16_t v30mz_cpu_device::default_base(int seg) { - if ( m_seg_prefix && (seg==DS || seg==SS) ) + if (m_seg_prefix && (seg==DS0 || seg==SS)) { return m_prefix_base; } else { - return m_sregs[seg] << 4; + return m_sregs[seg]; } } -inline uint32_t v30mz_cpu_device::get_ea() +inline void v30mz_cpu_device::get_ea() { - switch( m_modrm & 0xc7 ) + switch (m_modrm & 0xc7) { case 0x00: m_eo = m_regs.w[BW] + m_regs.w[IX]; - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); + clk(1); break; case 0x01: m_eo = m_regs.w[BW] + m_regs.w[IY]; - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); + clk(1); break; case 0x02: m_eo = m_regs.w[BP] + m_regs.w[IX]; - m_ea = default_base(SS) + m_eo; + m_ea_seg = default_base(SS); + clk(1); break; case 0x03: m_eo = m_regs.w[BP] + m_regs.w[IY]; - m_ea = default_base(SS) + m_eo; + m_ea_seg = default_base(SS); + clk(1); break; case 0x04: m_eo = m_regs.w[IX]; - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); break; case 0x05: m_eo = m_regs.w[IY]; - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); break; case 0x06: m_eo = fetch_word(); - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); break; case 0x07: m_eo = m_regs.w[BW]; - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); break; case 0x40: m_eo = m_regs.w[BW] + m_regs.w[IX] + (int8_t)fetch(); - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); + clk(1); break; case 0x41: m_eo = m_regs.w[BW] + m_regs.w[IY] + (int8_t)fetch(); - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); + clk(1); break; case 0x42: m_eo = m_regs.w[BP] + m_regs.w[IX] + (int8_t)fetch(); - m_ea = default_base(SS) + m_eo; + m_ea_seg = default_base(SS); + clk(1); break; case 0x43: m_eo = m_regs.w[BP] + m_regs.w[IY] + (int8_t)fetch(); - m_ea = default_base(SS) + m_eo; + m_ea_seg = default_base(SS); + clk(1); break; case 0x44: m_eo = m_regs.w[IX] + (int8_t)fetch(); - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); break; case 0x45: m_eo = m_regs.w[IY] + (int8_t)fetch(); - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); break; case 0x46: m_eo = m_regs.w[BP] + (int8_t)fetch(); - m_ea = default_base(SS) + m_eo; + m_ea_seg = default_base(SS); break; case 0x47: m_eo = m_regs.w[BW] + (int8_t)fetch(); - m_ea = default_base(DS) + m_eo; + m_ea_seg = default_base(DS0); break; case 0x80: - m_e16 = fetch_word(); - m_eo = m_regs.w[BW] + m_regs.w[IX] + (int16_t)m_e16; - m_ea = default_base(DS) + m_eo; + m_eo = m_regs.w[BW] + m_regs.w[IX] + (int16_t)fetch_word(); + m_ea_seg = default_base(DS0); + clk(1); break; case 0x81: - m_e16 = fetch_word(); - m_eo = m_regs.w[BW] + m_regs.w[IY] + (int16_t)m_e16; - m_ea = default_base(DS) + m_eo; + m_eo = m_regs.w[BW] + m_regs.w[IY] + (int16_t)fetch_word(); + m_ea_seg = default_base(DS0); + clk(1); break; case 0x82: - m_e16 = fetch_word(); - m_eo = m_regs.w[BP] + m_regs.w[IX] + (int16_t)m_e16; - m_ea = default_base(SS) + m_eo; + m_eo = m_regs.w[BP] + m_regs.w[IX] + (int16_t)fetch_word(); + m_ea_seg = default_base(SS); + clk(1); break; case 0x83: - m_e16 = fetch_word(); - m_eo = m_regs.w[BP] + m_regs.w[IY] + (int16_t)m_e16; - m_ea = default_base(SS) + m_eo; + m_eo = m_regs.w[BP] + m_regs.w[IY] + (int16_t)fetch_word(); + m_ea_seg = default_base(SS); + clk(1); break; case 0x84: - m_e16 = fetch_word(); - m_eo = m_regs.w[IX] + (int16_t)m_e16; - m_ea = default_base(DS) + m_eo; + m_eo = m_regs.w[IX] + (int16_t)fetch_word(); + m_ea_seg = default_base(DS0); break; case 0x85: - m_e16 = fetch_word(); - m_eo = m_regs.w[IY] + (int16_t)m_e16; - m_ea = default_base(DS) + m_eo; + m_eo = m_regs.w[IY] + (int16_t)fetch_word(); + m_ea_seg = default_base(DS0); break; case 0x86: - m_e16 = fetch_word(); - m_eo = m_regs.w[BP] + (int16_t)m_e16; - m_ea = default_base(SS) + m_eo; + m_eo = m_regs.w[BP] + (int16_t)fetch_word(); + m_ea_seg = default_base(SS); break; case 0x87: - m_e16 = fetch_word(); - m_eo = m_regs.w[BW] + (int16_t)m_e16; - m_ea = default_base(DS) + m_eo; + m_eo = m_regs.w[BW] + (int16_t)fetch_word(); + m_ea_seg = default_base(DS0); break; } - - return m_ea; } -inline void v30mz_cpu_device::PutbackRMByte(uint8_t data) +inline void v30mz_cpu_device::store_ea_rm_byte(uint8_t data) { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = data; + m_regs.b[m_Mod_RM.RM.b[m_modrm]] = data; } else { - write_byte( m_ea, data ); + write_byte(m_ea_seg, m_eo, data); } } -inline void v30mz_cpu_device::PutbackRMWord(uint16_t data) +inline void v30mz_cpu_device::store_ea_rm_word(uint16_t data) { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = data; + m_regs.w[m_Mod_RM.RM.w[m_modrm]] = data; } else { - write_word( m_ea, data ); + write_word(m_ea_seg, m_eo, data); } } -inline void v30mz_cpu_device::PutImmRMWord() + +inline void v30mz_cpu_device::put_imm_rm_word() { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = fetch_word(); + m_regs.w[m_Mod_RM.RM.w[m_modrm]] = fetch_word(); } else { - uint32_t addr = get_ea(); - write_word( addr, fetch_word() ); + get_ea(); + write_word(m_ea_seg, m_eo, fetch_word()); } } -inline void v30mz_cpu_device::PutRMWord(uint16_t val) + +inline void v30mz_cpu_device::put_rm_word(uint16_t val) { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ] = val; + m_regs.w[m_Mod_RM.RM.w[m_modrm]] = val; } else { - write_word( get_ea(), val ); + get_ea(); + write_word(m_ea_seg, m_eo, val); } } -inline void v30mz_cpu_device::PutRMByte(uint8_t val) +inline void v30mz_cpu_device::put_rm_byte(uint8_t val) { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = val; + m_regs.b[m_Mod_RM.RM.b[m_modrm]] = val; } else { - write_byte( get_ea(), val ); + get_ea(); + write_byte(m_ea_seg, m_eo, val); } } -inline void v30mz_cpu_device::PutImmRMByte() +inline void v30mz_cpu_device::put_imm_rm_byte() { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ] = fetch(); + m_regs.b[m_Mod_RM.RM.b[m_modrm]] = fetch(); } else { - uint32_t addr = get_ea(); - write_byte( addr, fetch() ); + get_ea(); + write_byte(m_ea_seg, m_eo, fetch()); } } -inline void v30mz_cpu_device::DEF_br8() +inline void v30mz_cpu_device::def_br8() { m_modrm = fetch(); - m_src = RegByte(); - m_dst = GetRMByte(); + m_src = reg_byte(); + m_dst = get_rm_byte(); } -inline void v30mz_cpu_device::DEF_wr16() +inline void v30mz_cpu_device::def_wr16() { m_modrm = fetch(); - m_src = RegWord(); - m_dst = GetRMWord(); + m_src = reg_word(); + m_dst = get_rm_word(); } -inline void v30mz_cpu_device::DEF_r8b() +inline void v30mz_cpu_device::def_r8b() { m_modrm = fetch(); - m_dst = RegByte(); - m_src = GetRMByte(); + m_src = get_rm_byte(); + m_dst = reg_byte(); } -inline void v30mz_cpu_device::DEF_r16w() +inline void v30mz_cpu_device::def_r16w() { m_modrm = fetch(); - m_dst = RegWord(); - m_src = GetRMWord(); + m_src = get_rm_word(); + m_dst = reg_word(); } -inline void v30mz_cpu_device::DEF_ald8() +inline void v30mz_cpu_device::def_ald8() { m_src = fetch(); m_dst = m_regs.b[AL]; } -inline void v30mz_cpu_device::DEF_axd16() +inline void v30mz_cpu_device::def_awd16() { m_src = fetch_word(); m_dst = m_regs.w[AW]; } - -inline void v30mz_cpu_device::RegByte(uint8_t data) +inline void v30mz_cpu_device::reg_byte(uint8_t data) { - m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ] = data; + m_regs.b[m_Mod_RM.reg.b[m_modrm]] = data; } -inline void v30mz_cpu_device::RegWord(uint16_t data) +inline void v30mz_cpu_device::reg_word(uint16_t data) { - m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ] = data; + m_regs.w[m_Mod_RM.reg.w[m_modrm]] = data; } -inline uint8_t v30mz_cpu_device::RegByte() +inline uint8_t v30mz_cpu_device::reg_byte() { - return m_regs.b[ m_Mod_RM.reg.b[ m_modrm ] ]; + return m_regs.b[m_Mod_RM.reg.b[m_modrm]]; } -inline uint16_t v30mz_cpu_device::RegWord() +inline uint16_t v30mz_cpu_device::reg_word() { - return m_regs.w[ m_Mod_RM.reg.w[ m_modrm ] ]; + return m_regs.w[m_Mod_RM.reg.w[m_modrm]]; } -inline uint16_t v30mz_cpu_device::GetRMWord() +inline uint16_t v30mz_cpu_device::get_rm_word() { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - return m_regs.w[ m_Mod_RM.RM.w[ m_modrm ] ]; + return m_regs.w[m_Mod_RM.RM.w[m_modrm]]; } else { - return read_word( get_ea() ); + get_ea(); + return read_word(m_ea_seg, m_eo); } } -inline uint16_t v30mz_cpu_device::GetnextRMWord() +inline uint16_t v30mz_cpu_device::get_next_rm_word() { - uint32_t addr = ( m_ea & 0xf0000 ) | ( ( m_ea + 2 ) & 0xffff ); - - return read_word( addr ); + return read_word(m_ea_seg, m_eo + 2); } -inline uint8_t v30mz_cpu_device::GetRMByte() +inline uint8_t v30mz_cpu_device::get_rm_byte() { - if ( m_modrm >= 0xc0 ) + if (m_modrm >= 0xc0) { - return m_regs.b[ m_Mod_RM.RM.b[ m_modrm ] ]; + return m_regs.b[m_Mod_RM.RM.b[m_modrm]]; } else { - return read_byte( get_ea() ); + get_ea(); + return read_byte(m_ea_seg, m_eo); } } -inline void v30mz_cpu_device::PutMemB(int seg, uint16_t offset, uint8_t data) -{ - write_byte( default_base( seg ) + offset, data); -} - - -inline void v30mz_cpu_device::PutMemW(int seg, uint16_t offset, uint16_t data) -{ - PutMemB( seg, offset, data & 0xff); - PutMemB( seg, offset+1, data >> 8); -} - - -inline uint8_t v30mz_cpu_device::GetMemB(int seg, uint16_t offset) -{ - return read_byte( default_base(seg) + offset ); -} - - -inline uint16_t v30mz_cpu_device::GetMemW(int seg, uint16_t offset) -{ - return GetMemB(seg, offset) | ( GetMemB(seg, offset + 1) << 8 ); -} - - // Setting flags -inline void v30mz_cpu_device::set_CFB(uint32_t x) +inline void v30mz_cpu_device::set_CF_byte(uint32_t x) { m_CarryVal = x & 0x100; } -inline void v30mz_cpu_device::set_CFW(uint32_t x) + +inline void v30mz_cpu_device::set_CF_word(uint32_t x) { m_CarryVal = x & 0x10000; } -inline void v30mz_cpu_device::set_AF(uint32_t x,uint32_t y,uint32_t z) + +inline void v30mz_cpu_device::set_AF(uint32_t x, uint32_t y, uint32_t z) { m_AuxVal = (x ^ (y ^ z)) & 0x10; } + inline void v30mz_cpu_device::set_SF(uint32_t x) { m_SignVal = x; } + inline void v30mz_cpu_device::set_ZF(uint32_t x) { m_ZeroVal = x; } + inline void v30mz_cpu_device::set_PF(uint32_t x) { m_ParityVal = x; } -inline void v30mz_cpu_device::set_SZPF_Byte(uint32_t x) + +inline void v30mz_cpu_device::set_SZPF_byte(uint32_t x) { m_SignVal = m_ZeroVal = m_ParityVal = (int8_t)x; } -inline void v30mz_cpu_device::set_SZPF_Word(uint32_t x) + +inline void v30mz_cpu_device::set_SZPF_word(uint32_t x) { m_SignVal = m_ZeroVal = m_ParityVal = (int16_t)x; } -inline void v30mz_cpu_device::set_OFW_Add(uint32_t x,uint32_t y,uint32_t z) + +inline void v30mz_cpu_device::set_OF_word_add(uint32_t x, uint32_t y, uint32_t z) { m_OverVal = (x ^ y) & (x ^ z) & 0x8000; } -inline void v30mz_cpu_device::set_OFB_Add(uint32_t x,uint32_t y,uint32_t z) + +inline void v30mz_cpu_device::set_OF_byte_add(uint32_t x, uint32_t y, uint32_t z) { m_OverVal = (x ^ y) & (x ^ z) & 0x80; } -inline void v30mz_cpu_device::set_OFW_Sub(uint32_t x,uint32_t y,uint32_t z) + +inline void v30mz_cpu_device::set_OF_word_sub(uint32_t x, uint32_t y, uint32_t z) { m_OverVal = (z ^ y) & (z ^ x) & 0x8000; } -inline void v30mz_cpu_device::set_OFB_Sub(uint32_t x,uint32_t y,uint32_t z) + +inline void v30mz_cpu_device::set_OF_byte_sub(uint32_t x, uint32_t y, uint32_t z) { m_OverVal = (z ^ y) & (z ^ x) & 0x80; } -inline uint16_t v30mz_cpu_device::CompressFlags() const +inline uint16_t v30mz_cpu_device::compress_flags() const { - return (CF ? 1 : 0) + return 0x7002 + | (CF ? 1 : 0) | (PF ? 4 : 0) | (AF ? 0x10 : 0) | (ZF ? 0x40 : 0) @@ -806,7 +863,8 @@ inline uint16_t v30mz_cpu_device::CompressFlags() const | (MD << 15); } -inline void v30mz_cpu_device::ExpandFlags(uint16_t f) + +inline void v30mz_cpu_device::expand_flags(uint16_t f) { m_CarryVal = (f) & 1; m_ParityVal = !((f) & 4); @@ -820,127 +878,139 @@ inline void v30mz_cpu_device::ExpandFlags(uint16_t f) m_MF = ((f) & 0x8000) == 0x8000; } + inline void v30mz_cpu_device::i_insb() { - PutMemB( ES, m_regs.w[IY], read_port( m_regs.w[DW] ) ); + write_byte(m_sregs[DS1], m_regs.w[IY], read_port(m_regs.w[DW])); m_regs.w[IY] += -2 * m_DF + 1; - CLK(6); + clk(6); } + inline void v30mz_cpu_device::i_insw() { - PutMemB( ES, m_regs.w[IY], read_port( m_regs.w[DW] ) ); - PutMemB( ES, (m_regs.w[IY] + 1) & 0xffff, read_port((m_regs.w[DW]+1)&0xffff)); + write_word(m_sregs[DS1], m_regs.w[IY], read_port_word(m_regs.w[DW])); m_regs.w[IY] += -4 * m_DF + 2; - CLK(6); + clk(6); } + inline void v30mz_cpu_device::i_outsb() { - write_port( m_regs.w[DW], GetMemB( DS, m_regs.w[IX] ) ); + write_port(m_regs.w[DW], read_byte(default_base(DS0), m_regs.w[IX])); m_regs.w[IX] += -2 * m_DF + 1; - CLK(7); + clk(7); } + inline void v30mz_cpu_device::i_outsw() { - write_port( m_regs.w[DW], GetMemB( DS, m_regs.w[IX] ) ); - write_port( (m_regs.w[DW]+1)&0xffff, GetMemB( DS, (m_regs.w[IX]+1)&0xffff ) ); + write_port_word(m_regs.w[DW], read_word(default_base(DS0), m_regs.w[IX])); m_regs.w[IX] += -4 * m_DF + 2; - CLK(7); + clk(7); } + inline void v30mz_cpu_device::i_movsb() { - uint8_t tmp = GetMemB( DS, m_regs.w[IX] ); - PutMemB( ES, m_regs.w[IY], tmp); + uint8_t tmp = read_byte(default_base(DS0), m_regs.w[IX]); + write_byte(m_sregs[DS1], m_regs.w[IY], tmp); m_regs.w[IY] += -2 * m_DF + 1; m_regs.w[IX] += -2 * m_DF + 1; - CLK(5); + clk(5); } + inline void v30mz_cpu_device::i_movsw() { - uint16_t tmp = GetMemW( DS, m_regs.w[IX] ); - PutMemW( ES, m_regs.w[IY], tmp ); + uint16_t tmp = read_word(default_base(DS0), m_regs.w[IX]); + write_word(m_sregs[DS1], m_regs.w[IY], tmp); m_regs.w[IY] += -4 * m_DF + 2; m_regs.w[IX] += -4 * m_DF + 2; - CLK(5); + clk(5); } + inline void v30mz_cpu_device::i_cmpsb() { - m_src = GetMemB( ES, m_regs.w[IY] ); - m_dst = GetMemB( DS, m_regs.w[IX] ); - SUBB(); + m_src = read_byte(m_sregs[DS1], m_regs.w[IY]); + m_dst = read_byte(default_base(DS0), m_regs.w[IX]); + sub_byte(); m_regs.w[IY] += -2 * m_DF + 1; m_regs.w[IX] += -2 * m_DF + 1; - CLK(6); + clk(6); } + inline void v30mz_cpu_device::i_cmpsw() { - m_src = GetMemW( ES, m_regs.w[IY] ); - m_dst = GetMemW( DS, m_regs.w[IX] ); - SUBW(); + m_src = read_word(m_sregs[DS1], m_regs.w[IY]); + m_dst = read_word(default_base(DS0), m_regs.w[IX]); + sub_word(); m_regs.w[IY] += -4 * m_DF + 2; m_regs.w[IX] += -4 * m_DF + 2; - CLK(6); + clk(6); } + inline void v30mz_cpu_device::i_stosb() { - PutMemB( ES, m_regs.w[IY], m_regs.b[AL] ); + write_byte(m_sregs[DS1], m_regs.w[IY], m_regs.b[AL]); m_regs.w[IY] += -2 * m_DF + 1; - CLK(3); + clk(3); } + inline void v30mz_cpu_device::i_stosw() { - PutMemW( ES, m_regs.w[IY], m_regs.w[AW] ); + write_word(m_sregs[DS1], m_regs.w[IY], m_regs.w[AW]); m_regs.w[IY] += -4 * m_DF + 2; - CLK(3); + clk(3); } + inline void v30mz_cpu_device::i_lodsb() { - m_regs.b[AL] = GetMemB( DS, m_regs.w[IX] ); + m_regs.b[AL] = read_byte(default_base(DS0), m_regs.w[IX]); m_regs.w[IX] += -2 * m_DF + 1; - CLK(3); + clk(3); } + inline void v30mz_cpu_device::i_lodsw() { - m_regs.w[AW] = GetMemW( DS, m_regs.w[IX] ); + m_regs.w[AW] = read_word(default_base(DS0), m_regs.w[IX]); m_regs.w[IX] += -4 * m_DF + 2; - CLK(3); + clk(3); } + inline void v30mz_cpu_device::i_scasb() { - m_src = GetMemB( ES, m_regs.w[IY] ); + m_src = read_byte(m_sregs[DS1], m_regs.w[IY]); m_dst = m_regs.b[AL]; - SUBB(); + sub_byte(); m_regs.w[IY] += -2 * m_DF + 1; - CLK(4); + clk(4); } + inline void v30mz_cpu_device::i_scasw() { - m_src = GetMemW( ES, m_regs.w[IY] ); + m_src = read_word(m_sregs[DS1], m_regs.w[IY]); m_dst = m_regs.w[AW]; - SUBW(); + sub_word(); m_regs.w[IY] += -4 * m_DF + 2; - CLK(4); + clk(4); } inline void v30mz_cpu_device::i_popf() { - uint32_t tmp = POP(); + uint32_t tmp = pop(); - ExpandFlags(tmp); - CLK(3); + expand_flags(tmp); + clk(3); if (m_TF) { m_fire_trap = 1; @@ -948,212 +1018,225 @@ inline void v30mz_cpu_device::i_popf() } -inline void v30mz_cpu_device::ADDB() +inline void v30mz_cpu_device::add_byte() { - uint32_t res = m_dst + m_src; + uint32_t res = (m_dst & 0xff) + (m_src & 0xff); - set_CFB(res); - set_OFB_Add(res,m_src,m_dst); - set_AF(res,m_src,m_dst); - set_SZPF_Byte(res); + set_CF_byte(res); + set_OF_byte_add(res, m_src, m_dst); + set_AF(res, m_src, m_dst); + set_SZPF_byte(res); m_dst = res & 0xff; } -inline void v30mz_cpu_device::ADDW() +inline void v30mz_cpu_device::add_word() { - uint32_t res = m_dst + m_src; + uint32_t res = (m_dst & 0xffff) + (m_src & 0xffff); - set_CFW(res); - set_OFW_Add(res,m_src,m_dst); - set_AF(res,m_src,m_dst); - set_SZPF_Word(res); + set_CF_word(res); + set_OF_word_add(res, m_src, m_dst); + set_AF(res, m_src, m_dst); + set_SZPF_word(res); m_dst = res & 0xffff; } -inline void v30mz_cpu_device::SUBB() +inline void v30mz_cpu_device::sub_byte() { - uint32_t res = m_dst - m_src; + uint32_t res = (m_dst & 0xff) - (m_src & 0xff); - set_CFB(res); - set_OFB_Sub(res,m_src,m_dst); - set_AF(res,m_src,m_dst); - set_SZPF_Byte(res); + set_CF_byte(res); + set_OF_byte_sub(res, m_src, m_dst); + set_AF(res, m_src, m_dst); + set_SZPF_byte(res); m_dst = res & 0xff; } -inline void v30mz_cpu_device::SUBW() +inline void v30mz_cpu_device::sub_word() { - uint32_t res = m_dst - m_src; + uint32_t res = (m_dst & 0xffff) - (m_src & 0xffff); - set_CFW(res); - set_OFW_Sub(res,m_src,m_dst); - set_AF(res,m_src,m_dst); - set_SZPF_Word(res); + set_CF_word(res); + set_OF_word_sub(res, m_src, m_dst); + set_AF(res, m_src, m_dst); + set_SZPF_word(res); m_dst = res & 0xffff; } -inline void v30mz_cpu_device::ORB() +inline void v30mz_cpu_device::or_byte() { m_dst |= m_src; m_CarryVal = m_OverVal = m_AuxVal = 0; - set_SZPF_Byte(m_dst); + set_SZPF_byte(m_dst); } -inline void v30mz_cpu_device::ORW() +inline void v30mz_cpu_device::or_word() { m_dst |= m_src; m_CarryVal = m_OverVal = m_AuxVal = 0; - set_SZPF_Word(m_dst); + set_SZPF_word(m_dst); } -inline void v30mz_cpu_device::ANDB() +inline void v30mz_cpu_device::and_byte() { m_dst &= m_src; m_CarryVal = m_OverVal = m_AuxVal = 0; - set_SZPF_Byte(m_dst); + set_SZPF_byte(m_dst); } -inline void v30mz_cpu_device::ANDW() +inline void v30mz_cpu_device::and_word() { m_dst &= m_src; m_CarryVal = m_OverVal = m_AuxVal = 0; - set_SZPF_Word(m_dst); + set_SZPF_word(m_dst); } -inline void v30mz_cpu_device::XORB() +inline void v30mz_cpu_device::xor_byte() { m_dst ^= m_src; m_CarryVal = m_OverVal = m_AuxVal = 0; - set_SZPF_Byte(m_dst); + set_SZPF_byte(m_dst); } -inline void v30mz_cpu_device::XORW() +inline void v30mz_cpu_device::xor_word() { m_dst ^= m_src; m_CarryVal = m_OverVal = m_AuxVal = 0; - set_SZPF_Word(m_dst); + set_SZPF_word(m_dst); } -inline void v30mz_cpu_device::ROL_BYTE() +inline void v30mz_cpu_device::rol_byte() { m_CarryVal = m_dst & 0x80; - m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); + m_dst = (m_dst << 1) | (CF ? 1 : 0); } -inline void v30mz_cpu_device::ROL_WORD() + +inline void v30mz_cpu_device::rol_word() { m_CarryVal = m_dst & 0x8000; - m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); + m_dst = (m_dst << 1) | (CF ? 1 : 0); } -inline void v30mz_cpu_device::ROR_BYTE() + +inline void v30mz_cpu_device::ror_byte() { m_CarryVal = m_dst & 0x1; m_dst = (m_dst >> 1) | (CF ? 0x80 : 0x00); } -inline void v30mz_cpu_device::ROR_WORD() + +inline void v30mz_cpu_device::ror_word() { m_CarryVal = m_dst & 0x1; m_dst = (m_dst >> 1) + (CF ? 0x8000 : 0x0000); } -inline void v30mz_cpu_device::ROLC_BYTE() + +inline void v30mz_cpu_device::rolc_byte() { - m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); - set_CFB(m_dst); + m_dst = (m_dst << 1) | (CF ? 1 : 0); + set_CF_byte(m_dst); } -inline void v30mz_cpu_device::ROLC_WORD() + +inline void v30mz_cpu_device::rolc_word() { - m_dst = (m_dst << 1) | ( CF ? 1 : 0 ); - set_CFW(m_dst); + m_dst = (m_dst << 1) | (CF ? 1 : 0); + set_CF_word(m_dst); } -inline void v30mz_cpu_device::RORC_BYTE() + +inline void v30mz_cpu_device::rorc_byte() { - m_dst |= ( CF ? 0x100 : 0x00); + m_dst |= (CF ? 0x100 : 0x00); m_CarryVal = m_dst & 0x01; m_dst >>= 1; } -inline void v30mz_cpu_device::RORC_WORD() + +inline void v30mz_cpu_device::rorc_word() { - m_dst |= ( CF ? 0x10000 : 0); + m_dst |= (CF ? 0x10000 : 0); m_CarryVal = m_dst & 0x01; m_dst >>= 1; } -inline void v30mz_cpu_device::SHL_BYTE(uint8_t c) + +inline void v30mz_cpu_device::shl_byte(uint8_t c) { m_icount -= c; m_dst <<= c; - set_CFB(m_dst); - set_SZPF_Byte(m_dst); - PutbackRMByte(m_dst); + set_CF_byte(m_dst); + set_SZPF_byte(m_dst); + store_ea_rm_byte(m_dst); } -inline void v30mz_cpu_device::SHL_WORD(uint8_t c) + +inline void v30mz_cpu_device::shl_word(uint8_t c) { m_icount -= c; m_dst <<= c; - set_CFW(m_dst); - set_SZPF_Word(m_dst); - PutbackRMWord(m_dst); + set_CF_word(m_dst); + set_SZPF_word(m_dst); + store_ea_rm_word(m_dst); } -inline void v30mz_cpu_device::SHR_BYTE(uint8_t c) + +inline void v30mz_cpu_device::shr_byte(uint8_t c) { m_icount -= c; m_dst >>= c-1; m_CarryVal = m_dst & 0x1; m_dst >>= 1; - set_SZPF_Byte(m_dst); - PutbackRMByte(m_dst); + set_SZPF_byte(m_dst); + store_ea_rm_byte(m_dst); } -inline void v30mz_cpu_device::SHR_WORD(uint8_t c) + +inline void v30mz_cpu_device::shr_word(uint8_t c) { m_icount -= c; m_dst >>= c-1; m_CarryVal = m_dst & 0x1; m_dst >>= 1; - set_SZPF_Word(m_dst); - PutbackRMWord(m_dst); + set_SZPF_word(m_dst); + store_ea_rm_word(m_dst); } -inline void v30mz_cpu_device::SHRA_BYTE(uint8_t c) + +inline void v30mz_cpu_device::shra_byte(uint8_t c) { m_icount -= c; m_dst = ((int8_t)m_dst) >> (c-1); m_CarryVal = m_dst & 0x1; m_dst = m_dst >> 1; - set_SZPF_Byte(m_dst); - PutbackRMByte(m_dst); + set_SZPF_byte(m_dst); + store_ea_rm_byte(m_dst); } -inline void v30mz_cpu_device::SHRA_WORD(uint8_t c) + +inline void v30mz_cpu_device::shra_word(uint8_t c) { m_icount -= c; m_dst = ((int16_t)m_dst) >> (c-1); m_CarryVal = m_dst & 0x1; m_dst = m_dst >> 1; - set_SZPF_Word(m_dst); - PutbackRMWord(m_dst); + set_SZPF_word(m_dst); + store_ea_rm_word(m_dst); } -inline void v30mz_cpu_device::XchgAWReg(uint8_t reg) +inline void v30mz_cpu_device::xchg_AW_reg(uint8_t reg) { uint16_t tmp = m_regs.w[reg]; @@ -1162,60 +1245,61 @@ inline void v30mz_cpu_device::XchgAWReg(uint8_t reg) } -inline void v30mz_cpu_device::IncWordReg(uint8_t reg) +inline void v30mz_cpu_device::inc_word_reg(uint8_t reg) { uint32_t tmp = m_regs.w[reg]; uint32_t tmp1 = tmp+1; m_OverVal = (tmp == 0x7fff); - set_AF(tmp1,tmp,1); - set_SZPF_Word(tmp1); + set_AF(tmp1, tmp, 1); + set_SZPF_word(tmp1); m_regs.w[reg] = tmp1; } -inline void v30mz_cpu_device::DecWordReg(uint8_t reg) +inline void v30mz_cpu_device::dec_word_reg(uint8_t reg) { uint32_t tmp = m_regs.w[reg]; uint32_t tmp1 = tmp-1; m_OverVal = (tmp == 0x8000); - set_AF(tmp1,tmp,1); - set_SZPF_Word(tmp1); + set_AF(tmp1, tmp, 1); + set_SZPF_word(tmp1); m_regs.w[reg] = tmp1; } -inline void v30mz_cpu_device::PUSH(uint16_t data) +inline void v30mz_cpu_device::push(uint16_t data) { m_regs.w[SP] -= 2; - write_word( ( m_sregs[SS] << 4 ) + m_regs.w[SP], data ); + write_word(m_sregs[SS], m_regs.w[SP], data); } -inline uint16_t v30mz_cpu_device::POP() +inline uint16_t v30mz_cpu_device::pop() { - uint16_t data = read_word( ( m_sregs[SS] << 4 ) + m_regs.w[SP] ); + uint16_t data = read_word(m_sregs[SS], m_regs.w[SP]); m_regs.w[SP] += 2; return data; } -inline void v30mz_cpu_device::JMP(bool cond) +inline void v30mz_cpu_device::jmp(bool cond) { int rel = (int)((int8_t)fetch()); if (cond) { m_ip += rel; - CLK(9); + init_prefetch(); + clk(9); } - CLK(1); + clk(1); } -inline void v30mz_cpu_device::ADJ4(int8_t param1,int8_t param2) +inline void v30mz_cpu_device::adj4(int8_t param1, int8_t param2) { if (AF || ((m_regs.b[AL] & 0xf) > 9)) { @@ -1230,18 +1314,18 @@ inline void v30mz_cpu_device::ADJ4(int8_t param1,int8_t param2) m_regs.b[AL] += param2; m_CarryVal = 1; } - set_SZPF_Byte(m_regs.b[AL]); + set_SZPF_byte(m_regs.b[AL]); } -inline void v30mz_cpu_device::ADJB(int8_t param1, int8_t param2) +inline void v30mz_cpu_device::adjb(int8_t param1, int8_t param2) { if (AF || ((m_regs.b[AL] & 0xf) > 9)) { m_regs.b[AL] += param1; m_regs.b[AH] += param2; + m_CarryVal = m_AuxVal; m_AuxVal = 1; - m_CarryVal = 1; } else { @@ -1254,33 +1338,35 @@ inline void v30mz_cpu_device::ADJB(int8_t param1, int8_t param2) void v30mz_cpu_device::interrupt(int int_num) { - PUSH( CompressFlags() ); - CLK(2); + push(compress_flags()); + clk(2); m_TF = m_IF = 0; if (int_num == -1) { - int_num = standard_irq_callback(0); + standard_irq_callback(0); + int_num = m_vector_func(); m_irq_state = CLEAR_LINE; m_pending_irq &= ~INT_IRQ; } - uint16_t dest_off = read_word( int_num * 4 + 0 ); - uint16_t dest_seg = read_word( int_num * 4 + 2 ); + uint16_t dest_off = read_word(0, int_num * 4 + 0); + uint16_t dest_seg = read_word(0, int_num * 4 + 2); - PUSH(m_sregs[CS]); - PUSH(m_ip); + push(m_sregs[PS]); + push(m_ip); m_ip = dest_off; - m_sregs[CS] = dest_seg; + m_sregs[PS] = dest_seg; + init_prefetch(); } -void v30mz_cpu_device::execute_set_input( int inptnum, int state ) +void v30mz_cpu_device::execute_set_input(int inptnum, int state) { if (inptnum == INPUT_LINE_NMI) { - if ( m_nmi_state == state ) + if (m_nmi_state == state) { return; } @@ -1313,9 +1399,9 @@ std::unique_ptr v30mz_cpu_device::create_disassembler() void v30mz_cpu_device::execute_run() { - while(m_icount > 0 ) + while (m_icount > 0) { - if ( m_seg_prefix_next ) + if (m_seg_prefix_next) { m_seg_prefix = true; m_seg_prefix_next = false; @@ -1324,34 +1410,34 @@ void v30mz_cpu_device::execute_run() { m_seg_prefix = false; - /* Dispatch IRQ */ - if ( m_pending_irq && m_no_interrupt == 0 ) + // Dispatch IRQ + if (m_pending_irq && m_no_interrupt == 0) { - if ( m_pending_irq & NMI_IRQ ) + if (m_pending_irq & NMI_IRQ) { - interrupt(NEC_NMI_INT_VECTOR); + interrupt(NMI_INT); m_pending_irq &= ~NMI_IRQ; } - else if ( m_IF ) + else if (m_IF) { - /* the actual vector is retrieved after pushing flags */ - /* and clearing the IF */ + // the actual vector is retrieved after pushing flags + // and clearing the IF interrupt(-1); } } - /* No interrupt allowed between last instruction and this one */ - if ( m_no_interrupt ) + // No interrupt allowed between last instruction and this one + if (m_no_interrupt) { m_no_interrupt--; } - /* trap should allow one instruction to be executed */ - if ( m_fire_trap ) + // trap should allow one instruction to be executed + if (m_fire_trap) { - if ( m_fire_trap >= 2 ) + if (m_fire_trap >= 2) { - interrupt(1); + interrupt(BREAK_INT); m_fire_trap = 0; } else @@ -1361,880 +1447,613 @@ void v30mz_cpu_device::execute_run() } } - debugger_instruction_hook( pc() ); + if (m_prefetch_fill_needed) { + for (int i = 0; i < PREFETCH_QUEUE_SIZE; i++) { + read_prefetch(); + } + m_prefetch_fill_needed = false; + } + + debugger_instruction_hook(pc()); uint8_t op = fetch_op(); - switch(op) + switch (op) { case 0x00: // i_add_br8 - DEF_br8(); - ADDB(); - PutbackRMByte(m_dst); - CLKM(1,3); + def_br8(); + add_byte(); + store_ea_rm_byte(m_dst); + clkm(1,3); break; case 0x01: // i_add_wr16 - DEF_wr16(); - ADDW(); - PutbackRMWord(m_dst); - CLKM(1,3); + def_wr16(); + add_word(); + store_ea_rm_word(m_dst); + clkm(1,3); break; case 0x02: // i_add_r8b - DEF_r8b(); - ADDB(); - RegByte(m_dst); - CLKM(1,2); + def_r8b(); + add_byte(); + reg_byte(m_dst); + clkm(1,2); break; case 0x03: // i_add_r16w - DEF_r16w(); - ADDW(); - RegWord(m_dst); - CLKM(1,2); + def_r16w(); + add_word(); + reg_word(m_dst); + clkm(1,2); break; case 0x04: // i_add_ald8 - DEF_ald8(); - ADDB(); + def_ald8(); + add_byte(); m_regs.b[AL] = m_dst; - CLK(1); + clk(1); break; case 0x05: // i_add_axd16 - DEF_axd16(); - ADDW(); + def_awd16(); + add_word(); m_regs.w[AW] = m_dst; - CLK(1); + clk(1); break; case 0x06: // i_push_es - PUSH(m_sregs[ES]); - CLK(2); + push(m_sregs[DS1]); + clk(2); break; case 0x07: // i_pop_es - m_sregs[ES] = POP(); - CLK(3); + m_sregs[DS1] = pop(); + clk(3); break; case 0x08: // i_or_br8 - DEF_br8(); - ORB(); - PutbackRMByte(m_dst); - CLKM(1,3); + def_br8(); + or_byte(); + store_ea_rm_byte(m_dst); + clkm(1,3); break; case 0x09: // i_or_wr16 - DEF_wr16(); - ORW(); - PutbackRMWord(m_dst); - CLKM(1,3); + def_wr16(); + or_word(); + store_ea_rm_word(m_dst); + clkm(1,3); break; case 0x0a: // i_or_r8b - DEF_r8b(); - ORB(); - RegByte(m_dst); - CLKM(1,2); + def_r8b(); + or_byte(); + reg_byte(m_dst); + clkm(1,2); break; case 0x0b: // i_or_r16w - DEF_r16w(); - ORW(); - RegWord(m_dst); - CLKM(1,2); + def_r16w(); + or_word(); + reg_word(m_dst); + clkm(1,2); break; case 0x0c: // i_or_ald8 - DEF_ald8(); - ORB(); + def_ald8(); + or_byte(); m_regs.b[AL] = m_dst; - CLK(1); + clk(1); break; case 0x0d: // i_or_axd16 - DEF_axd16(); - ORW(); + def_awd16(); + or_word(); m_regs.w[AW] = m_dst; - CLK(1); + clk(1); break; case 0x0e: // i_push_cs - PUSH(m_sregs[CS]); - CLK(2); + push(m_sregs[PS]); + clk(2); break; case 0x0f: // i_pre_nec - { - uint32_t tmp, tmp2; - - switch ( fetch() ) - { - case 0x10: /* Test */ - m_modrm = fetch(); - tmp = GetRMByte(); - tmp2 = m_regs.b[CL] & 0x7; - m_ZeroVal = (tmp & (1<>4)*10 + (tmp&0xf); - int v2 = (tmp2>>4)*10 + (tmp2&0xf); - int result = v1 + v2 + m_CarryVal; - m_CarryVal = result > 99 ? 1 : 0; - result = result % 100; - v1 = ((result/10)<<4) | (result % 10); - PutMemB(ES, di,v1); - if (v1) - { - m_ZeroVal = 1; - } - si++; - di++; - } - } - break; - case 0x22: - { - int count = (m_regs.b[CL]+1)/2; - uint16_t di = m_regs.w[IY]; - uint16_t si = m_regs.w[IX]; - if (m_seg_prefix) - { - logerror("%s: %06x: Warning: seg_prefix defined for sub4s\n", tag(), pc()); - } - m_ZeroVal = m_CarryVal = 0; - for (int i=0; i>4)*10 + (tmp&0xf); - int v2 = (tmp2>>4)*10 + (tmp2&0xf); - if (v1 < (v2+m_CarryVal)) - { - v1+=100; - result = v1-(v2+m_CarryVal); - m_CarryVal = 1; - } - else - { - result = v1-(v2+m_CarryVal); - m_CarryVal = 0; - } - v1 = ((result/10)<<4) | (result % 10); - PutMemB(ES, di,v1); - if (v1) - { - m_ZeroVal = 1; - } - si++; - di++; - } - } - break; - case 0x26: - { - int count = (m_regs.b[CL]+1)/2; - uint16_t di = m_regs.w[IY]; - uint16_t si = m_regs.w[IX]; - if (m_seg_prefix) - { - logerror("%s: %06x: Warning: seg_prefix defined for cmp4s\n", tag(), pc()); - } - m_ZeroVal = m_CarryVal = 0; - for (int i=0; i>4)*10 + (tmp&0xf); - int v2 = (tmp2>>4)*10 + (tmp2&0xf); - if (v1 < (v2+m_CarryVal)) - { - v1+=100; - result = v1-(v2+m_CarryVal); - m_CarryVal = 1; - } - else - { - result = v1-(v2+m_CarryVal); - m_CarryVal = 0; - } - v1 = ((result/10)<<4) | (result % 10); - if (v1) - { - m_ZeroVal = 1; - } - si++; - di++; - } - } - break; - case 0x28: - m_modrm = fetch(); - tmp = GetRMByte(); - tmp <<= 4; - tmp |= m_regs.b[AL] & 0xf; - m_regs.b[AL] = (m_regs.b[AL] & 0xf0) | ((tmp>>8)&0xf); - tmp &= 0xff; - PutbackRMByte(tmp); - CLKM(9,15); - break; - case 0x2a: - m_modrm = fetch(); - tmp = GetRMByte(); - tmp2 = (m_regs.b[AL] & 0xf)<<4; - m_regs.b[AL] = (m_regs.b[AL] & 0xf0) | (tmp&0xf); - tmp = tmp2 | (tmp>>4); - PutbackRMByte(tmp); - CLKM(13,19); - break; - case 0x31: - m_modrm = fetch(); m_modrm = 0; logerror("%s: %06x: Unimplemented bitfield INS\n", tag(), pc()); break; - case 0x33: - m_modrm = fetch(); m_modrm = 0; logerror("%s: %06x: Unimplemented bitfield EXT\n", tag(), pc()); break; - case 0x92: /* V25/35 FINT */ - CLK(2); - break; - case 0xe0: - m_modrm = fetch(); - m_modrm = 0; - logerror("%s: %06x: V33 unimplemented BRKXA (break to expansion address)\n", tag(), pc()); - break; - case 0xf0: - m_modrm = fetch(); - m_modrm = 0; - logerror("%s: %06x: V33 unimplemented RETXA (return from expansion address)\n", tag(), pc()); - break; - case 0xff: - m_modrm = fetch(); - m_modrm = 0; - logerror("%s: %06x: unimplemented BRKEM (break to 8080 emulation mode)\n", tag(), pc()); - break; - default: - logerror("%s: %06x: Unknown V20 instruction\n", tag(), pc()); - break; - } - } + clk(1); break; case 0x10: // i_adc_br8 - DEF_br8(); + def_br8(); m_src += CF ? 1 : 0; - ADDB(); - PutbackRMByte(m_dst); - CLKM(1,3); + add_byte(); + store_ea_rm_byte(m_dst); + clkm(1,3); break; case 0x11: // i_adc_wr16 - DEF_wr16(); + def_wr16(); m_src += CF ? 1 : 0; - ADDW(); - PutbackRMWord(m_dst); - CLKM(1,3); + add_word(); + store_ea_rm_word(m_dst); + clkm(1,3); break; case 0x12: // i_adc_r8b - DEF_r8b(); + def_r8b(); m_src += CF ? 1 : 0; - ADDB(); - RegByte(m_dst); - CLKM(1,2); + add_byte(); + reg_byte(m_dst); + clkm(1,2); break; case 0x13: // i_adc_r16w - DEF_r16w(); + def_r16w(); m_src += CF ? 1 : 0; - ADDW(); - RegWord(m_dst); - CLKM(1,2); + add_word(); + reg_word(m_dst); + clkm(1,2); break; case 0x14: // i_adc_ald8 - DEF_ald8(); + def_ald8(); m_src += CF ? 1 : 0; - ADDB(); + add_byte(); m_regs.b[AL] = m_dst; - CLK(1); + clk(1); break; case 0x15: // i_adc_axd16 - DEF_axd16(); + def_awd16(); m_src += CF ? 1 : 0; - ADDW(); + add_word(); m_regs.w[AW] = m_dst; - CLK(1); + clk(1); break; case 0x16: // i_push_ss - PUSH(m_sregs[SS]); - CLK(2); + push(m_sregs[SS]); + clk(2); break; case 0x17: // i_pop_ss - m_sregs[SS] = POP(); - CLK(3); + m_sregs[SS] = pop(); + clk(3); m_no_interrupt = 1; break; case 0x18: // i_sbb_br8 - DEF_br8(); + def_br8(); m_src += CF ? 1 : 0; - SUBB(); - PutbackRMByte(m_dst); - CLKM(1,3); + sub_byte(); + store_ea_rm_byte(m_dst); + clkm(1,3); break; case 0x19: // i_sbb_wr16 - DEF_wr16(); + def_wr16(); m_src += CF ? 1 : 0; - SUBW(); - PutbackRMWord(m_dst); - CLKM(1,3); + sub_word(); + store_ea_rm_word(m_dst); + clkm(1,3); break; case 0x1a: // i_sbb_r8b - DEF_r8b(); + def_r8b(); m_src += CF ? 1 : 0; - SUBB(); - RegByte(m_dst); - CLKM(1,2); + sub_byte(); + reg_byte(m_dst); + clkm(1,2); break; case 0x1b: // i_sbb_r16w - DEF_r16w(); + def_r16w(); m_src += CF ? 1 : 0; - SUBW(); - RegWord(m_dst); - CLKM(1,2); + sub_word(); + reg_word(m_dst); + clkm(1,2); break; case 0x1c: // i_sbb_ald8 - DEF_ald8(); + def_ald8(); m_src += CF ? 1 : 0; - SUBB(); + sub_byte(); m_regs.b[AL] = m_dst; - CLK(1); + clk(1); break; case 0x1d: // i_sbb_axd16 - DEF_axd16(); + def_awd16(); m_src += CF ? 1 : 0; - SUBW(); + sub_word(); m_regs.w[AW] = m_dst; - CLK(1); + clk(1); break; case 0x1e: // i_push_ds - PUSH(m_sregs[DS]); - CLK(2); + push(m_sregs[DS0]); + clk(2); break; case 0x1f: // i_pop_ds - m_sregs[DS] = POP(); - CLK(3); + m_sregs[DS0] = pop(); + clk(3); break; case 0x20: // i_and_br8 - DEF_br8(); - ANDB(); - PutbackRMByte(m_dst); - CLKM(1,3); + def_br8(); + and_byte(); + store_ea_rm_byte(m_dst); + clkm(1,3); break; case 0x21: // i_and_wr16 - DEF_wr16(); - ANDW(); - PutbackRMWord(m_dst); - CLKM(1,3); + def_wr16(); + and_word(); + store_ea_rm_word(m_dst); + clkm(1,3); break; case 0x22: // i_and_r8b - DEF_r8b(); - ANDB(); - RegByte(m_dst); - CLKM(1,2); + def_r8b(); + and_byte(); + reg_byte(m_dst); + clkm(1,2); break; case 0x23: // i_and_r16w - DEF_r16w(); - ANDW(); - RegWord(m_dst); - CLKM(1,2); + def_r16w(); + and_word(); + reg_word(m_dst); + clkm(1,2); break; case 0x24: // i_and_ald8 - DEF_ald8(); - ANDB(); + def_ald8(); + and_byte(); m_regs.b[AL] = m_dst; - CLK(1); + clk(1); break; case 0x25: // i_and_axd16 - DEF_axd16(); - ANDW(); + def_awd16(); + and_word(); m_regs.w[AW] = m_dst; - CLK(1); + clk(1); break; case 0x26: // i_es m_seg_prefix_next = true; - m_prefix_base = m_sregs[ES]<<4; - CLK(1); + m_prefix_base = m_sregs[DS1]; + clk(1); break; case 0x27: // i_daa - ADJ4(6,0x60); - CLK(10); + adj4(6,0x60); + clk(10); break; case 0x28: // i_sub_br8 - DEF_br8(); - SUBB(); - PutbackRMByte(m_dst); - CLKM(1,3); + def_br8(); + sub_byte(); + store_ea_rm_byte(m_dst); + clkm(1,3); break; case 0x29: // i_sub_wr16 - DEF_wr16(); - SUBW(); - PutbackRMWord(m_dst); - CLKM(1,3); + def_wr16(); + sub_word(); + store_ea_rm_word(m_dst); + clkm(1,3); break; case 0x2a: // i_sub_r8b - DEF_r8b(); - SUBB(); - RegByte(m_dst); - CLKM(1,2); + def_r8b(); + sub_byte(); + reg_byte(m_dst); + clkm(1,2); break; case 0x2b: // i_sub_r16w - DEF_r16w(); - SUBW(); - RegWord(m_dst); - CLKM(1,2); + def_r16w(); + sub_word(); + reg_word(m_dst); + clkm(1,2); break; case 0x2c: // i_sub_ald8 - DEF_ald8(); - SUBB(); + def_ald8(); + sub_byte(); m_regs.b[AL] = m_dst; - CLK(1); + clk(1); break; case 0x2d: // i_sub_axd16 - DEF_axd16(); - SUBW(); + def_awd16(); + sub_word(); m_regs.w[AW] = m_dst; - CLK(1); + clk(1); break; case 0x2e: // i_cs m_seg_prefix_next = true; - m_prefix_base = m_sregs[CS]<<4; - CLK(1); + m_prefix_base = m_sregs[PS]; + clk(1); break; case 0x2f: // i_das - ADJ4(-6,-0x60); - CLK(10); + adj4(-6, -0x60); + clk(10); break; case 0x30: // i_xor_br8 - DEF_br8(); - XORB(); - PutbackRMByte(m_dst); - CLKM(1,3); + def_br8(); + xor_byte(); + store_ea_rm_byte(m_dst); + clkm(1,3); break; case 0x31: // i_xor_wr16 - DEF_wr16(); - XORW(); - PutbackRMWord(m_dst); - CLKM(1,3); + def_wr16(); + xor_word(); + store_ea_rm_word(m_dst); + clkm(1,3); break; case 0x32: // i_xor_r8b - DEF_r8b(); - XORB(); - RegByte(m_dst); - CLKM(1,2); + def_r8b(); + xor_byte(); + reg_byte(m_dst); + clkm(1,2); break; case 0x33: // i_xor_r16w - DEF_r16w(); - XORW(); - RegWord(m_dst); - CLKM(1,2); + def_r16w(); + xor_word(); + reg_word(m_dst); + clkm(1,2); break; case 0x34: // i_xor_ald8 - DEF_ald8(); - XORB(); + def_ald8(); + xor_byte(); m_regs.b[AL] = m_dst; - CLK(1); + clk(1); break; case 0x35: // i_xor_axd16 - DEF_axd16(); - XORW(); + def_awd16(); + xor_word(); m_regs.w[AW] = m_dst; - CLK(1); + clk(1); break; case 0x36: // i_ss m_seg_prefix_next = true; - m_prefix_base = m_sregs[SS]<<4; - CLK(1); + m_prefix_base = m_sregs[SS]; + clk(1); break; case 0x37: // i_aaa - ADJB(6, (m_regs.b[AL] > 0xf9) ? 2 : 1); - CLK(9); + adjb(6, (m_regs.b[AL] > 0xf9) ? 2 : 1); + clk(9); break; case 0x38: // i_cmp_br8 - DEF_br8(); - SUBB(); - CLKM(1,2); + def_br8(); + sub_byte(); + clkm(1,2); break; case 0x39: // i_cmp_wr16 - DEF_wr16(); - SUBW(); - CLKM(1,2); + def_wr16(); + sub_word(); + clkm(1,2); break; case 0x3a: // i_cmp_r8b - DEF_r8b(); - SUBB(); - CLKM(1,2); + def_r8b(); + sub_byte(); + clkm(1,2); break; case 0x3b: // i_cmp_r16w - DEF_r16w(); - SUBW(); - CLKM(1,2); + def_r16w(); + sub_word(); + clkm(1,2); break; case 0x3c: // i_cmp_ald8 - DEF_ald8(); - SUBB(); - CLK(1); + def_ald8(); + sub_byte(); + clk(1); break; case 0x3d: // i_cmp_axd16 - DEF_axd16(); - SUBW(); - CLK(1); + def_awd16(); + sub_word(); + clk(1); break; case 0x3e: // i_ds m_seg_prefix_next = true; - m_prefix_base = m_sregs[DS]<<4; - CLK(1); + m_prefix_base = m_sregs[DS0]; + clk(1); break; case 0x3f: // i_aas - ADJB(-6, (m_regs.b[AL] < 6) ? -2 : -1); - CLK(9); + adjb(-6, (m_regs.b[AL] < 6) ? -2 : -1); + clk(9); break; case 0x40: // i_inc_ax - IncWordReg(AW); - CLK(1); + inc_word_reg(AW); + clk(1); break; case 0x41: // i_inc_cx - IncWordReg(CW); - CLK(1); + inc_word_reg(CW); + clk(1); break; case 0x42: // i_inc_dx - IncWordReg(DW); - CLK(1); + inc_word_reg(DW); + clk(1); break; case 0x43: // i_inc_bx - IncWordReg(BW); - CLK(1); + inc_word_reg(BW); + clk(1); break; case 0x44: // i_inc_sp - IncWordReg(SP); - CLK(1); + inc_word_reg(SP); + clk(1); break; case 0x45: // i_inc_bp - IncWordReg(BP); - CLK(1); + inc_word_reg(BP); + clk(1); break; case 0x46: // i_inc_si - IncWordReg(IX); - CLK(1); + inc_word_reg(IX); + clk(1); break; case 0x47: // i_inc_di - IncWordReg(IY); - CLK(1); + inc_word_reg(IY); + clk(1); break; case 0x48: // i_dec_ax - DecWordReg(AW); - CLK(1); + dec_word_reg(AW); + clk(1); break; case 0x49: // i_dec_cx - DecWordReg(CW); - CLK(1); + dec_word_reg(CW); + clk(1); break; case 0x4a: // i_dec_dx - DecWordReg(DW); - CLK(1); + dec_word_reg(DW); + clk(1); break; case 0x4b: // i_dec_bx - DecWordReg(BW); - CLK(1); + dec_word_reg(BW); + clk(1); break; case 0x4c: // i_dec_sp - DecWordReg(SP); - CLK(1); + dec_word_reg(SP); + clk(1); break; case 0x4d: // i_dec_bp - DecWordReg(BP); - CLK(1); + dec_word_reg(BP); + clk(1); break; case 0x4e: // i_dec_si - DecWordReg(IX); - CLK(1); + dec_word_reg(IX); + clk(1); break; case 0x4f: // i_dec_di - DecWordReg(IY); - CLK(1); + dec_word_reg(IY); + clk(1); break; case 0x50: // i_push_ax - PUSH(m_regs.w[AW]); - CLK(1); + push(m_regs.w[AW]); + clk(1); break; case 0x51: // i_push_cx - PUSH(m_regs.w[CW]); - CLK(1); + push(m_regs.w[CW]); + clk(1); break; case 0x52: // i_push_dx - PUSH(m_regs.w[DW]); - CLK(1); + push(m_regs.w[DW]); + clk(1); break; case 0x53: // i_push_bx - PUSH(m_regs.w[BW]); - CLK(1); + push(m_regs.w[BW]); + clk(1); break; case 0x54: // i_push_sp - PUSH(m_regs.w[SP]); - CLK(1); + push(m_regs.w[SP]); + clk(1); break; case 0x55: // i_push_bp - PUSH(m_regs.w[BP]); - CLK(1); + push(m_regs.w[BP]); + clk(1); break; case 0x56: // i_push_si - PUSH(m_regs.w[IX]); - CLK(1); + push(m_regs.w[IX]); + clk(1); break; case 0x57: // i_push_di - PUSH(m_regs.w[IY]); - CLK(1); + push(m_regs.w[IY]); + clk(1); break; case 0x58: // i_pop_ax - m_regs.w[AW] = POP(); - CLK(1); + m_regs.w[AW] = pop(); + clk(1); break; case 0x59: // i_pop_cx - m_regs.w[CW] = POP(); - CLK(1); + m_regs.w[CW] = pop(); + clk(1); break; case 0x5a: // i_pop_dx - m_regs.w[DW] = POP(); - CLK(1); + m_regs.w[DW] = pop(); + clk(1); break; case 0x5b: // i_pop_bx - m_regs.w[BW] = POP(); - CLK(1); + m_regs.w[BW] = pop(); + clk(1); break; case 0x5c: // i_pop_sp - m_regs.w[SP] = POP(); - CLK(1); + m_regs.w[SP] = pop(); + clk(1); break; case 0x5d: // i_pop_bp - m_regs.w[BP] = POP(); - CLK(1); + m_regs.w[BP] = pop(); + clk(1); break; case 0x5e: // i_pop_si - m_regs.w[IX] = POP(); - CLK(1); + m_regs.w[IX] = pop(); + clk(1); break; case 0x5f: // i_pop_di - m_regs.w[IY] = POP(); - CLK(1); + m_regs.w[IY] = pop(); + clk(1); break; @@ -2242,106 +2061,126 @@ void v30mz_cpu_device::execute_run() { uint32_t tmp = m_regs.w[SP]; - PUSH(m_regs.w[AW]); - PUSH(m_regs.w[CW]); - PUSH(m_regs.w[DW]); - PUSH(m_regs.w[BW]); - PUSH(tmp); - PUSH(m_regs.w[BP]); - PUSH(m_regs.w[IX]); - PUSH(m_regs.w[IY]); - CLK(9); + push(m_regs.w[AW]); + push(m_regs.w[CW]); + push(m_regs.w[DW]); + push(m_regs.w[BW]); + push(tmp); + push(m_regs.w[BP]); + push(m_regs.w[IX]); + push(m_regs.w[IY]); + clk(9); } break; case 0x61: // i_popa - m_regs.w[IY] = POP(); - m_regs.w[IX] = POP(); - m_regs.w[BP] = POP(); - POP(); - m_regs.w[BW] = POP(); - m_regs.w[DW] = POP(); - m_regs.w[CW] = POP(); - m_regs.w[AW] = POP(); - CLK(8); + m_regs.w[IY] = pop(); + m_regs.w[IX] = pop(); + m_regs.w[BP] = pop(); + pop(); + m_regs.w[BW] = pop(); + m_regs.w[DW] = pop(); + m_regs.w[CW] = pop(); + m_regs.w[AW] = pop(); + clk(8); break; case 0x62: // i_chkind { uint32_t low,high,tmp; m_modrm = fetch(); - low = GetRMWord(); - high = GetnextRMWord(); - tmp = RegWord(); - if (tmphigh) + low = get_rm_word(); + high = get_next_rm_word(); + tmp = reg_word(); + if (tmp < low || tmp > high) { - interrupt(5); - CLK(20); + interrupt(CHKIND_INT); + clk(20); } else { - CLK(13); + clk(13); } logerror("%s: %06x: bound %04x high %04x low %04x tmp\n", tag(), pc(), high, low, tmp); } break; - case 0x64: // i_repnc + case 0x64: // REPNC not supported by v30mz + fatalerror("%s: %06x: REPNC is not supported by v30mz\n", tag(), pc()); { uint8_t next = repx_op(); uint16_t c = m_regs.w[CW]; switch (next) { - case 0x6c: CLK(2); if (c) do { i_insb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6d: CLK(2); if (c) do { i_insw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6e: CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6f: CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa4: CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa5: CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa6: CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa7: CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaa: CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xab: CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xac: CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xad: CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xae: CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaf: CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6c: clk(2); if (c) do { i_insb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: clk(2); if (c) do { i_insw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: clk(2); if (c) do { i_outsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: clk(2); if (c) do { i_outsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: clk(2); if (c) do { i_movsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: clk(2); if (c) do { i_movsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: clk(2); if (c) do { i_cmpsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: clk(2); if (c) do { i_cmpsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: clk(2); if (c) do { i_stosb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: clk(2); if (c) do { i_stosw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: clk(2); if (c) do { i_lodsb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: clk(2); if (c) do { i_lodsw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: clk(2); if (c) do { i_scasb(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: clk(2); if (c) do { i_scasw(); c--; } while (c>0 && !CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; default: - logerror("%s: %06x: REPNC invalid\n", tag(), pc() ); + logerror("%s: %06x: REPNC invalid\n", tag(), pc()); // Decrement IP so the normal instruction will be executed next m_ip--; + m_pfp--; + if (m_prefetch_queue_tail == 0) + m_prefetch_queue_tail = PREFETCH_QUEUE_SIZE - 1; + else + m_prefetch_queue_tail--; + if (m_prefetch_queue_head == 0) + m_prefetch_queue_head = PREFETCH_QUEUE_SIZE - 1; + else + m_prefetch_queue_head--; break; } } break; - case 0x65: // i_repc + case 0x65: // REPC not supported by v30mz + fatalerror("%s: %06x: REPC is not supported by v30mz\n", tag(), pc()); { uint8_t next = repx_op(); uint16_t c = m_regs.w[CW]; switch (next) { - case 0x6c: CLK(2); if (c) do { i_insb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6d: CLK(2); if (c) do { i_insw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6e: CLK(2); if (c) do { i_outsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6f: CLK(2); if (c) do { i_outsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa4: CLK(2); if (c) do { i_movsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa5: CLK(2); if (c) do { i_movsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa6: CLK(2); if (c) do { i_cmpsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa7: CLK(2); if (c) do { i_cmpsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaa: CLK(2); if (c) do { i_stosb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xab: CLK(2); if (c) do { i_stosw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xac: CLK(2); if (c) do { i_lodsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xad: CLK(2); if (c) do { i_lodsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xae: CLK(2); if (c) do { i_scasb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaf: CLK(2); if (c) do { i_scasw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6c: clk(2); if (c) do { i_insb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: clk(2); if (c) do { i_insw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: clk(2); if (c) do { i_outsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: clk(2); if (c) do { i_outsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: clk(2); if (c) do { i_movsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: clk(2); if (c) do { i_movsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: clk(2); if (c) do { i_cmpsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: clk(2); if (c) do { i_cmpsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: clk(2); if (c) do { i_stosb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: clk(2); if (c) do { i_stosw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: clk(2); if (c) do { i_lodsb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: clk(2); if (c) do { i_lodsw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: clk(2); if (c) do { i_scasb(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: clk(2); if (c) do { i_scasw(); c--; } while (c>0 && CF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; default: logerror("%s: %06x: REPC invalid\n", tag(), pc()); // Decrement IP so the normal instruction will be executed next m_ip--; + m_pfp--; + if (m_prefetch_queue_tail == 0) + m_prefetch_queue_tail = PREFETCH_QUEUE_SIZE - 1; + else + m_prefetch_queue_tail--; + if (m_prefetch_queue_head == 0) + m_prefetch_queue_head = PREFETCH_QUEUE_SIZE - 1; + else + m_prefetch_queue_head--; break; } } @@ -2349,36 +2188,36 @@ void v30mz_cpu_device::execute_run() case 0x68: // i_push_d16 - PUSH( fetch_word() ); - CLK(1); + push(fetch_word()); + clk(1); break; case 0x69: // i_imul_d16 { uint32_t tmp; - DEF_r16w(); + def_r16w(); tmp = fetch_word(); - m_dst = (int32_t)((int16_t)m_src)*(int32_t)((int16_t)tmp); + m_dst = (int32_t)((int16_t)m_src) * (int32_t)((int16_t)tmp); m_CarryVal = m_OverVal = (((int32_t)m_dst) >> 15 != 0) && (((int32_t)m_dst) >> 15 != -1); - RegWord(m_dst); - CLKM(3,4); + reg_word(m_dst); + clkm(3,4); } break; case 0x6a: // i_push_d8 - PUSH( (uint16_t)((int16_t)((int8_t)fetch())) ); - CLK(1); + push( (uint16_t)((int16_t)((int8_t)fetch()))); + clk(1); break; case 0x6b: // i_imul_d8 { uint32_t src2; - DEF_r16w(); - src2= (uint16_t)((int16_t)((int8_t)fetch())); - m_dst = (int32_t)((int16_t)m_src)*(int32_t)((int16_t)src2); + def_r16w(); + src2 = (uint16_t)((int16_t)((int8_t)fetch())); + m_dst = (int32_t)((int16_t)m_src) * (int32_t)((int16_t)src2); m_CarryVal = m_OverVal = (((int32_t)m_dst) >> 15 != 0) && (((int32_t)m_dst) >> 15 != -1); - RegWord(m_dst); - CLKM(3,4); + reg_word(m_dst); + clkm(3,4); } break; @@ -2400,239 +2239,239 @@ void v30mz_cpu_device::execute_run() case 0x70: // i_jo - JMP( OF); + jmp( OF); break; case 0x71: // i_jno - JMP(!OF); + jmp(!OF); break; case 0x72: // i_jc - JMP( CF); + jmp( CF); break; case 0x73: // i_jnc - JMP(!CF); + jmp(!CF); break; case 0x74: // i_jz - JMP( ZF); + jmp( ZF); break; case 0x75: // i_jnz - JMP(!ZF); + jmp(!ZF); break; case 0x76: // i_jce - JMP(CF || ZF); + jmp(CF || ZF); break; case 0x77: // i_jnce - JMP(!(CF || ZF)); + jmp(!(CF || ZF)); break; case 0x78: // i_js - JMP( SF); + jmp( SF); break; case 0x79: // i_jns - JMP(!SF); + jmp(!SF); break; case 0x7a: // i_jp - JMP( PF); + jmp( PF); break; case 0x7b: // i_jnp - JMP(!PF); + jmp(!PF); break; case 0x7c: // i_jl - JMP((SF!=OF)&&(!ZF)); + jmp((SF != OF) && (!ZF)); break; case 0x7d: // i_jnl - JMP((ZF)||(SF==OF)); + jmp((ZF) || (SF == OF)); break; case 0x7e: // i_jle - JMP((ZF)||(SF!=OF)); + jmp((ZF) || (SF != OF)); break; case 0x7f: // i_jnle - JMP((SF==OF)&&(!ZF)); + jmp((SF == OF) && (!ZF)); break; case 0x80: // i_80pre m_modrm = fetch(); - m_dst = GetRMByte(); + m_dst = get_rm_byte(); m_src = fetch(); - if (m_modrm >=0xc0 ) { CLK(1); } - else if ((m_modrm & 0x38)==0x38) { CLK(2); } - else { CLK(3); } + if (m_modrm >=0xc0) { clk(1); } + else if ((m_modrm & 0x38)==0x38) { clk(2); } + else { clk(3); } switch (m_modrm & 0x38) { - case 0x00: ADDB(); PutbackRMByte(m_dst); break; - case 0x08: ORB(); PutbackRMByte(m_dst); break; - case 0x10: m_src += CF ? 1 : 0; ADDB(); PutbackRMByte(m_dst); break; - case 0x18: m_src += CF ? 1 : 0; SUBB(); PutbackRMByte(m_dst); break; - case 0x20: ANDB(); PutbackRMByte(m_dst); break; - case 0x28: SUBB(); PutbackRMByte(m_dst); break; - case 0x30: XORB(); PutbackRMByte(m_dst); break; - case 0x38: SUBB(); break; /* CMP */ + case 0x00: add_byte(); store_ea_rm_byte(m_dst); break; + case 0x08: or_byte(); store_ea_rm_byte(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; add_byte(); store_ea_rm_byte(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; sub_byte(); store_ea_rm_byte(m_dst); break; + case 0x20: and_byte(); store_ea_rm_byte(m_dst); break; + case 0x28: sub_byte(); store_ea_rm_byte(m_dst); break; + case 0x30: xor_byte(); store_ea_rm_byte(m_dst); break; + case 0x38: sub_byte(); break; // CMP } break; case 0x81: // i_81pre m_modrm = fetch(); - m_dst = GetRMWord(); + m_dst = get_rm_word(); m_src = fetch_word(); - if (m_modrm >=0xc0 ) { CLK(1); } - else if ((m_modrm & 0x38)==0x38) { CLK(2); } - else { CLK(3); } + if (m_modrm >=0xc0) { clk(1); } + else if ((m_modrm & 0x38)==0x38) { clk(2); } + else { clk(3); } switch (m_modrm & 0x38) { - case 0x00: ADDW(); PutbackRMWord(m_dst); break; - case 0x08: ORW(); PutbackRMWord(m_dst); break; - case 0x10: m_src += CF ? 1 : 0; ADDW(); PutbackRMWord(m_dst); break; - case 0x18: m_src += CF ? 1 : 0; SUBW(); PutbackRMWord(m_dst); break; - case 0x20: ANDW(); PutbackRMWord(m_dst); break; - case 0x28: SUBW(); PutbackRMWord(m_dst); break; - case 0x30: XORW(); PutbackRMWord(m_dst); break; - case 0x38: SUBW(); break; /* CMP */ + case 0x00: add_word(); store_ea_rm_word(m_dst); break; + case 0x08: or_word(); store_ea_rm_word(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; add_word(); store_ea_rm_word(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; sub_word(); store_ea_rm_word(m_dst); break; + case 0x20: and_word(); store_ea_rm_word(m_dst); break; + case 0x28: sub_word(); store_ea_rm_word(m_dst); break; + case 0x30: xor_word(); store_ea_rm_word(m_dst); break; + case 0x38: sub_word(); break; // CMP } break; case 0x82: // i_82pre m_modrm = fetch(); - m_dst = GetRMByte(); + m_dst = get_rm_byte(); m_src = (int8_t)fetch(); - if (m_modrm >=0xc0 ) { CLK(1); } - else if ((m_modrm & 0x38)==0x38) { CLK(2); } - else { CLK(3); } + if (m_modrm >=0xc0) { clk(1); } + else if ((m_modrm & 0x38) == 0x38) { clk(2); } + else { clk(3); } switch (m_modrm & 0x38) { - case 0x00: ADDB(); PutbackRMByte(m_dst); break; - case 0x08: ORB(); PutbackRMByte(m_dst); break; - case 0x10: m_src += CF ? 1 : 0; ADDB(); PutbackRMByte(m_dst); break; - case 0x18: m_src += CF ? 1 : 0; SUBB(); PutbackRMByte(m_dst); break; - case 0x20: ANDB(); PutbackRMByte(m_dst); break; - case 0x28: SUBB(); PutbackRMByte(m_dst); break; - case 0x30: XORB(); PutbackRMByte(m_dst); break; - case 0x38: SUBB(); break; /* CMP */ + case 0x00: add_byte(); store_ea_rm_byte(m_dst); break; + case 0x08: or_byte(); store_ea_rm_byte(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; add_byte(); store_ea_rm_byte(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; sub_byte(); store_ea_rm_byte(m_dst); break; + case 0x20: and_byte(); store_ea_rm_byte(m_dst); break; + case 0x28: sub_byte(); store_ea_rm_byte(m_dst); break; + case 0x30: xor_byte(); store_ea_rm_byte(m_dst); break; + case 0x38: sub_byte(); break; // CMP } break; case 0x83: // i_83pre m_modrm = fetch(); - m_dst = GetRMWord(); - m_src = ((int16_t)((int8_t)fetch())); - if ( m_modrm >= 0xc0 ) { CLK(1); } - else if (( m_modrm & 0x38 ) == 0x38) { CLK(2); } - else { CLK(3); } + m_dst = get_rm_word(); + m_src = (int8_t)fetch(); + if ( m_modrm >= 0xc0) { clk(1); } + else if ((m_modrm & 0x38) == 0x38) { clk(2); } + else { clk(3); } switch (m_modrm & 0x38) { - case 0x00: ADDW(); PutbackRMWord(m_dst); break; - case 0x08: ORW(); PutbackRMWord(m_dst); break; - case 0x10: m_src += CF ? 1 : 0; ADDW(); PutbackRMWord(m_dst); break; - case 0x18: m_src += CF ? 1 : 0; SUBW(); PutbackRMWord(m_dst); break; - case 0x20: ANDW(); PutbackRMWord(m_dst); break; - case 0x28: SUBW(); PutbackRMWord(m_dst); break; - case 0x30: XORW(); PutbackRMWord(m_dst); break; - case 0x38: SUBW(); break; /* CMP */ + case 0x00: add_word(); store_ea_rm_word(m_dst); break; + case 0x08: or_word(); store_ea_rm_word(m_dst); break; + case 0x10: m_src += CF ? 1 : 0; add_word(); store_ea_rm_word(m_dst); break; + case 0x18: m_src += CF ? 1 : 0; sub_word(); store_ea_rm_word(m_dst); break; + case 0x20: and_word(); store_ea_rm_word(m_dst); break; + case 0x28: sub_word(); store_ea_rm_word(m_dst); break; + case 0x30: xor_word(); store_ea_rm_word(m_dst); break; + case 0x38: sub_word(); break; // CMP } break; case 0x84: // i_test_br8 - DEF_br8(); - ANDB(); - CLKM(1,2); + def_br8(); + and_byte(); + clkm(1,2); break; case 0x85: // i_test_wr16 - DEF_wr16(); - ANDW(); - CLKM(1,2); + def_wr16(); + and_word(); + clkm(1,2); break; case 0x86: // i_xchg_br8 - DEF_br8(); - RegByte(m_dst); - PutbackRMByte(m_src); - CLKM(3,5); + def_br8(); + reg_byte(m_dst); + store_ea_rm_byte(m_src); + clkm(3,5); break; case 0x87: // i_xchg_wr16 - DEF_wr16(); - RegWord(m_dst); - PutbackRMWord(m_src); - CLKM(3,5); + def_wr16(); + reg_word(m_dst); + store_ea_rm_word(m_src); + clkm(3,5); break; case 0x88: // i_mov_br8 m_modrm = fetch(); - m_src = RegByte(); - PutRMByte(m_src); - CLK(1); + m_src = reg_byte(); + put_rm_byte(m_src); + clk(1); break; case 0x89: // i_mov_wr16 m_modrm = fetch(); - m_src = RegWord(); - PutRMWord(m_src); - CLK(1); + m_src = reg_word(); + put_rm_word(m_src); + clk(1); break; case 0x8a: // i_mov_r8b m_modrm = fetch(); - m_src = GetRMByte(); - RegByte(m_src); - CLK(1); + m_src = get_rm_byte(); + reg_byte(m_src); + clk(1); break; case 0x8b: // i_mov_r16w m_modrm = fetch(); - m_src = GetRMWord(); - RegWord(m_src); - CLK(1); + m_src = get_rm_word(); + reg_word(m_src); + clk(1); break; case 0x8c: // i_mov_wsreg m_modrm = fetch(); - PutRMWord(m_sregs[(m_modrm & 0x38) >> 3]); - CLKM(1,3); + put_rm_word(m_sregs[(m_modrm & 0x38) >> 3]); + clkm(1,3); break; case 0x8d: // i_lea m_modrm = fetch(); get_ea(); - RegWord(m_eo); - CLK(1); + reg_word(m_eo); + clk(1); break; case 0x8e: // i_mov_sregw m_modrm = fetch(); - m_src = GetRMWord(); - CLKM(2,3); + m_src = get_rm_word(); + clkm(2,3); switch (m_modrm & 0x38) { - case 0x00: /* mov es,ew */ - m_sregs[ES] = m_src; + case 0x00: // mov ds1,ew + m_sregs[DS1] = m_src; break; - case 0x08: /* mov cs,ew */ - m_sregs[CS] = m_src; + case 0x08: // mov cs,ew + m_sregs[PS] = m_src; break; - case 0x10: /* mov ss,ew */ + case 0x10: // mov ss,ew m_sregs[SS] = m_src; break; - case 0x18: /* mov ds,ew */ - m_sregs[DS] = m_src; + case 0x18: // mov ds0,ew + m_sregs[DS0] = m_src; break; default: logerror("%s: %06x: Mov Sreg - Invalid register\n", tag(), pc()); @@ -2642,69 +2481,70 @@ void v30mz_cpu_device::execute_run() case 0x8f: // i_popw m_modrm = fetch(); - PutRMWord( POP() ); - CLKM(1,3); + put_rm_word(pop()); + clkm(1,3); break; case 0x90: // i_nop - CLK(1); + clk(1); break; case 0x91: // i_xchg_axcx - XchgAWReg(CW); - CLK(3); + xchg_AW_reg(CW); + clk(3); break; case 0x92: // i_xchg_axdx - XchgAWReg(DW); - CLK(3); + xchg_AW_reg(DW); + clk(3); break; case 0x93: // i_xchg_axbx - XchgAWReg(BW); - CLK(3); + xchg_AW_reg(BW); + clk(3); break; case 0x94: // i_xchg_axsp - XchgAWReg(SP); - CLK(3); + xchg_AW_reg(SP); + clk(3); break; case 0x95: // i_xchg_axbp - XchgAWReg(BP); - CLK(3); + xchg_AW_reg(BP); + clk(3); break; case 0x96: // i_xchg_axsi - XchgAWReg(IX); - CLK(3); + xchg_AW_reg(IX); + clk(3); break; case 0x97: // i_xchg_axdi - XchgAWReg(IY); - CLK(3); + xchg_AW_reg(IY); + clk(3); break; case 0x98: // i_cbw m_regs.b[AH] = (m_regs.b[AL] & 0x80) ? 0xff : 0; - CLK(1); + clk(1); break; case 0x99: // i_cwd m_regs.w[DW] = (m_regs.b[AH] & 0x80) ? 0xffff : 0; - CLK(1); + clk(1); break; case 0x9a: // i_call_far { uint16_t tmp = fetch_word(); uint16_t tmp2 = fetch_word(); - PUSH(m_sregs[CS]); - PUSH(m_ip); + push(m_sregs[PS]); + push(m_ip); m_ip = tmp; - m_sregs[CS] = tmp2; - CLK(10); + m_sregs[PS] = tmp2; + init_prefetch(); + clk(10); } break; @@ -2713,8 +2553,8 @@ void v30mz_cpu_device::execute_run() break; case 0x9c: // i_pushf - PUSH( CompressFlags() ); - CLK(2); + push(compress_flags()); + clk(2); break; case 0x9d: // i_popf @@ -2723,50 +2563,36 @@ void v30mz_cpu_device::execute_run() case 0x9e: // i_sahf { - uint32_t tmp = (CompressFlags() & 0xff00) | (m_regs.b[AH] & 0xd5); - ExpandFlags(tmp); - CLK(4); + uint32_t tmp = (compress_flags() & 0xff00) | (m_regs.b[AH] & 0xd5); + expand_flags(tmp); + clk(4); } break; case 0x9f: // i_lahf - m_regs.b[AH] = CompressFlags(); - CLK(2); + m_regs.b[AH] = compress_flags(); + clk(2); break; case 0xa0: // i_mov_aldisp - { - uint32_t addr = fetch_word(); - m_regs.b[AL] = GetMemB(DS, addr); - CLK(1); - } + m_regs.b[AL] = read_byte(default_base(DS0), fetch_word()); + clk(1); break; case 0xa1: // i_mov_axdisp - { - uint32_t addr = fetch_word(); - m_regs.b[AL] = GetMemB(DS, addr); - m_regs.b[AH] = GetMemB(DS, addr+1); - CLK(1); - } + m_regs.w[AW] = read_word(default_base(DS0), fetch_word()); + clk(1); break; case 0xa2: // i_mov_dispal - { - uint32_t addr = fetch_word(); - PutMemB(DS, addr, m_regs.b[AL]); - CLK(1); - } + write_byte(default_base(DS0), fetch_word(), m_regs.b[AL]); + clk(1); break; case 0xa3: // i_mov_dispax - { - uint32_t addr = fetch_word(); - PutMemB(DS, addr, m_regs.b[AL]); - PutMemB(DS, addr+1, m_regs.b[AH]); - CLK(1); - } + write_word(default_base(DS0), fetch_word(), m_regs.w[AW]); + clk(1); break; case 0xa4: // i_movsb @@ -2787,15 +2613,15 @@ void v30mz_cpu_device::execute_run() case 0xa8: // i_test_ald8 - DEF_ald8(); - ANDB(); - CLK(1); + def_ald8(); + and_byte(); + clk(1); break; case 0xa9: // i_test_axd16 - DEF_axd16(); - ANDW(); - CLK(1); + def_awd16(); + and_word(); + clk(1); break; case 0xaa: // i_stosb @@ -2825,91 +2651,83 @@ void v30mz_cpu_device::execute_run() case 0xb0: // i_mov_ald8 m_regs.b[AL] = fetch(); - CLK(1); + clk(1); break; case 0xb1: // i_mov_cld8 m_regs.b[CL] = fetch(); - CLK(1); + clk(1); break; case 0xb2: // i_mov_dld8 m_regs.b[DL] = fetch(); - CLK(1); + clk(1); break; case 0xb3: // i_mov_bld8 m_regs.b[BL] = fetch(); - CLK(1); + clk(1); break; case 0xb4: // i_mov_ahd8 m_regs.b[AH] = fetch(); - CLK(1); + clk(1); break; case 0xb5: // i_mov_chd8 m_regs.b[CH] = fetch(); - CLK(1); + clk(1); break; case 0xb6: // i_mov_dhd8 m_regs.b[DH] = fetch(); - CLK(1); + clk(1); break; case 0xb7: // i_mov_bhd8 m_regs.b[BH] = fetch(); - CLK(1); + clk(1); break; case 0xb8: // i_mov_axd16 - m_regs.b[AL] = fetch(); - m_regs.b[AH] = fetch(); - CLK(1); + m_regs.w[AW] = fetch_word(); + clk(1); break; case 0xb9: // i_mov_cxd16 - m_regs.b[CL] = fetch(); - m_regs.b[CH] = fetch(); - CLK(1); + m_regs.w[CW] = fetch_word(); + clk(1); break; case 0xba: // i_mov_dxd16 - m_regs.b[DL] = fetch(); - m_regs.b[DH] = fetch(); - CLK(1); + m_regs.w[DW] = fetch_word(); + clk(1); break; case 0xbb: // i_mov_bxd16 - m_regs.b[BL] = fetch(); - m_regs.b[BH] = fetch(); - CLK(1); + m_regs.w[BW] = fetch_word(); + clk(1); break; case 0xbc: // i_mov_spd16 - m_regs.b[SPL] = fetch(); - m_regs.b[SPH] = fetch(); - CLK(1); + m_regs.w[SP] = fetch_word(); + clk(1); break; case 0xbd: // i_mov_bpd16 - m_regs.b[BPL] = fetch(); - m_regs.b[BPH] = fetch(); - CLK(1); + m_regs.w[BP] = fetch_word(); + clk(1); break; case 0xbe: // i_mov_sid16 - m_regs.b[IXL] = fetch(); - m_regs.b[IXH] = fetch(); - CLK(1); + m_regs.w[IX] = fetch_word(); + clk(1); break; case 0xbf: // i_mov_did16 - m_regs.b[IYL] = fetch(); - m_regs.b[IYH] = fetch(); - CLK(1); + m_regs.w[IY] = fetch_word(); + clk(1); break; @@ -2917,22 +2735,22 @@ void v30mz_cpu_device::execute_run() { uint8_t c; m_modrm = fetch(); - m_src = GetRMByte(); + m_src = get_rm_byte(); m_dst = m_src; c = fetch(); - CLKM(3,5); + clkm(3,5); if (c) { - switch ( m_modrm & 0x38 ) + switch (m_modrm & 0x38) { - case 0x00: do { ROL_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; - case 0x08: do { ROR_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; - case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; - case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; - case 0x20: SHL_BYTE(c); break; - case 0x28: SHR_BYTE(c); break; + case 0x00: do { rol_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x08: do { ror_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x10: do { rolc_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x18: do { rorc_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x20: shl_byte(c); break; + case 0x28: shr_byte(c); break; case 0x30: logerror("%s: %06x: Undefined opcode 0xc0 0x30 (SHLA)\n", tag(), pc()); break; - case 0x38: SHRA_BYTE(c); break; + case 0x38: shra_byte(c); break; } } } @@ -2942,22 +2760,22 @@ void v30mz_cpu_device::execute_run() { uint8_t c; m_modrm = fetch(); - m_src = GetRMWord(); + m_src = get_rm_word(); m_dst = m_src; c = fetch(); - CLKM(3,5); + clkm(3,5); if (c) { - switch ( m_modrm & 0x38 ) + switch (m_modrm & 0x38) { - case 0x00: do { ROL_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x08: do { ROR_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x20: SHL_WORD(c); break; - case 0x28: SHR_WORD(c); break; + case 0x00: do { rol_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x08: do { ror_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x10: do { rolc_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x18: do { rorc_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x20: shl_word(c); break; + case 0x28: shr_word(c); break; case 0x30: logerror("%s: %06x: Undefined opcode 0xc1 0x30 (SHLA)\n", tag(), pc()); break; - case 0x38: SHRA_WORD(c); break; + case 0x38: shra_word(c); break; } } } @@ -2967,41 +2785,43 @@ void v30mz_cpu_device::execute_run() case 0xc2: // i_ret_d16 { uint32_t count = fetch_word(); - m_ip = POP(); + m_ip = pop(); m_regs.w[SP] += count; - CLK(6); + init_prefetch(); + clk(6); } break; case 0xc3: // i_ret - m_ip = POP(); - CLK(6); + m_ip = pop(); + init_prefetch(); + clk(6); break; case 0xc4: // i_les_dw m_modrm = fetch(); - RegWord( GetRMWord() ); - m_sregs[ES] = GetnextRMWord(); - CLK(6); + reg_word(get_rm_word()); + m_sregs[DS1] = get_next_rm_word(); + clk(6); break; case 0xc5: // i_lds_dw m_modrm = fetch(); - RegWord( GetRMWord() ); - m_sregs[DS] = GetnextRMWord(); - CLK(6); + reg_word(get_rm_word()); + m_sregs[DS0] = get_next_rm_word(); + clk(6); break; case 0xc6: // i_mov_bd8 m_modrm = fetch(); - PutImmRMByte(); - CLK(1); + put_imm_rm_byte(); + clk(1); break; case 0xc7: // i_mov_wd16 m_modrm = fetch(); - PutImmRMWord(); - CLK(1); + put_imm_rm_word(); + clk(1); break; @@ -3010,107 +2830,110 @@ void v30mz_cpu_device::execute_run() uint16_t nb = fetch(); uint32_t level; - CLK(8); + clk(8); nb |= fetch() << 8; level = fetch(); - PUSH(m_regs.w[BP]); + push(m_regs.w[BP]); m_regs.w[BP] = m_regs.w[SP]; m_regs.w[SP] -= nb; - for (int i=1; i0); PutbackRMByte(m_dst); break; - case 0x08: do { ROR_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; - case 0x10: do { ROLC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; - case 0x18: do { RORC_BYTE(); c--; } while (c>0); PutbackRMByte(m_dst); break; - case 0x20: SHL_BYTE(c); break; - case 0x28: SHR_BYTE(c); break; + case 0x00: do { rol_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x08: do { ror_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x10: do { rolc_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x18: do { rorc_byte(); c--; } while (c > 0); store_ea_rm_byte(m_dst); break; + case 0x20: shl_byte(c); break; + case 0x28: shr_byte(c); break; case 0x30: logerror("%s: %06x: Undefined opcode 0xd2 0x30 (SHLA)\n", tag(), pc()); break; - case 0x38: SHRA_BYTE(c); break; + case 0x38: shra_byte(c); break; } } } @@ -3145,57 +2968,57 @@ void v30mz_cpu_device::execute_run() uint8_t c; m_modrm = fetch(); - m_src = GetRMWord(); + m_src = get_rm_word(); m_dst = m_src; c = m_regs.b[CL]; - CLKM(3,5); + clkm(3,5); if (c) { - switch ( m_modrm & 0x38 ) + switch (m_modrm & 0x38) { - case 0x00: do { ROL_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x08: do { ROR_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x10: do { ROLC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x18: do { RORC_WORD(); c--; } while (c>0); PutbackRMWord(m_dst); break; - case 0x20: SHL_WORD(c); break; - case 0x28: SHR_WORD(c); break; + case 0x00: do { rol_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x08: do { ror_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x10: do { rolc_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x18: do { rorc_word(); c--; } while (c > 0); store_ea_rm_word(m_dst); break; + case 0x20: shl_word(c); break; + case 0x28: shr_word(c); break; case 0x30: logerror("%s: %06x: Undefined opcode 0xd3 0x30 (SHLA)\n", tag(), pc()); break; - case 0x38: SHRA_WORD(c); break; + case 0x38: shra_word(c); break; } } } break; - case 0xd4: // i_aam + case 0xd4: // cvtbd fetch(); m_regs.b[AH] = m_regs.b[AL] / 10; m_regs.b[AL] %= 10; - set_SZPF_Word(m_regs.w[AW]); - CLK(17); + set_SZPF_word(m_regs.w[AW]); + clk(17); break; - case 0xd5: // i_aad + case 0xd5: // cvtdb fetch(); m_regs.b[AL] = m_regs.b[AH] * 10 + m_regs.b[AL]; m_regs.b[AH] = 0; - set_SZPF_Byte(m_regs.b[AL]); - CLK(5); + set_SZPF_byte(m_regs.b[AL]); + clk(5); break; case 0xd6: // i_setalc m_regs.b[AL] = (CF) ? 0xff : 0x00; - CLK(3); - logerror("%s: %06x: Undefined opcode (SETALC)\n", tag(), pc() ); + clk(3); + logerror("%s: %06x: Undefined opcode (SETALC)\n", tag(), pc()); break; case 0xd7: // i_trans - m_regs.b[AL] = GetMemB( DS, m_regs.w[BW] + m_regs.b[AL] ); - CLK(5); + m_regs.b[AL] = read_byte(default_base(DS0), m_regs.w[BW] + m_regs.b[AL]); + clk(5); break; - case 0xd8: // i_fpo + case 0xd8: // FPO1 not supported by v30mz m_modrm = fetch(); - CLK(1); + clk(1); logerror("%s: %06x: Unimplemented floating point control %04x\n", tag(), pc(), m_modrm); break; @@ -3208,9 +3031,10 @@ void v30mz_cpu_device::execute_run() if (!ZF && m_regs.w[CW]) { m_ip = m_ip + disp; - CLK(3); + init_prefetch(); + clk(3); } - CLK(3); + clk(3); } break; @@ -3222,9 +3046,10 @@ void v30mz_cpu_device::execute_run() if (ZF && m_regs.w[CW]) { m_ip = m_ip + disp; - CLK(3); + init_prefetch(); + clk(3); } - CLK(3); + clk(3); } break; @@ -3236,9 +3061,10 @@ void v30mz_cpu_device::execute_run() if (m_regs.w[CW]) { m_ip = m_ip + disp; - CLK(3); + init_prefetch(); + clk(3); } - CLK(2); + clk(2); } break; @@ -3249,40 +3075,31 @@ void v30mz_cpu_device::execute_run() if (m_regs.w[CW] == 0) { m_ip = m_ip + disp; - CLK(3); + init_prefetch(); + clk(3); } - CLK(1); + clk(1); } break; case 0xe4: // i_inal - m_regs.b[AL] = read_port( fetch() ); - CLK(6); + m_regs.b[AL] = read_port(fetch()); + clk(6); break; case 0xe5: // i_inax - { - uint8_t port = fetch(); - - m_regs.b[AL] = read_port(port); - m_regs.b[AH] = read_port(port+1); - CLK(6); - } + m_regs.w[AW] = read_port_word(fetch()); + clk(6); break; case 0xe6: // i_outal - write_port( fetch(), m_regs.b[AL]); - CLK(6); + write_port(fetch(), m_regs.b[AL]); + clk(6); break; case 0xe7: // i_outax - { - uint8_t port = fetch(); - - write_port(port, m_regs.b[AL]); - write_port(port+1, m_regs.b[AH]); - CLK(6); - } + write_port_word(fetch(), m_regs.w[AW]); + clk(6); break; @@ -3290,9 +3107,10 @@ void v30mz_cpu_device::execute_run() { int16_t tmp = (int16_t)fetch_word(); - PUSH(m_ip); + push(m_ip); m_ip = m_ip + tmp; - CLK(5); + init_prefetch(); + clk(5); } break; @@ -3300,7 +3118,8 @@ void v30mz_cpu_device::execute_run() { int16_t offset = (int16_t)fetch_word(); m_ip += offset; - CLK(4); + init_prefetch(); + clk(4); } break; @@ -3309,9 +3128,10 @@ void v30mz_cpu_device::execute_run() uint16_t tmp = fetch_word(); uint16_t tmp1 = fetch_word(); - m_sregs[CS] = tmp1; + m_sregs[PS] = tmp1; m_ip = tmp; - CLK(7); + init_prefetch(); + clk(7); } break; @@ -3319,50 +3139,41 @@ void v30mz_cpu_device::execute_run() { int tmp = (int)((int8_t)fetch()); - CLK(4); - if (tmp==-2 && m_no_interrupt==0 && (m_pending_irq==0) && m_icount>0) + clk(4); + if (tmp == -2 && m_no_interrupt == 0 && (m_pending_irq == 0) && m_icount > 0) { - m_icount%=12; /* cycle skip */ + m_icount %= 12; // cycle skip } - m_ip = (uint16_t)(m_ip+tmp); + m_ip = (uint16_t)(m_ip + tmp); + init_prefetch(); } break; case 0xec: // i_inaldx m_regs.b[AL] = read_port(m_regs.w[DW]); - CLK(6); + clk(6); break; case 0xed: // i_inaxdx - { - uint32_t port = m_regs.w[DW]; - - m_regs.b[AL] = read_port(port); - m_regs.b[AH] = read_port(port+1); - CLK(6); - } + m_regs.w[AW] = read_port_word(m_regs.w[DW]); + clk(6); break; case 0xee: // i_outdxal write_port(m_regs.w[DW], m_regs.b[AL]); - CLK(6); + clk(6); break; case 0xef: // i_outdxax - { - uint32_t port = m_regs.w[DW]; - - write_port(port, m_regs.b[AL]); - write_port(port+1, m_regs.b[AH]); - CLK(6); - } + write_port_word(m_regs.w[DW], m_regs.w[AW]); + clk(6); break; case 0xf0: // i_lock logerror("%s: %06x: Warning - BUSLOCK\n", tag(), pc()); m_no_interrupt = 1; - CLK(1); + clk(1); break; case 0xf2: // i_repne @@ -3372,24 +3183,33 @@ void v30mz_cpu_device::execute_run() switch (next) { - case 0x6c: CLK(3); if (c) do { i_insb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6d: CLK(3); if (c) do { i_insw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6e: CLK(3); if (c) do { i_outsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6f: CLK(3); if (c) do { i_outsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa4: CLK(3); if (c) do { i_movsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa5: CLK(3); if (c) do { i_movsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa6: CLK(3); if (c) do { i_cmpsb(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa7: CLK(3); if (c) do { i_cmpsw(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaa: CLK(3); if (c) do { i_stosb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xab: CLK(3); if (c) do { i_stosw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xac: CLK(3); if (c) do { i_lodsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xad: CLK(3); if (c) do { i_lodsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xae: CLK(3); if (c) do { i_scasb(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaf: CLK(3); if (c) do { i_scasw(); c--; } while (c>0 && !ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6c: clk(3); if (c) do { i_insb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: clk(3); if (c) do { i_insw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: clk(3); if (c) do { i_outsb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: clk(3); if (c) do { i_outsw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: clk(3); if (c) do { i_movsb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: clk(3); if (c) do { i_movsw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: clk(3); if (c) do { i_cmpsb(); c--; } while (c > 0 && !ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: clk(3); if (c) do { i_cmpsw(); c--; } while (c > 0 && !ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: clk(3); if (c) do { i_stosb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: clk(3); if (c) do { i_stosw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: clk(3); if (c) do { i_lodsb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: clk(3); if (c) do { i_lodsw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: clk(3); if (c) do { i_scasb(); c--; } while (c > 0 && !ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: clk(3); if (c) do { i_scasw(); c--; } while (c > 0 && !ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; default: logerror("%s: %06x: REPNE invalid\n", tag(), pc()); // Decrement IP so the normal instruction will be executed next m_ip--; + m_pfp--; + if (m_prefetch_queue_tail == 0) + m_prefetch_queue_tail = PREFETCH_MAX_SIZE - 1; + else + m_prefetch_queue_tail--; + if (m_prefetch_queue_head == 0) + m_prefetch_queue_head = PREFETCH_MAX_SIZE - 1; + else + m_prefetch_queue_head--; break; } } @@ -3402,89 +3222,97 @@ void v30mz_cpu_device::execute_run() switch (next) { - case 0x6c: CLK(3); if (c) do { i_insb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6d: CLK(3); if (c) do { i_insw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6e: CLK(3); if (c) do { i_outsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0x6f: CLK(3); if (c) do { i_outsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa4: CLK(3); if (c) do { i_movsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa5: CLK(3); if (c) do { i_movsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa6: CLK(3); if (c) do { i_cmpsb(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xa7: CLK(3); if (c) do { i_cmpsw(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaa: CLK(3); if (c) do { i_stosb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xab: CLK(3); if (c) do { i_stosw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xac: CLK(3); if (c) do { i_lodsb(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xad: CLK(3); if (c) do { i_lodsw(); c--; } while (c>0); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xae: CLK(3); if (c) do { i_scasb(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; - case 0xaf: CLK(3); if (c) do { i_scasw(); c--; } while (c>0 && ZF); m_regs.w[CW]=c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6c: clk(3); if (c) do { i_insb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6d: clk(3); if (c) do { i_insw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6e: clk(3); if (c) do { i_outsb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0x6f: clk(3); if (c) do { i_outsw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa4: clk(3); if (c) do { i_movsb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa5: clk(3); if (c) do { i_movsw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa6: clk(3); if (c) do { i_cmpsb(); c--; } while (c > 0 && ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xa7: clk(3); if (c) do { i_cmpsw(); c--; } while (c > 0 && ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaa: clk(3); if (c) do { i_stosb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xab: clk(3); if (c) do { i_stosw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xac: clk(3); if (c) do { i_lodsb(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xad: clk(3); if (c) do { i_lodsw(); c--; } while (c > 0); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xae: clk(3); if (c) do { i_scasb(); c--; } while (c > 0 && ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; + case 0xaf: clk(3); if (c) do { i_scasw(); c--; } while (c > 0 && ZF); m_regs.w[CW] = c; m_seg_prefix = false; m_seg_prefix_next = false; break; default: logerror("%s: %06x: REPE invalid\n", tag(), pc()); // Decrement IP so the normal instruction will be executed next m_ip--; + m_pfp--; + if (m_prefetch_queue_tail == 0) + m_prefetch_queue_tail = PREFETCH_MAX_SIZE - 1; + else + m_prefetch_queue_tail--; + if (m_prefetch_queue_head == 0) + m_prefetch_queue_head = PREFETCH_MAX_SIZE - 1; + else + m_prefetch_queue_head--; break; } } break; case 0xf4: // i_hlt - logerror("%s: %06x: HALT\n", tag(), pc()); m_icount = 0; break; case 0xf5: // i_cmc - m_CarryVal ^= 1; - CLK(4); + m_CarryVal = (CF ? 0 : 1); + clk(4); break; case 0xf6: // i_f6pre { - uint32_t tmp; - uint32_t uresult,uresult2; - int32_t result,result2; - m_modrm = fetch(); - tmp = GetRMByte(); - switch ( m_modrm & 0x38 ) + uint32_t tmp = get_rm_byte(); + switch (m_modrm & 0x38) { - case 0x00: /* TEST */ + case 0x00: // TEST tmp &= fetch(); m_CarryVal = m_OverVal = 0; - set_SZPF_Byte(tmp); - CLKM(1,2); + set_SZPF_byte(tmp); + clkm(1,2); break; case 0x08: logerror("%s: %06x: Undefined opcode 0xf6 0x08\n", tag(), pc()); break; - case 0x10: /* NOT */ - PutbackRMByte(~tmp); - CLKM(1,3); + case 0x10: // NOT + store_ea_rm_byte(~tmp); + clkm(1,3); break; - case 0x18: /* NEG */ - m_CarryVal = (tmp!=0) ? 1 : 0; - tmp = (~tmp)+1; - set_SZPF_Byte(tmp); - PutbackRMByte(tmp&0xff); - CLKM(1,3); + case 0x18: // NEG, AF? + m_CarryVal = (tmp != 0) ? 1 : 0; + tmp = (~tmp) + 1; + set_SZPF_byte(tmp); + store_ea_rm_byte(tmp & 0xff); + clkm(1,3); break; - case 0x20: /* MULU */ - uresult = m_regs.b[AL] * tmp; - m_regs.w[AW] = (uint16_t)uresult; - m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0; - CLKM(3,4); + case 0x20: // MULU + { + uint32_t uresult = m_regs.b[AL] * tmp; + m_regs.w[AW] = (uint16_t)uresult; + m_CarryVal = m_OverVal = (m_regs.b[AH] != 0) ? 1 : 0; + clkm(3,4); + } break; - case 0x28: /* MUL */ - result = (int16_t)((int8_t)m_regs.b[AL])*(int16_t)((int8_t)tmp); - m_regs.w[AW] = (uint16_t)result; - m_CarryVal = m_OverVal = (m_regs.b[AH]!=0) ? 1 : 0; - CLKM(3,4); + case 0x28: // MUL + { + int32_t result = (int16_t)((int8_t)m_regs.b[AL]) * (int16_t)((int8_t)tmp); + m_regs.w[AW] = (uint16_t)result; + m_CarryVal = m_OverVal = (m_regs.b[AH] != 0) ? 1 : 0; + clkm(3,4); + } break; - case 0x30: /* DIVU */ + case 0x30: // DIVU if (tmp) { - uresult = m_regs.w[AW]; - uresult2 = uresult % tmp; + uint32_t uresult = m_regs.w[AW]; + uint32_t uresult2 = uresult % tmp; if ((uresult /= tmp) > 0xff) { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } else { @@ -3494,18 +3322,18 @@ void v30mz_cpu_device::execute_run() } else { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } - CLKM(15,16); + clkm(15,16); break; - case 0x38: /* DIV */ + case 0x38: // DIV if (tmp) { - result = (int16_t)m_regs.w[AW]; - result2 = result % (int16_t)((int8_t)tmp); + int32_t result = (int16_t)m_regs.w[AW]; + int32_t result2 = result % (int16_t)((int8_t)tmp); if ((result /= (int16_t)((int8_t)tmp)) > 0xff) { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } else { @@ -3515,9 +3343,9 @@ void v30mz_cpu_device::execute_run() } else { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } - CLKM(17,18); + clkm(17,18); break; } } @@ -3531,52 +3359,52 @@ void v30mz_cpu_device::execute_run() int32_t result,result2; m_modrm = fetch(); - tmp = GetRMWord(); - switch ( m_modrm & 0x38 ) + tmp = get_rm_word(); + switch (m_modrm & 0x38) { - case 0x00: /* TEST */ + case 0x00: // TEST tmp2 = fetch_word(); tmp &= tmp2; m_CarryVal = m_OverVal = 0; - set_SZPF_Word(tmp); - CLKM(1,2); + set_SZPF_word(tmp); + clkm(1,2); break; case 0x08: logerror("%s: %06x: Undefined opcode 0xf7 0x08\n", tag(), pc()); break; - case 0x10: /* NOT */ - PutbackRMWord(~tmp); - CLKM(1,3); + case 0x10: // NOT + store_ea_rm_word(~tmp); + clkm(1,3); break; - case 0x18: /* NEG */ + case 0x18: // NEG m_CarryVal = (tmp!=0) ? 1 : 0; tmp = (~tmp) + 1; - set_SZPF_Word(tmp); - PutbackRMWord(tmp); - CLKM(1,3); + set_SZPF_word(tmp); + store_ea_rm_word(tmp); + clkm(1,3); break; - case 0x20: /* MULU */ + case 0x20: // MULU uresult = m_regs.w[AW]*tmp; m_regs.w[AW] = uresult & 0xffff; - m_regs.w[DW] = ((uint32_t)uresult)>>16; + m_regs.w[DW] = ((uint32_t)uresult) >> 16; m_CarryVal = m_OverVal = (m_regs.w[DW] != 0) ? 1 : 0; - CLKM(3,4); + clkm(3,4); break; - case 0x28: /* MUL */ + case 0x28: // MUL result = (int32_t)((int16_t)m_regs.w[AW]) * (int32_t)((int16_t)tmp); m_regs.w[AW] = result & 0xffff; m_regs.w[DW] = result >> 16; m_CarryVal = m_OverVal = (m_regs.w[DW] != 0) ? 1 : 0; - CLKM(3,4); + clkm(3,4); break; - case 0x30: /* DIVU */ + case 0x30: // DIVU if (tmp) { uresult = (((uint32_t)m_regs.w[DW]) << 16) | m_regs.w[AW]; uresult2 = uresult % tmp; if ((uresult /= tmp) > 0xffff) { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } else { @@ -3586,18 +3414,18 @@ void v30mz_cpu_device::execute_run() } else { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } - CLKM(23,24); + clkm(23,24); break; - case 0x38: /* DIV */ + case 0x38: // DIV if (tmp) { result = ((uint32_t)m_regs.w[DW] << 16) + m_regs.w[AW]; result2 = result % (int32_t)((int16_t)tmp); if ((result /= (int32_t)((int16_t)tmp)) > 0xffff) { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } else { @@ -3607,9 +3435,9 @@ void v30mz_cpu_device::execute_run() } else { - interrupt(0); + interrupt(DIVIDE_ERROR_INT); } - CLKM(24,25); + clkm(24,25); break; } } @@ -3618,56 +3446,56 @@ void v30mz_cpu_device::execute_run() case 0xf8: // i_clc m_CarryVal = 0; - CLK(4); + clk(4); break; case 0xf9: // i_stc m_CarryVal = 1; - CLK(4); + clk(4); break; case 0xfa: // i_di m_IF = 0; - CLK(4); + clk(4); break; case 0xfb: // i_ei m_IF = 1; - CLK(4); + clk(4); break; case 0xfc: // i_cld m_DF = 0; - CLK(4); + clk(4); break; case 0xfd: // i_std m_DF = 1; - CLK(4); + clk(4); break; case 0xfe: // i_fepre { uint32_t tmp, tmp1; m_modrm = fetch(); - tmp = GetRMByte(); - switch ( m_modrm & 0x38 ) + tmp = get_rm_byte(); + switch (m_modrm & 0x38) { - case 0x00: /* INC */ - tmp1 = tmp+1; - m_OverVal = (tmp==0x7f); + case 0x00: // INC + tmp1 = tmp + 1; + m_OverVal = (tmp == 0x7f); set_AF(tmp1,tmp,1); - set_SZPF_Byte(tmp1); - PutbackRMByte(tmp1); - CLKM(1,3); + set_SZPF_byte(tmp1); + store_ea_rm_byte(tmp1); + clkm(1,3); break; - case 0x08: /* DEC */ - tmp1 = tmp-1; - m_OverVal = (tmp==0x80); + case 0x08: // DEC + tmp1 = tmp - 1; + m_OverVal = (tmp == 0x80); set_AF(tmp1,tmp,1); - set_SZPF_Byte(tmp1); - PutbackRMByte(tmp1); - CLKM(1,3); + set_SZPF_byte(tmp1); + store_ea_rm_byte(tmp1); + clkm(1,3); break; default: logerror("%s: %06x: FE Pre with unimplemented mod\n", tag(), pc()); @@ -3680,50 +3508,54 @@ void v30mz_cpu_device::execute_run() { uint32_t tmp, tmp1; m_modrm = fetch(); - tmp = GetRMWord(); - switch ( m_modrm & 0x38 ) + tmp = get_rm_word(); + switch (m_modrm & 0x38) { - case 0x00: /* INC */ - tmp1 = tmp+1; - m_OverVal = (tmp==0x7fff); - set_AF(tmp1,tmp,1); - set_SZPF_Word(tmp1); - PutbackRMWord(tmp1); - CLKM(1,3); + case 0x00: // INC + tmp1 = tmp + 1; + m_OverVal = (tmp == 0x7fff); + set_AF(tmp1, tmp, 1); + set_SZPF_word(tmp1); + store_ea_rm_word(tmp1); + clkm(1,3); break; - case 0x08: /* DEC */ - tmp1 = tmp-1; - m_OverVal = (tmp==0x8000); - set_AF(tmp1,tmp,1); - set_SZPF_Word(tmp1); - PutbackRMWord(tmp1); - CLKM(1,3); + case 0x08: // DEC + tmp1 = tmp - 1; + m_OverVal = (tmp == 0x8000); + set_AF(tmp1, tmp, 1); + set_SZPF_word(tmp1); + store_ea_rm_word(tmp1); + clkm(1,3); break; - case 0x10: /* CALL */ - PUSH(m_ip); + case 0x10: // CALL + push(m_ip); m_ip = tmp; - CLKM(5,6); + init_prefetch(); + clkm(5,6); break; - case 0x18: /* CALL FAR */ - tmp1 = m_sregs[CS]; - m_sregs[CS] = GetnextRMWord(); - PUSH(tmp1); - PUSH(m_ip); + case 0x18: // CALL FAR + tmp1 = m_sregs[PS]; + m_sregs[PS] = get_next_rm_word(); + push(tmp1); + push(m_ip); m_ip = tmp; - CLKM(5,12); + init_prefetch(); + clkm(5,12); break; - case 0x20: /* JMP */ + case 0x20: // jmp m_ip = tmp; - CLKM(4,5); + init_prefetch(); + clkm(4,5); break; - case 0x28: /* JMP FAR */ + case 0x28: // jmp FAR m_ip = tmp; - m_sregs[CS] = GetnextRMWord(); - CLK(10); + m_sregs[PS] = get_next_rm_word(); + init_prefetch(); + clk(10); break; case 0x30: - PUSH(tmp); - CLK(1); + push(tmp); + clk(1); break; default: logerror("%s: %06x: FF Pre with unimplemented mod\n", tag(), pc()); diff --git a/src/devices/cpu/v30mz/v30mz.h b/src/devices/cpu/v30mz/v30mz.h index 7d8d06c7b68..770da50d954 100644 --- a/src/devices/cpu/v30mz/v30mz.h +++ b/src/devices/cpu/v30mz/v30mz.h @@ -5,17 +5,12 @@ #include "cpu/nec/necdasm.h" -struct nec_config -{ - const uint8_t* v25v35_decryptiontable; // internal decryption table -}; - enum { NEC_PC=0, NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY, - NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS, - NEC_VECTOR, NEC_PENDING + NEC_FLAGS, NEC_DS1, NEC_PS, NEC_SS, NEC_DS0, + NEC_VECTOR, NEC_PENDING, NEC_PFP }; @@ -29,6 +24,9 @@ public: // construction/destruction v30mz_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + auto vector_cb() { return m_vector_func.bind(); } + uint32_t pc(); + protected: // device-level overrides virtual void device_start() override; @@ -47,6 +45,8 @@ protected: // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + virtual void state_import(const device_state_entry &entry) override; + virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides virtual std::unique_ptr create_disassembler() override; @@ -54,67 +54,66 @@ protected: void interrupt(int int_num); - inline uint32_t pc(); // Accessing memory and io - inline uint8_t read_byte(uint32_t addr); - inline uint16_t read_word(uint32_t addr); - inline void write_byte(uint32_t addr, uint8_t data); - inline void write_word(uint32_t addr, uint16_t data); + inline uint8_t read_byte(uint16_t segment, uint16_t addr); + inline uint16_t read_word(uint16_t segment, uint16_t addr); + inline void write_byte(uint16_t segment, uint16_t addr, uint8_t data); + inline void write_word(uint16_t segment, uint16_t addr, uint16_t data); inline uint8_t read_port(uint16_t port); + inline uint16_t read_port_word(uint16_t port); inline void write_port(uint16_t port, uint8_t data); + inline void write_port_word(uint16_t port, uint16_t data); // Executing instructions + void read_prefetch(); + void init_prefetch(); inline uint8_t fetch_op(); inline uint8_t fetch(); inline uint16_t fetch_word(); inline uint8_t repx_op(); // Cycles passed while executing instructions - inline void CLK(uint32_t cycles); - inline void CLKM(uint32_t cycles_reg, uint32_t cycles_mem); + inline void clk(uint32_t cycles); + inline void clkm(uint32_t cycles_reg, uint32_t cycles_mem); // Memory handling while executing instructions - inline uint32_t default_base(int seg); - inline uint32_t get_ea(); - inline void PutbackRMByte(uint8_t data); - inline void PutbackRMWord(uint16_t data); - inline void RegByte(uint8_t data); - inline void RegWord(uint16_t data); - inline uint8_t RegByte(); - inline uint16_t RegWord(); - inline uint16_t GetRMWord(); - inline uint16_t GetnextRMWord(); - inline uint8_t GetRMByte(); - inline void PutMemB(int seg, uint16_t offset, uint8_t data); - inline void PutMemW(int seg, uint16_t offset, uint16_t data); - inline uint8_t GetMemB(int seg, uint16_t offset); - inline uint16_t GetMemW(int seg, uint16_t offset); - inline void PutImmRMWord(); - inline void PutRMWord(uint16_t val); - inline void PutRMByte(uint8_t val); - inline void PutImmRMByte(); - inline void DEF_br8(); - inline void DEF_wr16(); - inline void DEF_r8b(); - inline void DEF_r16w(); - inline void DEF_ald8(); - inline void DEF_axd16(); + inline uint16_t default_base(int seg); + inline void get_ea(); + inline void store_ea_rm_byte(uint8_t data); + inline void store_ea_rm_word(uint16_t data); + inline void reg_byte(uint8_t data); + inline void reg_word(uint16_t data); + inline uint8_t reg_byte(); + inline uint16_t reg_word(); + inline uint16_t get_rm_word(); + inline uint16_t get_next_rm_word(); + inline uint8_t get_rm_byte(); + inline void put_imm_rm_word(); + inline void put_rm_word(uint16_t val); + inline void put_rm_byte(uint8_t val); + inline void put_imm_rm_byte(); + inline void def_br8(); + inline void def_wr16(); + inline void def_r8b(); + inline void def_r16w(); + inline void def_ald8(); + inline void def_awd16(); // Flags - inline void set_CFB(uint32_t x); - inline void set_CFW(uint32_t x); - inline void set_AF(uint32_t x,uint32_t y,uint32_t z); + inline void set_CF_byte(uint32_t x); + inline void set_CF_word(uint32_t x); + inline void set_AF(uint32_t x, uint32_t y, uint32_t z); inline void set_SF(uint32_t x); inline void set_ZF(uint32_t x); inline void set_PF(uint32_t x); - inline void set_SZPF_Byte(uint32_t x); - inline void set_SZPF_Word(uint32_t x); - inline void set_OFW_Add(uint32_t x,uint32_t y,uint32_t z); - inline void set_OFB_Add(uint32_t x,uint32_t y,uint32_t z); - inline void set_OFW_Sub(uint32_t x,uint32_t y,uint32_t z); - inline void set_OFB_Sub(uint32_t x,uint32_t y,uint32_t z); - inline uint16_t CompressFlags() const; - inline void ExpandFlags(uint16_t f); + inline void set_SZPF_byte(uint32_t x); + inline void set_SZPF_word(uint32_t x); + inline void set_OF_word_add(uint32_t x, uint32_t y, uint32_t z); + inline void set_OF_byte_add(uint32_t x, uint32_t y, uint32_t z); + inline void set_OF_word_sub(uint32_t x, uint32_t y, uint32_t z); + inline void set_OF_byte_sub(uint32_t x, uint32_t y, uint32_t z); + inline uint16_t compress_flags() const; + inline void expand_flags(uint16_t f); // rep instructions inline void i_insb(); @@ -134,54 +133,61 @@ protected: inline void i_popf(); // sub implementations - inline void ADDB(); - inline void ADDW(); - inline void SUBB(); - inline void SUBW(); - inline void ORB(); - inline void ORW(); - inline void ANDB(); - inline void ANDW(); - inline void XORB(); - inline void XORW(); - inline void ROL_BYTE(); - inline void ROL_WORD(); - inline void ROR_BYTE(); - inline void ROR_WORD(); - inline void ROLC_BYTE(); - inline void ROLC_WORD(); - inline void RORC_BYTE(); - inline void RORC_WORD(); - inline void SHL_BYTE(uint8_t c); - inline void SHL_WORD(uint8_t c); - inline void SHR_BYTE(uint8_t c); - inline void SHR_WORD(uint8_t c); - inline void SHRA_BYTE(uint8_t c); - inline void SHRA_WORD(uint8_t c); - inline void XchgAWReg(uint8_t reg); - inline void IncWordReg(uint8_t reg); - inline void DecWordReg(uint8_t reg); - inline void PUSH(uint16_t data); - inline uint16_t POP(); - inline void JMP(bool cond); - inline void ADJ4(int8_t param1, int8_t param2); - inline void ADJB(int8_t param1, int8_t param2); + inline void add_byte(); + inline void add_word(); + inline void sub_byte(); + inline void sub_word(); + inline void or_byte(); + inline void or_word(); + inline void and_byte(); + inline void and_word(); + inline void xor_byte(); + inline void xor_word(); + inline void rol_byte(); + inline void rol_word(); + inline void ror_byte(); + inline void ror_word(); + inline void rolc_byte(); + inline void rolc_word(); + inline void rorc_byte(); + inline void rorc_word(); + inline void shl_byte(uint8_t c); + inline void shl_word(uint8_t c); + inline void shr_byte(uint8_t c); + inline void shr_word(uint8_t c); + inline void shra_byte(uint8_t c); + inline void shra_word(uint8_t c); + inline void xchg_AW_reg(uint8_t reg); + inline void inc_word_reg(uint8_t reg); + inline void dec_word_reg(uint8_t reg); + inline void push(uint16_t data); + inline uint16_t pop(); + inline void jmp(bool cond); + inline void adj4(int8_t param1, int8_t param2); + inline void adjb(int8_t param1, int8_t param2); address_space_config m_program_config; address_space_config m_io_config; union - { /* eight general registers */ - uint16_t w[8]; /* viewed as 16 bits registers */ - uint8_t b[16]; /* or as 8 bit registers */ + { // eight general registers + uint16_t w[8]; // viewed as 16 bits registers + uint8_t b[16]; // or as 8 bit registers } m_regs; uint16_t m_sregs[4]; uint16_t m_ip; + uint16_t m_pfp; // prefetch pointer + static const size_t PREFETCH_MAX_SIZE = 16; + static const size_t PREFETCH_QUEUE_SIZE = 8; + uint8_t m_prefetch_queue[PREFETCH_MAX_SIZE]; + int m_prefetch_queue_head; + int m_prefetch_queue_tail; + bool m_prefetch_fill_needed; int32_t m_SignVal; - uint32_t m_AuxVal, m_OverVal, m_ZeroVal, m_CarryVal, m_ParityVal; /* 0 or non-0 valued flags */ - uint8_t m_TF, m_IF, m_DF, m_MF; /* 0 or 1 valued flags */ /* OB[19.07.99] added Mode Flag V30 */ + uint32_t m_AuxVal, m_OverVal, m_ZeroVal, m_CarryVal, m_ParityVal; // 0 or non-0 valued flags + uint8_t m_TF, m_IF, m_DF, m_MF; // 0 or 1 valued flags. OB[19.07.99] added Mode Flag V30 uint32_t m_int_vector; uint32_t m_pending_irq; uint32_t m_nmi_state; @@ -189,18 +195,17 @@ protected: uint8_t m_no_interrupt; uint8_t m_fire_trap; - memory_access<20, 0, 0, ENDIANNESS_LITTLE>::cache m_cache; - memory_access<20, 0, 0, ENDIANNESS_LITTLE>::specific m_program; - memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_io; + memory_access<20, 1, 0, ENDIANNESS_LITTLE>::cache m_cache; + memory_access<20, 1, 0, ENDIANNESS_LITTLE>::specific m_program; + memory_access<16, 1, 0, ENDIANNESS_LITTLE>::specific m_io; int m_icount; - uint32_t m_prefix_base; /* base address of the latest prefix segment */ - bool m_seg_prefix; /* prefix segment indicator */ - bool m_seg_prefix_next; /* prefix segment for next instruction */ + uint16_t m_prefix_base; // base address of the latest prefix segment + bool m_seg_prefix; // prefix segment indicator + bool m_seg_prefix_next; // prefix segment for next instruction - uint32_t m_ea; uint16_t m_eo; - uint16_t m_e16; + uint16_t m_ea_seg; // Used during execution of instructions uint8_t m_modrm; @@ -220,6 +225,9 @@ protected: int b[256]; } RM; } m_Mod_RM; + + devcb_read32 m_vector_func; + uint16_t m_debugger_temp; }; #endif // MAME_CPU_V32MZ_V30MZ_H diff --git a/src/mame/audio/wswan.cpp b/src/mame/audio/wswan.cpp index 6f956ffb57c..35c9e5f54d6 100644 --- a/src/mame/audio/wswan.cpp +++ b/src/mame/audio/wswan.cpp @@ -54,7 +54,7 @@ wswan_sound_device::wswan_sound_device(const machine_config &mconfig, const char { } -constexpr int clk_div = 64; +static constexpr int clk_div = 64; //------------------------------------------------- // device_start - device-specific startup @@ -80,42 +80,15 @@ void wswan_sound_device::device_start() save_item(NAME(m_external_speaker)); save_item(NAME(m_noise_shift)); save_item(NAME(m_master_volume)); - - save_item(NAME(m_audio1.freq)); - save_item(NAME(m_audio1.period)); - save_item(NAME(m_audio1.pos)); - save_item(NAME(m_audio1.vol_left)); - save_item(NAME(m_audio1.vol_right)); - save_item(NAME(m_audio1.on)); - save_item(NAME(m_audio1.offset)); - save_item(NAME(m_audio1.signal)); - - save_item(NAME(m_audio2.freq)); - save_item(NAME(m_audio2.period)); - save_item(NAME(m_audio2.pos)); - save_item(NAME(m_audio2.vol_left)); - save_item(NAME(m_audio2.vol_right)); - save_item(NAME(m_audio2.on)); - save_item(NAME(m_audio2.offset)); - save_item(NAME(m_audio2.signal)); - - save_item(NAME(m_audio3.freq)); - save_item(NAME(m_audio3.period)); - save_item(NAME(m_audio3.pos)); - save_item(NAME(m_audio3.vol_left)); - save_item(NAME(m_audio3.vol_right)); - save_item(NAME(m_audio3.on)); - save_item(NAME(m_audio3.offset)); - save_item(NAME(m_audio3.signal)); - - save_item(NAME(m_audio4.freq)); - save_item(NAME(m_audio4.period)); - save_item(NAME(m_audio4.pos)); - save_item(NAME(m_audio4.vol_left)); - save_item(NAME(m_audio4.vol_right)); - save_item(NAME(m_audio4.on)); - save_item(NAME(m_audio4.offset)); - save_item(NAME(m_audio4.signal)); + save_item(NAME(m_system_volume)); + save_item(STRUCT_MEMBER(m_audio, freq)); + save_item(STRUCT_MEMBER(m_audio, period)); + save_item(STRUCT_MEMBER(m_audio, pos)); + save_item(STRUCT_MEMBER(m_audio, vol_left)); + save_item(STRUCT_MEMBER(m_audio, vol_right)); + save_item(STRUCT_MEMBER(m_audio, on)); + save_item(STRUCT_MEMBER(m_audio, offset)); + save_item(STRUCT_MEMBER(m_audio, signal)); } void wswan_sound_device::device_clock_changed() @@ -134,33 +107,21 @@ void wswan_sound_device::rom_bank_updated() void wswan_sound_device::device_reset() { - m_audio1.on = 0; - m_audio1.signal = 0; - m_audio1.offset = 0; - m_audio1.pos = 0; - m_audio2.on = 0; - m_audio2.signal = 0; - m_audio2.offset = 0; - m_audio2.pos = 0; - m_audio3.on = 0; - m_audio3.signal = 0; - m_audio3.offset = 0; - m_audio3.pos = 0; - m_audio4.on = 0; - m_audio4.signal = 0; - m_audio4.offset = 0; - m_audio4.pos = 0; + for (int i = 0; i < 4; i++) + { + m_audio[i].on = 0; + m_audio[i].signal = 0; + m_audio[i].offset = 0; + m_audio[i].pos = 0; + } m_noise_output = 0; } int wswan_sound_device::fetch_sample(int channel, int offset) { - uint8_t b = read_byte(m_sample_address + ((channel & 3) << 4) + ((offset & 0x1f) >> 1)); + u16 w = read_word(m_sample_address + ((channel & 3) << 4) + ((offset >> 1) & 0x0e)); - if (offset & 1) - return b >> 4; - else - return b & 0xf; + return (w >> ((offset & 0x03) * 4)) & 0x0f; } //------------------------------------------------- @@ -169,85 +130,83 @@ int wswan_sound_device::fetch_sample(int channel, int offset) void wswan_sound_device::sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) { - s32 sample, left, right; - auto &outputl = outputs[0]; auto &outputr = outputs[1]; for (int sampindex = 0; sampindex < outputl.samples(); sampindex++) { - left = right = 0; + s32 left = 0, right = 0; - if ( m_audio1.on ) + if (m_audio[0].on) { - sample = m_audio1.signal; - m_audio1.pos += clk_div; - if (m_audio1.pos >= m_audio1.period) + s32 sample = m_audio[0].signal; + m_audio[0].pos += clk_div; + if (m_audio[0].pos >= m_audio[0].period) { - m_audio1.pos -= m_audio1.period; - m_audio1.signal = fetch_sample(0, m_audio1.offset++); + m_audio[0].pos -= m_audio[0].period; + m_audio[0].signal = fetch_sample(0, m_audio[0].offset++); } - left += m_audio1.vol_left * sample; - right += m_audio1.vol_right * sample; + left += m_audio[0].vol_left * sample; + right += m_audio[0].vol_right * sample; } - if ( m_audio2.on ) + if (m_audio[1].on) { - if ( m_audio2_voice ) + if (m_audio2_voice) { - uint8_t voice_data = m_audio2.vol_left << 4 | m_audio2.vol_right; + u8 voice_data = (m_audio[1].vol_left << 4) | m_audio[1].vol_right; left += voice_data * (m_master_volume & 0x0f); right += voice_data * (m_master_volume & 0x0f); } else { - sample = m_audio2.signal; - m_audio2.pos += clk_div; - if (m_audio2.pos >= m_audio2.period) + s32 sample = m_audio[1].signal; + m_audio[1].pos += clk_div; + if (m_audio[1].pos >= m_audio[1].period) { - m_audio2.pos -= m_audio2.period; - m_audio2.signal = fetch_sample(1, m_audio2.offset++); + m_audio[1].pos -= m_audio[1].period; + m_audio[1].signal = fetch_sample(1, m_audio[1].offset++); } - left += m_audio2.vol_left * sample; - right += m_audio2.vol_right * sample; + left += m_audio[1].vol_left * sample; + right += m_audio[1].vol_right * sample; } } - if ( m_audio3.on ) + if (m_audio[2].on) { - sample = m_audio3.signal; - m_audio3.pos += clk_div; - if (m_audio3.pos >= m_audio3.period) + s32 sample = m_audio[2].signal; + m_audio[2].pos += clk_div; + if (m_audio[2].pos >= m_audio[2].period) { - m_audio3.pos -= m_audio3.period; - m_audio3.signal = fetch_sample(2, m_audio3.offset++); + m_audio[2].pos -= m_audio[2].period; + m_audio[2].signal = fetch_sample(2, m_audio[2].offset++); } - if ( m_audio3_sweep && m_sweep_time ) + if (m_audio3_sweep && m_sweep_time) { m_sweep_count += clk_div; - if ( m_sweep_count >= m_sweep_time ) + if (m_sweep_count >= m_sweep_time) { m_sweep_count -= m_sweep_time; - m_audio3.freq += m_sweep_step; - m_audio3.freq &= 0x7ff; - m_audio3.period = 2048 - m_audio3.freq; + m_audio[2].freq += m_sweep_step; + m_audio[2].freq &= 0x7ff; + m_audio[2].period = 2048 - m_audio[2].freq; } } - left += m_audio3.vol_left * sample; - right += m_audio3.vol_right * sample; + left += m_audio[2].vol_left * sample; + right += m_audio[2].vol_right * sample; } - if ( m_audio4.on ) + if (m_audio[3].on) { - sample = m_audio4.signal; - m_audio4.pos += clk_div; - if (m_audio4.pos >= m_audio4.period) + s32 sample = m_audio[3].signal; + m_audio[3].pos += clk_div; + if (m_audio[3].pos >= m_audio[3].period) { if (m_audio4_noise) - m_audio4.signal = m_noise_output ? 0xf : 0; + m_audio[3].signal = m_noise_output ? 0xf : 0; else - m_audio4.signal = fetch_sample(3, m_audio4.offset++); + m_audio[3].signal = fetch_sample(3, m_audio[3].offset++); - m_audio4.pos -= m_audio4.period; + m_audio[3].pos -= m_audio[3].period; if (m_noise_reset) { @@ -264,8 +223,8 @@ void wswan_sound_device::sound_stream_update(sound_stream &stream, std::vector> 5); @@ -274,116 +233,155 @@ void wswan_sound_device::sound_stream_update(sound_stream &stream, std::vectorfreq = freq; - ch->period = 2048 - freq; + m_channel->update(); + switch (offset) { + case 0x80 / 2: + case 0x82 / 2: + case 0x84 / 2: + case 0x86 / 2: + return m_audio[offset & 0x03].freq; + case 0x88 / 2: + return (m_audio[0].vol_left << 4) | m_audio[0].vol_right | + (m_audio[1].vol_left << 12) | (m_audio[1].vol_right << 8); + case 0x8a / 2: + return (m_audio[2].vol_left << 4) | m_audio[2].vol_right | + (m_audio[3].vol_left << 12) | (m_audio[3].vol_right << 8); + case 0x8c / 2: + return m_sweep_step | (((m_sweep_time / 8192) - 1) << 8); + case 0x8e / 2: + return m_noise_type | (m_noise_reset ? 0x08 : 0x00) | (m_noise_enable ? 0x10 : 0x00) | + ((m_sample_address << 2) & 0xff00); + case 0x90 / 2: + return (m_audio[0].on ? 0x01 : 0x00) | + (m_audio[1].on ? 0x02 : 0x00) | + (m_audio[2].on ? 0x04 : 0x00) | + (m_audio[3].on ? 0x08 : 0x00) | + (m_audio2_voice ? 0x20 : 0x00) | + (m_audio3_sweep ? 0x40 : 0x00) | + (m_audio4_noise ? 0x80 : 0x00) | + (m_mono ? 0x0100 : 0x00) | (m_output_volume << 9) | + (m_external_stereo ? 0x0800 : 0x00) | + (m_external_speaker ? 0x00 : 0x00); // TODO 0x80 is set when external speaker is connected + case 0x92 / 2: + return m_noise_shift; + case 0x94 / 2: + return m_master_volume; + case 0x9e / 2: + return m_system_volume; + } + return 0; } -void wswan_sound_device::port_w(offs_t offset, uint8_t data) +void wswan_sound_device::port_w(offs_t offset, u16 data, u16 mem_mask) { m_channel->update(); - switch( offset ) + switch (offset) { - case 0x80: /* Audio 1 freq (lo) */ - wswan_ch_set_freq(&m_audio1, (m_audio1.freq & 0xff00) | data); - break; - - case 0x81: /* Audio 1 freq (hi) */ - wswan_ch_set_freq(&m_audio1, (data << 8 ) | (m_audio1.freq & 0x00ff)); - break; - - case 0x82: /* Audio 2 freq (lo) */ - wswan_ch_set_freq(&m_audio2, (m_audio2.freq & 0xff00) | data); - break; - - case 0x83: /* Audio 2 freq (hi) */ - wswan_ch_set_freq(&m_audio2, (data << 8 ) | (m_audio2.freq & 0x00ff)); - break; - - case 0x84: /* Audio 3 freq (lo) */ - wswan_ch_set_freq(&m_audio3, (m_audio3.freq & 0xff00) | data); - break; - - case 0x85: /* Audio 3 freq (hi) */ - wswan_ch_set_freq(&m_audio3, (data << 8) | (m_audio3.freq & 0x00ff)); - break; - - case 0x86: /* Audio 4 freq (lo) */ - wswan_ch_set_freq(&m_audio4, (m_audio4.freq & 0xff00) | data); - break; - - case 0x87: /* Audio 4 freq (hi) */ - wswan_ch_set_freq(&m_audio4, (data << 8) | (m_audio4.freq & 0x00ff)); - break; - - case 0x88: /* Audio 1 volume */ - m_audio1.vol_left = ( data & 0xF0 ) >> 4; - m_audio1.vol_right = data & 0x0F; - break; - - case 0x89: /* Audio 2 volume */ - m_audio2.vol_left = ( data & 0xF0 ) >> 4; - m_audio2.vol_right = data & 0x0F; - break; - - case 0x8A: /* Audio 3 volume */ - m_audio3.vol_left = ( data & 0xF0 ) >> 4; - m_audio3.vol_right = data & 0x0F; - break; - - case 0x8B: /* Audio 4 volume */ - m_audio4.vol_left = ( data & 0xF0 ) >> 4; - m_audio4.vol_right = data & 0x0F; + case 0x80 / 2: // Audio 1 freq + case 0x82 / 2: // Audio 2 freq + case 0x84 / 2: // Audio 3 freq + case 0x86 / 2: // Audio 4 freq + COMBINE_DATA(&m_audio[offset & 0x03].freq); + m_audio[offset & 0x03].freq &= 0x7ff; + m_audio[offset & 0x03].period = 2048 - m_audio[offset & 0x03].freq; break; - case 0x8C: /* Sweep step */ - m_sweep_step = (int8_t)data; - break; - - case 0x8D: /* Sweep time */ - m_sweep_time = 8192 * (data + 1); + case 0x88 / 2: + // Audio 1 volume + if (ACCESSING_BITS_0_7) + { + m_audio[0].vol_left = (data >> 4) & 0x0f; + m_audio[0].vol_right = data & 0x0f; + } + // Audio 2 volume + if (ACCESSING_BITS_8_15) + { + m_audio[1].vol_left = (data >> 12) & 0x0f; + m_audio[1].vol_right = (data >> 8) & 0x0f; + } break; - case 0x8E: /* Noise control */ - m_noise_type = data & 0x07; - m_noise_reset = ( data & 0x08 ) >> 3; - m_noise_enable = ( data & 0x10 ) >> 4; + case 0x8a / 2: + // Audio 3 volume + if (ACCESSING_BITS_0_7) + { + m_audio[2].vol_left = (data >> 4) & 0x0f; + m_audio[2].vol_right = data & 0x0f; + } + // Audio 4 volume + if (ACCESSING_BITS_8_15) + { + m_audio[3].vol_left = (data >> 12) & 0x0f; + m_audio[3].vol_right = (data >> 8) & 0x0f; + } break; - case 0x8F: /* Sample location */ - m_sample_address = data << 6; + case 0x8c / 2: + // Sweep step + if (ACCESSING_BITS_0_7) + { + m_sweep_step = (int8_t)(data & 0xff); + } + // Sweep time + if (ACCESSING_BITS_8_15) + { + m_sweep_time = 8192 * ((data >> 8) + 1); + } break; - case 0x90: /* Audio control */ - m_audio1.on = data & 0x01; - m_audio2.on = ( data & 0x02 ) >> 1; - m_audio3.on = ( data & 0x04 ) >> 2; - m_audio4.on = ( data & 0x08 ) >> 3; - m_audio2_voice = ( data & 0x20 ) >> 5; - m_audio3_sweep = ( data & 0x40 ) >> 6; - m_audio4_noise = ( data & 0x80 ) >> 7; + case 0x8e / 2: + // Noise control + if (ACCESSING_BITS_0_7) + { + m_noise_type = data & 0x07; + m_noise_reset = BIT(data, 3); + m_noise_enable = BIT(data, 4); + } + // Sample location + if (ACCESSING_BITS_8_15) + { + m_sample_address = (data & 0xff00) >> 2; + } break; - case 0x91: /* Audio output */ - m_mono = data & 0x01; - m_output_volume = ( data & 0x06 ) >> 1; - m_external_stereo = ( data & 0x08 ) >> 3; - m_external_speaker = 1; + case 0x90 / 2: + // Audio control + if (ACCESSING_BITS_0_7) + { + m_audio[0].on = BIT(data, 0); + m_audio[1].on = BIT(data, 1); + m_audio[2].on = BIT(data, 2); + m_audio[3].on = BIT(data, 3); + m_audio2_voice = BIT(data, 5); + m_audio3_sweep = BIT(data, 6); + m_audio4_noise = BIT(data, 7); + } + // Audio output + if (ACCESSING_BITS_8_15) + { + m_mono = BIT(data, 8); + m_output_volume = ((data >> 9) & 0x03); + m_external_stereo = BIT(data, 11); + m_external_speaker = 1; + } break; - case 0x92: /* Noise counter shift register (lo) */ - m_noise_shift = ( m_noise_shift & 0xFF00 ) | data; + case 0x92 / 2: // Noise counter shift register + COMBINE_DATA(&m_noise_shift); + m_noise_shift &= 0x7fff; break; - case 0x93: /* Noise counter shift register (hi) */ - m_noise_shift = ( ( data & 0x7f ) << 8 ) | ( m_noise_shift & 0x00FF ); + case 0x94 / 2: // Master volume + if (ACCESSING_BITS_0_7) + m_master_volume = data & 0xff; break; - case 0x94: /* Master volume */ - m_master_volume = data; + case 0x9e / 2: // WSC volume setting (0, 1, 2, 3) (TODO) + if (ACCESSING_BITS_0_7) + m_system_volume = data & 0x03; break; } } diff --git a/src/mame/audio/wswan.h b/src/mame/audio/wswan.h index f21ad6adbc5..4029d0f23a1 100644 --- a/src/mame/audio/wswan.h +++ b/src/mame/audio/wswan.h @@ -1,11 +1,5 @@ // license:BSD-3-Clause // copyright-holders:Wilbert Pol -/***************************************************************************** - * - * includes/wswan.h - * - ****************************************************************************/ - #ifndef MAME_AUDIO_WSWAN_H #define MAME_AUDIO_WSWAN_H @@ -21,12 +15,13 @@ class wswan_sound_device : public device_t, public device_sound_interface, - public device_rom_interface<14> + public device_rom_interface<14,1> { public: - wswan_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + wswan_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - void port_w(offs_t offset, uint8_t data); + void port_w(offs_t offset, u16 data, u16 mem_mask); + u16 port_r(offs_t offset, u16 mem_mask); protected: struct CHAN @@ -41,14 +36,14 @@ protected: offset(0), signal(0) { } - uint16_t freq; /* frequency */ - uint16_t period; /* period */ - uint32_t pos; /* position */ - uint8_t vol_left; /* volume left */ - uint8_t vol_right; /* volume right */ - uint8_t on; /* on/off */ - uint8_t offset; /* sample offset */ - uint8_t signal; /* signal */ + u16 freq; + u16 period; + u32 pos; + u8 vol_left; + u8 vol_right; + u8 on; + u8 offset; + u8 signal; }; // device-level overrides @@ -62,31 +57,28 @@ protected: virtual void sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs) override; private: - void wswan_ch_set_freq( CHAN *ch, uint16_t freq ); int fetch_sample(int channel, int offset); sound_stream *m_channel; - CHAN m_audio1; /* Audio channel 1 */ - CHAN m_audio2; /* Audio channel 2 */ - CHAN m_audio3; /* Audio channel 3 */ - CHAN m_audio4; /* Audio channel 4 */ - int8_t m_sweep_step; /* Sweep step */ - uint32_t m_sweep_time; /* Sweep time */ - uint32_t m_sweep_count; /* Sweep counter */ - uint8_t m_noise_type; /* Noise generator type */ - uint8_t m_noise_reset; /* Noise reset */ - uint8_t m_noise_enable; /* Noise enable */ - uint8_t m_noise_output; /* Noise output */ - uint16_t m_sample_address; /* Sample address */ - uint8_t m_audio2_voice; /* Audio 2 voice */ - uint8_t m_audio3_sweep; /* Audio 3 sweep */ - uint8_t m_audio4_noise; /* Audio 4 noise */ - uint8_t m_mono; /* mono */ - uint8_t m_output_volume; /* output volume */ - uint8_t m_external_stereo; /* external stereo */ - uint8_t m_external_speaker; /* external speaker */ - uint16_t m_noise_shift; /* Noise counter shift register */ - uint8_t m_master_volume; /* Master volume */ + CHAN m_audio[4]; + s8 m_sweep_step; + u32 m_sweep_time; + u32 m_sweep_count; + u8 m_noise_type; + u8 m_noise_reset; + u8 m_noise_enable; + u8 m_noise_output; + u16 m_sample_address; + u8 m_audio2_voice; + u8 m_audio3_sweep; + u8 m_audio4_noise; + u8 m_mono; + u8 m_output_volume; + u8 m_external_stereo; + u8 m_external_speaker; + u16 m_noise_shift; + u8 m_master_volume; + u8 m_system_volume; }; DECLARE_DEVICE_TYPE(WSWAN_SND, wswan_sound_device) diff --git a/src/mame/drivers/wswan.cpp b/src/mame/drivers/wswan.cpp index dc1cc0d09a5..c770f0c5207 100644 --- a/src/mame/drivers/wswan.cpp +++ b/src/mame/drivers/wswan.cpp @@ -17,18 +17,10 @@ configuration menu. Known issues/TODOs: - - Add support for noise sound. - - Add support for voice sound. - - Add support for enveloped sound. - Perform video DMA at proper timing. - Add (real/proper) RTC support. - - Swan Crystal can handle up to 512Mbit ROMs?????? - - SRAM sizes should be in kbit instead of kbytes(?). This raises a few - interesting issues: - - mirror of smaller <64KBYTE/512kbit SRAM sizes - - banking when using 1M or 2M sram sizes - - The units likely came with the name "WONDERSWAN" configured in the - internal EEPOM + - Fix wonderwitch + - Make the flash rom changes save. ***************************************************************************/ @@ -64,34 +56,38 @@ public: m_region_maincpu(*this, "maincpu"), m_cursx(*this, "CURSX"), m_cursy(*this, "CURSY"), - m_buttons(*this, "BUTTONS") + m_buttons(*this, "BUTTONS"), + m_icons(*this, "icon%u", 0U) { } void wswan(machine_config &config); protected: // Interrupt flags - static const u8 WSWAN_IFLAG_STX = 0x01; - static const u8 WSWAN_IFLAG_KEY = 0x02; - static const u8 WSWAN_IFLAG_RTC = 0x04; - static const u8 WSWAN_IFLAG_SRX = 0x08; - static const u8 WSWAN_IFLAG_LCMP = 0x10; - static const u8 WSWAN_IFLAG_VBLTMR = 0x20; - static const u8 WSWAN_IFLAG_VBL = 0x40; - static const u8 WSWAN_IFLAG_HBLTMR = 0x80; + static constexpr u8 WSWAN_IFLAG_STX = 0x01; + static constexpr u8 WSWAN_IFLAG_KEY = 0x02; + static constexpr u8 WSWAN_IFLAG_RTC = 0x04; + static constexpr u8 WSWAN_IFLAG_SRX = 0x08; + static constexpr u8 WSWAN_IFLAG_LCMP = 0x10; + static constexpr u8 WSWAN_IFLAG_VBLTMR = 0x20; + static constexpr u8 WSWAN_IFLAG_VBL = 0x40; + static constexpr u8 WSWAN_IFLAG_HBLTMR = 0x80; // Interrupts - static const u8 WSWAN_INT_STX = 0; - static const u8 WSWAN_INT_KEY = 1; - static const u8 WSWAN_INT_RTC = 2; - static const u8 WSWAN_INT_SRX = 3; - static const u8 WSWAN_INT_LCMP = 4; - static const u8 WSWAN_INT_VBLTMR = 5; - static const u8 WSWAN_INT_VBL = 6; - static const u8 WSWAN_INT_HBLTMR = 7; - - static const u32 INTERNAL_EEPROM_SIZE = 1024; // 16kbit on WSC - static const u32 INTERNAL_EEPROM_SIZE_WS = 64; // 1kbit on WS + static constexpr u8 WSWAN_INT_STX = 0; + static constexpr u8 WSWAN_INT_KEY = 1; + static constexpr u8 WSWAN_INT_RTC = 2; + static constexpr u8 WSWAN_INT_SRX = 3; + static constexpr u8 WSWAN_INT_LCMP = 4; + static constexpr u8 WSWAN_INT_VBLTMR = 5; + static constexpr u8 WSWAN_INT_VBL = 6; + static constexpr u8 WSWAN_INT_HBLTMR = 7; + + static constexpr u32 INTERNAL_EEPROM_SIZE = 1024; // 16kbit on WSC + static constexpr u32 INTERNAL_EEPROM_SIZE_WS = 64; // 1kbit on WS + + // Labeled 12.3FXA on wonderswan color pcb + static constexpr XTAL X1 = 12.288_MHz_XTAL; enum enum_system { TYPE_WSWAN=0, TYPE_WSC }; @@ -104,26 +100,43 @@ protected: u8 enable = 0; // Enabled }; - required_device m_maincpu; + required_device m_maincpu; required_device m_vdp; required_device m_sound; required_device m_cart; - u8 m_ws_portram[256]; + u16 m_ws_portram[128]; u8 m_internal_eeprom[INTERNAL_EEPROM_SIZE * 2]; u8 m_system_type; sound_dma_t m_sound_dma; + u16 m_dma_source_offset; + u16 m_dma_source_segment; + u16 m_dma_destination; + u16 m_dma_length; + u16 m_dma_control; u8 m_bios_disabled; u8 m_rotate; + u32 m_vector; + u8 m_sys_control; + u8 m_irq_vector_base; + u8 m_serial_data; + u8 m_serial_control; + u8 m_irq_enable; + u8 m_irq_active; + u16 m_internal_eeprom_data; + u16 m_internal_eeprom_address; + u8 m_internal_eeprom_command; + u8 m_keypad; required_memory_region m_region_maincpu; required_ioport m_cursx; required_ioport m_cursy; required_ioport m_buttons; + output_finder<6> m_icons; - u8 bios_r(offs_t offset); - u8 port_r(offs_t offset); - void port_w(offs_t offset, u8 data); + u16 bios_r(offs_t offset, u16 mem_mask); + u16 port_r(offs_t offset, u16 mem_mask); + void port_w(offs_t offset, u16 data, u16 mem_mask); void set_irq_line(int irq); void dma_sound_cb(); @@ -140,8 +153,12 @@ protected: void handle_irqs(); void clear_irq_line(int irq); virtual u16 get_internal_eeprom_address(); + u32 get_vector() { return m_vector; } + void set_icons(u8 data); + void set_rotate_view(); }; + class wscolor_state : public wswan_state { public: @@ -155,25 +172,6 @@ protected: virtual u16 get_internal_eeprom_address() override; }; -static const uint8_t ws_portram_init[256] = -{ - 0x00, 0x00, 0x00/*?*/, 0xbb, 0x00, 0x00, 0x00, 0x26, 0xfe, 0xde, 0xf9, 0xfb, 0xdb, 0xd7, 0x7f, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9e, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x99, 0xfd, 0xb7, 0xdf, - 0x30, 0x57, 0x75, 0x76, 0x15, 0x73, 0x70/*77?*/, 0x77, 0x20, 0x75, 0x50, 0x36, 0x70, 0x67, 0x50, 0x77, - 0x57, 0x54, 0x75, 0x77, 0x75, 0x17, 0x37, 0x73, 0x50, 0x57, 0x60, 0x77, 0x70, 0x77, 0x10, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x87, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdb, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x83, 0x00, - 0x2f, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1 -}; void wswan_state::mem_map(address_map &map) { @@ -202,7 +200,7 @@ void wswan_state::snd_map(address_map &map) } -static INPUT_PORTS_START( wswan ) +static INPUT_PORTS_START(wswan) PORT_START("CURSX") PORT_BIT( 0x8, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("X4 - Left") PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("X3 - Down") @@ -221,7 +219,8 @@ static INPUT_PORTS_START( wswan ) PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Y1 - Up") PORT_CODE(KEYCODE_W) INPUT_PORTS_END -static GFXDECODE_START( gfx_wswan ) + +static GFXDECODE_START(gfx_wswan) GFXDECODE_END @@ -230,7 +229,7 @@ void wswan_state::palette(palette_device &palette) const { for (int i = 0; i < 16; i++) { - uint8_t const shade = i * (256 / 16); + u8 const shade = i * (256 / 16); palette.set_pen_color(15 - i, shade, shade, shade); } } @@ -253,29 +252,28 @@ static void wswan_cart(device_slot_interface &device) device.option_add_internal("ws_rom", WS_ROM_STD); device.option_add_internal("ws_sram", WS_ROM_SRAM); device.option_add_internal("ws_eeprom", WS_ROM_EEPROM); + device.option_add_internal("wwitch", WS_ROM_WWITCH); } void wswan_state::wswan(machine_config &config) { // Basic machine hardware - V30MZ(config, m_maincpu, 3.072_MHz_XTAL); + V30MZ(config, m_maincpu, X1 / 4); m_maincpu->set_addrmap(AS_PROGRAM, &wswan_state::mem_map); m_maincpu->set_addrmap(AS_IO, &wswan_state::io_map); + m_maincpu->vector_cb().set(FUNC(wswan_state::get_vector)); - WSWAN_VIDEO(config, m_vdp, 0); + WSWAN_VIDEO(config, m_vdp, X1 / 4); m_vdp->set_screen("screen"); m_vdp->set_vdp_type(wswan_video_device::VDP_TYPE_WSWAN); m_vdp->set_irq_callback(FUNC(wswan_state::set_irq_line)); m_vdp->set_dmasnd_callback(FUNC(wswan_state::dma_sound_cb)); + m_vdp->icons_cb().set(FUNC(wswan_state::set_icons)); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); -// screen.set_refresh_rate(75); -// screen.set_vblank_time(0); screen.set_screen_update("vdp", FUNC(wswan_video_device::screen_update)); -// screen.set_size(WSWAN_X_PIXELS, WSWAN_Y_PIXELS); -// screen.set_visarea(0*8, WSWAN_X_PIXELS - 1, 0, WSWAN_Y_PIXELS - 1); - screen.set_raw(3.072_MHz_XTAL, 256, 0, wswan_video_device::WSWAN_X_PIXELS, 159, 0, wswan_video_device::WSWAN_Y_PIXELS); + screen.set_raw(X1 / 4, 256, 0, wswan_video_device::WSWAN_X_PIXELS, 159, 0, wswan_video_device::WSWAN_Y_PIXELS); screen.set_palette("palette"); config.set_default_layout(layout_wswan); @@ -290,13 +288,13 @@ void wswan_state::wswan(machine_config &config) // sound hardware SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - WSWAN_SND(config, m_sound, 3.072_MHz_XTAL); + WSWAN_SND(config, m_sound, X1 / 4); m_sound->set_addrmap(0, &wswan_state::snd_map); m_sound->add_route(0, "lspeaker", 0.50); m_sound->add_route(1, "rspeaker", 0.50); // cartridge - WS_CART_SLOT(config, m_cart, 3.072_MHz_XTAL / 8, wswan_cart, nullptr); + WS_CART_SLOT(config, m_cart, X1 / 32, wswan_cart, nullptr); // software lists SOFTWARE_LIST(config, "cart_list").set_original("wswan"); @@ -327,50 +325,56 @@ void wscolor_state::wscolor(machine_config &config) void wswan_state::handle_irqs() { - if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_HBLTMR) + bool set_irq_line = false; + if (m_irq_enable & m_irq_active & WSWAN_IFLAG_HBLTMR) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_HBLTMR); // V30MZ + m_vector = m_irq_vector_base + WSWAN_INT_HBLTMR; + set_irq_line = true; } - else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBL) + else if (m_irq_enable & m_irq_active & WSWAN_IFLAG_VBL) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBL); // V30MZ + m_vector = m_irq_vector_base + WSWAN_INT_VBL; + set_irq_line = true; } - else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_VBLTMR) + else if (m_irq_enable & m_irq_active & WSWAN_IFLAG_VBLTMR) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_VBLTMR); // V30MZ + m_vector = m_irq_vector_base + WSWAN_INT_VBLTMR; + set_irq_line = true; } - else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_LCMP) + else if (m_irq_enable & m_irq_active & WSWAN_IFLAG_LCMP) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_LCMP); // V30MZ + m_vector = m_irq_vector_base + WSWAN_INT_LCMP; + set_irq_line = true; } - else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_SRX) + else if (m_irq_enable & m_irq_active & WSWAN_IFLAG_SRX) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_SRX); // V30MZ + m_vector = m_irq_vector_base + WSWAN_INT_SRX; + set_irq_line = true; } - else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_RTC) + else if (m_irq_enable & m_irq_active & WSWAN_IFLAG_RTC) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_RTC); // V30MZ + m_vector = m_irq_vector_base + WSWAN_INT_RTC; + set_irq_line = true; } - else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_KEY) + else if (m_irq_enable & m_irq_active & WSWAN_IFLAG_KEY) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_KEY); // V30MZ + m_vector = m_irq_vector_base + WSWAN_INT_KEY; + set_irq_line = true; } - else if (m_ws_portram[0xb2] & m_ws_portram[0xb6] & WSWAN_IFLAG_STX) + else if (m_irq_enable & m_irq_active & WSWAN_IFLAG_STX) { - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_ws_portram[0xb0] + WSWAN_INT_STX); // V30MZ - } - else - { - m_maincpu->set_input_line(0, CLEAR_LINE); + m_vector = m_irq_vector_base + WSWAN_INT_STX; + set_irq_line = true; } + m_maincpu->set_input_line(0, set_irq_line ? ASSERT_LINE : CLEAR_LINE); } void wswan_state::set_irq_line(int irq) { - if (m_ws_portram[0xb2] & irq) + if (m_irq_enable & irq) { - m_ws_portram[0xb6] |= irq; + m_irq_active |= irq; handle_irqs(); } } @@ -382,7 +386,7 @@ void wswan_state::dma_sound_cb() { address_space &space = m_maincpu->space(AS_PROGRAM); /* TODO: Output sound DMA byte */ - port_w(0x89, space.read_byte(m_sound_dma.source)); + port_w(0x88 > 2, space.read_byte(m_sound_dma.source) << 8, 0xff00); m_sound_dma.size--; m_sound_dma.source = (m_sound_dma.source + 1) & 0x0fffff; if (m_sound_dma.size == 0) @@ -395,7 +399,7 @@ void wswan_state::dma_sound_cb() void wswan_state::clear_irq_line(int irq) { - m_ws_portram[0xb6] &= ~irq; + m_irq_active &= ~irq; handle_irqs(); } @@ -410,6 +414,23 @@ void wswan_state::register_save() save_item(NAME(m_sound_dma.source)); save_item(NAME(m_sound_dma.size)); save_item(NAME(m_sound_dma.enable)); + save_item(NAME(m_vector)); + + save_item(NAME(m_dma_source_offset)); + save_item(NAME(m_dma_source_segment)); + save_item(NAME(m_dma_destination)); + save_item(NAME(m_dma_length)); + save_item(NAME(m_dma_control)); + save_item(NAME(m_sys_control)); + save_item(NAME(m_irq_vector_base)); + save_item(NAME(m_serial_data)); + save_item(NAME(m_serial_control)); + save_item(NAME(m_irq_enable)); + save_item(NAME(m_irq_active)); + save_item(NAME(m_internal_eeprom_data)); + save_item(NAME(m_internal_eeprom_address)); + save_item(NAME(m_internal_eeprom_command)); + save_item(NAME(m_keypad)); if (m_cart->exists()) m_cart->save_nvram(); @@ -420,18 +441,20 @@ void wswan_state::common_start() { register_save(); + m_icons.resolve(); + if (m_cart->exists()) { // ROM - m_maincpu->space(AS_PROGRAM).install_read_handler(0x20000, 0x2ffff, read8sm_delegate(*m_cart, FUNC(ws_cart_slot_device::read_rom20))); - m_maincpu->space(AS_PROGRAM).install_read_handler(0x30000, 0x3ffff, read8sm_delegate(*m_cart, FUNC(ws_cart_slot_device::read_rom30))); - m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000, 0xeffff, read8sm_delegate(*m_cart, FUNC(ws_cart_slot_device::read_rom40))); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x20000, 0x2ffff, read16s_delegate(*m_cart, FUNC(ws_cart_slot_device::read_rom20))); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x30000, 0x3ffff, read16s_delegate(*m_cart, FUNC(ws_cart_slot_device::read_rom30))); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000, 0xeffff, read16s_delegate(*m_cart, FUNC(ws_cart_slot_device::read_rom40))); // SRAM - if (m_cart->get_type() == WS_SRAM) + if (m_cart->get_type() == WS_SRAM || m_cart->get_type() == WWITCH) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0x10000, 0x1ffff, read8sm_delegate(*m_cart, FUNC(ws_cart_slot_device::read_ram))); - m_maincpu->space(AS_PROGRAM).install_write_handler(0x10000, 0x1ffff, write8sm_delegate(*m_cart, FUNC(ws_cart_slot_device::write_ram))); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x10000, 0x1ffff, read16s_delegate(*m_cart, FUNC(ws_cart_slot_device::read_ram))); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x10000, 0x1ffff, write16s_delegate(*m_cart, FUNC(ws_cart_slot_device::write_ram))); } } } @@ -457,97 +480,111 @@ void wswan_state::machine_reset() { m_bios_disabled = 0; - if (m_cart->exists()) - m_rotate = m_cart->get_is_rotated(); - else - m_rotate = 0; + m_rotate = 0; + + m_vector = 0; + m_irq_vector_base = 0; + m_serial_control = 0; + m_irq_enable = 0; + m_irq_active = 0; + m_internal_eeprom_data = 0; + m_internal_eeprom_address = 0; + m_internal_eeprom_command = 0; + m_sys_control = (m_system_type == TYPE_WSC) ? 2 : 0; /* Intialize ports */ - std::copy(std::begin(ws_portram_init), std::end(ws_portram_init), std::begin(m_ws_portram)); + std::fill(std::begin(m_ws_portram), std::end(m_ws_portram), 0); - render_target *target = machine().render().first_target(); - target->set_view(m_rotate); + set_rotate_view(); /* Initialize sound DMA */ m_sound_dma = sound_dma_t(); } -u8 wswan_state::bios_r(offs_t offset) +u16 wswan_state::bios_r(offs_t offset, u16 mem_mask) { if (!m_bios_disabled) - return m_region_maincpu->base()[offset & (m_region_maincpu->bytes() - 1)]; + return m_region_maincpu->as_u16(offset & ((m_region_maincpu->bytes() >> 1) - 1)); else - return m_cart->read_rom40(offset + 0xb0000); + return m_cart->read_rom40(offset + (0xb0000 >> 1), mem_mask); } -u8 wswan_state::port_r(offs_t offset) +u16 wswan_state::port_r(offs_t offset, u16 mem_mask) { - u8 value = m_ws_portram[offset]; - - if (offset != 2) - logerror("PC=%X: port read %02X\n", m_maincpu->pc(), offset); + u16 value = m_ws_portram[offset]; - if (offset < 0x40 || (offset >= 0xa1 && offset < 0xb0)) - return m_vdp->reg_r(offset); + if (offset < 0x40 / 2 || (offset > 0xa0 / 2 && offset < 0xb0 / 2)) + { + return m_vdp->reg_r(offset, mem_mask); + } + if (offset >= 0x80 / 2 && offset <= 0x9f / 2) + { + return m_sound->port_r(offset, mem_mask); + } switch (offset) { - case 0x4a: // Sound DMA source address (low) - value = m_sound_dma.source & 0xff; - break; - case 0x4b: // Sound DMA source address (high) - value = (m_sound_dma.source >> 8) & 0xff; - break; - case 0x4c: // Sound DMA source memory segment - value = (m_sound_dma.source >> 16) & 0xff; - break; - case 0x4e: // Sound DMA transfer size (low) - value = m_sound_dma.size & 0xff; - break; - case 0x4f: // Sound DMA transfer size (high) - value = (m_sound_dma.size >> 8) & 0xff; - break; - case 0x52: // Sound DMA start/stop - value = m_sound_dma.enable; - break; - case 0x60: - value = m_vdp->reg_r(offset); - break; - case 0xa0: // Hardware type + case 0x40 / 2: // DMA source address + return m_dma_source_offset; + case 0x42 / 2: // DMA source bank/segment + return m_dma_source_segment; + case 0x44 / 2: // DMA destination address + return m_dma_destination; + case 0x46 / 2: // DMA size (in bytes) + return m_dma_length; + case 0x48 / 2: // DMA control + return m_dma_control; + case 0x4a / 2: + // Sound DMA source address + return m_sound_dma.source & 0xffff; + case 0x4c / 2: + // Sound DMA source memory segment + return (m_sound_dma.source >> 16) & 0xffff; + case 0x4e / 2: + // Sound DMA transfer size + return m_sound_dma.size; + case 0x52 / 2: + // Sound DMA start/stop + return m_sound_dma.enable; + case 0x60 / 2: + return m_vdp->reg_r(offset, mem_mask); + case 0xa0 / 2: + // Hardware type // Bit 0 - Disable/enable Bios // Bit 1 - Determine mono/color // Bit 2 - Unknown, used to determine color/crystal // Bit 3 - Unknown - // Bit 7 - Checked during start up, expects bit 7 set - value = value & ~ 0x02; - if (m_system_type == TYPE_WSC) - value |= 2; - value |= 0x80; - break; - case 0xb5: // Read controls - // Bit 0-3 - Current state of input lines (read-only) - // Bit 4-6 - Select line of inputs to read - // 001 - Read Y cursors - // 010 - Read X cursors - // 100 - Read START,A,B buttons - // Bit 7 - Unknown - value = value & 0xf0; - switch (value) + // Bit 7 - Checked during start up, expects bit 7 set (part of cart unlock sequence?) + return m_sys_control | 0x80; + case 0xb0 / 2: + return m_irq_vector_base | (m_serial_data << 8); + case 0xb2 / 2: + return m_irq_enable | (m_serial_control << 8); + case 0xb4 / 2: + // Read controls + // Bit 8-11 - Current state of input lines (read-only) + // Bit 12-14 - Select line of inputs to read + // 001 - Read Y cursors + // 010 - Read X cursors + // 100 - Read START,A,B buttons + // Bit 15 - Unknown + value = (m_keypad << 8) & 0xf0ff; + switch (m_keypad & 0x70) { case 0x10: // Read Y cursors: Y1 - Y2 - Y3 - Y4 { u8 input = m_cursy->read(); if (m_rotate) // reorient controls if the console is rotated { - if (input & 0x01) value |= 0x02; - if (input & 0x02) value |= 0x04; - if (input & 0x04) value |= 0x08; - if (input & 0x08) value |= 0x01; + if (input & 0x01) value |= 0x0200; + if (input & 0x02) value |= 0x0400; + if (input & 0x04) value |= 0x0800; + if (input & 0x08) value |= 0x0100; } else - value = value | input; + value = value | (input << 8); } break; case 0x20: // Read X cursors: X1 - X2 - X3 - X4 @@ -555,155 +592,154 @@ u8 wswan_state::port_r(offs_t offset) u8 input = m_cursx->read(); if (m_rotate) // reorient controls if the console is rotated { - if (input & 0x01) value |= 0x02; - if (input & 0x02) value |= 0x04; - if (input & 0x04) value |= 0x08; - if (input & 0x08) value |= 0x01; + if (input & 0x01) value |= 0x0200; + if (input & 0x02) value |= 0x0400; + if (input & 0x04) value |= 0x0800; + if (input & 0x08) value |= 0x0100; } else - value = value | input; + value = value | (input << 8); } break; case 0x40: // Read buttons: START - A - B - value = value | m_buttons->read(); + value = value | (m_buttons->read() << 8); break; } - break; - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: // Cartridge EEPROM data - case 0xc5: // Cartridge EEPROM data - case 0xc6: - case 0xc7: - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: // RTC data - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - value = m_cart->read_io(offset & 0x0f); - break; + return value; + case 0xb6 / 2: + return m_irq_active; + case 0xba / 2: + return m_internal_eeprom_data; + case 0xbc / 2: + return m_internal_eeprom_address; + case 0xbe / 2: + return m_internal_eeprom_command; + case 0xc0 / 2: + case 0xc2 / 2: + case 0xc4 / 2: // Cartridge EEPROM data + case 0xc6 / 2: + case 0xc8 / 2: + case 0xca / 2: // RTC command & data + case 0xcc / 2: + case 0xce / 2: + return m_cart->read_io(offset, mem_mask); } return value; } -void wswan_state::port_w(offs_t offset, u8 data) +void wswan_state::port_w(offs_t offset, u16 data, u16 mem_mask) { - address_space &mem = m_maincpu->space(AS_PROGRAM); - logerror("PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data); - - if (offset < 0x40 || (offset >= 0xa1 && offset < 0xb0)) + if (offset < 0x40 / 2 || (offset > 0xa0 / 2 && offset < 0xb0 / 2)) { - m_vdp->reg_w(offset, data); + m_vdp->reg_w(offset, data, mem_mask); return; } switch (offset) { - case 0x40: // DMA source address (low) - case 0x41: // DMA source address (high) - case 0x42: // DMA source bank - case 0x43: // DMA destination bank - case 0x44: // DMA destination address (low) - case 0x45: // DMA destination address (high) - case 0x46: // Size of copied data (low) - case 0x47: // Size of copied data (high) + case 0x40 / 2: // DMA source address + COMBINE_DATA(&m_dma_source_offset); + m_dma_source_offset &= 0xfffe; + break; + case 0x42 / 2: // DMA source bank/segment + COMBINE_DATA(&m_dma_source_segment); + m_dma_source_segment &= 0x000f; + break; + case 0x44 / 2: // DMA destination address + COMBINE_DATA(&m_dma_destination); + m_dma_destination &= 0xfffe; break; - case 0x48: // DMA control + case 0x46 / 2: // DMA size (in bytes) + COMBINE_DATA(&m_dma_length); + break; + case 0x48 / 2: // DMA control // Bit 0-6 - Unknown // Bit 7 - DMA stop/start - if (data & 0x80) + if (ACCESSING_BITS_0_7) { - u32 src, dst; - u16 length; - - src = m_ws_portram[0x40] + (m_ws_portram[0x41] << 8) + (m_ws_portram[0x42] << 16); - dst = m_ws_portram[0x44] + (m_ws_portram[0x45] << 8) + (m_ws_portram[0x43] << 16); - length = m_ws_portram[0x46] + (m_ws_portram[0x47] << 8); - for ( ; length > 0; length--) + if (data & 0x80) { - mem.write_byte(dst, mem.read_byte(src)); - src++; - dst++; + address_space &mem = m_maincpu->space(AS_PROGRAM); + u32 src = m_dma_source_offset | (m_dma_source_segment << 16); + u32 dst = m_dma_destination; + u16 length = m_dma_length; + if (length) + m_maincpu->adjust_icount(-(5 + length)); + for ( ; length > 0; length -= 2) + { + mem.write_word(dst, mem.read_word(src)); + src += 2; + dst += 2; + } + m_dma_source_offset = src & 0xffff; + m_dma_source_segment = src >> 16; + m_dma_destination = dst & 0xffff; + m_dma_length = length & 0xffff; + data &= 0x7f; + m_dma_control = data; } -#ifdef MAME_DEBUG - logerror("DMA src:%X dst:%X length:%d\n", src, dst, length); -#endif - m_ws_portram[0x40] = src & 0xff; - m_ws_portram[0x41] = (src >> 8) & 0xff; - m_ws_portram[0x44] = dst & 0xff; - m_ws_portram[0x45] = (dst >> 8) & 0xff; - m_ws_portram[0x46] = length & 0xff; - m_ws_portram[0x47] = (length >> 8) & 0xff; - data &= 0x7f; } break; - case 0x4a: // Sound DMA source address (low) - m_sound_dma.source = (m_sound_dma.source & 0x0fff00) | data; - break; - case 0x4b: // Sound DMA source address (high) - m_sound_dma.source = (m_sound_dma.source & 0x0f00ff) | (data << 8); + case 0x4a / 2: + // Sound DMA source address (low) + if (ACCESSING_BITS_0_7) + m_sound_dma.source = (m_sound_dma.source & 0x0fff00) | (data & 0xff); + // Sound DMA source address (high) + if (ACCESSING_BITS_8_15) + m_sound_dma.source = (m_sound_dma.source & 0x0f00ff) | (data & 0xff00); break; - case 0x4c: // Sound DMA source memory segment + case 0x4c / 2: + // Sound DMA source memory segment // Bit 0-3 - Sound DMA source address segment // Bit 4-7 - Unknown - m_sound_dma.source = (m_sound_dma.source & 0xffff) | ((data & 0x0f) << 16); + if (ACCESSING_BITS_0_7) + m_sound_dma.source = (m_sound_dma.source & 0xffff) | ((data & 0x0f) << 16); break; - case 0x4d: // Unknown + case 0x4e / 2: + // Sound DMA transfer size + COMBINE_DATA(&m_sound_dma.size); break; - case 0x4e: // Sound DMA transfer size (low) - m_sound_dma.size = (m_sound_dma.size & 0xff00) | data; - break; - case 0x4f: // Sound DMA transfer size (high) - m_sound_dma.size = (m_sound_dma.size & 0xff) | (data << 8); - break; - case 0x50: // Unknown - case 0x51: // Unknown - break; - case 0x52: // Sound DMA start/stop + case 0x52 / 2: + // Sound DMA start/stop // Bit 0-6 - Unknown // Bit 7 - Sound DMA stop/start - m_sound_dma.enable = data; - break; - case 0x60: - m_vdp->reg_w(offset, data); - break; - case 0x80: // Audio 1 freq (lo) - case 0x81: // Audio 1 freq (hi) - case 0x82: // Audio 2 freq (lo) - case 0x83: // Audio 2 freq (hi) - case 0x84: // Audio 3 freq (lo) - case 0x85: // Audio 3 freq (hi) - case 0x86: // Audio 4 freq (lo) - case 0x87: // Audio 4 freq (hi) - case 0x88: // Audio 1 volume + if (ACCESSING_BITS_0_7) + m_sound_dma.enable = data & 0xff; + break; + case 0x60 / 2: + m_vdp->reg_w(offset, data, mem_mask); + break; + case 0x80 / 2: // Audio 1 freq + case 0x82 / 2: // Audio 2 freq + case 0x84 / 2: // Audio 3 freq + case 0x86 / 2: // Audio 4 freq + case 0x88 / 2: + // Audio 1 volume // Bit 0-3 - Right volume audio channel 1 // Bit 4-7 - Left volume audio channel 1 - case 0x89: // Audio 2 volume - // Bit 0-3 - Right volume audio channel 2 - // Bit 4-7 - Left volume audio channel 2 - case 0x8a: // Audio 3 volume + // Audio 2 volume + // Bit 8-11 - Right volume audio channel 2 + // Bit 12-15 - Left volume audio channel 2 + case 0x8a / 2: + // Audio 3 volume // Bit 0-3 - Right volume audio channel 3 // Bit 4-7 - Left volume audio channel 3 - case 0x8b: // Audio 4 volume - // Bit 0-3 - Right volume audio channel 4 - // Bit 4-7 - Left volume audio channel 4 - case 0x8c: // Sweep step - case 0x8d: // Sweep time - case 0x8e: // Noise control + // Audio 4 volume + // Bit 8-11 - Right volume audio channel 4 + // Bit 12-15 - Left volume audio channel 4 + case 0x8c / 2: // Sweep step / sweep time + case 0x8e / 2: + // Noise control // Bit 0-2 - Noise generator type // Bit 3 - Reset // Bit 4 - Enable // Bit 5-7 - Unknown - case 0x8f: // Sample location - // Bit 0-7 - Sample address location 0 00xxxxxx xx000000 - case 0x90: // Audio control + // Sample location + // Bit 8-15 - Sample address location 0 00xxxxxx xx000000 + case 0x90 / 2: + // Audio control // Bit 0 - Audio 1 enable // Bit 1 - Audio 2 enable // Bit 2 - Audio 3 enable @@ -711,40 +747,51 @@ void wswan_state::port_w(offs_t offset, u8 data) // Bit 4 - Unknown // Bit 5 - Audio 2 voice mode enable // Bit 6 - Audio 3 sweep mode enable - // Bit 7 - Audio 4 noise mode enable - case 0x91: // Audio output - // Bit 0 - Mono select - // Bit 1-2 - Output volume - // Bit 3 - External stereo - // Bit 4-6 - Unknown - // Bit 7 - External speaker (Read-only, set by hardware) - case 0x92: // Noise counter shift register (lo) - case 0x93: // Noise counter shift register (hi) - // Bit 0-6 - Noise counter shift register bit 8-14 - // bit 7 - Unknown - case 0x94: // Master volume + // Bit 7 - Audio 4 noise mode enable + // Audio output + // Bit 8 - Mono select + // Bit 9-10 - Output volume + // Bit 11 - External stereo + // Bit 12-14 - Unknown + // Bit 15 - External speaker (Read-only, set by hardware) + case 0x92 / 2: // Noise counter shift register + case 0x94 / 2: + // Master volume // Bit 0-3 - Master volume // Bit 4-7 - Unknown - m_sound->port_w(offset, data); - break; - case 0x9E: // WSC volume setting (0, 1, 2, 3) + case 0x9e / 2: // WSC volume setting (0, 1, 2, 3) (TODO) + m_sound->port_w(offset, data, mem_mask); break; - case 0xa0: // Hardware type/system control - // Bit 0 - Enable cartridge slot and/or disable bios + case 0xa0 / 2: + // Hardware type/system control + // Bit 0 - Disable bios // Bit 1 - Hardware type: 0 = WS, 1 = WSC - // Bit 2 - Unknown, written during boot - // Bit 3 - Unknown, written during boot + // Bit 2 - External bus width + // Bit 3 - Cart ROM cycles (0 = 3 cycles, 1 = 1 cycle) // Bit 4-6 - Unknown // Bit 7 - Unknown, read during boot - if ((data & 0x01) && !m_bios_disabled) - m_bios_disabled = 1; + if (ACCESSING_BITS_0_7) + { + m_sys_control = (data & 0xfd) | ((m_system_type == TYPE_WSC) ? 2 : 0); + if ((data & 0x01) && !m_bios_disabled) + { + m_bios_disabled = 1; + if (m_cart->exists()) + m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000, 0xfffff, read16s_delegate(*m_cart, FUNC(ws_cart_slot_device::read_rom40))); + } + } break; - case 0xb0: // Interrupt base vector + case 0xb0 / 2: + // Interrupt base vector + if (ACCESSING_BITS_0_7) + m_irq_vector_base = data & 0xff; + // Serial data (bit 8-15) + if (ACCESSING_BITS_8_15) + m_serial_data = data >> 8; break; - case 0xb1: // Communication byte - break; - case 0xb2: // Interrupt enable + case 0xb2 / 2: + // Interrupt enable // Bit 0 - Serial transmit interrupt enable // Bit 1 - Key press interrupt enable // Bit 2 - RTC alarm interrupt enable @@ -753,57 +800,64 @@ void wswan_state::port_w(offs_t offset, u8 data) // Bit 5 - VBlank timer interrupt enable // Bit 6 - VBlank interrupt enable // Bit 7 - HBlank timer interrupt enable - break; - case 0xb3: // serial communication control - // Bit 0 - Receive complete - // Bit 1 - Error - // Bit 2 - Send complete - // Bit 3-4 - Unknown - // Bit 5 - Send data interrupt generation - // Bit 6 - Connection speed: 0 = 9600 bps, 1 = 38400 bps - // Bit 7 - Receive data interrupt generation - m_ws_portram[0xb1] = 0xff; - if (data & 0x80) + if (ACCESSING_BITS_0_7) + m_irq_enable = data & 0xff; + // serial communication control + // Bit 8 - Receive complete + // Bit 9 - Error + // Bit 10 - Send complete + // Bit 11-12 - Unknown + // Bit 13 - Send data interrupt generation + // Bit 14 - Connection speed: 0 = 9600 bps, 1 = 38400 bps + // Bit 15 - Receive data interrupt generation + if (ACCESSING_BITS_8_15) { - // m_ws_portram[0xb1] = 0x00; - data |= 0x04; + m_serial_data = 0xff; + m_serial_control = data >> 8; + if (m_serial_control & 0x80) + { + // m_serial_data = 0x00; + m_serial_control |= 0x04; + } + if (m_serial_control & 0x20) + { + // m_serial_control |= 0x01; + } } - if (data & 0x20) + break; + case 0xb4 / 2: + if (ACCESSING_BITS_8_15) { - // data |= 0x01; + m_keypad = (data & 0xf0ff) >> 8; } break; - case 0xb5: // Read controls - // Bit 0-3 - Current state of input lines (read-only) - // Bit 4-6 - Select line of inputs to read - // 001 - Read Y cursors - // 010 - Read X cursors - // 100 - Read START,A,B buttons - // Bit 7 - Unknown - break; - case 0xb6: // Interrupt acknowledge - // Bit 0 - Serial transmit interrupt acknowledge - // Bit 1 - Key press interrupt acknowledge - // Bit 2 - RTC alarm interrupt acknowledge - // Bit 3 - Serial receive interrupt acknowledge - // Bit 4 - Drawing line detection interrupt acknowledge - // Bit 5 - VBlank timer interrupt acknowledge - // Bit 6 - VBlank interrupt acknowledge - // Bit 7 - HBlank timer interrupt acknowledge - clear_irq_line(data); - data = m_ws_portram[0xb6]; + case 0xb6 / 2: + // Interrupt acknowledge + // Bit 0 - Serial transmit interrupt acknowledge + // Bit 1 - Key press interrupt acknowledge + // Bit 2 - RTC alarm interrupt acknowledge + // Bit 3 - Serial receive interrupt acknowledge + // Bit 4 - Drawing line detection interrupt acknowledge + // Bit 5 - VBlank timer interrupt acknowledge + // Bit 6 - VBlank interrupt acknowledge + // Bit 7 - HBlank timer interrupt acknowledge + if (ACCESSING_BITS_0_7) + { + clear_irq_line(data & 0xff); + data = m_irq_active; + } break; - case 0xba: // Internal EEPROM data (low) - case 0xbb: // Internal EEPROM data (high) + case 0xba / 2: // Internal EEPROM data + COMBINE_DATA(&m_internal_eeprom_data); break; - case 0xbc: // Internal EEPROM address (low) - // (WS) Bit 0-5 = Internal EEPROM address - // (WSC) Bit 0-7 - Internal EEPROM address bit 1-8 - case 0xbd: // Internal EEPROM address (high) - // (WSC) Bit 0 - Internal EEPROM address bit 9(?) - // Bit 1-7 - Unknown + case 0xbc / 2: // Internal EEPROM address + // (WS) Bit 0-5 - Internal EEPROM address + // (WSC) Bit 0-8 - Internal EEPROM address bit 1-9 + // Bit 9-15 - Unknown + COMBINE_DATA(&m_internal_eeprom_address); break; - case 0xbe: // Internal EEPROM command/status + case 0xbe / 2: + // Internal EEPROM command/status // Bit 0 - Read complete (read only) // Bit 1 - Write complete (read only) // Bit 2-3 - Unknown @@ -811,60 +865,84 @@ void wswan_state::port_w(offs_t offset, u8 data) // Bit 5 - Write // Bit 6 - Protect // Bit 7 - Initialize - if (data & 0x20) + if (ACCESSING_BITS_0_7) { - u16 addr = get_internal_eeprom_address(); - m_internal_eeprom[addr] = m_ws_portram[0xba]; - m_internal_eeprom[addr + 1] = m_ws_portram[0xbb]; - data |= 0x02; - } - else if ( data & 0x10 ) - { - u16 addr = get_internal_eeprom_address(); - m_ws_portram[0xba] = m_internal_eeprom[addr]; - m_ws_portram[0xbb] = m_internal_eeprom[addr + 1]; - data |= 0x01; - } - else - { - logerror( "Unsupported internal EEPROM command: %X\n", data ); + m_internal_eeprom_command = data & 0xfc; + if (m_internal_eeprom_command & 0x20) + { + u16 addr = get_internal_eeprom_address(); + m_internal_eeprom[addr] = m_internal_eeprom_data & 0xff; + m_internal_eeprom[addr + 1] = m_internal_eeprom_data >> 8; + m_internal_eeprom_command |= 0x02; + } + else if (m_internal_eeprom_command & 0x10) + { + u16 addr = get_internal_eeprom_address(); + m_internal_eeprom_data = m_internal_eeprom[addr] | (m_internal_eeprom[addr + 1] << 8); + m_internal_eeprom_command |= 0x01; + } + else + { + logerror("Unsupported internal EEPROM command: %X\n", data); + } } break; - case 0xc0: // ROM bank $40000-$fffff - case 0xc1: // SRAM bank - case 0xc2: // ROM bank $20000-$2ffff - case 0xc3: // ROM bank $30000-$3ffff - case 0xc4: - case 0xc5: - case 0xc6: // EEPROM address / command - case 0xc7: // EEPROM address / command - case 0xc8: // EEPROM command - case 0xc9: - case 0xca: // RTC command - case 0xcb: // RTC data - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - m_cart->write_io(offset & 0x0f, data); + case 0xc0 / 2: // ROM bank $40000-$fffff and SRAM bank + case 0xc2 / 2: // ROM bank $20000-$2ffff and ROM bank $30000-$3ffff + case 0xc4 / 2: + case 0xc6 / 2: // EEPROM address / command + case 0xc8 / 2: // EEPROM command + case 0xca / 2: // RTC command and RTC data + case 0xcc / 2: + case 0xce / 2: + m_cart->write_io(offset, data, mem_mask); break; default: - logerror( "Write to unsupported port: %X - %X\n", offset, data ); + logerror("Write to unsupported port: %x - %x\n", offset, data); break; } // Update the port value - m_ws_portram[offset] = data; + COMBINE_DATA(&m_ws_portram[offset]); +} + + +void wswan_state::set_icons(u8 data) { + // Bit 0 - LCD sleep icon enable + // Bit 1 - Vertical position icon enable + // Bit 2 - Horizontal position icon enable + // Bit 3 - Dot 1 icon enable + // Bit 4 - Dot 2 icon enable + // Bit 5 - Dot 3 icon enable + for (int i = 0; i < 6; i++) { + m_icons[i] = BIT(data, i); + } + + u8 old_rotate = m_rotate; + + if ((!BIT(data, 2) && BIT(data, 1)) || (BIT(data, 2) && !BIT(data, 1))) { + m_rotate = (!BIT(data, 2) && BIT(data, 1)) ? 1 : 0; + + if (old_rotate != m_rotate) { + set_rotate_view(); + } + } +} + + +void wswan_state::set_rotate_view() { + render_target *target = machine().render().first_target(); + target->set_view(m_rotate); } u16 wswan_state::get_internal_eeprom_address() { - return (m_ws_portram[0xbc] & 0x3f) << 1; + return (m_internal_eeprom_address & 0x3f) << 1; } u16 wscolor_state::get_internal_eeprom_address() { - return (((m_ws_portram[0xbd] << 8) | m_ws_portram[0xbc]) & 0x1FF) << 1; + return (m_internal_eeprom_address & 0x1ff) << 1; } /*************************************************************************** @@ -889,10 +967,12 @@ ROM_START(wscolor) ROM_REGION(0x800, "nvram", 0) // Need a dump from an original new unit - // Empty file containing just the name 'WONDERSAN' - ROM_LOAD("internal_eeprom.wsc", 0x000, 0x800, BAD_DUMP CRC(9e29725c) SHA1(a903c2cb5f4bb94b67326ff87a2d91605dceffff)) + // Empty file containing just the name 'WONDERSWANCOLOR' (from Youtube videos) + ROM_LOAD("internal_eeprom.wsc", 0x000, 0x800, BAD_DUMP CRC(ca11afc9) SHA1(0951845f01f83bee497268a63b5fb7baccfeff7c)) ROM_END +// SwanCrystal has the name 'SWANCRYSTAL' (from Youtube videos) + } // anonymous namespace diff --git a/src/mame/video/wswan.cpp b/src/mame/video/wswan.cpp index 541e1277f42..a845117e6b2 100644 --- a/src/mame/video/wswan.cpp +++ b/src/mame/video/wswan.cpp @@ -8,9 +8,8 @@ Wilbert Pol TODO: - - remove the redundant parts of m_regs - split the Color VDP from the Mono VDP - - Add support for WSC high/low contrast (register 14, bit 1) + - Add support for WSC high/low contrast (register 14, bit 1) ***************************************************************************/ @@ -21,12 +20,13 @@ DEFINE_DEVICE_TYPE(WSWAN_VIDEO, wswan_video_device, "wswan_video", "Bandai WonderSwam VDP") -wswan_video_device::wswan_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +wswan_video_device::wswan_video_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, WSWAN_VIDEO, tag, owner, clock) , device_video_interface(mconfig, *this) , m_set_irq_cb(*this) , m_snd_dma_cb(*this) , m_vdp_type(VDP_TYPE_WSWAN) + , m_icons_cb(*this) { } @@ -72,7 +72,6 @@ void wswan_video_device::common_save() save_item(NAME(m_layer_fg_scroll_x)); save_item(NAME(m_layer_fg_scroll_y)); save_item(NAME(m_lcd_control)); - save_item(NAME(m_icons)); save_item(NAME(m_color_mode)); save_item(NAME(m_colors_16)); save_item(NAME(m_tile_packed)); @@ -92,7 +91,7 @@ void wswan_video_device::device_start() screen().register_screen_bitmap(m_bitmap); m_timer = timer_alloc(TIMER_SCANLINE); - m_timer->adjust(attotime::from_ticks(256, 3072000), 0, attotime::from_ticks(256, 3072000)); + m_timer->adjust(attotime::from_ticks(256, clock()), 0, attotime::from_ticks(256, clock())); // bind callbacks m_set_irq_cb.resolve(); @@ -100,41 +99,21 @@ void wswan_video_device::device_start() if (m_vdp_type == VDP_TYPE_WSC) { - m_vram.resize(0x10000); - memset(&m_vram[0], 0, 0x10000); - m_palette_vram = &m_vram[0xfe00]; + m_vram.resize(WSC_VRAM_SIZE); + m_palette_vram = &m_vram[WSC_VRAM_PALETTE]; } else { - m_vram.resize(0x4000); - memset(&m_vram[0], 0, 0x4000); + m_vram.resize(WS_VRAM_SIZE); m_palette_vram = &m_vram[0]; } + std::fill(std::begin(m_vram), std::end(m_vram), 0); + common_save(); -} -// This is a copy of ws_portram_init -// TODO: remove unneeded parts! -static const uint8_t vdp_regs_init[256] = -{ - 0x00, 0x00, 0x00/*?*/, 0xbb, 0x00, 0x00, 0x00, 0x26, 0xfe, 0xde, 0xf9, 0xfb, 0xdb, 0xd7, 0x7f, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9e, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x99, 0xfd, 0xb7, 0xdf, - 0x30, 0x57, 0x75, 0x76, 0x15, 0x73, 0x70/*77?*/, 0x77, 0x20, 0x75, 0x50, 0x36, 0x70, 0x67, 0x50, 0x77, - 0x57, 0x54, 0x75, 0x77, 0x75, 0x17, 0x37, 0x73, 0x50, 0x57, 0x60, 0x77, 0x70, 0x77, 0x10, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x87, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdb, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x83, 0x00, - 0x2f, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1 -}; + m_icons_cb.resolve(); +} void wswan_video_device::device_reset() @@ -145,7 +124,7 @@ void wswan_video_device::device_reset() m_window_sprites_enable = 0; m_window_fg_mode = 0; m_bg_control = 0; - m_current_line = 145; // Randomly chosen, beginning of VBlank period to give cart some time to boot up + m_current_line = 0; m_line_compare = 0; m_sprite_table_address = 0; m_sprite_first = 0; @@ -166,8 +145,7 @@ void wswan_video_device::device_reset() m_layer_bg_scroll_y = 0; m_layer_fg_scroll_x = 0; m_layer_fg_scroll_y = 0; - m_lcd_control = 0x01; - m_icons = 0; + m_lcd_control = 0; m_color_mode = 0; m_colors_16 = 0; m_tile_packed = 0; @@ -178,13 +156,12 @@ void wswan_video_device::device_reset() m_timer_vblank_enable = 0; m_timer_vblank_mode = 0; m_timer_vblank_reload = 0; - m_timer_vblank_count = 0; /* Vertical blank timer counter value */ + m_timer_vblank_count = 0; - memset(m_sprite_table_buffer, 0, sizeof(m_sprite_table_buffer)); - memset(m_main_palette, 0, sizeof(m_main_palette)); - memcpy(m_regs, vdp_regs_init, 256); - for (int i = 0; i < 0x20; i++) - m_palette_port[i] = m_regs[i + 0x20]; + std::fill(std::begin(m_sprite_table_buffer), std::end(m_sprite_table_buffer), 0); + std::fill(std::begin(m_main_palette), std::end(m_main_palette), 0); + std::fill(std::begin(m_regs), std::end(m_regs), 0); + std::fill(std::begin(m_palette_port), std::end(m_palette_port), 0); setup_palettes(); } @@ -207,33 +184,38 @@ void wswan_video_device::setup_palettes() { for (int i = 0; i < 16; i++) for (int j = 0; j < 16; j++) - m_pal[i][j] = ((m_palette_vram[(i << 5) + j * 2 + 1] << 8) | m_palette_vram[(i << 5) + j * 2]) & 0x0fff; + m_pal[i][j] = m_palette_vram[(i << 4) + j] & 0x0fff; } else { for (int i = 0; i < 16; i++) { - m_pal[i][0] = (m_palette_port[(i << 1)] >> 0) & 0x07; - m_pal[i][1] = (m_palette_port[(i << 1)] >> 4) & 0x07; - m_pal[i][2] = (m_palette_port[(i << 1) + 1] >> 0) & 0x07; - m_pal[i][3] = (m_palette_port[(i << 1) + 1] >> 4) & 0x07; + m_pal[i][0] = (m_palette_port[i] >> 0) & 0x07; + m_pal[i][1] = (m_palette_port[i] >> 4) & 0x07; + m_pal[i][2] = (m_palette_port[i] >> 8) & 0x07; + m_pal[i][3] = (m_palette_port[i] >> 12) & 0x07; } } } + +inline u16 wswan_video_device::swap_bytes(u16 word) { + return (word << 8) | (word >> 8); +} + + void wswan_video_device::draw_background() { - uint16_t map_addr = m_layer_bg_address + (((m_current_line + m_layer_bg_scroll_y) & 0xf8) << 3); - uint8_t start_column = (m_layer_bg_scroll_x >> 3); + const u16 map_addr = m_layer_bg_address + (((m_current_line + m_layer_bg_scroll_y) & 0xf8) << 2); + const u8 start_column = (m_layer_bg_scroll_x >> 3); for (int column = 0; column < 29; column++) { - uint32_t plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; - int x_offset, tile_line, tile_address; - int tile_data = (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8) - | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)]; - int tile_number = tile_data & 0x01ff; - int tile_palette = (tile_data >> 9) & 0x0f; + u32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; + int x_offset, tile_line; + const u16 tile_data = m_vram[map_addr + ((start_column + column) & 0x1f)]; + const u16 tile_number = tile_data & 0x01ff; + const u16 tile_palette = (tile_data >> 9) & 0x0f; tile_line = (m_current_line + m_layer_bg_scroll_y) & 0x07; if (tile_data & 0x8000) // vflip @@ -241,30 +223,30 @@ void wswan_video_device::draw_background() if (m_colors_16) { - tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2); + const u16 tile_address = ((tile_data & 0x2000) ? 0x4000 : 0x2000) + (tile_number * 16) + (tile_line << 1); if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3]; + plane0 = (swap_bytes(m_vram[tile_address]) << 16) | swap_bytes(m_vram[tile_address + 1]); } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; - plane2 = m_vram[tile_address + 2] << 2; - plane3 = m_vram[tile_address + 3] << 3; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; + plane2 = (m_vram[tile_address + 1] & 0xff) << 2; + plane3 = (m_vram[tile_address + 1] & 0xff00) >> 5; } } else { - tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1); + const u16 tile_address = 0x1000 + (tile_number * 8) + tile_line; if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1]; + plane0 = m_vram[tile_address]; } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; plane2 = 0; plane3 = 0; } @@ -306,13 +288,7 @@ void wswan_video_device::draw_background() { if (col) { - if (m_color_mode) - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; - else - { - /* Hmmmm, what should we do here... Is this correct?? */ - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; - } + m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; } } else @@ -332,17 +308,16 @@ void wswan_video_device::draw_background() void wswan_video_device::draw_foreground_0() { - uint16_t map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 3); - uint8_t start_column = (m_layer_fg_scroll_x >> 3); + const u16 map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 2); + const u8 start_column = (m_layer_fg_scroll_x >> 3); for (int column = 0; column < 29; column++) { - uint32_t plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; - int x_offset, tile_line, tile_address; - int tile_data = (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8) - | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)]; - int tile_number = tile_data & 0x01ff; - int tile_palette = (tile_data >> 9) & 0x0f; + u32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; + int x_offset, tile_line; + const u16 tile_data = m_vram[map_addr + ((start_column + column) & 0x1f)]; + const u16 tile_number = tile_data & 0x01ff; + const u16 tile_palette = (tile_data >> 9) & 0x0f; tile_line = (m_current_line + m_layer_fg_scroll_y) & 0x07; if (tile_data & 0x8000) // vflip @@ -350,30 +325,30 @@ void wswan_video_device::draw_foreground_0() if (m_colors_16) { - tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2); + const u16 tile_address = ((tile_data & 0x2000) ? 0x4000 : 0x2000) + (tile_number * 16) + (tile_line << 1); if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3]; + plane0 = (swap_bytes(m_vram[tile_address]) << 16) | swap_bytes(m_vram[tile_address + 1]); } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; - plane2 = m_vram[tile_address + 2] << 2; - plane3 = m_vram[tile_address + 3] << 3; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; + plane2 = (m_vram[tile_address + 1] & 0xff) << 2; + plane3 = (m_vram[tile_address + 1] & 0xff00) >> 5; } } else { - tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1); + const u16 tile_address = 0x1000 + (tile_number * 8) + tile_line; if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1]; + plane0 = m_vram[tile_address]; } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; plane2 = 0; plane3 = 0; } @@ -415,12 +390,7 @@ void wswan_video_device::draw_foreground_0() { if (col) { -// if (m_color_mode) { m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; -// } else { -// /* Hmmmm, what should we do here... Is this correct?? */ -// m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; -// } } } else @@ -440,17 +410,16 @@ void wswan_video_device::draw_foreground_0() void wswan_video_device::draw_foreground_2() { - uint16_t map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 3); - uint8_t start_column = (m_layer_fg_scroll_x >> 3); + const u16 map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 2); + const u8 start_column = (m_layer_fg_scroll_x >> 3); for (int column = 0; column < 29; column++) { - uint32_t plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; - int x_offset, tile_line, tile_address; - int tile_data = (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8) - | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)]; - int tile_number = tile_data & 0x01ff; - int tile_palette = (tile_data >> 9) & 0x0f; + u32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; + int x_offset, tile_line; + const u16 tile_data = m_vram[map_addr + ((start_column + column) & 0x1f)]; + const u16 tile_number = tile_data & 0x01ff; + const u16 tile_palette = (tile_data >> 9) & 0x0f; tile_line = (m_current_line + m_layer_fg_scroll_y) & 0x07; if (tile_data & 0x8000) // vflip @@ -459,30 +428,30 @@ void wswan_video_device::draw_foreground_2() if (m_colors_16) { - tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2); + const u16 tile_address = ((tile_data & 0x2000) ? 0x4000 : 0x2000) + (tile_number * 16) + (tile_line << 1); if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3]; + plane0 = (swap_bytes(m_vram[tile_address]) << 16) | swap_bytes(m_vram[tile_address + 1]); } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; - plane2 = m_vram[tile_address + 2] << 2; - plane3 = m_vram[tile_address + 3] << 3; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; + plane2 = (m_vram[tile_address + 1] & 0xff) << 2; + plane3 = (m_vram[tile_address + 1] & 0xff00) >> 5; } } else { - tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1); + const u16 tile_address = 0x1000 + (tile_number * 8) + tile_line; if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1]; + plane0 = m_vram[tile_address]; } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; plane2 = 0; plane3 = 0; } @@ -518,17 +487,13 @@ void wswan_video_device::draw_foreground_2() else x_offset = 7 - x + (column << 3) - (m_layer_fg_scroll_x & 0x07); - if (x_offset >= 0 && x_offset >= m_window_fg_left && x_offset < m_window_fg_right && x_offset < WSWAN_X_PIXELS) + if (x_offset >= 0 && x_offset >= m_window_fg_left && x_offset <= m_window_fg_right && x_offset < WSWAN_X_PIXELS) { if (m_colors_16) { if (col) { - if (m_color_mode) - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; - else - /* Hmmmm, what should we do here... Is this correct?? */ - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; + m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; } } else @@ -548,17 +513,16 @@ void wswan_video_device::draw_foreground_2() void wswan_video_device::draw_foreground_3() { - uint16_t map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 3); - uint8_t start_column = (m_layer_fg_scroll_x >> 3); + const u16 map_addr = m_layer_fg_address + (((m_current_line + m_layer_fg_scroll_y) & 0xf8) << 2); + const u8 start_column = (m_layer_fg_scroll_x >> 3); for (int column = 0; column < 29; column++) { - uint32_t plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; - int x_offset, tile_line, tile_address; - int tile_data = (m_vram[map_addr + (((start_column + column) & 0x1f) << 1) + 1] << 8) - | m_vram[map_addr + (((start_column + column) & 0x1f) << 1)]; - int tile_number = tile_data & 0x01ff; - int tile_palette = (tile_data >> 9) & 0x0f; + u32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; + int x_offset, tile_line; + const u16 tile_data = m_vram[map_addr + ((start_column + column) & 0x1f)]; + const u16 tile_number = tile_data & 0x01ff; + const u16 tile_palette = (tile_data >> 9) & 0x0f; tile_line = (m_current_line + m_layer_fg_scroll_y) & 0x07; if (tile_data & 0x8000) // vflip @@ -566,30 +530,30 @@ void wswan_video_device::draw_foreground_3() if (m_colors_16) { - tile_address = ((tile_data & 0x2000) ? 0x8000 : 0x4000) + (tile_number * 32) + (tile_line << 2); + const u16 tile_address = ((tile_data & 0x2000) ? 0x4000 : 0x2000) + (tile_number * 16) + (tile_line << 1); if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3]; + plane0 = (swap_bytes(m_vram[tile_address]) << 16) | swap_bytes(m_vram[tile_address + 1]); } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; - plane2 = m_vram[tile_address + 2] << 2; - plane3 = m_vram[tile_address + 3] << 3; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; + plane2 = (m_vram[tile_address + 1] & 0xff) << 2; + plane3 = (m_vram[tile_address + 1] & 0xff00) >> 5; } } else { - tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1); + const u16 tile_address = 0x1000 + (tile_number * 8) + tile_line; if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1]; + plane0 = m_vram[tile_address]; } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; plane2 = 0; plane3 = 0; } @@ -625,17 +589,13 @@ void wswan_video_device::draw_foreground_3() else x_offset = 7 - x + (column << 3) - (m_layer_fg_scroll_x & 0x07); - if ((x_offset >= 0 && x_offset < m_window_fg_left) || (x_offset >= m_window_fg_right && x_offset < WSWAN_X_PIXELS)) + if ((x_offset >= 0 && x_offset < m_window_fg_left) || (x_offset > m_window_fg_right && x_offset < WSWAN_X_PIXELS)) { if (m_colors_16) { if (col) { - if (m_color_mode) - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; - else - /* Hmmmm, what should we do here... Is this correct?? */ - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; + m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; } } else @@ -660,17 +620,17 @@ void wswan_video_device::handle_sprites(int mask) for (int i = m_sprite_first + m_sprite_count - 1; i >= m_sprite_first; i--) { - uint16_t tile_data = (m_sprite_table_buffer[i * 4 + 1] << 8) | m_sprite_table_buffer[i * 4]; - uint8_t y = m_sprite_table_buffer[ i * 4 + 2 ]; - uint8_t x = m_sprite_table_buffer[ i * 4 + 3 ]; + const u16 tile_data = m_sprite_table_buffer[i * 2]; + const u8 y = m_sprite_table_buffer[(i * 2) + 1] & 0xff; + const u8 x = m_sprite_table_buffer[(i * 2) + 1] >> 8; int tile_line = (m_current_line - y) & 0xff; if ((tile_line >= 0) && (tile_line < 8) && ((tile_data & 0x2000) == mask)) { - uint32_t plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; - int x_offset, tile_address; - int tile_number = tile_data & 0x01ff; - int tile_palette = 8 + ((tile_data >> 9) & 0x07); + u32 plane0 = 0, plane1 = 0, plane2 = 0, plane3 = 0; + int x_offset; + const int tile_number = tile_data & 0x01ff; + const int tile_palette = 8 + ((tile_data >> 9) & 0x07); int check_clip = 0; if (tile_data & 0x8000) @@ -678,30 +638,30 @@ void wswan_video_device::handle_sprites(int mask) if (m_colors_16) { - tile_address = 0x4000 + (tile_number * 32) + (tile_line << 2); + const u16 tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1); if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 24) | (m_vram[tile_address + 1] << 16) | (m_vram[tile_address + 2] << 8) | m_vram[tile_address + 3]; + plane0 = (swap_bytes(m_vram[tile_address]) << 16) | swap_bytes(m_vram[tile_address + 1]); } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; - plane2 = m_vram[tile_address + 2] << 2; - plane3 = m_vram[tile_address + 3] << 3; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; + plane2 = (m_vram[tile_address + 1] & 0xff) << 2; + plane3 = (m_vram[tile_address + 1] & 0xff00) >> 5; } } else { - tile_address = 0x2000 + (tile_number * 16) + (tile_line << 1); + const u16 tile_address = 0x1000 + (tile_number * 8) + tile_line; if (m_tile_packed) { - plane0 = (m_vram[tile_address + 0] << 8) | m_vram[tile_address + 1]; + plane0 = m_vram[tile_address]; } else { - plane0 = m_vram[tile_address + 0]; - plane1 = m_vram[tile_address + 1] << 1; + plane0 = m_vram[tile_address] & 0xff; + plane1 = (m_vram[tile_address] & 0xff00) >> 7; plane2 = 0; plane3 = 0; } @@ -774,11 +734,7 @@ void wswan_video_device::handle_sprites(int mask) { if (col) { - if (m_color_mode) - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; - else - /* Hmmmm, what should we do here... Is this correct?? */ - m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; + m_bitmap.pix(m_current_line, x_offset) = m_pal[tile_palette][col]; } } else @@ -855,297 +811,307 @@ void wswan_video_device::refresh_scanline() -uint32_t wswan_video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +u32 wswan_video_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); return 0; } -uint8_t wswan_video_device::reg_r(offs_t offset) +u16 wswan_video_device::reg_r(offs_t offset, u16 mem_mask) { - uint8_t value = m_regs[offset]; - - if (offset >= 0x20 && offset < 0x40) - return m_palette_port[offset & 0x1f]; + u16 value = m_regs[offset & 0x7f]; switch (offset) { - case 0x01: - value = m_bg_control; - break; - case 0x02: - value = m_current_line; - break; - case 0x14: - value = m_lcd_control; - break; - case 0xa8: - value = m_timer_hblank_count & 0xff; - break; - case 0xa9: - value = m_timer_hblank_count >> 8; - break; - case 0xaa: - value = m_timer_vblank_count & 0xff; - break; - case 0xab: - value = m_timer_vblank_count >> 8; - break; + case 0x02 / 2: + return (value & 0xff00) | m_current_line; + case 0xa8 / 2: + return m_timer_hblank_count; + case 0xaa / 2: + return m_timer_vblank_count; } return value; } -void wswan_video_device::reg_w(offs_t offset, uint8_t data) +void wswan_video_device::reg_w(offs_t offset, u16 data, u16 mem_mask) { - if (offset >= 0x20 && offset < 0x40) - { - // 0x20-0x3f tile/sprite palette settings - // even offs - // Bit 0-3 - Palette (offs & 0x1f)/2 index 0 - // Bit 4-7 - Palette (offs & 0x1f)/2 index 1 - // odd offs - // Bit 0-3 - Palette (offs & 0x1f)/2 index 2 - // Bit 4-7 - Palette (offs & 0x1f)/2 index 3 - m_palette_port[offset & 0x1f] = data; - return; - } - switch (offset) { - case 0x00: // Display control - // Bit 0 - Background layer enable - // Bit 1 - Foreground layer enable - // Bit 2 - Sprites enable - // Bit 3 - Sprite window enable - // Bit 4-5 - Foreground window configuration - // 00 - Foreground layer is displayed inside and outside foreground window area - // 01 - Unknown - // 10 - Foreground layer is displayed only inside foreground window area - // 11 - Foreground layer is displayed outside foreground window area - // Bit 6-7 - Unknown - m_layer_bg_enable = data & 0x1; - m_layer_fg_enable = (data & 0x2) >> 1; - m_sprites_enable = (data & 0x4) >> 2; - m_window_sprites_enable = (data & 0x8) >> 3; - m_window_fg_mode = (data & 0x30) >> 4; - break; - case 0x01: // Background colour - // In 16 colour mode: - // Bit 0-3 - Palette index - // Bit 4-7 - Palette number - // Otherwise: - // Bit 0-2 - Main palette index - // Bit 3-7 - Unknown - m_bg_control = data; - break; - case 0x02: // Current scanline (Most likely read-only) - logerror("Write to current scanline! Current value: %d Data to write: %d\n", m_current_line, data); - // Returning so we don't overwrite the value here, not that it really matters - return; - case 0x03: // Line compare - m_line_compare = data; - logerror("Write to line compare: %d\n", data); - break; - case 0x04: // Sprite table base address - // Bit 0-5 - Determine sprite table base address 0 0xxxxxx0 00000000 - // Bit 6-7 - Unknown - m_sprite_table_address = (data & 0x3f) << 9; - break; - case 0x05: // First sprite number (the one we start drawing with) - m_sprite_first_latch = data; - if (data) logerror("non-zero first sprite %d\n", data); - break; - case 0x06: // Number of sprites to draw - m_sprite_count_latch = data; - break; - case 0x07: // Background/Foreground table base addresses - // Bit 0-2 - Determine background table base address 00xxx000 00000000 - // Bit 3 - Unknown - // Bit 4-6 - Determine foreground table base address 00xxx000 00000000 - // Bit 7 - Unknown - m_layer_bg_address = (data & 0x7) << 11; - m_layer_fg_address = (data & 0x70) << 7; - break; - case 0x08: // Left coordinate of foreground window - m_window_fg_left = data; - break; - case 0x09: // Top coordinate of foreground window - m_window_fg_top = data; - break; - case 0x0a: // Right coordinate of foreground window - m_window_fg_right = data; - break; - case 0x0b: // Bottom coordinate of foreground window - m_window_fg_bottom = data; + case 0x00 / 2: + // Display control + // Bit 0 - Background layer enable + // Bit 1 - Foreground layer enable + // Bit 2 - Sprites enable + // Bit 3 - Sprite window enable + // Bit 4-5 - Foreground window configuration + // 00 - Foreground layer is displayed inside and outside foreground window area + // 01 - Unknown + // 10 - Foreground layer is displayed only inside foreground window area + // 11 - Foreground layer is displayed outside foreground window area + // Bit 6-7 - Unknown + if (ACCESSING_BITS_0_7) + { + m_layer_bg_enable = data & 0x1; + m_layer_fg_enable = (data & 0x2) >> 1; + m_sprites_enable = (data & 0x4) >> 2; + m_window_sprites_enable = (data & 0x8) >> 3; + m_window_fg_mode = (data & 0x30) >> 4; + } + // Background colour + // In 16 colour mode: + // Bit 0-3 - Palette index + // Bit 4-7 - Palette number + // Otherwise: + // Bit 0-2 - Main palette index + // Bit 3-7 - Unknown + if (ACCESSING_BITS_8_15) + m_bg_control = data >> 8; break; - case 0x0c: // Left coordinate of sprite window - m_window_sprites_left = data; + case 0x02 / 2: + // Current scanline (read-only) + if (ACCESSING_BITS_0_7) + logerror("Write to current scanline! Current value: %d Data to write: %d\n", m_current_line, data); + // Line compare + if (ACCESSING_BITS_8_15) + m_line_compare = data >> 8; break; - case 0x0d: // Top coordinate of sprite window - m_window_sprites_top = data; + case 0x04 / 2: + // Sprite table base address + // Bit 0-5 - Determine sprite table base address 0 0xxxxxx0 00000000 + // Bit 6-7 - Unknown + if (ACCESSING_BITS_0_7) + { + if (m_vdp_type == VDP_TYPE_WSC && !m_color_mode) + m_sprite_table_address = (data & 0x3f) << 8; + else + m_sprite_table_address = (data & 0x1f) << 8; + } + // First sprite number (the one we start drawing with) + if (ACCESSING_BITS_8_15) + m_sprite_first_latch = data >> 8; break; - case 0x0e: // Right coordinate of sprite window - m_window_sprites_right = data; + case 0x06 / 2: + // Number of sprites to draw + if (ACCESSING_BITS_0_7) + m_sprite_count_latch = data & 0xff; + // Background/Foreground table base addresses + // Bit 8-10 - Determine background table base address 00xxx000 00000000 (in bytes) + // Bit 11 - Unknown + // Bit 12-14 - Determine foreground table base address 00xxx000 00000000 (in bytes) + // Bit 15 - Unknown + if (ACCESSING_BITS_8_15) + { + m_layer_bg_address = (data & 0x0700) << 2; + m_layer_fg_address = (data & 0x7000) >> 2; + } break; - case 0x0f: // Bottom coordinate of sprite window - m_window_sprites_bottom = data; + case 0x08 / 2: + // Left coordinate of foreground window + if (ACCESSING_BITS_0_7) + m_window_fg_left = data & 0xff; + // Top coordinate of foreground window + if (ACCESSING_BITS_8_15) + m_window_fg_top = data >> 8; break; - case 0x10: // Background layer X scroll - m_layer_bg_scroll_x = data; + case 0x0a / 2: + // Right coordinate of foreground window + if (ACCESSING_BITS_0_7) + m_window_fg_right = data & 0xff; + // Bottom coordinate of foreground window + if (ACCESSING_BITS_8_15) + m_window_fg_bottom = data >> 8; break; - case 0x11: // Background layer Y scroll - m_layer_bg_scroll_y = data; + case 0x0c / 2: + // Left coordinate of sprite window + if (ACCESSING_BITS_0_7) + m_window_sprites_left = data & 0xff; + // Top coordinate of sprite window + if (ACCESSING_BITS_8_15) + m_window_sprites_top = data >> 8; break; - case 0x12: // Foreground layer X scroll - m_layer_fg_scroll_x = data; + case 0x0e / 2: + // Right coordinate of sprite window + if (ACCESSING_BITS_0_7) + m_window_sprites_right = data & 0xff; + // Bottom coordinate of sprite window + if (ACCESSING_BITS_8_15) + m_window_sprites_bottom = data >> 8; break; - case 0x13: // Foreground layer Y scroll - m_layer_fg_scroll_y = data; + case 0x10 / 2: + // Background layer X scroll + if (ACCESSING_BITS_0_7) + m_layer_bg_scroll_x = data & 0xff; + // Background layer Y scroll + if (ACCESSING_BITS_8_15) + m_layer_bg_scroll_y = data >> 8; break; - case 0x14: // LCD control - // Bit 0 - LCD enable - // Bit 1 - WSC only, brightness low/high - // Bit 2-7 - Unknown - m_lcd_control = data; + case 0x12 / 2: + // Foreground layer X scroll + if (ACCESSING_BITS_0_7) + m_layer_fg_scroll_x = data & 0xff; + // Foreground layer Y scroll + if (ACCESSING_BITS_8_15) + m_layer_fg_scroll_y = data >> 8; break; - case 0x15: // LCD icons - // Bit 0 - LCD sleep icon enable - // Bit 1 - Vertical position icon enable - // Bit 2 - Horizontal position icon enable - // Bit 3 - Dot 1 icon enable - // Bit 4 - Dot 2 icon enable - // Bit 5 - Dot 3 icon enable - // Bit 6-7 - Unknown - m_icons = data; /* ummmmm */ + case 0x14 / 2: + // LCD control + // Bit 0 - LCD enable + // Bit 1 - WSC only, brightness low/high + // Bit 2-7 - Unknown + if (ACCESSING_BITS_0_7) + m_lcd_control = data & 0xff; + // LCD icons + // Bit 8 - LCD sleep icon enable + // Bit 9 - Vertical position icon enable + // Bit 10 - Horizontal position icon enable + // Bit 11 - Dot 1 icon enable + // Bit 12 - Dot 2 icon enable + // Bit 13 - Dot 3 icon enable + // Bit 14-15 - Unknown + if (ACCESSING_BITS_8_15) + m_icons_cb(data >> 8); break; - case 0x1c: // Palette colors 0 and 1 - // Bit 0-3 - Gray tone setting for main palette index 0 - // Bit 4-7 - Gray tone setting for main palette index 1 - if (m_vdp_type == VDP_TYPE_WSC) + case 0x1c / 2: + // Palette colors 0 and 1 + // Bit 0-3 - Gray tone setting for main palette index 0 + // Bit 4-7 - Gray tone setting for main palette index 1 + if (ACCESSING_BITS_0_7) { - int i = 15 - (data & 0x0f); - int j = 15 - ((data & 0xf0) >> 4); - m_main_palette[0] = (i << 8) | (i << 4) | i; - m_main_palette[1] = (j << 8) | (j << 4) | j; + if (m_vdp_type == VDP_TYPE_WSC) + { + int i = 15 - (data & 0x0f); + int j = 15 - ((data >> 4) & 0x0f); + m_main_palette[0] = (i << 8) | (i << 4) | i; + m_main_palette[1] = (j << 8) | (j << 4) | j; + } + else + { + m_main_palette[0] = data & 0x0f; + m_main_palette[1] = (data >> 4) & 0x0f; + } } - else + // Palette colors 2 and 3 + // Bit 8-11 - Gray tone setting for main palette index 2 + // Bit 12-15 - Gray tone setting for main palette index 3 + if (ACCESSING_BITS_8_15) { - m_main_palette[0] = data & 0x0f; - m_main_palette[1] = (data & 0xf0) >> 4; + if (m_vdp_type == VDP_TYPE_WSC) + { + int i = 15 - ((data >> 8) & 0x0f); + int j = 15 - ((data >> 12) & 0x0f); + m_main_palette[2] = (i << 8) | (i << 4) | i; + m_main_palette[3] = (j << 8) | (j << 4) | j; + } + else + { + m_main_palette[2] = (data >> 8) & 0x0f; + m_main_palette[3] = (data >> 12) & 0x0f; + } } break; - case 0x1d: // Palette colors 2 and 3 - // Bit 0-3 - Gray tone setting for main palette index 2 - // Bit 4-7 - Gray tone setting for main palette index 3 - if (m_vdp_type == VDP_TYPE_WSC) + case 0x1e / 2: + // Palette colors 4 and 5 + // Bit 0-3 - Gray tone setting for main palette index 4 + // Bit 4-7 - Gray tone setting for main palette index 5 + if (ACCESSING_BITS_0_7) { - int i = 15 - (data & 0x0f); - int j = 15 - ((data & 0xf0) >> 4); - m_main_palette[2] = (i << 8) | (i << 4) | i; - m_main_palette[3] = (j << 8) | (j << 4) | j; + if (m_vdp_type == VDP_TYPE_WSC) + { + int i = 15 - (data & 0x0f); + int j = 15 - ((data >> 4) & 0x0f); + m_main_palette[4] = (i << 8) | (i << 4) | i; + m_main_palette[5] = (j << 8) | (j << 4) | j; + } + else + { + m_main_palette[4] = data & 0x0f; + m_main_palette[5] = (data >> 4) & 0x0f; + } } - else + // Palette colors 6 and 7 + // Bit 0-3 - Gray tone setting for main palette index 6 + // Bit 4-7 - Gray tone setting for main palette index 7 + if (ACCESSING_BITS_8_15) { - m_main_palette[2] = data & 0x0f; - m_main_palette[3] = (data & 0xf0) >> 4; + if (m_vdp_type == VDP_TYPE_WSC) + { + int i = 15 - ((data >> 8) & 0x0f); + int j = 15 - ((data >> 12) & 0x0f); + m_main_palette[6] = (i << 8) | (i << 4) | i; + m_main_palette[7] = (j << 8) | (j << 4) | j; + } + else + { + m_main_palette[6] = (data >> 8) & 0x0f; + m_main_palette[7] = (data >> 12) & 0x0f; + } } break; - case 0x1e: // Palette colors 4 and 5 - // Bit 0-3 - Gray tone setting for main palette index 4 - // Bit 4-7 - Gray tone setting for main palette index 5 - if (m_vdp_type == VDP_TYPE_WSC) - { - int i = 15 - (data & 0x0f); - int j = 15 - ((data & 0xf0) >> 4); - m_main_palette[4] = (i << 8) | (i << 4) | i; - m_main_palette[5] = (j << 8) | (j << 4) | j; - } - else - { - m_main_palette[4] = data & 0x0f; - m_main_palette[5] = (data & 0xf0) >> 4; - } + case 0x20 / 2: case 0x22 / 2: case 0x24 / 2: case 0x26 / 2: + case 0x28 / 2: case 0x2a / 2: case 0x2c / 2: case 0x2e / 2: + case 0x30 / 2: case 0x32 / 2: case 0x34 / 2: case 0x36 / 2: + case 0x38 / 2: case 0x3a / 2: case 0x3c / 2: case 0x3e / 2: + // 0x20-0x3f tile/sprite palette settings + // Bit 0- 3 - Palette (offs & 0x1f)/2 index 0 + // Bit 4- 7 - Palette (offs & 0x1f)/2 index 1 + // Bit 8-11 - Palette (offs & 0x1f)/2 index 2 + // Bit 12-15 - Palette (offs & 0x1f)/2 index 3 + data &= 0x7777; + COMBINE_DATA(&m_palette_port[offset & 0x0f]); break; - case 0x1f: // Palette colors 6 and 7 - // Bit 0-3 - Gray tone setting for main palette index 6 - // Bit 4-7 - Gray tone setting for main palette index 7 - if (m_vdp_type == VDP_TYPE_WSC) + case 0x60 / 2: + // Video mode + // Bit 0-4 - Unknown + // Bit 5 - Packed mode 0 = not packed mode, 1 = packed mode + // Bit 6 - 4/16 colour mode select: 0 = 4 colour mode, 1 = 16 colour mode + // Bit 7 - monochrome/colour mode select: 0 = monochrome mode, 1 = colour mode + // 111 - packed, 16 color, use 4000/8000, color + // 110 - not packed, 16 color, use 4000/8000, color + // 101 - packed, 4 color, use 2000, color + // 100 - not packed, 4 color, use 2000, color + // 011 - packed, 16 color, use 4000/8000, monochrome + // 010 - not packed, 16 color , use 4000/8000, monochrome + // 001 - packed, 4 color, use 2000, monochrome + // 000 - not packed, 4 color, use 2000, monochrome - Regular WS monochrome + if (ACCESSING_BITS_0_7) { - int i = 15 - (data & 0x0f); - int j = 15 - ((data & 0xf0) >> 4); - m_main_palette[6] = (i << 8) | (i << 4) | i; - m_main_palette[7] = (j << 8) | (j << 4) | j; - } - else - { - m_main_palette[6] = data & 0x0f; - m_main_palette[7] = (data & 0xf0) >> 4; + if (m_vdp_type == VDP_TYPE_WSC) + { + m_color_mode = data & 0x80; + m_colors_16 = data & 0x40; + m_tile_packed = data & 0x20; + } } break; - case 0x60: // Video mode - // Bit 0-4 - Unknown - // Bit 5 - Packed mode 0 = not packed mode, 1 = packed mode - // Bit 6 - 4/16 colour mode select: 0 = 4 colour mode, 1 = 16 colour mode - // Bit 7 - monochrome/colour mode select: 0 = monochrome mode, 1 = colour mode - /* - * 111 - packed, 16 color, use 4000/8000, color - * 110 - not packed, 16 color, use 4000/8000, color - * 101 - packed, 4 color, use 2000, color - * 100 - not packed, 4 color, use 2000, color - * 011 - packed, 16 color, use 4000/8000, monochrome - * 010 - not packed, 16 color , use 4000/8000, monochrome - * 001 - packed, 4 color, use 2000, monochrome - * 000 - not packed, 4 color, use 2000, monochrome - Regular WS monochrome - */ - if (m_vdp_type == VDP_TYPE_WSC) + case 0xa2 / 2: + // Timer control + // Bit 0 - HBlank Timer enable + // Bit 1 - HBlank Timer mode: 0 = one shot, 1 = auto reset + // Bit 2 - VBlank Timer(1/75s) enable + // Bit 3 - VBlank Timer mode: 0 = one shot, 1 = auto reset + // Bit 4-7 - Unknown + if (ACCESSING_BITS_0_7) { - m_color_mode = data & 0x80; - m_colors_16 = data & 0x40; - m_tile_packed = data & 0x20; + m_timer_hblank_enable = BIT(data, 0); + m_timer_hblank_mode = BIT(data, 1); + m_timer_vblank_enable = BIT(data, 2); + m_timer_vblank_mode = BIT(data, 3); } break; - case 0xa2: // Timer control - // Bit 0 - HBlank Timer enable - // Bit 1 - HBlank Timer mode: 0 = one shot, 1 = auto reset - // Bit 2 - VBlank Timer(1/75s) enable - // Bit 3 - VBlank Timer mode: 0 = one shot, 1 = auto reset - // Bit 4-7 - Unknown - m_timer_hblank_enable = BIT(data, 0); - m_timer_hblank_mode = BIT(data, 1); - m_timer_vblank_enable = BIT(data, 2); - m_timer_vblank_mode = BIT(data, 3); - break; - case 0xa4: // HBlank timer frequency reload value (bits 0-7) - m_timer_hblank_reload &= 0xff00; - m_timer_hblank_reload += data; - m_timer_hblank_count = m_timer_hblank_reload; - break; - case 0xa5: // HBlank timer frequency reload value (bits 8-15) - m_timer_hblank_reload &= 0xff; - m_timer_hblank_reload += data << 8; + case 0xa4 / 2: // HBlank timer frequency reload value + COMBINE_DATA(&m_timer_hblank_reload); m_timer_hblank_count = m_timer_hblank_reload; break; - case 0xa6: // VBlank timer frequency reload value (bits 0-7) - m_timer_vblank_reload &= 0xff00; - m_timer_vblank_reload += data; + case 0xa6 / 2: // VBlank timer frequency reload value + COMBINE_DATA(&m_timer_vblank_reload); m_timer_vblank_count = m_timer_vblank_reload; break; - case 0xa7: // VBlank timer frequency reload value (bits 8-15) - m_timer_vblank_reload &= 0xff; - m_timer_vblank_reload += data << 8; - m_timer_vblank_count = m_timer_vblank_reload; - break; - case 0xa8: // HBlank counter (bits 0-7) - case 0xa9: // HBlank counter (bits 8-15) - case 0xaa: // VBlank counter (bits 0-7) - case 0xab: // VBlank counter (bits 8-15) - break; } - m_regs[offset] = data; + COMBINE_DATA(&m_regs[offset & 0x7f]); } @@ -1158,7 +1124,6 @@ void wswan_video_device::scanline_interrupt() if (m_timer_hblank_enable && m_timer_hblank_reload != 0) { m_timer_hblank_count--; - logerror("timer_hblank_count: %X\n", m_timer_hblank_count); if (m_timer_hblank_count == 0) { if (m_timer_hblank_mode) @@ -1166,7 +1131,6 @@ void wswan_video_device::scanline_interrupt() else m_timer_hblank_reload = 0; - logerror( "triggering hbltmr interrupt\n" ); m_set_irq_cb(WSWAN_VIDEO_IFLAG_HBLTMR); } } @@ -1174,12 +1138,10 @@ void wswan_video_device::scanline_interrupt() // Handle Sound DMA m_snd_dma_cb(); -// m_current_line = (m_current_line + 1) % 159; - if (m_current_line == 144) // buffer sprite table { memcpy(m_sprite_table_buffer, &m_vram[m_sprite_table_address], 512); - m_sprite_first = m_sprite_first_latch; // always zero? + m_sprite_first = m_sprite_first_latch; m_sprite_count = m_sprite_count_latch; } @@ -1190,7 +1152,6 @@ void wswan_video_device::scanline_interrupt() if (m_timer_vblank_enable && m_timer_vblank_reload != 0) { m_timer_vblank_count--; - logerror("timer_vblank_count: %X\n", m_timer_vblank_count); if (m_timer_vblank_count == 0) { if (m_timer_vblank_mode) @@ -1198,14 +1159,11 @@ void wswan_video_device::scanline_interrupt() else m_timer_vblank_reload = 0; - logerror("triggering vbltmr interrupt\n"); m_set_irq_cb(WSWAN_VIDEO_IFLAG_VBLTMR); } } } -// m_current_line = (m_current_line + 1) % 159; - if (m_current_line == m_line_compare) m_set_irq_cb(WSWAN_VIDEO_IFLAG_LCMP); @@ -1213,12 +1171,13 @@ void wswan_video_device::scanline_interrupt() } -uint8_t wswan_video_device::vram_r(offs_t offset) +u16 wswan_video_device::vram_r(offs_t offset, u16 mem_mask) { return m_vram[offset]; } -void wswan_video_device::vram_w(offs_t offset, uint8_t data) + +void wswan_video_device::vram_w(offs_t offset, u16 data, u16 mem_mask) { - m_vram[offset] = data; + COMBINE_DATA(&m_vram[offset]); } diff --git a/src/mame/video/wswan.h b/src/mame/video/wswan.h index 0ca4b6d3c1d..f532ae5d3ab 100644 --- a/src/mame/video/wswan.h +++ b/src/mame/video/wswan.h @@ -30,12 +30,14 @@ public: template void set_dmasnd_callback(T &&... args) { m_snd_dma_cb.set(std::forward(args)...); } void set_vdp_type(int type) { m_vdp_type = type; } - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint8_t vram_r(offs_t offset); - void vram_w(offs_t offset, uint8_t data); - uint8_t reg_r(offs_t offset); - void reg_w(offs_t offset, uint8_t data); + u16 vram_r(offs_t offset, u16 mem_mask); + void vram_w(offs_t offset, u16 data, u16 mem_mask); + u16 reg_r(offs_t offset, u16 mem_mesk); + void reg_w(offs_t offset, u16 data, u16 mem_mask); + + auto icons_cb() { return m_icons_cb.bind(); } enum { @@ -61,71 +63,77 @@ protected: void refresh_scanline(); void scanline_interrupt(); void common_save(); + u16 swap_bytes(u16 word); bitmap_ind16 m_bitmap; - uint8_t m_layer_bg_enable; /* Background layer on/off */ - uint8_t m_layer_fg_enable; /* Foreground layer on/off */ - uint8_t m_sprites_enable; /* Sprites on/off */ - uint8_t m_window_sprites_enable; /* Sprite window on/off */ - uint8_t m_window_fg_mode; /* 0:inside/outside, 1:??, 2:inside, 3:outside */ - uint8_t m_bg_control; - uint8_t m_current_line; /* Current scanline : 0-158 (159?) */ - uint8_t m_line_compare; /* Line to trigger line interrupt on */ - uint32_t m_sprite_table_address; /* Address of the sprite table */ - uint8_t m_sprite_table_buffer[512]; - uint8_t m_sprite_first; /* First sprite to draw */ - uint8_t m_sprite_count; /* Number of sprites to draw */ - uint8_t m_sprite_first_latch; - uint8_t m_sprite_count_latch; - uint16_t m_layer_bg_address; /* Address of the background screen map */ - uint16_t m_layer_fg_address; /* Address of the foreground screen map */ - uint8_t m_window_fg_left; /* Left coordinate of foreground window */ - uint8_t m_window_fg_top; /* Top coordinate of foreground window */ - uint8_t m_window_fg_right; /* Right coordinate of foreground window */ - uint8_t m_window_fg_bottom; /* Bottom coordinate of foreground window */ - uint8_t m_window_sprites_left; /* Left coordinate of sprites window */ - uint8_t m_window_sprites_top; /* Top coordinate of sprites window */ - uint8_t m_window_sprites_right; /* Right coordinate of sprites window */ - uint8_t m_window_sprites_bottom; /* Bottom coordinate of sprites window */ - uint8_t m_layer_bg_scroll_x; /* Background layer X scroll */ - uint8_t m_layer_bg_scroll_y; /* Background layer Y scroll */ - uint8_t m_layer_fg_scroll_x; /* Foreground layer X scroll */ - uint8_t m_layer_fg_scroll_y; /* Foreground layer Y scroll */ - uint8_t m_lcd_control; /* LCD on/off */ - uint8_t m_icons; /* FIXME: What do we do with these? Maybe artwork? */ - uint8_t m_color_mode; /* monochrome/color mode */ - uint8_t m_colors_16; /* 4/16 colors mode */ - uint8_t m_tile_packed; /* layered/packed tile mode switch */ - uint8_t m_timer_hblank_enable; /* Horizontal blank interrupt on/off */ - uint8_t m_timer_hblank_mode; /* Horizontal blank timer mode */ - uint16_t m_timer_hblank_reload; /* Horizontal blank timer reload value */ - uint16_t m_timer_hblank_count; /* Horizontal blank timer counter value */ - uint8_t m_timer_vblank_enable; /* Vertical blank interrupt on/off */ - uint8_t m_timer_vblank_mode; /* Vertical blank timer mode */ - uint16_t m_timer_vblank_reload; /* Vertical blank timer reload value */ - uint16_t m_timer_vblank_count; /* Vertical blank timer counter value */ + u8 m_layer_bg_enable; // Background layer on/off + u8 m_layer_fg_enable; // Foreground layer on/off + u8 m_sprites_enable; // Sprites on/off + u8 m_window_sprites_enable; // Sprite window on/off + u8 m_window_fg_mode; // 0:inside/outside, 1:??, 2:inside, 3:outside + u8 m_bg_control; + u8 m_current_line; // Current scanline : 0-158 (159?) + u8 m_line_compare; // Line to trigger line interrupt on + u32 m_sprite_table_address; // Address of the sprite table + u16 m_sprite_table_buffer[256]; + u8 m_sprite_first; // First sprite to draw + u8 m_sprite_count; // Number of sprites to draw + u8 m_sprite_first_latch; + u8 m_sprite_count_latch; + u16 m_layer_bg_address; // Address of the background screen map + u16 m_layer_fg_address; // Address of the foreground screen map + u8 m_window_fg_left; // Left coordinate of foreground window + u8 m_window_fg_top; // Top coordinate of foreground window + u8 m_window_fg_right; // Right coordinate of foreground window + u8 m_window_fg_bottom; // Bottom coordinate of foreground window + u8 m_window_sprites_left; // Left coordinate of sprites window + u8 m_window_sprites_top; // Top coordinate of sprites window + u8 m_window_sprites_right; // Right coordinate of sprites window + u8 m_window_sprites_bottom; // Bottom coordinate of sprites window + u8 m_layer_bg_scroll_x; // Background layer X scroll + u8 m_layer_bg_scroll_y; // Background layer Y scroll + u8 m_layer_fg_scroll_x; // Foreground layer X scroll + u8 m_layer_fg_scroll_y; // Foreground layer Y scroll + u8 m_lcd_control; // LCD on/off + u8 m_color_mode; // monochrome/color mode + u8 m_colors_16; // 4/16 colors mode + u8 m_tile_packed; // layered/packed tile mode switch + u8 m_timer_hblank_enable; // Horizontal blank interrupt on/off + u8 m_timer_hblank_mode; // Horizontal blank timer mode + u16 m_timer_hblank_reload; // Horizontal blank timer reload value + u16 m_timer_hblank_count; // Horizontal blank timer counter value + u8 m_timer_vblank_enable; // Vertical blank interrupt on/off + u8 m_timer_vblank_mode; // Vertical blank timer mode + u16 m_timer_vblank_reload; // Vertical blank timer reload value + u16 m_timer_vblank_count; // Vertical blank timer counter value int m_main_palette[8]; emu_timer *m_timer; - std::vector m_vram; - uint8_t *m_palette_vram; - uint8_t m_palette_port[0x20]; + std::vector m_vram; + u16 *m_palette_vram; + u16 m_palette_port[0x10]; int m_pal[16][16]; - uint8_t m_regs[256]; + u16 m_regs[128]; irq_cb_delegate m_set_irq_cb; dmasnd_cb_delegate m_snd_dma_cb; int m_vdp_type; + devcb_write8 m_icons_cb; + // timer IDs - static const device_timer_id TIMER_SCANLINE = 0; + static constexpr device_timer_id TIMER_SCANLINE = 0; // interrupt flags // these are the same as the wswan.h ones - static const uint8_t WSWAN_VIDEO_IFLAG_LCMP = 0x10; - static const uint8_t WSWAN_VIDEO_IFLAG_VBLTMR = 0x20; - static const uint8_t WSWAN_VIDEO_IFLAG_VBL = 0x40; - static const uint8_t WSWAN_VIDEO_IFLAG_HBLTMR = 0x80; + static constexpr u8 WSWAN_VIDEO_IFLAG_LCMP = 0x10; + static constexpr u8 WSWAN_VIDEO_IFLAG_VBLTMR = 0x20; + static constexpr u8 WSWAN_VIDEO_IFLAG_VBL = 0x40; + static constexpr u8 WSWAN_VIDEO_IFLAG_HBLTMR = 0x80; + + static constexpr size_t WS_VRAM_SIZE = 0x4000 >> 1; + static constexpr size_t WSC_VRAM_SIZE = 0x10000 >> 1; + static constexpr size_t WSC_VRAM_PALETTE = 0xfe00 >> 1; }; DECLARE_DEVICE_TYPE(WSWAN_VIDEO, wswan_video_device) -- cgit v1.2.3